From 9c374559aeb922fd6531a6ad6e29d44fa471f22f Mon Sep 17 00:00:00 2001 From: Gildas Bazin Date: Sun, 23 Nov 2003 13:15:27 +0000 Subject: [PATCH] * modules/demux/*: some containers don't carry any PTS information, just a DTS. In that case, make sure the PTS forwarded to the decoder is set to 0. * modules/codec/ffmpeg/video.c: use PTS if available, if not find out the PTS from the DTS and the p_context->has_b_frames and p_pic->reference flags. --- modules/codec/ffmpeg/video.c | 46 ++++++++++++++++++++++++------------ modules/demux/asf/asf.c | 11 +++++++-- modules/demux/avi/avi.c | 30 +++++++++++++---------- modules/demux/mkv.cpp | 11 ++++++--- modules/demux/mp4/mp4.c | 19 +++++++++++---- modules/demux/ogg.c | 25 +++++++++++++++++--- 6 files changed, 101 insertions(+), 41 deletions(-) diff --git a/modules/codec/ffmpeg/video.c b/modules/codec/ffmpeg/video.c index 966140574d..939ea0b9c0 100644 --- a/modules/codec/ffmpeg/video.c +++ b/modules/codec/ffmpeg/video.c @@ -2,7 +2,7 @@ * video.c: video decoder using the ffmpeg library ***************************************************************************** * Copyright (C) 1999-2001 VideoLAN - * $Id: video.c,v 1.49 2003/11/23 03:55:01 fenrir Exp $ + * $Id: video.c,v 1.50 2003/11/23 13:15:27 gbazin Exp $ * * Authors: Laurent Aimar * Gildas Bazin @@ -52,6 +52,7 @@ struct decoder_sys_t /* Video decoder specific part */ mtime_t input_pts; + mtime_t input_dts; mtime_t i_pts; AVFrame *p_ff_pic; @@ -318,7 +319,7 @@ int E_(InitVideoDec)( decoder_t *p_dec, AVCodecContext *p_context, } /* ***** misc init ***** */ - p_sys->input_pts = 0; + p_sys->input_pts = p_sys->input_dts = 0; p_sys->i_pts = 0; p_sys->b_has_b_frames = VLC_FALSE; p_sys->i_late_frames = 0; @@ -346,10 +347,13 @@ picture_t *E_(DecodeVideo)( decoder_t *p_dec, block_t **pp_block ) p_block = *pp_block; - if( p_block->i_pts > 0 ) + if( p_block->i_pts > 0 || p_block->i_dts > 0 ) { p_sys->input_pts = p_block->i_pts; - p_block->i_pts = 0; /* Make sure we don't reuse the same pts twice */ + p_sys->input_dts = p_block->i_dts; + + /* Make sure we don't reuse the same timestamps twice */ + p_block->i_pts = p_block->i_dts = 0; } /* TODO implement it in a better way */ @@ -485,17 +489,13 @@ picture_t *E_(DecodeVideo)( decoder_t *p_dec, block_t **pp_block ) p_pic = (picture_t *)p_sys->p_ff_pic->opaque; } - /* Set the PTS - * There is an ugly hack here because some demuxers pass us a dts - * instead of a pts so this screw up things for streams with - * B frames. */ + /* Set the PTS */ + if( p_sys->p_ff_pic->pts ) p_sys->i_pts = p_sys->p_ff_pic->pts; + + /* Sanity check (seems to be needed for some streams ) */ if( p_sys->p_ff_pic->pict_type == FF_B_TYPE ) - p_sys->b_has_b_frames = VLC_TRUE; - if( p_sys->p_ff_pic->pts && - ( !p_sys->p_context->has_b_frames || !p_sys->b_has_b_frames || - p_sys->p_ff_pic->pict_type == FF_B_TYPE ) ) { - p_sys->i_pts = p_sys->p_ff_pic->pts; + p_sys->b_has_b_frames = VLC_TRUE; } /* Send decoded frame to vout */ @@ -622,8 +622,24 @@ static int ffmpeg_GetFrameBuf( struct AVCodecContext *p_context, picture_t *p_pic; /* Set picture PTS */ - p_ff_pic->pts = p_sys->input_pts; - p_sys->input_pts = 0; + if( p_sys->input_pts ) + { + p_ff_pic->pts = p_sys->input_pts; + } + else if( p_sys->input_dts ) + { + /* Some demuxers only set the dts so let's try to find a useful + * timestamp from this */ + if( !p_context->has_b_frames || !p_sys->b_has_b_frames || + !p_ff_pic->reference ) + { + p_ff_pic->pts = p_sys->input_dts; + } + else p_ff_pic->pts = 0; + } + else p_ff_pic->pts = 0; + + p_sys->input_pts = p_sys->input_dts = 0; /* Not much to do in indirect rendering mode */ if( !p_sys->b_direct_rendering ) diff --git a/modules/demux/asf/asf.c b/modules/demux/asf/asf.c index 47aefcc617..d5ba74c5d2 100644 --- a/modules/demux/asf/asf.c +++ b/modules/demux/asf/asf.c @@ -2,7 +2,7 @@ * asf.c : ASFv01 file input module for vlc ***************************************************************************** * Copyright (C) 2002-2003 VideoLAN - * $Id: asf.c,v 1.45 2003/11/21 16:02:36 fenrir Exp $ + * $Id: asf.c,v 1.46 2003/11/23 13:15:27 gbazin Exp $ * * Authors: Laurent Aimar * @@ -739,11 +739,18 @@ static int DemuxPacket( input_thread_t *p_input, vlc_bool_t b_play_audio ) p_stream->i_time = ( (mtime_t)i_pts + i_payload * (mtime_t)i_pts_delta ); - p_frag->i_dts = p_frag->i_pts = input_ClockGetTS( p_input, p_input->stream.p_selected_program, p_stream->i_time * 9 /100 ); + + if( p_stream->i_cat != VIDEO_ES ) + p_frag->i_dts = p_frag->i_pts; + else + { + p_frag->i_dts = p_frag->i_pts; + p_frag->i_pts = 0; + } } block_ChainAppend( &p_stream->p_frame, p_frag ); diff --git a/modules/demux/avi/avi.c b/modules/demux/avi/avi.c index 29b161753c..40d238486f 100644 --- a/modules/demux/avi/avi.c +++ b/modules/demux/avi/avi.c @@ -2,7 +2,7 @@ * avi.c : AVI file Stream input module for vlc ***************************************************************************** * Copyright (C) 2001 VideoLAN - * $Id: avi.c,v 1.74 2003/11/22 15:10:38 fenrir Exp $ + * $Id: avi.c,v 1.75 2003/11/23 13:15:27 gbazin Exp $ * Authors: Laurent Aimar * * This program is free software; you can redistribute it and/or modify @@ -465,7 +465,6 @@ static int Demux_Seekable( input_thread_t *p_input ) unsigned int i_track_count = 0; unsigned int i_track; vlc_bool_t b_stream; - vlc_bool_t b_play_audio; /* cannot be more than 100 stream (dcXX or wbXX) */ avi_track_toread_t toread[100]; @@ -511,9 +510,6 @@ static int Demux_Seekable( input_thread_t *p_input ) p_sys->i_time += 25*1000; /* read 25ms */ - /* Check if we need to send the audio data to decoder */ - b_play_audio = !p_input->stream.control.b_mute; - /* init toread */ for( i_track = 0; i_track < p_sys->i_track; i_track++ ) { @@ -758,20 +754,21 @@ static int Demux_Seekable( input_thread_t *p_input ) b_stream = VLC_TRUE; /* at least one read succeed */ - p_frame->i_dts = p_frame->i_pts = input_ClockGetTS( p_input, p_input->stream.p_selected_program, p_frame->i_pts * 9/100); - //p_pes->i_rate = p_input->stream.control.i_rate; - if( b_play_audio || tk->i_cat != AUDIO_ES ) - { - es_out_Send( p_input->p_es_out, tk->p_es, p_frame ); - } + + if( tk->i_cat != VIDEO_ES ) + p_frame->i_dts = p_frame->i_pts; else { - block_Release( p_frame ); + p_frame->i_dts = p_frame->i_pts; + p_frame->i_pts = 0; } + + //p_pes->i_rate = p_input->stream.control.i_rate; + es_out_Send( p_input->p_es_out, tk->p_es, p_frame ); } } @@ -885,12 +882,19 @@ static int Demux_UnSeekable( input_thread_t *p_input ) { return( -1 ); } - p_frame->i_dts = p_frame->i_pts = input_ClockGetTS( p_input, p_input->stream.p_selected_program, AVI_GetPTS( p_stream ) * 9/100); + if( avi_pk.i_cat != VIDEO_ES ) + p_frame->i_dts = p_frame->i_pts; + else + { + p_frame->i_dts = p_frame->i_pts; + p_frame->i_pts = 0; + } + //p_pes->i_rate = p_input->stream.control.i_rate; es_out_Send( p_input->p_es_out, p_stream->p_es, p_frame ); } diff --git a/modules/demux/mkv.cpp b/modules/demux/mkv.cpp index e0a191c52b..072cbbf585 100644 --- a/modules/demux/mkv.cpp +++ b/modules/demux/mkv.cpp @@ -2,7 +2,7 @@ * mkv.cpp : matroska demuxer ***************************************************************************** * Copyright (C) 2001 VideoLAN - * $Id: mkv.cpp,v 1.43 2003/11/21 00:38:01 gbazin Exp $ + * $Id: mkv.cpp,v 1.44 2003/11/23 13:15:27 gbazin Exp $ * * Authors: Laurent Aimar * @@ -1487,8 +1487,13 @@ static void BlockDecode( input_thread_t *p_input, KaxBlock *block, mtime_t i_pts break; } - p_block->i_pts = i_pts; - p_block->i_dts = i_pts; + if( tk.fmt.i_cat != VIDEO_ES ) + p_block->i_dts = p_block->i_pts = i_pts; + else + { + p_block->i_dts = i_pts; + p_block->i_pts = 0; + } if( tk.fmt.i_cat == SPU_ES && strcmp( tk.psz_codec, "S_VOBSUB" ) ) { diff --git a/modules/demux/mp4/mp4.c b/modules/demux/mp4/mp4.c index 004f19d14e..98909f158f 100644 --- a/modules/demux/mp4/mp4.c +++ b/modules/demux/mp4/mp4.c @@ -2,7 +2,7 @@ * mp4.c : MP4 file input module for vlc ***************************************************************************** * Copyright (C) 2001 VideoLAN - * $Id: mp4.c,v 1.40 2003/10/07 14:59:10 gbazin Exp $ + * $Id: mp4.c,v 1.41 2003/11/23 13:15:27 gbazin Exp $ * Authors: Laurent Aimar * * This program is free software; you can redistribute it and/or modify @@ -518,10 +518,19 @@ static int Demux( input_thread_t *p_input ) MP4_TrackUnselect( p_input, &track ); break; } - p_pes->i_dts = - p_pes->i_pts = input_ClockGetTS( p_input, - p_input->stream.p_selected_program, - MP4_GetTrackPTS( &track ) * 9/100); + + p_pes->i_pts = + input_ClockGetTS( p_input, + p_input->stream.p_selected_program, + MP4_GetTrackPTS( &track ) * 9/100 ); + + if( track.i_cat != VIDEO_ES ) + p_pes->i_dts = p_pes->i_pts; + else + { + p_pes->i_dts = p_pes->i_pts; + p_pes->i_pts = 0; + } if( track.p_es->p_decoder_fifo ) { diff --git a/modules/demux/ogg.c b/modules/demux/ogg.c index 64b0015b0f..0e9e30f036 100644 --- a/modules/demux/ogg.c +++ b/modules/demux/ogg.c @@ -2,7 +2,7 @@ * ogg.c : ogg stream input module for vlc ***************************************************************************** * Copyright (C) 2001-2003 VideoLAN - * $Id: ogg.c,v 1.45 2003/11/22 12:41:32 gbazin Exp $ + * $Id: ogg.c,v 1.46 2003/11/23 13:15:27 gbazin Exp $ * * Authors: Gildas Bazin * @@ -259,6 +259,13 @@ static void Ogg_DecodePacket( input_thread_t *p_input, int i_header_len = 0; mtime_t i_pts; + /* Sanity check */ + if( !p_oggpacket->bytes ) + { + msg_Dbg( p_input, "discarding 0 sized packet" ); + return; + } + if( p_stream->b_force_backup ) { ogg_packet *p_packet_backup; @@ -450,9 +457,21 @@ static void Ogg_DecodePacket( input_thread_t *p_input, { return; } - p_block->i_dts = p_block->i_pts = i_pts; - if( p_stream->fmt.i_cat == SPU_ES ) p_block->i_dts = 0; + if( p_stream->fmt.i_cat == AUDIO_ES ) + p_block->i_dts = p_block->i_pts = i_pts; + else if( p_stream->fmt.i_cat == SPU_ES ) + { + p_block->i_pts = i_pts; + p_block->i_dts = 0; + } + else if( p_stream->fmt.i_codec == VLC_FOURCC( 't','h','e','o' ) ) + p_block->i_dts = p_block->i_pts = i_pts; + else + { + p_block->i_dts = i_pts; + p_block->i_pts = 0; + } if( p_stream->fmt.i_codec != VLC_FOURCC( 'v','o','r','b' ) && p_stream->fmt.i_codec != VLC_FOURCC( 's','p','x',' ' ) && -- 2.39.2