mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 01:45:33 +00:00
h264decoder: Update latency dynamically
The actual number of reorder frames is unknown unless frame reordering is disabled (e.g., POC type 2 or constrained-* profiles). Also derived maximum DPB size or max_num_reorder_frames in VUI is not the upper bound of output delay. Fixes: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/2702 Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5326>
This commit is contained in:
parent
bd25c2738e
commit
48a0c01570
2 changed files with 55 additions and 8 deletions
|
@ -153,6 +153,12 @@ struct _GstH264DecoderPrivate
|
||||||
|
|
||||||
/* Return value from output_picture() */
|
/* Return value from output_picture() */
|
||||||
GstFlowReturn last_flow;
|
GstFlowReturn last_flow;
|
||||||
|
|
||||||
|
/* Latency report params */
|
||||||
|
guint32 max_reorder_count;
|
||||||
|
guint32 last_reorder_frame_number;
|
||||||
|
gint fps_n;
|
||||||
|
gint fps_d;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -405,6 +411,17 @@ gst_h264_decoder_finalize (GObject * object)
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_h264_decoder_reset_latency_infos (GstH264Decoder * self)
|
||||||
|
{
|
||||||
|
GstH264DecoderPrivate *priv = self->priv;
|
||||||
|
|
||||||
|
priv->max_reorder_count = 0;
|
||||||
|
priv->last_reorder_frame_number = 0;
|
||||||
|
priv->fps_n = 25;
|
||||||
|
priv->fps_d = 1;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_h264_decoder_reset (GstH264Decoder * self)
|
gst_h264_decoder_reset (GstH264Decoder * self)
|
||||||
{
|
{
|
||||||
|
@ -420,6 +437,8 @@ gst_h264_decoder_reset (GstH264Decoder * self)
|
||||||
priv->height = 0;
|
priv->height = 0;
|
||||||
priv->nal_length_size = 4;
|
priv->nal_length_size = 4;
|
||||||
priv->last_flow = GST_FLOW_OK;
|
priv->last_flow = GST_FLOW_OK;
|
||||||
|
|
||||||
|
gst_h264_decoder_reset_latency_infos (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -1290,6 +1309,9 @@ gst_h264_decoder_parse_slice (GstH264Decoder * self, GstH264NalUnit * nalu)
|
||||||
gst_h264_picture_unref (picture);
|
gst_h264_picture_unref (picture);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
priv->last_reorder_frame_number++;
|
||||||
|
picture->reorder_frame_number = priv->last_reorder_frame_number;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This allows accessing the frame from the picture. */
|
/* This allows accessing the frame from the picture. */
|
||||||
|
@ -1797,6 +1819,28 @@ gst_h264_decoder_do_output_picture (GstH264Decoder * self,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (priv->last_reorder_frame_number > picture->reorder_frame_number) {
|
||||||
|
guint64 diff = priv->last_reorder_frame_number -
|
||||||
|
picture->reorder_frame_number;
|
||||||
|
guint64 total_delay = diff + priv->preferred_output_delay;
|
||||||
|
if (diff > priv->max_reorder_count && total_delay < G_MAXUINT32) {
|
||||||
|
GstClockTime latency;
|
||||||
|
|
||||||
|
priv->max_reorder_count = (guint32) diff;
|
||||||
|
latency = gst_util_uint64_scale_int (GST_SECOND * total_delay,
|
||||||
|
priv->fps_d, priv->fps_n);
|
||||||
|
|
||||||
|
if (latency != G_MAXUINT64) {
|
||||||
|
GST_DEBUG_OBJECT (self, "Updating latency to %" GST_TIME_FORMAT
|
||||||
|
", reorder count: %" G_GUINT64_FORMAT ", output-delay: %u",
|
||||||
|
GST_TIME_ARGS (latency), diff, priv->preferred_output_delay);
|
||||||
|
|
||||||
|
gst_video_decoder_set_latency (GST_VIDEO_DECODER (self),
|
||||||
|
latency, latency);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
frame = gst_video_decoder_get_frame (GST_VIDEO_DECODER (self),
|
frame = gst_video_decoder_get_frame (GST_VIDEO_DECODER (self),
|
||||||
GST_CODEC_PICTURE_FRAME_NUMBER (picture));
|
GST_CODEC_PICTURE_FRAME_NUMBER (picture));
|
||||||
|
|
||||||
|
@ -2309,16 +2353,14 @@ gst_h264_decoder_set_latency (GstH264Decoder * self, const GstH264SPS * sps,
|
||||||
|
|
||||||
bump_level = get_bump_level (self);
|
bump_level = get_bump_level (self);
|
||||||
if (bump_level != GST_H264_DPB_BUMP_NORMAL_LATENCY) {
|
if (bump_level != GST_H264_DPB_BUMP_NORMAL_LATENCY) {
|
||||||
if (sps->pic_order_cnt_type == 2) {
|
GST_DEBUG_OBJECT (self, "Actual latency will be updated later");
|
||||||
/* POC type 2 has does not allow frame reordering */
|
|
||||||
frames_delay = 0;
|
frames_delay = 0;
|
||||||
} else {
|
|
||||||
guint32 max_reorder_frames =
|
|
||||||
gst_h264_dpb_get_max_num_reorder_frames (priv->dpb);
|
|
||||||
frames_delay = MIN (max_dpb_size, max_reorder_frames);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
priv->max_reorder_count = frames_delay;
|
||||||
|
priv->fps_n = fps_n;
|
||||||
|
priv->fps_d = fps_d;
|
||||||
|
|
||||||
/* Consider output delay wanted by subclass */
|
/* Consider output delay wanted by subclass */
|
||||||
frames_delay += priv->preferred_output_delay;
|
frames_delay += priv->preferred_output_delay;
|
||||||
|
|
||||||
|
@ -2433,6 +2475,8 @@ gst_h264_decoder_process_sps (GstH264Decoder * self, GstH264SPS * sps)
|
||||||
if (ret != GST_FLOW_OK)
|
if (ret != GST_FLOW_OK)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
gst_h264_decoder_reset_latency_infos (self);
|
||||||
|
|
||||||
g_assert (klass->new_sequence);
|
g_assert (klass->new_sequence);
|
||||||
|
|
||||||
if (klass->get_preferred_output_delay) {
|
if (klass->get_preferred_output_delay) {
|
||||||
|
|
|
@ -153,6 +153,9 @@ struct _GstH264Picture
|
||||||
|
|
||||||
GstH264DecRefPicMarking dec_ref_pic_marking;
|
GstH264DecRefPicMarking dec_ref_pic_marking;
|
||||||
|
|
||||||
|
/* Set by decoder to trace the number of delayed output pictures */
|
||||||
|
guint32 reorder_frame_number;
|
||||||
|
|
||||||
/* For interlaced decoding */
|
/* For interlaced decoding */
|
||||||
gboolean second_field;
|
gboolean second_field;
|
||||||
GstH264Picture * other_field;
|
GstH264Picture * other_field;
|
||||||
|
|
Loading…
Reference in a new issue