xpra icon
Bug tracker and wiki

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


Ticket #229: yuvimage-wrapper.patch

File yuvimage-wrapper.patch, 11.1 KB (added by Antoine Martin, 8 years ago)

uses the YUVImage wrapper for both vpx and x264

  • xpra/gl/gl_window_backing.py

     
    6868        self.size = w, h
    6969        # Re-create textures and shader
    7070        self.pixel_format = None
    71         self.yuv_shader = None
     71        self.remove_shader()
    7272
    7373    def gl_init(self):
    7474        drawable = self.gl_begin()
     
    146146
    147147    def do_video_paint(self, coding, img_data, x, y, w, h, options, callbacks):
    148148        debug("do_video_paint: options=%s, decoder=%s", options, type(self._video_decoder))
    149         err, rowstrides, img_data = self._video_decoder.decompress_image_to_yuv(img_data, options)
     149        err, YUVImage = self._video_decoder.decompress_image_to_yuv(img_data, options)
    150150        csc_pixel_format = options.get("csc_pixel_format", -1)
    151151        #this needs to be done here so we still hold the video_decoder lock:
    152152        pixel_format = self._video_decoder.get_pixel_format(csc_pixel_format)
    153         success = err==0 and img_data and len(img_data)==3
    154         if not success:
     153        if YUVImage is None or err!=0:
    155154            log.error("do_video_paint: %s decompression error %s on %s bytes of picture data for %sx%s pixels, options=%s",
    156155                      coding, err, len(img_data), w, h, options)
    157156            gobject.idle_add(fire_paint_callbacks, callbacks, False)
    158157            return
    159         gobject.idle_add(self.do_gl_paint, x, y, w, h, img_data, rowstrides, pixel_format, callbacks)
     158        gobject.idle_add(self.do_gl_paint, x, y, w, h, YUVImage, pixel_format, callbacks)
    160159
    161     def do_gl_paint(self, x, y, w, h, img_data, rowstrides, pixel_format, callbacks):
     160    def do_gl_paint(self, x, y, w, h, YUVImage, pixel_format, callbacks):
    162161        #this function runs in the UI thread, no video_decoder lock held
    163162        drawable = self.gl_init()
    164163        if not drawable:
     
    167166            return
    168167        try:
    169168            try:
    170                 self.update_texture_yuv(img_data, x, y, w, h, rowstrides, pixel_format)
     169                self.update_texture_yuv(YUVImage, x, y, w, h, pixel_format)
    171170                if self.paint_screen:
    172171                    self.render_image(x, y, x+w, y+h)
    173172                fire_paint_callbacks(callbacks, True)
     
    189188            return (1, 1), (1, 1), (1, 1)
    190189        raise Exception("invalid pixel format: %s" % pixel_format)
    191190
    192     def update_texture_yuv(self, img_data, x, y, width, height, rowstrides, pixel_format):
     191    def update_texture_yuv(self, YUVImage, x, y, width, height, pixel_format):
    193192        window_width, window_height = self.size
    194193        assert self.textures is not None, "no OpenGL textures!"
    195194
     
    238237            (div_w, div_h) = divs[index]
    239238            glActiveTexture(texture)
    240239            glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[index])
    241             glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstrides[index])
    242             glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, x, y, width/div_w, height/div_h, GL_LUMINANCE, GL_UNSIGNED_BYTE, img_data[index])
     240            rowstride = YUVImage.get_rowstride(index)
     241            glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstride)
     242            pixel_data = YUVImage.get_component(index)
     243            glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, x, y, width/div_w, height/div_h, GL_LUMINANCE, GL_UNSIGNED_BYTE, pixel_data)
    243244            if index == 1:
    244245                U_width = width/div_w
    245246                U_height = height/div_h
     
    248249                    log.error("Width of V plane is %d, differs from width of corresponding U plane (%d), pixel_format is %d", width/div_w, U_width, pixel_format)
    249250                if height/div_h != U_height:
    250251                    log.error("Height of V plane is %d, differs from height of corresponding U plane (%d)", height/div_h, U_height)
     252        del YUVImage
    251253
    252254    def render_image(self, rx, ry, rw, rh):
    253255        debug("render_image %sx%s at %sx%s pixel_format=%s", rw, rh, rx, ry, self.pixel_format)
  • xpra/vpx/codec.pyx

     
    66import os
    77from libc.stdlib cimport free
    88
     9cdef extern from "string.h":
     10    void * memcpy ( void * destination, void * source, size_t num )
     11    void * memset ( void * ptr, int value, size_t num )
     12
    913cdef extern from "Python.h":
    1014    ctypedef int Py_ssize_t
    1115    ctypedef object PyObject
     
    8185    def __dealloc__(self):                  #@DuplicatedSignature
    8286        self.free()
    8387
     88cdef class YUVImage:
     89    cdef uint8_t *y
     90    cdef uint8_t *u
     91    cdef uint8_t *v
     92    cdef int ystride
     93    cdef int ustride
     94    cdef int vstride
     95    cdef int width                          #@DuplicatedSignature
     96    cdef int height                         #@DuplicatedSignature
    8497
     98    cdef uint8_t* copy(self, uint8_t *src, long size):
     99        cdef uint8_t *dst
     100        dst = <uint8_t*> xmemalign(size)
     101        assert dst!=NULL, "xmemalign failed for %s bytes" % size
     102        memcpy(dst, src, size)
     103        return dst
     104
     105    cdef init(self, int width, int height, uint8_t *y, int ystride, uint8_t *u, int ustride, uint8_t *v, int vstride):
     106        self.width = width
     107        self.height = height
     108        self.ystride = ystride
     109        self.ustride = ustride
     110        self.vstride = vstride
     111        self.y = self.copy(y, height * ystride)
     112        self.u = self.copy(u, height * ustride)
     113        self.v = self.copy(v, height * vstride)
     114
     115    cdef free(self):                        #@DuplicatedSignature
     116        xmemfree(self.y)
     117        xmemfree(self.u)
     118        xmemfree(self.v)
     119        self.y = NULL
     120        self.u = NULL
     121        self.v = NULL
     122
     123    def get_component(self, index):
     124        #PyString_FromStringAndSize
     125        if index==0:
     126            return (<char *> self.y)[:self.height * self.ystride]
     127        elif index==1:
     128            return (<char *> self.u)[:self.height * self.ustride]
     129        elif index==2:
     130            return (<char *> self.v)[:self.height * self.vstride]
     131        else:
     132            raise Exception("invalid component index %s" % index)
     133
     134    def get_rowstride(self, index):         #@DuplicatedSignature
     135        if index==0:
     136            return self.ystride
     137        elif index==1:
     138            return self.ustride
     139        elif index==2:
     140            return self.vstride
     141        else:
     142            raise Exception("invalid component index %s" % index)
     143
     144    def __dealloc__(self):                  #@DuplicatedSignature
     145        self.free()
     146
     147
    85148cdef class Decoder(xcoder):
    86149
    87150    def init_context(self, width, height, use_swscale, options):
     
    104167        PyObject_AsReadBuffer(input, <const_void_pp> &buf, &buf_len)
    105168        i = decompress_image(self.context, buf, buf_len, &dout, &outsize, &outstrides)
    106169        if i!=0:
    107             return i, [0, 0, 0], ["", "", ""]
    108         doutvY = (<char *>dout[0])[:self.height * outstrides[0]]
    109         doutvU = (<char *>dout[1])[:self.height * outstrides[1]]
    110         doutvV = (<char *>dout[2])[:self.height * outstrides[2]]
    111         out = [doutvY, doutvU, doutvV]
    112         strides = [outstrides[0], outstrides[1], outstrides[2]]
    113         return  i, strides, out
     170            return i, None
     171        yuv = YUVImage()
     172        yuv.init(self.width, self.height, dout[0], outstrides[0], dout[1], outstrides[1], dout[2], outstrides[2])
     173        return 0, yuv
    114174
    115175    def get_pixel_format(self, csc_pixel_format):
    116176        #we only support 420 at present
  • xpra/x264/codec.pyx

     
    115115    def __dealloc__(self):                  #@DuplicatedSignature
    116116        self.free()
    117117
     118cdef class YUVImage:
     119    cdef uint8_t *y
     120    cdef uint8_t *u
     121    cdef uint8_t *v
     122    cdef int ystride
     123    cdef int ustride
     124    cdef int vstride
     125    cdef int width                          #@DuplicatedSignature
     126    cdef int height                         #@DuplicatedSignature
    118127
     128    cdef uint8_t* copy(self, uint8_t *src, long size):
     129        cdef uint8_t *dst
     130        dst = <uint8_t*> xmemalign(size)
     131        assert dst!=NULL, "xmemalign failed for %s bytes" % size
     132        memcpy(dst, src, size)
     133        return dst
     134
     135    cdef init(self, int width, int height, uint8_t *y, int ystride, uint8_t *u, int ustride, uint8_t *v, int vstride):
     136        self.width = width
     137        self.height = height
     138        self.ystride = ystride
     139        self.ustride = ustride
     140        self.vstride = vstride
     141        self.y = self.copy(y, height * ystride)
     142        self.u = self.copy(u, height * ustride)
     143        self.v = self.copy(v, height * vstride)
     144
     145    cdef free(self):                        #@DuplicatedSignature
     146        xmemfree(self.y)
     147        xmemfree(self.u)
     148        xmemfree(self.v)
     149        self.y = NULL
     150        self.u = NULL
     151        self.v = NULL
     152
     153    def get_component(self, index):
     154        #doutvY = (<char *>dout[0])[:self.height * outstrides[0]]
     155        if index==0:
     156            return (<char *> self.y)[:self.height * self.ystride]
     157        elif index==1:
     158            return (<char *> self.u)[:self.height * self.ustride]
     159        elif index==2:
     160            return (<char *> self.v)[:self.height * self.vstride]
     161        else:
     162            raise Exception("invalid component index %s" % index)
     163
     164    def get_rowstride(self, index):         #@DuplicatedSignature
     165        if index==0:
     166            return self.ystride
     167        elif index==1:
     168            return self.ustride
     169        elif index==2:
     170            return self.vstride
     171        else:
     172            raise Exception("invalid component index %s" % index)
     173
     174    def __dealloc__(self):                  #@DuplicatedSignature
     175        self.free()
     176
     177
    119178cdef class Decoder(xcoder):
    120179
    121180    def init_context(self, width, height, use_swscale, options):
     
    138197        PyObject_AsReadBuffer(input, <const_void_pp> &buf, &buf_len)
    139198        padded_buf = <unsigned char *> xmemalign(buf_len+32)
    140199        if padded_buf==NULL:
    141             return 1, [0, 0, 0], ["", "", ""]
     200            return 100, None
    142201        memcpy(padded_buf, buf, buf_len)
    143202        memset(padded_buf+buf_len, 0, 32)
    144203        set_decoder_csc_format(self.context, int(options.get("csc_pixel_format", -1)))
     
    147206            i = decompress_image(self.context, padded_buf, buf_len, &dout, &outstrides)
    148207        xmemfree(padded_buf)
    149208        if i!=0:
    150             return i, [0, 0, 0], ["", "", ""]
    151         doutvY = (<char *>dout[0])[:self.height * outstrides[0]]
    152         doutvU = (<char *>dout[1])[:self.height * outstrides[1]]
    153         doutvV = (<char *>dout[2])[:self.height * outstrides[2]]
    154         out = [doutvY, doutvU, doutvV]
    155         strides = [outstrides[0], outstrides[1], outstrides[2]]
    156         return  i, strides, out
     209            return i, None
     210        yuv = YUVImage()
     211        yuv.init(self.width, self.height, dout[0], outstrides[0], dout[1], outstrides[1], dout[2], outstrides[2])
     212        return 0, yuv
    157213
    158214    def get_pixel_format(self, csc_pixel_format):
    159215        return get_pixel_format(csc_pixel_format)