#include "sysdeps.h"
#include <string.h>
+#include "gst/gstutils.h"
#include "gstvaapicompat.h"
#include "gstvaapiutils.h"
#include "gstvaapiimage.h"
return success;
}
+static gboolean
+_image_convert_to_nv12(
+ guint8 *src,
+ guint32 width,
+ guint32 height,
+ GstVaapiImageFormat src_format,
+ guint8 *dest,
+ VAImage *va_image)
+{
+ guint8 *y_src, *u_src, *v_src, *uv_src;
+ guint8 *y_dest, *uv_dest;
+ guint32 ystride, ustride, vstride, uv_stride;
+ guint row, column;
+
+ y_src = src;
+ ystride = GST_ROUND_UP_4(width);
+
+ y_dest = dest + va_image->offsets[0];
+ uv_dest = dest + va_image->offsets[1];
+ g_assert(va_image->num_planes == 2);
+
+ /* copy Y first */
+ for (row = 0; row < height; row++) {
+ memcpy(y_dest, y_src, width);
+ y_src += ystride;
+ y_dest += va_image->pitches[0];
+ }
+
+ switch (src_format) {
+ case GST_VAAPI_IMAGE_NV12: {
+ uv_src = src + ystride*GST_ROUND_UP_2(height);
+ uv_stride = ystride;
+ for (row = 0; row < GST_ROUND_UP_2(height)/2; row++) {
+ memcpy(uv_dest, uv_src, width);
+ uv_src += uv_stride;
+ uv_dest += va_image->pitches[1];
+ }
+ }
+ break;
+
+ case GST_VAAPI_IMAGE_I420: {
+ u_src = src + ystride*GST_ROUND_UP_2(height);
+ ustride = GST_ROUND_UP_8(ystride)/2;
+ v_src = u_src + ustride*GST_ROUND_UP_2(height)/2;
+ vstride = GST_ROUND_UP_8(ystride)/2;
+
+ for (row = 0; row < GST_ROUND_UP_2(height)/2; row++) {
+ for (column = 0; column < width/2; column++) {
+ uv_dest[column*2] = u_src[column];
+ uv_dest[column*2+1] = v_src[column];
+ }
+ u_src += ustride;
+ v_src += vstride;
+ uv_dest += va_image->pitches[1];
+ }
+ }
+ break;
+
+ case GST_VAAPI_IMAGE_YV12:{
+ v_src = src + ystride*GST_ROUND_UP_2(height);
+ vstride = GST_ROUND_UP_8(ystride)/2;
+ u_src = v_src + vstride*GST_ROUND_UP_2(height)/2;
+ ustride = GST_ROUND_UP_8(ystride)/2;
+
+ for (row = 0; row < GST_ROUND_UP_2(height)/2; row++) {
+ for (column = 0; column < width/2; column++) {
+ uv_dest[column*2] = u_src[column];
+ uv_dest[column*2+1] = v_src[column];
+ }
+ u_src += ustride;
+ v_src += vstride;
+ uv_dest += va_image->pitches[1];
+ }
+ }
+ break;
+
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
gboolean
gst_vaapi_convert_buffer_to_image(
GstVaapiImage *image,
- GstBuffer *inbuf) // inbuf : I420
+ GstBuffer *inbuf, // inbuf : I420
+ GstVaapiImageFormat in_format)
{
GstVaapiImagePrivate *priv;
guint width, height;
- guint row, column;
- GstVaapiImageFormat format;
- guint8 *y_src, *u_src, *v_src;
- guint8 *y_dest, *u_dest, *v_dest;
+ GstVaapiImageFormat image_format;
+ gboolean success = TRUE;
priv = image->priv;
gst_vaapi_image_get_size(image, &width, &height);
- format = gst_vaapi_image_get_format(image);
- gst_vaapi_image_map(image);
+ image_format = gst_vaapi_image_get_format(image);
+
+ /* currently only support YUV convert */
+ if ( (in_format != GST_VAAPI_IMAGE_NV12
+ && in_format != GST_VAAPI_IMAGE_YV12
+ && in_format != GST_VAAPI_IMAGE_I420)
+ || (image_format != GST_VAAPI_IMAGE_NV12
+ && image_format != GST_VAAPI_IMAGE_YV12
+ && image_format != GST_VAAPI_IMAGE_I420)
+ )
+ {
+ return FALSE;
+ }
- y_src = GST_BUFFER_DATA(inbuf);
- u_src = y_src + width*height;
- v_src = u_src + (width/2)*(height/2);
- y_dest = priv->image_data + priv->image.offsets[0];
- u_dest = priv->image_data + priv->image.offsets[1];
- v_dest = priv->image_data + priv->image.offsets[2];
+ gst_vaapi_image_map(image);
+ switch (image_format) {
+ case GST_VAAPI_IMAGE_NV12:
+ success = _image_convert_to_nv12(GST_BUFFER_DATA(inbuf),
+ width, height, in_format,
+ priv->image_data,
+ &priv->image);
+ break;
+
+ case GST_VAAPI_IMAGE_I420:
+ case GST_VAAPI_IMAGE_YV12:
+ success = FALSE;
+ break;
- if (format == GST_VAAPI_IMAGE_NV12) {
- for (row = 0; row < height; row++) {
- memcpy(y_dest, y_src, width);
- y_src += width;
- y_dest += priv->image.pitches[0];
- }
- for (row = 0; row < height/2; row++) {
- for (column = 0; column < width/2; column++) {
- u_dest[column*2] = u_src[column];
- u_dest[column*2+1] = v_src[column];
- }
- u_src += width/2;
- v_src += width/2;
- u_dest += priv->image.pitches[1];
- }
+ default:
+ success = FALSE;
+ break;
}
gst_vaapi_image_unmap(image);
- return TRUE;
+
+ return success;
}