mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-03 14:08:56 +00:00
avviddec: Report a latency even without upstream framerate
There are cases where upstream will not provide a framerate, or it won't be fixed. But if there is latency introduced by the decoder we do want to report it. Therefore use the framerate stored in the actual decoder, which will have a default. Fixes hangs when playing back such streams with decodebin3 (where the multiqueue will not have been informed of that downstream latency and not grow accordingly) Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3391>
This commit is contained in:
parent
d77fe9495a
commit
c39400b52c
1 changed files with 20 additions and 10 deletions
|
@ -666,16 +666,20 @@ update_state:
|
||||||
gst_video_codec_state_unref (ffmpegdec->input_state);
|
gst_video_codec_state_unref (ffmpegdec->input_state);
|
||||||
ffmpegdec->input_state = gst_video_codec_state_ref (state);
|
ffmpegdec->input_state = gst_video_codec_state_ref (state);
|
||||||
|
|
||||||
if (ffmpegdec->input_state->info.fps_n) {
|
/* Use the framerate values stored in the decoder for calculating latency. The
|
||||||
GstVideoInfo *info = &ffmpegdec->input_state->info;
|
* upstream framerate might not be set but we still want to report a latency
|
||||||
|
* if needed. */
|
||||||
|
if (ffmpegdec->context->time_base.den && ffmpegdec->context->ticks_per_frame) {
|
||||||
|
gint fps_n =
|
||||||
|
ffmpegdec->context->time_base.den / ffmpegdec->context->ticks_per_frame;
|
||||||
|
gint fps_d = ffmpegdec->context->time_base.num;
|
||||||
latency = gst_util_uint64_scale_ceil (
|
latency = gst_util_uint64_scale_ceil (
|
||||||
(ffmpegdec->context->has_b_frames) * GST_SECOND, info->fps_d,
|
(ffmpegdec->context->has_b_frames) * GST_SECOND, fps_d, fps_n);
|
||||||
info->fps_n);
|
|
||||||
|
|
||||||
if (ffmpegdec->context->thread_type & FF_THREAD_FRAME) {
|
if (ffmpegdec->context->thread_type & FF_THREAD_FRAME) {
|
||||||
latency +=
|
latency +=
|
||||||
gst_util_uint64_scale_ceil (ffmpegdec->context->thread_count *
|
gst_util_uint64_scale_ceil (ffmpegdec->context->thread_count *
|
||||||
GST_SECOND, info->fps_d, info->fps_n);
|
GST_SECOND, fps_d, fps_n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1453,8 +1457,7 @@ gst_ffmpegviddec_negotiate (GstFFMpegVidDec * ffmpegdec,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* try to find a good framerate */
|
/* try to find a good framerate */
|
||||||
if ((in_info->fps_d && in_info->fps_n) ||
|
if ((in_info->fps_d && in_info->fps_n)) {
|
||||||
GST_VIDEO_INFO_FLAG_IS_SET (in_info, GST_VIDEO_FLAG_VARIABLE_FPS)) {
|
|
||||||
/* take framerate from input when it was specified (#313970) */
|
/* take framerate from input when it was specified (#313970) */
|
||||||
fps_n = in_info->fps_n;
|
fps_n = in_info->fps_n;
|
||||||
fps_d = in_info->fps_d;
|
fps_d = in_info->fps_d;
|
||||||
|
@ -1475,9 +1478,16 @@ gst_ffmpegviddec_negotiate (GstFFMpegVidDec * ffmpegdec,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_LOG_OBJECT (ffmpegdec, "setting framerate: %d/%d", fps_n, fps_d);
|
if (GST_VIDEO_INFO_FLAG_IS_SET (in_info, GST_VIDEO_FLAG_VARIABLE_FPS)) {
|
||||||
out_info->fps_n = fps_n;
|
GST_LOG_OBJECT (ffmpegdec, "setting framerate: %d/%d", in_info->fps_n,
|
||||||
out_info->fps_d = fps_d;
|
in_info->fps_d);
|
||||||
|
out_info->fps_n = in_info->fps_n;
|
||||||
|
out_info->fps_d = in_info->fps_d;
|
||||||
|
} else {
|
||||||
|
GST_LOG_OBJECT (ffmpegdec, "setting framerate: %d/%d", fps_n, fps_d);
|
||||||
|
out_info->fps_n = fps_n;
|
||||||
|
out_info->fps_d = fps_d;
|
||||||
|
}
|
||||||
|
|
||||||
/* calculate and update par now */
|
/* calculate and update par now */
|
||||||
gst_ffmpegviddec_update_par (ffmpegdec, in_info, out_info);
|
gst_ffmpegviddec_update_par (ffmpegdec, in_info, out_info);
|
||||||
|
|
Loading…
Reference in a new issue