def update_texture_yuv(self, img_data, x, y, width, height, rowstrides, pixel_format): assert x==0 and y==0 assert self.textures is not None, "no OpenGL textures!" if self.pixel_format is None or self.pixel_format!=pixel_format or self.texture_size!=(width, height): self.pixel_format = pixel_format self.texture_size = (width, height) divs = get_subsampling_divs(pixel_format) debug("GL creating new YUV textures for pixel format %s using divs=%s", pixel_format, divs) self.gl_marker("Creating new YUV textures") # Create textures of the same size as the window's glEnable(GL_TEXTURE_RECTANGLE_ARB) for texture, index in ((GL_TEXTURE0, 0), (GL_TEXTURE1, 1), (GL_TEXTURE2, 2)): (div_w, div_h) = divs[index] glActiveTexture(texture) glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[index]) glEnable(GL_TEXTURE_RECTANGLE_ARB) mag_filter = GL_NEAREST if div_w > 1 or div_h > 1: mag_filter = GL_LINEAR glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, mag_filter) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, width/div_w, height/div_h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0) debug("Assigning fragment program") glEnable(GL_FRAGMENT_PROGRAM_ARB) if not self.yuv_shader: self.yuv_shader = [ 1 ] glGenProgramsARB(1, self.yuv_shader) glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, self.yuv_shader[0]) prog = GL_COLORSPACE_CONVERSIONS glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, len(prog), prog) err = glGetString(GL_PROGRAM_ERROR_STRING_ARB) if err: #FIXME: maybe we should do something else here? log.error(err) self.gl_marker("Updating YUV textures") divs = get_subsampling_divs(pixel_format) U_width = 0 U_height = 0 for texture, index in ((GL_TEXTURE0, 0), (GL_TEXTURE1, 1), (GL_TEXTURE2, 2)): (div_w, div_h) = divs[index] glActiveTexture(texture) glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[index]) glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstrides[index]) glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, x, y, width/div_w, height/div_h, GL_LUMINANCE, GL_UNSIGNED_BYTE, img_data[index]) if index == 1: U_width = width/div_w U_height = height/div_h elif index == 2: if width/div_w != U_width: 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) if height/div_h != U_height: log.error("Height of V plane is %d, differs from height of corresponding U plane (%d)", height/div_h, U_height)
def render_yuv_update(self, rx, ry, rw, rh): debug("render_yuv_update %sx%s at %sx%s pixel_format=%s", rw, rh, rx, ry, self.pixel_format) if self.pixel_format not in (YUV420P, YUV422P, YUV444P): #not ready to render yet return self.gl_marker("Painting YUV update") divs = get_subsampling_divs(self.pixel_format) glEnable(GL_FRAGMENT_PROGRAM_ARB) glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, self.yuv_shader[0]) for texture, index in ((GL_TEXTURE0, 0), (GL_TEXTURE1, 1), (GL_TEXTURE2, 2)): glActiveTexture(texture) glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[index]) tw, th = self.texture_size debug("render_yuv_update texture_size=%s, size=%s", self.texture_size, self.size) glBegin(GL_QUADS) for x, y in ((rx, ry), (rx, ry + rh), (rx + rw, ry + rh), (rx + rw, ry)): ax = min(tw, x) ay = min(th, y) for texture, index in ((GL_TEXTURE0, 0), (GL_TEXTURE1, 1), (GL_TEXTURE2, 2)): (div_w, div_h) = divs[index] glMultiTexCoord2i(texture, ax / div_w, ay / div_h) glVertex2i(ax, ay) glEnd()
def render_yuv_update(self, rx, ry, rw, rh): debug("render_yuv_update %sx%s at %sx%s pixel_format=%s", rw, rh, rx, ry, self.pixel_format) if self.pixel_format not in (YUV420P, YUV422P, YUV444P): #not ready to render yet return self.gl_marker("Painting YUV update") divs = get_subsampling_divs(self.pixel_format) glEnable(GL_FRAGMENT_PROGRAM_ARB) glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, self.yuv_shader[0]) for texture, index in ((GL_TEXTURE0, 0), (GL_TEXTURE1, 1), (GL_TEXTURE2, 2)): glActiveTexture(texture) glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[index]) tw, th = self.texture_size debug("render_yuv_update texture_size=%s, size=%s", self.texture_size, self.size) glBegin(GL_QUADS) for x,y in ((rx, ry), (rx, ry+rh), (rx+rw, ry+rh), (rx+rw, ry)): ax = min(tw, x) ay = min(th, y) for texture, index in ((GL_TEXTURE0, 0), (GL_TEXTURE1, 1), (GL_TEXTURE2, 2)): (div_w, div_h) = divs[index] glMultiTexCoord2i(texture, ax/div_w, ay/div_h) glVertex2i(ax, ay) glEnd()
def update_texture_yuv(self, img_data, x, y, width, height, rowstrides, pixel_format): assert x == 0 and y == 0 assert self.textures is not None, "no OpenGL textures!" if self.pixel_format is None or self.pixel_format != pixel_format or self.texture_size != ( width, height): self.pixel_format = pixel_format self.texture_size = (width, height) divs = get_subsampling_divs(pixel_format) debug( "GL creating new YUV textures for pixel format %s using divs=%s", pixel_format, divs) self.gl_marker("Creating new YUV textures") # Create textures of the same size as the window's glEnable(GL_TEXTURE_RECTANGLE_ARB) for texture, index in ((GL_TEXTURE0, 0), (GL_TEXTURE1, 1), (GL_TEXTURE2, 2)): (div_w, div_h) = divs[index] glActiveTexture(texture) glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[index]) glEnable(GL_TEXTURE_RECTANGLE_ARB) mag_filter = GL_NEAREST if div_w > 1 or div_h > 1: mag_filter = GL_LINEAR glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, mag_filter) glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, width / div_w, height / div_h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0) debug("Assigning fragment program") glEnable(GL_FRAGMENT_PROGRAM_ARB) if not self.yuv_shader: self.yuv_shader = [1] glGenProgramsARB(1, self.yuv_shader) glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, self.yuv_shader[0]) prog = GL_COLORSPACE_CONVERSIONS glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, len(prog), prog) err = glGetString(GL_PROGRAM_ERROR_STRING_ARB) if err: #FIXME: maybe we should do something else here? log.error(err) self.gl_marker("Updating YUV textures") divs = get_subsampling_divs(pixel_format) U_width = 0 U_height = 0 for texture, index in ((GL_TEXTURE0, 0), (GL_TEXTURE1, 1), (GL_TEXTURE2, 2)): (div_w, div_h) = divs[index] glActiveTexture(texture) glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[index]) glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstrides[index]) glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, x, y, width / div_w, height / div_h, GL_LUMINANCE, GL_UNSIGNED_BYTE, img_data[index]) if index == 1: U_width = width / div_w U_height = height / div_h elif index == 2: if width / div_w != U_width: 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) if height / div_h != U_height: log.error( "Height of V plane is %d, differs from height of corresponding U plane (%d)", height / div_h, U_height)