v4l2codecs: decoders: Add DMA_DRM caps support

In order to simplify caps negotiations for clients and, notably, be more
compatible with va* decoders.
Crucially this allows clients to know ahead of time whether buffers will
actually be DMABufs.

Similar to GstVaBaseDec we only announce system memory caps if the peer
has ANY caps. Further more, and again like va decoders, we fail in
`decide_allocation()` if DMA_DRM caps are used without VideoMeta.
Apart from buggy peers this can happen e.g. when a peer with ANY caps
is used in combination with caps filters.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5890>
This commit is contained in:
Robert Mader 2024-01-06 13:07:16 +01:00 committed by GStreamer Marge Bot
parent 513d0d8cbb
commit 5189e8b956
8 changed files with 271 additions and 42 deletions

View file

@ -53,9 +53,14 @@ GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SINK_NAME,
GST_STATIC_CAPS ("video/x-av1, alignment=frame")); GST_STATIC_CAPS ("video/x-av1, alignment=frame"));
#define SRC_CAPS \ #define SRC_CAPS \
GST_VIDEO_DMA_DRM_CAPS_MAKE " ; " \
GST_VIDEO_CAPS_MAKE (GST_V4L2_DEFAULT_VIDEO_FORMATS)
#define SRC_CAPS_NO_DRM \
GST_VIDEO_CAPS_MAKE (GST_V4L2_DEFAULT_VIDEO_FORMATS) GST_VIDEO_CAPS_MAKE (GST_V4L2_DEFAULT_VIDEO_FORMATS)
static GstStaticCaps static_src_caps = GST_STATIC_CAPS (SRC_CAPS); static GstStaticCaps static_src_caps = GST_STATIC_CAPS (SRC_CAPS);
static GstStaticCaps static_src_caps_no_drm = GST_STATIC_CAPS (SRC_CAPS_NO_DRM);
static GstStaticPadTemplate src_template = static GstStaticPadTemplate src_template =
GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SRC_NAME, GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SRC_NAME,
@ -68,6 +73,7 @@ struct _GstV4l2CodecAV1Dec
GstV4l2Decoder *decoder; GstV4l2Decoder *decoder;
GstVideoCodecState *output_state; GstVideoCodecState *output_state;
GstVideoInfo vinfo; GstVideoInfo vinfo;
GstVideoInfoDmaDrm vinfo_drm;
GstV4l2CodecAllocator *sink_allocator; GstV4l2CodecAllocator *sink_allocator;
GstV4l2CodecAllocator *src_allocator; GstV4l2CodecAllocator *src_allocator;
@ -283,7 +289,9 @@ gst_v4l2_codec_av1_dec_negotiate (GstVideoDecoder * decoder)
}; };
/* *INDENT-ON* */ /* *INDENT-ON* */
GstCaps *filter, *caps; GstCaps *peer_caps, *filter, *caps;
GstStaticCaps *static_filter;
/* Ignore downstream renegotiation request. */ /* Ignore downstream renegotiation request. */
if (self->streaming) if (self->streaming)
goto done; goto done;
@ -308,7 +316,13 @@ gst_v4l2_codec_av1_dec_negotiate (GstVideoDecoder * decoder)
return FALSE; return FALSE;
} }
filter = gst_v4l2_decoder_enum_src_formats (self->decoder, &static_src_caps); /* If the peer has ANY caps only advertise system memory caps */
peer_caps = gst_pad_peer_query_caps (decoder->srcpad, NULL);
static_filter =
gst_caps_is_any (peer_caps) ? &static_src_caps_no_drm : &static_src_caps;
gst_caps_unref (peer_caps);
filter = gst_v4l2_decoder_enum_src_formats (self->decoder, static_filter);
if (!filter) { if (!filter) {
GST_ELEMENT_ERROR (self, CORE, NEGOTIATION, GST_ELEMENT_ERROR (self, CORE, NEGOTIATION,
("No supported decoder output formats"), (NULL)); ("No supported decoder output formats"), (NULL));
@ -320,7 +334,8 @@ gst_v4l2_codec_av1_dec_negotiate (GstVideoDecoder * decoder)
gst_caps_unref (filter); gst_caps_unref (filter);
GST_DEBUG_OBJECT (self, "Peer supported formats: %" GST_PTR_FORMAT, caps); GST_DEBUG_OBJECT (self, "Peer supported formats: %" GST_PTR_FORMAT, caps);
if (!gst_v4l2_decoder_select_src_format (self->decoder, caps, &self->vinfo)) { if (!gst_v4l2_decoder_select_src_format (self->decoder, caps, &self->vinfo,
&self->vinfo_drm)) {
GST_ELEMENT_ERROR (self, CORE, NEGOTIATION, GST_ELEMENT_ERROR (self, CORE, NEGOTIATION,
("Unsupported pixel format"), ("Unsupported pixel format"),
("No support for %ux%u", self->frame_width, self->frame_height)); ("No support for %ux%u", self->frame_width, self->frame_height));
@ -335,7 +350,8 @@ done:
self->output_state = self->output_state =
gst_v4l2_decoder_set_output_state (GST_VIDEO_DECODER (self), &self->vinfo, gst_v4l2_decoder_set_output_state (GST_VIDEO_DECODER (self), &self->vinfo,
self->render_width, self->render_height, av1dec->input_state); &self->vinfo_drm, self->render_width, self->render_height,
av1dec->input_state);
if (GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder)) { if (GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder)) {
if (self->streaming) if (self->streaming)
@ -368,6 +384,7 @@ gst_v4l2_codec_av1_dec_decide_allocation (GstVideoDecoder * decoder,
GstQuery * query) GstQuery * query)
{ {
GstV4l2CodecAV1Dec *self = GST_V4L2_CODEC_AV1_DEC (decoder); GstV4l2CodecAV1Dec *self = GST_V4L2_CODEC_AV1_DEC (decoder);
GstCaps *caps = NULL;
guint min = 0, num_bitstream; guint min = 0, num_bitstream;
/* If we are streaming here, then it means there is nothing allocation /* If we are streaming here, then it means there is nothing allocation
@ -375,11 +392,24 @@ gst_v4l2_codec_av1_dec_decide_allocation (GstVideoDecoder * decoder,
if (self->streaming) if (self->streaming)
goto no_internal_changes; goto no_internal_changes;
g_clear_object (&self->src_pool);
g_clear_object (&self->src_allocator);
self->has_videometa = gst_query_find_allocation_meta (query, self->has_videometa = gst_query_find_allocation_meta (query,
GST_VIDEO_META_API_TYPE, NULL); GST_VIDEO_META_API_TYPE, NULL);
g_clear_object (&self->src_pool); gst_query_parse_allocation (query, &caps, NULL);
g_clear_object (&self->src_allocator); if (!caps) {
GST_ERROR_OBJECT (self, "No valid caps");
return FALSE;
}
if (gst_video_is_dma_drm_caps (caps) && !self->has_videometa) {
GST_ERROR_OBJECT (self,
"DMABuf caps negotiated without the mandatory support of VideoMeta");
return FALSE;
}
gst_caps_unref (caps);
if (gst_query_get_n_allocation_pools (query) > 0) if (gst_query_get_n_allocation_pools (query) > 0)
gst_query_parse_nth_allocation_pool (query, 0, NULL, NULL, &min, NULL); gst_query_parse_nth_allocation_pool (query, 0, NULL, NULL, &min, NULL);
@ -1551,6 +1581,7 @@ gst_v4l2_codec_av1_dec_subinit (GstV4l2CodecAV1Dec * self,
{ {
self->decoder = gst_v4l2_decoder_new (klass->device); self->decoder = gst_v4l2_decoder_new (klass->device);
gst_video_info_init (&self->vinfo); gst_video_info_init (&self->vinfo);
gst_video_info_dma_drm_init (&self->vinfo_drm);
self->tile_group_entries = self->tile_group_entries =
g_array_new (FALSE, TRUE, sizeof (struct v4l2_ctrl_av1_tile_group_entry)); g_array_new (FALSE, TRUE, sizeof (struct v4l2_ctrl_av1_tile_group_entry));
} }

View file

@ -51,9 +51,14 @@ GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SINK_NAME,
); );
#define SRC_CAPS \ #define SRC_CAPS \
GST_VIDEO_DMA_DRM_CAPS_MAKE " ; " \
GST_VIDEO_CAPS_MAKE (GST_V4L2_DEFAULT_VIDEO_FORMATS)
#define SRC_CAPS_NO_DRM \
GST_VIDEO_CAPS_MAKE (GST_V4L2_DEFAULT_VIDEO_FORMATS) GST_VIDEO_CAPS_MAKE (GST_V4L2_DEFAULT_VIDEO_FORMATS)
static GstStaticCaps static_src_caps = GST_STATIC_CAPS (SRC_CAPS); static GstStaticCaps static_src_caps = GST_STATIC_CAPS (SRC_CAPS);
static GstStaticCaps static_src_caps_no_drm = GST_STATIC_CAPS (SRC_CAPS_NO_DRM);
static GstStaticPadTemplate src_template = static GstStaticPadTemplate src_template =
GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SRC_NAME, GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SRC_NAME,
@ -66,6 +71,7 @@ struct _GstV4l2CodecH264Dec
GstV4l2Decoder *decoder; GstV4l2Decoder *decoder;
GstVideoCodecState *output_state; GstVideoCodecState *output_state;
GstVideoInfo vinfo; GstVideoInfo vinfo;
GstVideoInfoDmaDrm vinfo_drm;
gint display_width; gint display_width;
gint display_height; gint display_height;
gint coded_width; gint coded_width;
@ -324,7 +330,8 @@ gst_v4l2_codec_h264_dec_negotiate (GstVideoDecoder * decoder)
}, },
}; };
/* *INDENT-ON* */ /* *INDENT-ON* */
GstCaps *filter, *caps; GstCaps *peer_caps, *filter, *caps;
GstStaticCaps *static_filter;
/* Ignore downstream renegotiation request. */ /* Ignore downstream renegotiation request. */
if (self->streaming) if (self->streaming)
@ -350,7 +357,13 @@ gst_v4l2_codec_h264_dec_negotiate (GstVideoDecoder * decoder)
return FALSE; return FALSE;
} }
filter = gst_v4l2_decoder_enum_src_formats (self->decoder, &static_src_caps); /* If the peer has ANY caps only advertise system memory caps */
peer_caps = gst_pad_peer_query_caps (decoder->srcpad, NULL);
static_filter =
gst_caps_is_any (peer_caps) ? &static_src_caps_no_drm : &static_src_caps;
gst_caps_unref (peer_caps);
filter = gst_v4l2_decoder_enum_src_formats (self->decoder, static_filter);
if (!filter) { if (!filter) {
GST_ELEMENT_ERROR (self, CORE, NEGOTIATION, GST_ELEMENT_ERROR (self, CORE, NEGOTIATION,
("No supported decoder output formats"), (NULL)); ("No supported decoder output formats"), (NULL));
@ -362,7 +375,8 @@ gst_v4l2_codec_h264_dec_negotiate (GstVideoDecoder * decoder)
gst_caps_unref (filter); gst_caps_unref (filter);
GST_DEBUG_OBJECT (self, "Peer supported formats: %" GST_PTR_FORMAT, caps); GST_DEBUG_OBJECT (self, "Peer supported formats: %" GST_PTR_FORMAT, caps);
if (!gst_v4l2_decoder_select_src_format (self->decoder, caps, &self->vinfo)) { if (!gst_v4l2_decoder_select_src_format (self->decoder, caps, &self->vinfo,
&self->vinfo_drm)) {
GST_ELEMENT_ERROR (self, CORE, NEGOTIATION, GST_ELEMENT_ERROR (self, CORE, NEGOTIATION,
("Unsupported bitdepth/chroma format"), ("Unsupported bitdepth/chroma format"),
("No support for %ux%u %ubit chroma IDC %i", self->coded_width, ("No support for %ux%u %ubit chroma IDC %i", self->coded_width,
@ -378,7 +392,8 @@ done:
self->output_state = self->output_state =
gst_v4l2_decoder_set_output_state (GST_VIDEO_DECODER (self), &self->vinfo, gst_v4l2_decoder_set_output_state (GST_VIDEO_DECODER (self), &self->vinfo,
self->display_width, self->display_height, h264dec->input_state); &self->vinfo_drm, self->display_width, self->display_height,
h264dec->input_state);
if (self->interlaced) if (self->interlaced)
self->output_state->info.interlace_mode = GST_VIDEO_INTERLACE_MODE_MIXED; self->output_state->info.interlace_mode = GST_VIDEO_INTERLACE_MODE_MIXED;
@ -414,6 +429,7 @@ gst_v4l2_codec_h264_dec_decide_allocation (GstVideoDecoder * decoder,
GstQuery * query) GstQuery * query)
{ {
GstV4l2CodecH264Dec *self = GST_V4L2_CODEC_H264_DEC (decoder); GstV4l2CodecH264Dec *self = GST_V4L2_CODEC_H264_DEC (decoder);
GstCaps *caps = NULL;
guint min = 0, num_bitstream; guint min = 0, num_bitstream;
/* If we are streaming here, then it means there is nothing allocation /* If we are streaming here, then it means there is nothing allocation
@ -421,11 +437,24 @@ gst_v4l2_codec_h264_dec_decide_allocation (GstVideoDecoder * decoder,
if (self->streaming) if (self->streaming)
goto no_internal_changes; goto no_internal_changes;
g_clear_object (&self->src_pool);
g_clear_object (&self->src_allocator);
self->has_videometa = gst_query_find_allocation_meta (query, self->has_videometa = gst_query_find_allocation_meta (query,
GST_VIDEO_META_API_TYPE, NULL); GST_VIDEO_META_API_TYPE, NULL);
g_clear_object (&self->src_pool); gst_query_parse_allocation (query, &caps, NULL);
g_clear_object (&self->src_allocator); if (!caps) {
GST_ERROR_OBJECT (self, "No valid caps");
return FALSE;
}
if (gst_video_is_dma_drm_caps (caps) && !self->has_videometa) {
GST_ERROR_OBJECT (self,
"DMABuf caps negotiated without the mandatory support of VideoMeta");
return FALSE;
}
gst_caps_unref (caps);
if (gst_query_get_n_allocation_pools (query) > 0) if (gst_query_get_n_allocation_pools (query) > 0)
gst_query_parse_nth_allocation_pool (query, 0, NULL, NULL, &min, NULL); gst_query_parse_nth_allocation_pool (query, 0, NULL, NULL, &min, NULL);
@ -1484,6 +1513,7 @@ gst_v4l2_codec_h264_dec_subinit (GstV4l2CodecH264Dec * self,
{ {
self->decoder = gst_v4l2_decoder_new (klass->device); self->decoder = gst_v4l2_decoder_new (klass->device);
gst_video_info_init (&self->vinfo); gst_video_info_init (&self->vinfo);
gst_video_info_dma_drm_init (&self->vinfo_drm);
self->slice_params = g_array_sized_new (FALSE, TRUE, self->slice_params = g_array_sized_new (FALSE, TRUE,
sizeof (struct v4l2_ctrl_h264_slice_params), 4); sizeof (struct v4l2_ctrl_h264_slice_params), 4);
g_array_set_size (self->slice_params, 4); g_array_set_size (self->slice_params, 4);

View file

@ -52,9 +52,14 @@ GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SINK_NAME,
); );
#define SRC_CAPS \ #define SRC_CAPS \
GST_VIDEO_DMA_DRM_CAPS_MAKE " ; " \
GST_VIDEO_CAPS_MAKE (GST_V4L2_DEFAULT_VIDEO_FORMATS)
#define SRC_CAPS_NO_DRM \
GST_VIDEO_CAPS_MAKE (GST_V4L2_DEFAULT_VIDEO_FORMATS) GST_VIDEO_CAPS_MAKE (GST_V4L2_DEFAULT_VIDEO_FORMATS)
static GstStaticCaps static_src_caps = GST_STATIC_CAPS (SRC_CAPS); static GstStaticCaps static_src_caps = GST_STATIC_CAPS (SRC_CAPS);
static GstStaticCaps static_src_caps_no_drm = GST_STATIC_CAPS (SRC_CAPS_NO_DRM);
static GstStaticPadTemplate src_template = static GstStaticPadTemplate src_template =
GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SRC_NAME, GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SRC_NAME,
@ -67,6 +72,7 @@ struct _GstV4l2CodecH265Dec
GstV4l2Decoder *decoder; GstV4l2Decoder *decoder;
GstVideoCodecState *output_state; GstVideoCodecState *output_state;
GstVideoInfo vinfo; GstVideoInfo vinfo;
GstVideoInfoDmaDrm vinfo_drm;
gint display_width; gint display_width;
gint display_height; gint display_height;
gint coded_width; gint coded_width;
@ -358,7 +364,8 @@ gst_v4l2_codec_h265_dec_negotiate (GstVideoDecoder * decoder)
}, },
}; };
/* *INDENT-ON* */ /* *INDENT-ON* */
GstCaps *filter, *caps; GstCaps *peer_caps, *filter, *caps;
GstStaticCaps *static_filter;
/* Ignore downstream renegotiation request. */ /* Ignore downstream renegotiation request. */
if (self->streaming) if (self->streaming)
@ -384,7 +391,13 @@ gst_v4l2_codec_h265_dec_negotiate (GstVideoDecoder * decoder)
return FALSE; return FALSE;
} }
filter = gst_v4l2_decoder_enum_src_formats (self->decoder, &static_src_caps); /* If the peer has ANY caps only advertise system memory caps */
peer_caps = gst_pad_peer_query_caps (decoder->srcpad, NULL);
static_filter =
gst_caps_is_any (peer_caps) ? &static_src_caps_no_drm : &static_src_caps;
gst_caps_unref (peer_caps);
filter = gst_v4l2_decoder_enum_src_formats (self->decoder, static_filter);
if (!filter) { if (!filter) {
GST_ELEMENT_ERROR (self, CORE, NEGOTIATION, GST_ELEMENT_ERROR (self, CORE, NEGOTIATION,
("No supported decoder output formats"), (NULL)); ("No supported decoder output formats"), (NULL));
@ -396,7 +409,8 @@ gst_v4l2_codec_h265_dec_negotiate (GstVideoDecoder * decoder)
gst_caps_unref (filter); gst_caps_unref (filter);
GST_DEBUG_OBJECT (self, "Peer supported formats: %" GST_PTR_FORMAT, caps); GST_DEBUG_OBJECT (self, "Peer supported formats: %" GST_PTR_FORMAT, caps);
if (!gst_v4l2_decoder_select_src_format (self->decoder, caps, &self->vinfo)) { if (!gst_v4l2_decoder_select_src_format (self->decoder, caps, &self->vinfo,
&self->vinfo_drm)) {
GST_ELEMENT_ERROR (self, CORE, NEGOTIATION, GST_ELEMENT_ERROR (self, CORE, NEGOTIATION,
("Unsupported bitdepth/chroma format"), ("Unsupported bitdepth/chroma format"),
("No support for %ux%u %ubit chroma IDC %i", self->coded_width, ("No support for %ux%u %ubit chroma IDC %i", self->coded_width,
@ -412,7 +426,8 @@ done:
self->output_state = self->output_state =
gst_v4l2_decoder_set_output_state (GST_VIDEO_DECODER (self), &self->vinfo, gst_v4l2_decoder_set_output_state (GST_VIDEO_DECODER (self), &self->vinfo,
self->display_width, self->display_height, h265dec->input_state); &self->vinfo_drm, self->display_width, self->display_height,
h265dec->input_state);
if (GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder)) { if (GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder)) {
if (self->streaming) if (self->streaming)
@ -445,16 +460,30 @@ gst_v4l2_codec_h265_dec_decide_allocation (GstVideoDecoder * decoder,
GstQuery * query) GstQuery * query)
{ {
GstV4l2CodecH265Dec *self = GST_V4L2_CODEC_H265_DEC (decoder); GstV4l2CodecH265Dec *self = GST_V4L2_CODEC_H265_DEC (decoder);
GstCaps *caps = NULL;
guint min = 0; guint min = 0;
if (self->streaming) if (self->streaming)
goto no_internal_changes; goto no_internal_changes;
g_clear_object (&self->src_pool);
g_clear_object (&self->src_allocator);
self->has_videometa = gst_query_find_allocation_meta (query, self->has_videometa = gst_query_find_allocation_meta (query,
GST_VIDEO_META_API_TYPE, NULL); GST_VIDEO_META_API_TYPE, NULL);
g_clear_object (&self->src_pool); gst_query_parse_allocation (query, &caps, NULL);
g_clear_object (&self->src_allocator); if (!caps) {
GST_ERROR_OBJECT (self, "No valid caps");
return FALSE;
}
if (gst_video_is_dma_drm_caps (caps) && !self->has_videometa) {
GST_ERROR_OBJECT (self,
"DMABuf caps negotiated without the mandatory support of VideoMeta");
return FALSE;
}
gst_caps_unref (caps);
if (gst_query_get_n_allocation_pools (query) > 0) if (gst_query_get_n_allocation_pools (query) > 0)
gst_query_parse_nth_allocation_pool (query, 0, NULL, NULL, &min, NULL); gst_query_parse_nth_allocation_pool (query, 0, NULL, NULL, &min, NULL);
@ -1598,6 +1627,7 @@ gst_v4l2_codec_h265_dec_subinit (GstV4l2CodecH265Dec * self,
{ {
self->decoder = gst_v4l2_decoder_new (klass->device); self->decoder = gst_v4l2_decoder_new (klass->device);
gst_video_info_init (&self->vinfo); gst_video_info_init (&self->vinfo);
gst_video_info_dma_drm_init (&self->vinfo_drm);
self->slice_params = g_array_sized_new (FALSE, TRUE, self->slice_params = g_array_sized_new (FALSE, TRUE,
sizeof (struct v4l2_ctrl_hevc_slice_params), 4); sizeof (struct v4l2_ctrl_hevc_slice_params), 4);
g_array_set_size (self->slice_params, 4); g_array_set_size (self->slice_params, 4);

View file

@ -54,9 +54,14 @@ GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SINK_NAME,
"mpegversion=(int) 2, " "profile=(string) {main, simple} ")); "mpegversion=(int) 2, " "profile=(string) {main, simple} "));
#define SRC_CAPS \ #define SRC_CAPS \
GST_VIDEO_DMA_DRM_CAPS_MAKE " ; " \
GST_VIDEO_CAPS_MAKE (GST_V4L2_DEFAULT_VIDEO_FORMATS)
#define SRC_CAPS_NO_DRM \
GST_VIDEO_CAPS_MAKE (GST_V4L2_DEFAULT_VIDEO_FORMATS) GST_VIDEO_CAPS_MAKE (GST_V4L2_DEFAULT_VIDEO_FORMATS)
static GstStaticCaps static_src_caps = GST_STATIC_CAPS (SRC_CAPS); static GstStaticCaps static_src_caps = GST_STATIC_CAPS (SRC_CAPS);
static GstStaticCaps static_src_caps_no_drm = GST_STATIC_CAPS (SRC_CAPS_NO_DRM);
static GstStaticPadTemplate src_template = static GstStaticPadTemplate src_template =
GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SRC_NAME, GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SRC_NAME,
@ -70,6 +75,7 @@ struct _GstV4l2CodecMpeg2Dec
GstV4l2Decoder *decoder; GstV4l2Decoder *decoder;
GstVideoCodecState *output_state; GstVideoCodecState *output_state;
GstVideoInfo vinfo; GstVideoInfo vinfo;
GstVideoInfoDmaDrm vinfo_drm;
guint16 width; guint16 width;
guint16 height; guint16 height;
@ -246,7 +252,8 @@ gst_v4l2_codec_mpeg2_dec_negotiate (GstVideoDecoder * decoder)
}; };
/* *INDENT-ON* */ /* *INDENT-ON* */
GstCaps *filter, *caps; GstCaps *peer_caps, *filter, *caps;
GstStaticCaps *static_filter;
/* Ignore downstream renegotiation request. */ /* Ignore downstream renegotiation request. */
if (self->streaming) if (self->streaming)
@ -272,7 +279,13 @@ gst_v4l2_codec_mpeg2_dec_negotiate (GstVideoDecoder * decoder)
return FALSE; return FALSE;
} }
filter = gst_v4l2_decoder_enum_src_formats (self->decoder, &static_src_caps); /* If the peer has ANY caps only advertise system memory caps */
peer_caps = gst_pad_peer_query_caps (decoder->srcpad, NULL);
static_filter =
gst_caps_is_any (peer_caps) ? &static_src_caps_no_drm : &static_src_caps;
gst_caps_unref (peer_caps);
filter = gst_v4l2_decoder_enum_src_formats (self->decoder, static_filter);
if (!filter) { if (!filter) {
GST_ELEMENT_ERROR (self, CORE, NEGOTIATION, GST_ELEMENT_ERROR (self, CORE, NEGOTIATION,
("No supported decoder output formats"), (NULL)); ("No supported decoder output formats"), (NULL));
@ -284,7 +297,8 @@ gst_v4l2_codec_mpeg2_dec_negotiate (GstVideoDecoder * decoder)
gst_caps_unref (filter); gst_caps_unref (filter);
GST_DEBUG_OBJECT (self, "Peer supported formats: %" GST_PTR_FORMAT, caps); GST_DEBUG_OBJECT (self, "Peer supported formats: %" GST_PTR_FORMAT, caps);
if (!gst_v4l2_decoder_select_src_format (self->decoder, caps, &self->vinfo)) { if (!gst_v4l2_decoder_select_src_format (self->decoder, caps, &self->vinfo,
&self->vinfo_drm)) {
GST_ELEMENT_ERROR (self, CORE, NEGOTIATION, GST_ELEMENT_ERROR (self, CORE, NEGOTIATION,
("Unsupported bitdepth/chroma format"), ("Unsupported bitdepth/chroma format"),
("No support for %ux%u chroma IDC %i", self->width, ("No support for %ux%u chroma IDC %i", self->width,
@ -300,7 +314,7 @@ done:
self->output_state = self->output_state =
gst_v4l2_decoder_set_output_state (GST_VIDEO_DECODER (self), &self->vinfo, gst_v4l2_decoder_set_output_state (GST_VIDEO_DECODER (self), &self->vinfo,
self->width, self->height, mpeg2dec->input_state); &self->vinfo_drm, self->width, self->height, mpeg2dec->input_state);
if (self->interlaced) if (self->interlaced)
self->output_state->info.interlace_mode = self->output_state->info.interlace_mode =
@ -337,6 +351,7 @@ gst_v4l2_codec_mpeg2_dec_decide_allocation (GstVideoDecoder * decoder,
GstQuery * query) GstQuery * query)
{ {
GstV4l2CodecMpeg2Dec *self = GST_V4L2_CODEC_MPEG2_DEC (decoder); GstV4l2CodecMpeg2Dec *self = GST_V4L2_CODEC_MPEG2_DEC (decoder);
GstCaps *caps = NULL;
guint min = 0, num_bitstream; guint min = 0, num_bitstream;
/* If we are streaming here, then it means there is nothing allocation /* If we are streaming here, then it means there is nothing allocation
@ -344,11 +359,24 @@ gst_v4l2_codec_mpeg2_dec_decide_allocation (GstVideoDecoder * decoder,
if (self->streaming) if (self->streaming)
goto no_internal_changes; goto no_internal_changes;
g_clear_object (&self->src_pool);
g_clear_object (&self->src_allocator);
self->has_videometa = gst_query_find_allocation_meta (query, self->has_videometa = gst_query_find_allocation_meta (query,
GST_VIDEO_META_API_TYPE, NULL); GST_VIDEO_META_API_TYPE, NULL);
g_clear_object (&self->src_pool); gst_query_parse_allocation (query, &caps, NULL);
g_clear_object (&self->src_allocator); if (!caps) {
GST_ERROR_OBJECT (self, "No valid caps");
return FALSE;
}
if (gst_video_is_dma_drm_caps (caps) && !self->has_videometa) {
GST_ERROR_OBJECT (self,
"DMABuf caps negotiated without the mandatory support of VideoMeta");
return FALSE;
}
gst_caps_unref (caps);
if (gst_query_get_n_allocation_pools (query) > 0) if (gst_query_get_n_allocation_pools (query) > 0)
gst_query_parse_nth_allocation_pool (query, 0, NULL, NULL, &min, NULL); gst_query_parse_nth_allocation_pool (query, 0, NULL, NULL, &min, NULL);
@ -1009,6 +1037,7 @@ gst_v4l2_codec_mpeg2_dec_subinit (GstV4l2CodecMpeg2Dec * self,
{ {
self->decoder = gst_v4l2_decoder_new (klass->device); self->decoder = gst_v4l2_decoder_new (klass->device);
gst_video_info_init (&self->vinfo); gst_video_info_init (&self->vinfo);
gst_video_info_dma_drm_init (&self->vinfo_drm);
} }
static void static void

View file

@ -55,9 +55,14 @@ GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SINK_NAME,
); );
#define SRC_CAPS \ #define SRC_CAPS \
GST_VIDEO_DMA_DRM_CAPS_MAKE " ; " \
GST_VIDEO_CAPS_MAKE (GST_V4L2_DEFAULT_VIDEO_FORMATS)
#define SRC_CAPS_NO_DRM \
GST_VIDEO_CAPS_MAKE (GST_V4L2_DEFAULT_VIDEO_FORMATS) GST_VIDEO_CAPS_MAKE (GST_V4L2_DEFAULT_VIDEO_FORMATS)
static GstStaticCaps static_src_caps = GST_STATIC_CAPS (SRC_CAPS); static GstStaticCaps static_src_caps = GST_STATIC_CAPS (SRC_CAPS);
static GstStaticCaps static_src_caps_no_drm = GST_STATIC_CAPS (SRC_CAPS_NO_DRM);
static GstStaticPadTemplate src_template = static GstStaticPadTemplate src_template =
GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SRC_NAME, GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SRC_NAME,
@ -70,6 +75,7 @@ struct _GstV4l2CodecVp8Dec
GstV4l2Decoder *decoder; GstV4l2Decoder *decoder;
GstVideoCodecState *output_state; GstVideoCodecState *output_state;
GstVideoInfo vinfo; GstVideoInfo vinfo;
GstVideoInfoDmaDrm vinfo_drm;
gint width; gint width;
gint height; gint height;
@ -195,7 +201,8 @@ gst_v4l2_codec_vp8_dec_negotiate (GstVideoDecoder * decoder)
}, },
}; };
/* *INDENT-ON* */ /* *INDENT-ON* */
GstCaps *filter, *caps; GstCaps *peer_caps, *filter, *caps;
GstStaticCaps *static_filter;
/* Ignore downstream renegotiation request. */ /* Ignore downstream renegotiation request. */
if (self->streaming) if (self->streaming)
@ -221,7 +228,13 @@ gst_v4l2_codec_vp8_dec_negotiate (GstVideoDecoder * decoder)
return FALSE; return FALSE;
} }
filter = gst_v4l2_decoder_enum_src_formats (self->decoder, &static_src_caps); /* If the peer has ANY caps only advertise system memory caps */
peer_caps = gst_pad_peer_query_caps (decoder->srcpad, NULL);
static_filter =
gst_caps_is_any (peer_caps) ? &static_src_caps_no_drm : &static_src_caps;
gst_caps_unref (peer_caps);
filter = gst_v4l2_decoder_enum_src_formats (self->decoder, static_filter);
if (!filter) { if (!filter) {
GST_ELEMENT_ERROR (self, CORE, NEGOTIATION, GST_ELEMENT_ERROR (self, CORE, NEGOTIATION,
("No supported decoder output formats"), (NULL)); ("No supported decoder output formats"), (NULL));
@ -233,7 +246,8 @@ gst_v4l2_codec_vp8_dec_negotiate (GstVideoDecoder * decoder)
gst_caps_unref (filter); gst_caps_unref (filter);
GST_DEBUG_OBJECT (self, "Peer supported formats: %" GST_PTR_FORMAT, caps); GST_DEBUG_OBJECT (self, "Peer supported formats: %" GST_PTR_FORMAT, caps);
if (!gst_v4l2_decoder_select_src_format (self->decoder, caps, &self->vinfo)) { if (!gst_v4l2_decoder_select_src_format (self->decoder, caps, &self->vinfo,
&self->vinfo_drm)) {
GST_ELEMENT_ERROR (self, CORE, NEGOTIATION, GST_ELEMENT_ERROR (self, CORE, NEGOTIATION,
("Unsupported pixel format"), ("Unsupported pixel format"),
("No support for %ux%u format %s", self->width, self->height, ("No support for %ux%u format %s", self->width, self->height,
@ -249,7 +263,7 @@ done:
self->output_state = self->output_state =
gst_v4l2_decoder_set_output_state (GST_VIDEO_DECODER (self), &self->vinfo, gst_v4l2_decoder_set_output_state (GST_VIDEO_DECODER (self), &self->vinfo,
self->width, self->height, vp8dec->input_state); &self->vinfo_drm, self->width, self->height, vp8dec->input_state);
if (GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder)) { if (GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder)) {
if (self->streaming) if (self->streaming)
@ -282,17 +296,31 @@ gst_v4l2_codec_vp8_dec_decide_allocation (GstVideoDecoder * decoder,
GstQuery * query) GstQuery * query)
{ {
GstV4l2CodecVp8Dec *self = GST_V4L2_CODEC_VP8_DEC (decoder); GstV4l2CodecVp8Dec *self = GST_V4L2_CODEC_VP8_DEC (decoder);
GstCaps *caps = NULL;
guint min = 0; guint min = 0;
guint num_bitstream; guint num_bitstream;
if (self->streaming) if (self->streaming)
goto no_internal_changes; goto no_internal_changes;
g_clear_object (&self->src_pool);
g_clear_object (&self->src_allocator);
self->has_videometa = gst_query_find_allocation_meta (query, self->has_videometa = gst_query_find_allocation_meta (query,
GST_VIDEO_META_API_TYPE, NULL); GST_VIDEO_META_API_TYPE, NULL);
g_clear_object (&self->src_pool); gst_query_parse_allocation (query, &caps, NULL);
g_clear_object (&self->src_allocator); if (!caps) {
GST_ERROR_OBJECT (self, "No valid caps");
return FALSE;
}
if (gst_video_is_dma_drm_caps (caps) && !self->has_videometa) {
GST_ERROR_OBJECT (self,
"DMABuf caps negotiated without the mandatory support of VideoMeta");
return FALSE;
}
gst_caps_unref (caps);
if (gst_query_get_n_allocation_pools (query) > 0) if (gst_query_get_n_allocation_pools (query) > 0)
gst_query_parse_nth_allocation_pool (query, 0, NULL, NULL, &min, NULL); gst_query_parse_nth_allocation_pool (query, 0, NULL, NULL, &min, NULL);
@ -869,6 +897,7 @@ gst_v4l2_codec_vp8_dec_subinit (GstV4l2CodecVp8Dec * self,
{ {
self->decoder = gst_v4l2_decoder_new (klass->device); self->decoder = gst_v4l2_decoder_new (klass->device);
gst_video_info_init (&self->vinfo); gst_video_info_init (&self->vinfo);
gst_video_info_dma_drm_init (&self->vinfo_drm);
} }
static void static void

View file

@ -56,9 +56,14 @@ GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SINK_NAME,
); );
#define SRC_CAPS \ #define SRC_CAPS \
GST_VIDEO_DMA_DRM_CAPS_MAKE " ; " \
GST_VIDEO_CAPS_MAKE (GST_V4L2_DEFAULT_VIDEO_FORMATS)
#define SRC_CAPS_NO_DRM \
GST_VIDEO_CAPS_MAKE (GST_V4L2_DEFAULT_VIDEO_FORMATS) GST_VIDEO_CAPS_MAKE (GST_V4L2_DEFAULT_VIDEO_FORMATS)
static GstStaticCaps static_src_caps = GST_STATIC_CAPS (SRC_CAPS); static GstStaticCaps static_src_caps = GST_STATIC_CAPS (SRC_CAPS);
static GstStaticCaps static_src_caps_no_drm = GST_STATIC_CAPS (SRC_CAPS_NO_DRM);
static GstStaticPadTemplate src_template = static GstStaticPadTemplate src_template =
GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SRC_NAME, GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SRC_NAME,
@ -71,6 +76,7 @@ struct _GstV4l2CodecVp9Dec
GstV4l2Decoder *decoder; GstV4l2Decoder *decoder;
GstVideoCodecState *output_state; GstVideoCodecState *output_state;
GstVideoInfo vinfo; GstVideoInfo vinfo;
GstVideoInfoDmaDrm vinfo_drm;
gint width; gint width;
gint height; gint height;
@ -467,7 +473,9 @@ gst_v4l2_codec_vp9_dec_negotiate (GstVideoDecoder * decoder)
}; };
/* *INDENT-ON* */ /* *INDENT-ON* */
GstCaps *filter, *caps; GstCaps *peer_caps, *filter, *caps;
GstStaticCaps *static_filter;
/* Ignore downstream renegotiation request. */ /* Ignore downstream renegotiation request. */
if (self->streaming) if (self->streaming)
goto done; goto done;
@ -491,7 +499,13 @@ gst_v4l2_codec_vp9_dec_negotiate (GstVideoDecoder * decoder)
return FALSE; return FALSE;
} }
filter = gst_v4l2_decoder_enum_src_formats (self->decoder, &static_src_caps); /* If the peer has ANY caps only advertise system memory caps */
peer_caps = gst_pad_peer_query_caps (decoder->srcpad, NULL);
static_filter =
gst_caps_is_any (peer_caps) ? &static_src_caps_no_drm : &static_src_caps;
gst_caps_unref (peer_caps);
filter = gst_v4l2_decoder_enum_src_formats (self->decoder, static_filter);
if (!filter) { if (!filter) {
GST_ELEMENT_ERROR (self, CORE, NEGOTIATION, GST_ELEMENT_ERROR (self, CORE, NEGOTIATION,
("No supported decoder output formats"), (NULL)); ("No supported decoder output formats"), (NULL));
@ -503,7 +517,8 @@ gst_v4l2_codec_vp9_dec_negotiate (GstVideoDecoder * decoder)
gst_caps_unref (filter); gst_caps_unref (filter);
GST_DEBUG_OBJECT (self, "Peer supported formats: %" GST_PTR_FORMAT, caps); GST_DEBUG_OBJECT (self, "Peer supported formats: %" GST_PTR_FORMAT, caps);
if (!gst_v4l2_decoder_select_src_format (self->decoder, caps, &self->vinfo)) { if (!gst_v4l2_decoder_select_src_format (self->decoder, caps, &self->vinfo,
&self->vinfo_drm)) {
GST_ELEMENT_ERROR (self, CORE, NEGOTIATION, GST_ELEMENT_ERROR (self, CORE, NEGOTIATION,
("Unsupported pixel format"), ("Unsupported pixel format"),
("No support for %ux%u format %s", self->width, self->height, ("No support for %ux%u format %s", self->width, self->height,
@ -519,7 +534,7 @@ done:
self->output_state = self->output_state =
gst_v4l2_decoder_set_output_state (GST_VIDEO_DECODER (self), &self->vinfo, gst_v4l2_decoder_set_output_state (GST_VIDEO_DECODER (self), &self->vinfo,
self->width, self->height, vp9dec->input_state); &self->vinfo_drm, self->width, self->height, vp9dec->input_state);
if (GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder)) { if (GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder)) {
if (self->streaming) if (self->streaming)
@ -552,6 +567,7 @@ gst_v4l2_codec_vp9_dec_decide_allocation (GstVideoDecoder * decoder,
GstQuery * query) GstQuery * query)
{ {
GstV4l2CodecVp9Dec *self = GST_V4L2_CODEC_VP9_DEC (decoder); GstV4l2CodecVp9Dec *self = GST_V4L2_CODEC_VP9_DEC (decoder);
GstCaps *caps = NULL;
guint min = 0; guint min = 0;
guint num_bitstream; guint num_bitstream;
@ -560,11 +576,24 @@ gst_v4l2_codec_vp9_dec_decide_allocation (GstVideoDecoder * decoder,
if (self->streaming) if (self->streaming)
goto no_internal_changes; goto no_internal_changes;
g_clear_object (&self->src_pool);
g_clear_object (&self->src_allocator);
self->has_videometa = gst_query_find_allocation_meta (query, self->has_videometa = gst_query_find_allocation_meta (query,
GST_VIDEO_META_API_TYPE, NULL); GST_VIDEO_META_API_TYPE, NULL);
g_clear_object (&self->src_pool); gst_query_parse_allocation (query, &caps, NULL);
g_clear_object (&self->src_allocator); if (!caps) {
GST_ERROR_OBJECT (self, "No valid caps");
return FALSE;
}
if (gst_video_is_dma_drm_caps (caps) && !self->has_videometa) {
GST_ERROR_OBJECT (self,
"DMABuf caps negotiated without the mandatory support of VideoMeta");
return FALSE;
}
gst_caps_unref (caps);
if (gst_query_get_n_allocation_pools (query) > 0) if (gst_query_get_n_allocation_pools (query) > 0)
gst_query_parse_nth_allocation_pool (query, 0, NULL, NULL, &min, NULL); gst_query_parse_nth_allocation_pool (query, 0, NULL, NULL, &min, NULL);
@ -1111,6 +1140,7 @@ gst_v4l2_codec_vp9_dec_subinit (GstV4l2CodecVp9Dec * self,
{ {
self->decoder = gst_v4l2_decoder_new (klass->device); self->decoder = gst_v4l2_decoder_new (klass->device);
gst_video_info_init (&self->vinfo); gst_video_info_init (&self->vinfo);
gst_video_info_dma_drm_init (&self->vinfo_drm);
} }
static void static void

View file

@ -410,6 +410,7 @@ gst_v4l2_decoder_probe_caps_for_format (GstV4l2Decoder * self,
gint index = 0; gint index = 0;
GstCaps *caps, *tmp, *size_caps; GstCaps *caps, *tmp, *size_caps;
GstVideoFormat format; GstVideoFormat format;
guint32 drm_fourcc;
GST_DEBUG_OBJECT (self, "enumerate size for %" GST_FOURCC_FORMAT, GST_DEBUG_OBJECT (self, "enumerate size for %" GST_FOURCC_FORMAT,
GST_FOURCC_ARGS (pixelformat)); GST_FOURCC_ARGS (pixelformat));
@ -432,6 +433,31 @@ gst_v4l2_decoder_probe_caps_for_format (GstV4l2Decoder * self,
gst_caps_unref (tmp); gst_caps_unref (tmp);
} }
/* TODO: Add a V4L2 to DRM fourcc translator for formats that we don't support
* in software.
*/
drm_fourcc = gst_video_dma_drm_fourcc_from_format (format);
if (drm_fourcc /* != DRM_FORMAT_INVALID */ ) {
GstCaps *drm_caps;
drm_caps = gst_caps_new_simple ("video/x-raw", "format", G_TYPE_STRING,
"DMA_DRM", "drm-format", G_TYPE_STRING,
gst_video_dma_drm_fourcc_to_string (drm_fourcc, 0), NULL);
gst_caps_set_features_simple (drm_caps,
gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_DMABUF));
if (!gst_caps_is_empty (size_caps)) {
gst_caps_set_features_simple (size_caps,
gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_DMABUF));
tmp = drm_caps;
drm_caps =
gst_caps_intersect_full (tmp, size_caps, GST_CAPS_INTERSECT_FIRST);
gst_caps_unref (tmp);
}
caps = gst_caps_merge (drm_caps, caps);
}
gst_caps_unref (size_caps); gst_caps_unref (size_caps);
return caps; return caps;
@ -491,7 +517,7 @@ gst_v4l2_decoder_enum_src_formats (GstV4l2Decoder * self,
gboolean gboolean
gst_v4l2_decoder_select_src_format (GstV4l2Decoder * self, GstCaps * caps, gst_v4l2_decoder_select_src_format (GstV4l2Decoder * self, GstCaps * caps,
GstVideoInfo * vinfo) GstVideoInfo * vinfo, GstVideoInfoDmaDrm * vinfo_drm)
{ {
gint ret; gint ret;
struct v4l2_format fmt = { struct v4l2_format fmt = {
@ -500,6 +526,7 @@ gst_v4l2_decoder_select_src_format (GstV4l2Decoder * self, GstCaps * caps,
GstVideoFormat format; GstVideoFormat format;
guint32 pix_fmt; guint32 pix_fmt;
GstVideoInfo tmp_vinfo; GstVideoInfo tmp_vinfo;
GstVideoInfoDmaDrm tmp_vinfo_drm;
if (gst_caps_is_empty (caps)) if (gst_caps_is_empty (caps))
return FALSE; return FALSE;
@ -511,12 +538,15 @@ gst_v4l2_decoder_select_src_format (GstV4l2Decoder * self, GstCaps * caps,
} }
gst_video_info_init (&tmp_vinfo); gst_video_info_init (&tmp_vinfo);
gst_video_info_dma_drm_init (&tmp_vinfo_drm);
GST_DEBUG_OBJECT (self, "Original caps: %" GST_PTR_FORMAT, caps); GST_DEBUG_OBJECT (self, "Original caps: %" GST_PTR_FORMAT, caps);
caps = gst_caps_fixate (caps); caps = gst_caps_fixate (caps);
GST_DEBUG_OBJECT (self, "Fixated caps: %" GST_PTR_FORMAT, caps); GST_DEBUG_OBJECT (self, "Fixated caps: %" GST_PTR_FORMAT, caps);
if (gst_video_info_from_caps (&tmp_vinfo, caps)) { if (gst_video_info_dma_drm_from_caps (&tmp_vinfo_drm, caps)) {
format = tmp_vinfo_drm.vinfo.finfo->format;
} else if (gst_video_info_from_caps (&tmp_vinfo, caps)) {
format = tmp_vinfo.finfo->format; format = tmp_vinfo.finfo->format;
} else { } else {
GST_WARNING_OBJECT (self, "Can't transform caps into video info!"); GST_WARNING_OBJECT (self, "Can't transform caps into video info!");
@ -547,6 +577,17 @@ gst_v4l2_decoder_select_src_format (GstV4l2Decoder * self, GstCaps * caps,
return FALSE; return FALSE;
} }
if (tmp_vinfo_drm.drm_fourcc) {
if (!gst_video_info_dma_drm_from_video_info (vinfo_drm, vinfo, 0)) {
GST_ERROR_OBJECT (self,
"Unsupported V4L2 pixelformat for DRM %" GST_FOURCC_FORMAT,
GST_FOURCC_ARGS (fmt.fmt.pix_mp.pixelformat));
return FALSE;
}
} else {
gst_video_info_dma_drm_init (vinfo_drm);
}
GST_INFO_OBJECT (self, "Selected format %s %ix%i", GST_INFO_OBJECT (self, "Selected format %s %ix%i",
gst_video_format_to_string (vinfo->finfo->format), gst_video_format_to_string (vinfo->finfo->format),
vinfo->width, vinfo->height); vinfo->width, vinfo->height);
@ -556,15 +597,22 @@ gst_v4l2_decoder_select_src_format (GstV4l2Decoder * self, GstCaps * caps,
GstVideoCodecState * GstVideoCodecState *
gst_v4l2_decoder_set_output_state (GstVideoDecoder * decoder, gst_v4l2_decoder_set_output_state (GstVideoDecoder * decoder,
GstVideoInfo * vinfo, guint width, guint height, GstVideoInfo * vinfo, GstVideoInfoDmaDrm * vinfo_drm, guint width,
GstVideoCodecState * reference) guint height, GstVideoCodecState * reference)
{ {
GstVideoCodecState *state; GstVideoCodecState *state;
state = gst_video_decoder_set_output_state (decoder, vinfo->finfo->format, state = gst_video_decoder_set_output_state (decoder, vinfo->finfo->format,
width, height, reference); width, height, reference);
state->caps = gst_video_info_to_caps (&state->info); if (vinfo_drm->drm_fourcc /* != DRM_FORMAT_INVALID */ ) {
GstVideoInfoDmaDrm tmp_vinfo_drm;
gst_video_info_dma_drm_from_video_info (&tmp_vinfo_drm, &state->info, 0);
state->caps = gst_video_info_dma_drm_to_caps (&tmp_vinfo_drm);
} else {
state->caps = gst_video_info_to_caps (&state->info);
}
GST_DEBUG_OBJECT (decoder, "Setting caps: %" GST_PTR_FORMAT, state->caps); GST_DEBUG_OBJECT (decoder, "Setting caps: %" GST_PTR_FORMAT, state->caps);

View file

@ -72,10 +72,12 @@ GstCaps * gst_v4l2_decoder_enum_src_formats (GstV4l2Decoder * self,
gboolean gst_v4l2_decoder_select_src_format (GstV4l2Decoder * self, gboolean gst_v4l2_decoder_select_src_format (GstV4l2Decoder * self,
GstCaps * caps, GstCaps * caps,
GstVideoInfo * vinfo); GstVideoInfo * vinfo,
GstVideoInfoDmaDrm * vinfo_drm);
GstVideoCodecState * gst_v4l2_decoder_set_output_state (GstVideoDecoder * decoder, GstVideoCodecState * gst_v4l2_decoder_set_output_state (GstVideoDecoder * decoder,
GstVideoInfo * vinfo, GstVideoInfo * vinfo,
GstVideoInfoDmaDrm * drm_info,
guint width, guint width,
guint height, guint height,
GstVideoCodecState * reference); GstVideoCodecState * reference);