+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