Skip to content

Commit

Permalink
client GL: fix 422 CSC rendering
Browse files Browse the repository at this point in the history
Texture dividers were set up incorrectly and we were trying to render U and V textures with different sizes. The numbers is "420" "422" mean "reference, horizontal sampling frequency, vertical sampling frequency", not "Y frequency, U frequency, V frequency". Both chroma planes have the same dimensions in all cases.

git-svn-id: https://xpra.org/svn/Xpra/trunk@2949 3bb7dfac-3a0b-4e04-842a-767bc560f471
  • Loading branch information
Arthur Huillet committed Mar 13, 2013
1 parent dcf48fe commit 8af8a7c
Showing 1 changed file with 22 additions and 10 deletions.
32 changes: 22 additions & 10 deletions src/xpra/gl/gl_window_backing.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,12 +181,14 @@ def do_gl_paint(self, x, y, w, h, img_data, rowstrides, pixel_format, callbacks)


def get_subsampling_divs(self, pixel_format):
# Return size dividers for the given pixel format
# (Y_w, Y_h), (U_w, U_h), (V_w, V_h)
if pixel_format==YUV420P:
return 1, 2, 2
return (1, 1), (2, 2), (2, 2)
elif pixel_format==YUV422P:
return 1, 2, 1
return (1, 1), (2, 1), (2, 1)
elif pixel_format==YUV444P:
return 1, 1, 1
return (1, 1), (1, 1), (1, 1)
raise Exception("invalid pixel format: %s" % pixel_format)

def update_texture_yuv(self, img_data, x, y, width, height, rowstrides, pixel_format):
Expand All @@ -201,16 +203,16 @@ def update_texture_yuv(self, img_data, x, y, width, height, rowstrides, pixel_fo
glEnable(GL_TEXTURE_RECTANGLE_ARB)

for texture, index in ((GL_TEXTURE0, 0), (GL_TEXTURE1, 1), (GL_TEXTURE2, 2)):
div = divs[index]
(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>1:
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, window_width/div, window_height/div, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0)
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, window_width/div_w, window_height/div_h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0)

debug("Assigning fragment program")
glEnable(GL_FRAGMENT_PROGRAM_ARB)
Expand All @@ -232,12 +234,22 @@ def update_texture_yuv(self, img_data, x, y, width, height, rowstrides, pixel_fo
height = window_height - y

divs = self.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 = divs[index]
(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, height/div, GL_LUMINANCE, GL_UNSIGNED_BYTE, img_data[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)
glFlush()

def render_image(self, rx, ry, rw, rh):
Expand All @@ -255,8 +267,8 @@ def render_image(self, rx, ry, rw, rh):
glBegin(GL_QUADS)
for x,y in ((rx, ry), (rx, ry+rh), (rx+rw, ry+rh), (rx+rw, ry)):
for texture, index in ((GL_TEXTURE0, 0), (GL_TEXTURE1, 1), (GL_TEXTURE2, 2)):
div = divs[index]
glMultiTexCoord2i(texture, x/div, y/div)
(div_w, div_h) = divs[index]
glMultiTexCoord2i(texture, x/div_w, y/div_h)
glVertex2i(x, y)
glEnd()
glFlush()

0 comments on commit 8af8a7c

Please sign in to comment.