diff --git a/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codecmpeg2dec.c b/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codecmpeg2dec.c index 3e0e802022f36b59949feb0b9cec7e0824916030..633de2717d23cb3031a7cfd729f8ce3c87029b9e 100644 --- a/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codecmpeg2dec.c +++ b/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codecmpeg2dec.c @@ -40,7 +40,13 @@ GST_DEBUG_CATEGORY_STATIC (v4l2_mpeg2dec_debug); enum { PROP_0, - PROP_LAST = PROP_0 + PROP_UAPI_VERSION, + PROP_LAST = PROP_UAPI_VERSION, +}; + +static const int _gst_supported_uapi_versions[] = { + V4L2_STATELESS_MPEG2_UAPI_V1, + V4L2_STATELESS_MPEG2_UAPI_V2, }; static GstStaticPadTemplate sink_template = @@ -73,9 +79,22 @@ struct _GstV4l2CodecMpeg2Dec gboolean need_sequence; gboolean need_quantiser; - struct v4l2_ctrl_mpeg2_sequence v4l2_sequence; - struct v4l2_ctrl_mpeg2_picture v4l2_picture; - struct v4l2_ctrl_mpeg2_quantisation v4l2_quantisation; + union + { + struct + { + struct v4l2_ctrl_mpeg2_sequence v4l2_sequence; + struct v4l2_ctrl_mpeg2_picture v4l2_picture; + struct v4l2_ctrl_mpeg2_quantisation v4l2_quantisation; + } v1; + + struct + { + struct v4l2_ctrl_mpeg2_sequence_v2 v4l2_sequence; + struct v4l2_ctrl_mpeg2_picture_v2 v4l2_picture; + struct v4l2_ctrl_mpeg2_quantisation_v2 v4l2_quantisation; + } v2; + } uapi; GstV4l2CodecAllocator *sink_allocator; GstV4l2CodecAllocator *src_allocator; @@ -88,6 +107,7 @@ struct _GstV4l2CodecMpeg2Dec GstMapInfo bitstream_map; gboolean copy_frames; + gint uapi_version; }; G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstV4l2CodecMpeg2Dec, @@ -212,27 +232,102 @@ get_pixel_bitdepth (GstV4l2CodecMpeg2Dec * self) return depth; } +static inline void +_validate_uapi_version (GstV4l2CodecMpeg2Dec * self) +{ + gint driver_default; + gint i; + + struct v4l2_ext_control control = (struct v4l2_ext_control) { + .id = V4L2_CID_STATELESS_MPEG2_UAPI_VERSION, + }; + + if (!gst_v4l2_codec_mpeg2_dec_open (GST_VIDEO_DECODER (self))) { + self->uapi_version = -1; + return; + } + + if (!gst_v4l2_decoder_get_controls (self->decoder, &control, 1)) { + GST_ELEMENT_ERROR (self, RESOURCE, OPEN_READ_WRITE, + ("Driver did not report its supported uAPI version, assuming v1."), + ("gst_v4l2_decoder_get_controls() failed: %s", g_strerror (errno))); + self->uapi_version = V4L2_STATELESS_MPEG2_UAPI_V1; + gst_v4l2_codec_mpeg2_dec_close (GST_VIDEO_DECODER (self)); + return; + } + + driver_default = control.value; + if (self->uapi_version == driver_default) { + gst_v4l2_codec_mpeg2_dec_close (GST_VIDEO_DECODER (self)); + return; + } + + /* + * driver supports versioning, try our version i.e. we might want to make sure + * all versions work for a particular driver, so being able to choose via a gst + * property might prove useful.. + */ + control.value = self->uapi_version; + + if (gst_v4l2_decoder_set_controls (self->decoder, NULL, &control, 1)) { + gst_v4l2_codec_mpeg2_dec_close (GST_VIDEO_DECODER (self)); + return; + } else { + GST_ELEMENT_ERROR (self, RESOURCE, WRITE, + ("Driver does not support the selected uAPI version, trying driver default %d", + driver_default), + ("Driver does not support the selected uAPI version, trying driver default %d", + driver_default)); + + for (i = 0; i < G_N_ELEMENTS (_gst_supported_uapi_versions); i++) + if (_gst_supported_uapi_versions[i] == driver_default) { + self->uapi_version = driver_default; + gst_v4l2_codec_mpeg2_dec_close (GST_VIDEO_DECODER (self)); + return; + } + } + + GST_ELEMENT_ERROR (self, RESOURCE, WRITE, + ("GStreamer does not support this uAPI version %d", + self->uapi_version), + ("GStreamer does not support this uAPI version %d", self->uapi_version)); + + self->uapi_version = -1; + gst_v4l2_codec_mpeg2_dec_close (GST_VIDEO_DECODER (self)); +} + static gboolean gst_v4l2_codec_mpeg2_dec_negotiate (GstVideoDecoder * decoder) { GstV4l2CodecMpeg2Dec *self = GST_V4L2_CODEC_MPEG2_DEC (decoder); GstMpeg2Decoder *mpeg2dec = GST_MPEG2_DECODER (decoder); /* *INDENT-OFF* */ - struct v4l2_ext_control control[] = { - { - .id = V4L2_CID_STATELESS_MPEG2_SEQUENCE, - .ptr = &self->v4l2_sequence, - .size = sizeof(self->v4l2_sequence), - }, - { - .id = V4L2_CID_STATELESS_MPEG2_QUANTISATION, - .ptr = &self->v4l2_quantisation, - .size = sizeof(self->v4l2_quantisation), - }, - }; + struct v4l2_ext_control control[2]; + GstCaps *filter, *caps; + + switch (self->uapi_version) { + case V4L2_STATELESS_MPEG2_UAPI_V1: + control[0].id = V4L2_CID_STATELESS_MPEG2_SEQUENCE; + control[0].ptr = &self->uapi.v1.v4l2_sequence; + control[0].size = sizeof(self->uapi.v1.v4l2_sequence); + + control[1].id = V4L2_CID_STATELESS_MPEG2_QUANTISATION; + control[1].ptr = &self->uapi.v1.v4l2_quantisation; + control[1].size = sizeof(self->uapi.v1.v4l2_quantisation); + break; + case V4L2_STATELESS_MPEG2_UAPI_V2: + /* actually implement v2 */ + break; + + /* we do not support this version */ + default: + GST_ELEMENT_ERROR (decoder, CORE, NEGOTIATION, + ("Invalid uAPI version %d", self->uapi_version), + ("Invalid uAPI version %d", self->uapi_version)); + return FALSE; + } /* *INDENT-ON* */ - GstCaps *filter, *caps; /* Ignore downstream renegotiation request. */ if (!self->need_negotiation) @@ -427,26 +522,32 @@ gst_v4l2_codec_mpeg2_dec_new_sequence (GstMpeg2Decoder * decoder, * if none is provided this will copy the default ones * added by the parser */ - memcpy (self->v4l2_quantisation.intra_quantiser_matrix, - seq->intra_quantizer_matrix, - sizeof (self->v4l2_quantisation.intra_quantiser_matrix));; - memcpy (self->v4l2_quantisation.non_intra_quantiser_matrix, - seq->non_intra_quantizer_matrix, - sizeof (self->v4l2_quantisation.non_intra_quantiser_matrix));; - /* *INDENT-OFF* */ - self->v4l2_sequence = (struct v4l2_ctrl_mpeg2_sequence) { - .horizontal_size = self->width, - .vertical_size = self->height, - .vbv_buffer_size = self->vbv_buffer_size * 16 * 1024, - .profile_and_level_indication = - seq_ext ? (seq_ext->profile << 4) | (seq_ext-> - level << 1) | seq_ext->profile_level_escape_bit : 0, - .chroma_format = seq_ext ? seq_ext->chroma_format : 0, - .flags = seq_ext->progressive ? V4L2_MPEG2_SEQ_FLAG_PROGRESSIVE : 0, - }; - /* *INDENT-ON* */ + switch (self->uapi_version) { + case V4L2_STATELESS_MPEG2_UAPI_V1: + memcpy (self->uapi.v1.v4l2_quantisation.intra_quantiser_matrix, + seq->intra_quantizer_matrix, + sizeof (self->uapi.v1.v4l2_quantisation.intra_quantiser_matrix));; + memcpy (self->uapi.v1.v4l2_quantisation.non_intra_quantiser_matrix, + seq->non_intra_quantizer_matrix, + sizeof (self->uapi.v1.v4l2_quantisation.non_intra_quantiser_matrix));; + + self->uapi.v1.v4l2_sequence = (struct v4l2_ctrl_mpeg2_sequence) { + .horizontal_size = self->width, + .vertical_size = self->height, + .vbv_buffer_size = self->vbv_buffer_size * 16 * 1024, + .profile_and_level_indication = + seq_ext ? (seq_ext->profile << 4) | (seq_ext-> + level << 1) | seq_ext->profile_level_escape_bit : 0, + .chroma_format = seq_ext ? seq_ext->chroma_format : 0, + .flags = seq_ext->progressive ? V4L2_MPEG2_SEQ_FLAG_PROGRESSIVE : 0, + }; + break; + case V4L2_STATELESS_MPEG2_UAPI_V2: + /* actually implement v2 */ + break; + } if (negotiation_needed) { self->need_negotiation = TRUE; if (!gst_video_decoder_negotiate (GST_VIDEO_DECODER (self))) { @@ -563,54 +664,66 @@ gst_v4l2_codec_mpeg2_dec_start_picture (GstMpeg2Decoder * decoder, if (!gst_v4l2_codec_mpeg2_dec_ensure_bitstream (self)) return GST_FLOW_ERROR; + switch (self->uapi_version) { + case V4L2_STATELESS_MPEG2_UAPI_V1: + /* *INDENT-OFF* */ + self->uapi.v1.v4l2_picture = (struct v4l2_ctrl_mpeg2_picture) { + .backward_ref_ts = next_picture ? next_picture->system_frame_number * 1000 : GST_CLOCK_TIME_NONE, + .forward_ref_ts = prev_picture ? prev_picture->system_frame_number * 1000 : GST_CLOCK_TIME_NONE, + .intra_dc_precision = slice->pic_ext ? slice->pic_ext->intra_dc_precision : 0, + .flags = (slice->pic_ext && slice->pic_ext->top_field_first ? V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST : 0) | + (slice->pic_ext && slice->pic_ext->frame_pred_frame_dct ? V4L2_MPEG2_PIC_FLAG_FRAME_PRED_DCT : 0 ) | + (slice->pic_ext && slice->pic_ext->concealment_motion_vectors ? V4L2_MPEG2_PIC_FLAG_CONCEALMENT_MV : 0) | + (slice->pic_ext && slice->pic_ext->q_scale_type ? V4L2_MPEG2_PIC_FLAG_Q_SCALE_TYPE : 0) | + (slice->pic_ext && slice->pic_ext->intra_vlc_format ? V4L2_MPEG2_PIC_FLAG_INTRA_VLC : 0) | + (slice->pic_ext && slice->pic_ext->alternate_scan ? V4L2_MPEG2_PIC_FLAG_ALT_SCAN : 0) | + (slice->pic_ext && slice->pic_ext->repeat_first_field ? V4L2_MPEG2_PIC_FLAG_REPEAT_FIRST : 0) | + (slice->pic_ext && slice->pic_ext->progressive_frame ? V4L2_MPEG2_PIC_FLAG_PROGRESSIVE : 0), + }; + /* *INDENT-ON* */ + + _parse_picture_coding_type (&self->uapi.v1.v4l2_picture, picture); + _parse_picture_structure (&self->uapi.v1.v4l2_picture, slice); + + /* slices share pic_ext and quant_matrix for the picture which might be there or not */ + if (slice->pic_ext) + memcpy (&self->uapi.v1.v4l2_picture.f_code, slice->pic_ext->f_code, + sizeof (self->uapi.v1.v4l2_picture.f_code)); + + /* overwrite the sequence ones if needed, see 6.1.1.6 for reference */ + if (slice->quant_matrix) { + if (slice->quant_matrix->load_intra_quantiser_matrix) + memcpy (self->uapi.v1.v4l2_quantisation.intra_quantiser_matrix, + slice->quant_matrix->intra_quantiser_matrix, + sizeof (self->uapi.v1.v4l2_quantisation.intra_quantiser_matrix)); + if (slice->quant_matrix->load_non_intra_quantiser_matrix) + memcpy (self->uapi.v1.v4l2_quantisation.non_intra_quantiser_matrix, + slice->quant_matrix->non_intra_quantiser_matrix, + sizeof (self->uapi.v1. + v4l2_quantisation.non_intra_quantiser_matrix)); + if (slice->quant_matrix->load_chroma_intra_quantiser_matrix) + memcpy (self->uapi.v1.v4l2_quantisation.chroma_intra_quantiser_matrix, + slice->quant_matrix->chroma_intra_quantiser_matrix, + sizeof (self->uapi.v1. + v4l2_quantisation.chroma_intra_quantiser_matrix)); + if (slice->quant_matrix->load_chroma_non_intra_quantiser_matrix) + memcpy (self->uapi.v1. + v4l2_quantisation.chroma_non_intra_quantiser_matrix, + slice->quant_matrix->chroma_non_intra_quantiser_matrix, + sizeof (self->uapi.v1. + v4l2_quantisation.chroma_non_intra_quantiser_matrix)); + + self->need_quantiser |= + (slice->quant_matrix->load_intra_quantiser_matrix + || slice->quant_matrix->load_non_intra_quantiser_matrix + || slice->quant_matrix->load_chroma_intra_quantiser_matrix + || slice->quant_matrix->load_chroma_non_intra_quantiser_matrix); + } + break; - /* *INDENT-OFF* */ - self->v4l2_picture = (struct v4l2_ctrl_mpeg2_picture) { - .backward_ref_ts = next_picture ? next_picture->system_frame_number * 1000 : GST_CLOCK_TIME_NONE, - .forward_ref_ts = prev_picture ? prev_picture->system_frame_number * 1000 : GST_CLOCK_TIME_NONE, - .intra_dc_precision = slice->pic_ext ? slice->pic_ext->intra_dc_precision : 0, - .flags = (slice->pic_ext && slice->pic_ext->top_field_first ? V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST : 0) | - (slice->pic_ext && slice->pic_ext->frame_pred_frame_dct ? V4L2_MPEG2_PIC_FLAG_FRAME_PRED_DCT : 0 ) | - (slice->pic_ext && slice->pic_ext->concealment_motion_vectors ? V4L2_MPEG2_PIC_FLAG_CONCEALMENT_MV : 0) | - (slice->pic_ext && slice->pic_ext->q_scale_type ? V4L2_MPEG2_PIC_FLAG_Q_SCALE_TYPE : 0) | - (slice->pic_ext && slice->pic_ext->intra_vlc_format ? V4L2_MPEG2_PIC_FLAG_INTRA_VLC : 0) | - (slice->pic_ext && slice->pic_ext->alternate_scan ? V4L2_MPEG2_PIC_FLAG_ALT_SCAN : 0) | - (slice->pic_ext && slice->pic_ext->repeat_first_field ? V4L2_MPEG2_PIC_FLAG_REPEAT_FIRST : 0) | - (slice->pic_ext && slice->pic_ext->progressive_frame ? V4L2_MPEG2_PIC_FLAG_PROGRESSIVE : 0), - }; - /* *INDENT-ON* */ - - _parse_picture_coding_type (&self->v4l2_picture, picture); - _parse_picture_structure (&self->v4l2_picture, slice); - - /* slices share pic_ext and quant_matrix for the picture which might be there or not */ - if (slice->pic_ext) - memcpy (&self->v4l2_picture.f_code, slice->pic_ext->f_code, - sizeof (self->v4l2_picture.f_code)); - - /* overwrite the sequence ones if needed, see 6.1.1.6 for reference */ - if (slice->quant_matrix) { - if (slice->quant_matrix->load_intra_quantiser_matrix) - memcpy (self->v4l2_quantisation.intra_quantiser_matrix, - slice->quant_matrix->intra_quantiser_matrix, - sizeof (self->v4l2_quantisation.intra_quantiser_matrix)); - if (slice->quant_matrix->load_non_intra_quantiser_matrix) - memcpy (self->v4l2_quantisation.non_intra_quantiser_matrix, - slice->quant_matrix->non_intra_quantiser_matrix, - sizeof (self->v4l2_quantisation.non_intra_quantiser_matrix)); - if (slice->quant_matrix->load_chroma_intra_quantiser_matrix) - memcpy (self->v4l2_quantisation.chroma_intra_quantiser_matrix, - slice->quant_matrix->chroma_intra_quantiser_matrix, - sizeof (self->v4l2_quantisation.chroma_intra_quantiser_matrix)); - if (slice->quant_matrix->load_chroma_non_intra_quantiser_matrix) - memcpy (self->v4l2_quantisation.chroma_non_intra_quantiser_matrix, - slice->quant_matrix->chroma_non_intra_quantiser_matrix, - sizeof (self->v4l2_quantisation.chroma_non_intra_quantiser_matrix)); - - self->need_quantiser |= (slice->quant_matrix->load_intra_quantiser_matrix || - slice->quant_matrix->load_non_intra_quantiser_matrix || - slice->quant_matrix->load_chroma_intra_quantiser_matrix || - slice->quant_matrix->load_chroma_non_intra_quantiser_matrix); + case V4L2_STATELESS_MPEG2_UAPI_V2: + /* actually implement v2 */ + break; } return GST_FLOW_OK; @@ -758,6 +871,10 @@ gst_v4l2_codec_mpeg2_dec_submit_bitstream (GstV4l2CodecMpeg2Dec * self, /* *INDENT-OFF* */ /* Reserve space for controls */ + /* + * TODO: calloc memory since newer versions might have a different number of + * controls in practice + */ struct v4l2_ext_control control[] = { { }, /* sequence */ { }, /* picture */ @@ -803,25 +920,32 @@ gst_v4l2_codec_mpeg2_dec_submit_bitstream (GstV4l2CodecMpeg2Dec * self, goto done; } - if (self->need_sequence) { - control[count].id = V4L2_CID_STATELESS_MPEG2_SEQUENCE; - control[count].ptr = &self->v4l2_sequence; - control[count].size = sizeof (self->v4l2_sequence); - count++; - self->need_sequence = FALSE; - } + switch (self->uapi_version) { + case V4L2_STATELESS_MPEG2_UAPI_V1: + if (self->need_sequence) { + control[count].id = V4L2_CID_STATELESS_MPEG2_SEQUENCE; + control[count].ptr = &self->uapi.v1.v4l2_sequence; + control[count].size = sizeof (self->uapi.v1.v4l2_sequence); + count++; + self->need_sequence = FALSE; + } - control[count].id = V4L2_CID_STATELESS_MPEG2_PICTURE; - control[count].ptr = &self->v4l2_picture; - control[count].size = sizeof (self->v4l2_picture); - count++; - - if (self->need_quantiser) { - control[count].id = V4L2_CID_STATELESS_MPEG2_QUANTISATION; - control[count].ptr = &self->v4l2_quantisation; - control[count].size = sizeof (self->v4l2_quantisation); - count++; - self->need_quantiser = FALSE; + control[count].id = V4L2_CID_STATELESS_MPEG2_PICTURE; + control[count].ptr = &self->uapi.v1.v4l2_picture; + control[count].size = sizeof (self->uapi.v1.v4l2_picture); + count++; + + if (self->need_quantiser) { + control[count].id = V4L2_CID_STATELESS_MPEG2_QUANTISATION; + control[count].ptr = &self->uapi.v1.v4l2_quantisation; + control[count].size = sizeof (self->uapi.v1.v4l2_quantisation); + count++; + self->need_quantiser = FALSE; + } + break; + case V4L2_STATELESS_MPEG2_UAPI_V2: + /* actually implement v2 */ + break; } if (!gst_v4l2_decoder_set_controls (self->decoder, request, control, count)) { @@ -938,6 +1062,20 @@ gst_v4l2_codec_mpeg2_dec_change_state (GstElement * element, return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); } +static void +_set_uapi_version (GstV4l2CodecMpeg2Dec * self, gint version) +{ + switch (version) { + default: + case 1: + self->uapi_version = V4L2_STATELESS_MPEG2_UAPI_V1; + break; + case 2: + self->uapi_version = V4L2_STATELESS_MPEG2_UAPI_V2; + break; + } +} + static void gst_v4l2_codec_mpeg2_dec_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) @@ -946,6 +1084,13 @@ gst_v4l2_codec_mpeg2_dec_set_property (GObject * object, guint prop_id, GObject *dec = G_OBJECT (self->decoder); switch (prop_id) { + case PROP_UAPI_VERSION: + if (self->uapi_version == -1) { + _set_uapi_version (self, g_value_get_int (value)); + _validate_uapi_version (self); + } + GST_DEBUG_OBJECT (self, "Using uAPI v%d", self->uapi_version); + break; default: gst_v4l2_decoder_set_property (dec, prop_id - PROP_LAST, value, pspec); break; @@ -960,6 +1105,8 @@ gst_v4l2_codec_mpeg2_dec_get_property (GObject * object, guint prop_id, GObject *dec = G_OBJECT (self->decoder); switch (prop_id) { + case PROP_UAPI_VERSION: + g_value_set_int (value, self->uapi_version); default: gst_v4l2_decoder_get_property (dec, prop_id - PROP_LAST, value, pspec); break; @@ -977,6 +1124,7 @@ gst_v4l2_codec_mpeg2_dec_subinit (GstV4l2CodecMpeg2Dec * self, { self->decoder = gst_v4l2_decoder_new (klass->device); gst_video_info_init (&self->vinfo); + self->uapi_version = -1; } static void @@ -1007,6 +1155,11 @@ gst_v4l2_codec_mpeg2_dec_subclass_init (GstV4l2CodecMpeg2DecClass * klass, gobject_class->get_property = gst_v4l2_codec_mpeg2_dec_get_property; gobject_class->dispose = gst_v4l2_codec_mpeg2_dec_dispose; + g_object_class_install_property (gobject_class, PROP_UAPI_VERSION, + g_param_spec_int ("uapi-version", "uAPI Version", + "The Linux Kernel uAPI version to use for this stateless codec", 1, 2, + 1, G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS)); + gst_element_class_set_static_metadata (element_class, "V4L2 Stateless Mpeg2 Video Decoder", "Codec/Decoder/Video/Hardware", diff --git a/subprojects/gst-plugins-bad/sys/v4l2codecs/linux/v4l2-controls.h b/subprojects/gst-plugins-bad/sys/v4l2codecs/linux/v4l2-controls.h index 091b933b0793912de0f2a34b887068db1485725c..b7112841d968d5eea9542cc02b4903a5c6b8488d 100644 --- a/subprojects/gst-plugins-bad/sys/v4l2codecs/linux/v4l2-controls.h +++ b/subprojects/gst-plugins-bad/sys/v4l2codecs/linux/v4l2-controls.h @@ -1973,6 +1973,44 @@ struct v4l2_ctrl_mpeg2_quantisation { __u8 chroma_non_intra_quantiser_matrix[64]; }; +#define V4L2_CID_STATELESS_MPEG2_UAPI_VERSION (V4L2_CID_CODEC_STATELESS_BASE+223) + +enum v4l2_stateless_mpeg2_uapi_version { + V4L2_STATELESS_MPEG2_UAPI_V1, /* assume V1 by default */ + V4L2_STATELESS_MPEG2_UAPI_V2, +}; + +#define V4L2_CID_STATELESS_MPEG2_QUANTISATION_V2 (V4L2_CID_CODEC_STATELESS_BASE+224) +#define V4L2_CID_STATELESS_MPEG2_PICTURE_V2 (V4L2_CID_CODEC_STATELESS_BASE+225) +#define V4L2_CID_STATELESS_MPEG2_SEQUENCE_V2 (V4L2_CID_CODEC_STATELESS_BASE+226) + +struct v4l2_ctrl_mpeg2_quantisation_v2 { + __u8 intra_quantiser_matrix[64]; + __u8 non_intra_quantiser_matrix[64]; + __u8 chroma_intra_quantiser_matrix[64]; + __u8 chroma_non_intra_quantiser_matrix[64]; +}; + +struct v4l2_ctrl_mpeg2_picture_v2 { + __u64 backward_ref_ts; + __u64 forward_ref_ts; + __u32 flags; + __u8 f_code[2][2]; + __u8 picture_coding_type; + __u8 picture_structure; + __u8 intra_dc_precision; + __u8 reserved[5]; +}; + +struct v4l2_ctrl_mpeg2_sequence_v2 { + __u16 horizontal_size; + __u16 vertical_size; + __u32 vbv_buffer_size; + __u16 profile_and_level_indication; + __u8 chroma_format; + __u8 flags; +}; + #define V4L2_CID_COLORIMETRY_CLASS_BASE (V4L2_CTRL_CLASS_COLORIMETRY | 0x900) #define V4L2_CID_COLORIMETRY_CLASS (V4L2_CTRL_CLASS_COLORIMETRY | 1) diff --git a/subprojects/gst-plugins-bad/sys/v4l2codecs/linux/videodev2.h b/subprojects/gst-plugins-bad/sys/v4l2codecs/linux/videodev2.h index 2ee05f658aa7a7d400a21ec50bd7f4300ef486f9..41ac6f4f7def2b371be32b26cc2581568d673c0d 100644 --- a/subprojects/gst-plugins-bad/sys/v4l2codecs/linux/videodev2.h +++ b/subprojects/gst-plugins-bad/sys/v4l2codecs/linux/videodev2.h @@ -1720,6 +1720,10 @@ struct v4l2_ext_control { struct v4l2_ctrl_mpeg2_quantisation *p_mpeg2_quantisation; struct v4l2_ctrl_vp9_compressed_hdr *p_vp9_compressed_hdr_probs; struct v4l2_ctrl_vp9_frame *p_vp9_frame; + struct v4l2_ctrl_mpeg2_uapi_version *p_mpeg2_uapi_version; + struct v4l2_ctrl_mpeg2_sequence_v2 *p_mpeg2_sequence_v2; + struct v4l2_ctrl_mpeg2_picture_v2 *p_mpeg2_picture_v2; + struct v4l2_ctrl_mpeg2_quantisation_v2 *p_mpeg2_quantisation_v2; void *ptr; }; } __attribute__ ((packed)); @@ -1776,6 +1780,9 @@ enum v4l2_ctrl_type { V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR = 0x0260, V4L2_CTRL_TYPE_VP9_FRAME = 0x0261, + V4L2_CTRL_TYPE_MPEG2_QUANTISATION_V2 = 0x0253, + V4L2_CTRL_TYPE_MPEG2_SEQUENCE_V2 = 0x0254, + V4L2_CTRL_TYPE_MPEG2_PICTURE_V2 = 0x0255, }; /* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */