ffmpegcolorspace: Add conversion from/to YVYU colorspace

Fixes bug #572872.
This commit is contained in:
Sebastian Dröge 2009-02-24 14:06:38 +01:00
parent 0842dd1c6f
commit 77a56d5975
3 changed files with 178 additions and 2 deletions

View file

@ -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

View file

@ -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;

View file

@ -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,
@ -1042,6 +1171,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) {