decoder: remove unused variable
[vlc.git] / modules / packetizer / mpegvideo.c
blob2388cc5488593883f3db86de5b21335b3590747a
1 /*****************************************************************************
2 * mpegvideo.c: parse and packetize an MPEG1/2 video stream
3 *****************************************************************************
4 * Copyright (C) 2001-2006 VLC authors and VideoLAN
6 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
7 * Eric Petit <titer@videolan.org>
8 * Gildas Bazin <gbazin@videolan.org>
9 * Jean-Paul Saman <jpsaman #_at_# m2x dot nl>
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU Lesser General Public License as published by
13 * the Free Software Foundation; either version 2.1 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public License
22 * along with this program; if not, write to the Free Software Foundation,
23 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
24 *****************************************************************************/
26 /*****************************************************************************
27 * Problem with this implementation:
29 * Although we should time-stamp each picture with a PTS, this isn't possible
30 * with the current implementation.
31 * The problem comes from the fact that for non-low-delay streams we can't
32 * calculate the PTS of pictures used as backward reference. Even the temporal
33 * reference number doesn't help here because all the pictures don't
34 * necessarily have the same duration (eg. 3:2 pulldown).
36 * However this doesn't really matter as far as the MPEG muxers are concerned
37 * because they allow having empty PTS fields. --gibalou
38 *****************************************************************************/
40 /*****************************************************************************
41 * Preamble
42 *****************************************************************************/
44 #ifdef HAVE_CONFIG_H
45 # include "config.h"
46 #endif
48 #include <vlc_common.h>
49 #include <vlc_plugin.h>
50 #include <vlc_block.h>
51 #include <vlc_codec.h>
52 #include <vlc_block_helper.h>
53 #include "mpegvideo.h"
54 #include "../codec/cc.h"
55 #include "packetizer_helper.h"
56 #include "startcode_helper.h"
57 #include "iso_color_tables.h"
59 #include <limits.h>
61 #define SYNC_INTRAFRAME_TEXT N_("Sync on Intra Frame")
62 #define SYNC_INTRAFRAME_LONGTEXT N_("Normally the packetizer would " \
63 "sync on the next full frame. This flags instructs the packetizer " \
64 "to sync on the first Intra Frame found.")
66 /*****************************************************************************
67 * Module descriptor
68 *****************************************************************************/
69 static int Open ( vlc_object_t * );
70 static void Close( vlc_object_t * );
72 vlc_module_begin ()
73 set_category( CAT_SOUT )
74 set_subcategory( SUBCAT_SOUT_PACKETIZER )
75 set_description( N_("MPEG-I/II video packetizer") )
76 set_shortname( N_("MPEG Video") )
77 set_capability( "packetizer", 50 )
78 set_callbacks( Open, Close )
80 add_bool( "packetizer-mpegvideo-sync-iframe", false, SYNC_INTRAFRAME_TEXT,
81 SYNC_INTRAFRAME_LONGTEXT, true )
82 vlc_module_end ()
84 enum mpeg_startcode_e
86 PICTURE_STARTCODE = 0x00,
87 SLICE_STARTCODE_FIRST = 0x01,
88 SLICE_STARTCODE_LAST = 0xAF,
89 USER_DATA_STARTCODE = 0xB2,
90 SEQUENCE_HEADER_STARTCODE = 0xB3,
91 SEQUENCE_ERROR_STARTCODE = 0xB4,
92 EXTENSION_STARTCODE = 0xB5,
93 SEQUENCE_END_STARTCODE = 0xB7,
94 GROUP_STARTCODE = 0xB8,
95 SYSTEM_STARTCODE_FIRST = 0xB9,
96 SYSTEM_STARTCODE_LAST = 0xFF,
99 enum extension_start_code_identifier_e
101 SEQUENCE_EXTENSION_ID = 0x01,
102 SEQUENCE_DISPLAY_EXTENSION_ID = 0x02,
103 QUANT_MATRIX_EXTENSION_ID = 0x03,
104 COPYRIGHT_EXTENSION_ID = 0x04,
105 SEQUENCE_SCALABLE_EXTENSION_ID = 0x05,
106 PICTURE_DISPLAY_EXTENSION_ID = 0x07,
107 PICTURE_CODING_EXTENSION_ID = 0x08,
108 PICTURE_SPATIAL_SCALABLE_EXTENSION_ID = 0x09,
109 PICTURE_TEMPORAL_SCALABLE_EXTENSION_ID = 0x0A,
110 CAMERA_PARAMETERS_EXTENSION_ID = 0x0B,
111 ITU_T_EXTENSION_ID = 0x0C,
114 /*****************************************************************************
115 * Local prototypes
116 *****************************************************************************/
117 typedef struct
120 * Input properties
122 packetizer_t packetizer;
124 /* Sequence header and extension */
125 block_t *p_seq;
126 block_t *p_ext;
128 /* Current frame being built */
129 block_t *p_frame;
130 block_t **pp_last;
132 bool b_frame_slice;
133 vlc_tick_t i_pts;
134 vlc_tick_t i_dts;
136 date_t dts;
137 date_t prev_iframe_dts;
139 /* Sequence properties */
140 uint16_t i_h_size_value;
141 uint16_t i_v_size_value;
142 uint8_t i_aspect_ratio_info;
143 uint8_t i_frame_rate_value;
144 uint32_t i_bitratelower18;
145 /* Extended Sequence properties (MPEG2) */
146 uint8_t i_h_size_ext;
147 uint8_t i_v_size_ext;
148 uint16_t i_bitrateupper12;
149 bool b_seq_progressive;
150 bool b_low_delay;
151 uint8_t i_frame_rate_ext_n;
152 uint8_t i_frame_rate_ext_d;
154 /* Picture properties */
155 int i_temporal_ref;
156 int i_prev_temporal_ref;
157 int i_picture_type;
158 int i_picture_structure;
159 int i_top_field_first;
160 int i_repeat_first_field;
161 int i_progressive_frame;
163 vlc_tick_t i_last_ref_pts;
165 vlc_tick_t i_last_frame_pts;
166 uint16_t i_last_frame_refid;
168 bool b_second_field;
170 /* Number of pictures since last sequence header */
171 unsigned i_seq_old;
173 /* Sync behaviour */
174 bool b_sync_on_intra_frame;
175 bool b_waiting_iframe;
176 int i_next_block_flags;
178 /* */
179 bool b_cc_reset;
180 uint32_t i_cc_flags;
181 vlc_tick_t i_cc_pts;
182 vlc_tick_t i_cc_dts;
183 cc_data_t cc;
184 } decoder_sys_t;
186 static block_t *Packetize( decoder_t *, block_t ** );
187 static void PacketizeFlush( decoder_t * );
188 static block_t *GetCc( decoder_t *p_dec, decoder_cc_desc_t * );
190 static void PacketizeReset( void *p_private, bool b_broken );
191 static block_t *PacketizeParse( void *p_private, bool *pb_ts_used, block_t * );
192 static int PacketizeValidate( void *p_private, block_t * );
193 static block_t * PacketizeDrain( void *p_private );
195 static block_t *ParseMPEGBlock( decoder_t *, block_t * );
197 static const uint8_t p_mp2v_startcode[3] = { 0x00, 0x00, 0x01 };
199 /*****************************************************************************
200 * Open:
201 *****************************************************************************/
202 static int Open( vlc_object_t *p_this )
204 decoder_t *p_dec = (decoder_t*)p_this;
205 decoder_sys_t *p_sys;
207 if( p_dec->fmt_in.i_codec != VLC_CODEC_MPGV &&
208 p_dec->fmt_in.i_codec != VLC_CODEC_MP2V )
209 return VLC_EGENERIC;
211 p_dec->p_sys = p_sys = malloc( sizeof( decoder_sys_t ) );
212 if( !p_dec->p_sys )
213 return VLC_ENOMEM;
214 memset( p_dec->p_sys, 0, sizeof( decoder_sys_t ) );
216 p_dec->fmt_out.i_codec = VLC_CODEC_MPGV;
217 p_dec->fmt_out.i_original_fourcc = p_dec->fmt_in.i_original_fourcc;
219 /* Misc init */
220 packetizer_Init( &p_sys->packetizer,
221 p_mp2v_startcode, sizeof(p_mp2v_startcode), startcode_FindAnnexB,
222 NULL, 0, 4,
223 PacketizeReset, PacketizeParse, PacketizeValidate, PacketizeDrain,
224 p_dec );
226 p_sys->p_seq = NULL;
227 p_sys->p_ext = NULL;
228 p_sys->p_frame = NULL;
229 p_sys->pp_last = &p_sys->p_frame;
230 p_sys->b_frame_slice = false;
232 p_sys->i_dts =
233 p_sys->i_pts = VLC_TICK_INVALID;
235 unsigned num, den;
236 if( p_dec->fmt_in.video.i_frame_rate && p_dec->fmt_in.video.i_frame_rate_base )
238 num = p_dec->fmt_in.video.i_frame_rate;
239 den = p_dec->fmt_in.video.i_frame_rate_base;
241 else
243 num = 30000;
244 den = 1001;
246 date_Init( &p_sys->dts, 2 * num, den ); /* fields / den */
247 date_Init( &p_sys->prev_iframe_dts, 2 * num, den );
249 p_sys->i_h_size_value = 0;
250 p_sys->i_v_size_value = 0;
251 p_sys->i_aspect_ratio_info = 0;
252 p_sys->i_frame_rate_value = 0;
253 p_sys->i_bitratelower18 = 0;
254 p_sys->i_bitrateupper12 = 0;
255 p_sys->i_h_size_ext = 0;
256 p_sys->i_v_size_ext = 0;
257 p_sys->b_seq_progressive = true;
258 p_sys->b_low_delay = false;
259 p_sys->i_frame_rate_ext_n = 0;
260 p_sys->i_frame_rate_ext_d = 0;
261 p_sys->i_seq_old = 0;
263 p_sys->i_temporal_ref = 0;
264 p_sys->i_prev_temporal_ref = 2048;
265 p_sys->i_picture_type = 0;
266 p_sys->i_picture_structure = 0x03; /* frame */
267 p_sys->i_top_field_first = 0;
268 p_sys->i_repeat_first_field = 0;
269 p_sys->i_progressive_frame = 0;
271 p_sys->i_last_ref_pts = VLC_TICK_INVALID;
272 p_sys->b_second_field = 0;
274 p_sys->i_next_block_flags = 0;
276 p_sys->i_last_frame_refid = 0;
278 p_sys->b_waiting_iframe =
279 p_sys->b_sync_on_intra_frame = var_CreateGetBool( p_dec, "packetizer-mpegvideo-sync-iframe" );
280 if( p_sys->b_sync_on_intra_frame )
281 msg_Dbg( p_dec, "syncing on intra frame now" );
283 p_sys->b_cc_reset = false;
284 p_sys->i_cc_pts = 0;
285 p_sys->i_cc_dts = 0;
286 p_sys->i_cc_flags = 0;
287 cc_Init( &p_sys->cc );
289 p_dec->pf_packetize = Packetize;
290 p_dec->pf_flush = PacketizeFlush;
291 p_dec->pf_get_cc = GetCc;
293 return VLC_SUCCESS;
296 /*****************************************************************************
297 * Close:
298 *****************************************************************************/
299 static void Close( vlc_object_t *p_this )
301 decoder_t *p_dec = (decoder_t*)p_this;
302 decoder_sys_t *p_sys = p_dec->p_sys;
304 if( p_sys->p_seq )
306 block_Release( p_sys->p_seq );
308 if( p_sys->p_ext )
310 block_Release( p_sys->p_ext );
312 if( p_sys->p_frame )
314 block_ChainRelease( p_sys->p_frame );
316 packetizer_Clean( &p_sys->packetizer );
318 var_Destroy( p_dec, "packetizer-mpegvideo-sync-iframe" );
320 free( p_sys );
323 /*****************************************************************************
324 * Packetize:
325 *****************************************************************************/
326 static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
328 decoder_sys_t *p_sys = p_dec->p_sys;
330 return packetizer_Packetize( &p_sys->packetizer, pp_block );
333 static void PacketizeFlush( decoder_t *p_dec )
335 decoder_sys_t *p_sys = p_dec->p_sys;
337 packetizer_Flush( &p_sys->packetizer );
340 /*****************************************************************************
341 * GetCc:
342 *****************************************************************************/
343 static block_t *GetCc( decoder_t *p_dec, decoder_cc_desc_t *p_desc )
345 decoder_sys_t *p_sys = p_dec->p_sys;
346 block_t *p_cc;
348 if( !p_sys->cc.b_reorder && p_sys->cc.i_data <= 0 )
349 return NULL;
351 p_cc = block_Alloc( p_sys->cc.i_data );
352 if( p_cc )
354 memcpy( p_cc->p_buffer, p_sys->cc.p_data, p_sys->cc.i_data );
355 p_cc->i_dts =
356 p_cc->i_pts = p_sys->cc.b_reorder ? p_sys->i_cc_pts : p_sys->i_cc_dts;
357 p_cc->i_flags = p_sys->i_cc_flags & BLOCK_FLAG_TYPE_MASK;
359 p_desc->i_608_channels = p_sys->cc.i_608channels;
360 p_desc->i_708_channels = p_sys->cc.i_708channels;
361 p_desc->i_reorder_depth = p_sys->cc.b_reorder ? 0 : -1;
363 cc_Flush( &p_sys->cc );
364 return p_cc;
367 /*****************************************************************************
368 * ProcessSequenceParameters
369 *****************************************************************************/
370 static void ProcessSequenceParameters( decoder_t *p_dec )
372 decoder_sys_t *p_sys = p_dec->p_sys;
373 video_format_t *fmt = &p_dec->fmt_out.video;
375 /* Picture size */
376 fmt->i_visible_width = p_sys->i_h_size_value + (p_sys->i_h_size_ext << 14);
377 fmt->i_width = (fmt->i_visible_width + 0x0F) & ~0x0F;
378 fmt->i_visible_height = p_sys->i_v_size_value + (p_sys->i_v_size_ext << 14);
379 if( p_sys->b_seq_progressive )
380 fmt->i_height = (fmt->i_visible_height + 0x0F) & ~0x0F;
381 else
382 fmt->i_height = (fmt->i_visible_height + 0x1F) & ~0x1F;
384 /* Bitrate */
385 if( p_dec->fmt_out.i_bitrate == 0 )
386 p_dec->fmt_out.i_bitrate = ((p_sys->i_bitrateupper12 << 18) |
387 p_sys->i_bitratelower18) * 400;
389 /* Frame Rate */
391 /* Only of not specified by container */
392 if ( !p_dec->fmt_in.video.i_frame_rate ||
393 !p_dec->fmt_in.video.i_frame_rate_base )
395 static const int code_to_frame_rate[16][2] =
397 { 1, 1 }, /* invalid */
398 { 24000, 1001 }, { 24, 1 }, { 25, 1 }, { 30000, 1001 },
399 { 30, 1 }, { 50, 1 }, { 60000, 1001 }, { 60, 1 },
400 /* Unofficial 15fps from Xing*/
401 { 15, 1 },
402 /* Unofficial economy rates from libmpeg3 */
403 { 5, 1 }, { 10, 1 }, { 12, 1 }, { 15, 1 },
404 { 1, 1 }, { 1, 1 } /* invalid */
407 /* frames / den */
408 unsigned num = code_to_frame_rate[p_sys->i_frame_rate_value][0] << 1;
409 unsigned den = code_to_frame_rate[p_sys->i_frame_rate_value][1];
410 if( p_sys->i_frame_rate_ext_n || p_sys->i_frame_rate_ext_d )
412 vlc_ureduce( &num, &den,
413 num * (1 + p_sys->i_frame_rate_ext_n),
414 den * (1 + p_sys->i_frame_rate_ext_d),
415 CLOCK_FREQ );
418 if( num && den ) /* fields / den */
420 date_Change( &p_sys->dts, num, den );
421 date_Change( &p_sys->prev_iframe_dts, num, den );
425 if( fmt->i_frame_rate != (p_sys->dts.i_divider_num >> 1) ||
426 fmt->i_frame_rate_base != p_sys->dts.i_divider_den )
428 fmt->i_frame_rate = p_sys->dts.i_divider_num >> 1;
429 fmt->i_frame_rate_base = p_sys->dts.i_divider_den;
431 msg_Dbg( p_dec, "size %ux%u/%ux%u fps %u:%u",
432 fmt->i_visible_width, fmt->i_visible_height,
433 fmt->i_width, fmt->i_height,
434 fmt->i_frame_rate, fmt->i_frame_rate_base);
438 /*****************************************************************************
439 * OutputFrame: assemble and tag frame
440 *****************************************************************************/
441 static block_t *OutputFrame( decoder_t *p_dec )
443 decoder_sys_t *p_sys = p_dec->p_sys;
444 block_t *p_pic = NULL;
446 if( !p_sys->p_frame )
447 return NULL;
449 ProcessSequenceParameters( p_dec );
451 p_pic = block_ChainGather( p_sys->p_frame );
452 if( p_pic == NULL )
454 p_sys->p_frame = NULL;
455 p_sys->pp_last = &p_sys->p_frame;
456 p_sys->b_frame_slice = false;
457 return p_pic;
460 unsigned i_num_fields;
462 if( !p_sys->b_seq_progressive && p_sys->i_picture_structure != 0x03 /* Field Picture */ )
463 i_num_fields = 1;
464 else
465 i_num_fields = 2;
467 if( p_sys->b_seq_progressive )
469 if( p_sys->i_top_field_first == 0 &&
470 p_sys->i_repeat_first_field == 1 )
472 i_num_fields *= 2;
474 else if( p_sys->i_top_field_first == 1 &&
475 p_sys->i_repeat_first_field == 1 )
477 i_num_fields *= 3;
480 else
482 if( p_sys->i_picture_structure == 0x03 /* Frame Picture */ )
484 if( p_sys->i_progressive_frame && p_sys->i_repeat_first_field )
486 i_num_fields += 1;
491 switch ( p_sys->i_picture_type )
493 case 0x01:
494 p_pic->i_flags |= BLOCK_FLAG_TYPE_I;
495 break;
496 case 0x02:
497 p_pic->i_flags |= BLOCK_FLAG_TYPE_P;
498 break;
499 case 0x03:
500 p_pic->i_flags |= BLOCK_FLAG_TYPE_B;
501 break;
504 if( !p_sys->b_seq_progressive )
506 if( p_sys->i_picture_structure < 0x03 )
508 p_pic->i_flags |= BLOCK_FLAG_SINGLE_FIELD;
509 p_pic->i_flags |= (p_sys->i_picture_structure == 0x01) ? BLOCK_FLAG_TOP_FIELD_FIRST
510 : BLOCK_FLAG_BOTTOM_FIELD_FIRST;
512 else /* if( p_sys->i_picture_structure == 0x03 ) */
514 p_pic->i_flags |= (p_sys->i_top_field_first) ? BLOCK_FLAG_TOP_FIELD_FIRST
515 : BLOCK_FLAG_BOTTOM_FIELD_FIRST;
519 /* Special case for DVR-MS where we need to fully build pts from scratch
520 * and only use first dts as it does not monotonically increase
521 * This will NOT work with frame repeats and such, as we would need to fully
522 * fill the DPB to get accurate pts timings. */
523 if( unlikely( p_dec->fmt_in.i_original_fourcc == VLC_FOURCC( 'D','V','R',' ') ) )
525 const bool b_first_xmited = (p_sys->i_prev_temporal_ref != p_sys->i_temporal_ref );
527 if( ( p_pic->i_flags & BLOCK_FLAG_TYPE_I ) && b_first_xmited )
529 if( date_Get( &p_sys->prev_iframe_dts ) == VLC_TICK_INVALID )
531 if( p_sys->i_dts != VLC_TICK_INVALID )
533 date_Set( &p_sys->dts, p_sys->i_dts );
535 else
537 if( date_Get( &p_sys->dts ) == VLC_TICK_INVALID )
539 date_Set( &p_sys->dts, VLC_TICK_0 );
543 p_sys->prev_iframe_dts = p_sys->dts;
546 p_pic->i_dts = date_Get( &p_sys->dts );
548 /* Compute pts from poc */
549 date_t datepts = p_sys->prev_iframe_dts;
550 date_Increment( &datepts, (1 + p_sys->i_temporal_ref) * 2 );
552 /* Field picture second field case */
553 if( p_sys->i_picture_structure != 0x03 )
555 /* first sent is not the first in display order */
556 if( (p_sys->i_picture_structure >> 1) != !p_sys->i_top_field_first &&
557 b_first_xmited )
559 date_Increment( &datepts, 2 );
563 p_pic->i_pts = date_Get( &datepts );
565 if( date_Get( &p_sys->dts ) != VLC_TICK_INVALID )
567 date_Increment( &p_sys->dts, i_num_fields );
569 p_pic->i_length = date_Get( &p_sys->dts ) - p_pic->i_dts;
571 p_sys->i_prev_temporal_ref = p_sys->i_temporal_ref;
573 else /* General case, use demuxer's dts/pts when set or interpolate */
575 if( p_sys->b_low_delay || p_sys->i_picture_type == 0x03 )
577 /* Trivial case (DTS == PTS) */
578 /* Correct interpolated dts when we receive a new pts/dts */
579 if( p_sys->i_pts != VLC_TICK_INVALID )
580 date_Set( &p_sys->dts, p_sys->i_pts );
581 if( p_sys->i_dts != VLC_TICK_INVALID )
582 date_Set( &p_sys->dts, p_sys->i_dts );
584 else
586 /* Correct interpolated dts when we receive a new pts/dts */
587 if(p_sys->i_last_ref_pts != VLC_TICK_INVALID && !p_sys->b_second_field)
588 date_Set( &p_sys->dts, p_sys->i_last_ref_pts );
589 if( p_sys->i_dts != VLC_TICK_INVALID )
590 date_Set( &p_sys->dts, p_sys->i_dts );
592 if( !p_sys->b_second_field )
593 p_sys->i_last_ref_pts = p_sys->i_pts;
596 p_pic->i_dts = date_Get( &p_sys->dts );
598 /* Set PTS only if we have a B frame or if it comes from the stream */
599 if( p_sys->i_pts != VLC_TICK_INVALID )
601 p_pic->i_pts = p_sys->i_pts;
603 else if( p_sys->i_picture_type == 0x03 )
605 p_pic->i_pts = p_pic->i_dts;
607 else
609 p_pic->i_pts = VLC_TICK_INVALID;
612 if( date_Get( &p_sys->dts ) != VLC_TICK_INVALID )
614 date_Increment( &p_sys->dts, i_num_fields );
616 p_pic->i_length = date_Get( &p_sys->dts ) - p_pic->i_dts;
620 #if 0
621 msg_Dbg( p_dec, "pic: type=%d struct=%d ref=%d nf=%d tff=%d dts=%"PRId64" ptsdiff=%"PRId64" len=%"PRId64,
622 p_sys->i_picture_type, p_sys->i_picture_structure, p_sys->i_temporal_ref, i_num_fields,
623 p_sys->i_top_field_first,
624 p_pic->i_dts , (p_pic->i_pts != VLC_TICK_INVALID) ? p_pic->i_pts - p_pic->i_dts : 0, p_pic->i_length );
625 #endif
628 /* Reset context */
629 p_sys->p_frame = NULL;
630 p_sys->pp_last = &p_sys->p_frame;
631 p_sys->b_frame_slice = false;
633 if( p_sys->i_picture_structure != 0x03 )
635 p_sys->b_second_field = !p_sys->b_second_field;
637 else
639 p_sys->b_second_field = 0;
642 /* CC */
643 p_sys->b_cc_reset = true;
644 p_sys->i_cc_pts = p_pic->i_pts;
645 p_sys->i_cc_dts = p_pic->i_dts;
646 p_sys->i_cc_flags = p_pic->i_flags & BLOCK_FLAG_TYPE_MASK;
648 return p_pic;
651 /*****************************************************************************
652 * Helpers:
653 *****************************************************************************/
654 static void PacketizeReset( void *p_private, bool b_flush )
656 VLC_UNUSED(b_flush);
657 decoder_t *p_dec = p_private;
658 decoder_sys_t *p_sys = p_dec->p_sys;
660 p_sys->i_next_block_flags = BLOCK_FLAG_DISCONTINUITY;
661 if( p_sys->p_frame )
663 block_ChainRelease( p_sys->p_frame );
664 p_sys->p_frame = NULL;
665 p_sys->pp_last = &p_sys->p_frame;
666 p_sys->b_frame_slice = false;
668 date_Set( &p_sys->dts, VLC_TICK_INVALID );
669 date_Set( &p_sys->prev_iframe_dts, VLC_TICK_INVALID );
670 p_sys->i_dts =
671 p_sys->i_pts =
672 p_sys->i_last_ref_pts = VLC_TICK_INVALID;
673 p_sys->b_waiting_iframe = p_sys->b_sync_on_intra_frame;
674 p_sys->i_prev_temporal_ref = 2048;
677 static block_t *PacketizeParse( void *p_private, bool *pb_ts_used, block_t *p_block )
679 decoder_t *p_dec = p_private;
680 decoder_sys_t *p_sys = p_dec->p_sys;
682 /* Check if we have a picture start code */
683 *pb_ts_used = p_block->p_buffer[3] == PICTURE_STARTCODE;
685 p_block = ParseMPEGBlock( p_dec, p_block );
686 if( p_block )
688 p_block->i_flags |= p_sys->i_next_block_flags;
689 p_sys->i_next_block_flags = 0;
691 else *pb_ts_used = false; /* only clear up if output */
693 return p_block;
696 static block_t * PacketizeDrain( void *p_private )
698 decoder_t *p_dec = p_private;
699 decoder_sys_t *p_sys = p_dec->p_sys;
701 if( p_sys->b_waiting_iframe || !p_sys->b_frame_slice )
702 return NULL;
704 block_t *p_out = OutputFrame( p_dec );
705 if( p_out )
707 p_out->i_flags |= p_sys->i_next_block_flags;
708 p_sys->i_next_block_flags = 0;
711 return p_out;
714 static int PacketizeValidate( void *p_private, block_t *p_au )
716 decoder_t *p_dec = p_private;
717 decoder_sys_t *p_sys = p_dec->p_sys;
719 if( unlikely( p_sys->b_waiting_iframe ) )
721 if( (p_au->i_flags & BLOCK_FLAG_TYPE_I) == 0 )
723 msg_Dbg( p_dec, "waiting on intra frame" );
724 return VLC_EGENERIC;
726 msg_Dbg( p_dec, "synced on intra frame" );
727 p_sys->b_waiting_iframe = false;
730 /* We've just started the stream, wait for the first PTS.
731 * We discard here so we can still get the sequence header. */
732 if( unlikely( p_sys->i_dts == VLC_TICK_INVALID && p_sys->i_pts == VLC_TICK_INVALID &&
733 date_Get( &p_sys->dts ) == VLC_TICK_INVALID ))
735 msg_Dbg( p_dec, "need a starting pts/dts" );
736 return VLC_EGENERIC;
739 /* When starting the stream we can have the first frame with
740 * an invalid DTS (i_interpolated_pts is initialized to VLC_TICK_INVALID) */
741 if( unlikely( p_au->i_dts == VLC_TICK_INVALID ) )
742 p_au->i_dts = p_au->i_pts;
744 return VLC_SUCCESS;
746 /*****************************************************************************
747 * ParseMPEGBlock: Re-assemble fragments into a block containing a picture
748 *****************************************************************************/
749 static block_t *ParseMPEGBlock( decoder_t *p_dec, block_t *p_frag )
751 decoder_sys_t *p_sys = p_dec->p_sys;
752 block_t *p_pic = NULL;
754 const enum mpeg_startcode_e startcode = p_frag->p_buffer[3];
756 * Check if previous picture is finished
758 if( ( p_sys->b_frame_slice &&
759 (startcode == PICTURE_STARTCODE || startcode > SLICE_STARTCODE_LAST ) ) &&
760 p_sys->p_seq == NULL )
762 /* We have a picture but without a sequence header we can't
763 * do anything */
764 msg_Dbg( p_dec, "waiting for sequence start" );
765 if( p_sys->p_frame ) block_ChainRelease( p_sys->p_frame );
766 p_sys->p_frame = NULL;
767 p_sys->pp_last = &p_sys->p_frame;
768 p_sys->b_frame_slice = false;
771 else if( p_sys->b_frame_slice &&
772 (startcode == PICTURE_STARTCODE || startcode > SLICE_STARTCODE_LAST) )
774 const bool b_eos = startcode == SEQUENCE_END_STARTCODE;
776 if( b_eos )
778 block_ChainLastAppend( &p_sys->pp_last, p_frag );
779 p_frag = NULL;
782 p_pic = OutputFrame( p_dec );
784 if( p_pic && b_eos )
785 p_pic->i_flags |= BLOCK_FLAG_END_OF_SEQUENCE;
788 if( !p_pic && p_sys->b_cc_reset )
790 p_sys->b_cc_reset = false;
791 cc_Flush( &p_sys->cc );
794 if( !p_frag )
795 return p_pic;
797 * Check info of current fragment
799 if( startcode == GROUP_STARTCODE )
801 /* Group start code */
802 unsigned i_fps = p_sys->dts.i_divider_num / (p_sys->dts.i_divider_den << 1);
803 if( p_sys->p_seq && p_sys->i_seq_old > i_fps )
805 /* Useful for mpeg1: repeat sequence header every second */
806 const block_t * params[2] = { p_sys->p_seq, p_sys->p_ext };
807 for( int i=0; i<2; i++ )
809 if( params[i] == NULL )
810 break;
811 block_t *p_dup = block_Duplicate( params[i] );
812 if( p_dup )
813 block_ChainLastAppend( &p_sys->pp_last, p_dup );
815 p_sys->i_seq_old = 0;
818 else if( startcode == SEQUENCE_HEADER_STARTCODE && p_frag->i_buffer >= 11 )
820 /* Sequence header code */
821 if( p_sys->p_seq ) block_Release( p_sys->p_seq );
822 if( p_sys->p_ext ) block_Release( p_sys->p_ext );
824 p_sys->p_seq = block_Duplicate( p_frag );
825 p_sys->i_seq_old = 0;
826 p_sys->p_ext = NULL;
828 p_sys->i_h_size_value = ( p_frag->p_buffer[4] << 4)|(p_frag->p_buffer[5] >> 4 );
829 p_sys->i_v_size_value = ( (p_frag->p_buffer[5]&0x0f) << 8 )|p_frag->p_buffer[6];
830 p_sys->i_aspect_ratio_info = p_frag->p_buffer[7] >> 4;
832 /* TODO: MPEG1 aspect ratio */
834 p_sys->i_frame_rate_value = p_frag->p_buffer[7] & 0x0f;
836 p_sys->i_bitratelower18 = (p_frag->p_buffer[ 8] << 12) |
837 (p_frag->p_buffer[ 9] << 4) |
838 (p_frag->p_buffer[10] & 0x0F);
840 else if( startcode == EXTENSION_STARTCODE && p_frag->i_buffer > 4 )
842 /* extension_start_code_identifier */
843 const enum extension_start_code_identifier_e extid = p_frag->p_buffer[4] >> 4;
845 /* Extension start code */
846 if( extid == SEQUENCE_EXTENSION_ID )
848 #if 0
849 static const int mpeg2_aspect[16][2] =
851 {0,1}, {1,1}, {4,3}, {16,9}, {221,100},
852 {0,1}, {0,1}, {0,1}, {0,1}, {0,1}, {0,1}, {0,1}, {0,1}, {0,1},
853 {0,1}, {0,1}
855 #endif
856 /* sequence extension */
857 if( p_sys->p_ext) block_Release( p_sys->p_ext );
858 p_sys->p_ext = block_Duplicate( p_frag );
860 if( p_frag->i_buffer >= 10 )
862 /* profile and level indication */
863 if( p_dec->fmt_out.i_profile == -1 )
865 const uint16_t profilelevel = ((p_frag->p_buffer[4] << 4) |
866 (p_frag->p_buffer[5] >> 4)) & 0xFF;
867 int i_profile = -1;
868 int i_level = -1;
869 switch( profilelevel )
871 case 0x82:
872 i_profile = PROFILE_MPEG2_422;
873 i_level = LEVEL_MPEG2_HIGH;
874 break;
875 case 0x85:
876 i_profile = PROFILE_MPEG2_422;
877 i_level = LEVEL_MPEG2_MAIN;
878 break;
879 case 0x8A:
880 i_profile = PROFILE_MPEG2_MULTIVIEW;
881 i_level = LEVEL_MPEG2_HIGH;
882 break;
883 case 0x8B:
884 i_profile = PROFILE_MPEG2_MULTIVIEW;
885 i_level = LEVEL_MPEG2_HIGH_1440;
886 break;
887 case 0x8D:
888 i_profile = PROFILE_MPEG2_MULTIVIEW;
889 i_level = LEVEL_MPEG2_MAIN;
890 break;
891 case 0x8E:
892 i_profile = PROFILE_MPEG2_MULTIVIEW;
893 i_level = LEVEL_MPEG2_LOW;
894 break;
895 default:
896 if( (profilelevel & 0x80) == 0 ) /* escape bit */
898 i_profile = (profilelevel >> 4) & 0x07;
899 i_level = profilelevel & 0x0F;
901 break;
903 p_dec->fmt_out.i_profile = i_profile;
904 p_dec->fmt_out.i_level = i_level;
907 p_sys->b_seq_progressive =
908 p_frag->p_buffer[5]&0x08 ? true : false;
910 p_sys->i_h_size_ext = ((p_frag->p_buffer[5] & 0x01) << 1) | (p_frag->p_buffer[6] >> 7);
911 p_sys->i_v_size_ext = (p_frag->p_buffer[6] >> 5) & 0x03;
913 p_sys->i_bitrateupper12 = ((p_frag->p_buffer[6] & 0x1F) << 8) | (p_frag->p_buffer[7] >> 1);
915 p_sys->b_low_delay =
916 p_frag->p_buffer[9]&0x80 ? true : false;
918 p_sys->i_frame_rate_ext_n = (p_frag->p_buffer[9] >> 5) & 0x03;
919 p_sys->i_frame_rate_ext_d = p_frag->p_buffer[9] & 0x1F;
922 /* Do not set aspect ratio : in case we're transcoding,
923 * transcode will take our fmt_out as a fmt_in to libmpeg2.
924 * libmpeg2.c will then believe that the user has requested
925 * a specific aspect ratio, which she hasn't. Thus in case
926 * of aspect ratio change, we're screwed. --Meuuh
928 #if 0
929 p_dec->fmt_out.video.i_sar_num =
930 mpeg2_aspect[p_sys->i_aspect_ratio_info][0] *
931 p_dec->fmt_out.video.i_height;
932 p_dec->fmt_out.video.i_sar_den =
933 mpeg2_aspect[p_sys->i_aspect_ratio_info][1] *
934 p_dec->fmt_out.video.i_width;
935 #endif
938 else if( extid == PICTURE_CODING_EXTENSION_ID && p_frag->i_buffer > 8 )
940 /* picture extension */
941 p_sys->i_picture_structure = p_frag->p_buffer[6]&0x03;
942 p_sys->i_top_field_first = p_frag->p_buffer[7] >> 7;
943 p_sys->i_repeat_first_field= (p_frag->p_buffer[7]>>1)&0x01;
944 p_sys->i_progressive_frame = p_frag->p_buffer[8] >> 7;
946 else if( extid == SEQUENCE_DISPLAY_EXTENSION_ID && p_frag->i_buffer > 8 )
948 /* Sequence display extension */
949 bool contains_color_description = (p_frag->p_buffer[4] & 0x01);
950 //uint8_t video_format = (p_frag->p_buffer[4] & 0x0f) >> 1;
952 if( contains_color_description && p_frag->i_buffer > 11 )
954 p_dec->fmt_out.video.primaries =
955 iso_23001_8_cp_to_vlc_primaries( p_frag->p_buffer[5] );
956 p_dec->fmt_out.video.transfer =
957 iso_23001_8_tc_to_vlc_xfer( p_frag->p_buffer[6] );
958 p_dec->fmt_out.video.space =
959 iso_23001_8_mc_to_vlc_coeffs( p_frag->p_buffer[7] );
964 else if( startcode == USER_DATA_STARTCODE && p_frag->i_buffer > 8 )
966 /* Frame Packing extension identifier as H262 2012 Amd4 Annex L */
967 if( !memcmp( &p_frag->p_buffer[4], "JP3D", 4 ) &&
968 p_frag->i_buffer > 11 && p_frag->p_buffer[8] == 0x03 &&
969 p_dec->fmt_in.video.multiview_mode == MULTIVIEW_2D )
971 video_multiview_mode_t mode;
972 switch( p_frag->p_buffer[9] & 0x7F )
974 case 0x03:
975 mode = MULTIVIEW_STEREO_SBS; break;
976 case 0x04:
977 mode = MULTIVIEW_STEREO_TB; break;
978 case 0x08:
979 default:
980 mode = MULTIVIEW_2D; break;
982 p_dec->fmt_out.video.multiview_mode = mode;
984 else
985 cc_ProbeAndExtract( &p_sys->cc, p_sys->i_top_field_first,
986 &p_frag->p_buffer[4], p_frag->i_buffer - 4 );
988 else if( startcode == PICTURE_STARTCODE )
990 /* Picture start code */
991 p_sys->i_seq_old++;
993 if( p_frag->i_buffer >= 6 )
995 p_sys->i_temporal_ref =
996 ( p_frag->p_buffer[4] << 2 )|(p_frag->p_buffer[5] >> 6);
997 p_sys->i_picture_type = ( p_frag->p_buffer[5] >> 3 ) & 0x03;
1000 /* Check if we can use timestamps */
1001 if(p_frag->i_dts != VLC_TICK_INVALID &&
1002 p_frag->i_dts <= p_sys->i_dts)
1004 date_t next = p_sys->dts;
1005 date_Set(&next, p_frag->i_dts);
1006 /* Because the prev timestamp could have been repeated though
1007 * helper, clear up if we are within 2 frames backward */
1008 if(date_Increment(&next, 4) >= p_sys->i_dts)
1009 p_frag->i_dts = p_frag->i_pts = VLC_TICK_INVALID; /* do not reuse */
1012 p_sys->i_dts = p_frag->i_dts;
1013 p_sys->i_pts = p_frag->i_pts;
1015 else if( startcode >= SLICE_STARTCODE_FIRST &&
1016 startcode <= SLICE_STARTCODE_LAST )
1018 /* Slice start code */
1019 p_sys->b_frame_slice = true;
1022 /* Append the block */
1023 block_ChainLastAppend( &p_sys->pp_last, p_frag );
1025 return p_pic;