1 diff --git a/gstdvbvideosink.c b/gstdvbvideosink.c
2 index 903432c..dd31dc7 100644
3 --- a/gstdvbvideosink.c
4 +++ b/gstdvbvideosink.c
5 @@ -150,6 +150,16 @@ void bitstream_put(struct bitstream *bit, unsigned long val, int bits)
9 +static unsigned int Vc1ParseSeqHeader( GstDVBVideoSink *self, struct bitstream *bit );
10 +static unsigned int Vc1ParseEntryPointHeader( GstDVBVideoSink *self, struct bitstream *bit );
11 +static unsigned char Vc1GetFrameType( GstDVBVideoSink *self, struct bitstream *bit );
12 +static unsigned char Vc1GetBFractionVal( GstDVBVideoSink *self, struct bitstream *bit );
13 +static unsigned char Vc1GetNrOfFramesFromBFractionVal( unsigned char ucBFVal );
14 +static unsigned char Vc1HandleStreamBuffer( GstDVBVideoSink *self, unsigned char *data, int flags );
16 +#define cVC1NoBufferDataAvailable 0
17 +#define cVC1BufferDataAvailable 1
19 GST_DEBUG_CATEGORY_STATIC (dvbvideosink_debug);
20 #define GST_CAT_DEFAULT dvbvideosink_debug
22 @@ -338,6 +348,7 @@ static void gst_dvbvideosink_init(GstDVBVideoSink *self)
23 self->num_non_keyframes = 0;
24 self->prev_frame = NULL;
27 #if GST_VERSION_MAJOR >= 1
28 self->use_dts = FALSE;
30 @@ -351,6 +362,17 @@ static void gst_dvbvideosink_init(GstDVBVideoSink *self)
31 self->saved_fallback_framerate[0] = 0;
34 + self->ucPrevFramePicType = 0;
35 + self->ucVC1_PULLDOWN = 0;
36 + self->ucVC1_INTERLACE = 0;
37 + self->ucVC1_TFCNTRFLAG = 0;
38 + self->ucVC1_FINTERPFLAG = 0;
39 + self->ucVC1_PSF = 0;
40 + self->ucVC1_HRD_PARAM_FLAG = 0;
41 + self->ucVC1_HRD_NUM_LEAKY_BUCKETS = 0;
42 + self->ucVC1_PANSCAN_FLAG = 0;
43 + self->ucVC1_REFDIST_FLAG = 0;
45 gst_base_sink_set_sync(GST_BASE_SINK(self), FALSE);
46 gst_base_sink_set_async_enabled(GST_BASE_SINK(self), TRUE);
48 @@ -875,18 +897,31 @@ static GstFlowReturn gst_dvbvideosink_render(GstBaseSink *sink, GstBuffer *buffe
52 + if (self->codec_type == CT_VC1)
54 + if (self->no_header && self->ucPrevFramePicType == 6) { // I-Frame...
55 + GST_INFO_OBJECT(self, "send seq header");
56 + self->must_send_header = 1;
59 if (self->must_send_header)
61 if (self->codec_type != CT_MPEG1 && self->codec_type != CT_MPEG2 && (self->codec_type != CT_DIVX4 || data[3] == 0x00))
63 + unsigned char *_codec_data = codec_data;
64 + unsigned int _codec_data_size = codec_data_size;
65 + if (self->codec_type == CT_VC1) {
67 + _codec_data_size -= 1;
69 if (self->codec_type == CT_DIVX311)
71 video_write(sink, self, self->codec_data, 0, codec_data_size);
75 - memcpy(pes_header + pes_header_len, codec_data, codec_data_size);
76 - pes_header_len += codec_data_size;
77 + memcpy(pes_header + pes_header_len, _codec_data, _codec_data_size);
78 + pes_header_len += _codec_data_size;
80 self->must_send_header = FALSE;
82 @@ -976,6 +1011,47 @@ static GstFlowReturn gst_dvbvideosink_render(GstBaseSink *sink, GstBuffer *buffe
87 + else if (self->codec_type == CT_VC1 || self->codec_type == CT_VC1_SM)
89 + int skip_header_check;
91 + if (data[0] || data[1] || data[2] != 1) {
92 + memcpy(pes_header+pes_header_len, "\x00\x00\x01\x0d", 4);
93 + pes_header_len += 4;
94 + skip_header_check = 1;
97 + skip_header_check = 0;
99 + self->no_header = skip_header_check;
101 + if (self->codec_type == CT_VC1) {
102 + unsigned char ucRetVal = Vc1HandleStreamBuffer( self, data, skip_header_check );
103 + if ( ucRetVal != cVC1NoBufferDataAvailable ) {
104 +#if GST_VERSION_MAJOR < 1
105 + data_len = GST_BUFFER_SIZE(self->prev_frame);
106 + data = GST_BUFFER_DATA(self->prev_frame);
108 + gst_buffer_unmap(buffer, &map);
109 + gst_buffer_map(self->prev_frame, &map, GST_MAP_READ);
110 + data_len = map.size;
115 + GST_DEBUG_OBJECT(self, "first buffer!");
117 + gst_buffer_ref(buffer);
118 + self->prev_frame = buffer;
123 + cache_prev_frame = TRUE;
127 else if (self->codec_type == CT_DIVX311)
129 if (memcmp(data, "\x00\x00\x01\xb6", 4))
130 @@ -1204,12 +1280,6 @@ static GstFlowReturn gst_dvbvideosink_render(GstBaseSink *sink, GstBuffer *buffe
134 - else if (self->codec_type == CT_VC1 || self->codec_type == CT_VC1_SM)
136 - memcpy(pes_header + pes_header_len, "\x00\x00\x01\x0d", 4);
137 - pes_header_len += 4;
141 pes_set_payload_size(payload_len, pes_header);
143 @@ -1617,12 +1687,90 @@ static gboolean gst_dvbvideosink_set_caps(GstBaseSink *basesink, GstCaps *caps)
144 self->codec_type = CT_VC1_SM;
145 GST_INFO_OBJECT (self, "MIMETYPE video/x-wmv -> STREAMTYPE_VC1_SM");
148 + if (self->codec_type == CT_VC1)
150 + const GValue *codec_data = gst_structure_get_value(structure, "codec_data");
154 + self->codec_data = gst_value_get_buffer (codec_data);
155 + gst_buffer_ref (self->codec_data);
156 +#if GST_VERSION_MAJOR < 1
157 + Vc1HandleStreamBuffer(self, GST_BUFFER_DATA(self->codec_data)+1, 2 );
159 + GstMapInfo codec_data_map;
160 + gst_buffer_map(self->codec_data, &codec_data_map, GST_MAP_READ);
161 + Vc1HandleStreamBuffer(self, codec_data_map.data+1, 2 );
162 + gst_buffer_unmap(self->codec_data, &codec_data_map);
167 + else if (self->codec_type == CT_VC1_SM)
169 + const GValue *codec_data = gst_structure_get_value(structure, "codec_data");
173 + /* wmv version 3 test */
174 + guint8 *codec_data_pointer, *data;
175 + gint codec_size, size;
176 + gint width, height;
177 +#if GST_VERSION_MAJOR < 1
178 + codec_size = GST_BUFFER_SIZE(gst_value_get_buffer(codec_data));
179 + codec_data_pointer = GST_BUFFER_DATA(gst_value_get_buffer(codec_data));
181 + GstMapInfo codecdatamap;
182 + gst_buffer_map(gst_value_get_buffer(codec_data), &codecdatamap, GST_MAP_READ);
183 + codec_data_pointer = codecdatamap.data;
184 + codec_size = codecdatamap.size;
186 + if (codec_size > 4) codec_size = 4;
187 + gst_structure_get_int(structure, "width", &width);
188 + gst_structure_get_int(structure, "height", &height);
190 + self->codec_data = gst_buffer_new_and_alloc(19);
191 +#if GST_VERSION_MAJOR < 1
192 + data = GST_BUFFER_DATA(self->codec_data);
194 + GstMapInfo self_codec_map;
195 + gst_buffer_map(self->codec_data, &self_codec_map, GST_MAP_WRITE);
196 + data = self_codec_map.data;
197 + size = codecdatamap.size;
199 + memset(data, 0, size);
207 + *(data++) = (width >> 8) & 0xff;
208 + *(data++) = width & 0xff;
210 + *(data++) = (height >> 8) & 0xff;
211 + *(data++) = height & 0xff;
213 + if (codec_data && codec_size)
214 + memcpy(data, codec_data_pointer, codec_size);
216 + codec_data_pointer[0] >>= 4;
217 + if (codec_data_pointer[0] != 4 && codec_data_pointer[0] != 0)
218 + GST_ERROR_OBJECT(self, "unsupported vc1-sm video compression format (profile %d)", codec_data_pointer[0]);
219 +#if GST_VERSION_MAJOR >= 1
220 + gst_buffer_unmap(gst_value_get_buffer(codec_data), &self_codec_map);
221 + gst_buffer_unmap(self->codec_data, &codecdatamap);
227 if (self->stream_type != STREAMTYPE_UNKNOWN)
229 gint numerator, denominator;
230 - if (gst_structure_get_fraction (structure, "framerate", &numerator, &denominator))
231 + if (self->framerate == -1 && gst_structure_get_fraction (structure, "framerate", &numerator, &denominator))
233 FILE *f = fopen("/proc/stb/vmpeg/0/fallback_framerate", "w");
235 @@ -1663,76 +1811,7 @@ static gboolean gst_dvbvideosink_set_caps(GstBaseSink *basesink, GstCaps *caps)
239 - if (self->codec_type == CT_VC1)
241 - const GValue *codec_data = gst_structure_get_value(structure, "codec_data");
244 - guint8 *codec_data_pointer;
247 - video_codec_data_t videocodecdata;
248 -#if GST_VERSION_MAJOR < 1
249 - codec_size = GST_BUFFER_SIZE(gst_value_get_buffer(codec_data));
250 - codec_data_pointer = GST_BUFFER_DATA(gst_value_get_buffer(codec_data));
252 - GstMapInfo codecdatamap;
253 - gst_buffer_map(gst_value_get_buffer(codec_data), &codecdatamap, GST_MAP_READ);
254 - codec_data_pointer = codecdatamap.data;
255 - codec_size = codecdatamap.size;
257 - videocodecdata.length = 8 + codec_size;
258 - data = videocodecdata.data = (guint8*)g_malloc(videocodecdata.length);
259 - memset(data, 0, videocodecdata.length);
261 - memcpy(data, codec_data_pointer, codec_size);
262 - ioctl(self->fd, VIDEO_SET_CODEC_DATA, &videocodecdata);
263 - g_free(videocodecdata.data);
264 -#if GST_VERSION_MAJOR >= 1
265 - gst_buffer_unmap(gst_value_get_buffer(codec_data), &codecdatamap);
269 - else if (self->codec_type == CT_VC1_SM)
271 - const GValue *codec_data = gst_structure_get_value(structure, "codec_data");
274 - guint8 *codec_data_pointer;
277 - video_codec_data_t videocodecdata;
278 - gint width, height;
279 -#if GST_VERSION_MAJOR < 1
280 - codec_size = GST_BUFFER_SIZE(gst_value_get_buffer(codec_data));
281 - codec_data_pointer = GST_BUFFER_DATA(gst_value_get_buffer(codec_data));
283 - GstMapInfo codecdatamap;
284 - gst_buffer_map(gst_value_get_buffer(codec_data), &codecdatamap, GST_MAP_READ);
285 - codec_data_pointer = codecdatamap.data;
286 - codec_size = codecdatamap.size;
288 - if (codec_size > 4) codec_size = 4;
289 - gst_structure_get_int(structure, "width", &width);
290 - gst_structure_get_int(structure, "height", &height);
291 - videocodecdata.length = 33;
292 - data = videocodecdata.data = (guint8*)g_malloc(videocodecdata.length);
293 - memset(data, 0, videocodecdata.length);
296 - *(data++) = (width >> 8) & 0xff;
297 - *(data++) = width & 0xff;
299 - *(data++) = (height >> 8) & 0xff;
300 - *(data++) = height & 0xff;
301 - if (codec_data && codec_size) memcpy(data, codec_data_pointer, codec_size);
302 - ioctl(self->fd, VIDEO_SET_CODEC_DATA, &videocodecdata);
303 - g_free(videocodecdata.data);
304 -#if GST_VERSION_MAJOR >= 1
305 - gst_buffer_unmap(gst_value_get_buffer(codec_data), &codecdatamap);
310 ioctl(self->fd, VIDEO_PLAY);
312 self->playing = TRUE;
313 @@ -1941,3 +2020,434 @@ GST_PLUGIN_DEFINE (
315 "http://gstreamer.net/"
319 +Vc1ParseSeqHeader( GstDVBVideoSink *self, struct bitstream *bit )
322 + long uiStartAddr = (long)&(bit->data[0]);
323 + long uiStopAddr = 0;
325 + // skip first 5 bytes (PROFILE,LEVEL,COLORDIFF_FORMAT,FRMRTQ_POSTPROC,BITRTQ_POSTPROC,POSTPROCFLAG,MAX_CODED_WIDTH,MAX_CODED_HEIGHT)
326 + bitstream_get( bit, 32 );
327 + bitstream_get( bit, 8 );
328 + self->ucVC1_PULLDOWN = (unsigned char)bitstream_get( bit, 1 );
329 + self->ucVC1_INTERLACE = (unsigned char)bitstream_get( bit, 1 );
330 + self->ucVC1_TFCNTRFLAG = (unsigned char)bitstream_get( bit, 1 );
331 + self->ucVC1_FINTERPFLAG = (unsigned char)bitstream_get( bit, 1 );
332 + // skip 1 bit (RESERVED)
333 + bitstream_get( bit, 1 );
334 + self->ucVC1_PSF = (unsigned char)bitstream_get( bit, 1 );
336 + if ( bitstream_get( bit, 1 ) == 1 ) {
337 + // DISPLAY_EXT == 1
339 + // skip 28 bits (DISP_HORIZ_SIZE,DISP_VERT_SIZE)
340 + bitstream_get( bit, 28 );
342 + if ( bitstream_get( bit, 1 ) == 1 ) {
343 + // ASPECT_RATIO_FLAG == 1
344 + if ( bitstream_get( bit, 4 ) == 15 )
346 + // ASPECT_RATIO == '15'
348 + // skip 16 bits (ASPECT_HORIZ_SIZE,ASPECT_VERT_SIZE)
349 + bitstream_get( bit, 16 );
353 + if ( bitstream_get( bit, 1 ) == 1 ) {
354 + int framerate = -1;
355 + // FRAMERATE_FLAG == 1
356 + if ( bitstream_get( bit, 1 ) == 0 ) {
357 + // FRAMERATEIND == 0
358 + int frameratenr = bitstream_get( bit, 8 );
359 + int frameratedr = bitstream_get( bit, 4 );
361 + GST_DEBUG_OBJECT(self, "VC1 frameratenr %d, frameratedr %d", frameratenr, frameratedr);
363 + switch (frameratenr) {
364 + case 1: framerate = 24000; break;
365 + case 2: framerate = 25000; break;
366 + case 3: framerate = 30000; break;
367 + case 4: framerate = 50000; break;
368 + case 5: framerate = 60000; break;
369 + case 6: framerate = 48000; break;
370 + case 7: framerate = 72000; break;
372 + GST_INFO_OBJECT(self, "forbidden VC1 frameratenr %d", frameratenr);
375 + if (framerate != -1) {
376 + switch (frameratedr) {
378 + case 2: framerate *= 1000;
382 + GST_INFO_OBJECT(self, "forbidden VC1 frameratedr %d", frameratedr);
388 + // FRAMERATEIND == 1
389 + int framerateexp = bitstream_get( bit, 16 );
391 + GST_DEBUG_OBJECT(self, "VC1 framerateexp %d", framerateexp);
393 + framerate = (framerateexp * 1000) / 32;
396 + if (framerate != -1) {
397 + GST_INFO_OBJECT(self, "VC1 seq header framerate %d", framerate);
399 + self->framerate = framerate;
403 + if ( bitstream_get( bit, 1 ) == 1 ) {
404 + // COLOR_FORMAT_FLAG ==1
406 + // skip 24 bits (COLOR_PRIM,TRANSFER_CHAR,MATRIX_COEF)
407 + bitstream_get( bit, 24 );
411 + self->ucVC1_HRD_PARAM_FLAG = (unsigned char)bitstream_get( bit, 1 );
413 + if ( self->ucVC1_HRD_PARAM_FLAG == 1 ) {
414 + // ucVC1_HRD_PARAM_FLAG == 1
415 + self->ucVC1_HRD_NUM_LEAKY_BUCKETS = (unsigned char)bitstream_get( bit, 5 );
417 + // skip 8 bits (BIT_RATE_EXPONENT,BUFFER_SIZE_EXPONENT)
418 + bitstream_get( bit, 8 );
420 + for ( n = 1; n <= self->ucVC1_HRD_NUM_LEAKY_BUCKETS; n++ ) {
421 + // skip 32 bits (HRD_RATE[n],HRD_BUFFER[n])
422 + bitstream_get( bit, 32 );
426 + uiStopAddr = (long)&(bit->data[0]);
427 + return (unsigned int)(uiStopAddr - uiStartAddr + 1);
431 +Vc1ParseEntryPointHeader( GstDVBVideoSink *self, struct bitstream *bit )
433 + unsigned char n, ucEXTENDED_MV;
434 + long uiStartAddr = (long)&(bit->data[0]);
435 + long uiStopAddr = 0;
437 + // skip the first two bits (BROKEN_LINK,CLOSED_ENTRY)
438 + bitstream_get( bit, 2 );
439 + self->ucVC1_PANSCAN_FLAG = (unsigned char)bitstream_get( bit, 1 );
440 + self->ucVC1_REFDIST_FLAG = (unsigned char)bitstream_get( bit, 1 );
442 + // skip 2 bits (LOOPFILTER,FASTUVMC)
443 + bitstream_get( bit, 2 );
445 + ucEXTENDED_MV = (unsigned char)bitstream_get( bit, 1 );
447 + // skip 6 bits (DQUANT,VSTRANSFORM,OVERLAP,QUANTIZER)
448 + bitstream_get( bit, 6 );
450 + if ( self->ucVC1_HRD_PARAM_FLAG == 1 ) {
451 + for ( n = 1; n <= self->ucVC1_HRD_NUM_LEAKY_BUCKETS; n++ ) {
452 + // skip 8 bits (HRD_FULL[n])
453 + bitstream_get( bit, 8 );
457 + if ( bitstream_get( bit, 1 ) == 1 ) {
458 + // CODED_SIZE_FLAG == 1
460 + // skip 24 bits (CODED_WIDTH,CODED_HEIGHT)
461 + bitstream_get( bit, 24 );
464 + if ( ucEXTENDED_MV == 1 ) {
465 + // skip 1 bit (EXTENDED_DMV)
466 + bitstream_get( bit, 1 );
469 + if ( bitstream_get( bit, 1 ) == 1 ) {
470 + // RANGE_MAPY_FLAG == 1
472 + // skip 3 bits (RANGE_MAPY)
473 + bitstream_get( bit, 3 );
476 + if ( bitstream_get( bit, 1 ) == 1 ) {
477 + // RANGE_MAPUV_FLAG == 1
479 + // skip 3 bits (RANGE_MAPUV)
480 + bitstream_get( bit, 3 );
483 + uiStopAddr = (long)&(bit->data[0]);
485 + return (unsigned int)(uiStopAddr - uiStartAddr + 1);
488 +static unsigned char
489 +Vc1GetFrameType( GstDVBVideoSink *self, struct bitstream *bit )
491 + unsigned char ucRetVal = 0;
493 + if ( self->ucVC1_INTERLACE == 1 ) {
495 + if ( bitstream_get( bit, 1 ) == 1 ) {
496 + // Frame- or Field-Interlace Coding Mode -> we have to skip a further bit
497 + bitstream_get( bit, 1 );
500 + // Progressive Frame Coding Mode -> no need to consume a further bit
504 + if ( bitstream_get( bit, 1 ) == 0 ) {
505 + // P-Frame detected
508 + else if ( bitstream_get( bit, 1 ) == 0 ) {
509 + // B-Frame detected
512 + else if ( bitstream_get( bit, 1 ) == 0 ) {
513 + // I-Frame detected
516 + else if ( bitstream_get( bit, 1 ) == 0 ) {
517 + // BI-Frame detected
521 + // Skipped-Frame detected
528 +static unsigned char
529 +Vc1GetBFractionVal( GstDVBVideoSink *self, struct bitstream *bit )
531 + unsigned char ucRetVal = 0;
532 + unsigned char ucNumberOfPanScanWindows = 0;
533 + unsigned char ucRFF = 0;
534 + unsigned char ucRPTFRM = 0;
535 + unsigned char ucTmpVar = 0;
538 + if ( self->ucVC1_TFCNTRFLAG == 1 ) {
539 + // skip the first 8 bit (TFCNTR)
540 + bitstream_get( bit, 8 );
543 + if ( self->ucVC1_PULLDOWN == 1 ) {
544 + if ( self->ucVC1_INTERLACE == 0 || self->ucVC1_PSF == 1 ) {
545 + ucRPTFRM = (unsigned char)bitstream_get( bit, 2 );
548 + // skip 1 bit (TFF)
549 + bitstream_get( bit, 1 );
550 + ucRFF = (unsigned char)bitstream_get( bit, 1 );
554 + if ( self->ucVC1_PANSCAN_FLAG == 1 ) {
555 + if ( bitstream_get( bit, 2 ) != 0 ) {
557 + if ( self->ucVC1_INTERLACE == 1 && self->ucVC1_PSF == 0 ) {
558 + if ( self->ucVC1_PULLDOWN == 1 ) {
559 + ucNumberOfPanScanWindows = 2 + ucRFF;
562 + ucNumberOfPanScanWindows = 2;
566 + if ( self->ucVC1_PULLDOWN == 1 ) {
567 + ucNumberOfPanScanWindows = 1 + ucRPTFRM;
570 + ucNumberOfPanScanWindows = 1;
573 + for ( i = 0; i < ucNumberOfPanScanWindows; i++ ) {
574 + // skip 8 bytes (PS_HOFFSET,PS_VOFFSET,PS_WIDTH,PS_HEIGHT)
575 + bitstream_get( bit, 32 );
576 + bitstream_get( bit, 32 );
581 + // skip 1 bit (RNDCTRL)
582 + bitstream_get( bit, 1 );
584 + if ( self->ucVC1_INTERLACE == 1 ) {
585 + // skip 1 bit (UVSAMP)
586 + bitstream_get( bit, 1 );
589 + if ( self->ucVC1_FINTERPFLAG == 1 ) {
590 + // skip 1 bit (INTERPFRM)
591 + bitstream_get( bit, 1 );
594 + ucTmpVar = (unsigned char)bitstream_get( bit, 3 );
595 + ucRetVal = ucTmpVar;
597 + if ( ucTmpVar > 6 ) {
599 + ucTmpVar = (unsigned char)bitstream_get( bit, 4 );
600 + ucRetVal |= ucTmpVar;
606 +static unsigned char
607 +Vc1GetNrOfFramesFromBFractionVal( unsigned char ucBFVal )
609 + unsigned char ucRetVal;
611 + switch( ucBFVal ) {
613 + //printf("(1/2)\n");
617 + //printf("(1/3)\n");
621 + //printf("(1/4)\n");
625 + //printf("(1/5)\n");
629 + //printf("(1/6)\n");
633 + //printf("(1/7)\n");
637 + //printf("(1/8)\n");
642 + //printf("ucBFVal = %d\n", ucBFVal);
649 +static unsigned char
650 +Vc1HandleStreamBuffer( GstDVBVideoSink *self, unsigned char *data, int flags )
652 + unsigned char ucPType, ucRetVal = cVC1BufferDataAvailable;
653 + unsigned int i = -1;
656 + goto parse_frame_header;
660 + if ( ((data[i] == 0) && (data[i+1] == 0) && (data[i+2] == 1)) ) {
664 + if ( data[i] == 0x0F ) {
666 + struct bitstream bitstr;
668 + bitstream_init( &bitstr, &data[i], 0 );
669 + i += Vc1ParseSeqHeader(self, &bitstr);
670 + //printf("Sequence header\n");
672 + if ( data[i] == 0 && data[i+1] == 0 && data[i+2] == 1 && data[i+3] == 0x0E ) {
673 + // Entry Point Header
674 + struct bitstream bitstr;
676 + bitstream_init( &bitstr, &data[i], 0 );
677 + i += Vc1ParseEntryPointHeader(self, &bitstr);
678 + //printf("Entry Point header\n");
680 + if ( flags & 2 ) // parse codec_data only
683 + if ( data[i] == 0 && data[i+1] == 0 && data[i+2] == 1 && data[i+3] == 0x0D )
686 + GST_ERROR_OBJECT(self, "No Frame Header after a VC1 Entry Point header!!!");
689 + GST_ERROR_OBJECT(self, "No Entry Point Header after a VC1 Sequence header!!!");
692 + if ( data[i] == 0x0D )
696 + struct bitstream bitstr;
697 + unsigned char ucBFractionVal = 0;
701 + bitstream_init( &bitstr, &data[i], 0 );
702 + ucPType = Vc1GetFrameType( self, &bitstr );
704 + GST_DEBUG_OBJECT(self, "picturetype = %d", ucPType);
706 + if ( self->prev_frame == NULL ) {
707 + // first frame received
708 + ucRetVal = cVC1NoBufferDataAvailable;
711 + if ( ucPType == 2 && (self->ucPrevFramePicType == 0 || self->ucPrevFramePicType == 6 || self->ucPrevFramePicType == 15) )
714 + // last frame was a reference frame (P-,I- or Skipped-Frame) and current frame is a B-Frame
715 + // -> correct the timestamp of the previous reference frame
716 + ucBFractionVal = Vc1GetBFractionVal( self, &bitstr );
718 + num_frames = Vc1GetNrOfFramesFromBFractionVal( ucBFractionVal );
720 + GST_DEBUG_OBJECT(self, "num_frames = %d", num_frames);
721 +#if GST_VERSION_MAJOR < 1
722 + GST_BUFFER_TIMESTAMP(self->prev_frame) += (1000000000000ULL / self->framerate) * num_frames;
724 + GST_BUFFER_PTS(self->prev_frame) += (1000000000000ULL / self->framerate) * num_frames;
727 + else if ( self->ucPrevFramePicType == 2 )
729 + // last frame was a B-Frame -> correct the timestamp by the duration
730 + // of the preceding reference frame
731 +#if GST_VERSION_MAJOR < 1
732 + GST_BUFFER_TIMESTAMP(self->prev_frame) -= 1000000000000ULL / self->framerate;
734 + GST_BUFFER_PTS(self->prev_frame) -= 1000000000000ULL / self->framerate;
738 + // save the current picture type
739 + self->ucPrevFramePicType = ucPType;
743 + GST_ERROR_OBJECT(self, "startcodes in VC1 buffer not correctly aligned!");
748 diff --git a/gstdvbvideosink.h b/gstdvbvideosink.h
749 index 8cf1dc2..14429a8 100644
750 --- a/gstdvbvideosink.h
751 +++ b/gstdvbvideosink.h
752 @@ -71,9 +71,9 @@ typedef enum {
753 STREAMTYPE_MPEG2 = 0,
754 STREAMTYPE_MPEG4_H264 = 1,
756 - STREAMTYPE_VC1 = 3,
757 + STREAMTYPE_VC1 = 16,
758 STREAMTYPE_MPEG4_Part2 = 4,
759 - STREAMTYPE_VC1_SM = 5,
760 + STREAMTYPE_VC1_SM = 17,
761 STREAMTYPE_MPEG1 = 6,
762 STREAMTYPE_XVID = 10,
763 STREAMTYPE_DIVX311 = 13,
764 @@ -116,6 +116,27 @@ struct _GstDVBVideoSink
765 gboolean must_send_header;
767 queue_entry_t *queue;
773 + int framerate; // current framerate
775 + unsigned char ucPrevFramePicType;
777 + // Sequence header variables
778 + unsigned char ucVC1_PULLDOWN;
779 + unsigned char ucVC1_INTERLACE;
780 + unsigned char ucVC1_TFCNTRFLAG ;
781 + unsigned char ucVC1_FINTERPFLAG;
782 + unsigned char ucVC1_PSF;
783 + unsigned char ucVC1_HRD_PARAM_FLAG;
784 + unsigned char ucVC1_HRD_NUM_LEAKY_BUCKETS;
786 + // Entry Point header variables
787 + unsigned char ucVC1_PANSCAN_FLAG;
788 + unsigned char ucVC1_REFDIST_FLAG;
791 struct _GstDVBVideoSinkClass