Ticket #229: gl-yuv-cython-fix.patch
File gl-yuv-cython-fix.patch, 8.4 KB (added by , 9 years ago) |
---|
-
xpra/gl/gl_window_backing.py
128 128 glFlush() 129 129 drawable.gl_end() 130 130 131 def cairo_draw(self, context): 132 drawable = self.gl_init() 133 if drawable: 134 try: 135 self.do_cairo_draw(context, drawable) 136 finally: 137 self.gl_end(drawable) 138 131 139 def gl_expose_event(self, glarea, event): 132 140 debug("gl_expose_event(%s, %s)", glarea, event) 133 141 area = event.area … … 146 154 147 155 def do_video_paint(self, coding, img_data, x, y, w, h, options, callbacks): 148 156 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)157 YUVImage = self._video_decoder.decompress_image_to_yuv(img_data, options) 150 158 csc_pixel_format = options.get("csc_pixel_format", -1) 151 159 #this needs to be done here so we still hold the video_decoder lock: 152 160 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: 155 log.error("do_video_paint: %s decompression error %s on %s bytes of picture data for %sx%s pixels, options=%s", 156 coding, err, len(img_data), w, h, options) 161 if YUVImage is None: 162 log.error("do_video_paint: %s decompression error on %s bytes of picture data for %sx%s pixels, options=%s", 163 coding, len(img_data), w, h, options) 157 164 gobject.idle_add(fire_paint_callbacks, callbacks, False) 158 165 return 159 gobject.idle_add(self.do_gl_paint, x, y, w, h, img_data, rowstrides, pixel_format, callbacks)166 gobject.idle_add(self.do_gl_paint, x, y, w, h, YUVImage, pixel_format, callbacks) 160 167 161 def do_gl_paint(self, x, y, w, h, img_data, rowstrides, pixel_format, callbacks):168 def do_gl_paint(self, x, y, w, h, YUVImage, pixel_format, callbacks): 162 169 #this function runs in the UI thread, no video_decoder lock held 163 170 drawable = self.gl_init() 164 171 if not drawable: … … 167 174 return 168 175 try: 169 176 try: 170 self.update_texture_yuv( img_data, x, y, w, h, rowstrides, pixel_format)177 self.update_texture_yuv(YUVImage, x, y, w, h, pixel_format) 171 178 if self.paint_screen: 172 179 self.render_image(x, y, x+w, y+h) 173 180 fire_paint_callbacks(callbacks, True) … … 189 196 return (1, 1), (1, 1), (1, 1) 190 197 raise Exception("invalid pixel format: %s" % pixel_format) 191 198 192 def update_texture_yuv(self, img_data, x, y, width, height, rowstrides, pixel_format):199 def update_texture_yuv(self, YUVImage, x, y, width, height, pixel_format): 193 200 window_width, window_height = self.size 194 201 assert self.textures is not None, "no OpenGL textures!" 195 202 … … 238 245 (div_w, div_h) = divs[index] 239 246 glActiveTexture(texture) 240 247 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]) 248 rowstride = YUVImage.get_rowstride(index) 249 glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstride) 250 pixel_data = YUVImage.get_component(index) 251 glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, x, y, width/div_w, height/div_h, GL_LUMINANCE, GL_UNSIGNED_BYTE, pixel_data) 243 252 if index == 1: 244 253 U_width = width/div_w 245 254 U_height = height/div_h … … 248 257 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) 249 258 if height/div_h != U_height: 250 259 log.error("Height of V plane is %d, differs from height of corresponding U plane (%d)", height/div_h, U_height) 260 del YUVImage 251 261 252 262 def render_image(self, rx, ry, rw, rh): 253 263 debug("render_image %sx%s at %sx%s pixel_format=%s", rw, rh, rx, ry, self.pixel_format) -
xpra/vpx/codec.pyx
6 6 import os 7 7 from libc.stdlib cimport free 8 8 9 cdef 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 9 13 cdef extern from "Python.h": 10 14 ctypedef int Py_ssize_t 11 15 ctypedef object PyObject … … 81 85 def __dealloc__(self): #@DuplicatedSignature 82 86 self.free() 83 87 88 cdef 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 height 84 96 97 cdef uint8_t* copy(self, uint8_t *src, long size): 98 cdef uint8_t *dst 99 dst = <uint8_t*> xmemalign(size+1024) 100 memcpy(dst, src, size) 101 return dst 102 103 cdef init(self, uint8_t *y, int ystride, uint8_t *u, int ustride, uint8_t *v, int vstride, int height): 104 print("new YUVImage(%s, %s, %s, %s)" % (ystride, ustride, vstride, height)) 105 self.height = height 106 self.ystride = ystride 107 self.ustride = ustride 108 self.vstride = vstride 109 self.y = self.copy(y, height * ystride) 110 self.u = self.copy(u, height * ustride) 111 self.v = self.copy(v, height * vstride) 112 print("new YUVImage(%s, %s, %s, %s) done" % (ystride, ustride, vstride, height)) 113 114 cdef free(self): #@DuplicatedSignature 115 print("YUVImage.free()") 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 #doutvY = (<char *>dout[0])[:self.height * outstrides[0]] 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 85 148 cdef class Decoder(xcoder): 86 149 87 150 def init_context(self, width, height, use_swscale, options): … … 104 167 PyObject_AsReadBuffer(input, <const_void_pp> &buf, &buf_len) 105 168 i = decompress_image(self.context, buf, buf_len, &dout, &outsize, &outstrides) 106 169 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 None 171 yuv = YUVImage() 172 yuv.init(dout[0], outstrides[0], dout[1], outstrides[1], dout[2], outstrides[2], self.height) 173 return yuv 114 174 115 175 def get_pixel_format(self, csc_pixel_format): 116 176 #we only support 420 at present -
xpra/window_backing.py
174 174 175 175 176 176 def cairo_draw(self, context): 177 self.do_cairo_draw(context, self._backing) 178 179 def do_cairo_draw(self, context, drawable): 177 180 try: 178 context.set_source_pixmap( self._backing, 0, 0)181 context.set_source_pixmap(drawable, 0, 0) 179 182 context.set_operator(cairo.OPERATOR_SOURCE) 180 183 context.paint() 181 184 return True