From: hschang Date: Tue, 17 Mar 2015 09:34:16 +0000 (+0900) Subject: [dvbmediasink] Remove WMV patch. X-Git-Url: http://code.vuplus.com/gitweb/?p=vuplus_openvuplus_3.0;a=commitdiff_plain;h=9efcbdc1ab9b560da84765907eecc22620e0dfcd [dvbmediasink] Remove WMV patch. --- diff --git a/meta-openvuplus/recipes-multimedia/gstreamer1.0/gstreamer1.0-plugin-dvbmediasink.bbappend b/meta-openvuplus/recipes-multimedia/gstreamer1.0/gstreamer1.0-plugin-dvbmediasink.bbappend index 52ea114..fe30104 100644 --- a/meta-openvuplus/recipes-multimedia/gstreamer1.0/gstreamer1.0-plugin-dvbmediasink.bbappend +++ b/meta-openvuplus/recipes-multimedia/gstreamer1.0/gstreamer1.0-plugin-dvbmediasink.bbappend @@ -2,10 +2,9 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" SRC_URI += "\ file://gstreamer10_dvbmediasink_vuplus.patch \ - file://gstreamer10_dvbmediasink_vuplus_wmv.patch \ " -PR .= "-vuplus0" +PR .= "-vuplus1" DVBMEDIASINK_CONFIG = "--with-wmv --with-pcm --with-eac3" diff --git a/meta-openvuplus/recipes-multimedia/gstreamer1.0/gstreamer1.0-plugin-dvbmediasink/gstreamer10_dvbmediasink_vuplus.patch b/meta-openvuplus/recipes-multimedia/gstreamer1.0/gstreamer1.0-plugin-dvbmediasink/gstreamer10_dvbmediasink_vuplus.patch index 6cd49bf..64fef32 100644 --- a/meta-openvuplus/recipes-multimedia/gstreamer1.0/gstreamer1.0-plugin-dvbmediasink/gstreamer10_dvbmediasink_vuplus.patch +++ b/meta-openvuplus/recipes-multimedia/gstreamer1.0/gstreamer1.0-plugin-dvbmediasink/gstreamer10_dvbmediasink_vuplus.patch @@ -150,24 +150,6 @@ index a6b0a10..903432c 100644 break; } -@@ -614,6 +625,8 @@ static int video_write(GstBaseSink *sink, GstDVBVideoSink *self, GstBuffer *buff - } - else if (evt.type == VIDEO_EVENT_FRAME_RATE_CHANGED) - { -+ self->framerate = evt.u.frame_rate; -+ GST_INFO_OBJECT(self, "decoder framerate %d", self->framerate); - s = gst_structure_new ("eventFrameRateChanged", - "frame_rate", G_TYPE_INT, evt.u.frame_rate, NULL); - msg = gst_message_new_element (GST_OBJECT(sink), s); -@@ -1289,6 +1302,8 @@ static gboolean gst_dvbvideosink_set_caps(GstBaseSink *basesink, GstCaps *caps) - GstStructure *structure = gst_caps_get_structure (caps, 0); - const char *mimetype = gst_structure_get_name (structure); - self->stream_type = STREAMTYPE_UNKNOWN; -+ self->framerate = -1; -+ self->no_header = 0; - - GST_INFO_OBJECT (self, "caps = %" GST_PTR_FORMAT, caps); - @@ -1557,6 +1572,10 @@ static gboolean gst_dvbvideosink_set_caps(GstBaseSink *basesink, GstCaps *caps) gst_buffer_ref (self->codec_data); } @@ -179,21 +161,3 @@ index a6b0a10..903432c 100644 break; case 6: case 5: -@@ -1622,10 +1641,17 @@ static gboolean gst_dvbvideosink_set_caps(GstBaseSink *basesink, GstCaps *caps) - best = i; - } - } -+ self->framerate = valid_framerates[best]; -+ -+ GST_INFO_OBJECT(self, "framerate %d", self->framerate); -+ - fprintf(f, "%d", valid_framerates[best]); - fclose(f); - } - } -+ else if (self->framerate == -1) -+ GST_INFO_OBJECT(self, "no framerate given!"); -+ - if (self->playing) - { - if (self->fd >= 0) ioctl(self->fd, VIDEO_STOP, 0); diff --git a/meta-openvuplus/recipes-multimedia/gstreamer1.0/gstreamer1.0-plugin-dvbmediasink/gstreamer10_dvbmediasink_vuplus_wmv.patch b/meta-openvuplus/recipes-multimedia/gstreamer1.0/gstreamer1.0-plugin-dvbmediasink/gstreamer10_dvbmediasink_vuplus_wmv.patch deleted file mode 100644 index 3a32a5a..0000000 --- a/meta-openvuplus/recipes-multimedia/gstreamer1.0/gstreamer1.0-plugin-dvbmediasink/gstreamer10_dvbmediasink_vuplus_wmv.patch +++ /dev/null @@ -1,791 +0,0 @@ -diff --git a/gstdvbvideosink.c b/gstdvbvideosink.c -index 903432c..dd31dc7 100644 ---- a/gstdvbvideosink.c -+++ b/gstdvbvideosink.c -@@ -150,6 +150,16 @@ void bitstream_put(struct bitstream *bit, unsigned long val, int bits) - } - #endif - -+static unsigned int Vc1ParseSeqHeader( GstDVBVideoSink *self, struct bitstream *bit ); -+static unsigned int Vc1ParseEntryPointHeader( GstDVBVideoSink *self, struct bitstream *bit ); -+static unsigned char Vc1GetFrameType( GstDVBVideoSink *self, struct bitstream *bit ); -+static unsigned char Vc1GetBFractionVal( GstDVBVideoSink *self, struct bitstream *bit ); -+static unsigned char Vc1GetNrOfFramesFromBFractionVal( unsigned char ucBFVal ); -+static unsigned char Vc1HandleStreamBuffer( GstDVBVideoSink *self, unsigned char *data, int flags ); -+ -+#define cVC1NoBufferDataAvailable 0 -+#define cVC1BufferDataAvailable 1 -+ - GST_DEBUG_CATEGORY_STATIC (dvbvideosink_debug); - #define GST_CAT_DEFAULT dvbvideosink_debug - -@@ -338,6 +348,7 @@ static void gst_dvbvideosink_init(GstDVBVideoSink *self) - self->num_non_keyframes = 0; - self->prev_frame = NULL; - #endif -+ - #if GST_VERSION_MAJOR >= 1 - self->use_dts = FALSE; - #endif -@@ -351,6 +362,17 @@ static void gst_dvbvideosink_init(GstDVBVideoSink *self) - self->saved_fallback_framerate[0] = 0; - self->rate = 1.0; - -+ self->ucPrevFramePicType = 0; -+ self->ucVC1_PULLDOWN = 0; -+ self->ucVC1_INTERLACE = 0; -+ self->ucVC1_TFCNTRFLAG = 0; -+ self->ucVC1_FINTERPFLAG = 0; -+ self->ucVC1_PSF = 0; -+ self->ucVC1_HRD_PARAM_FLAG = 0; -+ self->ucVC1_HRD_NUM_LEAKY_BUCKETS = 0; -+ self->ucVC1_PANSCAN_FLAG = 0; -+ self->ucVC1_REFDIST_FLAG = 0; -+ - gst_base_sink_set_sync(GST_BASE_SINK(self), FALSE); - gst_base_sink_set_async_enabled(GST_BASE_SINK(self), TRUE); - } -@@ -875,18 +897,31 @@ static GstFlowReturn gst_dvbvideosink_render(GstBaseSink *sink, GstBuffer *buffe - - if (self->codec_data) - { -+ if (self->codec_type == CT_VC1) -+ { -+ if (self->no_header && self->ucPrevFramePicType == 6) { // I-Frame... -+ GST_INFO_OBJECT(self, "send seq header"); -+ self->must_send_header = 1; -+ } -+ } - if (self->must_send_header) - { - if (self->codec_type != CT_MPEG1 && self->codec_type != CT_MPEG2 && (self->codec_type != CT_DIVX4 || data[3] == 0x00)) - { -+ unsigned char *_codec_data = codec_data; -+ unsigned int _codec_data_size = codec_data_size; -+ if (self->codec_type == CT_VC1) { -+ _codec_data += 1; -+ _codec_data_size -= 1; -+ } - if (self->codec_type == CT_DIVX311) - { - video_write(sink, self, self->codec_data, 0, codec_data_size); - } - else - { -- memcpy(pes_header + pes_header_len, codec_data, codec_data_size); -- pes_header_len += codec_data_size; -+ memcpy(pes_header + pes_header_len, _codec_data, _codec_data_size); -+ pes_header_len += _codec_data_size; - } - self->must_send_header = FALSE; - } -@@ -976,6 +1011,47 @@ static GstFlowReturn gst_dvbvideosink_render(GstBaseSink *sink, GstBuffer *buffe - pes_header_len += 3; - } - } -+#if 1 -+ else if (self->codec_type == CT_VC1 || self->codec_type == CT_VC1_SM) -+ { -+ int skip_header_check; -+ -+ if (data[0] || data[1] || data[2] != 1) { -+ memcpy(pes_header+pes_header_len, "\x00\x00\x01\x0d", 4); -+ pes_header_len += 4; -+ skip_header_check = 1; -+ } -+ else -+ skip_header_check = 0; -+ -+ self->no_header = skip_header_check; -+ -+ if (self->codec_type == CT_VC1) { -+ unsigned char ucRetVal = Vc1HandleStreamBuffer( self, data, skip_header_check ); -+ if ( ucRetVal != cVC1NoBufferDataAvailable ) { -+#if GST_VERSION_MAJOR < 1 -+ data_len = GST_BUFFER_SIZE(self->prev_frame); -+ data = GST_BUFFER_DATA(self->prev_frame); -+#else -+ gst_buffer_unmap(buffer, &map); -+ gst_buffer_map(self->prev_frame, &map, GST_MAP_READ); -+ data_len = map.size; -+ data = map.data; -+#endif -+ } -+ else { -+ GST_DEBUG_OBJECT(self, "first buffer!"); -+ -+ gst_buffer_ref(buffer); -+ self->prev_frame = buffer; -+ -+ goto ok; -+ } -+ -+ cache_prev_frame = TRUE; -+ } -+ } -+#endif - else if (self->codec_type == CT_DIVX311) - { - if (memcmp(data, "\x00\x00\x01\xb6", 4)) -@@ -1204,12 +1280,6 @@ static GstFlowReturn gst_dvbvideosink_render(GstBaseSink *sink, GstBuffer *buffe - } - } - } -- else if (self->codec_type == CT_VC1 || self->codec_type == CT_VC1_SM) -- { -- memcpy(pes_header + pes_header_len, "\x00\x00\x01\x0d", 4); -- pes_header_len += 4; -- payload_len += 4; -- } - - pes_set_payload_size(payload_len, pes_header); - -@@ -1617,12 +1687,90 @@ static gboolean gst_dvbvideosink_set_caps(GstBaseSink *basesink, GstCaps *caps) - self->codec_type = CT_VC1_SM; - GST_INFO_OBJECT (self, "MIMETYPE video/x-wmv -> STREAMTYPE_VC1_SM"); - } -+ -+ if (self->codec_type == CT_VC1) -+ { -+ const GValue *codec_data = gst_structure_get_value(structure, "codec_data"); -+ if (codec_data) -+ { -+ -+ self->codec_data = gst_value_get_buffer (codec_data); -+ gst_buffer_ref (self->codec_data); -+#if GST_VERSION_MAJOR < 1 -+ Vc1HandleStreamBuffer(self, GST_BUFFER_DATA(self->codec_data)+1, 2 ); -+#else -+ GstMapInfo codec_data_map; -+ gst_buffer_map(self->codec_data, &codec_data_map, GST_MAP_READ); -+ Vc1HandleStreamBuffer(self, codec_data_map.data+1, 2 ); -+ gst_buffer_unmap(self->codec_data, &codec_data_map); -+#endif -+ -+ } -+ } -+ else if (self->codec_type == CT_VC1_SM) -+ { -+ const GValue *codec_data = gst_structure_get_value(structure, "codec_data"); -+ -+ if (codec_data) -+ { -+ /* wmv version 3 test */ -+ guint8 *codec_data_pointer, *data; -+ gint codec_size, size; -+ gint width, height; -+#if GST_VERSION_MAJOR < 1 -+ codec_size = GST_BUFFER_SIZE(gst_value_get_buffer(codec_data)); -+ codec_data_pointer = GST_BUFFER_DATA(gst_value_get_buffer(codec_data)); -+#else -+ GstMapInfo codecdatamap; -+ gst_buffer_map(gst_value_get_buffer(codec_data), &codecdatamap, GST_MAP_READ); -+ codec_data_pointer = codecdatamap.data; -+ codec_size = codecdatamap.size; -+#endif -+ if (codec_size > 4) codec_size = 4; -+ gst_structure_get_int(structure, "width", &width); -+ gst_structure_get_int(structure, "height", &height); -+ -+ self->codec_data = gst_buffer_new_and_alloc(19); -+#if GST_VERSION_MAJOR < 1 -+ data = GST_BUFFER_DATA(self->codec_data); -+#else -+ GstMapInfo self_codec_map; -+ gst_buffer_map(self->codec_data, &self_codec_map, GST_MAP_WRITE); -+ data = self_codec_map.data; -+ size = codecdatamap.size; -+#endif -+ memset(data, 0, size); -+ -+ *(data++) = 0x00; -+ *(data++) = 0x00; -+ *(data++) = 0x01; -+ *(data++) = 0x0F; -+ -+ /* width */ -+ *(data++) = (width >> 8) & 0xff; -+ *(data++) = width & 0xff; -+ /* height */ -+ *(data++) = (height >> 8) & 0xff; -+ *(data++) = height & 0xff; -+ -+ if (codec_data && codec_size) -+ memcpy(data, codec_data_pointer, codec_size); -+ -+ codec_data_pointer[0] >>= 4; -+ if (codec_data_pointer[0] != 4 && codec_data_pointer[0] != 0) -+ GST_ERROR_OBJECT(self, "unsupported vc1-sm video compression format (profile %d)", codec_data_pointer[0]); -+#if GST_VERSION_MAJOR >= 1 -+ gst_buffer_unmap(gst_value_get_buffer(codec_data), &self_codec_map); -+ gst_buffer_unmap(self->codec_data, &codecdatamap); -+#endif -+ } -+ } - } - - if (self->stream_type != STREAMTYPE_UNKNOWN) - { - gint numerator, denominator; -- if (gst_structure_get_fraction (structure, "framerate", &numerator, &denominator)) -+ if (self->framerate == -1 && gst_structure_get_fraction (structure, "framerate", &numerator, &denominator)) - { - FILE *f = fopen("/proc/stb/vmpeg/0/fallback_framerate", "w"); - if (f) -@@ -1663,76 +1811,7 @@ static gboolean gst_dvbvideosink_set_caps(GstBaseSink *basesink, GstCaps *caps) - } - if (self->fd >= 0) - { -- if (self->codec_type == CT_VC1) -- { -- const GValue *codec_data = gst_structure_get_value(structure, "codec_data"); -- if (codec_data) -- { -- guint8 *codec_data_pointer; -- gint codec_size; -- guint8 *data; -- video_codec_data_t videocodecdata; --#if GST_VERSION_MAJOR < 1 -- codec_size = GST_BUFFER_SIZE(gst_value_get_buffer(codec_data)); -- codec_data_pointer = GST_BUFFER_DATA(gst_value_get_buffer(codec_data)); --#else -- GstMapInfo codecdatamap; -- gst_buffer_map(gst_value_get_buffer(codec_data), &codecdatamap, GST_MAP_READ); -- codec_data_pointer = codecdatamap.data; -- codec_size = codecdatamap.size; --#endif -- videocodecdata.length = 8 + codec_size; -- data = videocodecdata.data = (guint8*)g_malloc(videocodecdata.length); -- memset(data, 0, videocodecdata.length); -- data += 8; -- memcpy(data, codec_data_pointer, codec_size); -- ioctl(self->fd, VIDEO_SET_CODEC_DATA, &videocodecdata); -- g_free(videocodecdata.data); --#if GST_VERSION_MAJOR >= 1 -- gst_buffer_unmap(gst_value_get_buffer(codec_data), &codecdatamap); --#endif -- } -- } -- else if (self->codec_type == CT_VC1_SM) -- { -- const GValue *codec_data = gst_structure_get_value(structure, "codec_data"); -- if (codec_data) -- { -- guint8 *codec_data_pointer; -- gint codec_size; -- guint8 *data; -- video_codec_data_t videocodecdata; -- gint width, height; --#if GST_VERSION_MAJOR < 1 -- codec_size = GST_BUFFER_SIZE(gst_value_get_buffer(codec_data)); -- codec_data_pointer = GST_BUFFER_DATA(gst_value_get_buffer(codec_data)); --#else -- GstMapInfo codecdatamap; -- gst_buffer_map(gst_value_get_buffer(codec_data), &codecdatamap, GST_MAP_READ); -- codec_data_pointer = codecdatamap.data; -- codec_size = codecdatamap.size; --#endif -- if (codec_size > 4) codec_size = 4; -- gst_structure_get_int(structure, "width", &width); -- gst_structure_get_int(structure, "height", &height); -- videocodecdata.length = 33; -- data = videocodecdata.data = (guint8*)g_malloc(videocodecdata.length); -- memset(data, 0, videocodecdata.length); -- data += 18; -- /* width */ -- *(data++) = (width >> 8) & 0xff; -- *(data++) = width & 0xff; -- /* height */ -- *(data++) = (height >> 8) & 0xff; -- *(data++) = height & 0xff; -- if (codec_data && codec_size) memcpy(data, codec_data_pointer, codec_size); -- ioctl(self->fd, VIDEO_SET_CODEC_DATA, &videocodecdata); -- g_free(videocodecdata.data); --#if GST_VERSION_MAJOR >= 1 -- gst_buffer_unmap(gst_value_get_buffer(codec_data), &codecdatamap); --#endif -- } -- } -+ - ioctl(self->fd, VIDEO_PLAY); - } - self->playing = TRUE; -@@ -1941,3 +2020,434 @@ GST_PLUGIN_DEFINE ( - "GStreamer", - "http://gstreamer.net/" - ) -+ -+static unsigned int -+Vc1ParseSeqHeader( GstDVBVideoSink *self, struct bitstream *bit ) -+{ -+ unsigned char n; -+ long uiStartAddr = (long)&(bit->data[0]); -+ long uiStopAddr = 0; -+ -+ // skip first 5 bytes (PROFILE,LEVEL,COLORDIFF_FORMAT,FRMRTQ_POSTPROC,BITRTQ_POSTPROC,POSTPROCFLAG,MAX_CODED_WIDTH,MAX_CODED_HEIGHT) -+ bitstream_get( bit, 32 ); -+ bitstream_get( bit, 8 ); -+ self->ucVC1_PULLDOWN = (unsigned char)bitstream_get( bit, 1 ); -+ self->ucVC1_INTERLACE = (unsigned char)bitstream_get( bit, 1 ); -+ self->ucVC1_TFCNTRFLAG = (unsigned char)bitstream_get( bit, 1 ); -+ self->ucVC1_FINTERPFLAG = (unsigned char)bitstream_get( bit, 1 ); -+ // skip 1 bit (RESERVED) -+ bitstream_get( bit, 1 ); -+ self->ucVC1_PSF = (unsigned char)bitstream_get( bit, 1 ); -+ -+ if ( bitstream_get( bit, 1 ) == 1 ) { -+ // DISPLAY_EXT == 1 -+ -+ // skip 28 bits (DISP_HORIZ_SIZE,DISP_VERT_SIZE) -+ bitstream_get( bit, 28 ); -+ -+ if ( bitstream_get( bit, 1 ) == 1 ) { -+ // ASPECT_RATIO_FLAG == 1 -+ if ( bitstream_get( bit, 4 ) == 15 ) -+ { -+ // ASPECT_RATIO == '15' -+ -+ // skip 16 bits (ASPECT_HORIZ_SIZE,ASPECT_VERT_SIZE) -+ bitstream_get( bit, 16 ); -+ } -+ } -+ -+ if ( bitstream_get( bit, 1 ) == 1 ) { -+ int framerate = -1; -+ // FRAMERATE_FLAG == 1 -+ if ( bitstream_get( bit, 1 ) == 0 ) { -+ // FRAMERATEIND == 0 -+ int frameratenr = bitstream_get( bit, 8 ); -+ int frameratedr = bitstream_get( bit, 4 ); -+ -+ GST_DEBUG_OBJECT(self, "VC1 frameratenr %d, frameratedr %d", frameratenr, frameratedr); -+ -+ switch (frameratenr) { -+ case 1: framerate = 24000; break; -+ case 2: framerate = 25000; break; -+ case 3: framerate = 30000; break; -+ case 4: framerate = 50000; break; -+ case 5: framerate = 60000; break; -+ case 6: framerate = 48000; break; -+ case 7: framerate = 72000; break; -+ default: -+ GST_INFO_OBJECT(self, "forbidden VC1 frameratenr %d", frameratenr); -+ break; -+ } -+ if (framerate != -1) { -+ switch (frameratedr) { -+ case 1: break; -+ case 2: framerate *= 1000; -+ framerate /= 1001; -+ break; -+ default: -+ GST_INFO_OBJECT(self, "forbidden VC1 frameratedr %d", frameratedr); -+ break; -+ } -+ } -+ } -+ else { -+ // FRAMERATEIND == 1 -+ int framerateexp = bitstream_get( bit, 16 ); -+ -+ GST_DEBUG_OBJECT(self, "VC1 framerateexp %d", framerateexp); -+ -+ framerate = (framerateexp * 1000) / 32; -+ } -+ -+ if (framerate != -1) { -+ GST_INFO_OBJECT(self, "VC1 seq header framerate %d", framerate); -+ -+ self->framerate = framerate; -+ } -+ } -+ -+ if ( bitstream_get( bit, 1 ) == 1 ) { -+ // COLOR_FORMAT_FLAG ==1 -+ -+ // skip 24 bits (COLOR_PRIM,TRANSFER_CHAR,MATRIX_COEF) -+ bitstream_get( bit, 24 ); -+ } -+ } -+ -+ self->ucVC1_HRD_PARAM_FLAG = (unsigned char)bitstream_get( bit, 1 ); -+ -+ if ( self->ucVC1_HRD_PARAM_FLAG == 1 ) { -+ // ucVC1_HRD_PARAM_FLAG == 1 -+ self->ucVC1_HRD_NUM_LEAKY_BUCKETS = (unsigned char)bitstream_get( bit, 5 ); -+ -+ // skip 8 bits (BIT_RATE_EXPONENT,BUFFER_SIZE_EXPONENT) -+ bitstream_get( bit, 8 ); -+ -+ for ( n = 1; n <= self->ucVC1_HRD_NUM_LEAKY_BUCKETS; n++ ) { -+ // skip 32 bits (HRD_RATE[n],HRD_BUFFER[n]) -+ bitstream_get( bit, 32 ); -+ } -+ } -+ -+ uiStopAddr = (long)&(bit->data[0]); -+ return (unsigned int)(uiStopAddr - uiStartAddr + 1); -+} -+ -+static unsigned int -+Vc1ParseEntryPointHeader( GstDVBVideoSink *self, struct bitstream *bit ) -+{ -+ unsigned char n, ucEXTENDED_MV; -+ long uiStartAddr = (long)&(bit->data[0]); -+ long uiStopAddr = 0; -+ -+ // skip the first two bits (BROKEN_LINK,CLOSED_ENTRY) -+ bitstream_get( bit, 2 ); -+ self->ucVC1_PANSCAN_FLAG = (unsigned char)bitstream_get( bit, 1 ); -+ self->ucVC1_REFDIST_FLAG = (unsigned char)bitstream_get( bit, 1 ); -+ -+ // skip 2 bits (LOOPFILTER,FASTUVMC) -+ bitstream_get( bit, 2 ); -+ -+ ucEXTENDED_MV = (unsigned char)bitstream_get( bit, 1 ); -+ -+ // skip 6 bits (DQUANT,VSTRANSFORM,OVERLAP,QUANTIZER) -+ bitstream_get( bit, 6 ); -+ -+ if ( self->ucVC1_HRD_PARAM_FLAG == 1 ) { -+ for ( n = 1; n <= self->ucVC1_HRD_NUM_LEAKY_BUCKETS; n++ ) { -+ // skip 8 bits (HRD_FULL[n]) -+ bitstream_get( bit, 8 ); -+ } -+ } -+ -+ if ( bitstream_get( bit, 1 ) == 1 ) { -+ // CODED_SIZE_FLAG == 1 -+ -+ // skip 24 bits (CODED_WIDTH,CODED_HEIGHT) -+ bitstream_get( bit, 24 ); -+ } -+ -+ if ( ucEXTENDED_MV == 1 ) { -+ // skip 1 bit (EXTENDED_DMV) -+ bitstream_get( bit, 1 ); -+ } -+ -+ if ( bitstream_get( bit, 1 ) == 1 ) { -+ // RANGE_MAPY_FLAG == 1 -+ -+ // skip 3 bits (RANGE_MAPY) -+ bitstream_get( bit, 3 ); -+ } -+ -+ if ( bitstream_get( bit, 1 ) == 1 ) { -+ // RANGE_MAPUV_FLAG == 1 -+ -+ // skip 3 bits (RANGE_MAPUV) -+ bitstream_get( bit, 3 ); -+ } -+ -+ uiStopAddr = (long)&(bit->data[0]); -+ -+ return (unsigned int)(uiStopAddr - uiStartAddr + 1); -+} -+ -+static unsigned char -+Vc1GetFrameType( GstDVBVideoSink *self, struct bitstream *bit ) -+{ -+ unsigned char ucRetVal = 0; -+ -+ if ( self->ucVC1_INTERLACE == 1 ) { -+ // determine FCM -+ if ( bitstream_get( bit, 1 ) == 1 ) { -+ // Frame- or Field-Interlace Coding Mode -> we have to skip a further bit -+ bitstream_get( bit, 1 ); -+ } -+ else { -+ // Progressive Frame Coding Mode -> no need to consume a further bit -+ } -+ } -+ -+ if ( bitstream_get( bit, 1 ) == 0 ) { -+ // P-Frame detected -+ ucRetVal = 0; -+ } -+ else if ( bitstream_get( bit, 1 ) == 0 ) { -+ // B-Frame detected -+ ucRetVal = 2; -+ } -+ else if ( bitstream_get( bit, 1 ) == 0 ) { -+ // I-Frame detected -+ ucRetVal = 6; -+ } -+ else if ( bitstream_get( bit, 1 ) == 0 ) { -+ // BI-Frame detected -+ ucRetVal = 14; -+ } -+ else { -+ // Skipped-Frame detected -+ ucRetVal = 15; -+ } -+ -+ return ucRetVal; -+} -+ -+static unsigned char -+Vc1GetBFractionVal( GstDVBVideoSink *self, struct bitstream *bit ) -+{ -+ unsigned char ucRetVal = 0; -+ unsigned char ucNumberOfPanScanWindows = 0; -+ unsigned char ucRFF = 0; -+ unsigned char ucRPTFRM = 0; -+ unsigned char ucTmpVar = 0; -+ unsigned char i; -+ -+ if ( self->ucVC1_TFCNTRFLAG == 1 ) { -+ // skip the first 8 bit (TFCNTR) -+ bitstream_get( bit, 8 ); -+ } -+ -+ if ( self->ucVC1_PULLDOWN == 1 ) { -+ if ( self->ucVC1_INTERLACE == 0 || self->ucVC1_PSF == 1 ) { -+ ucRPTFRM = (unsigned char)bitstream_get( bit, 2 ); -+ } -+ else { -+ // skip 1 bit (TFF) -+ bitstream_get( bit, 1 ); -+ ucRFF = (unsigned char)bitstream_get( bit, 1 ); -+ } -+ } -+ -+ if ( self->ucVC1_PANSCAN_FLAG == 1 ) { -+ if ( bitstream_get( bit, 2 ) != 0 ) { -+ // PS_PRESENT -+ if ( self->ucVC1_INTERLACE == 1 && self->ucVC1_PSF == 0 ) { -+ if ( self->ucVC1_PULLDOWN == 1 ) { -+ ucNumberOfPanScanWindows = 2 + ucRFF; -+ } -+ else { -+ ucNumberOfPanScanWindows = 2; -+ } -+ } -+ else { -+ if ( self->ucVC1_PULLDOWN == 1 ) { -+ ucNumberOfPanScanWindows = 1 + ucRPTFRM; -+ } -+ else { -+ ucNumberOfPanScanWindows = 1; -+ } -+ } -+ for ( i = 0; i < ucNumberOfPanScanWindows; i++ ) { -+ // skip 8 bytes (PS_HOFFSET,PS_VOFFSET,PS_WIDTH,PS_HEIGHT) -+ bitstream_get( bit, 32 ); -+ bitstream_get( bit, 32 ); -+ } -+ } -+ } -+ -+ // skip 1 bit (RNDCTRL) -+ bitstream_get( bit, 1 ); -+ -+ if ( self->ucVC1_INTERLACE == 1 ) { -+ // skip 1 bit (UVSAMP) -+ bitstream_get( bit, 1 ); -+ } -+ -+ if ( self->ucVC1_FINTERPFLAG == 1 ) { -+ // skip 1 bit (INTERPFRM) -+ bitstream_get( bit, 1 ); -+ } -+ -+ ucTmpVar = (unsigned char)bitstream_get( bit, 3 ); -+ ucRetVal = ucTmpVar; -+ -+ if ( ucTmpVar > 6 ) { -+ ucRetVal <<= 4; -+ ucTmpVar = (unsigned char)bitstream_get( bit, 4 ); -+ ucRetVal |= ucTmpVar; -+ } -+ -+ return ucRetVal; -+} -+ -+static unsigned char -+Vc1GetNrOfFramesFromBFractionVal( unsigned char ucBFVal ) -+{ -+ unsigned char ucRetVal; -+ -+ switch( ucBFVal ) { -+ case 0: -+ //printf("(1/2)\n"); -+ ucRetVal = 1; -+ break; -+ case 1: -+ //printf("(1/3)\n"); -+ ucRetVal = 2; -+ break; -+ case 3: -+ //printf("(1/4)\n"); -+ ucRetVal = 3; -+ break; -+ case 5: -+ //printf("(1/5)\n"); -+ ucRetVal = 4; -+ break; -+ case 0x72: -+ //printf("(1/6)\n"); -+ ucRetVal = 5; -+ break; -+ case 0x74: -+ //printf("(1/7)\n"); -+ ucRetVal = 6; -+ break; -+ case 0x7A: -+ //printf("(1/8)\n"); -+ ucRetVal = 7; -+ break; -+ default: -+ ucRetVal = 0; -+ //printf("ucBFVal = %d\n", ucBFVal); -+ break; -+ } -+ -+ return ucRetVal; -+} -+ -+static unsigned char -+Vc1HandleStreamBuffer( GstDVBVideoSink *self, unsigned char *data, int flags ) -+{ -+ unsigned char ucPType, ucRetVal = cVC1BufferDataAvailable; -+ unsigned int i = -1; -+ -+ if (flags & 1) -+ goto parse_frame_header; -+ -+ i = 0; -+ -+ if ( ((data[i] == 0) && (data[i+1] == 0) && (data[i+2] == 1)) ) { -+ -+ i += 3; -+ -+ if ( data[i] == 0x0F ) { -+ // Sequence header -+ struct bitstream bitstr; -+ i++; -+ bitstream_init( &bitstr, &data[i], 0 ); -+ i += Vc1ParseSeqHeader(self, &bitstr); -+ //printf("Sequence header\n"); -+ -+ if ( data[i] == 0 && data[i+1] == 0 && data[i+2] == 1 && data[i+3] == 0x0E ) { -+ // Entry Point Header -+ struct bitstream bitstr; -+ i += 4; -+ bitstream_init( &bitstr, &data[i], 0 ); -+ i += Vc1ParseEntryPointHeader(self, &bitstr); -+ //printf("Entry Point header\n"); -+ -+ if ( flags & 2 ) // parse codec_data only -+ return 0; -+ -+ if ( data[i] == 0 && data[i+1] == 0 && data[i+2] == 1 && data[i+3] == 0x0D ) -+ i += 3; -+ else -+ GST_ERROR_OBJECT(self, "No Frame Header after a VC1 Entry Point header!!!"); -+ } -+ else -+ GST_ERROR_OBJECT(self, "No Entry Point Header after a VC1 Sequence header!!!"); -+ } -+ -+ if ( data[i] == 0x0D ) -+parse_frame_header: -+ { -+ // Frame Header -+ struct bitstream bitstr; -+ unsigned char ucBFractionVal = 0; -+ -+ i++; -+ -+ bitstream_init( &bitstr, &data[i], 0 ); -+ ucPType = Vc1GetFrameType( self, &bitstr ); -+ -+ GST_DEBUG_OBJECT(self, "picturetype = %d", ucPType); -+ -+ if ( self->prev_frame == NULL ) { -+ // first frame received -+ ucRetVal = cVC1NoBufferDataAvailable; -+ } -+ else { -+ if ( ucPType == 2 && (self->ucPrevFramePicType == 0 || self->ucPrevFramePicType == 6 || self->ucPrevFramePicType == 15) ) -+ { -+ int num_frames; -+ // last frame was a reference frame (P-,I- or Skipped-Frame) and current frame is a B-Frame -+ // -> correct the timestamp of the previous reference frame -+ ucBFractionVal = Vc1GetBFractionVal( self, &bitstr ); -+ -+ num_frames = Vc1GetNrOfFramesFromBFractionVal( ucBFractionVal ); -+ -+ GST_DEBUG_OBJECT(self, "num_frames = %d", num_frames); -+#if GST_VERSION_MAJOR < 1 -+ GST_BUFFER_TIMESTAMP(self->prev_frame) += (1000000000000ULL / self->framerate) * num_frames; -+#else -+ GST_BUFFER_PTS(self->prev_frame) += (1000000000000ULL / self->framerate) * num_frames; -+#endif -+ } -+ else if ( self->ucPrevFramePicType == 2 ) -+ { -+ // last frame was a B-Frame -> correct the timestamp by the duration -+ // of the preceding reference frame -+#if GST_VERSION_MAJOR < 1 -+ GST_BUFFER_TIMESTAMP(self->prev_frame) -= 1000000000000ULL / self->framerate; -+#else -+ GST_BUFFER_PTS(self->prev_frame) -= 1000000000000ULL / self->framerate; -+#endif -+ } -+ } -+ // save the current picture type -+ self->ucPrevFramePicType = ucPType; -+ } -+ } -+ else -+ GST_ERROR_OBJECT(self, "startcodes in VC1 buffer not correctly aligned!"); -+ -+ return ucRetVal; -+} -+ -diff --git a/gstdvbvideosink.h b/gstdvbvideosink.h -index 8cf1dc2..14429a8 100644 ---- a/gstdvbvideosink.h -+++ b/gstdvbvideosink.h -@@ -71,9 +71,9 @@ typedef enum { - STREAMTYPE_MPEG2 = 0, - STREAMTYPE_MPEG4_H264 = 1, - STREAMTYPE_H263 = 2, -- STREAMTYPE_VC1 = 3, -+ STREAMTYPE_VC1 = 16, - STREAMTYPE_MPEG4_Part2 = 4, -- STREAMTYPE_VC1_SM = 5, -+ STREAMTYPE_VC1_SM = 17, - STREAMTYPE_MPEG1 = 6, - STREAMTYPE_XVID = 10, - STREAMTYPE_DIVX311 = 13, -@@ -116,6 +116,27 @@ struct _GstDVBVideoSink - gboolean must_send_header; - - queue_entry_t *queue; -+ -+ // VC1 stuff.... -+ -+ int no_header; -+ -+ int framerate; // current framerate -+ -+ unsigned char ucPrevFramePicType; -+ -+ // Sequence header variables -+ unsigned char ucVC1_PULLDOWN; -+ unsigned char ucVC1_INTERLACE; -+ unsigned char ucVC1_TFCNTRFLAG ; -+ unsigned char ucVC1_FINTERPFLAG; -+ unsigned char ucVC1_PSF; -+ unsigned char ucVC1_HRD_PARAM_FLAG; -+ unsigned char ucVC1_HRD_NUM_LEAKY_BUCKETS; -+ -+ // Entry Point header variables -+ unsigned char ucVC1_PANSCAN_FLAG; -+ unsigned char ucVC1_REFDIST_FLAG; - }; - - struct _GstDVBVideoSinkClass