mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-29 13:11:06 +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/6376>
This commit is contained in:
parent
383545d856
commit
aef872944e
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"));
|
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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
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);
|
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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue