mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
msdkdec: Fix to not trigger SFC scaling when vpp at downstream
When there is vpp scaling downstream, we need to make sure SFC is not triggered because vpp may fall into passthrough mode which causes the decoder negotiation to create src caps with vpp scaled width/height. This patch includes bitstream's original size in first query with downstream in gst_msdkdec_src_caps, which is the same for what we do for color format in this query. This is to ensure SFC scaling starts to work only when downstream directly asks for a different size instead of through vpp. Note that here SFC scaling follows the same behavior as msdkvpp: if user only changes width or height, e.g. dec ! video/x-raw,width=xx !, the height will be modified to the value which fits the original DAR. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1838>
This commit is contained in:
parent
89a5cae89b
commit
c9aa529484
1 changed files with 55 additions and 26 deletions
|
@ -612,10 +612,13 @@ gst_msdkdec_set_src_caps (GstMsdkDec * thiz, gboolean need_allocation)
|
|||
guint width, height;
|
||||
guint alloc_w, alloc_h;
|
||||
int out_width = 0, out_height = 0;
|
||||
gint dar_n = -1, dar_d = -1;
|
||||
const gchar *format_str;
|
||||
GstStructure *outs = NULL;
|
||||
const gchar *out_format;
|
||||
GValue v_format = G_VALUE_INIT;
|
||||
GValue v_width = G_VALUE_INIT;
|
||||
GValue v_height = G_VALUE_INIT;
|
||||
|
||||
/* use display width and display height in output state, which
|
||||
* will be used for caps negotiation */
|
||||
|
@ -638,53 +641,73 @@ gst_msdkdec_set_src_caps (GstMsdkDec * thiz, gboolean need_allocation)
|
|||
/* SFC is triggered (for AVC and HEVC) when default output format is not
|
||||
* accepted by downstream or when downstream requests for a smaller
|
||||
* resolution (i.e. SFC supports down-scaling)
|
||||
* 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. */
|
||||
* Here we need to do the query twice: the first time uses default color
|
||||
* format and bitstream's original size to query peer pad, empty caps
|
||||
* means default format and/or size are not accepted by downstream;
|
||||
* then we need the second query to decide src caps' color format and size,
|
||||
* 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_init (&v_width, G_TYPE_INT);
|
||||
g_value_init (&v_height, G_TYPE_INT);
|
||||
|
||||
g_value_set_string (&v_format, gst_video_format_to_string (format));
|
||||
g_value_set_int (&v_width, width);
|
||||
g_value_set_int (&v_height, height);
|
||||
|
||||
gst_caps_set_value (temp_caps, "format", &v_format);
|
||||
gst_caps_set_value (temp_caps, "width", &v_width);
|
||||
gst_caps_set_value (temp_caps, "height", &v_height);
|
||||
|
||||
if (gst_caps_is_empty (gst_pad_peer_query_caps (GST_VIDEO_DECODER
|
||||
(thiz)->srcpad, temp_caps))) {
|
||||
if (!gst_util_fraction_multiply (width, height,
|
||||
GST_VIDEO_INFO_PAR_N (&thiz->input_state->info),
|
||||
GST_VIDEO_INFO_PAR_D (&thiz->input_state->info),
|
||||
&dar_n, &dar_d)) {
|
||||
GST_ERROR_OBJECT (thiz, "Error to calculate the output scaled size");
|
||||
gst_caps_unref (temp_caps);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
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");
|
||||
gst_structure_get_int (outs, "width", &out_width);
|
||||
gst_structure_get_int (outs, "height", &out_height);
|
||||
|
||||
if (out_format) {
|
||||
format = gst_video_format_from_string (out_format);
|
||||
thiz->sfc = TRUE;
|
||||
}
|
||||
|
||||
if (!out_width && !out_height) {
|
||||
out_width = width;
|
||||
out_height = height;
|
||||
} else {
|
||||
/* When user does not set out_width, fill it to fit DAR */
|
||||
if (!out_width)
|
||||
out_width = gst_util_uint64_scale (out_height, dar_n, dar_d);
|
||||
/* When user does not set out_height, fill it to fit DAR */
|
||||
if (!out_height)
|
||||
out_height = gst_util_uint64_scale (out_width, dar_d, dar_n);
|
||||
|
||||
if (out_width > width || out_height > height)
|
||||
goto sfc_error;
|
||||
else if (out_width < width || out_height < height) {
|
||||
width = out_width;
|
||||
height = out_height;
|
||||
thiz->sfc = TRUE;
|
||||
}
|
||||
}
|
||||
gst_caps_unref (allowed_caps);
|
||||
}
|
||||
gst_caps_unref (temp_caps);
|
||||
|
||||
/* SFC scaling, need to check if downstream asking for a different resolution */
|
||||
if (!allowed_caps) {
|
||||
allowed_caps =
|
||||
gst_pad_get_allowed_caps (GST_VIDEO_DECODER (thiz)->srcpad);
|
||||
outs = gst_caps_get_structure (allowed_caps, 0);
|
||||
}
|
||||
|
||||
gst_structure_get_int (outs, "width", &out_width);
|
||||
gst_structure_get_int (outs, "height", &out_height);
|
||||
gst_caps_unref (allowed_caps);
|
||||
|
||||
if (out_width && out_height && (out_width != width || out_height != height)) {
|
||||
if (out_width > width || out_height > height)
|
||||
GST_WARNING_OBJECT (thiz, "Decoder SFC cannot do up-scaling");
|
||||
else {
|
||||
GST_LOG_OBJECT (thiz, "Decoder SFC is doing down-scaling");
|
||||
thiz->sfc = TRUE;
|
||||
width = out_width;
|
||||
height = out_height;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -746,6 +769,12 @@ gst_msdkdec_set_src_caps (GstMsdkDec * thiz, gboolean need_allocation)
|
|||
gst_video_codec_state_unref (output_state);
|
||||
|
||||
return TRUE;
|
||||
|
||||
sfc_error:
|
||||
GST_ERROR_OBJECT (thiz, "Decoder SFC cannot do up-scaling");
|
||||
gst_caps_unref (allowed_caps);
|
||||
gst_caps_unref (temp_caps);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
Loading…
Reference in a new issue