mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 02:01:12 +00:00
va: Apply the new DMA format:modifier pair negotiation in decoder
We will consider the DMA modifier for negotiation, setting caps and memory pool allocation. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4044>
This commit is contained in:
parent
919d398bff
commit
5df0bfa7cb
4 changed files with 113 additions and 32 deletions
|
@ -265,7 +265,7 @@ _create_internal_pool (GstVaAV1Dec * self, gint width, gint height)
|
||||||
GstVideoFormat format;
|
GstVideoFormat format;
|
||||||
|
|
||||||
gst_va_base_dec_get_preferred_format_and_caps_features (base,
|
gst_va_base_dec_get_preferred_format_and_caps_features (base,
|
||||||
&format, NULL);
|
&format, NULL, NULL);
|
||||||
if (format == GST_VIDEO_FORMAT_UNKNOWN) {
|
if (format == GST_VIDEO_FORMAT_UNKNOWN) {
|
||||||
GST_WARNING_OBJECT (self, "Failed to get format for internal pool");
|
GST_WARNING_OBJECT (self, "Failed to get format for internal pool");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -501,7 +501,10 @@ gst_va_base_dec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query)
|
||||||
|
|
||||||
gst_query_parse_allocation (query, &caps, NULL);
|
gst_query_parse_allocation (query, &caps, NULL);
|
||||||
|
|
||||||
if (!(caps && gst_video_info_from_caps (&info, caps)))
|
if (!caps)
|
||||||
|
goto wrong_caps;
|
||||||
|
|
||||||
|
if (!gst_va_video_info_from_caps (&info, NULL, caps))
|
||||||
goto wrong_caps;
|
goto wrong_caps;
|
||||||
|
|
||||||
has_videometa = gst_query_find_allocation_meta (query,
|
has_videometa = gst_query_find_allocation_meta (query,
|
||||||
|
@ -515,9 +518,12 @@ gst_va_base_dec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query)
|
||||||
2. Some codec such as H265, it does not clean the DPB when new SPS
|
2. Some codec such as H265, it does not clean the DPB when new SPS
|
||||||
comes. The new SPS may set the crop window to top-left corner and
|
comes. The new SPS may set the crop window to top-left corner and
|
||||||
so no video crop is needed here. But we may still have cached frames
|
so no video crop is needed here. But we may still have cached frames
|
||||||
in DPB which need a copy. */
|
in DPB which need a copy.
|
||||||
if ((_need_video_crop (base) && !has_video_crop_meta) ||
|
3. For DMA kind memory, because we may not be able to map this buffer,
|
||||||
base->apply_video_crop) {
|
just disable the copy for crop. This may cause some alignment garbage. */
|
||||||
|
if (!gst_video_is_dma_drm_caps (caps) &&
|
||||||
|
((_need_video_crop (base) && !has_video_crop_meta) ||
|
||||||
|
base->apply_video_crop)) {
|
||||||
return _decide_allocation_for_video_crop (decoder, query, caps, &info);
|
return _decide_allocation_for_video_crop (decoder, query, caps, &info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -758,16 +764,24 @@ gst_va_base_dec_class_init (GstVaBaseDecClass * klass, GstVaCodecs codec,
|
||||||
/* XXX: if chroma has not an available format, the first format is
|
/* XXX: if chroma has not an available format, the first format is
|
||||||
* returned, relying on an hypothetical internal CSC */
|
* returned, relying on an hypothetical internal CSC */
|
||||||
static GstVideoFormat
|
static GstVideoFormat
|
||||||
_find_video_format_from_chroma (const GValue * formats, guint chroma_type)
|
_find_video_format_from_chroma (const GValue * formats, guint chroma_type,
|
||||||
|
gboolean drm_format, guint64 * modifier)
|
||||||
{
|
{
|
||||||
GstVideoFormat fmt;
|
GstVideoFormat fmt;
|
||||||
|
guint32 fourcc;
|
||||||
guint i, num_values;
|
guint i, num_values;
|
||||||
|
|
||||||
if (!formats)
|
if (!formats)
|
||||||
return GST_VIDEO_FORMAT_UNKNOWN;
|
return GST_VIDEO_FORMAT_UNKNOWN;
|
||||||
|
|
||||||
if (G_VALUE_HOLDS_STRING (formats)) {
|
if (G_VALUE_HOLDS_STRING (formats)) {
|
||||||
return gst_video_format_from_string (g_value_get_string (formats));
|
if (drm_format) {
|
||||||
|
fourcc = gst_video_dma_drm_fourcc_from_string
|
||||||
|
(g_value_get_string (formats), modifier);
|
||||||
|
return gst_va_video_format_from_drm_fourcc (fourcc);
|
||||||
|
} else {
|
||||||
|
return gst_video_format_from_string (g_value_get_string (formats));
|
||||||
|
}
|
||||||
} else if (GST_VALUE_HOLDS_LIST (formats)) {
|
} else if (GST_VALUE_HOLDS_LIST (formats)) {
|
||||||
GValue *val, *first_val = NULL;
|
GValue *val, *first_val = NULL;
|
||||||
|
|
||||||
|
@ -778,13 +792,28 @@ _find_video_format_from_chroma (const GValue * formats, guint chroma_type)
|
||||||
continue;
|
continue;
|
||||||
if (!first_val)
|
if (!first_val)
|
||||||
first_val = val;
|
first_val = val;
|
||||||
fmt = gst_video_format_from_string (g_value_get_string (val));
|
|
||||||
|
if (drm_format) {
|
||||||
|
fourcc = gst_video_dma_drm_fourcc_from_string (g_value_get_string (val),
|
||||||
|
modifier);
|
||||||
|
fmt = gst_va_video_format_from_drm_fourcc (fourcc);
|
||||||
|
} else {
|
||||||
|
fmt = gst_video_format_from_string (g_value_get_string (val));
|
||||||
|
}
|
||||||
|
|
||||||
if (gst_va_chroma_from_video_format (fmt) == chroma_type)
|
if (gst_va_chroma_from_video_format (fmt) == chroma_type)
|
||||||
return fmt;
|
return fmt;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (first_val)
|
if (first_val) {
|
||||||
return gst_video_format_from_string (g_value_get_string (first_val));
|
if (drm_format) {
|
||||||
|
fourcc = gst_video_dma_drm_fourcc_from_string (g_value_get_string
|
||||||
|
(first_val), modifier);
|
||||||
|
return gst_va_video_format_from_drm_fourcc (fourcc);
|
||||||
|
} else {
|
||||||
|
return gst_video_format_from_string (g_value_get_string (first_val));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return GST_VIDEO_FORMAT_UNKNOWN;
|
return GST_VIDEO_FORMAT_UNKNOWN;
|
||||||
|
@ -792,13 +821,15 @@ _find_video_format_from_chroma (const GValue * formats, guint chroma_type)
|
||||||
|
|
||||||
static GstVideoFormat
|
static GstVideoFormat
|
||||||
_caps_video_format_from_chroma (GstCaps * caps, GstCapsFeatures * features,
|
_caps_video_format_from_chroma (GstCaps * caps, GstCapsFeatures * features,
|
||||||
guint chroma_type)
|
guint chroma_type, guint64 * ret_modifier)
|
||||||
{
|
{
|
||||||
guint i, num_structures;
|
guint i, num_structures;
|
||||||
|
gboolean drm_format;
|
||||||
GstCapsFeatures *feats;
|
GstCapsFeatures *feats;
|
||||||
GstStructure *structure;
|
GstStructure *structure;
|
||||||
const GValue *format;
|
const GValue *format;
|
||||||
GstVideoFormat fmt, ret_fmt = GST_VIDEO_FORMAT_UNKNOWN;
|
GstVideoFormat fmt, ret_fmt = GST_VIDEO_FORMAT_UNKNOWN;
|
||||||
|
guint64 modifier;
|
||||||
|
|
||||||
num_structures = gst_caps_get_size (caps);
|
num_structures = gst_caps_get_size (caps);
|
||||||
for (i = 0; i < num_structures; i++) {
|
for (i = 0; i < num_structures; i++) {
|
||||||
|
@ -806,19 +837,30 @@ _caps_video_format_from_chroma (GstCaps * caps, GstCapsFeatures * features,
|
||||||
if (!gst_caps_features_is_equal (feats, features))
|
if (!gst_caps_features_is_equal (feats, features))
|
||||||
continue;
|
continue;
|
||||||
structure = gst_caps_get_structure (caps, i);
|
structure = gst_caps_get_structure (caps, i);
|
||||||
format = gst_structure_get_value (structure, "format");
|
|
||||||
|
|
||||||
fmt = _find_video_format_from_chroma (format, chroma_type);
|
if (gst_caps_features_contains (feats, GST_CAPS_FEATURE_MEMORY_DMABUF)) {
|
||||||
|
format = gst_structure_get_value (structure, "drm-format");
|
||||||
|
drm_format = TRUE;
|
||||||
|
} else {
|
||||||
|
format = gst_structure_get_value (structure, "format");
|
||||||
|
drm_format = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt = _find_video_format_from_chroma (format, chroma_type, drm_format,
|
||||||
|
&modifier);
|
||||||
if (fmt == GST_VIDEO_FORMAT_UNKNOWN)
|
if (fmt == GST_VIDEO_FORMAT_UNKNOWN)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Record the first valid format as the fallback if we can
|
if (ret_fmt == GST_VIDEO_FORMAT_UNKNOWN) {
|
||||||
not find a better one. */
|
|
||||||
if (ret_fmt == GST_VIDEO_FORMAT_UNKNOWN)
|
|
||||||
ret_fmt = fmt;
|
ret_fmt = fmt;
|
||||||
|
if (ret_modifier)
|
||||||
|
*ret_modifier = modifier;
|
||||||
|
}
|
||||||
|
|
||||||
if (gst_va_chroma_from_video_format (fmt) == chroma_type) {
|
if (gst_va_chroma_from_video_format (fmt) == chroma_type) {
|
||||||
ret_fmt = fmt;
|
ret_fmt = fmt;
|
||||||
|
if (ret_modifier)
|
||||||
|
*ret_modifier = modifier;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -828,13 +870,28 @@ _caps_video_format_from_chroma (GstCaps * caps, GstCapsFeatures * features,
|
||||||
|
|
||||||
static GstVideoFormat
|
static GstVideoFormat
|
||||||
_default_video_format_from_chroma (GstVaBaseDec * base,
|
_default_video_format_from_chroma (GstVaBaseDec * base,
|
||||||
GstCapsFeatures * features, guint chroma_type)
|
GstCaps * preferred_caps, GstCapsFeatures * features, guint chroma_type,
|
||||||
|
guint64 * modifier)
|
||||||
{
|
{
|
||||||
GstCaps *tmpl_caps;
|
GstCaps *tmpl_caps;
|
||||||
GstVideoFormat ret = GST_VIDEO_FORMAT_UNKNOWN;
|
GstVideoFormat ret = GST_VIDEO_FORMAT_UNKNOWN;
|
||||||
|
|
||||||
tmpl_caps = gst_pad_get_pad_template_caps (GST_VIDEO_DECODER_SRC_PAD (base));
|
tmpl_caps = gst_pad_get_pad_template_caps (GST_VIDEO_DECODER_SRC_PAD (base));
|
||||||
ret = _caps_video_format_from_chroma (tmpl_caps, features, chroma_type);
|
|
||||||
|
/* Make the preferred caps in the order of our template */
|
||||||
|
if (preferred_caps) {
|
||||||
|
GstCaps *tmp;
|
||||||
|
g_assert (!gst_caps_is_empty (preferred_caps));
|
||||||
|
|
||||||
|
tmp = tmpl_caps;
|
||||||
|
tmpl_caps = gst_caps_intersect_full (tmp, preferred_caps,
|
||||||
|
GST_CAPS_INTERSECT_FIRST);
|
||||||
|
gst_caps_unref (tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = _caps_video_format_from_chroma (tmpl_caps, features, chroma_type,
|
||||||
|
modifier);
|
||||||
|
|
||||||
gst_caps_unref (tmpl_caps);
|
gst_caps_unref (tmpl_caps);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -858,9 +915,10 @@ _downstream_has_video_meta (GstVaBaseDec * base, GstCaps * caps)
|
||||||
|
|
||||||
void
|
void
|
||||||
gst_va_base_dec_get_preferred_format_and_caps_features (GstVaBaseDec * base,
|
gst_va_base_dec_get_preferred_format_and_caps_features (GstVaBaseDec * base,
|
||||||
GstVideoFormat * format, GstCapsFeatures ** capsfeatures)
|
GstVideoFormat * format, GstCapsFeatures ** capsfeatures,
|
||||||
|
guint64 * modifier)
|
||||||
{
|
{
|
||||||
GstCaps *peer_caps, *preferred_caps = NULL;
|
GstCaps *peer_caps = NULL, *preferred_caps = NULL;
|
||||||
GstCapsFeatures *features;
|
GstCapsFeatures *features;
|
||||||
GstStructure *structure;
|
GstStructure *structure;
|
||||||
guint num_structures, i;
|
guint num_structures, i;
|
||||||
|
@ -897,16 +955,14 @@ gst_va_base_dec_get_preferred_format_and_caps_features (GstVaBaseDec * base,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!preferred_caps)
|
if (!preferred_caps)
|
||||||
preferred_caps = peer_caps;
|
preferred_caps = gst_caps_copy (peer_caps);
|
||||||
else
|
|
||||||
gst_clear_caps (&peer_caps);
|
|
||||||
|
|
||||||
if (gst_caps_is_empty (preferred_caps)) {
|
if (gst_caps_is_empty (preferred_caps)) {
|
||||||
if (capsfeatures)
|
if (capsfeatures)
|
||||||
*capsfeatures = NULL; /* system memory */
|
*capsfeatures = NULL; /* system memory */
|
||||||
if (format) {
|
if (format) {
|
||||||
*format = _default_video_format_from_chroma (base,
|
*format = _default_video_format_from_chroma (base, NULL,
|
||||||
GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY, base->rt_format);
|
GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY, base->rt_format, NULL);
|
||||||
}
|
}
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
@ -922,7 +978,10 @@ gst_va_base_dec_get_preferred_format_and_caps_features (GstVaBaseDec * base,
|
||||||
&& !_downstream_has_video_meta (base, preferred_caps)) {
|
&& !_downstream_has_video_meta (base, preferred_caps)) {
|
||||||
GST_INFO_OBJECT (base, "Downstream reports ANY caps but without"
|
GST_INFO_OBJECT (base, "Downstream reports ANY caps but without"
|
||||||
" VideoMeta support; fallback to system memory.");
|
" VideoMeta support; fallback to system memory.");
|
||||||
|
|
||||||
features = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
|
features = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
|
||||||
|
gst_clear_caps (&preferred_caps);
|
||||||
|
preferred_caps = gst_caps_copy (peer_caps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -932,12 +991,13 @@ gst_va_base_dec_get_preferred_format_and_caps_features (GstVaBaseDec * base,
|
||||||
/* Use the format from chroma and available format for selected
|
/* Use the format from chroma and available format for selected
|
||||||
* capsfeature */
|
* capsfeature */
|
||||||
if (format) {
|
if (format) {
|
||||||
*format = _default_video_format_from_chroma (base, features,
|
*format = _default_video_format_from_chroma (base, preferred_caps,
|
||||||
base->rt_format);
|
features, base->rt_format, modifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
bail:
|
bail:
|
||||||
gst_clear_caps (&preferred_caps);
|
gst_clear_caps (&preferred_caps);
|
||||||
|
gst_clear_caps (&peer_caps);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -1143,6 +1203,7 @@ gst_va_base_dec_set_output_state (GstVaBaseDec * base)
|
||||||
{
|
{
|
||||||
GstVideoDecoder *decoder = GST_VIDEO_DECODER (base);
|
GstVideoDecoder *decoder = GST_VIDEO_DECODER (base);
|
||||||
GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;
|
GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;
|
||||||
|
guint64 modifier;
|
||||||
GstCapsFeatures *capsfeatures = NULL;
|
GstCapsFeatures *capsfeatures = NULL;
|
||||||
GstVideoInfo *info = &base->output_info;
|
GstVideoInfo *info = &base->output_info;
|
||||||
|
|
||||||
|
@ -1150,7 +1211,7 @@ gst_va_base_dec_set_output_state (GstVaBaseDec * base)
|
||||||
gst_video_codec_state_unref (base->output_state);
|
gst_video_codec_state_unref (base->output_state);
|
||||||
|
|
||||||
gst_va_base_dec_get_preferred_format_and_caps_features (base, &format,
|
gst_va_base_dec_get_preferred_format_and_caps_features (base, &format,
|
||||||
&capsfeatures);
|
&capsfeatures, &modifier);
|
||||||
if (format == GST_VIDEO_FORMAT_UNKNOWN)
|
if (format == GST_VIDEO_FORMAT_UNKNOWN)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
@ -1160,7 +1221,15 @@ gst_va_base_dec_set_output_state (GstVaBaseDec * base)
|
||||||
GST_VIDEO_INFO_HEIGHT (info), base->input_state);
|
GST_VIDEO_INFO_HEIGHT (info), base->input_state);
|
||||||
|
|
||||||
/* set caps feature */
|
/* set caps feature */
|
||||||
base->output_state->caps = gst_video_info_to_caps (&base->output_state->info);
|
if (capsfeatures && gst_caps_features_contains (capsfeatures,
|
||||||
|
GST_CAPS_FEATURE_MEMORY_DMABUF)) {
|
||||||
|
base->output_state->caps =
|
||||||
|
gst_va_video_info_to_dma_caps (&base->output_state->info, modifier);
|
||||||
|
} else {
|
||||||
|
base->output_state->caps =
|
||||||
|
gst_video_info_to_caps (&base->output_state->info);
|
||||||
|
}
|
||||||
|
|
||||||
if (capsfeatures)
|
if (capsfeatures)
|
||||||
gst_caps_set_features_simple (base->output_state->caps, capsfeatures);
|
gst_caps_set_features_simple (base->output_state->caps, capsfeatures);
|
||||||
|
|
||||||
|
|
|
@ -133,7 +133,8 @@ void gst_va_base_dec_class_init (GstVaBaseDecClass * k
|
||||||
gboolean gst_va_base_dec_close (GstVideoDecoder * decoder);
|
gboolean gst_va_base_dec_close (GstVideoDecoder * decoder);
|
||||||
void gst_va_base_dec_get_preferred_format_and_caps_features (GstVaBaseDec * base,
|
void gst_va_base_dec_get_preferred_format_and_caps_features (GstVaBaseDec * base,
|
||||||
GstVideoFormat * format,
|
GstVideoFormat * format,
|
||||||
GstCapsFeatures ** capsfeatures);
|
GstCapsFeatures ** capsfeatures,
|
||||||
|
guint64 * modifier);
|
||||||
gboolean gst_va_base_dec_copy_output_buffer (GstVaBaseDec * base,
|
gboolean gst_va_base_dec_copy_output_buffer (GstVaBaseDec * base,
|
||||||
GstVideoCodecFrame * codec_frame);
|
GstVideoCodecFrame * codec_frame);
|
||||||
gboolean gst_va_base_dec_process_output (GstVaBaseDec * base,
|
gboolean gst_va_base_dec_process_output (GstVaBaseDec * base,
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
|
|
||||||
#include <gst/va/gstvavideoformat.h>
|
#include <gst/va/gstvavideoformat.h>
|
||||||
|
|
||||||
|
#include "gstvacaps.h"
|
||||||
#include "gstvabasedec.h"
|
#include "gstvabasedec.h"
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_STATIC (gst_va_jpegdec_debug);
|
GST_DEBUG_CATEGORY_STATIC (gst_va_jpegdec_debug);
|
||||||
|
@ -356,6 +357,7 @@ gst_va_jpeg_dec_negotiate (GstVideoDecoder * decoder)
|
||||||
GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
|
GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
|
||||||
GstVaJpegDec *self = GST_VA_JPEG_DEC (decoder);
|
GstVaJpegDec *self = GST_VA_JPEG_DEC (decoder);
|
||||||
GstVideoFormat format;
|
GstVideoFormat format;
|
||||||
|
guint64 modifier;
|
||||||
GstCapsFeatures *capsfeatures = NULL;
|
GstCapsFeatures *capsfeatures = NULL;
|
||||||
|
|
||||||
/* Ignore downstream renegotiation request. */
|
/* Ignore downstream renegotiation request. */
|
||||||
|
@ -386,7 +388,7 @@ gst_va_jpeg_dec_negotiate (GstVideoDecoder * decoder)
|
||||||
base->rt_format = VA_RT_FORMAT_RGBP;
|
base->rt_format = VA_RT_FORMAT_RGBP;
|
||||||
|
|
||||||
gst_va_base_dec_get_preferred_format_and_caps_features (base, &format,
|
gst_va_base_dec_get_preferred_format_and_caps_features (base, &format,
|
||||||
&capsfeatures);
|
&capsfeatures, &modifier);
|
||||||
if (format == GST_VIDEO_FORMAT_UNKNOWN)
|
if (format == GST_VIDEO_FORMAT_UNKNOWN)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
@ -402,7 +404,16 @@ gst_va_jpeg_dec_negotiate (GstVideoDecoder * decoder)
|
||||||
gst_video_decoder_set_output_state (decoder, format,
|
gst_video_decoder_set_output_state (decoder, format,
|
||||||
base->width, base->height, base->input_state);
|
base->width, base->height, base->input_state);
|
||||||
|
|
||||||
base->output_state->caps = gst_video_info_to_caps (&base->output_state->info);
|
/* set caps feature */
|
||||||
|
if (capsfeatures && gst_caps_features_contains (capsfeatures,
|
||||||
|
GST_CAPS_FEATURE_MEMORY_DMABUF)) {
|
||||||
|
base->output_state->caps =
|
||||||
|
gst_va_video_info_to_dma_caps (&base->output_state->info, modifier);
|
||||||
|
} else {
|
||||||
|
base->output_state->caps =
|
||||||
|
gst_video_info_to_caps (&base->output_state->info);
|
||||||
|
}
|
||||||
|
|
||||||
if (capsfeatures)
|
if (capsfeatures)
|
||||||
gst_caps_set_features_simple (base->output_state->caps, capsfeatures);
|
gst_caps_set_features_simple (base->output_state->caps, capsfeatures);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue