summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorBenjamin Gaignard <benjamin.gaignard@collabora.com>2021-02-16 11:23:17 +0100
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>2021-03-02 22:03:34 +0000
commit5e8daa1c5c85767ce0f4eace61347c5774b86416 (patch)
tree9db055d8d675bd6abd85f47d1c7561898d827976 /sys
parent84daea6be29e835aa683c4ec9a5076ab6fcce0f0 (diff)
downloadgstreamer-plugins-bad-5e8daa1c5c85767ce0f4eace61347c5774b86416.tar.gz
v4l2codecs: h264: retrieve interlaced information
Lets the decoder knows if the frames are interlaced or not. Provide this information to the driver while filling reference pictures fields in slice params structure Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1624>
Diffstat (limited to 'sys')
-rw-r--r--sys/v4l2codecs/gstv4l2codech264dec.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/sys/v4l2codecs/gstv4l2codech264dec.c b/sys/v4l2codecs/gstv4l2codech264dec.c
index 6aae3f3e8..095632515 100644
--- a/sys/v4l2codecs/gstv4l2codech264dec.c
+++ b/sys/v4l2codecs/gstv4l2codech264dec.c
@@ -75,6 +75,7 @@ struct _GstV4l2CodecH264Dec
gint min_pool_size;
gboolean has_videometa;
gboolean need_negotiation;
+ gboolean interlaced;
gboolean need_sequence;
gboolean copy_frames;
gboolean scaling_matrix_present;
@@ -372,6 +373,9 @@ gst_v4l2_codec_h264_dec_negotiate (GstVideoDecoder * decoder)
self->vinfo.finfo->format, self->display_width,
self->display_height, h264dec->input_state);
+ if (self->interlaced)
+ self->output_state->info.interlace_mode = GST_VIDEO_INTERLACE_MODE_MIXED;
+
self->output_state->caps = gst_video_info_to_caps (&self->output_state->info);
if (GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder)) {
@@ -715,7 +719,10 @@ gst_v4l2_codec_h264_dec_fill_references (GstV4l2CodecH264Dec * self,
GArray * ref_pic_list0, GArray * ref_pic_list1)
{
struct v4l2_ctrl_h264_slice_params *slice_params;
- gint i;
+ gint i, fields = V4L2_H264_FRAME_REF;
+
+ if (self->interlaced)
+ fields = 0;
slice_params = &g_array_index (self->slice_params,
struct v4l2_ctrl_h264_slice_params, 0);
@@ -730,7 +737,7 @@ gst_v4l2_codec_h264_dec_fill_references (GstV4l2CodecH264Dec * self,
g_array_index (ref_pic_list0, GstH264Picture *, i);
slice_params->ref_pic_list0[i].index =
lookup_dpb_index (self->decode_params.dpb, ref_pic);
- slice_params->ref_pic_list0[i].fields = 0;
+ slice_params->ref_pic_list0[i].fields = fields;
}
for (i = 0; i < ref_pic_list1->len; i++) {
@@ -738,7 +745,7 @@ gst_v4l2_codec_h264_dec_fill_references (GstV4l2CodecH264Dec * self,
g_array_index (ref_pic_list1, GstH264Picture *, i);
slice_params->ref_pic_list1[i].index =
lookup_dpb_index (self->decode_params.dpb, ref_pic);
- slice_params->ref_pic_list1[i].fields = 0;
+ slice_params->ref_pic_list1[i].fields = fields;
}
}
@@ -750,6 +757,7 @@ gst_v4l2_codec_h264_dec_new_sequence (GstH264Decoder * decoder,
gint crop_width = sps->width;
gint crop_height = sps->height;
gboolean negotiation_needed = FALSE;
+ gboolean interlaced;
if (self->vinfo.finfo->format == GST_VIDEO_FORMAT_UNKNOWN)
negotiation_needed = TRUE;
@@ -778,6 +786,14 @@ gst_v4l2_codec_h264_dec_new_sequence (GstH264Decoder * decoder,
self->coded_width, self->coded_height);
}
+ interlaced = !sps->frame_mbs_only_flag;
+ if (self->interlaced != interlaced) {
+ self->interlaced = interlaced;
+
+ negotiation_needed = TRUE;
+ GST_INFO_OBJECT (self, "Interlaced mode changed to %d", interlaced);
+ }
+
if (self->bitdepth != sps->bit_depth_luma_minus8 + 8) {
self->bitdepth = sps->bit_depth_luma_minus8 + 8;
negotiation_needed = TRUE;