mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
vdpau: factor out common caps calculation and put it in gstvdputils.[ch]
This commit is contained in:
parent
3545720d7a
commit
da05417b13
5 changed files with 167 additions and 113 deletions
|
@ -20,8 +20,8 @@
|
|||
|
||||
#include "gstvdputils.h"
|
||||
|
||||
GstCaps *
|
||||
gst_vdp_get_video_caps (GstVdpDevice * device, gint chroma_format)
|
||||
static GstCaps *
|
||||
gst_vdp_get_allowed_yuv_caps (GstVdpDevice * device)
|
||||
{
|
||||
GstCaps *caps;
|
||||
gint i;
|
||||
|
@ -32,9 +32,6 @@ gst_vdp_get_video_caps (GstVdpDevice * device, gint chroma_format)
|
|||
VdpBool is_supported;
|
||||
guint32 max_w, max_h;
|
||||
|
||||
if (chroma_format != chroma_types[i])
|
||||
continue;
|
||||
|
||||
status =
|
||||
device->vdp_video_surface_query_capabilities (device->device,
|
||||
chroma_types[i], &is_supported, &max_w, &max_h);
|
||||
|
@ -80,10 +77,154 @@ gst_vdp_get_video_caps (GstVdpDevice * device, gint chroma_format)
|
|||
}
|
||||
|
||||
error:
|
||||
if (gst_caps_is_empty (caps)) {
|
||||
gst_caps_unref (caps);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
GstCaps *
|
||||
gst_vdp_video_to_yuv_caps (GstCaps * caps)
|
||||
{
|
||||
GstCaps *new_caps, *allowed_caps, *result;
|
||||
gint i;
|
||||
GstStructure *structure;
|
||||
const GValue *value;
|
||||
GstVdpDevice *device = NULL;
|
||||
|
||||
new_caps = gst_caps_new_empty ();
|
||||
|
||||
for (i = 0; i < gst_caps_get_size (caps); i++) {
|
||||
gint chroma_type;
|
||||
GSList *fourcc = NULL, *iter;
|
||||
|
||||
structure = gst_caps_get_structure (caps, i);
|
||||
|
||||
if (gst_structure_get_int (structure, "chroma-type", &chroma_type)) {
|
||||
/* calculate fourcc from chroma_type */
|
||||
for (i = 0; i < N_FORMATS; i++) {
|
||||
if (formats[i].chroma_type == chroma_type) {
|
||||
fourcc = g_slist_append (fourcc, GINT_TO_POINTER (formats[i].fourcc));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < N_FORMATS; i++) {
|
||||
fourcc = g_slist_append (fourcc, GINT_TO_POINTER (formats[i].fourcc));
|
||||
}
|
||||
}
|
||||
|
||||
for (iter = fourcc; iter; iter = iter->next) {
|
||||
GstStructure *new_struct = gst_structure_copy (structure);
|
||||
|
||||
gst_structure_set_name (new_struct, "video/x-raw-yuv");
|
||||
gst_structure_remove_field (new_struct, "chroma-type");
|
||||
gst_structure_remove_field (new_struct, "device");
|
||||
gst_structure_set (new_struct, "format", GST_TYPE_FOURCC,
|
||||
GPOINTER_TO_INT (iter->data), NULL);
|
||||
|
||||
gst_caps_append_structure (new_caps, new_struct);
|
||||
}
|
||||
|
||||
g_slist_free (fourcc);
|
||||
}
|
||||
structure = gst_caps_get_structure (caps, 0);
|
||||
|
||||
value = gst_structure_get_value (structure, "device");
|
||||
if (value)
|
||||
device = g_value_get_object (value);
|
||||
|
||||
if (device) {
|
||||
allowed_caps = gst_vdp_get_allowed_yuv_caps (device);
|
||||
result = gst_caps_intersect (new_caps, allowed_caps);
|
||||
|
||||
gst_caps_unref (new_caps);
|
||||
gst_caps_unref (allowed_caps);
|
||||
} else
|
||||
result = new_caps;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
gst_vdp_get_allowed_video_caps (GstVdpDevice * device)
|
||||
{
|
||||
GstCaps *caps;
|
||||
gint i;
|
||||
|
||||
caps = gst_caps_new_empty ();
|
||||
for (i = 0; i < N_CHROMA_TYPES; i++) {
|
||||
VdpStatus status;
|
||||
VdpBool is_supported;
|
||||
guint32 max_w, max_h;
|
||||
|
||||
status =
|
||||
device->vdp_video_surface_query_capabilities (device->device,
|
||||
chroma_types[i], &is_supported, &max_w, &max_h);
|
||||
|
||||
if (status != VDP_STATUS_OK && status != VDP_STATUS_INVALID_CHROMA_TYPE) {
|
||||
GST_ERROR_OBJECT (device,
|
||||
"Could not get query VDPAU video surface capabilites, "
|
||||
"Error returned from vdpau was: %s",
|
||||
device->vdp_get_error_string (status));
|
||||
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (is_supported) {
|
||||
GstCaps *format_caps;
|
||||
|
||||
format_caps = gst_caps_new_simple ("video/x-vdpau-video",
|
||||
"chroma-type", G_TYPE_INT, chroma_types[i],
|
||||
"width", GST_TYPE_INT_RANGE, 1, max_w,
|
||||
"height", GST_TYPE_INT_RANGE, 1, max_h, NULL);
|
||||
gst_caps_append (caps, format_caps);
|
||||
}
|
||||
}
|
||||
|
||||
error:
|
||||
return caps;
|
||||
}
|
||||
|
||||
GstCaps *
|
||||
gst_vdp_yuv_to_video_caps (GstCaps * caps, GstVdpDevice * device)
|
||||
{
|
||||
GstCaps *new_caps, *result;
|
||||
gint i;
|
||||
|
||||
new_caps = gst_caps_copy (caps);
|
||||
for (i = 0; i < gst_caps_get_size (new_caps); i++) {
|
||||
GstStructure *structure = gst_caps_get_structure (new_caps, i);
|
||||
guint32 fourcc;
|
||||
|
||||
if (gst_structure_get_fourcc (structure, "format", &fourcc)) {
|
||||
gint chroma_type = -1;
|
||||
|
||||
/* calculate chroma type from fourcc */
|
||||
for (i = 0; i < N_FORMATS; i++) {
|
||||
if (formats[i].fourcc == fourcc) {
|
||||
chroma_type = formats[i].chroma_type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
gst_structure_remove_field (structure, "format");
|
||||
gst_structure_set (structure, "chroma-type", G_TYPE_INT, chroma_type,
|
||||
NULL);
|
||||
} else
|
||||
gst_structure_set (structure, "chroma-type", GST_TYPE_INT_RANGE, 0, 2,
|
||||
NULL);
|
||||
|
||||
gst_structure_set_name (structure, "video/x-vdpau-video");
|
||||
if (device)
|
||||
gst_structure_set (structure, "device", G_TYPE_OBJECT, device, NULL);
|
||||
}
|
||||
|
||||
if (device) {
|
||||
GstCaps *allowed_caps;
|
||||
|
||||
allowed_caps = gst_vdp_get_allowed_video_caps (device);
|
||||
result = gst_caps_intersect (new_caps, allowed_caps);
|
||||
|
||||
gst_caps_unref (new_caps);
|
||||
gst_caps_unref (allowed_caps);
|
||||
} else
|
||||
result = new_caps;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -76,6 +76,7 @@ static const VdpauFormats formats[N_FORMATS] = {
|
|||
}
|
||||
};
|
||||
|
||||
GstCaps *gst_vdp_get_video_caps (GstVdpDevice *device, gint chroma_format);
|
||||
GstCaps *gst_vdp_video_to_yuv_caps (GstCaps *caps);
|
||||
GstCaps *gst_vdp_yuv_to_video_caps (GstCaps *caps, GstVdpDevice *device);
|
||||
|
||||
#endif /* _GST_VDP_UTILS_H_ */
|
|
@ -51,12 +51,11 @@ GST_STATIC_PAD_TEMPLATE (GST_BASE_TRANSFORM_SINK_NAME,
|
|||
GST_STATIC_CAPS (GST_VDP_VIDEO_CAPS));
|
||||
|
||||
static GstStaticPadTemplate src_template =
|
||||
GST_STATIC_PAD_TEMPLATE (GST_BASE_TRANSFORM_SRC_NAME,
|
||||
GST_STATIC_PAD_TEMPLATE (GST_BASE_TRANSFORM_SRC_NAME,
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("video/x-raw-yuv, "
|
||||
"framerate = (fraction) [ 0, MAX ], "
|
||||
"width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]"));
|
||||
GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420") ";"
|
||||
GST_VIDEO_CAPS_YUV ("YV12") ";" GST_VIDEO_CAPS_YUV ("NV12")));
|
||||
|
||||
#define DEBUG_INIT(bla) \
|
||||
GST_DEBUG_CATEGORY_INIT (gst_vdp_video_yuv_debug, "vdpauvideoyuv", 0, "VDPAU VdpSurface to YUV");
|
||||
|
@ -254,67 +253,15 @@ GstCaps *
|
|||
gst_vdp_video_yuv_transform_caps (GstBaseTransform * trans,
|
||||
GstPadDirection direction, GstCaps * caps)
|
||||
{
|
||||
GstCaps *result = NULL;
|
||||
GstCaps *result;
|
||||
|
||||
if (direction == GST_PAD_SINK) {
|
||||
GstCaps *new_caps, *allowed_caps = NULL;
|
||||
gint i;
|
||||
GstStructure *structure;
|
||||
gint chroma_type;
|
||||
const GValue *value;
|
||||
GstVdpDevice *device = NULL;
|
||||
if (direction == GST_PAD_SINK)
|
||||
result = gst_vdp_video_to_yuv_caps (caps);
|
||||
|
||||
new_caps = gst_caps_new_empty ();
|
||||
else if (direction == GST_PAD_SRC)
|
||||
result = gst_vdp_yuv_to_video_caps (caps, NULL);
|
||||
|
||||
for (i = 0; i < gst_caps_get_size (caps); i++) {
|
||||
GSList *fourcc = NULL, *iter;
|
||||
|
||||
structure = gst_caps_get_structure (caps, i);
|
||||
gst_structure_get_int (structure, "chroma-type", &chroma_type);
|
||||
/* calculate fourcc from chroma_type */
|
||||
for (i = 0; i < N_FORMATS; i++) {
|
||||
if (formats[i].chroma_type == chroma_type) {
|
||||
fourcc = g_slist_append (fourcc, GINT_TO_POINTER (formats[i].fourcc));
|
||||
}
|
||||
}
|
||||
|
||||
for (iter = fourcc; iter; iter = iter->next) {
|
||||
GstStructure *new_struct = gst_structure_copy (structure);
|
||||
|
||||
gst_structure_set_name (new_struct, "video/x-raw-yuv");
|
||||
gst_structure_remove_field (new_struct, "chroma-type");
|
||||
gst_structure_remove_field (new_struct, "device");
|
||||
gst_structure_set (new_struct, "format", GST_TYPE_FOURCC,
|
||||
GPOINTER_TO_INT (iter->data), NULL);
|
||||
|
||||
gst_caps_append_structure (new_caps, new_struct);
|
||||
}
|
||||
|
||||
g_slist_free (fourcc);
|
||||
}
|
||||
structure = gst_caps_get_structure (caps, 0);
|
||||
|
||||
gst_structure_get_int (structure, "chroma-type", &chroma_type);
|
||||
value = gst_structure_get_value (structure, "device");
|
||||
if (value)
|
||||
device = g_value_get_object (value);
|
||||
|
||||
if (device)
|
||||
allowed_caps = gst_vdp_get_video_caps (device, chroma_type);
|
||||
else
|
||||
allowed_caps = gst_static_pad_template_get_caps (&src_template);
|
||||
|
||||
result = gst_caps_intersect (new_caps, allowed_caps);
|
||||
gst_caps_unref (new_caps);
|
||||
gst_caps_unref (allowed_caps);
|
||||
|
||||
GST_LOG ("transformed %" GST_PTR_FORMAT " to %" GST_PTR_FORMAT, caps,
|
||||
result);
|
||||
|
||||
} else if (direction == GST_PAD_SRC) {
|
||||
/* FIXME: upstream negotiation */
|
||||
result = gst_static_pad_template_get_caps (&sink_template);
|
||||
}
|
||||
GST_LOG ("transformed %" GST_PTR_FORMAT " to %" GST_PTR_FORMAT, caps, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -235,44 +235,16 @@ gst_vdp_yuv_video_transform_caps (GstBaseTransform * trans,
|
|||
GstPadDirection direction, GstCaps * caps)
|
||||
{
|
||||
GstVdpYUVVideo *yuv_video = GST_VDP_YUV_VIDEO (trans);
|
||||
GstCaps *result = NULL;
|
||||
GstCaps *result;
|
||||
|
||||
if (direction == GST_PAD_SINK) {
|
||||
gint i;
|
||||
|
||||
/* Intersect with the allowed caps */
|
||||
if (yuv_video->sink_caps)
|
||||
result = gst_caps_intersect (caps, yuv_video->sink_caps);
|
||||
else
|
||||
result = gst_caps_copy (caps);
|
||||
|
||||
for (i = 0; i < gst_caps_get_size (result); i++) {
|
||||
GstStructure *structure = gst_caps_get_structure (result, i);
|
||||
guint32 fourcc;
|
||||
gint chroma_type;
|
||||
|
||||
gst_structure_get_fourcc (structure, "format", &fourcc);
|
||||
/* calculate chroma type from fourcc */
|
||||
for (i = 0; i < N_FORMATS; i++) {
|
||||
if (formats[i].fourcc == fourcc) {
|
||||
chroma_type = formats[i].chroma_type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gst_structure_set_name (structure, "video/x-vdpau-video");
|
||||
gst_structure_remove_field (structure, "format");
|
||||
gst_structure_set (structure, "chroma-type", G_TYPE_INT, chroma_type,
|
||||
"device", G_TYPE_OBJECT, yuv_video->device, NULL);
|
||||
}
|
||||
gst_caps_do_simplify (result);
|
||||
GST_LOG ("transformed %" GST_PTR_FORMAT " to %" GST_PTR_FORMAT, caps,
|
||||
result);
|
||||
result = gst_vdp_yuv_to_video_caps (caps, yuv_video->device);
|
||||
} else if (direction == GST_PAD_SRC) {
|
||||
/* FIXME: upstream negotiation */
|
||||
result = gst_static_pad_template_get_caps (&sink_template);
|
||||
result = gst_vdp_video_to_yuv_caps (caps);
|
||||
}
|
||||
|
||||
GST_LOG ("transformed %" GST_PTR_FORMAT " to %" GST_PTR_FORMAT, caps, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -284,7 +256,6 @@ gst_vdp_yuv_video_start (GstBaseTransform * trans)
|
|||
yuv_video->device = gst_vdp_get_device (yuv_video->display);
|
||||
if (!yuv_video->device)
|
||||
return FALSE;
|
||||
yuv_video->sink_caps = gst_vdp_get_video_caps (yuv_video->device, -1);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -295,8 +266,6 @@ gst_vdp_yuv_video_stop (GstBaseTransform * trans)
|
|||
GstVdpYUVVideo *yuv_video = GST_VDP_YUV_VIDEO (trans);
|
||||
|
||||
g_object_unref (yuv_video->device);
|
||||
gst_caps_unref (yuv_video->sink_caps);
|
||||
yuv_video->sink_caps = NULL;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -390,7 +359,5 @@ gst_vdp_yuv_video_class_init (GstVdpYUVVideoClass * klass)
|
|||
static void
|
||||
gst_vdp_yuv_video_init (GstVdpYUVVideo * yuv_video, GstVdpYUVVideoClass * klass)
|
||||
{
|
||||
yuv_video->sink_caps = NULL;
|
||||
|
||||
yuv_video->display = NULL;
|
||||
}
|
||||
|
|
|
@ -41,8 +41,6 @@ typedef struct _GstVdpYUVVideoClass GstVdpYUVVideoClass;
|
|||
struct _GstVdpYUVVideo {
|
||||
GstBaseTransform trans;
|
||||
|
||||
GstCaps *sink_caps;
|
||||
|
||||
gchar *display;
|
||||
GstVdpDevice *device;
|
||||
|
||||
|
|
Loading…
Reference in a new issue