提交 171f0e3d 编写于 作者: J jp9000

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.
上级 4725641c
......@@ -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);
......
......@@ -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;
......
......@@ -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);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册