mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-22 08:17:01 +00:00
msdkdec: Enable SFC csc for AVC and HEVC
Decoder SFC will be triggered when default output format is not accept at downstream. One use case below can work without using msdkvpp: "! msdkh265dec ! "video/x-raw,format=BGRA" ! glimagesink", Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1444>
This commit is contained in:
parent
eb742c8ed0
commit
c5f0e075e2
3 changed files with 46 additions and 1 deletions
|
@ -581,10 +581,15 @@ gst_msdkdec_set_src_caps (GstMsdkDec * thiz, gboolean need_allocation)
|
||||||
GstVideoInfo *vinfo;
|
GstVideoInfo *vinfo;
|
||||||
GstVideoAlignment align;
|
GstVideoAlignment align;
|
||||||
GstCaps *allocation_caps = NULL;
|
GstCaps *allocation_caps = NULL;
|
||||||
|
GstCaps *allowed_caps, *temp_caps;
|
||||||
GstVideoFormat format;
|
GstVideoFormat format;
|
||||||
guint width, height;
|
guint width, height;
|
||||||
guint alloc_w, alloc_h;
|
guint alloc_w, alloc_h;
|
||||||
const gchar *format_str;
|
const gchar *format_str;
|
||||||
|
GstStructure *outs;
|
||||||
|
const gchar *out_format;
|
||||||
|
GValue v_format = G_VALUE_INIT;
|
||||||
|
|
||||||
|
|
||||||
/* use display width and display height in output state, which
|
/* use display width and display height in output state, which
|
||||||
* will be used for caps negotiation */
|
* will be used for caps negotiation */
|
||||||
|
@ -603,6 +608,37 @@ gst_msdkdec_set_src_caps (GstMsdkDec * thiz, gboolean need_allocation)
|
||||||
GST_WARNING_OBJECT (thiz, "Failed to find a valid video format");
|
GST_WARNING_OBJECT (thiz, "Failed to find a valid video format");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
#if (MFX_VERSION >= 1022)
|
||||||
|
/* SFC is triggered (for AVC and HEVC) when default output format is not
|
||||||
|
* accepted by downstream.
|
||||||
|
* For SFC csc, need to do the query twice: the first time uses default
|
||||||
|
* color format to query peer pad, empty caps means default format is
|
||||||
|
* not accepted by downstream; then we need the second query to decide
|
||||||
|
* src caps color format and let SFC work. */
|
||||||
|
if (thiz->param.mfx.CodecId == MFX_CODEC_AVC ||
|
||||||
|
thiz->param.mfx.CodecId == MFX_CODEC_HEVC) {
|
||||||
|
temp_caps = gst_pad_query_caps (GST_VIDEO_DECODER (thiz)->srcpad, NULL);
|
||||||
|
temp_caps = gst_caps_make_writable (temp_caps);
|
||||||
|
|
||||||
|
g_value_init (&v_format, G_TYPE_STRING);
|
||||||
|
g_value_set_string (&v_format, gst_video_format_to_string (format));
|
||||||
|
gst_caps_set_value (temp_caps, "format", &v_format);
|
||||||
|
|
||||||
|
if (gst_caps_is_empty (gst_pad_peer_query_caps (GST_VIDEO_DECODER
|
||||||
|
(thiz)->srcpad, temp_caps))) {
|
||||||
|
allowed_caps =
|
||||||
|
gst_pad_get_allowed_caps (GST_VIDEO_DECODER (thiz)->srcpad);
|
||||||
|
outs = gst_caps_get_structure (allowed_caps, 0);
|
||||||
|
out_format = gst_structure_get_string (outs, "format");
|
||||||
|
if (out_format) {
|
||||||
|
format = gst_video_format_from_string (out_format);
|
||||||
|
thiz->sfc = TRUE;
|
||||||
|
}
|
||||||
|
gst_caps_unref (allowed_caps);
|
||||||
|
}
|
||||||
|
gst_caps_unref (temp_caps);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
output_state =
|
output_state =
|
||||||
gst_video_decoder_set_output_state (GST_VIDEO_DECODER (thiz),
|
gst_video_decoder_set_output_state (GST_VIDEO_DECODER (thiz),
|
||||||
|
|
|
@ -54,6 +54,8 @@
|
||||||
GST_DEBUG_CATEGORY_EXTERN (gst_msdkh264dec_debug);
|
GST_DEBUG_CATEGORY_EXTERN (gst_msdkh264dec_debug);
|
||||||
#define GST_CAT_DEFAULT gst_msdkh264dec_debug
|
#define GST_CAT_DEFAULT gst_msdkh264dec_debug
|
||||||
|
|
||||||
|
#define COMMON_FORMAT "{ NV12, BGRA, BGRx }"
|
||||||
|
|
||||||
static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
|
static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
GST_PAD_SINK,
|
GST_PAD_SINK,
|
||||||
GST_PAD_ALWAYS,
|
GST_PAD_ALWAYS,
|
||||||
|
@ -63,6 +65,12 @@ static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
"profile = (string) { high, progressive-high, constrained-high, main, baseline, constrained-baseline }")
|
"profile = (string) { high, progressive-high, constrained-high, main, baseline, constrained-baseline }")
|
||||||
);
|
);
|
||||||
|
|
||||||
|
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
|
||||||
|
GST_PAD_SRC,
|
||||||
|
GST_PAD_ALWAYS,
|
||||||
|
GST_STATIC_CAPS (GST_MSDK_CAPS_STR (COMMON_FORMAT, COMMON_FORMAT))
|
||||||
|
);
|
||||||
|
|
||||||
#define gst_msdkh264dec_parent_class parent_class
|
#define gst_msdkh264dec_parent_class parent_class
|
||||||
G_DEFINE_TYPE (GstMsdkH264Dec, gst_msdkh264dec, GST_TYPE_MSDKDEC);
|
G_DEFINE_TYPE (GstMsdkH264Dec, gst_msdkh264dec, GST_TYPE_MSDKDEC);
|
||||||
|
|
||||||
|
@ -181,6 +189,7 @@ gst_msdkh264dec_class_init (GstMsdkH264DecClass * klass)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
gst_element_class_add_static_pad_template (element_class, &sink_factory);
|
gst_element_class_add_static_pad_template (element_class, &sink_factory);
|
||||||
|
gst_element_class_add_static_pad_template (element_class, &src_factory);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -56,7 +56,7 @@ GST_DEBUG_CATEGORY_EXTERN (gst_msdkh265dec_debug);
|
||||||
#define GST_CAT_DEFAULT gst_msdkh265dec_debug
|
#define GST_CAT_DEFAULT gst_msdkh265dec_debug
|
||||||
|
|
||||||
#define COMMON_FORMAT \
|
#define COMMON_FORMAT \
|
||||||
"{ NV12, P010_10LE, YUY2, Y210, VUYA, Y410, P012_LE, Y212_LE, Y412_LE }"
|
"{ NV12, P010_10LE, YUY2, Y210, VUYA, Y410, P012_LE, Y212_LE, Y412_LE, BGRA, BGRx }"
|
||||||
|
|
||||||
/* TODO: update both sink and src dynamically */
|
/* TODO: update both sink and src dynamically */
|
||||||
static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
|
static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
|
|
Loading…
Reference in a new issue