mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
msdkvpp: Add fix_format for src caps
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5208>
This commit is contained in:
parent
5536f742e9
commit
484a636841
1 changed files with 136 additions and 13 deletions
|
@ -29,6 +29,11 @@
|
|||
#include "msdk-enums.h"
|
||||
#include "gstmsdkcaps.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <libdrm/drm_fourcc.h>
|
||||
#include <gst/va/gstvavideoformat.h>
|
||||
#endif
|
||||
|
||||
#define SWAP_GINT(a, b) do { \
|
||||
const gint t = a; a = b; b = t; \
|
||||
} while (0)
|
||||
|
@ -52,6 +57,127 @@ gst_msdkvpp_is_deinterlace_enabled (GstMsdkVPP * msdkvpp, GstVideoInfo * vip)
|
|||
return deinterlace;
|
||||
}
|
||||
|
||||
/* This help function is to fixate output format for vpp src caps,
|
||||
* when downstream element does not set a specific format, i.e. queried
|
||||
* caps contains a list of formats, vpp src caps will loop the format
|
||||
* list and find one format that matches the vpp sink caps format (in vinfo);
|
||||
* if downstream has set a specific format, we use this format for vpp src caps.
|
||||
*/
|
||||
static GstCaps *
|
||||
fixate_output_format (GstMsdkVPP * thiz, GstVideoInfo * vinfo, GstCaps * caps)
|
||||
{
|
||||
GstVideoFormat fmt = GST_VIDEO_FORMAT_UNKNOWN;
|
||||
guint i, size, fixated_idx = 0;
|
||||
GstStructure *s, *out = NULL;
|
||||
GstCapsFeatures *features;
|
||||
GstCaps *ret;
|
||||
const GValue *format;
|
||||
gboolean is_dma = FALSE;
|
||||
gboolean fixate = FALSE;
|
||||
#ifndef _WIN32
|
||||
guint64 modifier = DRM_FORMAT_MOD_INVALID;
|
||||
guint32 fourcc;
|
||||
#endif
|
||||
|
||||
if (!caps)
|
||||
return NULL;
|
||||
size = gst_caps_get_size (caps);
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
s = gst_caps_get_structure (caps, i);
|
||||
features = gst_caps_get_features (caps, i);
|
||||
|
||||
if (gst_caps_features_contains (features, GST_CAPS_FEATURE_MEMORY_DMABUF)) {
|
||||
format = gst_structure_get_value (s, "drm-format");
|
||||
is_dma = TRUE;
|
||||
} else {
|
||||
format = gst_structure_get_value (s, "format");
|
||||
is_dma = FALSE;
|
||||
}
|
||||
|
||||
if (format == NULL)
|
||||
continue;
|
||||
|
||||
if (GST_VALUE_HOLDS_LIST (format)) {
|
||||
gint j, len;
|
||||
|
||||
len = gst_value_list_get_size (format);
|
||||
GST_DEBUG_OBJECT (thiz, "have %d formats", len);
|
||||
for (j = 0; j < len; j++) {
|
||||
const GValue *val;
|
||||
|
||||
val = gst_value_list_get_value (format, j);
|
||||
if (G_VALUE_HOLDS_STRING (val)) {
|
||||
#ifndef _WIN32
|
||||
if (is_dma) {
|
||||
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));
|
||||
}
|
||||
#else
|
||||
fmt = gst_video_format_from_string (g_value_get_string (val));
|
||||
#endif
|
||||
if (fmt == GST_VIDEO_FORMAT_UNKNOWN)
|
||||
continue;
|
||||
if (fmt == GST_VIDEO_INFO_FORMAT (vinfo)) {
|
||||
fixate = TRUE;
|
||||
fixated_idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (G_VALUE_HOLDS_STRING (format)) {
|
||||
#ifndef _WIN32
|
||||
if (is_dma) {
|
||||
fourcc = gst_video_dma_drm_fourcc_from_string
|
||||
(g_value_get_string (format), &modifier);
|
||||
fmt = gst_va_video_format_from_drm_fourcc (fourcc);
|
||||
} else {
|
||||
fmt = gst_video_format_from_string (g_value_get_string (format));
|
||||
}
|
||||
#else
|
||||
fmt = gst_video_format_from_string (g_value_get_string (format));
|
||||
#endif
|
||||
if (fmt == GST_VIDEO_FORMAT_UNKNOWN)
|
||||
continue;
|
||||
fixate = TRUE;
|
||||
break;
|
||||
}
|
||||
if (fixate)
|
||||
break;
|
||||
}
|
||||
|
||||
out = gst_structure_copy (gst_caps_get_structure (caps, fixated_idx));
|
||||
features = gst_caps_features_copy (gst_caps_get_features (caps, fixated_idx));
|
||||
|
||||
#ifndef _WIN32
|
||||
if (is_dma) {
|
||||
gchar *drm_fmt_name;
|
||||
|
||||
g_assert (modifier != DRM_FORMAT_MOD_INVALID);
|
||||
|
||||
drm_fmt_name = gst_video_dma_drm_fourcc_to_string
|
||||
(gst_va_drm_fourcc_from_video_format (fmt), modifier);
|
||||
|
||||
gst_structure_set (out, "drm-format", G_TYPE_STRING, drm_fmt_name, NULL);
|
||||
g_free (drm_fmt_name);
|
||||
} else {
|
||||
gst_structure_set (out, "format", G_TYPE_STRING,
|
||||
gst_video_format_to_string (fmt), NULL);
|
||||
}
|
||||
#else
|
||||
gst_structure_set (out, "format", G_TYPE_STRING,
|
||||
gst_video_format_to_string (fmt), NULL);
|
||||
#endif
|
||||
|
||||
ret = gst_caps_new_full (out, NULL);
|
||||
gst_caps_set_features_simple (ret, features);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fixate_output_frame_size (GstMsdkVPP * thiz, GstVideoInfo * vinfo,
|
||||
GstStructure * outs)
|
||||
|
@ -529,27 +655,23 @@ static GstCaps *
|
|||
_get_preferred_src_caps (GstMsdkVPP * thiz, GstVideoInfo * vinfo,
|
||||
GstCaps * srccaps)
|
||||
{
|
||||
GstStructure *structure;
|
||||
GstCaps *outcaps;
|
||||
GstStructure *structure = NULL;
|
||||
GstCaps *outcaps, *fixate_caps;
|
||||
|
||||
structure = gst_caps_get_structure (srccaps, 0);
|
||||
/* Fixate the format */
|
||||
fixate_caps = fixate_output_format (thiz, vinfo, srccaps);
|
||||
if (!fixate_caps)
|
||||
goto fixate_failed;
|
||||
|
||||
structure = gst_caps_get_structure (fixate_caps, 0);
|
||||
/* make a copy */
|
||||
structure = gst_structure_copy (structure);
|
||||
gst_caps_unref (fixate_caps);
|
||||
|
||||
if (thiz->keep_aspect)
|
||||
gst_structure_set (structure, "pixel-aspect-ratio", GST_TYPE_FRACTION, 1,
|
||||
1, NULL);
|
||||
|
||||
/* Fixate the format */
|
||||
if (gst_video_is_dma_drm_caps (srccaps) &&
|
||||
gst_structure_has_field (structure, "drm-format")) {
|
||||
if (!gst_structure_fixate_field (structure, "drm-format"))
|
||||
goto fixate_failed;
|
||||
} else if (gst_structure_has_field (structure, "format"))
|
||||
if (!gst_structure_fixate_field (structure, "format"))
|
||||
goto fixate_failed;
|
||||
|
||||
/* Fixate the frame size */
|
||||
if (!fixate_output_frame_size (thiz, vinfo, structure))
|
||||
goto fixate_failed;
|
||||
|
@ -577,7 +699,8 @@ _get_preferred_src_caps (GstMsdkVPP * thiz, GstVideoInfo * vinfo,
|
|||
fixate_failed:
|
||||
{
|
||||
GST_WARNING_OBJECT (thiz, "Could not fixate src caps");
|
||||
gst_structure_free (structure);
|
||||
if (structure)
|
||||
gst_structure_free (structure);
|
||||
return NULL;
|
||||
}
|
||||
interlace_mode_failed:
|
||||
|
|
Loading…
Reference in a new issue