mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-22 16:26:39 +00:00
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:
parent
513d0d8cbb
commit
5189e8b956
8 changed files with 271 additions and 42 deletions
|
@ -53,9 +53,14 @@ GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SINK_NAME,
|
|||
GST_STATIC_CAPS ("video/x-av1, alignment=frame"));
|
||||
|
||||
#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)
|
||||
|
||||
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 =
|
||||
GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SRC_NAME,
|
||||
|
@ -68,6 +73,7 @@ struct _GstV4l2CodecAV1Dec
|
|||
GstV4l2Decoder *decoder;
|
||||
GstVideoCodecState *output_state;
|
||||
GstVideoInfo vinfo;
|
||||
GstVideoInfoDmaDrm vinfo_drm;
|
||||
|
||||
GstV4l2CodecAllocator *sink_allocator;
|
||||
GstV4l2CodecAllocator *src_allocator;
|
||||
|
@ -283,7 +289,9 @@ gst_v4l2_codec_av1_dec_negotiate (GstVideoDecoder * decoder)
|
|||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
GstCaps *filter, *caps;
|
||||
GstCaps *peer_caps, *filter, *caps;
|
||||
GstStaticCaps *static_filter;
|
||||
|
||||
/* Ignore downstream renegotiation request. */
|
||||
if (self->streaming)
|
||||
goto done;
|
||||
|
@ -308,7 +316,13 @@ gst_v4l2_codec_av1_dec_negotiate (GstVideoDecoder * decoder)
|
|||
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) {
|
||||
GST_ELEMENT_ERROR (self, CORE, NEGOTIATION,
|
||||
("No supported decoder output formats"), (NULL));
|
||||
|
@ -320,7 +334,8 @@ gst_v4l2_codec_av1_dec_negotiate (GstVideoDecoder * decoder)
|
|||
gst_caps_unref (filter);
|
||||
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,
|
||||
("Unsupported pixel format"),
|
||||
("No support for %ux%u", self->frame_width, self->frame_height));
|
||||
|
@ -335,7 +350,8 @@ done:
|
|||
|
||||
self->output_state =
|
||||
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 (self->streaming)
|
||||
|
@ -368,6 +384,7 @@ gst_v4l2_codec_av1_dec_decide_allocation (GstVideoDecoder * decoder,
|
|||
GstQuery * query)
|
||||
{
|
||||
GstV4l2CodecAV1Dec *self = GST_V4L2_CODEC_AV1_DEC (decoder);
|
||||
GstCaps *caps = NULL;
|
||||
guint min = 0, num_bitstream;
|
||||
|
||||
/* 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)
|
||||
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,
|
||||
GST_VIDEO_META_API_TYPE, NULL);
|
||||
|
||||
g_clear_object (&self->src_pool);
|
||||
g_clear_object (&self->src_allocator);
|
||||
gst_query_parse_allocation (query, &caps, NULL);
|
||||
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)
|
||||
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);
|
||||
gst_video_info_init (&self->vinfo);
|
||||
gst_video_info_dma_drm_init (&self->vinfo_drm);
|
||||
self->tile_group_entries =
|
||||
g_array_new (FALSE, TRUE, sizeof (struct v4l2_ctrl_av1_tile_group_entry));
|
||||
}
|
||||
|
|
|
@ -51,9 +51,14 @@ GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SINK_NAME,
|
|||
);
|
||||
|
||||
#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)
|
||||
|
||||
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 =
|
||||
GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SRC_NAME,
|
||||
|
@ -66,6 +71,7 @@ struct _GstV4l2CodecH264Dec
|
|||
GstV4l2Decoder *decoder;
|
||||
GstVideoCodecState *output_state;
|
||||
GstVideoInfo vinfo;
|
||||
GstVideoInfoDmaDrm vinfo_drm;
|
||||
gint display_width;
|
||||
gint display_height;
|
||||
gint coded_width;
|
||||
|
@ -324,7 +330,8 @@ gst_v4l2_codec_h264_dec_negotiate (GstVideoDecoder * decoder)
|
|||
},
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
GstCaps *filter, *caps;
|
||||
GstCaps *peer_caps, *filter, *caps;
|
||||
GstStaticCaps *static_filter;
|
||||
|
||||
/* Ignore downstream renegotiation request. */
|
||||
if (self->streaming)
|
||||
|
@ -350,7 +357,13 @@ gst_v4l2_codec_h264_dec_negotiate (GstVideoDecoder * decoder)
|
|||
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) {
|
||||
GST_ELEMENT_ERROR (self, CORE, NEGOTIATION,
|
||||
("No supported decoder output formats"), (NULL));
|
||||
|
@ -362,7 +375,8 @@ gst_v4l2_codec_h264_dec_negotiate (GstVideoDecoder * decoder)
|
|||
gst_caps_unref (filter);
|
||||
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,
|
||||
("Unsupported bitdepth/chroma format"),
|
||||
("No support for %ux%u %ubit chroma IDC %i", self->coded_width,
|
||||
|
@ -378,7 +392,8 @@ done:
|
|||
|
||||
self->output_state =
|
||||
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)
|
||||
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)
|
||||
{
|
||||
GstV4l2CodecH264Dec *self = GST_V4L2_CODEC_H264_DEC (decoder);
|
||||
GstCaps *caps = NULL;
|
||||
guint min = 0, num_bitstream;
|
||||
|
||||
/* 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)
|
||||
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,
|
||||
GST_VIDEO_META_API_TYPE, NULL);
|
||||
|
||||
g_clear_object (&self->src_pool);
|
||||
g_clear_object (&self->src_allocator);
|
||||
gst_query_parse_allocation (query, &caps, NULL);
|
||||
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)
|
||||
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);
|
||||
gst_video_info_init (&self->vinfo);
|
||||
gst_video_info_dma_drm_init (&self->vinfo_drm);
|
||||
self->slice_params = g_array_sized_new (FALSE, TRUE,
|
||||
sizeof (struct v4l2_ctrl_h264_slice_params), 4);
|
||||
g_array_set_size (self->slice_params, 4);
|
||||
|
|
|
@ -52,9 +52,14 @@ GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SINK_NAME,
|
|||
);
|
||||
|
||||
#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)
|
||||
|
||||
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 =
|
||||
GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SRC_NAME,
|
||||
|
@ -67,6 +72,7 @@ struct _GstV4l2CodecH265Dec
|
|||
GstV4l2Decoder *decoder;
|
||||
GstVideoCodecState *output_state;
|
||||
GstVideoInfo vinfo;
|
||||
GstVideoInfoDmaDrm vinfo_drm;
|
||||
gint display_width;
|
||||
gint display_height;
|
||||
gint coded_width;
|
||||
|
@ -358,7 +364,8 @@ gst_v4l2_codec_h265_dec_negotiate (GstVideoDecoder * decoder)
|
|||
},
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
GstCaps *filter, *caps;
|
||||
GstCaps *peer_caps, *filter, *caps;
|
||||
GstStaticCaps *static_filter;
|
||||
|
||||
/* Ignore downstream renegotiation request. */
|
||||
if (self->streaming)
|
||||
|
@ -384,7 +391,13 @@ gst_v4l2_codec_h265_dec_negotiate (GstVideoDecoder * decoder)
|
|||
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) {
|
||||
GST_ELEMENT_ERROR (self, CORE, NEGOTIATION,
|
||||
("No supported decoder output formats"), (NULL));
|
||||
|
@ -396,7 +409,8 @@ gst_v4l2_codec_h265_dec_negotiate (GstVideoDecoder * decoder)
|
|||
gst_caps_unref (filter);
|
||||
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,
|
||||
("Unsupported bitdepth/chroma format"),
|
||||
("No support for %ux%u %ubit chroma IDC %i", self->coded_width,
|
||||
|
@ -412,7 +426,8 @@ done:
|
|||
|
||||
self->output_state =
|
||||
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 (self->streaming)
|
||||
|
@ -445,16 +460,30 @@ gst_v4l2_codec_h265_dec_decide_allocation (GstVideoDecoder * decoder,
|
|||
GstQuery * query)
|
||||
{
|
||||
GstV4l2CodecH265Dec *self = GST_V4L2_CODEC_H265_DEC (decoder);
|
||||
GstCaps *caps = NULL;
|
||||
guint min = 0;
|
||||
|
||||
if (self->streaming)
|
||||
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,
|
||||
GST_VIDEO_META_API_TYPE, NULL);
|
||||
|
||||
g_clear_object (&self->src_pool);
|
||||
g_clear_object (&self->src_allocator);
|
||||
gst_query_parse_allocation (query, &caps, NULL);
|
||||
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)
|
||||
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);
|
||||
gst_video_info_init (&self->vinfo);
|
||||
gst_video_info_dma_drm_init (&self->vinfo_drm);
|
||||
self->slice_params = g_array_sized_new (FALSE, TRUE,
|
||||
sizeof (struct v4l2_ctrl_hevc_slice_params), 4);
|
||||
g_array_set_size (self->slice_params, 4);
|
||||
|
|
|
@ -54,9 +54,14 @@ GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SINK_NAME,
|
|||
"mpegversion=(int) 2, " "profile=(string) {main, simple} "));
|
||||
|
||||
#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)
|
||||
|
||||
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 =
|
||||
GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SRC_NAME,
|
||||
|
@ -70,6 +75,7 @@ struct _GstV4l2CodecMpeg2Dec
|
|||
GstV4l2Decoder *decoder;
|
||||
GstVideoCodecState *output_state;
|
||||
GstVideoInfo vinfo;
|
||||
GstVideoInfoDmaDrm vinfo_drm;
|
||||
|
||||
guint16 width;
|
||||
guint16 height;
|
||||
|
@ -246,7 +252,8 @@ gst_v4l2_codec_mpeg2_dec_negotiate (GstVideoDecoder * decoder)
|
|||
};
|
||||
|
||||
/* *INDENT-ON* */
|
||||
GstCaps *filter, *caps;
|
||||
GstCaps *peer_caps, *filter, *caps;
|
||||
GstStaticCaps *static_filter;
|
||||
|
||||
/* Ignore downstream renegotiation request. */
|
||||
if (self->streaming)
|
||||
|
@ -272,7 +279,13 @@ gst_v4l2_codec_mpeg2_dec_negotiate (GstVideoDecoder * decoder)
|
|||
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) {
|
||||
GST_ELEMENT_ERROR (self, CORE, NEGOTIATION,
|
||||
("No supported decoder output formats"), (NULL));
|
||||
|
@ -284,7 +297,8 @@ gst_v4l2_codec_mpeg2_dec_negotiate (GstVideoDecoder * decoder)
|
|||
gst_caps_unref (filter);
|
||||
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,
|
||||
("Unsupported bitdepth/chroma format"),
|
||||
("No support for %ux%u chroma IDC %i", self->width,
|
||||
|
@ -300,7 +314,7 @@ done:
|
|||
|
||||
self->output_state =
|
||||
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)
|
||||
self->output_state->info.interlace_mode =
|
||||
|
@ -337,6 +351,7 @@ gst_v4l2_codec_mpeg2_dec_decide_allocation (GstVideoDecoder * decoder,
|
|||
GstQuery * query)
|
||||
{
|
||||
GstV4l2CodecMpeg2Dec *self = GST_V4L2_CODEC_MPEG2_DEC (decoder);
|
||||
GstCaps *caps = NULL;
|
||||
guint min = 0, num_bitstream;
|
||||
|
||||
/* 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)
|
||||
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,
|
||||
GST_VIDEO_META_API_TYPE, NULL);
|
||||
|
||||
g_clear_object (&self->src_pool);
|
||||
g_clear_object (&self->src_allocator);
|
||||
gst_query_parse_allocation (query, &caps, NULL);
|
||||
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)
|
||||
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);
|
||||
gst_video_info_init (&self->vinfo);
|
||||
gst_video_info_dma_drm_init (&self->vinfo_drm);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -55,9 +55,14 @@ GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SINK_NAME,
|
|||
);
|
||||
|
||||
#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)
|
||||
|
||||
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 =
|
||||
GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SRC_NAME,
|
||||
|
@ -70,6 +75,7 @@ struct _GstV4l2CodecVp8Dec
|
|||
GstV4l2Decoder *decoder;
|
||||
GstVideoCodecState *output_state;
|
||||
GstVideoInfo vinfo;
|
||||
GstVideoInfoDmaDrm vinfo_drm;
|
||||
gint width;
|
||||
gint height;
|
||||
|
||||
|
@ -195,7 +201,8 @@ gst_v4l2_codec_vp8_dec_negotiate (GstVideoDecoder * decoder)
|
|||
},
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
GstCaps *filter, *caps;
|
||||
GstCaps *peer_caps, *filter, *caps;
|
||||
GstStaticCaps *static_filter;
|
||||
|
||||
/* Ignore downstream renegotiation request. */
|
||||
if (self->streaming)
|
||||
|
@ -221,7 +228,13 @@ gst_v4l2_codec_vp8_dec_negotiate (GstVideoDecoder * decoder)
|
|||
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) {
|
||||
GST_ELEMENT_ERROR (self, CORE, NEGOTIATION,
|
||||
("No supported decoder output formats"), (NULL));
|
||||
|
@ -233,7 +246,8 @@ gst_v4l2_codec_vp8_dec_negotiate (GstVideoDecoder * decoder)
|
|||
gst_caps_unref (filter);
|
||||
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,
|
||||
("Unsupported pixel format"),
|
||||
("No support for %ux%u format %s", self->width, self->height,
|
||||
|
@ -249,7 +263,7 @@ done:
|
|||
|
||||
self->output_state =
|
||||
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 (self->streaming)
|
||||
|
@ -282,17 +296,31 @@ gst_v4l2_codec_vp8_dec_decide_allocation (GstVideoDecoder * decoder,
|
|||
GstQuery * query)
|
||||
{
|
||||
GstV4l2CodecVp8Dec *self = GST_V4L2_CODEC_VP8_DEC (decoder);
|
||||
GstCaps *caps = NULL;
|
||||
guint min = 0;
|
||||
guint num_bitstream;
|
||||
|
||||
if (self->streaming)
|
||||
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,
|
||||
GST_VIDEO_META_API_TYPE, NULL);
|
||||
|
||||
g_clear_object (&self->src_pool);
|
||||
g_clear_object (&self->src_allocator);
|
||||
gst_query_parse_allocation (query, &caps, NULL);
|
||||
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)
|
||||
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);
|
||||
gst_video_info_init (&self->vinfo);
|
||||
gst_video_info_dma_drm_init (&self->vinfo_drm);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -56,9 +56,14 @@ GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SINK_NAME,
|
|||
);
|
||||
|
||||
#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)
|
||||
|
||||
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 =
|
||||
GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SRC_NAME,
|
||||
|
@ -71,6 +76,7 @@ struct _GstV4l2CodecVp9Dec
|
|||
GstV4l2Decoder *decoder;
|
||||
GstVideoCodecState *output_state;
|
||||
GstVideoInfo vinfo;
|
||||
GstVideoInfoDmaDrm vinfo_drm;
|
||||
gint width;
|
||||
gint height;
|
||||
|
||||
|
@ -467,7 +473,9 @@ gst_v4l2_codec_vp9_dec_negotiate (GstVideoDecoder * decoder)
|
|||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
GstCaps *filter, *caps;
|
||||
GstCaps *peer_caps, *filter, *caps;
|
||||
GstStaticCaps *static_filter;
|
||||
|
||||
/* Ignore downstream renegotiation request. */
|
||||
if (self->streaming)
|
||||
goto done;
|
||||
|
@ -491,7 +499,13 @@ gst_v4l2_codec_vp9_dec_negotiate (GstVideoDecoder * decoder)
|
|||
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) {
|
||||
GST_ELEMENT_ERROR (self, CORE, NEGOTIATION,
|
||||
("No supported decoder output formats"), (NULL));
|
||||
|
@ -503,7 +517,8 @@ gst_v4l2_codec_vp9_dec_negotiate (GstVideoDecoder * decoder)
|
|||
gst_caps_unref (filter);
|
||||
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,
|
||||
("Unsupported pixel format"),
|
||||
("No support for %ux%u format %s", self->width, self->height,
|
||||
|
@ -519,7 +534,7 @@ done:
|
|||
|
||||
self->output_state =
|
||||
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 (self->streaming)
|
||||
|
@ -552,6 +567,7 @@ gst_v4l2_codec_vp9_dec_decide_allocation (GstVideoDecoder * decoder,
|
|||
GstQuery * query)
|
||||
{
|
||||
GstV4l2CodecVp9Dec *self = GST_V4L2_CODEC_VP9_DEC (decoder);
|
||||
GstCaps *caps = NULL;
|
||||
guint min = 0;
|
||||
guint num_bitstream;
|
||||
|
||||
|
@ -560,11 +576,24 @@ gst_v4l2_codec_vp9_dec_decide_allocation (GstVideoDecoder * decoder,
|
|||
if (self->streaming)
|
||||
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,
|
||||
GST_VIDEO_META_API_TYPE, NULL);
|
||||
|
||||
g_clear_object (&self->src_pool);
|
||||
g_clear_object (&self->src_allocator);
|
||||
gst_query_parse_allocation (query, &caps, NULL);
|
||||
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)
|
||||
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);
|
||||
gst_video_info_init (&self->vinfo);
|
||||
gst_video_info_dma_drm_init (&self->vinfo_drm);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -410,6 +410,7 @@ gst_v4l2_decoder_probe_caps_for_format (GstV4l2Decoder * self,
|
|||
gint index = 0;
|
||||
GstCaps *caps, *tmp, *size_caps;
|
||||
GstVideoFormat format;
|
||||
guint32 drm_fourcc;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "enumerate size for %" GST_FOURCC_FORMAT,
|
||||
GST_FOURCC_ARGS (pixelformat));
|
||||
|
@ -432,6 +433,31 @@ gst_v4l2_decoder_probe_caps_for_format (GstV4l2Decoder * self,
|
|||
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);
|
||||
|
||||
return caps;
|
||||
|
@ -491,7 +517,7 @@ gst_v4l2_decoder_enum_src_formats (GstV4l2Decoder * self,
|
|||
|
||||
gboolean
|
||||
gst_v4l2_decoder_select_src_format (GstV4l2Decoder * self, GstCaps * caps,
|
||||
GstVideoInfo * vinfo)
|
||||
GstVideoInfo * vinfo, GstVideoInfoDmaDrm * vinfo_drm)
|
||||
{
|
||||
gint ret;
|
||||
struct v4l2_format fmt = {
|
||||
|
@ -500,6 +526,7 @@ gst_v4l2_decoder_select_src_format (GstV4l2Decoder * self, GstCaps * caps,
|
|||
GstVideoFormat format;
|
||||
guint32 pix_fmt;
|
||||
GstVideoInfo tmp_vinfo;
|
||||
GstVideoInfoDmaDrm tmp_vinfo_drm;
|
||||
|
||||
if (gst_caps_is_empty (caps))
|
||||
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_dma_drm_init (&tmp_vinfo_drm);
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Original caps: %" GST_PTR_FORMAT, caps);
|
||||
caps = gst_caps_fixate (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;
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
|
||||
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_video_format_to_string (vinfo->finfo->format),
|
||||
vinfo->width, vinfo->height);
|
||||
|
@ -556,15 +597,22 @@ gst_v4l2_decoder_select_src_format (GstV4l2Decoder * self, GstCaps * caps,
|
|||
|
||||
GstVideoCodecState *
|
||||
gst_v4l2_decoder_set_output_state (GstVideoDecoder * decoder,
|
||||
GstVideoInfo * vinfo, guint width, guint height,
|
||||
GstVideoCodecState * reference)
|
||||
GstVideoInfo * vinfo, GstVideoInfoDmaDrm * vinfo_drm, guint width,
|
||||
guint height, GstVideoCodecState * reference)
|
||||
{
|
||||
GstVideoCodecState *state;
|
||||
|
||||
state = gst_video_decoder_set_output_state (decoder, vinfo->finfo->format,
|
||||
width, height, reference);
|
||||
|
||||
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);
|
||||
|
||||
|
|
|
@ -72,10 +72,12 @@ GstCaps * gst_v4l2_decoder_enum_src_formats (GstV4l2Decoder * self,
|
|||
|
||||
gboolean gst_v4l2_decoder_select_src_format (GstV4l2Decoder * self,
|
||||
GstCaps * caps,
|
||||
GstVideoInfo * vinfo);
|
||||
GstVideoInfo * vinfo,
|
||||
GstVideoInfoDmaDrm * vinfo_drm);
|
||||
|
||||
GstVideoCodecState * gst_v4l2_decoder_set_output_state (GstVideoDecoder * decoder,
|
||||
GstVideoInfo * vinfo,
|
||||
GstVideoInfoDmaDrm * drm_info,
|
||||
guint width,
|
||||
guint height,
|
||||
GstVideoCodecState * reference);
|
||||
|
|
Loading…
Reference in a new issue