diff options
author | Sebastian Dröge <sebastian.droege@collabora.co.uk> | 2012-11-13 12:51:49 +0100 |
---|---|---|
committer | Sebastian Dröge <sebastian.droege@collabora.co.uk> | 2012-11-15 15:43:30 +0100 |
commit | 47eae0e44a6c1896c42b4e23f23e389111e03696 (patch) | |
tree | 2610f5d3a040f138e6a29827054b48af7f98e99e | |
parent | fc13f649771497c8c040b0ff374b02da153c4b1d (diff) | |
download | gstreamer-plugins-base-47eae0e44a6c1896c42b4e23f23e389111e03696.tar.gz |
ffmpegcolorspace: Add support for 10 bit YUV color formats
-rw-r--r-- | gst/ffmpegcolorspace/avcodec.h | 6 | ||||
-rw-r--r-- | gst/ffmpegcolorspace/gstffmpegcodecmap.c | 58 | ||||
-rw-r--r-- | gst/ffmpegcolorspace/gstffmpegcolorspace.c | 2 | ||||
-rw-r--r-- | gst/ffmpegcolorspace/imgconvert.c | 1026 |
4 files changed, 1090 insertions, 2 deletions
diff --git a/gst/ffmpegcolorspace/avcodec.h b/gst/ffmpegcolorspace/avcodec.h index 6067aedb5..ebfaa2d5e 100644 --- a/gst/ffmpegcolorspace/avcodec.h +++ b/gst/ffmpegcolorspace/avcodec.h @@ -94,6 +94,12 @@ enum PixelFormat { PIX_FMT_AYUV4444, ///< Packed pixel, A0 Y0 Cb Cr PIX_FMT_YUVA420P, ///< Planar YUV 4:4:2:0 (1 Cr & Cb sample per 2x2 Y & A samples) (A420) + PIX_FMT_YUV420P10BE,///< planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian + PIX_FMT_YUV420P10LE,///< planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian + PIX_FMT_YUV422P10BE,///< planar YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian + PIX_FMT_YUV422P10LE,///< planar YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian + PIX_FMT_YUV444P10BE,///< planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian + PIX_FMT_YUV444P10LE,///< planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), little-en PIX_FMT_NB }; diff --git a/gst/ffmpegcolorspace/gstffmpegcodecmap.c b/gst/ffmpegcolorspace/gstffmpegcodecmap.c index 97052cb45..99ac045b5 100644 --- a/gst/ffmpegcolorspace/gstffmpegcodecmap.c +++ b/gst/ffmpegcolorspace/gstffmpegcodecmap.c @@ -404,6 +404,24 @@ gst_ffmpeg_pixfmt_to_caps (enum PixelFormat pix_fmt, AVCodecContext * context) "bpp", G_TYPE_INT, bpp, "depth", G_TYPE_INT, depth, "endianness", G_TYPE_INT, G_BIG_ENDIAN, NULL); break; + case PIX_FMT_YUV420P10BE: + fmt = GST_MAKE_FOURCC ('D', '4', '2', '0'); + break; + case PIX_FMT_YUV420P10LE: + fmt = GST_MAKE_FOURCC ('d', '4', '2', '0'); + break; + case PIX_FMT_YUV422P10BE: + fmt = GST_MAKE_FOURCC ('D', '4', '2', '2'); + break; + case PIX_FMT_YUV422P10LE: + fmt = GST_MAKE_FOURCC ('d', '4', '2', '2'); + break; + case PIX_FMT_YUV444P10BE: + fmt = GST_MAKE_FOURCC ('D', '4', '4', '4'); + break; + case PIX_FMT_YUV444P10LE: + fmt = GST_MAKE_FOURCC ('d', '4', '4', '4'); + break; default: /* give up ... */ break; @@ -680,6 +698,24 @@ gst_ffmpeg_caps_to_pixfmt (const GstCaps * caps, case GST_MAKE_FOURCC ('Y', '1', '6', ' '): context->pix_fmt = PIX_FMT_Y16; break; + case GST_MAKE_FOURCC ('D', '4', '2', '0'): + context->pix_fmt = PIX_FMT_YUV420P10BE; + break; + case GST_MAKE_FOURCC ('d', '4', '2', '0'): + context->pix_fmt = PIX_FMT_YUV420P10LE; + break; + case GST_MAKE_FOURCC ('D', '4', '2', '2'): + context->pix_fmt = PIX_FMT_YUV422P10BE; + break; + case GST_MAKE_FOURCC ('d', '4', '2', '2'): + context->pix_fmt = PIX_FMT_YUV422P10LE; + break; + case GST_MAKE_FOURCC ('D', '4', '4', '4'): + context->pix_fmt = PIX_FMT_YUV444P10BE; + break; + case GST_MAKE_FOURCC ('d', '4', '4', '4'): + context->pix_fmt = PIX_FMT_YUV444P10LE; + break; } } } else if (gst_structure_has_name (structure, "video/x-raw-rgb")) { @@ -1004,6 +1040,28 @@ gst_ffmpegcsp_avpicture_fill (AVPicture * picture, picture->linesize[0] = stride; picture->linesize[1] = 4; return size + 256 * 4; + + case PIX_FMT_YUV420P10BE: + case PIX_FMT_YUV420P10LE: + case PIX_FMT_YUV422P10BE: + case PIX_FMT_YUV422P10LE: + case PIX_FMT_YUV444P10BE: + case PIX_FMT_YUV444P10LE: + stride = GST_ROUND_UP_4 (width * 2); + h2 = ROUND_UP_X (height, pinfo->y_chroma_shift); + size = stride * h2; + w2 = DIV_ROUND_UP_X (width, pinfo->x_chroma_shift); + stride2 = GST_ROUND_UP_4 (w2 * 2); + h2 = DIV_ROUND_UP_X (height, pinfo->y_chroma_shift); + size2 = stride2 * h2; + picture->data[0] = ptr; + picture->data[1] = picture->data[0] + size; + picture->data[2] = picture->data[1] + size2; + picture->linesize[0] = stride; + picture->linesize[1] = stride2; + picture->linesize[2] = stride2; + return size + 2 * size2; + default: picture->data[0] = NULL; picture->data[1] = NULL; diff --git a/gst/ffmpegcolorspace/gstffmpegcolorspace.c b/gst/ffmpegcolorspace/gstffmpegcolorspace.c index c8805b35f..815848509 100644 --- a/gst/ffmpegcolorspace/gstffmpegcolorspace.c +++ b/gst/ffmpegcolorspace/gstffmpegcolorspace.c @@ -47,7 +47,7 @@ GST_DEBUG_CATEGORY (ffmpegcolorspace_performance); #define FFMPEGCSP_VIDEO_CAPS \ "video/x-raw-yuv, width = "GST_VIDEO_SIZE_RANGE" , " \ "height="GST_VIDEO_SIZE_RANGE",framerate="GST_VIDEO_FPS_RANGE"," \ - "format= (fourcc) { I420 , NV12 , NV21 , YV12 , YUY2 , Y42B , Y444 , YUV9 , YVU9 , Y41B , Y800 , Y8 , GREY , Y16 , UYVY , YVYU , IYU1 , v308 , AYUV, A420} ;" \ + "format= (fourcc) { I420 , NV12 , NV21 , YV12 , YUY2 , Y42B , Y444 , YUV9 , YVU9 , Y41B , Y800 , Y8 , GREY , Y16 , UYVY , YVYU , IYU1 , v308 , AYUV, A420, D420, d420, D422, d422, D444, d444} ;" \ GST_VIDEO_CAPS_RGB";" \ GST_VIDEO_CAPS_BGR";" \ GST_VIDEO_CAPS_RGBx";" \ diff --git a/gst/ffmpegcolorspace/imgconvert.c b/gst/ffmpegcolorspace/imgconvert.c index 54d325102..64f1d34b3 100644 --- a/gst/ffmpegcolorspace/imgconvert.c +++ b/gst/ffmpegcolorspace/imgconvert.c @@ -488,7 +488,73 @@ static PixFmtInfo pix_fmt_info[PIX_FMT_NB] = { /* .x_chroma_shift = */ 1, /* .y_chroma_shift = */ 1, /* .depth = */ 8, - } + }, + /* [PIX_FMT_YUV420P10BE] = */ { + /* .format = */ PIX_FMT_YUV420P10BE, + /* .name = */ "yuv420p10be", + /* .nb_channels = */ 3, + /* .color_type = */ FF_COLOR_YUV, + /* .pixel_type = */ FF_PIXEL_PLANAR, + /* .is_alpha = */ 0, + /* .x_chroma_shift = */ 1, + /* .y_chroma_shift = */ 1, + /* .depth = */ 10, + }, + /* [PIX_FMT_YUV420P10LE] = */ { + /* .format = */ PIX_FMT_YUV420P10LE, + /* .name = */ "yuv420p10le", + /* .nb_channels = */ 3, + /* .color_type = */ FF_COLOR_YUV, + /* .pixel_type = */ FF_PIXEL_PLANAR, + /* .is_alpha = */ 0, + /* .x_chroma_shift = */ 1, + /* .y_chroma_shift = */ 1, + /* .depth = */ 10, + }, + /* [PIX_FMT_YUV422P10BE] = */ { + /* .format = */ PIX_FMT_YUV422P10BE, + /* .name = */ "yuv422p10be", + /* .nb_channels = */ 3, + /* .color_type = */ FF_COLOR_YUV, + /* .pixel_type = */ FF_PIXEL_PLANAR, + /* .is_alpha = */ 0, + /* .x_chroma_shift = */ 1, + /* .y_chroma_shift = */ 0, + /* .depth = */ 10, + }, + /* [PIX_FMT_YUV422P10LE] = */ { + /* .format = */ PIX_FMT_YUV422P10LE, + /* .name = */ "yuv422p10le", + /* .nb_channels = */ 3, + /* .color_type = */ FF_COLOR_YUV, + /* .pixel_type = */ FF_PIXEL_PLANAR, + /* .is_alpha = */ 0, + /* .x_chroma_shift = */ 1, + /* .y_chroma_shift = */ 0, + /* .depth = */ 10, + }, + /* [PIX_FMT_YUV444P10BE] = */ { + /* .format = */ PIX_FMT_YUV444P10BE, + /* .name = */ "yuv444p10be", + /* .nb_channels = */ 3, + /* .color_type = */ FF_COLOR_YUV, + /* .pixel_type = */ FF_PIXEL_PLANAR, + /* .is_alpha = */ 0, + /* .x_chroma_shift = */ 0, + /* .y_chroma_shift = */ 0, + /* .depth = */ 10, + }, + /* [PIX_FMT_YUV444P10LE] = */ { + /* .format = */ PIX_FMT_YUV444P10LE, + /* .name = */ "yuv444p10le", + /* .nb_channels = */ 3, + /* .color_type = */ FF_COLOR_YUV, + /* .pixel_type = */ FF_PIXEL_PLANAR, + /* .is_alpha = */ 0, + /* .x_chroma_shift = */ 0, + /* .y_chroma_shift = */ 0, + /* .depth = */ 10, + }, }; /* returns NULL if not found */ @@ -1781,6 +1847,950 @@ yuva420p_to_yuv422 (AVPicture * dst, const AVPicture * src, } } +static void +yuv420p10be_to_yuv444p (AVPicture * dst, const AVPicture * src, int width, + int height) +{ + int w, h; + uint8_t *dst_lum1, *dst_lum2, *dst_line = dst->data[0]; + uint8_t *dst_cb1, *dst_cb2, *dst_cb_line = dst->data[1]; + uint8_t *dst_cr1, *dst_cr2, *dst_cr_line = dst->data[2]; + uint16_t *lum1, *lum2, *src_lum_line = (uint16_t *) src->data[0]; + uint16_t *src_cb1, *src_cb_line = (uint16_t *) src->data[1]; + uint16_t *src_cr1, *src_cr_line = (uint16_t *) src->data[2]; + uint16_t y1, y2, cb, cr; + + for (h = height / 2; h--;) { + dst_lum1 = dst_line; + dst_lum2 = dst_line + dst->linesize[0]; + + dst_cb1 = dst_cb_line; + dst_cb2 = dst_cb_line + dst->linesize[1]; + dst_cr1 = dst_cr_line; + dst_cr2 = dst_cr_line + dst->linesize[2]; + + lum1 = src_lum_line; + lum2 = src_lum_line + src->linesize[0] / 2; + + src_cb1 = src_cb_line; + src_cr1 = src_cr_line; + + for (w = width / 2; w--;) { + cb = *src_cb1++; + cr = *src_cr1++; + y1 = *lum1++; + y2 = *lum2++; + cb = GUINT16_FROM_BE (cb) >> 6; + cr = GUINT16_FROM_BE (cr) >> 6; + y1 = GUINT16_FROM_BE (y1) >> 6; + y2 = GUINT16_FROM_BE (y2) >> 6; + + *dst_lum1++ = y1; + *dst_lum2++ = y2; + *dst_cb1++ = *dst_cb2++ = cb; + *dst_cr1++ = *dst_cr2++ = cr; + + y1 = *lum1++; + y2 = *lum2++; + y1 = GUINT16_FROM_BE (y1) >> 6; + y2 = GUINT16_FROM_BE (y2) >> 6; + + *dst_lum1++ = y1; + *dst_lum2++ = y2; + *dst_cb1++ = *dst_cb2++ = cb; + *dst_cr1++ = *dst_cr2++ = cr; + } + /* odd width */ + if (width % 2 != 0) { + cb = *src_cb1++; + cr = *src_cr1++; + y1 = *lum1++; + y2 = *lum2++; + cb = GUINT16_FROM_BE (cb) >> 6; + cr = GUINT16_FROM_BE (cr) >> 6; + y1 = GUINT16_FROM_BE (y1) >> 6; + y2 = GUINT16_FROM_BE (y2) >> 6; + + *dst_lum1++ = y1; + *dst_lum2++ = y2; + *dst_cb1++ = *dst_cb2++ = cb; + *dst_cr1++ = *dst_cr2++ = cr; + } + + dst_line += dst->linesize[0] * 2; + dst_cb_line += dst->linesize[1] * 2; + dst_cr_line += dst->linesize[2] * 2; + src_lum_line += src->linesize[0]; + src_cb_line += src->linesize[1] / 2; + src_cr_line += src->linesize[2] / 2; + } + + /* odd height */ + if (height % 2 != 0) { + dst_lum1 = dst_line; + lum1 = src_lum_line; + src_cb1 = src_cb_line; + src_cr1 = src_cr_line; + dst_cb1 = dst_cb_line; + dst_cr1 = dst_cr_line; + + for (w = width / 2; w--;) { + cb = *src_cb1++; + cr = *src_cr1++; + y1 = *lum1++; + cb = GUINT16_FROM_BE (cb) >> 6; + cr = GUINT16_FROM_BE (cr) >> 6; + y1 = GUINT16_FROM_BE (y1) >> 6; + + *dst_lum1++ = y1; + *dst_cb1++ = cb; + *dst_cr1++ = cr; + + y1 = *lum1++; + y1 = GUINT16_FROM_BE (y1) >> 6; + + *dst_lum1++ = y1; + *dst_cb1++ = cb >> 6; + *dst_cr1++ = cr >> 6; + } + /* odd width */ + if (width % 2 != 0) { + cb = *src_cb1++; + cr = *src_cr1++; + y1 = *lum1++; + cb = GUINT16_FROM_BE (cb) >> 6; + cr = GUINT16_FROM_BE (cr) >> 6; + y1 = GUINT16_FROM_BE (y1) >> 6; + *dst_lum1++ = y1; + *dst_cb1++ = cb; + *dst_cr1++ = cr; + } + } +} + +static void +yuv420p10le_to_yuv444p (AVPicture * dst, const AVPicture * src, int width, + int height) +{ + int w, h; + uint8_t *dst_lum1, *dst_lum2, *dst_line = dst->data[0]; + uint8_t *dst_cb1, *dst_cb2, *dst_cb_line = dst->data[1]; + uint8_t *dst_cr1, *dst_cr2, *dst_cr_line = dst->data[2]; + uint16_t *lum1, *lum2, *src_lum_line = (uint16_t *) src->data[0]; + uint16_t *src_cb1, *src_cb_line = (uint16_t *) src->data[1]; + uint16_t *src_cr1, *src_cr_line = (uint16_t *) src->data[2]; + uint16_t y1, y2, cb, cr; + + for (h = height / 2; h--;) { + dst_lum1 = dst_line; + dst_lum2 = dst_line + dst->linesize[0]; + + dst_cb1 = dst_cb_line; + dst_cb2 = dst_cb_line + dst->linesize[1]; + dst_cr1 = dst_cr_line; + dst_cr2 = dst_cr_line + dst->linesize[2]; + + lum1 = src_lum_line; + lum2 = src_lum_line + src->linesize[0] / 2; + + src_cb1 = src_cb_line; + src_cr1 = src_cr_line; + + for (w = width / 2; w--;) { + cb = *src_cb1++; + cr = *src_cr1++; + y1 = *lum1++; + y2 = *lum2++; + cb = GUINT16_FROM_LE (cb) >> 6; + cr = GUINT16_FROM_LE (cr) >> 6; + y1 = GUINT16_FROM_LE (y1) >> 6; + y2 = GUINT16_FROM_LE (y2) >> 6; + + *dst_lum1++ = y1; + *dst_lum2++ = y2; + *dst_cb1++ = *dst_cb2++ = cb; + *dst_cr1++ = *dst_cr2++ = cr; + + y1 = *lum1++; + y2 = *lum2++; + y1 = GUINT16_FROM_LE (y1) >> 6; + y2 = GUINT16_FROM_LE (y2) >> 6; + + *dst_lum1++ = y1; + *dst_lum2++ = y2; + *dst_cb1++ = *dst_cb2++ = cb; + *dst_cr1++ = *dst_cr2++ = cr; + } + /* odd width */ + if (width % 2 != 0) { + cb = *src_cb1++; + cr = *src_cr1++; + y1 = *lum1++; + y2 = *lum2++; + cb = GUINT16_FROM_LE (cb) >> 6; + cr = GUINT16_FROM_LE (cr) >> 6; + y1 = GUINT16_FROM_LE (y1) >> 6; + y2 = GUINT16_FROM_LE (y2) >> 6; + + *dst_lum1++ = y1; + *dst_lum2++ = y2; + *dst_cb1++ = *dst_cb2++ = cb; + *dst_cr1++ = *dst_cr2++ = cr; + } + + dst_line += dst->linesize[0] * 2; + dst_cb_line += dst->linesize[1] * 2; + dst_cr_line += dst->linesize[2] * 2; + src_lum_line += src->linesize[0]; + src_cb_line += src->linesize[1] / 2; + src_cr_line += src->linesize[2] / 2; + } + + /* odd height */ + if (height % 2 != 0) { + dst_lum1 = dst_line; + lum1 = src_lum_line; + src_cb1 = src_cb_line; + src_cr1 = src_cr_line; + dst_cb1 = dst_cb_line; + dst_cr1 = dst_cr_line; + + for (w = width / 2; w--;) { + cb = *src_cb1++; + cr = *src_cr1++; + y1 = *lum1++; + cb = GUINT16_FROM_LE (cb) >> 6; + cr = GUINT16_FROM_LE (cr) >> 6; + y1 = GUINT16_FROM_LE (y1) >> 6; + + *dst_lum1++ = y1; + *dst_cb1++ = cb; + *dst_cr1++ = cr; + + y1 = *lum1++; + y1 = GUINT16_FROM_LE (y1) >> 6; + + *dst_lum1++ = y1; + *dst_cb1++ = cb >> 6; + *dst_cr1++ = cr >> 6; + } + /* odd width */ + if (width % 2 != 0) { + cb = *src_cb1++; + cr = *src_cr1++; + y1 = *lum1++; + cb = GUINT16_FROM_LE (cb) >> 6; + cr = GUINT16_FROM_LE (cr) >> 6; + y1 = GUINT16_FROM_LE (y1) >> 6; + *dst_lum1++ = y1; + *dst_cb1++ = cb; + *dst_cr1++ = cr; + } + } +} + +static void +yuv444p_to_yuv420p10be (AVPicture * dst, const AVPicture * src, int width, + int height) +{ + int w, h; + uint16_t *dst_lum1, *dst_lum2, *dst_line = (uint16_t *) dst->data[0]; + uint16_t *dst_cb1, *dst_cb_line = (uint16_t *) dst->data[1]; + uint16_t *dst_cr1, *dst_cr_line = (uint16_t *) dst->data[2]; + uint8_t *lum1, *lum2, *src_lum_line = src->data[0]; + uint8_t *src_cb1, *src_cb2, *src_cb_line = src->data[1]; + uint8_t *src_cr1, *src_cr2, *src_cr_line = src->data[2]; + uint16_t y1, y2, cb, cr; + + for (h = height / 2; h--;) { + dst_lum1 = dst_line; + dst_lum2 = dst_line + dst->linesize[0] / 2; + + dst_cb1 = dst_cb_line; + dst_cr1 = dst_cr_line; + + lum1 = src_lum_line; + lum2 = src_lum_line + src->linesize[0]; + + src_cb1 = src_cb_line; + src_cb2 = src_cb_line + src->linesize[1]; + src_cr1 = src_cr_line; + src_cr2 = src_cr_line + src->linesize[2]; + + for (w = width / 2; w--;) { + cb = *src_cb1++; + cb += *src_cb1++; + cb += *src_cb2++; + cb += *src_cb2++; + cr = *src_cr1++; + cr += *src_cr1++; + cr += *src_cr2++; + cr += *src_cr2++; + y1 = *lum1++; + y2 = *lum1++; + cb = cb << 4; + cr = cr << 4; + y1 = y1 << 6; + y2 = y2 << 6; + + *dst_lum1++ = GUINT16_TO_BE (y1); + *dst_lum1++ = GUINT16_TO_BE (y2); + *dst_cb1++ = GUINT16_TO_BE (cb); + *dst_cr1++ = GUINT16_TO_BE (cr); + + y1 = *lum2++; + y2 = *lum2++; + y1 = y1 << 6; + y2 = y2 << 6; + + *dst_lum2++ = GUINT16_TO_BE (y1); + *dst_lum2++ = GUINT16_TO_BE (y2); + } + + /* odd width */ + if (width % 2 != 0) { + cb = *src_cb1++; + cb += *src_cb2++; + cr = *src_cr1++; + cr += *src_cr2++; + y1 = *lum1++; + + cb = cb << 5; + cr = cr << 5; + y1 = y1 << 6; + + *dst_lum1++ = GUINT16_TO_BE (y1); + *dst_cb1++ = GUINT16_TO_BE (cb); + *dst_cr1++ = GUINT16_TO_BE (cr); + } + + dst_line += dst->linesize[0]; + dst_cb_line += dst->linesize[1] / 2; + dst_cr_line += dst->linesize[2] / 2; + src_lum_line += src->linesize[0] * 2; + src_cb_line += src->linesize[1] * 2; + src_cr_line += src->linesize[2] * 2; + } + + /* odd height */ + if (height % 2 != 0) { + dst_lum1 = dst_line; + lum1 = src_lum_line; + src_cb1 = src_cb_line; + src_cr1 = src_cr_line; + dst_cb1 = dst_cb_line; + dst_cr1 = dst_cr_line; + + for (w = width / 2; w--;) { + cb = *src_cb1++; + cb += *src_cb1++; + cr = *src_cr1++; + cr += *src_cr1++; + y1 = *lum1++; + y2 = *lum1++; + cb = cb << 5; + cr = cr << 5; + y1 = y1 << 6; + y2 = y2 << 6; + + *dst_lum1++ = GUINT16_TO_BE (y1); + *dst_lum1++ = GUINT16_TO_BE (y2); + *dst_cb1++ = GUINT16_TO_BE (cb); + *dst_cr1++ = GUINT16_TO_BE (cr); + } + + /* odd width */ + if (width % 2 != 0) { + cb = *src_cb1++; + cr = *src_cr1++; + y1 = *lum1++; + + cb = cb << 6; + cr = cr << 6; + y1 = y1 << 6; + + *dst_lum1++ = GUINT16_TO_BE (y1); + *dst_cb1++ = GUINT16_TO_BE (cb); + *dst_cr1++ = GUINT16_TO_BE (cr); + } + } +} + +static void +yuv444p_to_yuv420p10le (AVPicture * dst, const AVPicture * src, int width, + int height) +{ + int w, h; + uint16_t *dst_lum1, *dst_lum2, *dst_line = (uint16_t *) dst->data[0]; + uint16_t *dst_cb1, *dst_cb_line = (uint16_t *) dst->data[1]; + uint16_t *dst_cr1, *dst_cr_line = (uint16_t *) dst->data[2]; + uint8_t *lum1, *lum2, *src_lum_line = src->data[0]; + uint8_t *src_cb1, *src_cb2, *src_cb_line = src->data[1]; + uint8_t *src_cr1, *src_cr2, *src_cr_line = src->data[2]; + uint16_t y1, y2, cb, cr; + + for (h = height / 2; h--;) { + dst_lum1 = dst_line; + dst_lum2 = dst_line + dst->linesize[0] / 2; + + dst_cb1 = dst_cb_line; + dst_cr1 = dst_cr_line; + + lum1 = src_lum_line; + lum2 = src_lum_line + src->linesize[0]; + + src_cb1 = src_cb_line; + src_cb2 = src_cb_line + src->linesize[1]; + src_cr1 = src_cr_line; + src_cr2 = src_cr_line + src->linesize[2]; + + for (w = width / 2; w--;) { + cb = *src_cb1++; + cb += *src_cb1++; + cb += *src_cb2++; + cb += *src_cb2++; + cr = *src_cr1++; + cr += *src_cr1++; + cr += *src_cr2++; + cr += *src_cr2++; + y1 = *lum1++; + y2 = *lum1++; + cb = cb << 4; + cr = cr << 4; + y1 = y1 << 6; + y2 = y2 << 6; + + *dst_lum1++ = GUINT16_TO_LE (y1); + *dst_lum1++ = GUINT16_TO_LE (y2); + *dst_cb1++ = GUINT16_TO_LE (cb); + *dst_cr1++ = GUINT16_TO_LE (cr); + + y1 = *lum2++; + y2 = *lum2++; + y1 = y1 << 6; + y2 = y2 << 6; + + *dst_lum2++ = GUINT16_TO_LE (y1); + *dst_lum2++ = GUINT16_TO_LE (y2); + } + + /* odd width */ + if (width % 2 != 0) { + cb = *src_cb1++; + cb += *src_cb2++; + cr = *src_cr1++; + cr += *src_cr2++; + y1 = *lum1++; + + cb = cb << 5; + cr = cr << 5; + y1 = y1 << 6; + + *dst_lum1++ = GUINT16_TO_LE (y1); + *dst_cb1++ = GUINT16_TO_LE (cb); + *dst_cr1++ = GUINT16_TO_LE (cr); + } + + dst_line += dst->linesize[0]; + dst_cb_line += dst->linesize[1] / 2; + dst_cr_line += dst->linesize[2] / 2; + src_lum_line += src->linesize[0] * 2; + src_cb_line += src->linesize[1] * 2; + src_cr_line += src->linesize[2] * 2; + } + + /* odd height */ + if (height % 2 != 0) { + dst_lum1 = dst_line; + lum1 = src_lum_line; + src_cb1 = src_cb_line; + src_cr1 = src_cr_line; + dst_cb1 = dst_cb_line; + dst_cr1 = dst_cr_line; + + for (w = width / 2; w--;) { + cb = *src_cb1++; + cb += *src_cb1++; + cr = *src_cr1++; + cr += *src_cr1++; + y1 = *lum1++; + y2 = *lum1++; + cb = cb << 5; + cr = cr << 5; + y1 = y1 << 6; + y2 = y2 << 6; + + *dst_lum1++ = GUINT16_TO_LE (y1); + *dst_lum1++ = GUINT16_TO_LE (y2); + *dst_cb1++ = GUINT16_TO_LE (cb); + *dst_cr1++ = GUINT16_TO_LE (cr); + } + + /* odd width */ + if (width % 2 != 0) { + cb = *src_cb1++; + cr = *src_cr1++; + y1 = *lum1++; + + cb = cb << 6; + cr = cr << 6; + y1 = y1 << 6; + + *dst_lum1++ = GUINT16_TO_LE (y1); + *dst_cb1++ = GUINT16_TO_LE (cb); + *dst_cr1++ = GUINT16_TO_LE (cr); + } + } +} + +static void +yuv422p10be_to_yuv444p (AVPicture * dst, const AVPicture * src, int width, + int height) +{ + int w, h; + uint8_t *dst_lum1, *dst_line = dst->data[0]; + uint8_t *dst_cb1, *dst_cb_line = dst->data[1]; + uint8_t *dst_cr1, *dst_cr_line = dst->data[2]; + uint16_t *lum1, *src_lum_line = (uint16_t *) src->data[0]; + uint16_t *src_cb1, *src_cb_line = (uint16_t *) src->data[1]; + uint16_t *src_cr1, *src_cr_line = (uint16_t *) src->data[2]; + uint16_t y1, cb, cr; + + for (h = height; h--;) { + dst_lum1 = dst_line; + + dst_cb1 = dst_cb_line; + dst_cr1 = dst_cr_line; + + lum1 = src_lum_line; + + src_cb1 = src_cb_line; + src_cr1 = src_cr_line; + + for (w = width / 2; w--;) { + cb = *src_cb1++; + cr = *src_cr1++; + y1 = *lum1++; + cb = GUINT16_FROM_BE (cb) >> 6; + cr = GUINT16_FROM_BE (cr) >> 6; + y1 = GUINT16_FROM_BE (y1) >> 6; + + *dst_lum1++ = y1; + *dst_cb1++ = cb; + *dst_cr1++ = cr; + + y1 = *lum1++; + y1 = GUINT16_FROM_BE (y1) >> 6; + + *dst_lum1++ = y1; + *dst_cb1++ = cb; + *dst_cr1++ = cr; + } + /* odd width */ + if (width % 2 != 0) { + cb = *src_cb1++; + cr = *src_cr1++; + y1 = *lum1++; + cb = GUINT16_FROM_BE (cb) >> 6; + cr = GUINT16_FROM_BE (cr) >> 6; + y1 = GUINT16_FROM_BE (y1) >> 6; + + *dst_lum1++ = y1; + *dst_cb1++ = cb; + *dst_cr1++ = cr; + } + + dst_line += dst->linesize[0]; + dst_cb_line += dst->linesize[1]; + dst_cr_line += dst->linesize[2]; + src_lum_line += src->linesize[0] / 2; + src_cb_line += src->linesize[1] / 2; + src_cr_line += src->linesize[2] / 2; + } +} + +static void +yuv422p10le_to_yuv444p (AVPicture * dst, const AVPicture * src, int width, + int height) +{ + int w, h; + uint8_t *dst_lum1, *dst_line = dst->data[0]; + uint8_t *dst_cb1, *dst_cb_line = dst->data[1]; + uint8_t *dst_cr1, *dst_cr_line = dst->data[2]; + uint16_t *lum1, *src_lum_line = (uint16_t *) src->data[0]; + uint16_t *src_cb1, *src_cb_line = (uint16_t *) src->data[1]; + uint16_t *src_cr1, *src_cr_line = (uint16_t *) src->data[2]; + uint16_t y1, cb, cr; + + for (h = height; h--;) { + dst_lum1 = dst_line; + + dst_cb1 = dst_cb_line; + dst_cr1 = dst_cr_line; + + lum1 = src_lum_line; + + src_cb1 = src_cb_line; + src_cr1 = src_cr_line; + + for (w = width / 2; w--;) { + cb = *src_cb1++; + cr = *src_cr1++; + y1 = *lum1++; + cb = GUINT16_FROM_LE (cb) >> 6; + cr = GUINT16_FROM_LE (cr) >> 6; + y1 = GUINT16_FROM_LE (y1) >> 6; + + *dst_lum1++ = y1; + *dst_cb1++ = cb; + *dst_cr1++ = cr; + + y1 = *lum1++; + y1 = GUINT16_FROM_LE (y1) >> 6; + + *dst_lum1++ = y1; + *dst_cb1++ = cb; + *dst_cr1++ = cr; + } + /* odd width */ + if (width % 2 != 0) { + cb = *src_cb1++; + cr = *src_cr1++; + y1 = *lum1++; + cb = GUINT16_FROM_LE (cb) >> 6; + cr = GUINT16_FROM_LE (cr) >> 6; + y1 = GUINT16_FROM_LE (y1) >> 6; + + *dst_lum1++ = y1; + *dst_cb1++ = cb; + *dst_cr1++ = cr; + } + + dst_line += dst->linesize[0]; + dst_cb_line += dst->linesize[1]; + dst_cr_line += dst->linesize[2]; + src_lum_line += src->linesize[0] / 2; + src_cb_line += src->linesize[1] / 2; + src_cr_line += src->linesize[2] / 2; + } +} + +static void +yuv444p_to_yuv422p10be (AVPicture * dst, const AVPicture * src, int width, + int height) +{ + int w, h; + uint16_t *dst_lum1, *dst_line = (uint16_t *) dst->data[0]; + uint16_t *dst_cb1, *dst_cb_line = (uint16_t *) dst->data[1]; + uint16_t *dst_cr1, *dst_cr_line = (uint16_t *) dst->data[2]; + uint8_t *lum1, *src_lum_line = src->data[0]; + uint8_t *src_cb1, *src_cb_line = src->data[1]; + uint8_t *src_cr1, *src_cr_line = src->data[2]; + uint16_t y1, y2, cb, cr; + + for (h = height; h--;) { + dst_lum1 = dst_line; + + dst_cb1 = dst_cb_line; + dst_cr1 = dst_cr_line; + + lum1 = src_lum_line; + + src_cb1 = src_cb_line; + src_cr1 = src_cr_line; + + for (w = width / 2; w--;) { + cb = *src_cb1++; + cb += *src_cb1++; + cr = *src_cr1++; + cr += *src_cr1++; + y1 = *lum1++; + y2 = *lum1++; + cb = cb << 5; + cr = cr << 5; + y1 = y1 << 6; + y2 = y2 << 6; + + *dst_lum1++ = GUINT16_TO_BE (y1); + *dst_lum1++ = GUINT16_TO_BE (y2); + *dst_cb1++ = GUINT16_TO_BE (cb); + *dst_cr1++ = GUINT16_TO_BE (cr); + } + + /* odd width */ + if (width % 2 != 0) { + cb = *src_cb1++; + cr = *src_cr1++; + y1 = *lum1++; + + cb = cb << 6; + cr = cr << 6; + y1 = y1 << 6; + + *dst_lum1++ = GUINT16_TO_BE (y1); + *dst_cb1++ = GUINT16_TO_BE (cb); + *dst_cr1++ = GUINT16_TO_BE (cr); + } + + dst_line += dst->linesize[0] / 2; + dst_cb_line += dst->linesize[1] / 2; + dst_cr_line += dst->linesize[2] / 2; + src_lum_line += src->linesize[0]; + src_cb_line += src->linesize[1]; + src_cr_line += src->linesize[2]; + } +} + +static void +yuv444p_to_yuv422p10le (AVPicture * dst, const AVPicture * src, int width, + int height) +{ + int w, h; + uint16_t *dst_lum1, *dst_line = (uint16_t *) dst->data[0]; + uint16_t *dst_cb1, *dst_cb_line = (uint16_t *) dst->data[1]; + uint16_t *dst_cr1, *dst_cr_line = (uint16_t *) dst->data[2]; + uint8_t *lum1, *src_lum_line = src->data[0]; + uint8_t *src_cb1, *src_cb_line = src->data[1]; + uint8_t *src_cr1, *src_cr_line = src->data[2]; + uint16_t y1, y2, cb, cr; + + for (h = height; h--;) { + dst_lum1 = dst_line; + + dst_cb1 = dst_cb_line; + dst_cr1 = dst_cr_line; + + lum1 = src_lum_line; + + src_cb1 = src_cb_line; + src_cr1 = src_cr_line; + + for (w = width / 2; w--;) { + cb = *src_cb1++; + cb += *src_cb1++; + cr = *src_cr1++; + cr += *src_cr1++; + y1 = *lum1++; + y2 = *lum1++; + cb = cb << 5; + cr = cr << 5; + y1 = y1 << 6; + y2 = y2 << 6; + + *dst_lum1++ = GUINT16_TO_LE (y1); + *dst_lum1++ = GUINT16_TO_LE (y2); + *dst_cb1++ = GUINT16_TO_LE (cb); + *dst_cr1++ = GUINT16_TO_LE (cr); + } + + /* odd width */ + if (width % 2 != 0) { + cb = *src_cb1++; + cr = *src_cr1++; + y1 = *lum1++; + + cb = cb << 6; + cr = cr << 6; + y1 = y1 << 6; + + *dst_lum1++ = GUINT16_TO_LE (y1); + *dst_cb1++ = GUINT16_TO_LE (cb); + *dst_cr1++ = GUINT16_TO_LE (cr); + } + + dst_line += dst->linesize[0] / 2; + dst_cb_line += dst->linesize[1] / 2; + dst_cr_line += dst->linesize[2] / 2; + src_lum_line += src->linesize[0]; + src_cb_line += src->linesize[1]; + src_cr_line += src->linesize[2]; + } +} + +static void +yuv444p10be_to_yuv444p (AVPicture * dst, const AVPicture * src, int width, + int height) +{ + int w, h; + uint8_t *dst_lum1, *dst_line = dst->data[0]; + uint8_t *dst_cb1, *dst_cb_line = dst->data[1]; + uint8_t *dst_cr1, *dst_cr_line = dst->data[2]; + uint16_t *lum1, *src_lum_line = (uint16_t *) src->data[0]; + uint16_t *src_cb1, *src_cb_line = (uint16_t *) src->data[1]; + uint16_t *src_cr1, *src_cr_line = (uint16_t *) src->data[2]; + uint16_t y1, cb, cr; + + for (h = height; h--;) { + dst_lum1 = dst_line; + + dst_cb1 = dst_cb_line; + dst_cr1 = dst_cr_line; + + lum1 = src_lum_line; + + src_cb1 = src_cb_line; + src_cr1 = src_cr_line; + + for (w = width; w--;) { + cb = *src_cb1++; + cr = *src_cr1++; + y1 = *lum1++; + cb = GUINT16_FROM_BE (cb) >> 6; + cr = GUINT16_FROM_BE (cr) >> 6; + y1 = GUINT16_FROM_BE (y1) >> 6; + + *dst_lum1++ = y1; + *dst_cb1++ = cb; + *dst_cr1++ = cr; + } + + dst_line += dst->linesize[0]; + dst_cb_line += dst->linesize[1]; + dst_cr_line += dst->linesize[2]; + src_lum_line += src->linesize[0] / 2; + src_cb_line += src->linesize[1] / 2; + src_cr_line += src->linesize[2] / 2; + } +} + +static void +yuv444p10le_to_yuv444p (AVPicture * dst, const AVPicture * src, int width, + int height) +{ + int w, h; + uint8_t *dst_lum1, *dst_line = dst->data[0]; + uint8_t *dst_cb1, *dst_cb_line = dst->data[1]; + uint8_t *dst_cr1, *dst_cr_line = dst->data[2]; + uint16_t *lum1, *src_lum_line = (uint16_t *) src->data[0]; + uint16_t *src_cb1, *src_cb_line = (uint16_t *) src->data[1]; + uint16_t *src_cr1, *src_cr_line = (uint16_t *) src->data[2]; + uint16_t y1, cb, cr; + + for (h = height; h--;) { + dst_lum1 = dst_line; + + dst_cb1 = dst_cb_line; + dst_cr1 = dst_cr_line; + + lum1 = src_lum_line; + + src_cb1 = src_cb_line; + src_cr1 = src_cr_line; + + for (w = width; w--;) { + cb = *src_cb1++; + cr = *src_cr1++; + y1 = *lum1++; + cb = GUINT16_FROM_LE (cb) >> 6; + cr = GUINT16_FROM_LE (cr) >> 6; + y1 = GUINT16_FROM_LE (y1) >> 6; + + *dst_lum1++ = y1; + *dst_cb1++ = cb; + *dst_cr1++ = cr; + } + + dst_line += dst->linesize[0]; + dst_cb_line += dst->linesize[1]; + dst_cr_line += dst->linesize[2]; + src_lum_line += src->linesize[0] / 2; + src_cb_line += src->linesize[1] / 2; + src_cr_line += src->linesize[2] / 2; + } +} + +static void +yuv444p_to_yuv444p10be (AVPicture * dst, const AVPicture * src, int width, + int height) +{ + int w, h; + uint16_t *dst_lum1, *dst_line = (uint16_t *) dst->data[0]; + uint16_t *dst_cb1, *dst_cb_line = (uint16_t *) dst->data[1]; + uint16_t *dst_cr1, *dst_cr_line = (uint16_t *) dst->data[2]; + uint8_t *lum1, *src_lum_line = src->data[0]; + uint8_t *src_cb1, *src_cb_line = src->data[1]; + uint8_t *src_cr1, *src_cr_line = src->data[2]; + uint16_t y1, cb, cr; + + for (h = height; h--;) { + dst_lum1 = dst_line; + + dst_cb1 = dst_cb_line; + dst_cr1 = dst_cr_line; + + lum1 = src_lum_line; + + src_cb1 = src_cb_line; + src_cr1 = src_cr_line; + + for (w = width; w--;) { + cb = *src_cb1++; + cr = *src_cr1++; + y1 = *lum1++; + cb = cb << 6; + cr = cr << 6; + y1 = y1 << 6; + + *dst_lum1++ = GUINT16_TO_BE (y1); + *dst_cb1++ = GUINT16_TO_BE (cb); + *dst_cr1++ = GUINT16_TO_BE (cr); + } + + dst_line += dst->linesize[0] / 2; + dst_cb_line += dst->linesize[1] / 2; + dst_cr_line += dst->linesize[2] / 2; + src_lum_line += src->linesize[0]; + src_cb_line += src->linesize[1]; + src_cr_line += src->linesize[2]; + } +} + +static void +yuv444p_to_yuv444p10le (AVPicture * dst, const AVPicture * src, int width, + int height) +{ + int w, h; + uint16_t *dst_lum1, *dst_line = (uint16_t *) dst->data[0]; + uint16_t *dst_cb1, *dst_cb_line = (uint16_t *) dst->data[1]; + uint16_t *dst_cr1, *dst_cr_line = (uint16_t *) dst->data[2]; + uint8_t *lum1, *src_lum_line = src->data[0]; + uint8_t *src_cb1, *src_cb_line = src->data[1]; + uint8_t *src_cr1, *src_cr_line = src->data[2]; + uint16_t y1, cb, cr; + + for (h = height; h--;) { + dst_lum1 = dst_line; + + dst_cb1 = dst_cb_line; + dst_cr1 = dst_cr_line; + + lum1 = src_lum_line; + + src_cb1 = src_cb_line; + src_cr1 = src_cr_line; + + for (w = width; w--;) { + cb = *src_cb1++; + cr = *src_cr1++; + y1 = *lum1++; + cb = cb << 6; + cr = cr << 6; + y1 = y1 << 6; + + *dst_lum1++ = GUINT16_TO_LE (y1); + *dst_cb1++ = GUINT16_TO_LE (cb); + *dst_cr1++ = GUINT16_TO_LE (cr); + } + + dst_line += dst->linesize[0] / 2; + dst_cb_line += dst->linesize[1] / 2; + dst_cr_line += dst->linesize[2] / 2; + src_lum_line += src->linesize[0]; + src_cb_line += src->linesize[1]; + src_cr_line += src->linesize[2]; + } +} + #define SCALEBITS 10 #define ONE_HALF (1 << (SCALEBITS - 1)) #define FIX(x) ((int) ((x) * (1<<SCALEBITS) + 0.5)) @@ -3571,6 +4581,20 @@ static ConvertEntry convert_table[] = { {PIX_FMT_YUVA420P, PIX_FMT_BGRA32, yuva420p_to_bgra32}, {PIX_FMT_YUVA420P, PIX_FMT_ARGB32, yuva420p_to_argb32}, {PIX_FMT_YUVA420P, PIX_FMT_ABGR32, yuva420p_to_abgr32}, + + {PIX_FMT_YUV420P10BE, PIX_FMT_YUV444P, yuv420p10be_to_yuv444p}, + {PIX_FMT_YUV420P10LE, PIX_FMT_YUV444P, yuv420p10le_to_yuv444p}, + {PIX_FMT_YUV422P10BE, PIX_FMT_YUV444P, yuv422p10be_to_yuv444p}, + {PIX_FMT_YUV422P10LE, PIX_FMT_YUV444P, yuv422p10le_to_yuv444p}, + {PIX_FMT_YUV444P10BE, PIX_FMT_YUV444P, yuv444p10be_to_yuv444p}, + {PIX_FMT_YUV444P10LE, PIX_FMT_YUV444P, yuv444p10le_to_yuv444p}, + + {PIX_FMT_YUV444P, PIX_FMT_YUV420P10BE, yuv444p_to_yuv420p10be}, + {PIX_FMT_YUV444P, PIX_FMT_YUV420P10LE, yuv444p_to_yuv420p10le}, + {PIX_FMT_YUV444P, PIX_FMT_YUV422P10BE, yuv444p_to_yuv422p10be}, + {PIX_FMT_YUV444P, PIX_FMT_YUV422P10LE, yuv444p_to_yuv422p10le}, + {PIX_FMT_YUV444P, PIX_FMT_YUV444P10BE, yuv444p_to_yuv444p10be}, + {PIX_FMT_YUV444P, PIX_FMT_YUV444P10LE, yuv444p_to_yuv444p10le}, }; static ConvertEntry * |