Commit 9c374559 authored by Gildas Bazin's avatar Gildas Bazin

* 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.
parent 0eb0aecc
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* video.c: video decoder using the ffmpeg library * video.c: video decoder using the ffmpeg library
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * 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 <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Gildas Bazin <gbazin@netcourrier.com> * Gildas Bazin <gbazin@netcourrier.com>
...@@ -52,6 +52,7 @@ struct decoder_sys_t ...@@ -52,6 +52,7 @@ struct decoder_sys_t
/* Video decoder specific part */ /* Video decoder specific part */
mtime_t input_pts; mtime_t input_pts;
mtime_t input_dts;
mtime_t i_pts; mtime_t i_pts;
AVFrame *p_ff_pic; AVFrame *p_ff_pic;
...@@ -318,7 +319,7 @@ int E_(InitVideoDec)( decoder_t *p_dec, AVCodecContext *p_context, ...@@ -318,7 +319,7 @@ int E_(InitVideoDec)( decoder_t *p_dec, AVCodecContext *p_context,
} }
/* ***** misc init ***** */ /* ***** misc init ***** */
p_sys->input_pts = 0; p_sys->input_pts = p_sys->input_dts = 0;
p_sys->i_pts = 0; p_sys->i_pts = 0;
p_sys->b_has_b_frames = VLC_FALSE; p_sys->b_has_b_frames = VLC_FALSE;
p_sys->i_late_frames = 0; p_sys->i_late_frames = 0;
...@@ -346,10 +347,13 @@ picture_t *E_(DecodeVideo)( decoder_t *p_dec, block_t **pp_block ) ...@@ -346,10 +347,13 @@ picture_t *E_(DecodeVideo)( decoder_t *p_dec, block_t **pp_block )
p_block = *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_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 */ /* TODO implement it in a better way */
...@@ -485,17 +489,13 @@ picture_t *E_(DecodeVideo)( decoder_t *p_dec, block_t **pp_block ) ...@@ -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; p_pic = (picture_t *)p_sys->p_ff_pic->opaque;
} }
/* Set the PTS /* Set the PTS */
* There is an ugly hack here because some demuxers pass us a dts if( p_sys->p_ff_pic->pts ) p_sys->i_pts = p_sys->p_ff_pic->pts;
* instead of a pts so this screw up things for streams with
* B frames. */ /* Sanity check (seems to be needed for some streams ) */
if( p_sys->p_ff_pic->pict_type == FF_B_TYPE ) 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 */ /* Send decoded frame to vout */
...@@ -622,8 +622,24 @@ static int ffmpeg_GetFrameBuf( struct AVCodecContext *p_context, ...@@ -622,8 +622,24 @@ static int ffmpeg_GetFrameBuf( struct AVCodecContext *p_context,
picture_t *p_pic; picture_t *p_pic;
/* Set picture PTS */ /* Set picture PTS */
p_ff_pic->pts = p_sys->input_pts; if( p_sys->input_pts )
p_sys->input_pts = 0; {
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 */ /* Not much to do in indirect rendering mode */
if( !p_sys->b_direct_rendering ) if( !p_sys->b_direct_rendering )
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* asf.c : ASFv01 file input module for vlc * asf.c : ASFv01 file input module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2002-2003 VideoLAN * 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 <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -739,11 +739,18 @@ static int DemuxPacket( input_thread_t *p_input, vlc_bool_t b_play_audio ) ...@@ -739,11 +739,18 @@ static int DemuxPacket( input_thread_t *p_input, vlc_bool_t b_play_audio )
p_stream->i_time = p_stream->i_time =
( (mtime_t)i_pts + i_payload * (mtime_t)i_pts_delta ); ( (mtime_t)i_pts + i_payload * (mtime_t)i_pts_delta );
p_frag->i_dts =
p_frag->i_pts = p_frag->i_pts =
input_ClockGetTS( p_input, input_ClockGetTS( p_input,
p_input->stream.p_selected_program, p_input->stream.p_selected_program,
p_stream->i_time * 9 /100 ); 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 ); block_ChainAppend( &p_stream->p_frame, p_frag );
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* avi.c : AVI file Stream input module for vlc * avi.c : AVI file Stream input module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * 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 <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
* This program is free software; you can redistribute it and/or modify * 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 ) ...@@ -465,7 +465,6 @@ static int Demux_Seekable( input_thread_t *p_input )
unsigned int i_track_count = 0; unsigned int i_track_count = 0;
unsigned int i_track; unsigned int i_track;
vlc_bool_t b_stream; vlc_bool_t b_stream;
vlc_bool_t b_play_audio;
/* cannot be more than 100 stream (dcXX or wbXX) */ /* cannot be more than 100 stream (dcXX or wbXX) */
avi_track_toread_t toread[100]; avi_track_toread_t toread[100];
...@@ -511,9 +510,6 @@ static int Demux_Seekable( input_thread_t *p_input ) ...@@ -511,9 +510,6 @@ static int Demux_Seekable( input_thread_t *p_input )
p_sys->i_time += 25*1000; /* read 25ms */ 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 */ /* init toread */
for( i_track = 0; i_track < p_sys->i_track; i_track++ ) 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 ) ...@@ -758,20 +754,21 @@ static int Demux_Seekable( input_thread_t *p_input )
b_stream = VLC_TRUE; /* at least one read succeed */ b_stream = VLC_TRUE; /* at least one read succeed */
p_frame->i_dts =
p_frame->i_pts = p_frame->i_pts =
input_ClockGetTS( p_input, input_ClockGetTS( p_input,
p_input->stream.p_selected_program, p_input->stream.p_selected_program,
p_frame->i_pts * 9/100); 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 ) if( tk->i_cat != VIDEO_ES )
{ p_frame->i_dts = p_frame->i_pts;
es_out_Send( p_input->p_es_out, tk->p_es, p_frame );
}
else 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 ) ...@@ -885,12 +882,19 @@ static int Demux_UnSeekable( input_thread_t *p_input )
{ {
return( -1 ); return( -1 );
} }
p_frame->i_dts =
p_frame->i_pts = p_frame->i_pts =
input_ClockGetTS( p_input, input_ClockGetTS( p_input,
p_input->stream.p_selected_program, p_input->stream.p_selected_program,
AVI_GetPTS( p_stream ) * 9/100); 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; //p_pes->i_rate = p_input->stream.control.i_rate;
es_out_Send( p_input->p_es_out, p_stream->p_es, p_frame ); es_out_Send( p_input->p_es_out, p_stream->p_es, p_frame );
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* mkv.cpp : matroska demuxer * mkv.cpp : matroska demuxer
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * 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 <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -1487,8 +1487,13 @@ static void BlockDecode( input_thread_t *p_input, KaxBlock *block, mtime_t i_pts ...@@ -1487,8 +1487,13 @@ static void BlockDecode( input_thread_t *p_input, KaxBlock *block, mtime_t i_pts
break; break;
} }
p_block->i_pts = i_pts; if( tk.fmt.i_cat != VIDEO_ES )
p_block->i_dts = i_pts; 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" ) ) if( tk.fmt.i_cat == SPU_ES && strcmp( tk.psz_codec, "S_VOBSUB" ) )
{ {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* mp4.c : MP4 file input module for vlc * mp4.c : MP4 file input module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * 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 <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -518,10 +518,19 @@ static int Demux( input_thread_t *p_input ) ...@@ -518,10 +518,19 @@ static int Demux( input_thread_t *p_input )
MP4_TrackUnselect( p_input, &track ); MP4_TrackUnselect( p_input, &track );
break; break;
} }
p_pes->i_dts =
p_pes->i_pts = input_ClockGetTS( p_input, p_pes->i_pts =
p_input->stream.p_selected_program, input_ClockGetTS( p_input,
MP4_GetTrackPTS( &track ) * 9/100); 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 ) if( track.p_es->p_decoder_fifo )
{ {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ogg.c : ogg stream input module for vlc * ogg.c : ogg stream input module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2001-2003 VideoLAN * 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 <gbazin@netcourrier.com> * Authors: Gildas Bazin <gbazin@netcourrier.com>
* *
...@@ -259,6 +259,13 @@ static void Ogg_DecodePacket( input_thread_t *p_input, ...@@ -259,6 +259,13 @@ static void Ogg_DecodePacket( input_thread_t *p_input,
int i_header_len = 0; int i_header_len = 0;
mtime_t i_pts; 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 ) if( p_stream->b_force_backup )
{ {
ogg_packet *p_packet_backup; ogg_packet *p_packet_backup;
...@@ -450,9 +457,21 @@ static void Ogg_DecodePacket( input_thread_t *p_input, ...@@ -450,9 +457,21 @@ static void Ogg_DecodePacket( input_thread_t *p_input,
{ {
return; 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' ) && if( p_stream->fmt.i_codec != VLC_FOURCC( 'v','o','r','b' ) &&
p_stream->fmt.i_codec != VLC_FOURCC( 's','p','x',' ' ) && p_stream->fmt.i_codec != VLC_FOURCC( 's','p','x',' ' ) &&
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment