From 77a56d597562628b94840e707b9fbd381cbf7905 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 24 Feb 2009 14:06:38 +0100 Subject: [PATCH] ffmpegcolorspace: Add conversion from/to YVYU colorspace Fixes bug #572872. --- gst/ffmpegcolorspace/avcodec.h | 1 + gst/ffmpegcolorspace/gstffmpegcodecmap.c | 7 ++ gst/ffmpegcolorspace/imgconvert.c | 172 ++++++++++++++++++++++++++++++- 3 files changed, 178 insertions(+), 2 deletions(-) diff --git a/gst/ffmpegcolorspace/avcodec.h b/gst/ffmpegcolorspace/avcodec.h index ec42eb0..f786a75 100644 --- a/gst/ffmpegcolorspace/avcodec.h +++ b/gst/ffmpegcolorspace/avcodec.h @@ -84,6 +84,7 @@ enum PixelFormat { PIX_FMT_XVMC_MPEG2_MC,///< XVideo Motion Acceleration via common packet passing(xvmc_render.h) PIX_FMT_XVMC_MPEG2_IDCT, PIX_FMT_UYVY422, ///< Packed pixel, Cb Y0 Cr Y1 + PIX_FMT_YVYU422, ///< Packed pixel, Y0 Cr Y1 Cb PIX_FMT_UYVY411, ///< Packed pixel, Cb Y0 Y1 Cr Y2 Y3 PIX_FMT_V308, ///< Packed pixel, Y0 Cb Cr diff --git a/gst/ffmpegcolorspace/gstffmpegcodecmap.c b/gst/ffmpegcolorspace/gstffmpegcodecmap.c index 8ce9c24..0a11659 100644 --- a/gst/ffmpegcolorspace/gstffmpegcodecmap.c +++ b/gst/ffmpegcolorspace/gstffmpegcodecmap.c @@ -182,6 +182,9 @@ gst_ffmpeg_pixfmt_to_caps (enum PixelFormat pix_fmt, AVCodecContext * context) case PIX_FMT_UYVY422: fmt = GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'); break; + case PIX_FMT_YVYU422: + fmt = GST_MAKE_FOURCC ('Y', 'V', 'Y', 'U'); + break; case PIX_FMT_UYVY411: fmt = GST_MAKE_FOURCC ('I', 'Y', 'U', '1'); break; @@ -590,6 +593,9 @@ gst_ffmpeg_caps_to_pixfmt (const GstCaps * caps, case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'): context->pix_fmt = PIX_FMT_UYVY422; break; + case GST_MAKE_FOURCC ('Y', 'V', 'Y', 'U'): + context->pix_fmt = PIX_FMT_YVYU422; + break; case GST_MAKE_FOURCC ('I', 'Y', 'U', '1'): context->pix_fmt = PIX_FMT_UYVY411; break; @@ -856,6 +862,7 @@ gst_ffmpegcsp_avpicture_fill (AVPicture * picture, case PIX_FMT_RGB565: case PIX_FMT_YUV422: case PIX_FMT_UYVY422: + case PIX_FMT_YVYU422: stride = GST_ROUND_UP_4 (width * 2); size = stride * height; picture->data[0] = ptr; diff --git a/gst/ffmpegcolorspace/imgconvert.c b/gst/ffmpegcolorspace/imgconvert.c index 33b3430..5e72e14 100644 --- a/gst/ffmpegcolorspace/imgconvert.c +++ b/gst/ffmpegcolorspace/imgconvert.c @@ -130,6 +130,17 @@ static PixFmtInfo pix_fmt_info[PIX_FMT_NB] = { /* .y_chroma_shift = */ 0, /* .depth = */ 8, }, + /* [PIX_FMT_YVYU422] = */ { + /* .format = */ PIX_FMT_YVYU422, + /* .name = */ "yvyu422", + /* .nb_channels = */ 1, + /* .color_type = */ FF_COLOR_YUV, + /* .pixel_type = */ FF_PIXEL_PACKED, + /* .is_alpha = */ 0, + /* .x_chroma_shift = */ 1, + /* .y_chroma_shift = */ 0, + /* .depth = */ 8, + }, /* [PIX_FMT_V308] = */ { /* .format = */ PIX_FMT_V308, /* .name = */ "v308", @@ -601,6 +612,7 @@ avg_bits_per_pixel (int pix_fmt) switch (pix_fmt) { case PIX_FMT_YUV422: case PIX_FMT_UYVY422: + case PIX_FMT_YVYU422: case PIX_FMT_RGB565: case PIX_FMT_RGB555: bits = 16; @@ -718,6 +730,7 @@ img_copy (AVPicture * dst, const AVPicture * src, switch (pix_fmt) { case PIX_FMT_YUV422: case PIX_FMT_UYVY422: + case PIX_FMT_YVYU422: case PIX_FMT_RGB565: case PIX_FMT_RGB555: bits = 16; @@ -935,6 +948,122 @@ uyvy422_to_yuv422p (AVPicture * dst, const AVPicture * src, } } +static void +yvyu422_to_gray (AVPicture * dst, const AVPicture * src, int width, int height) +{ + const uint8_t *p, *p1; + uint8_t *lum, *lum1; + int w; + + p1 = src->data[0]; + lum1 = dst->data[0]; + for (; height > 0; height--) { + p = p1; + lum = lum1; + + for (w = width; w >= 2; w -= 2) { + lum[0] = p[0]; + lum[1] = p[2]; + p += 4; + lum += 2; + } + p1 += src->linesize[0]; + lum1 += dst->linesize[0]; + } +} + + +static void +yvyu422_to_yuv420p (AVPicture * dst, const AVPicture * src, + int width, int height) +{ + const uint8_t *p, *p1; + uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1; + int w; + + p1 = src->data[0]; + + lum1 = dst->data[0]; + cb1 = dst->data[1]; + cr1 = dst->data[2]; + + for (; height >= 1; height -= 2) { + p = p1; + lum = lum1; + cb = cb1; + cr = cr1; + for (w = width; w >= 2; w -= 2) { + lum[0] = p[0]; + cb[0] = p[3]; + lum[1] = p[2]; + cr[0] = p[1]; + p += 4; + lum += 2; + cb++; + cr++; + } + if (w) { + lum[0] = p[0]; + cb[0] = p[3]; + cr[0] = p[1]; + cb++; + cr++; + } + p1 += src->linesize[0]; + lum1 += dst->linesize[0]; + if (height > 1) { + p = p1; + lum = lum1; + for (w = width; w >= 2; w -= 2) { + lum[0] = p[0]; + lum[1] = p[2]; + p += 4; + lum += 2; + } + if (w) { + lum[0] = p[0]; + } + p1 += src->linesize[0]; + lum1 += dst->linesize[0]; + } + cb1 += dst->linesize[1]; + cr1 += dst->linesize[2]; + } +} + +static void +yvyu422_to_yuv422p (AVPicture * dst, const AVPicture * src, + int width, int height) +{ + const uint8_t *p, *p1; + uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1; + int w; + + p1 = src->data[0]; + lum1 = dst->data[0]; + cb1 = dst->data[1]; + cr1 = dst->data[2]; + for (; height > 0; height--) { + p = p1; + lum = lum1; + cb = cb1; + cr = cr1; + for (w = width; w >= 2; w -= 2) { + lum[0] = p[0]; + cb[0] = p[3]; + lum[1] = p[2]; + cr[0] = p[1]; + p += 4; + lum += 2; + cb++; + cr++; + } + p1 += src->linesize[0]; + lum1 += dst->linesize[0]; + cb1 += dst->linesize[1]; + cr1 += dst->linesize[2]; + } +} static void yuv422_to_yuv422p (AVPicture * dst, const AVPicture * src, @@ -1043,6 +1172,40 @@ yuv422p_to_uyvy422 (AVPicture * dst, const AVPicture * src, } static void +yuv422p_to_yvyu422 (AVPicture * dst, const AVPicture * src, + int width, int height) +{ + uint8_t *p, *p1; + const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1; + int w; + + p1 = dst->data[0]; + lum1 = src->data[0]; + cb1 = src->data[1]; + cr1 = src->data[2]; + for (; height > 0; height--) { + p = p1; + lum = lum1; + cb = cb1; + cr = cr1; + for (w = width; w >= 2; w -= 2) { + p[0] = lum[0]; + p[3] = cb[0]; + p[2] = lum[1]; + p[1] = cr[0]; + p += 4; + lum += 2; + cb++; + cr++; + } + p1 += dst->linesize[0]; + lum1 += src->linesize[0]; + cb1 += src->linesize[1]; + cr1 += src->linesize[2]; + } +} + +static void uyvy411_to_yuv411p (AVPicture * dst, const AVPicture * src, int width, int height) { @@ -1078,7 +1241,6 @@ uyvy411_to_yuv411p (AVPicture * dst, const AVPicture * src, } } - static void yuv420p_to_yuv422 (AVPicture * dst, const AVPicture * src, int width, int height) @@ -2174,6 +2336,7 @@ static ConvertEntry convert_table[] = { {PIX_FMT_YUV422P, PIX_FMT_YUV422, yuv422p_to_yuv422}, {PIX_FMT_YUV422P, PIX_FMT_UYVY422, yuv422p_to_uyvy422}, + {PIX_FMT_YUV422P, PIX_FMT_YVYU422, yuv422p_to_yvyu422}, {PIX_FMT_YUV444P, PIX_FMT_RGB24, yuv444p_to_rgb24}, @@ -2199,6 +2362,10 @@ static ConvertEntry convert_table[] = { {PIX_FMT_UYVY422, PIX_FMT_YUV422P, uyvy422_to_yuv422p}, {PIX_FMT_UYVY422, PIX_FMT_GRAY8, uyvy422_to_gray}, + {PIX_FMT_YVYU422, PIX_FMT_YUV420P, yvyu422_to_yuv420p}, + {PIX_FMT_YVYU422, PIX_FMT_YUV422P, yvyu422_to_yuv422p}, + {PIX_FMT_YVYU422, PIX_FMT_GRAY8, yvyu422_to_gray}, + {PIX_FMT_RGB24, PIX_FMT_YUV420P, rgb24_to_yuv420p}, {PIX_FMT_RGB24, PIX_FMT_NV12, rgb24_to_nv12}, {PIX_FMT_RGB24, PIX_FMT_NV21, rgb24_to_nv21}, @@ -2581,7 +2748,8 @@ no_chroma_filter: if (src_pix_fmt == PIX_FMT_YUV422 || dst_pix_fmt == PIX_FMT_YUV422) { /* specific case: convert to YUV422P first */ int_pix_fmt = PIX_FMT_YUV422P; - } else if (src_pix_fmt == PIX_FMT_UYVY422 || dst_pix_fmt == PIX_FMT_UYVY422) { + } else if (src_pix_fmt == PIX_FMT_UYVY422 || dst_pix_fmt == PIX_FMT_UYVY422 || + src_pix_fmt == PIX_FMT_YVYU422 || dst_pix_fmt == PIX_FMT_YVYU422) { /* specific case: convert to YUV422P first */ int_pix_fmt = PIX_FMT_YUV422P; } else if (src_pix_fmt == PIX_FMT_UYVY411 || dst_pix_fmt == PIX_FMT_UYVY411) { -- 2.7.4