Theora video: broken colour handling

Darren Salt <[email protected]> Wed, 18 Sep 2013 23:32:48 +0100
Newsgroups gmane.comp.video.xine.devel
Message-ID <5392C012B0%[email protected]>
http://bugs.debian.org/723627 – bug report about an Ogg Theora video. Issue
is broken colour handling.

http://bugs.debian.org/cgi-bin/bugreport.cgi?msg=5;filename=bug-gxine-20130918.ogv;att=1;bug=723627

That file shows a rendering bug: the Theora decoder assumes that the video is
YV12 but this one is, according to mplayer (which displays it without
problem), yuv444p.

A proof-of-concept patch which fixes this is attached. I won't be applying
it, though, since it may break playback of other video files and there are
better ways of converting the colour information.

If anybody wants to write a proper patch to fix this, by all means...

-- 
|  _  | Darren Salt, using Debian GNU/Linux (and Android)
| ( ) |
|  X  | ASCII Ribbon campaign against HTML e-mail
| / \ | http://www.asciiribbon.org/

team player: n. one who shuts up and does as told but knows that it's wrong.

------------------------------------------------------------------------------
LIMITED TIME SALE - Full Year of Microsoft Training For Just $49.99!
1,500+ hours of tutorials including VisualStudio 2012, Windows 8, SharePoint
2013, SQL 2012, MVC 4, more. BEST VALUE: New Multi-Library Power Pack includes
Mobile, Cloud, Java, and UX Design. Lowest price ever! Ends 9/20/13. 
http://pubads.g.doubleclick.net/gampad/clk?id=58041151&iu=/4140/ostg.clktrk

_______________________________________________
xine-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/xine-devel
theora.patch (application/octet-stream, 1.1 KB)
diff --git a/src/combined/xine_theora_decoder.c b/src/combined/xine_theora_decoder.c
--- a/src/combined/xine_theora_decoder.c
+++ b/src/combined/xine_theora_decoder.c
@@ -107,6 +107,27 @@ static void yuv2frame(yuv_buffer *yuv, v
 
   crop_offset=(offset_x/2)+(yuv->uv_stride)*(offset_y/2);
   for(i=0;i<frame->height/2;i++){
+    int j, w;
+    unsigned char *dst, *src;
+
+    w = frame->width / 2;
+
+    src = yuv->u + crop_offset + yuv->uv_stride * i * 2;
+    dst = frame->base[1] + frame->pitches[1] * i;
+    for (j = 0; j < w; ++j)
+    {
+      *dst++ = (src[0] + src[1]) / 2;
+      src += 2;
+    }
+
+    src = yuv->v + crop_offset + yuv->uv_stride * i * 2;
+    dst = frame->base[2] + frame->pitches[2] * i;
+    for (j = 0; j < w; ++j)
+    {
+      *dst++ = (src[0] + src[1]) / 2;
+      src += 2;
+    }
+/*
     xine_fast_memcpy(frame->base[1]+frame->pitches[1]*i,
 		     yuv->u+crop_offset+yuv->uv_stride*i,
 		     frame->width/2);
@@ -114,6 +135,7 @@ static void yuv2frame(yuv_buffer *yuv, v
 		     yuv->v+crop_offset+yuv->uv_stride*i,
 		     frame->width/2);
 
+*/
   }
 }