From 1ccf6a1bebe5ceb3c5ff55595e25266e72e01deb Mon Sep 17 00:00:00 2001 From: Uoti Urpala Date: Wed, 22 Aug 2012 17:58:21 +0300 Subject: [PATCH] video: support GBR mode h264 decoding Add support for GBR pixel formats (used by special x264 encoding mode). When these formats are not directly supported, converting them to RGB would be sanest. However, it seems that currently libswscale only supports GBRP* -> RGB conversions in the 8-bit case. So only add entries to the vf_scale preferred conversions list for that case. Also add 422P9 support (for some reason only depths 8, 10 and 16 were supported for 422). --- fmt-conversion.c | 5 +++++ libmpcodecs/img_format.c | 17 +++++++++++++++++ libmpcodecs/img_format.h | 17 +++++++++++++++++ libmpcodecs/mp_image.c | 9 ++++++++- libmpcodecs/vf_scale.c | 9 +++++++++ 5 files changed, 56 insertions(+), 1 deletion(-) diff --git a/fmt-conversion.c b/fmt-conversion.c index 2604c7e974..5b6ac4b07b 100644 --- a/fmt-conversion.c +++ b/fmt-conversion.c @@ -55,6 +55,9 @@ static const struct { {IMGFMT_RGB8, PIX_FMT_BGR8}, {IMGFMT_RGB4, PIX_FMT_BGR4}, {IMGFMT_BGR8, PIX_FMT_PAL8}, + {IMGFMT_GBRP, PIX_FMT_GBRP}, + {IMGFMT_GBRP9, PIX_FMT_GBRP9}, + {IMGFMT_GBRP10, PIX_FMT_GBRP10}, {IMGFMT_YUY2, PIX_FMT_YUYV422}, {IMGFMT_UYVY, PIX_FMT_UYVY422}, {IMGFMT_NV12, PIX_FMT_NV12}, @@ -87,6 +90,8 @@ static const struct { {IMGFMT_444P10_LE, PIX_FMT_YUV444P10LE}, {IMGFMT_422P16_LE, PIX_FMT_YUV422P16LE}, {IMGFMT_422P16_BE, PIX_FMT_YUV422P16BE}, + {IMGFMT_422P9_LE, PIX_FMT_YUV422P9LE}, + {IMGFMT_422P9_BE, PIX_FMT_YUV422P9BE}, {IMGFMT_444P16_LE, PIX_FMT_YUV444P16LE}, {IMGFMT_444P16_BE, PIX_FMT_YUV444P16BE}, diff --git a/libmpcodecs/img_format.c b/libmpcodecs/img_format.c index 19c3ede56d..50d2fe3eb8 100644 --- a/libmpcodecs/img_format.c +++ b/libmpcodecs/img_format.c @@ -33,6 +33,8 @@ const struct imgfmt_name mp_imgfmt_list[] = { {"422p16be", IMGFMT_422P16_BE}, {"422p10le", IMGFMT_422P10_LE}, {"422p10be", IMGFMT_422P10_BE}, + {"422p9le", IMGFMT_422P9_LE}, + {"422p9be", IMGFMT_422P9_BE}, {"420p16le", IMGFMT_420P16_LE}, {"420p16be", IMGFMT_420P16_BE}, {"420p10le", IMGFMT_420P10_LE}, @@ -44,6 +46,7 @@ const struct imgfmt_name mp_imgfmt_list[] = { {"444p9", IMGFMT_444P9}, {"422p16", IMGFMT_422P16}, {"422p10", IMGFMT_422P10}, + {"422p9", IMGFMT_422P9}, {"420p10", IMGFMT_420P10}, {"420p9", IMGFMT_420P9}, {"420p16", IMGFMT_420P16}, @@ -91,6 +94,13 @@ const struct imgfmt_name mp_imgfmt_list[] = { {"argb", IMGFMT_ARGB}, {"bgra", IMGFMT_BGRA}, {"abgr", IMGFMT_ABGR}, + {"gbrp", IMGFMT_GBRP}, + {"gbrp9", IMGFMT_GBRP9}, + {"gbrp9le", IMGFMT_GBRP9LE}, + {"gbrp9be", IMGFMT_GBRP9BE}, + {"gbrp10", IMGFMT_GBRP10}, + {"gbrp10le", IMGFMT_GBRP10LE}, + {"gbrp10be", IMGFMT_GBRP10BE}, {"mjpeg", IMGFMT_MJPEG}, {"mjpg", IMGFMT_MJPEG}, { NULL, 0 } @@ -149,6 +159,11 @@ const char *vo_format_name(int format) case IMGFMT_BGRA: return "BGRA"; case IMGFMT_ARGB: return "ARGB"; case IMGFMT_RGBA: return "RGBA"; + case IMGFMT_GBRP: return "Planar GBR 24-bit"; + case IMGFMT_GBRP9LE: return "Planar GBR 27-bit little-endian"; + case IMGFMT_GBRP9BE: return "Planar GBR 27-bit big-endian"; + case IMGFMT_GBRP10LE: return "Planar GBR 30-bit little-endian"; + case IMGFMT_GBRP10BE: return "Planar GBR 30-bit big-endian"; case IMGFMT_YVU9: return "Planar YVU9"; case IMGFMT_IF09: return "Planar IF09"; case IMGFMT_YV12: return "Planar YV12"; @@ -167,6 +182,8 @@ const char *vo_format_name(int format) case IMGFMT_422P16_BE: return "Planar 422P 16-bit big-endian"; case IMGFMT_422P10_LE: return "Planar 422P 10-bit little-endian"; case IMGFMT_422P10_BE: return "Planar 422P 10-bit big-endian"; + case IMGFMT_422P9_LE: return "Planar 422P 9-bit little-endian"; + case IMGFMT_422P9_BE: return "Planar 422P 9-bit big-endian"; case IMGFMT_444P16_LE: return "Planar 444P 16-bit little-endian"; case IMGFMT_444P16_BE: return "Planar 444P 16-bit big-endian"; case IMGFMT_444P10_LE: return "Planar 444P 10-bit little-endian"; diff --git a/libmpcodecs/img_format.h b/libmpcodecs/img_format.h index 0f7d38a088..941afcffda 100644 --- a/libmpcodecs/img_format.h +++ b/libmpcodecs/img_format.h @@ -52,6 +52,10 @@ #define IMGFMT_BGR24 (IMGFMT_BGR|24) #define IMGFMT_BGR32 (IMGFMT_BGR|32) +#define IMGFMT_GBRP (('G'<<24)|('B'<<16)|('R'<<8)|24) +#define IMGFMT_GBRP9 (('G'<<24)|('B'<<16)|('R'<<8)|27) +#define IMGFMT_GBRP10 (('G'<<24)|('B'<<16)|('R'<<8)|30) + #if HAVE_BIGENDIAN #define IMGFMT_ABGR IMGFMT_RGB32 #define IMGFMT_BGRA (IMGFMT_RGB32|64) @@ -70,6 +74,10 @@ #define IMGFMT_BGR15LE (IMGFMT_BGR15|64) #define IMGFMT_BGR16BE IMGFMT_BGR16 #define IMGFMT_BGR16LE (IMGFMT_BGR16|64) +#define IMGFMT_GBRP9BE IMGFMT_GBRP9 +#define IMGFMT_GBRP9LE (IMGFMT_GBRP9 | 64) +#define IMGFMT_GBRP10BE IMGFMT_GBRP10 +#define IMGFMT_GBRP10LE (IMGFMT_GBRP10 | 64) #else #define IMGFMT_ABGR (IMGFMT_BGR32|64) #define IMGFMT_BGRA IMGFMT_BGR32 @@ -88,6 +96,10 @@ #define IMGFMT_BGR15LE IMGFMT_BGR15 #define IMGFMT_BGR16BE (IMGFMT_BGR16|64) #define IMGFMT_BGR16LE IMGFMT_BGR16 +#define IMGFMT_GBRP9BE (IMGFMT_GBRP9 | 64) +#define IMGFMT_GBRP9LE IMGFMT_GBRP9 +#define IMGFMT_GBRP10BE (IMGFMT_GBRP10 | 64) +#define IMGFMT_GBRP10LE IMGFMT_GBRP10 #endif /* old names for compatibility */ @@ -96,6 +108,7 @@ #define IMGFMT_IS_RGB(fmt) (((fmt)&IMGFMT_RGB_MASK)==IMGFMT_RGB) #define IMGFMT_IS_BGR(fmt) (((fmt)&IMGFMT_BGR_MASK)==IMGFMT_BGR) +#define IMGFMT_IS_GBRP(fmt) (((fmt)&0xffffff00) == (IMGFMT_GBRP&0xffffff00)) #define IMGFMT_RGB_DEPTH(fmt) ((fmt)&0x3F) #define IMGFMT_BGR_DEPTH(fmt) ((fmt)&0x3F) @@ -134,6 +147,8 @@ #define IMGFMT_422P16_BE 0x34323251 #define IMGFMT_422P10_LE 0x52323234 #define IMGFMT_422P10_BE 0x34323252 +#define IMGFMT_422P9_LE 0x53323234 +#define IMGFMT_422P9_BE 0x34323253 #define IMGFMT_420P16_LE 0x51303234 #define IMGFMT_420P16_BE 0x34323051 #define IMGFMT_420P10_LE 0x52303234 @@ -146,6 +161,7 @@ #define IMGFMT_444P9 IMGFMT_444P9_BE #define IMGFMT_422P16 IMGFMT_422P16_BE #define IMGFMT_422P10 IMGFMT_422P10_BE +#define IMGFMT_422P9 IMGFMT_422P9_BE #define IMGFMT_420P16 IMGFMT_420P16_BE #define IMGFMT_420P10 IMGFMT_420P10_BE #define IMGFMT_420P9 IMGFMT_420P9_BE @@ -156,6 +172,7 @@ #define IMGFMT_444P9 IMGFMT_444P9_LE #define IMGFMT_422P16 IMGFMT_422P16_LE #define IMGFMT_422P10 IMGFMT_422P10_LE +#define IMGFMT_422P9 IMGFMT_422P9_LE #define IMGFMT_420P16 IMGFMT_420P16_LE #define IMGFMT_420P10 IMGFMT_420P10_LE #define IMGFMT_420P9 IMGFMT_420P9_LE diff --git a/libmpcodecs/mp_image.c b/libmpcodecs/mp_image.c index 45426eb673..2dd58a0086 100644 --- a/libmpcodecs/mp_image.c +++ b/libmpcodecs/mp_image.c @@ -119,8 +119,13 @@ void mp_image_setfmt(mp_image_t* mpi,unsigned int out_fmt){ mpi->flags|=MP_IMGFLAG_SWAPPED; return; } - mpi->flags|=MP_IMGFLAG_YUV; mpi->num_planes=3; + if (IMGFMT_IS_GBRP(out_fmt)) { + mpi->bpp = IMGFMT_RGB_DEPTH(out_fmt); + mpi->flags |= MP_IMGFLAG_PLANAR; + return; + } + mpi->flags|=MP_IMGFLAG_YUV; if (mp_get_chroma_shift(out_fmt, NULL, NULL, NULL)) { mpi->flags|=MP_IMGFLAG_PLANAR; mpi->bpp = mp_get_chroma_shift(out_fmt, &mpi->chroma_x_shift, &mpi->chroma_y_shift, NULL); @@ -151,6 +156,8 @@ void mp_image_setfmt(mp_image_t* mpi,unsigned int out_fmt){ case IMGFMT_422P16_BE: case IMGFMT_422P10_LE: case IMGFMT_422P10_BE: + case IMGFMT_422P9_LE: + case IMGFMT_422P9_BE: case IMGFMT_420P16_LE: case IMGFMT_420P16_BE: case IMGFMT_420P10_LE: diff --git a/libmpcodecs/vf_scale.c b/libmpcodecs/vf_scale.c index 9d06a132d9..a9663abdaf 100644 --- a/libmpcodecs/vf_scale.c +++ b/libmpcodecs/vf_scale.c @@ -84,6 +84,8 @@ static const unsigned int outfmt_list[]={ IMGFMT_422P16_BE, IMGFMT_422P10_LE, IMGFMT_422P10_BE, + IMGFMT_422P9_LE, + IMGFMT_422P9_BE, IMGFMT_YV12, IMGFMT_I420, IMGFMT_420P16_LE, @@ -107,6 +109,9 @@ static const unsigned int outfmt_list[]={ IMGFMT_RGB32, IMGFMT_BGR24, IMGFMT_RGB24, + IMGFMT_GBRP, + IMGFMT_GBRP10, + IMGFMT_GBRP9, IMGFMT_RGB48LE, IMGFMT_RGB48BE, IMGFMT_BGR16, @@ -141,6 +146,10 @@ static int preferred_conversions[][2] = { {IMGFMT_UYVY, IMGFMT_422P}, {IMGFMT_422P, IMGFMT_YUY2}, {IMGFMT_422P, IMGFMT_UYVY}, + {IMGFMT_GBRP, IMGFMT_BGR24}, + {IMGFMT_GBRP, IMGFMT_RGB24}, + {IMGFMT_GBRP, IMGFMT_BGR32}, + {IMGFMT_GBRP, IMGFMT_RGB32}, {0, 0} }; -- 2.11.4.GIT