mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-11 06:11:27 +00:00
vdpau: add functions to GstVdpOutputBuffer needed for rgb download
This commit is contained in:
parent
64601993c9
commit
4dd36435a7
2 changed files with 198 additions and 9 deletions
|
@ -51,6 +51,10 @@ gst_vdp_output_buffer_new (GstVdpDevice * device, VdpRGBAFormat rgba_format,
|
|||
(GstVdpOutputBuffer *) gst_mini_object_new (GST_TYPE_VDP_OUTPUT_BUFFER);
|
||||
|
||||
buffer->device = g_object_ref (device);
|
||||
buffer->rgba_format = rgba_format;
|
||||
buffer->width = width;
|
||||
buffer->height = height;
|
||||
|
||||
buffer->surface = surface;
|
||||
|
||||
return buffer;
|
||||
|
@ -133,8 +137,8 @@ GstVdpOutputBufferFormats rgba_formats[] = {
|
|||
{VDP_RGBA_FORMAT_A8,
|
||||
GST_STATIC_CAPS ("video/x-raw-rgb, "
|
||||
"bpp = (int)8, "
|
||||
"depth = (int)0, "
|
||||
"endianness = G_BIG_ENDIAN, "
|
||||
"depth = (int)8, "
|
||||
"endianness = (int)4321, "
|
||||
"red_mask = (int)0x00, "
|
||||
"green_mask = (int)0x00, "
|
||||
"blue_mask = (int)0x00, " "alpha_mask = (int)0xff")},
|
||||
|
@ -142,7 +146,7 @@ GstVdpOutputBufferFormats rgba_formats[] = {
|
|||
GST_STATIC_CAPS ("video/x-raw-rgb, "
|
||||
"bpp = (int)32, "
|
||||
"depth = (int)30, "
|
||||
"endianness = G_BIG_ENDIAN, "
|
||||
"endianness = (int)4321, "
|
||||
"red_mask = (int)0x000003fc, "
|
||||
"green_mask = (int)0x003ff000, "
|
||||
"blue_mask = (int)0xffc00000, " "alpha_mask = (int)0x00000003")},
|
||||
|
@ -150,7 +154,7 @@ GstVdpOutputBufferFormats rgba_formats[] = {
|
|||
GST_STATIC_CAPS ("video/x-raw-rgb, "
|
||||
"bpp = (int)32, "
|
||||
"depth = (int)24, "
|
||||
"endianness = G_BIG_ENDIAN, "
|
||||
"endianness = (int)4321, "
|
||||
"red_mask = (int)0x0000ff00, "
|
||||
"green_mask = (int)0x00ff0000, "
|
||||
"blue_mask = (int)0xff000000, " "alpha_mask = (int)0x000000ff")},
|
||||
|
@ -158,7 +162,7 @@ GstVdpOutputBufferFormats rgba_formats[] = {
|
|||
GST_STATIC_CAPS ("video/x-raw-rgb, "
|
||||
"bpp = (int)32, "
|
||||
"depth = (int)30, "
|
||||
"endianness = G_BIG_ENDIAN, "
|
||||
"endianness = (int)4321, "
|
||||
"red_mask = (int)0xffc00000, "
|
||||
"green_mask = (int)0x003ff000, "
|
||||
"blue_mask = (int)0x000003fc, " "alpha_mask = (int)0x00000003")},
|
||||
|
@ -166,25 +170,57 @@ GstVdpOutputBufferFormats rgba_formats[] = {
|
|||
GST_STATIC_CAPS ("video/x-raw-rgb, "
|
||||
"bpp = (int)32, "
|
||||
"depth = (int)24, "
|
||||
"endianness = G_BIG_ENDIAN"
|
||||
"endianness = (int)4321, "
|
||||
"red_mask = (int)0xff000000, "
|
||||
"green_mask = (int)0x00ff0000, "
|
||||
"blue_mask = (int)0x0000ff00, " "alpha_mask = (int)0x000000ff")},
|
||||
};
|
||||
|
||||
int n_rgba_formats = G_N_ELEMENTS (rgba_formats);
|
||||
|
||||
GstCaps *
|
||||
gst_vdp_output_buffer_get_template_caps ()
|
||||
{
|
||||
GstCaps *caps, *rgb_caps;
|
||||
gint i;
|
||||
|
||||
caps = gst_caps_new_empty ();
|
||||
rgb_caps = gst_caps_new_empty ();
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (rgba_formats); i++) {
|
||||
GstCaps *format_caps;
|
||||
|
||||
format_caps = gst_caps_new_simple ("video/x-vdpau-output",
|
||||
"rgba-format", G_TYPE_INT, rgba_formats[i].format,
|
||||
"width", GST_TYPE_INT_RANGE, 1, 8192,
|
||||
"height", GST_TYPE_INT_RANGE, 1, 8192, NULL);
|
||||
gst_caps_append (caps, format_caps);
|
||||
|
||||
format_caps = gst_static_caps_get (&rgba_formats[i].caps);
|
||||
format_caps = gst_caps_copy (format_caps);
|
||||
gst_caps_set_simple (format_caps,
|
||||
"width", GST_TYPE_INT_RANGE, 1, 8192,
|
||||
"height", GST_TYPE_INT_RANGE, 1, 8192, NULL);
|
||||
gst_caps_append (rgb_caps, format_caps);
|
||||
|
||||
}
|
||||
|
||||
gst_caps_append (caps, rgb_caps);
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
GstCaps *
|
||||
gst_vdp_output_buffer_get_allowed_caps (GstVdpDevice * device)
|
||||
{
|
||||
GstCaps *caps;
|
||||
GstCaps *caps, *rgb_caps;
|
||||
gint i;
|
||||
|
||||
g_return_val_if_fail (GST_IS_VDP_DEVICE (device), NULL);
|
||||
|
||||
caps = gst_caps_new_empty ();
|
||||
rgb_caps = gst_caps_new_empty ();
|
||||
|
||||
for (i = 0; i < n_rgba_formats; i++) {
|
||||
for (i = 0; i < G_N_ELEMENTS (rgba_formats); i++) {
|
||||
VdpStatus status;
|
||||
VdpBool is_supported;
|
||||
guint max_w, max_h;
|
||||
|
@ -208,10 +244,155 @@ gst_vdp_output_buffer_get_allowed_caps (GstVdpDevice * device)
|
|||
"width", GST_TYPE_INT_RANGE, 1, max_w,
|
||||
"height", GST_TYPE_INT_RANGE, 1, max_h, NULL);
|
||||
gst_caps_append (caps, format_caps);
|
||||
|
||||
format_caps = gst_static_caps_get (&rgba_formats[i].caps);
|
||||
format_caps = gst_caps_copy (format_caps);
|
||||
gst_caps_set_simple (format_caps,
|
||||
"width", GST_TYPE_INT_RANGE, 1, 8192,
|
||||
"height", GST_TYPE_INT_RANGE, 1, 8192, NULL);
|
||||
gst_caps_append (rgb_caps, format_caps);
|
||||
}
|
||||
}
|
||||
|
||||
gst_caps_append (caps, rgb_caps);
|
||||
|
||||
error:
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_vdp_caps_to_rgba_format (GstCaps * caps, VdpRGBAFormat * rgba_format)
|
||||
{
|
||||
GstStructure *structure;
|
||||
gint c_bpp, c_depth, c_endianness, c_red_mask, c_green_mask, c_blue_mask,
|
||||
c_alpha_mask;
|
||||
|
||||
gint i;
|
||||
|
||||
g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
|
||||
|
||||
if (!gst_caps_is_fixed (caps))
|
||||
return FALSE;
|
||||
|
||||
structure = gst_caps_get_structure (caps, 0);
|
||||
if (!gst_structure_has_name (structure, "video/x-raw-rgb"))
|
||||
return FALSE;
|
||||
|
||||
if (!gst_structure_get_int (structure, "bpp", &c_bpp) ||
|
||||
!gst_structure_get_int (structure, "depth", &c_depth) ||
|
||||
!gst_structure_get_int (structure, "endianness", &c_endianness) ||
|
||||
!gst_structure_get_int (structure, "red_mask", &c_red_mask) ||
|
||||
!gst_structure_get_int (structure, "green_mask", &c_green_mask) ||
|
||||
!gst_structure_get_int (structure, "blue_mask", &c_blue_mask) ||
|
||||
!gst_structure_get_int (structure, "alpha_mask", &c_alpha_mask))
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (rgba_formats); i++) {
|
||||
gint bpp, depth, endianness, red_mask, green_mask, blue_mask, alpha_mask;
|
||||
|
||||
GstCaps *rgb_caps = gst_static_caps_get (&rgba_formats[i].caps);
|
||||
structure = gst_caps_get_structure (rgb_caps, 0);
|
||||
|
||||
gst_structure_get_int (structure, "bpp", &bpp);
|
||||
gst_structure_get_int (structure, "depth", &depth);
|
||||
gst_structure_get_int (structure, "endianness", &endianness);
|
||||
gst_structure_get_int (structure, "red_mask", &red_mask);
|
||||
gst_structure_get_int (structure, "green_mask", &green_mask);
|
||||
gst_structure_get_int (structure, "blue_mask", &blue_mask);
|
||||
gst_structure_get_int (structure, "alpha_mask", &alpha_mask);
|
||||
|
||||
if (c_bpp == bpp && c_depth == depth && c_endianness == endianness &&
|
||||
c_red_mask == red_mask && c_green_mask == green_mask &&
|
||||
c_blue_mask == blue_mask && c_alpha_mask == alpha_mask) {
|
||||
gst_caps_unref (rgb_caps);
|
||||
*rgba_format = rgba_formats[i].format;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gst_caps_unref (rgb_caps);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_vdp_output_buffer_calculate_size (GstVdpOutputBuffer * output_buf,
|
||||
guint * size)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_VDP_OUTPUT_BUFFER (output_buf), FALSE);
|
||||
|
||||
switch (output_buf->rgba_format) {
|
||||
case VDP_RGBA_FORMAT_A8:
|
||||
{
|
||||
*size = output_buf->width * output_buf->height;
|
||||
break;
|
||||
}
|
||||
|
||||
case VDP_RGBA_FORMAT_B10G10R10A2:
|
||||
case VDP_RGBA_FORMAT_B8G8R8A8:
|
||||
case VDP_RGBA_FORMAT_R10G10B10A2:
|
||||
case VDP_RGBA_FORMAT_R8G8B8A8:
|
||||
{
|
||||
*size = output_buf->width * output_buf->height * 4;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_vdp_output_buffer_download (GstVdpOutputBuffer * output_buf,
|
||||
GstBuffer * outbuf)
|
||||
{
|
||||
guint8 *data[1];
|
||||
guint32 stride[1];
|
||||
GstVdpDevice *device;
|
||||
VdpOutputSurface surface;
|
||||
VdpStatus status;
|
||||
|
||||
g_return_val_if_fail (GST_IS_VDP_OUTPUT_BUFFER (output_buf), FALSE);
|
||||
|
||||
switch (output_buf->rgba_format) {
|
||||
case VDP_RGBA_FORMAT_A8:
|
||||
{
|
||||
stride[0] = output_buf->width;
|
||||
break;
|
||||
}
|
||||
|
||||
case VDP_RGBA_FORMAT_B10G10R10A2:
|
||||
case VDP_RGBA_FORMAT_B8G8R8A8:
|
||||
case VDP_RGBA_FORMAT_R10G10B10A2:
|
||||
case VDP_RGBA_FORMAT_R8G8B8A8:
|
||||
{
|
||||
stride[0] = output_buf->width * 4;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
device = output_buf->device;
|
||||
surface = output_buf->surface;
|
||||
data[0] = GST_BUFFER_DATA (outbuf);
|
||||
|
||||
GST_LOG_OBJECT (output_buf, "Entering vdp_output_surface_get_bits_native");
|
||||
status =
|
||||
device->vdp_output_surface_get_bits_native (surface, NULL, (void *) data,
|
||||
stride);
|
||||
GST_LOG_OBJECT (output_buf,
|
||||
"Got status %d from vdp_output_get_bits_native", status);
|
||||
if (G_UNLIKELY (status != VDP_STATUS_OK)) {
|
||||
GST_ERROR_OBJECT (output_buf,
|
||||
"Couldn't get data from vdpau, Error returned from vdpau was: %s",
|
||||
device->vdp_get_error_string (status));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -35,6 +35,9 @@ struct _GstVdpOutputBuffer {
|
|||
GstBuffer buffer;
|
||||
|
||||
GstVdpDevice *device;
|
||||
VdpRGBAFormat rgba_format;
|
||||
gint width, height;
|
||||
|
||||
VdpOutputSurface surface;
|
||||
};
|
||||
|
||||
|
@ -42,7 +45,12 @@ GType gst_vdp_output_buffer_get_type (void);
|
|||
|
||||
GstVdpOutputBuffer* gst_vdp_output_buffer_new (GstVdpDevice * device, VdpRGBAFormat rgba_format, gint width, gint height);
|
||||
|
||||
GstCaps *gst_vdp_output_buffer_get_template_caps ();
|
||||
GstCaps *gst_vdp_output_buffer_get_allowed_caps (GstVdpDevice *device);
|
||||
gboolean gst_vdp_caps_to_rgba_format (GstCaps *caps, VdpRGBAFormat *rgba_format);
|
||||
|
||||
gboolean gst_vdp_output_buffer_calculate_size (GstVdpOutputBuffer *output_buf, guint *size);
|
||||
gboolean gst_vdp_output_buffer_download (GstVdpOutputBuffer *output_buf, GstBuffer *outbuf);
|
||||
|
||||
#define GST_VDP_OUTPUT_CAPS \
|
||||
"video/x-vdpau-output, " \
|
||||
|
|
Loading…
Reference in a new issue