[Sumover-dev] [svn commit] r3806 - vic/trunk/codec

sumover-dev at cs.ucl.ac.uk sumover-dev at cs.ucl.ac.uk
Wed Sep 6 03:37:52 BST 2006


Author: rhys
Date: Wed Sep  6 03:38:03 2006
New Revision: 3806

Modified:
   vic/trunk/codec/decoder-dv.cpp

Log:

Fixed problems with dv decoder. Now can get image in VIC although
packet loss is too high for it to be any use.



Modified: vic/trunk/codec/decoder-dv.cpp
==============================================================================
--- vic/trunk/codec/decoder-dv.cpp	(original)
+++ vic/trunk/codec/decoder-dv.cpp	Wed Sep  6 03:38:03 2006
@@ -11,6 +11,22 @@
 
 #include <libdv/dv.h>
 
+/*
+ * libdv does either yv12 or yuyv and this is determined at
+ * libdv's compile time. There is no way programatically to 
+ * check this, so we use the following #define depending on
+ * how libdv is compiled. A segfault is likely if libdv 
+ * produces yuy2 and this code assumes yv12 and visa-versa.
+ */
+
+#define ASSUME_YUY2 1
+#if ASSUME_YUY2 == 1
+static void yuy2_to_i420(const u_char *in,
+			 u_int width,
+			 u_int height,
+			 u_char *out);
+#endif // ASSUME_YUY2
+
 class DVDecoder : public Decoder {
     public:
 	DVDecoder();
@@ -28,6 +44,10 @@
 
         u_char *dv_frame;
 
+#if ASSUME_YUY2 == 1
+	u_char *dv_yuy2_frame;
+#endif 
+
         bool header_received;
         bool headers_received[12];
         bool vaux_received[12];
@@ -61,6 +81,9 @@
 			 dv_decoder(0), 
 			 dv_buffer(new u_char[144000]), 
 			 dv_frame(new u_char[(DV_WIDTH * DV_PAL_HEIGHT * 3)/2]), 
+#if ASSUME_YUY2 == 1
+			 dv_yuy2_frame(new u_char[DV_WIDTH * DV_PAL_HEIGHT * 2]),
+#endif 
 			 header_received(false),
 			 difblocks(0)
 {
@@ -72,12 +95,6 @@
 	stat_[STAT_BAD_HEADER].name = "H261-Bad-Header";
 	nstat_ = 6;
 
-	/*
-         * libdv does either yv12 or yuyv and this is determined at
-	 * libdv's compile time. There is no way programatically to 
-	 * check this, so the default of yv12 is assumed. yv12 is the
-	 * same as i420 but with the u and v planes swapped.
-	 */
 	decimation_ = 411;
 
 	/*
@@ -100,6 +117,9 @@
 
 	memset(dv_buffer, 0, 144000);
 	memset(dv_frame, 127, (DV_WIDTH * DV_PAL_HEIGHT * 3)/2);
+#if ASSUME_YUY2 == 1
+	memset(dv_yuy2_frame, 127, DV_WIDTH * DV_PAL_HEIGHT * 2);
+#endif 
 }
 
 DVDecoder::~DVDecoder()
@@ -217,6 +237,29 @@
 				        break;
 				}
 
+#if ASSUME_YUY2 == 1
+				unsigned char *pixels[3];
+				int pitches[3];
+
+				pixels[0] = dv_yuy2_frame;
+				pixels[1] = 0;
+				pixels[2] = 0;
+
+				pitches[0] = inw_*2;
+				pitches[1] = 0;
+				pitches[2] = 0;
+
+ 				dv_decode_full_frame(dv_decoder,
+ 						     (const uint8_t*)dv_buffer,
+ 						     e_dv_color_yuv,
+ 						     pixels,
+ 						     pitches);
+
+				yuy2_to_i420(dv_yuy2_frame,
+					     inw_,
+					     inh_,
+					     dv_frame);
+#else				
 				unsigned char *pixels[3];
 				int pitches[3];
 
@@ -225,11 +268,17 @@
 				pixels[1] = dv_frame + (inh_ * inw_ * 5)/4;
 				pixels[2] = dv_frame + (inh_ * inw_);
 
-				dv_decode_full_frame(dv_decoder,
-						     (const uint8_t*)dv_buffer,
-						     e_dv_color_yuv,
-						     pixels,
-						     pitches);
+				pitches[0] = inw_;
+				pitches[1] = inw_/2;
+				pitches[2] = inw_/2;
+
+				printf("decoding yv12\n");
+// 				dv_decode_full_frame(dv_decoder,
+// 						     (const uint8_t*)dv_buffer,
+// 						     e_dv_color_yuv,
+// 						     pixels,
+// 						     pitches);
+#endif // ASSUME_YUY2
 				
 				render_frame(dv_frame);
 			}
@@ -244,4 +293,49 @@
         Decoder::redraw(dv_frame);
 }
 
+static void yuy2_to_i420(const u_char *in,
+			 u_int width,
+			 u_int height,
+			 u_char *out)
+{
+  const u_char *_in[2];
+  u_int in_rowstride = width * 2;
+    
+
+  u_char *out_y[2];
+  u_char *out_u;
+  u_char *out_v;
+
+  u_int half_width = width/2;
+  u_int half_height = height/2;
+
+  _in[0] = in;
+  _in[1] = in + in_rowstride;
+
+  out_y[0] = out;
+  out_y[1] = out + width;
+  out_u = out + width * height;
+  out_v = out + (width * height * 5)/4;
+
+  for (u_int j = 0; j < half_height; j ++) {
+    for (u_int i = 0; i < half_width; i ++, _in[0] += 4, _in[1] += 4, out_y[0] += 2, out_y[1] += 2, out_u ++, out_v ++) {
+
+      out_y[0][0] = _in[0][0];
+      out_y[0][1] = _in[0][2];
+
+      out_y[1][0] = _in[1][0];
+      out_y[1][1] = _in[1][2];
+
+      *out_u = _in[0][1];
+      *out_v = _in[0][3];
+    }
+     _in[0] += in_rowstride;
+     _in[1] += in_rowstride;
+
+     out_y[0] += width;
+     out_y[1] += width;
+  }
+}
+
 #endif // USE_DVDECODER
+



More information about the Sumover-dev mailing list