xpra icon
Bug tracker and wiki

This bug tracker and wiki are being discontinued
please use https://github.com/Xpra-org/xpra instead.


Ticket #147: xpra-vpx-gl.patch

File xpra-vpx-gl.patch, 8.5 KB (added by Antoine Martin, 9 years ago)

fixing vpx to allow it to work with yuv/opengl codepath (work in progress patch)

  • xpra/vpx/codec.pyx

     
    88cdef extern from "Python.h":
    99    ctypedef int Py_ssize_t
    1010    ctypedef object PyObject
     11    ctypedef void** const_void_pp "const void**"
    1112    int PyObject_AsReadBuffer(object obj, void ** buffer, Py_ssize_t * buffer_len) except -1
    1213
    1314ctypedef unsigned char uint8_t
     
    1617cdef extern from "vpxlib.h":
    1718    vpx_codec_ctx_t* init_encoder(int width, int height)
    1819    void clean_encoder(vpx_codec_ctx_t *context)
    19     vpx_image_t* csc_image(vpx_codec_ctx_t *ctx, uint8_t *input, int stride)
     20    vpx_image_t* csc_image_rgb2yuv(vpx_codec_ctx_t *ctx, uint8_t *input, int stride)
    2021    int compress_image(vpx_codec_ctx_t *ctx, vpx_image_t *image, uint8_t **out, int *outsz) nogil
    2122
    2223    vpx_codec_ctx_t* init_decoder(int width, int height)
    2324    void clean_decoder(vpx_codec_ctx_t *context)
    24     int decompress_image(vpx_codec_ctx_t *context, uint8_t *input, int size, uint8_t **out, int *outsize, int *outstride)
     25    int decompress_image(vpx_codec_ctx_t *ctx, uint8_t *input, int size, uint8_t *(*out)[4], int *outsize, int (*outstride)[4])
     26    int csc_image_yuv2rgb(vpx_codec_ctx_t *ctx, uint8_t *input[3], int stride[3], uint8_t **out, int *outsz, int *outstride) nogil
    2527
    2628
    2729ENCODERS = {}
     
    6466            clean_decoder(self.context)
    6567            self.context = NULL
    6668
     69    def decompress_image_to_yuv(self, input):
     70        cdef uint8_t *dout[4]
     71        cdef int outsize
     72        cdef int outstrides[4]
     73        cdef unsigned char * buf = <uint8_t *> 0
     74        cdef Py_ssize_t buf_len = 0
     75        assert self.context!=NULL
     76        PyObject_AsReadBuffer(input, <const_void_pp> &buf, &buf_len)
     77        i = decompress_image(self.context, buf, buf_len, &dout, &outsize, &outstrides)
     78        if i!=0:
     79            return i, [0, 0, 0], ["", "", ""]
     80        doutvY = (<char *>dout[0])[:self.height * outstrides[0]]
     81        doutvU = (<char *>dout[1])[:self.height * outstrides[1]]
     82        doutvV = (<char *>dout[2])[:self.height * outstrides[2]]
     83        out = [doutvY, doutvU, doutvV]
     84        strides = [outstrides[0], outstrides[1], outstrides[2]]
     85        return  i, strides, out
     86
    6787    def decompress_image_to_rgb(self, input):
     88        cdef uint8_t *yuvplanes[4]
    6889        cdef uint8_t *dout
    6990        cdef int outsize
     91        cdef int yuvstrides[4]
    7092        cdef int outstride
    7193        cdef unsigned char * buf = <uint8_t *> 0
    7294        cdef Py_ssize_t buf_len = 0
     95        cdef int i
    7396        assert self.context!=NULL
    7497        assert self.last_image==NULL
    75         PyObject_AsReadBuffer(input, <void **>&buf, &buf_len)
    76         i = decompress_image(self.context, buf, buf_len, &dout, &outsize, &outstride)
    77         self.last_image = dout
     98        PyObject_AsReadBuffer(input, <const_void_pp> &buf, &buf_len)
     99        print("vpx: before decompress_image")
     100        i = decompress_image(self.context, buf, buf_len, &yuvplanes, &outsize, &yuvstrides)
    78101        if i!=0:
    79102            return i, 0, ""
     103        for x in xrange(0,4):
     104            print("vpx stride[%s]=%s" % (x, yuvstrides[x]))
     105            print("vpx out[%s]=%s" % (x, yuvplanes[x][0]))
     106        with nogil:
     107            i = csc_image_yuv2rgb(self.context, yuvplanes, yuvstrides, &dout, &outsize, &outstride)
     108        print("vpx: csc returned %s" % i)
     109        if i!=0:
     110            return i, 0, ""
     111        self.last_image = dout
    80112        doutv = (<char *>dout)[:outsize]
    81113        return  i, outstride, doutv
    82114
     
    104136        cdef Py_ssize_t buf_len = 0
    105137        assert self.context!=NULL
    106138        #colourspace conversion with gil held:
    107         PyObject_AsReadBuffer(input, <void **>&buf, &buf_len)
    108         pic_in = csc_image(self.context, buf, rowstride)
     139        PyObject_AsReadBuffer(input, <const_void_pp> &buf, &buf_len)
     140        pic_in = csc_image_rgb2yuv(self.context, buf, rowstride)
    109141        assert pic_in!=NULL, "colourspace conversion failed"
    110142        #actual compression (no gil):
    111143        with nogil:
  • xpra/vpx/vpxlib.c

     
    3030#define fourcc    0x30385056
    3131#define IVF_FILE_HDR_SZ  (32)
    3232#include <libswscale/swscale.h>
     33#include <libavcodec/avcodec.h>
    3334
    3435struct vpx_context {
    3536        vpx_codec_ctx_t codec;
     
    99100        free(ctx);
    100101}
    101102
    102 vpx_image_t* csc_image(struct vpx_context *ctx, const uint8_t *in, int stride)
     103vpx_image_t* csc_image_rgb2yuv(struct vpx_context *ctx, const uint8_t *in, int stride)
    103104{
    104105        vpx_image_t *image = malloc(sizeof(vpx_image_t));
    105106        if (!vpx_img_alloc(image, VPX_IMG_FMT_I420, ctx->width, ctx->height, 1)) {
     
    144145        return 0;
    145146}
    146147
    147 int decompress_image(struct vpx_context *ctx, uint8_t *in, int size, uint8_t **out, int *outsize, int *outstride)
     148int csc_image_yuv2rgb(struct vpx_context *ctx, uint8_t *in[4], const int stride[4], uint8_t **out, int *outsz, int *outstride)
    148149{
     150        AVPicture pic;
     151
     152        if (!ctx->yuv2rgb)
     153                return 1;
     154
     155        avpicture_fill(&pic, malloc(ctx->height * ctx->width * 3), PIX_FMT_RGB24, ctx->width, ctx->height);
     156
     157        sws_scale(ctx->yuv2rgb, (const uint8_t * const*) in, stride, 0, ctx->height, pic.data, pic.linesize);
     158
     159        /* Output (must be freed!) */
     160        *out = pic.data[0];
     161        *outsz = pic.linesize[0] * ctx->height;
     162        *outstride = pic.linesize[0];
     163
     164        return 0;
     165}
     166
     167int decompress_image(struct vpx_context *ctx, uint8_t *input, int size, uint8_t *(*out)[4], int *outsize, int (*outstride)[4])
     168{
    149169        vpx_image_t      *img;
    150170        int frame_sz = size;
    151171        vpx_codec_iter_t  iter = NULL;
    152         uint8_t* frame = in;
    153         int outstrides[4];
    154         uint8_t* outs[4];
    155172        int stride = 0;
    156173        int i = 0;
    157174
    158         if (vpx_codec_decode(&ctx->codec, frame, frame_sz, NULL, 0)) {
     175        if (vpx_codec_decode(&ctx->codec, (uint8_t *) input, frame_sz, NULL, 0)) {
    159176                codec_error(&ctx->codec, "vpx_codec_decode");
    160177                return -1;
    161178        }
     
    164181                codec_error(&ctx->codec, "vpx_codec_get_frame");
    165182                return -1;
    166183        }
    167         for (i=0; i<4; i++)
     184        for (i=0; i<4; i++) {
     185                *outstride[i] = img->stride[i];
     186                *out[i] = img->planes[i];
    168187                stride += img->stride[i];
     188        }
    169189        *outsize = stride * img->h;
    170 
    171         *out = malloc(*outsize);
    172         for (i=0; i<4; i++) {
    173                 outstrides[i] = img->w*3;
    174                 outs[i] = *out;
    175         }
    176         sws_scale(ctx->yuv2rgb, img->planes, img->stride, 0, img->h, outs, outstrides);
    177         stride = 0;
    178         for (i=0; i<4; i++)
    179                 stride += img->stride[i];
    180         *outstride = stride;
    181190        return 0;
    182191}
  • xpra/vpx/vpxlib.h

     
    2121/** Cleanup decoding context. Must be freed after calling this function. */
    2222void clean_decoder(struct vpx_context *ctx);
    2323
    24 /** Colourspace conversion.
     24/** Colorspace conversion.
    2525 * Note: you must call compress_image to free the image buffer.
    2626 @param in: Input buffer, format is packed RGB24.
    2727 @param stride: Input stride (size is taken from context).
    2828 @return: the converted picture.
    2929*/
    30 vpx_image_t* csc_image(struct vpx_context *ctx, const uint8_t *in, int stride);
     30vpx_image_t *csc_image_rgb2yuv(struct vpx_context *ctx, const uint8_t *in, int stride);
    3131
     32/** Colorspace conversion.
     33 * Note: you must call compress_image to free the image buffer.
     34 @param in: Input picture (3 planes).
     35 @param stride: Input strides (3 planes).
     36 @param out: Will be set to point to the output data in packed RGB24 format. Must be freed after use by calling free().
     37 @param outsz: Will be set to the size of the output buffer.
     38 @param outstride: Output stride.
     39 @return non zero on error.
     40*/
     41int csc_image_yuv2rgb(struct vpx_context *ctx, uint8_t *in[3], const int stride[3], uint8_t **out, int *outsz, int *outstride);
     42
    3243/** Compress an image using the given context.
    3344 @param pic_in: the input image, as returned by csc_image
    3445 @param out: Will be set to point to the output data. This output buffer MUST NOT BE FREED and will be erased on the
     
    4051/** Decompress an image using the given context.
    4152 @param in: Input buffer, format is H264.
    4253 @param size: Input size.
    43  @param out: Will be set to point to the output data in RGB24 format.
    44  @param outstride: Output stride.
     54 @param out: Will be filled to point to the output data in planar YUV420 format (4 planes).
     55 @param outstride: Output strides. (4 planes)
    4556*/
    46 int decompress_image(struct vpx_context *ctx, uint8_t *in, int size, uint8_t **out, int *outsize, int *outstride);
     57int decompress_image(struct vpx_context *ctx, uint8_t *in, int size, uint8_t *(*out)[4], int *outsize, int (*outstride)[4]);