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 */