mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 18:21:04 +00:00
codecs: h264decoder: Split gap picture as well if needed
field pair pictures might be required for reference list depending on context. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1812>
This commit is contained in:
parent
4ee6167616
commit
e1adc572a7
2 changed files with 62 additions and 34 deletions
|
@ -185,6 +185,8 @@ gst_h264_decoder_sliding_window_picture_marking (GstH264Decoder * self,
|
||||||
GstH264Picture * picture);
|
GstH264Picture * picture);
|
||||||
static void gst_h264_decoder_do_output_picture (GstH264Decoder * self,
|
static void gst_h264_decoder_do_output_picture (GstH264Decoder * self,
|
||||||
GstH264Picture * picture);
|
GstH264Picture * picture);
|
||||||
|
static GstH264Picture *gst_h264_decoder_new_field_picture (GstH264Decoder *
|
||||||
|
self, GstH264Picture * picture);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_h264_decoder_class_init (GstH264DecoderClass * klass)
|
gst_h264_decoder_class_init (GstH264DecoderClass * klass)
|
||||||
|
@ -606,6 +608,47 @@ gst_h264_decoder_update_pic_nums (GstH264Decoder * self,
|
||||||
g_array_unref (dpb);
|
g_array_unref (dpb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GstH264Picture *
|
||||||
|
gst_h264_decoder_split_frame (GstH264Decoder * self, GstH264Picture * picture)
|
||||||
|
{
|
||||||
|
GstH264Picture *other_field;
|
||||||
|
|
||||||
|
g_assert (GST_H264_PICTURE_IS_FRAME (picture));
|
||||||
|
|
||||||
|
other_field = gst_h264_decoder_new_field_picture (self, picture);
|
||||||
|
if (!other_field) {
|
||||||
|
GST_WARNING_OBJECT (self,
|
||||||
|
"Couldn't split frame into complementary field pair");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_LOG_OBJECT (self, "Split picture %p, poc %d, frame num %d",
|
||||||
|
picture, picture->pic_order_cnt, picture->frame_num);
|
||||||
|
|
||||||
|
/* FIXME: enhance TFF decision by using picture timing SEI */
|
||||||
|
if (picture->top_field_order_cnt < picture->bottom_field_order_cnt) {
|
||||||
|
picture->field = GST_H264_PICTURE_FIELD_TOP_FIELD;
|
||||||
|
picture->pic_order_cnt = picture->top_field_order_cnt;
|
||||||
|
|
||||||
|
other_field->field = GST_H264_PICTURE_FIELD_BOTTOM_FIELD;
|
||||||
|
other_field->pic_order_cnt = picture->bottom_field_order_cnt;
|
||||||
|
} else {
|
||||||
|
picture->field = GST_H264_PICTURE_FIELD_BOTTOM_FIELD;
|
||||||
|
picture->pic_order_cnt = picture->bottom_field_order_cnt;
|
||||||
|
|
||||||
|
other_field->field = GST_H264_PICTURE_FIELD_TOP_FIELD;
|
||||||
|
other_field->pic_order_cnt = picture->top_field_order_cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
other_field->top_field_order_cnt = picture->top_field_order_cnt;
|
||||||
|
other_field->bottom_field_order_cnt = picture->bottom_field_order_cnt;
|
||||||
|
other_field->frame_num = picture->frame_num;
|
||||||
|
other_field->ref = picture->ref;
|
||||||
|
other_field->nonexisting = picture->nonexisting;
|
||||||
|
|
||||||
|
return other_field;
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
@ -669,7 +712,15 @@ gst_h264_decoder_handle_frame_num_gap (GstH264Decoder * self, gint frame_num)
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_h264_dpb_delete_unused (priv->dpb);
|
gst_h264_dpb_delete_unused (priv->dpb);
|
||||||
gst_h264_dpb_add (priv->dpb, picture);
|
if (gst_h264_dpb_get_interlaced (priv->dpb)) {
|
||||||
|
GstH264Picture *other_field =
|
||||||
|
gst_h264_decoder_split_frame (self, picture);
|
||||||
|
|
||||||
|
gst_h264_dpb_add (priv->dpb, picture);
|
||||||
|
gst_h264_dpb_add (priv->dpb, other_field);
|
||||||
|
} else {
|
||||||
|
gst_h264_dpb_add (priv->dpb, picture);
|
||||||
|
}
|
||||||
while (gst_h264_dpb_needs_bump (priv->dpb, priv->max_num_reorder_frames,
|
while (gst_h264_dpb_needs_bump (priv->dpb, priv->max_num_reorder_frames,
|
||||||
FALSE)) {
|
FALSE)) {
|
||||||
GstH264Picture *to_output;
|
GstH264Picture *to_output;
|
||||||
|
@ -793,7 +844,9 @@ gst_h264_decoder_new_field_picture (GstH264Decoder * self,
|
||||||
}
|
}
|
||||||
|
|
||||||
new_picture = gst_h264_picture_new ();
|
new_picture = gst_h264_picture_new ();
|
||||||
if (!klass->new_field_picture (self, picture, new_picture)) {
|
/* don't confuse subclass by non-existing picture */
|
||||||
|
if (!picture->nonexisting &&
|
||||||
|
!klass->new_field_picture (self, picture, new_picture)) {
|
||||||
GST_ERROR_OBJECT (self, "Subclass couldn't handle new field picture");
|
GST_ERROR_OBJECT (self, "Subclass couldn't handle new field picture");
|
||||||
gst_h264_picture_unref (new_picture);
|
gst_h264_picture_unref (new_picture);
|
||||||
|
|
||||||
|
@ -1679,40 +1732,14 @@ gst_h264_decoder_finish_picture (GstH264Decoder * self,
|
||||||
*/
|
*/
|
||||||
if (gst_h264_dpb_get_interlaced (priv->dpb) &&
|
if (gst_h264_dpb_get_interlaced (priv->dpb) &&
|
||||||
GST_H264_PICTURE_IS_FRAME (picture)) {
|
GST_H264_PICTURE_IS_FRAME (picture)) {
|
||||||
GstH264Picture *other_field =
|
GstH264Picture *other_field = gst_h264_decoder_split_frame (self, picture);
|
||||||
gst_h264_decoder_new_field_picture (self, picture);
|
|
||||||
|
|
||||||
|
gst_h264_dpb_add (priv->dpb, 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... */
|
||||||
gst_h264_dpb_add (priv->dpb, picture);
|
|
||||||
} else {
|
} else {
|
||||||
GST_LOG_OBJECT (self, "Split picture %p, poc %d, frame num %d",
|
|
||||||
picture, picture->pic_order_cnt, picture->frame_num);
|
|
||||||
|
|
||||||
/* FIXME: enhance TFF decision by using picture timing SEI */
|
|
||||||
if (picture->top_field_order_cnt < picture->bottom_field_order_cnt) {
|
|
||||||
picture->field = GST_H264_PICTURE_FIELD_TOP_FIELD;
|
|
||||||
picture->pic_order_cnt = picture->top_field_order_cnt;
|
|
||||||
|
|
||||||
other_field->field = GST_H264_PICTURE_FIELD_BOTTOM_FIELD;
|
|
||||||
other_field->pic_order_cnt = picture->bottom_field_order_cnt;
|
|
||||||
} else {
|
|
||||||
picture->field = GST_H264_PICTURE_FIELD_BOTTOM_FIELD;
|
|
||||||
picture->pic_order_cnt = picture->bottom_field_order_cnt;
|
|
||||||
|
|
||||||
other_field->field = GST_H264_PICTURE_FIELD_TOP_FIELD;
|
|
||||||
other_field->pic_order_cnt = picture->top_field_order_cnt;
|
|
||||||
}
|
|
||||||
|
|
||||||
other_field->top_field_order_cnt = picture->top_field_order_cnt;
|
|
||||||
other_field->bottom_field_order_cnt = picture->bottom_field_order_cnt;
|
|
||||||
other_field->frame_num = picture->frame_num;
|
|
||||||
other_field->ref = picture->ref;
|
|
||||||
|
|
||||||
gst_h264_dpb_add (priv->dpb, picture);
|
|
||||||
gst_h264_dpb_add (priv->dpb, other_field);
|
gst_h264_dpb_add (priv->dpb, other_field);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -265,16 +265,17 @@ gst_h264_dpb_add (GstH264Dpb * dpb, GstH264Picture * picture)
|
||||||
/* We can do output only when field pair are complete */
|
/* We can do output only when field pair are complete */
|
||||||
if (picture->second_field) {
|
if (picture->second_field) {
|
||||||
dpb->num_output_needed++;
|
dpb->num_output_needed++;
|
||||||
|
|
||||||
/* And link each field */
|
|
||||||
if (picture->other_field)
|
|
||||||
picture->other_field->other_field = picture;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
picture->needed_for_output = FALSE;
|
picture->needed_for_output = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Link each field */
|
||||||
|
if (picture->second_field && picture->other_field) {
|
||||||
|
picture->other_field->other_field = picture;
|
||||||
|
}
|
||||||
|
|
||||||
g_array_append_val (dpb->pic_list, picture);
|
g_array_append_val (dpb->pic_list, picture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue