1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2001, 2002 VideoLAN
5 * $Id: mpegvideo.c,v 1.23 2003/11/27 22:44:50 massiot Exp $
7 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8 * Eric Petit <titer@videolan.org>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
23 *****************************************************************************/
25 /*****************************************************************************
26 * Problem with this implementation:
28 * Although we should time-stamp each picture with a PTS, this isn't possible
29 * with the current implementation.
30 * The problem comes from the fact that for non-low-delay streams we can't
31 * calculate the PTS of pictures used as backward reference. Even the temporal
32 * reference number doesn't help here because all the pictures don't
33 * necessarily have the same duration (eg. 3:2 pulldown).
35 * However this doesn't really matter as far as the MPEG muxers are concerned
36 * because they allow having empty PTS fields. --gibalou
37 *****************************************************************************/
39 /*****************************************************************************
41 *****************************************************************************/
42 #include <stdlib.h> /* malloc(), free() */
45 #include <vlc/decoder.h>
46 #include <vlc/input.h>
48 /*****************************************************************************
50 *****************************************************************************/
51 static int Open ( vlc_object_t * );
52 static void Close( vlc_object_t * );
55 set_description( _("MPEG-I/II video packetizer") );
56 set_capability( "packetizer", 50 );
57 set_callbacks( Open, Close );
61 /*****************************************************************************
63 *****************************************************************************/
64 static block_t *Packetize( decoder_t *, block_t ** );
66 static int mpgv_FindStartCode( uint8_t **pp_start, uint8_t *p_end );
70 /* sequence header and extention */
74 /* current frame being building */
76 vlc_bool_t b_frame_slice;
77 vlc_bool_t b_frame_corrupted;
80 /* pts of current picture */
84 /* gathering buffer */
88 uint8_t *p_start, *p_old;
92 int i_frame_rate_base;
93 vlc_bool_t b_seq_progressive;
94 vlc_bool_t b_low_delay;
99 int i_picture_structure;
100 int i_top_field_first;
101 int i_repeat_first_field;
102 int i_progressive_frame;
105 int i_seq_old; /* How many picture from last seq */
109 mtime_t i_interpolated_dts;
110 mtime_t i_old_duration;
111 mtime_t i_last_ref_pts;
114 /*****************************************************************************
116 *****************************************************************************/
117 static int Open( vlc_object_t *p_this )
119 decoder_t *p_dec = (decoder_t*)p_this;
120 decoder_sys_t *p_sys;
122 if( p_dec->fmt_in.i_codec != VLC_FOURCC( 'm', 'p', 'g', '1' ) &&
123 p_dec->fmt_in.i_codec != VLC_FOURCC( 'm', 'p', 'g', '2' ) &&
124 p_dec->fmt_in.i_codec != VLC_FOURCC( 'm', 'p', 'g', 'v' ) )
129 es_format_Init( &p_dec->fmt_out, VIDEO_ES, VLC_FOURCC( 'm', 'p', 'g', 'v' ) );
130 p_dec->pf_packetize = Packetize;
132 p_dec->p_sys = p_sys = malloc( sizeof( decoder_sys_t ) );
136 p_sys->p_frame = NULL;
137 p_sys->b_frame_slice = VLC_FALSE;
138 p_sys->b_frame_corrupted = VLC_FALSE;
139 p_sys->b_gop = VLC_FALSE;
142 p_sys->i_buffer_size = 10000;
143 p_sys->p_buffer = malloc( p_sys->i_buffer_size );
144 p_sys->p_start = p_sys->p_buffer;
150 p_sys->i_frame_rate = 1;
151 p_sys->i_frame_rate_base = 1;
152 p_sys->b_seq_progressive = VLC_TRUE;
153 p_sys->b_low_delay = VLC_TRUE;
154 p_sys->i_seq_old = 0;
156 p_sys->i_temporal_ref = 0;
157 p_sys->i_picture_type = 0;
158 p_sys->i_picture_structure = 0x03; /* frame */
159 p_sys->i_top_field_first = 0;
160 p_sys->i_repeat_first_field = 0;
161 p_sys->i_progressive_frame = 0;
163 p_sys->i_interpolated_dts = 0;
164 p_sys->i_old_duration = 0;
165 p_sys->i_last_ref_pts = 0;
170 /*****************************************************************************
172 *****************************************************************************/
173 static void Close( vlc_object_t *p_this )
175 decoder_t *p_dec = (decoder_t*)p_this;
176 decoder_sys_t *p_sys = p_dec->p_sys;
180 block_Release( p_sys->p_seq );
184 block_Release( p_sys->p_ext );
188 block_Release( p_sys->p_frame );
190 free( p_sys->p_buffer );
194 /*****************************************************************************
196 *****************************************************************************/
197 static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
199 decoder_sys_t *p_sys = p_dec->p_sys;
200 block_t *p_chain_out = NULL;
203 if( pp_block == NULL || *pp_block == NULL )
210 if( p_block->b_discontinuity )
212 p_sys->b_frame_corrupted = VLC_TRUE;
216 if( p_sys->i_buffer + p_block->i_buffer > p_sys->i_buffer_size )
218 uint8_t *p_buffer = p_sys->p_buffer;
220 p_sys->i_buffer_size += p_block->i_buffer + 1024;
221 p_sys->p_buffer = realloc( p_sys->p_buffer, p_sys->i_buffer_size );
225 p_sys->p_start = p_sys->p_start - p_buffer + p_sys->p_buffer;
229 p_sys->p_old = p_sys->p_old - p_buffer + p_sys->p_buffer;
233 memcpy( &p_sys->p_buffer[p_sys->i_buffer], p_block->p_buffer,
235 p_sys->i_buffer += p_block->i_buffer;
238 if( p_sys->i_buffer > 10*1000000 )
240 msg_Err( p_dec, "mmh reseting context" );
244 /* Split data in block */
247 if( mpgv_FindStartCode( &p_sys->p_start, &p_sys->p_buffer[p_sys->i_buffer] ) )
249 block_Release( p_block );
251 if( p_sys->p_seq == NULL )
253 block_ChainRelease( p_chain_out );
261 /* Extract the data */
262 int i_frag = p_sys->p_start - p_sys->p_old;
263 block_t *p_frag = block_New( p_dec, i_frag );
265 memcpy( p_frag->p_buffer, p_sys->p_old, i_frag );
266 if( i_frag < p_sys->i_buffer )
268 memmove( p_sys->p_buffer, &p_sys->p_buffer[i_frag],
269 p_sys->i_buffer - i_frag );
271 p_sys->i_buffer -= i_frag;
272 p_sys->p_start -= i_frag;
273 p_sys->p_old -= i_frag;
275 if( p_sys->b_frame_slice && ( p_frag->p_buffer[3] == 0x00 || p_frag->p_buffer[3] > 0xaf ) )
277 /* We have a complete picture output it */
278 if( p_sys->p_seq == NULL )
280 msg_Dbg( p_dec, "waiting sequence start" );
281 block_ChainRelease( p_sys->p_frame );
283 else if( p_sys->i_dts <= 0 && p_sys->i_pts <= 0 && p_sys->i_interpolated_dts <= 0 )
285 msg_Dbg( p_dec, "need a starting pts/dts" );
286 block_ChainRelease( p_sys->p_frame );
288 else if( p_sys->b_frame_corrupted )
290 msg_Warn( p_dec, "trashing a corrupted picture" );
291 block_ChainRelease( p_sys->p_frame );
292 p_sys->b_frame_corrupted = VLC_FALSE;
296 block_t *p_pic = block_ChainGather( p_sys->p_frame );
297 mtime_t i_duration = (mtime_t)( 1000000 * p_sys->i_frame_rate_base / p_sys->i_frame_rate);
299 if( !p_sys->b_seq_progressive && p_sys->i_picture_structure != 0x03 )
304 if( p_sys->b_seq_progressive )
306 if( p_sys->i_top_field_first == 0 && p_sys->i_repeat_first_field == 1 )
310 else if( p_sys->i_top_field_first == 1 && p_sys->i_repeat_first_field == 1 )
317 if( p_sys->i_picture_structure == 0x03 )
319 if( p_sys->i_progressive_frame && p_sys->i_repeat_first_field )
321 i_duration += i_duration / 2;
326 if( p_sys->b_low_delay || p_sys->i_picture_type == 0x03 )
328 /* Trivial case (DTS == PTS) */
329 /* Correct interpolated dts when we receive a new pts/dts */
330 if( p_sys->i_pts > 0 ) p_sys->i_interpolated_dts = p_sys->i_pts;
331 if( p_sys->i_dts > 0 ) p_sys->i_interpolated_dts = p_sys->i_dts;
335 /* Correct interpolated dts when we receive a new pts/dts */
336 if( p_sys->i_last_ref_pts > 0 )
337 p_sys->i_interpolated_dts = p_sys->i_last_ref_pts;
338 if( p_sys->i_dts > 0 ) p_sys->i_interpolated_dts = p_sys->i_dts;
340 p_sys->i_last_ref_pts = p_sys->i_pts;
343 p_pic->i_dts = p_sys->i_interpolated_dts;
344 /* Set PTS only if I frame or come from stream */
345 if( p_sys->i_pts > 0 )
347 p_pic->i_pts = p_sys->i_pts;
349 else if( p_sys->i_picture_type == 0x03 )
351 p_pic->i_pts = p_pic->i_dts;
358 if( p_sys->b_low_delay || p_sys->i_picture_type == 0x03 )
360 /* Trivial case (DTS == PTS) */
361 p_sys->i_interpolated_dts += i_duration;
365 p_sys->i_interpolated_dts += p_sys->i_old_duration;
366 p_sys->i_old_duration = i_duration;
369 p_pic->i_length = p_sys->i_interpolated_dts - p_pic->i_dts;
371 //msg_Dbg( p_dec, "pic: type=%d dts=%lld pts-dts=%lld", p_sys->i_picture_type, p_pic->i_dts, p_pic->i_pts - p_pic->i_dts);
373 block_ChainAppend( &p_chain_out, p_pic );
378 p_sys->p_frame = NULL;
379 p_sys->b_frame_slice = VLC_FALSE;
380 p_sys->b_gop = VLC_FALSE;
385 if( p_frag->p_buffer[3] == 0xb8 )
388 p_sys->i_seq_old > p_sys->i_frame_rate/p_sys->i_frame_rate_base )
390 /* Usefull for mpeg1: repeat sequence header every second */
391 block_ChainAppend( &p_sys->p_frame,
392 block_Duplicate( p_sys->p_seq ) );
395 block_ChainAppend( &p_sys->p_frame,
396 block_Duplicate( p_sys->p_ext ) );
399 p_sys->i_seq_old = 0;
401 p_sys->b_gop = VLC_TRUE;
403 else if( p_frag->p_buffer[3] == 0xb3 )
405 static const int code_to_frame_rate[16][2] =
407 { 1, 1 }, /* invalid */
408 { 24000, 1001 }, { 24, 1 }, { 25, 1 }, { 30000, 1001 },
409 { 30, 1 }, { 50, 1 }, { 60000, 1001 }, { 60, 1 },
410 { 1, 1 }, { 1, 1 }, { 1, 1 }, { 1, 1 }, /* invalid */
411 { 1, 1 }, { 1, 1 }, { 1, 1 } /* invalid */
414 /* sequence header */
417 block_Release( p_sys->p_seq );
421 block_Release( p_sys->p_ext );
424 p_sys->p_seq = block_Duplicate( p_frag );
425 p_sys->i_seq_old = 0;
427 p_dec->fmt_out.video.i_width = ( p_frag->p_buffer[4] << 4)|(p_frag->p_buffer[5] >> 4 );
428 p_dec->fmt_out.video.i_height= ( (p_frag->p_buffer[5]&0x0f) << 8 )|p_frag->p_buffer[6];
430 p_sys->i_frame_rate = code_to_frame_rate[p_frag->p_buffer[7]&0x0f][0];
431 p_sys->i_frame_rate_base = code_to_frame_rate[p_frag->p_buffer[7]&0x0f][1];
434 p_sys->b_seq_progressive = VLC_TRUE;
435 p_sys->b_low_delay = VLC_TRUE;
438 msg_Dbg( p_dec, "Size %dx%d fps=%.3f",
439 p_dec->fmt_out.video.i_width,
440 p_dec->fmt_out.video.i_height,
441 (float)p_sys->i_frame_rate / (float)p_sys->i_frame_rate_base );
444 else if( p_frag->p_buffer[3] == 0xb5 )
446 int i_type = p_frag->p_buffer[4] >> 4;
447 /* extention start code */
450 /* sequence extention */
453 block_Release( p_sys->p_ext );
455 p_sys->p_ext = block_Duplicate( p_frag );
457 if( p_frag->i_buffer >= 10 )
459 p_sys->b_seq_progressive = p_frag->p_buffer[5]&0x08 ? VLC_TRUE : VLC_FALSE;
460 p_sys->b_low_delay = p_frag->p_buffer[9]&0x80 ? VLC_TRUE : VLC_FALSE;
463 else if( i_type == 0x08 )
465 /* picture extention */
466 p_sys->i_picture_structure = p_frag->p_buffer[6]&0x03;
467 p_sys->i_top_field_first = p_frag->p_buffer[7] >> 7;
468 p_sys->i_repeat_first_field= (p_frag->p_buffer[7]>>1)&0x01;
469 p_sys->i_progressive_frame = p_frag->p_buffer[8] >> 7;
472 else if( p_frag->p_buffer[3] == 0x00 )
477 if( p_frag->i_buffer >= 6 )
479 p_sys->i_temporal_ref = ( p_frag->p_buffer[4] << 2 )|(p_frag->p_buffer[5] >> 6);
480 p_sys->i_picture_type = ( p_frag->p_buffer[5] >> 3 )&0x03;
482 if( !p_sys->b_frame_slice )
484 p_sys->i_dts = p_block->i_dts; p_block->i_dts = 0;
485 p_sys->i_pts = p_block->i_pts; p_block->i_pts = 0;
488 else if( p_frag->p_buffer[3] >= 0x01 && p_frag->p_buffer[3] <= 0xaf )
491 p_sys->b_frame_slice = VLC_TRUE;
494 /* Append the block */
495 block_ChainAppend( &p_sys->p_frame, p_frag );
497 p_sys->p_old = p_sys->p_start;
502 static int mpgv_FindStartCode( uint8_t **pp_start, uint8_t *p_end )
504 uint8_t *p = *pp_start;
506 for( p = *pp_start; p < p_end - 4; p++ )
508 if( p[0] == 0 && p[1] == 0 && p[2] == 1 )