mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 05:16:13 +00:00
codecs: h264dec: consider the last field when add picture to DPB.
There are cases that the first field of the last picture is not a ref but the second field is a ref. We need to add both of them because the bumping always needs a complete frame in the DPB. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2430>
This commit is contained in:
parent
055ded53e9
commit
f95aa0a374
1 changed files with 28 additions and 6 deletions
|
@ -778,6 +778,28 @@ output:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_picture_to_dpb (GstH264Decoder * self, GstH264Picture * picture)
|
||||||
|
{
|
||||||
|
GstH264DecoderPrivate *priv = self->priv;
|
||||||
|
|
||||||
|
if (!gst_h264_dpb_get_interlaced (priv->dpb)) {
|
||||||
|
g_assert (priv->last_field == NULL);
|
||||||
|
gst_h264_dpb_add (priv->dpb, picture);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The first field of the last picture may not be able to enter the
|
||||||
|
DPB if it is a non ref, but if the second field enters the DPB, we
|
||||||
|
need to add both of them. */
|
||||||
|
if (priv->last_field && picture->other_field == priv->last_field) {
|
||||||
|
gst_h264_dpb_add (priv->dpb, priv->last_field);
|
||||||
|
priv->last_field = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_h264_dpb_add (priv->dpb, picture);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_h264_decoder_handle_frame_num_gap (GstH264Decoder * self, gint frame_num)
|
gst_h264_decoder_handle_frame_num_gap (GstH264Decoder * self, gint frame_num)
|
||||||
{
|
{
|
||||||
|
@ -860,10 +882,10 @@ gst_h264_decoder_handle_frame_num_gap (GstH264Decoder * self, gint frame_num)
|
||||||
GstH264Picture *other_field =
|
GstH264Picture *other_field =
|
||||||
gst_h264_decoder_split_frame (self, picture);
|
gst_h264_decoder_split_frame (self, picture);
|
||||||
|
|
||||||
gst_h264_dpb_add (priv->dpb, picture);
|
add_picture_to_dpb (self, picture);
|
||||||
gst_h264_dpb_add (priv->dpb, other_field);
|
add_picture_to_dpb (self, other_field);
|
||||||
} else {
|
} else {
|
||||||
gst_h264_dpb_add (priv->dpb, picture);
|
add_picture_to_dpb (self, picture);
|
||||||
}
|
}
|
||||||
|
|
||||||
unused_short_term_frame_num++;
|
unused_short_term_frame_num++;
|
||||||
|
@ -1953,16 +1975,16 @@ gst_h264_decoder_finish_picture (GstH264Decoder * self,
|
||||||
GstH264Picture *other_field =
|
GstH264Picture *other_field =
|
||||||
gst_h264_decoder_split_frame (self, picture);
|
gst_h264_decoder_split_frame (self, picture);
|
||||||
|
|
||||||
gst_h264_dpb_add (priv->dpb, picture);
|
add_picture_to_dpb (self, picture);
|
||||||
if (!other_field) {
|
if (!other_field) {
|
||||||
GST_WARNING_OBJECT (self,
|
GST_WARNING_OBJECT (self,
|
||||||
"Couldn't split frame into complementary field pair");
|
"Couldn't split frame into complementary field pair");
|
||||||
/* Keep decoding anyway... */
|
/* Keep decoding anyway... */
|
||||||
} else {
|
} else {
|
||||||
gst_h264_dpb_add (priv->dpb, other_field);
|
add_picture_to_dpb (self, other_field);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
gst_h264_dpb_add (priv->dpb, picture);
|
add_picture_to_dpb (self, picture);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ret = output_picture_directly (self, picture);
|
ret = output_picture_directly (self, picture);
|
||||||
|
|
Loading…
Reference in a new issue