X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;ds=sidebyside;f=modules%2Fpacketizer%2Fmpegvideo.c;h=4380a037164cac355ea4c8a49fee2b7ec09d31ee;hb=130e82918269cab7b5f06129a81f34d627a9600d;hp=8129ddd6e5a58c3eb3f385b45f87b2ad9f913ef9;hpb=02d6bac4129293e33ae12057fd6e418f20d7d771;p=vlc diff --git a/modules/packetizer/mpegvideo.c b/modules/packetizer/mpegvideo.c index 8129ddd6e5..4380a03716 100644 --- a/modules/packetizer/mpegvideo.c +++ b/modules/packetizer/mpegvideo.c @@ -1,12 +1,12 @@ /***************************************************************************** * mpegvideo.c: parse and packetize an MPEG1/2 video stream ***************************************************************************** - * Copyright (C) 2001, 2002 VideoLAN - * $Id: mpegvideo.c,v 1.28 2004/01/27 14:05:33 gbazin Exp $ + * Copyright (C) 2001, 2002 the VideoLAN team + * $Id$ * * Authors: Laurent Aimar * Eric Petit - * Gildas Bazin + * Gildas Bazin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -55,6 +55,8 @@ static int Open ( vlc_object_t * ); static void Close( vlc_object_t * ); vlc_module_begin(); + set_category( CAT_SOUT ); + set_subcategory( SUBCAT_SOUT_PACKETIZER ); set_description( _("MPEG-I/II video packetizer") ); set_capability( "packetizer", 50 ); set_callbacks( Open, Close ); @@ -76,12 +78,14 @@ struct decoder_sys_t int i_offset; uint8_t p_startcode[3]; - /* Sequence header and extention */ + /* Sequence header and extension */ block_t *p_seq; block_t *p_ext; /* Current frame being built */ block_t *p_frame; + block_t **pp_last; + vlc_bool_t b_frame_slice; mtime_t i_pts; mtime_t i_dts; @@ -92,6 +96,7 @@ struct decoder_sys_t vlc_bool_t b_seq_progressive; vlc_bool_t b_low_delay; int i_aspect_ratio_info; + vlc_bool_t b_inited; /* Picture properties */ int i_temporal_ref; @@ -105,7 +110,7 @@ struct decoder_sys_t mtime_t i_old_duration; mtime_t i_last_ref_pts; - /* Number of pictues since last sequence header */ + /* Number of pictures since last sequence header */ int i_seq_old; }; @@ -146,6 +151,7 @@ static int Open( vlc_object_t *p_this ) p_sys->p_seq = NULL; p_sys->p_ext = NULL; p_sys->p_frame = NULL; + p_sys->pp_last = &p_sys->p_frame; p_sys->b_frame_slice = VLC_FALSE; p_sys->i_dts = p_sys->i_pts = 0; @@ -162,6 +168,7 @@ static int Open( vlc_object_t *p_this ) p_sys->i_top_field_first = 0; p_sys->i_repeat_first_field = 0; p_sys->i_progressive_frame = 0; + p_sys->b_inited = 0; p_sys->i_interpolated_dts = 0; p_sys->i_old_duration = 0; @@ -209,12 +216,15 @@ static block_t *Packetize( decoder_t *p_dec, block_t **pp_block ) return NULL; } - if( (*pp_block)->b_discontinuity ) + if( (*pp_block)->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) ) { p_sys->i_state = STATE_NOSYNC; if( p_sys->p_frame ) block_ChainRelease( p_sys->p_frame ); p_sys->p_frame = NULL; + p_sys->pp_last = &p_sys->p_frame; p_sys->b_frame_slice = VLC_FALSE; + block_Release( *pp_block ); + return NULL; } block_BytestreamPush( &p_sys->bytestream, *pp_block ); @@ -260,6 +270,7 @@ static block_t *Packetize( decoder_t *p_dec, block_t **pp_block ) /* Get the new fragment and set the pts/dts */ p_pic = block_New( p_dec, p_sys->i_offset ); + block_BytestreamFlush( &p_sys->bytestream ); p_pic->i_pts = p_sys->bytestream.p_block->i_pts; p_pic->i_dts = p_sys->bytestream.p_block->i_dts; @@ -328,6 +339,7 @@ static block_t *ParseMPEGBlock( decoder_t *p_dec, block_t *p_frag ) msg_Dbg( p_dec, "waiting for sequence start" ); if( p_sys->p_frame ) block_ChainRelease( p_sys->p_frame ); p_sys->p_frame = NULL; + p_sys->pp_last = &p_sys->p_frame; p_sys->b_frame_slice = VLC_FALSE; } @@ -414,6 +426,19 @@ static block_t *ParseMPEGBlock( decoder_t *p_dec, block_t *p_frag ) p_sys->i_old_duration = i_duration; } + switch ( p_sys->i_picture_type ) + { + case 0x01: + p_pic->i_flags |= BLOCK_FLAG_TYPE_I; + break; + case 0x02: + p_pic->i_flags |= BLOCK_FLAG_TYPE_P; + break; + case 0x03: + p_pic->i_flags |= BLOCK_FLAG_TYPE_B; + break; + } + p_pic->i_length = p_sys->i_interpolated_dts - p_pic->i_dts; #if 0 @@ -423,6 +448,7 @@ static block_t *ParseMPEGBlock( decoder_t *p_dec, block_t *p_frag ) /* Reset context */ p_sys->p_frame = NULL; + p_sys->pp_last = &p_sys->p_frame; p_sys->b_frame_slice = VLC_FALSE; } @@ -436,12 +462,10 @@ static block_t *ParseMPEGBlock( decoder_t *p_dec, block_t *p_frag ) p_sys->i_seq_old > p_sys->i_frame_rate/p_sys->i_frame_rate_base ) { /* Usefull for mpeg1: repeat sequence header every second */ - block_ChainAppend( &p_sys->p_frame, - block_Duplicate( p_sys->p_seq ) ); + block_ChainLastAppend( &p_sys->pp_last, block_Duplicate( p_sys->p_seq ) ); if( p_sys->p_ext ) { - block_ChainAppend( &p_sys->p_frame, - block_Duplicate( p_sys->p_ext ) ); + block_ChainLastAppend( &p_sys->pp_last, block_Duplicate( p_sys->p_ext ) ); } p_sys->i_seq_old = 0; @@ -481,14 +505,19 @@ static block_t *ParseMPEGBlock( decoder_t *p_dec, block_t *p_frag ) p_sys->i_frame_rate_base = code_to_frame_rate[p_frag->p_buffer[7]&0x0f][1]; + p_dec->fmt_out.video.i_frame_rate = p_sys->i_frame_rate; + p_dec->fmt_out.video.i_frame_rate_base = p_sys->i_frame_rate_base; + p_sys->b_seq_progressive = VLC_TRUE; p_sys->b_low_delay = VLC_TRUE; -#if 0 - msg_Dbg( p_dec, "Size %dx%d fps=%.3f", + if ( !p_sys->b_inited ) + { + msg_Dbg( p_dec, "Size %dx%d fps=%.3f", p_dec->fmt_out.video.i_width, p_dec->fmt_out.video.i_height, p_sys->i_frame_rate / (float)p_sys->i_frame_rate_base ); -#endif + p_sys->b_inited = 1; + } } else if( p_frag->p_buffer[3] == 0xb5 ) { @@ -497,12 +526,14 @@ static block_t *ParseMPEGBlock( decoder_t *p_dec, block_t *p_frag ) /* Extention start code */ if( i_type == 0x01 ) { +#if 0 static const int mpeg2_aspect[16][2] = { {0,1}, {1,1}, {4,3}, {16,9}, {221,100}, {0,1}, {0,1}, {0,1}, {0,1}, {0,1}, {0,1}, {0,1}, {0,1}, {0,1}, {0,1}, {0,1} }; +#endif /* sequence extention */ if( p_sys->p_ext) block_Release( p_sys->p_ext ); @@ -516,10 +547,18 @@ static block_t *ParseMPEGBlock( decoder_t *p_dec, block_t *p_frag ) p_frag->p_buffer[9]&0x80 ? VLC_TRUE : VLC_FALSE; } + /* Do not set aspect ratio : in case we're transcoding, + * transcode will take our fmt_out as a fmt_in to libmpeg2. + * libmpeg2.c will then believe that the user has requested + * a specific aspect ratio, which she hasn't. Thus in case + * of aspect ratio change, we're screwed. --Meuuh + */ +#if 0 p_dec->fmt_out.video.i_aspect = mpeg2_aspect[p_sys->i_aspect_ratio_info][0] * VOUT_ASPECT_FACTOR / mpeg2_aspect[p_sys->i_aspect_ratio_info][1]; +#endif } else if( i_type == 0x08 ) @@ -553,7 +592,7 @@ static block_t *ParseMPEGBlock( decoder_t *p_dec, block_t *p_frag ) } /* Append the block */ - block_ChainAppend( &p_sys->p_frame, p_frag ); + block_ChainLastAppend( &p_sys->pp_last, p_frag ); return p_pic; }