diff options
author | Benjamin Gaignard <benjamin.gaignard@collabora.com> | 2021-02-16 11:23:17 +0100 |
---|---|---|
committer | GStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org> | 2021-03-02 22:03:34 +0000 |
commit | 5e8daa1c5c85767ce0f4eace61347c5774b86416 (patch) | |
tree | 9db055d8d675bd6abd85f47d1c7561898d827976 /sys | |
parent | 84daea6be29e835aa683c4ec9a5076ab6fcce0f0 (diff) | |
download | gstreamer-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.c | 22 |
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; |