deps-libff: Offset start of stream by start pts

Now that we're using the timestamps from the stream for playback,
certain types of streams and certain file formats will not start from a
pts of 0.  This causes the start of the playback to be delayed.  This
code simply ensures that there's no delay on startup.  This is basically
the same code as used in FFmpeg itself for handling this situation.
master
jp9000 2015-07-04 15:48:05 -07:00
parent 4725641c88
commit 171f0e3d26
3 changed files with 39 additions and 0 deletions

View File

@ -50,6 +50,7 @@ struct ff_decoder *ff_decoder_init(AVCodecContext *codec_context,
decoder->timer_next_wake = (double)av_gettime() / 1000000.0;
decoder->previous_pts_diff = 40e-3;
decoder->current_pts_time = av_gettime();
decoder->start_pts = 0;
decoder->predicted_pts = 0;
success = ff_timer_init(&decoder->refresh_timer, ff_decoder_refresh,
@ -308,6 +309,8 @@ double ff_decoder_get_best_effort_pts(struct ff_decoder *decoder,
best_effort_pts = av_frame_get_best_effort_timestamp(frame);
if (best_effort_pts != AV_NOPTS_VALUE) {
best_effort_pts -= decoder->start_pts;
// Since the best effort pts came from the stream we use his
// time base
d_pts = best_effort_pts * av_q2d(decoder->stream->time_base);

View File

@ -46,6 +46,7 @@ struct ff_decoder {
double predicted_pts; // predicted pts of next frame
double current_pts; // pts of the most recently dispatched frame
int64_t current_pts_time; // clock time when current_pts was set
int64_t start_pts;
bool hwaccel_decoder;
enum AVDiscard frame_drop;

View File

@ -380,12 +380,21 @@ static bool open_input(struct ff_demuxer *demuxer,
return avformat_find_stream_info(*format_context, NULL) >= 0;
}
static inline void set_decoder_start_time(struct ff_decoder *decoder,
int64_t start_time)
{
if (decoder)
decoder->start_pts = av_rescale_q(start_time, AV_TIME_BASE_Q,
decoder->stream->time_base);
}
static bool find_and_initialize_stream_decoders(struct ff_demuxer *demuxer)
{
AVFormatContext *format_context = demuxer->format_context;
unsigned int i;
AVStream *audio_stream = NULL;
AVStream *video_stream = NULL;
int64_t start_time = INT64_MAX;
for (i = 0; i < format_context->nb_streams; i++) {
AVCodecContext *codec = format_context->streams[i]->codec;
@ -424,6 +433,32 @@ static bool find_and_initialize_stream_decoders(struct ff_demuxer *demuxer)
return false;
}
for (i = 0; i < format_context->nb_streams; i++) {
AVStream *st = format_context->streams[i];
int64_t st_start_time;
if (st->discard == AVDISCARD_ALL ||
st->start_time == AV_NOPTS_VALUE) {
continue;
}
st_start_time = av_rescale_q(st->start_time, st->time_base,
AV_TIME_BASE_Q);
start_time = FFMIN(start_time, st_start_time);
}
if (format_context->start_time != AV_NOPTS_VALUE) {
if (start_time > format_context->start_time ||
start_time == INT64_MAX) {
start_time = format_context->start_time;
}
}
if (start_time != INT64_MAX) {
set_decoder_start_time(demuxer->video_decoder, start_time);
set_decoder_start_time(demuxer->audio_decoder, start_time);
}
if (demuxer->audio_decoder != NULL) {
if (ff_callbacks_initialize(&demuxer->audio_callbacks)) {
ff_decoder_start(demuxer->audio_decoder);