vaapipostproc: fix transform caps.

Fix GstBaseTransform::transform_caps() implementation to always return
the complete set of allowed sink pad caps (unfixated) even if the src
pad caps we are getting are fixated. Rationale: there are just so many
possible combinations, and it was wrong to provide a unique set anyway.

As a side effect, this greatly simplifies the ability to derive src pad
caps from fixated sink pad caps.
This commit is contained in:
Gwenole Beauchesne 2013-11-21 15:08:55 +01:00
parent 5a9e169504
commit a3af786c78

View file

@ -905,80 +905,61 @@ gst_vaapipostproc_transform_caps_impl(GstBaseTransform *trans,
GstVideoFormat format; GstVideoFormat format;
GstCaps *out_caps; GstCaps *out_caps;
guint width, height; guint width, height;
gint fps_n, fps_d, par_n, par_d;
if (!gst_caps_is_fixed(caps)) { /* Generate the sink pad caps, that could be fixated afterwards */
out_caps = NULL; if (direction == GST_PAD_SRC) {
if (direction == GST_PAD_SINK) { if (!ensure_allowed_sinkpad_caps(postproc))
/* Generate the allowed set of caps on the src pad */ return NULL;
if (ensure_allowed_srcpad_caps(postproc)) return gst_caps_ref(postproc->allowed_sinkpad_caps);
out_caps = gst_caps_ref(postproc->allowed_srcpad_caps);
}
else {
/* Generate the allowed set of caps on the sink pad */
if (ensure_allowed_sinkpad_caps(postproc))
out_caps = gst_caps_ref(postproc->allowed_sinkpad_caps);
}
return out_caps;
} }
/* Generate the other pad caps, based on the current pad caps, as /* Generate complete set of src pad caps if non-fixated sink pad
specified by the direction argument */ caps are provided */
if (!gst_caps_is_fixed(caps)) {
if (!ensure_allowed_srcpad_caps(postproc))
return NULL;
return gst_caps_ref(postproc->allowed_srcpad_caps);
}
/* Generate the expected src pad caps, from the current fixated
sink pad caps */
if (!gst_video_info_from_caps(&vi, caps)) if (!gst_video_info_from_caps(&vi, caps))
return NULL; return NULL;
format = GST_VIDEO_INFO_FORMAT(&vi); // Set double framerate in interlaced mode
if (format == GST_VIDEO_FORMAT_UNKNOWN) if (is_deinterlace_enabled(postproc, &vi)) {
gint fps_n = GST_VIDEO_INFO_FPS_N(&vi);
gint fps_d = GST_VIDEO_INFO_FPS_D(&vi);
if (!gst_util_fraction_multiply(fps_n, fps_d, 2, 1, &fps_n, &fps_d))
return NULL;
GST_VIDEO_INFO_FPS_N(&vi) = fps_n;
GST_VIDEO_INFO_FPS_D(&vi) = fps_d;
}
// Signal the other pad that we only generate progressive frames
GST_VIDEO_INFO_INTERLACE_MODE(&vi) = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE;
// Update size from user-specified parameters
format = GST_VIDEO_FORMAT_ENCODED;
find_best_size(postproc, &vi, &width, &height);
gst_video_info_set_format(&vi, format, width, height);
/* XXX: gst_video_info_to_caps() from GStreamer 0.10 does not
reconstruct suitable caps for "encoded" video formats */
out_caps = gst_caps_from_string(GST_VAAPI_SURFACE_CAPS_NAME);
if (!out_caps)
return NULL; return NULL;
fps_n = GST_VIDEO_INFO_FPS_N(&vi); gst_caps_set_simple(out_caps,
fps_d = GST_VIDEO_INFO_FPS_D(&vi); "type", G_TYPE_STRING, "vaapi",
if (direction == GST_PAD_SINK) { "opengl", G_TYPE_BOOLEAN, USE_GLX,
if (is_deinterlace_enabled(postproc, &vi)) { "width", G_TYPE_INT, GST_VIDEO_INFO_WIDTH(&vi),
/* Set double framerate in interlaced mode */ "height", G_TYPE_INT, GST_VIDEO_INFO_HEIGHT(&vi),
if (!gst_util_fraction_multiply(fps_n, fps_d, 2, 1, &fps_n, &fps_d)) "framerate", GST_TYPE_FRACTION, GST_VIDEO_INFO_FPS_N(&vi),
return NULL; GST_VIDEO_INFO_FPS_D(&vi),
} "pixel-aspect-ratio", GST_TYPE_FRACTION, GST_VIDEO_INFO_PAR_N(&vi),
format = GST_VIDEO_FORMAT_ENCODED; GST_VIDEO_INFO_PAR_D(&vi),
NULL);
/* Signal the other pad that we generate only progressive frames */
GST_VIDEO_INFO_INTERLACE_MODE(&vi) =
GST_VIDEO_INTERLACE_MODE_PROGRESSIVE;
find_best_size(postproc, &vi, &width, &height);
gst_video_info_set_format(&vi, format, width, height);
}
else {
if (is_deinterlace_enabled(postproc, &vi)) {
/* Set half framerate in interlaced mode */
if (!gst_util_fraction_multiply(fps_n, fps_d, 1, 2, &fps_n, &fps_d))
return NULL;
}
}
if (format != GST_VIDEO_FORMAT_ENCODED) {
out_caps = gst_video_info_to_caps(&vi);
if (!out_caps)
return NULL;
}
else {
/* XXX: gst_video_info_to_caps() from GStreamer 0.10 does not
reconstruct suitable caps for "encoded" video formats */
out_caps = gst_caps_from_string(GST_VAAPI_SURFACE_CAPS_NAME);
if (!out_caps)
return NULL;
par_n = GST_VIDEO_INFO_PAR_N(&vi);
par_d = GST_VIDEO_INFO_PAR_D(&vi);
gst_caps_set_simple(out_caps,
"type", G_TYPE_STRING, "vaapi",
"opengl", G_TYPE_BOOLEAN, USE_GLX,
"width", G_TYPE_INT, GST_VIDEO_INFO_WIDTH(&vi),
"height", G_TYPE_INT, GST_VIDEO_INFO_HEIGHT(&vi),
"framerate", GST_TYPE_FRACTION, fps_n, fps_d,
"pixel-aspect-ratio", GST_TYPE_FRACTION, par_n, par_d,
NULL);
}
gst_caps_set_interlaced(out_caps, &vi); gst_caps_set_interlaced(out_caps, &vi);
return out_caps; return out_caps;