return success;
}
-static gboolean
-_image_convert_to_nv12(
- guint8 *src,
- guint32 width,
- guint32 height,
- guint32 src_format,
- guint8 *dest,
- VAImage *va_image)
+static void
+_yuv411_to_nv12(
+ const guint8 *y_src,
+ guint32 y_src_stride,
+ const guint8 *u_src,
+ guint32 u_src_stride,
+ const guint8 *v_src,
+ guint32 v_src_stride,
+ guint8 *y_dest,
+ guint32 y_dest_stride,
+ guint8 *uv_dest,
+ guint32 uv_dest_stride,
+ guint32 width,
+ guint32 height
+)
{
- 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 */
- if (GST_VAAPI_IMAGE_NV12 == src_format
- || GST_VAAPI_IMAGE_I420 == src_format
- || GST_VAAPI_IMAGE_YV12 == src_format)
- {
- 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;
+ guint32 row, column;
+ guint32 uv_height;
- for (row = 0; row < GST_ROUND_UP_2(height)/2; row++) {
+ memcpy_pic(y_dest, y_dest_stride, y_src, y_src_stride, width, height);
+ uv_height = GST_ROUND_UP_2(height)/2;
+ for (row = 0; row < uv_height; row++) {
for (column = 0; column < width/2; column++) {
- uv_dest[column*2] = u_src[column];
- uv_dest[column*2+1] = v_src[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];
- }
+ u_src += u_src_stride;
+ v_src += v_src_stride;
+ uv_dest += uv_dest_stride;
}
- 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;
+static void
+_nv12_to_yuv411(
+ const guint8 *y_src,
+ guint32 y_src_stride,
+ const guint8 *uv_src,
+ guint32 uv_src_stride,
+ guint8 *y_dest,
+ guint32 y_dest_stride,
+ guint8 *u_dest,
+ guint32 u_dest_stride,
+ guint8 *v_dest,
+ guint32 v_dest_stride,
+ guint32 width,
+ guint32 height
+)
+{
+ guint32 row, column;
+ guint32 uv_height;
- for (row = 0; row < GST_ROUND_UP_2(height)/2; row++) {
+ memcpy_pic(y_dest, y_dest_stride, y_src, y_src_stride, width, height);
+ uv_height = GST_ROUND_UP_2(height)/2;
+ for (row = 0; row < uv_height; row++) {
for (column = 0; column < width/2; column++) {
- uv_dest[column*2] = u_src[column];
- uv_dest[column*2+1] = v_src[column];
+ u_dest[column] = uv_src[column*2];
+ v_dest[column] = uv_src[column*2+1];
}
- u_src += ustride;
- v_src += vstride;
- uv_dest += va_image->pitches[1];
- }
+ uv_src += uv_src_stride;
+ u_dest += u_dest_stride;
+ v_dest += v_dest_stride;
}
- break;
-
- case GST_MAKE_FOURCC('Y', 'U', 'Y', '2'): {
- const guint8 *y_next_src;
- guint8 *y_next_dest;
- ystride = GST_ROUND_UP_2(width)*2;
- for (row = 0; row < height/2; row++) {
- y_next_src = y_src + ystride;
- y_next_dest = y_dest + va_image->pitches[0];
+}
+
+static void
+_yuy2_to_yuv411(
+ const guint8 *yuv_src,
+ guint32 yuv_src_stride,
+ guint8 *y_dest,
+ guint32 y_dest_stride,
+ guint8 *u_dest,
+ guint32 u_dest_stride,
+ guint8 *v_dest,
+ guint32 v_dest_stride,
+ gboolean uv_interlaced,
+ guint32 width,
+ guint32 height
+)
+{
+ guint32 row, column;
+ const guint8 *yuv_next_src;
+ guint8 *y_next_dest;
+ guint32 interval;
+
+ interval = uv_interlaced ? 2 : 1;
+ for (row = 0; row < height/2; row++) {
+ yuv_next_src = yuv_src + yuv_src_stride;
+ y_next_dest = y_dest + y_dest_stride;
for (column = 0; column < width/2; column++) {
- y_dest[column*2] = y_src[column*4];
- y_dest[column*2+1] = y_src[column*4+2];
- y_next_dest[column*2] = y_next_src[column*4];
- y_next_dest[column*2+1] = y_next_src[column*4+2];
- uv_dest[column*2] = (y_src[column*4+1] + y_next_src[column*4+1])>>1;
- uv_dest[column*2+1] = (y_src[column*4+3] + y_next_src[column*4+3])>>1;
+ y_dest[column*2] = yuv_src[column*4];
+ y_dest[column*2+1] = yuv_src[column*4+2];
+ y_next_dest[column*2] = yuv_next_src[column*4];
+ y_next_dest[column*2+1] = yuv_next_src[column*4+2];
+ u_dest[column*interval] = ((yuv_src[column*4+1] + yuv_next_src[column*4+1])>>1);
+ v_dest[column*interval] = ((yuv_src[column*4+3] + yuv_next_src[column*4+3])>>1);
}
- y_src = y_next_src + ystride;
- y_dest = y_next_dest + va_image->pitches[0];
- uv_dest += va_image->pitches[1];
- }
- /* odd line */
- if (height%2) {
- y_next_dest = y_dest + va_image->pitches[0];
+ yuv_src = yuv_next_src + yuv_src_stride;
+ y_dest = y_next_dest + y_dest_stride;
+ u_dest += u_dest_stride;
+ v_dest += v_dest_stride;
+ }
+
+ /* odd line */
+ if (height%2) {
for (column = 0; column < width/2; column++) {
- y_dest[column*2] = y_src[column*4];
- y_dest[column*2+1] = y_src[column*4+2];
- y_next_dest[column*2] = y_src[column*4];
- y_next_dest[column*2+1] = y_src[column*4+2];
- uv_dest[column*2] = y_src[column*4+1];
- uv_dest[column*2+1] = y_src[column*4+3];
+ y_dest[column*2] = yuv_src[column*4];
+ y_dest[column*2+1] = yuv_src[column*4+2];
+ u_dest[column*interval] = yuv_src[column*4+1];
+ v_dest[column*interval] = yuv_src[column*4+3];
}
- }
}
- break;
- default:
- return FALSE;
- }
- return TRUE;
+}
+
+static gboolean
+_image_convert_to_nv12(
+ const guint8 *src,
+ guint32 width,
+ guint32 height,
+ guint32 src_format,
+ guint8 *y_dest,
+ guint32 y_dest_stride,
+ guint8 *uv_dest,
+ guint32 uv_dest_stride
+)
+{
+ const guint8 *y_src, *u_src, *v_src, *uv_src;
+ guint32 ystride, ustride, vstride, uv_stride;
+
+ switch (src_format) {
+ case GST_MAKE_FOURCC('N','V','1','2'): {
+ y_src = src;
+ ystride = GST_ROUND_UP_4(width);
+ uv_src = src + ystride*GST_ROUND_UP_2(height);
+ uv_stride = ystride;
+ memcpy_pic(y_dest, y_dest_stride, y_src, ystride, width, height);
+ memcpy_pic(uv_dest, uv_dest_stride, uv_src, uv_stride,
+ width, GST_ROUND_UP_2(height)/2);
+ break;
+ }
+
+ case GST_MAKE_FOURCC('I','4','2','0'): {
+ y_src = src;
+ ystride = GST_ROUND_UP_4(width);
+ 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;
+
+ _yuv411_to_nv12(y_src, ystride, u_src, ustride, v_src, vstride,
+ y_dest, y_dest_stride,
+ uv_dest, uv_dest_stride,
+ width, height);
+ break;
+ }
+
+ case GST_MAKE_FOURCC('Y','V','1','2'):{
+ y_src = src;
+ ystride = GST_ROUND_UP_4(width);
+ 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;
+
+ _yuv411_to_nv12(y_src, ystride, u_src, ustride, v_src, vstride,
+ y_dest, y_dest_stride, uv_dest, uv_dest_stride,
+ width, height);
+ break;
+ }
+
+ case GST_MAKE_FOURCC('Y', 'U', 'Y', '2'): {
+ y_src = src;
+ ystride = GST_ROUND_UP_2(width)*2;
+ _yuy2_to_yuv411(y_src, ystride,
+ y_dest, y_dest_stride,
+ uv_dest, uv_dest_stride,
+ uv_dest+1, uv_dest_stride,
+ TRUE,
+ width, height);
+ break;
+ }
+
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static gboolean
+_image_convert_to_yuv411(
+ const guint8 *src,
+ guint32 width,
+ guint32 height,
+ guint32 src_format,
+ guint8 *y_dest,
+ guint32 y_dest_stride,
+ guint8 *u_dest,
+ guint32 u_dest_stride,
+ guint8 *v_dest,
+ guint32 v_dest_stride
+)
+{
+ const guint8 *y_src, *u_src, *v_src, *uv_src;
+ guint32 ystride, ustride, vstride, uv_stride;
+
+ switch (src_format) {
+ case GST_MAKE_FOURCC('N','V','1','2'): {
+ y_src = src;
+ ystride = GST_ROUND_UP_4(width);
+ uv_src = src + ystride*GST_ROUND_UP_2(height);
+ uv_stride = ystride;
+ _nv12_to_yuv411(y_src, ystride, uv_src, uv_stride,
+ y_dest, y_dest_stride,
+ u_dest, u_dest_stride,
+ v_dest, v_dest_stride,
+ width, height);
+ break;
+ }
+
+ case GST_MAKE_FOURCC('I','4','2','0'):
+ case GST_MAKE_FOURCC('Y','V','1','2'):{
+ y_src = src;
+ ystride = GST_ROUND_UP_4(width);
+ if (GST_MAKE_FOURCC('I','4','2','0') == src_format) {
+ 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;
+ } else {
+ 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;
+ }
+
+ memcpy_pic(y_dest, y_dest_stride, y_src, ystride, width, height);
+ memcpy_pic(u_dest, u_dest_stride, u_src, ustride, width/2, GST_ROUND_UP_2(height)/2);
+ memcpy_pic(v_dest, v_dest_stride, v_src, vstride, width/2, GST_ROUND_UP_2(height)/2);
+ break;
+ }
+
+ case GST_MAKE_FOURCC('Y', 'U', 'Y', '2'): {
+ y_src = src;
+ ystride = GST_ROUND_UP_2(width)*2;
+ _yuy2_to_yuv411(y_src, ystride,
+ y_dest, y_dest_stride,
+ u_dest, u_dest_stride,
+ v_dest, v_dest_stride,
+ FALSE,
+ width, height);
+ break;
+ }
+
+ default:
+ return FALSE;
+ }
+ return TRUE;
}
GstBuffer *inbuf, // inbuf : I420
guint32 in_format)
{
- GstVaapiImagePrivate *priv;
- guint width, height;
- GstVaapiImageFormat image_format;
- gboolean success = TRUE;
-
- priv = image->priv;
- gst_vaapi_image_get_size(image, &width, &height);
- 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
- && in_format != GST_MAKE_FOURCC('Y', 'U', 'Y', '2'))
- || (image_format != GST_VAAPI_IMAGE_NV12
- && image_format != GST_VAAPI_IMAGE_YV12
- && image_format != GST_VAAPI_IMAGE_I420)
- )
- {
- return FALSE;
- }
-
-
- 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;
+ GstVaapiImagePrivate *priv;
+ guint width, height;
+ GstVaapiImageFormat image_format;
+ gboolean success = TRUE;
- case GST_VAAPI_IMAGE_I420:
- case GST_VAAPI_IMAGE_YV12:
- success = FALSE;
- break;
+ priv = image->priv;
+ gst_vaapi_image_get_size(image, &width, &height);
+ image_format = gst_vaapi_image_get_format(image);
+
+ /* currently only support YUV convert */
+ if ( (in_format != GST_MAKE_FOURCC('N','V','1','2')
+ && in_format != GST_MAKE_FOURCC('Y','V','1','2')
+ && in_format != GST_MAKE_FOURCC('I','4','2','0')
+ && in_format != GST_MAKE_FOURCC('Y', 'U', 'Y', '2'))
+ || (image_format != GST_VAAPI_IMAGE_NV12
+ && image_format != GST_VAAPI_IMAGE_YV12
+ && image_format != GST_VAAPI_IMAGE_I420)
+ )
+ {
+ return FALSE;
+ }
- default:
- success = FALSE;
- break;
- }
- gst_vaapi_image_unmap(image);
- return success;
+ gst_vaapi_image_map(image);
+ switch (image_format) {
+ case GST_VAAPI_IMAGE_NV12: {
+ g_assert(priv->image.num_planes == 2);
+ success = _image_convert_to_nv12(GST_BUFFER_DATA(inbuf),
+ width, height, in_format,
+ priv->image_data+priv->image.offsets[0],
+ priv->image.pitches[0],
+ priv->image_data+priv->image.offsets[1],
+ priv->image.pitches[1]);
+ break;
+ }
+
+ case GST_VAAPI_IMAGE_I420: {
+ g_assert(priv->image.num_planes == 3);
+ success = _image_convert_to_yuv411(GST_BUFFER_DATA(inbuf),
+ width, height, in_format,
+ priv->image_data+priv->image.offsets[0],
+ priv->image.pitches[0],
+ priv->image_data+priv->image.offsets[1],
+ priv->image.pitches[1],
+ priv->image_data+priv->image.offsets[2],
+ priv->image.pitches[2]);
+ break;
+ }
+ case GST_VAAPI_IMAGE_YV12:{
+ g_assert(priv->image.num_planes == 3);
+ success = _image_convert_to_yuv411(GST_BUFFER_DATA(inbuf),
+ width, height, in_format,
+ priv->image_data+priv->image.offsets[0],
+ priv->image.pitches[0],
+ priv->image_data+priv->image.offsets[2],
+ priv->image.pitches[2],
+ priv->image_data+priv->image.offsets[1],
+ priv->image.pitches[1]);
+ break;
+ }
+
+ default:
+ success = FALSE;
+ break;
+ }
+ gst_vaapi_image_unmap(image);
+
+ return success;
}