From 00653a3eb0520e9d2409929cd217a5c299be2f5c Mon Sep 17 00:00:00 2001 From: wm4 Date: Mon, 31 Dec 2012 01:58:25 +0100 Subject: video: use libavutil pixel format descriptors Replace the internal pixel format stuff with code that queries the libavutil list of pixel format descriptors. Trying to map IMGFMT_IS_RGB() etc. turned out extremely hacky. --- video/img_format.c | 312 ++++++++++++++++++++++++++++++++++------------------- video/img_format.h | 79 ++++++++++++-- video/mp_image.c | 149 ++++--------------------- video/mp_image.h | 31 +++--- 4 files changed, 307 insertions(+), 264 deletions(-) diff --git a/video/img_format.c b/video/img_format.c index 203c8746db..064cd3b041 100644 --- a/video/img_format.c +++ b/video/img_format.c @@ -16,122 +16,18 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include + +#include +#include + #include "config.h" #include "video/img_format.h" -#include "stdio.h" -#include "compat/mpbswap.h" +#include "video/mp_image.h" +#include "video/fmt-conversion.h" #include -const char *vo_format_name(int format) -{ - const char *name = mp_imgfmt_to_name(format); - if (name) - return name; - static char unknown_format[20]; - snprintf(unknown_format, 20, "Unknown 0x%04x", format); - return unknown_format; -} - -int mp_get_chroma_shift(int format, int *x_shift, int *y_shift, - int *component_bits) -{ - int xs = 0, ys = 0; - int bpp; - int err = 0; - int bits = 8; - if ((format & 0xff0000f0) == 0x34000050) - format = bswap_32(format); - if ((format & 0xf00000ff) == 0x50000034) { - switch (format >> 24) { - case 0x50: - break; - case 0x51: - bits = 16; - break; - case 0x55: - bits = 14; - break; - case 0x54: - bits = 12; - break; - case 0x52: - bits = 10; - break; - case 0x53: - bits = 9; - break; - default: - err = 1; - break; - } - switch (format & 0x00ffffff) { - case 0x00343434: // 444 - xs = 0; - ys = 0; - break; - case 0x00323234: // 422 - xs = 1; - ys = 0; - break; - case 0x00303234: // 420 - xs = 1; - ys = 1; - break; - case 0x00313134: // 411 - xs = 2; - ys = 0; - break; - case 0x00303434: // 440 - xs = 0; - ys = 1; - break; - default: - err = 1; - break; - } - } else - switch (format) { - case IMGFMT_420A: - case IMGFMT_I420: - case IMGFMT_IYUV: - case IMGFMT_YV12: - xs = 1; - ys = 1; - break; - case IMGFMT_IF09: - case IMGFMT_YVU9: - xs = 2; - ys = 2; - break; - case IMGFMT_Y8: - case IMGFMT_Y800: - xs = 31; - ys = 31; - break; - case IMGFMT_Y16BE: - case IMGFMT_Y16LE: - bits = 16; - xs = 31; - ys = 31; - break; - default: - err = 1; - break; - } - if (x_shift) - *x_shift = xs; - if (y_shift) - *y_shift = ys; - if (component_bits) - *component_bits = bits; - bpp = 8 + ((16 >> xs) >> ys); - if (format == IMGFMT_420A) - bpp += 8; - bpp *= (bits + 7) >> 3; - return err ? 0 : bpp; -} - struct mp_imgfmt_entry mp_imgfmt_list[] = { {"444p16le", IMGFMT_444P16_LE}, {"444p16be", IMGFMT_444P16_BE}, @@ -237,6 +133,32 @@ struct mp_imgfmt_entry mp_imgfmt_list[] = { {0} }; +const char *vo_format_name(int format) +{ + const char *name = mp_imgfmt_to_name(format); + if (name) + return name; + static char unknown_format[20]; + snprintf(unknown_format, 20, "Unknown 0x%04x", format); + return unknown_format; +} + +int mp_get_chroma_shift(int format, int *x_shift, int *y_shift, + int *component_bits) +{ + struct mp_imgfmt_desc fmt = mp_imgfmt_get_desc(format); + if (fmt.id && (fmt.flags & MP_IMGFLAG_YUV_P)) { + if (x_shift) + *x_shift = fmt.xs[1]; + if (y_shift) + *y_shift = fmt.ys[1]; + if (component_bits) + *component_bits = fmt.plane_bits; + return fmt.avg_bpp; + } + return 0; +} + unsigned int mp_imgfmt_from_name(bstr name, bool allow_hwaccel) { if (bstr_startswith0(name, "0x")) { @@ -264,3 +186,171 @@ const char *mp_imgfmt_to_name(unsigned int fmt) } return NULL; } + +static int comp_bit_order(const AVPixFmtDescriptor *pd, int bpp, int c) +{ + int el_size = (pd->flags & PIX_FMT_BITSTREAM) ? 1 : 8; + // NOTE: offset_plus1 can be 0 + int offset = (((int)pd->comp[c].offset_plus1) - 1) * el_size; + int read_depth = pd->comp[c].shift + pd->comp[c].depth_minus1 + 1; + if (read_depth <= 8 && !(pd->flags & PIX_FMT_BITSTREAM)) + offset += 8 * !!(pd->flags & PIX_FMT_BE); + offset += pd->comp[c].shift; + // revert ffmpeg's bullshit hack that mixes byte and bit access + if ((pd->flags & PIX_FMT_BE) && bpp <= 16 && read_depth <= 8) + offset = (8 + offset) % 16; + return offset; +} + +static struct mp_imgfmt_desc get_avutil_fmt(enum PixelFormat fmt) +{ + const AVPixFmtDescriptor *pd = &av_pix_fmt_descriptors[fmt]; + int mpfmt = pixfmt2imgfmt(fmt); + if (!pd || !mpfmt) + return (struct mp_imgfmt_desc) {0}; + + struct mp_imgfmt_desc desc = { + .id = mpfmt, + .avformat = fmt, + .name = mp_imgfmt_to_name(desc.id), + .chroma_xs = pd->log2_chroma_w, + .chroma_ys = pd->log2_chroma_h, + }; + + int planedepth[4] = {0}; + int xs[4] = {0, pd->log2_chroma_w, pd->log2_chroma_w, 0}; + int ys[4] = {0, pd->log2_chroma_h, pd->log2_chroma_h, 0}; + int el_size = (pd->flags & PIX_FMT_BITSTREAM) ? 1 : 8; + for (int c = 0; c < pd->nb_components; c++) { + AVComponentDescriptor d = pd->comp[c]; + // multiple components per plane -> Y is definitive, ignore chroma + if (!desc.bpp[d.plane]) + desc.bpp[d.plane] = (d.step_minus1 + 1) * el_size; + planedepth[d.plane] += d.depth_minus1 + 1; + } + + int avgbpp16 = 0; + for (int p = 0; p < 4; p++) + avgbpp16 += (16 * desc.bpp[p]) >> xs[p] >> ys[p]; + desc.avg_bpp = avgbpp16 / 16; + //assert(desc.avg_bpp == av_get_padded_bits_per_pixel(pd)); + + for (int p = 0; p < 4; p++) { + if (desc.bpp[p]) + desc.num_planes++; + } + + if (desc.bpp[0] <= 8 || !(pd->flags & PIX_FMT_BE)) + desc.flags |= MP_IMGFLAG_NE; + + desc.plane_bits = planedepth[0]; + + if (!(pd->flags & PIX_FMT_RGB) && !(pd->flags & PIX_FMT_HWACCEL) && + fmt != PIX_FMT_MONOWHITE && fmt != PIX_FMT_MONOBLACK && + fmt != PIX_FMT_PAL8) + { + desc.flags |= MP_IMGFLAG_YUV; + } + +#ifdef PIX_FMT_ALPHA + if (pd->flags & PIX_FMT_ALPHA) + desc.flags |= MP_IMGFLAG_ALPHA; +#else + if (desc.num_planes > 3) + desc.flags |= MP_IMGFLAG_ALPHA; +#endif + + if (desc.num_planes > 1) + desc.flags |= MP_IMGFLAG_PLANAR; + + if (desc.flags & MP_IMGFLAG_YUV) { + bool same_depth = true; + for (int p = 0; p < desc.num_planes; p++) { + same_depth &= planedepth[p] == planedepth[0] && + desc.bpp[p] == desc.bpp[0]; + } + if (same_depth && pd->nb_components == desc.num_planes) + desc.flags |= MP_IMGFLAG_YUV_P; + } + + if ((pd->flags & PIX_FMT_RGB) && desc.num_planes == 1 + && pd->nb_components >= 3) + { + // RGB vs. BGR component order, as distinguished by mplayer: + // - for byte accessed formats (RGB24, RGB48), the order of bytes + // determines RGB/BGR (e.g. R is first byte -> RGB) + // - for bit accessed formats (RGB32, RGB16, etc.), the order of bits + // determines BGR/RGB (e.g. R is LSB -> RGB) + // - formats like IMGFMT_RGBA are aliases to allow byte access to bit- + // accessed formats (IMGFMT_RGBA is RGB32 on LE, BGR32|128 on BE) + // (ffmpeg does it the other way around, and defines bit-access + // aliases to byte-accessed formats) + int b = desc.bpp[0]; + bool swap = comp_bit_order(pd, b, 0) > comp_bit_order(pd, b, 1); + if ((desc.bpp[0] == 24 || desc.bpp[0] > 32) && BYTE_ORDER == BIG_ENDIAN) + swap = !swap; // byte accessed + if (swap) + desc.flags |= MP_IMGFLAG_SWAPPED; + } + + // compatibility with old mp_image_setfmt() + + switch (desc.id) { + case IMGFMT_I420: + case IMGFMT_IYUV: + desc.flags |= MP_IMGFLAG_SWAPPED; // completely pointless + break; + case IMGFMT_UYVY: + desc.flags |= MP_IMGFLAG_SWAPPED; // for vf_mpi_clear() + /* fallthrough */ + case IMGFMT_YUY2: + desc.chroma_ys = 1; // ??? + break; + case IMGFMT_Y8: + case IMGFMT_Y800: + case IMGFMT_Y16LE: + case IMGFMT_Y16BE: + // probably for vo_opengl, and possibly more code using Y8 + desc.chroma_xs = desc.chroma_ys = 31; + break; + case IMGFMT_NV12: + desc.flags |= MP_IMGFLAG_SWAPPED; // completely pointless + /* fallthrough */ + case IMGFMT_NV21: + // some hack to make cropping code etc. work? (doesn't work anyway) + desc.chroma_xs = 0; + desc.chroma_ys = 1; + break; + case IMGFMT_RGB4: + case IMGFMT_BGR4: + case IMGFMT_BGR1: + desc.flags ^= MP_IMGFLAG_SWAPPED; // ??? + break; + case IMGFMT_BGR0: + desc.flags &= ~MP_IMGFLAG_SWAPPED; // not covered by IS_RGB/IS_BGR + break; + } + + if (pd->flags & PIX_FMT_HWACCEL) + desc.chroma_xs = desc.chroma_ys = 0; + + for (int p = 0; p < desc.num_planes; p++) { + desc.xs[p] = (p == 1 || p == 2) ? desc.chroma_xs : 0; + desc.ys[p] = (p == 1 || p == 2) ? desc.chroma_ys : 0; + } + + return desc; +} + +struct mp_imgfmt_desc mp_imgfmt_get_desc(unsigned int out_fmt) +{ + struct mp_imgfmt_desc fmt = {0}; + enum PixelFormat avfmt = imgfmt2pixfmt(out_fmt); + if (avfmt != PIX_FMT_NONE) + fmt = get_avutil_fmt(avfmt); + if (!fmt.id) { + mp_msg(MSGT_DECVIDEO, MSGL_V, "mp_image: unknown out_fmt: 0x%X\n", + out_fmt); + } + return fmt; +} diff --git a/video/img_format.h b/video/img_format.h index ab657a22d0..6f68cae5d1 100644 --- a/video/img_format.h +++ b/video/img_format.h @@ -23,6 +23,46 @@ #include "config.h" #include "core/bstr.h" +#define MP_MAX_PLANES 4 + +// set if (possibly) alpha is included (might be not definitive for packed RGB) +#define MP_IMGFLAG_ALPHA 0x80 +// set if number of planes > 1 +#define MP_IMGFLAG_PLANAR 0x100 +// set if it's YUV colorspace +#define MP_IMGFLAG_YUV 0x200 +// set if it's swapped (BGR or YVU) plane/byteorder +#define MP_IMGFLAG_SWAPPED 0x400 +// set if you want memory for palette allocated and managed by vf_get_image etc. +#define MP_IMGFLAG_RGB_PALETTE 0x800 +// set if the format is standard YUV format: +// - planar and yuv colorspace +// - chroma shift 0-2 +// - 1-4 planes (1: gray, 2: gray/alpha, 3: yuv, 4: yuv/alpha) +// - 8-16 bit per pixel/plane, all planes have same depth +#define MP_IMGFLAG_YUV_P 0x1000 +// set if format is in native endian, or <= 8 bit per pixel/plane +#define MP_IMGFLAG_NE 0x2000 + +#define MP_IMGFLAG_FMT_MASK 0x3FFF + +struct mp_imgfmt_desc { + int id; // IMGFMT_* + int avformat; // AV_PIX_FMT_* (or AV_PIX_FMT_NONE) + const char *name; // e.g. "420p16" + int flags; // MP_IMGFLAG_* bitfield + int num_planes; + int chroma_xs, chroma_ys; // chroma shift (i.e. log2 of chroma pixel size) + int avg_bpp; + int bpp[MP_MAX_PLANES]; + int plane_bits; // number of bits in use for plane 0 + // chroma shifts per plane (provided for convenience with planar formats) + int xs[MP_MAX_PLANES]; + int ys[MP_MAX_PLANES]; +}; + +struct mp_imgfmt_desc mp_imgfmt_get_desc(unsigned int out_fmt); + /* RGB/BGR Formats */ #define IMGFMT_RGB_MASK 0xFFFFFF00 @@ -95,14 +135,26 @@ #define IMGFMT_RG4B IMGFMT_RGB4_CHAR #define IMGFMT_BG4B IMGFMT_BGR4_CHAR -#define IMGFMT_IS_RGB(fmt) (((fmt)&IMGFMT_RGB_MASK)==IMGFMT_RGB) -#define IMGFMT_IS_BGR(fmt) (((fmt)&IMGFMT_BGR_MASK)==IMGFMT_BGR) - -#define IMGFMT_RGB_DEPTH(fmt) ((fmt)&0x3F) -#define IMGFMT_BGR_DEPTH(fmt) ((fmt)&0x3F) // AV_PIX_FMT_BGR0 #define IMGFMT_BGR0 0x1DC70000 + +static inline bool IMGFMT_IS_RGB(unsigned int fmt) +{ + struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(fmt); + return !(desc.flags & MP_IMGFLAG_YUV) && !(desc.flags & MP_IMGFLAG_SWAPPED) + && desc.num_planes == 1 && desc.id != IMGFMT_BGR0; +} +static inline bool IMGFMT_IS_BGR(unsigned int fmt) +{ + struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(fmt); + return !(desc.flags & MP_IMGFLAG_YUV) && (desc.flags & MP_IMGFLAG_SWAPPED) + && desc.num_planes == 1 && desc.id != IMGFMT_BGR0; +} + +#define IMGFMT_RGB_DEPTH(fmt) (mp_imgfmt_get_desc(fmt).plane_bits) +#define IMGFMT_BGR_DEPTH(fmt) (mp_imgfmt_get_desc(fmt).plane_bits) + // AV_PIX_FMT_GRAY16LE #define IMGFMT_Y16LE 0x1DC70001 // AV_PIX_FMT_GRAY16BE @@ -203,9 +255,20 @@ #define IMGFMT_IS_YUVP16_NE(fmt) IMGFMT_IS_YUVP16_LE(fmt) #endif -// These macros are misnamed - they actually match 9 to 16 bits (inclusive) -#define IMGFMT_IS_YUVP16_LE(fmt) (((fmt - 0x51000034) & 0xf80000ff) == 0 || fmt == IMGFMT_Y16LE) -#define IMGFMT_IS_YUVP16_BE(fmt) (((fmt - 0x34000051) & 0xff0000f8) == 0 || fmt == IMGFMT_Y16BE) +// These functions are misnamed - they actually match 9 to 16 bits (inclusive) +static inline bool IMGFMT_IS_YUVP16_LE(int fmt) { + struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(fmt); + bool le_is_ne = BYTE_ORDER == LITTLE_ENDIAN; + return (desc.flags & MP_IMGFLAG_YUV_P) && desc.plane_bits > 8 && + (le_is_ne == !!(desc.flags & MP_IMGFLAG_NE)); +} +static inline bool IMGFMT_IS_YUVP16_BE(int fmt) { + struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(fmt); + bool be_is_ne = BYTE_ORDER == BIG_ENDIAN; + return (desc.flags & MP_IMGFLAG_YUV_P) && desc.plane_bits > 8 && + (be_is_ne == !!(desc.flags & MP_IMGFLAG_NE)); +} + #define IMGFMT_IS_YUVP16(fmt) (IMGFMT_IS_YUVP16_LE(fmt) || IMGFMT_IS_YUVP16_BE(fmt)) /* Packed YUV Formats */ diff --git a/video/mp_image.c b/video/mp_image.c index 7695538b84..7479c98c62 100644 --- a/video/mp_image.c +++ b/video/mp_image.c @@ -23,16 +23,16 @@ #include #include +#include +#include + #include "talloc.h" #include "video/img_format.h" #include "video/mp_image.h" #include "video/sws_utils.h" #include "video/filter/vf.h" - #include "video/memcpy_pic.h" -#include "libavutil/mem.h" -#include "libavutil/common.h" struct m_refcount { void *arg; @@ -161,129 +161,18 @@ void mp_image_copy_attributes(struct mp_image *dmpi, struct mp_image *mpi) vf_clone_mpi_attributes(dmpi, mpi); } -void mp_image_setfmt(mp_image_t* mpi,unsigned int out_fmt){ - mpi->flags&=~(MP_IMGFLAG_PLANAR|MP_IMGFLAG_YUV|MP_IMGFLAG_SWAPPED); - mpi->imgfmt=out_fmt; - // compressed formats - if(IMGFMT_IS_HWACCEL(out_fmt)){ - mpi->bpp=0; - return; - } - mpi->num_planes=1; - if (IMGFMT_IS_RGB(out_fmt)) { - if (IMGFMT_RGB_DEPTH(out_fmt) < 8 && !(out_fmt&128)) - mpi->bpp = IMGFMT_RGB_DEPTH(out_fmt); - else - mpi->bpp=(IMGFMT_RGB_DEPTH(out_fmt)+7)&(~7); - return; - } - if (IMGFMT_IS_BGR(out_fmt)) { - if (IMGFMT_BGR_DEPTH(out_fmt) < 8 && !(out_fmt&128)) - mpi->bpp = IMGFMT_BGR_DEPTH(out_fmt); - else - mpi->bpp=(IMGFMT_BGR_DEPTH(out_fmt)+7)&(~7); - mpi->flags|=MP_IMGFLAG_SWAPPED; - return; - } - switch (out_fmt) { - case IMGFMT_BGR0: - mpi->bpp = 32; - return; - } - mpi->num_planes=3; - if (out_fmt == IMGFMT_GBRP) { - mpi->bpp=24; - mpi->flags|=MP_IMGFLAG_PLANAR; - mpi->chroma_x_shift = 0; - mpi->chroma_y_shift = 0; - mpi->chroma_width=mpi->w; - mpi->chroma_height=mpi->h; - 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); - mpi->chroma_width = mpi->w >> mpi->chroma_x_shift; - mpi->chroma_height = mpi->h >> mpi->chroma_y_shift; - } - switch(out_fmt){ - case IMGFMT_I420: - case IMGFMT_IYUV: - mpi->flags|=MP_IMGFLAG_SWAPPED; - case IMGFMT_YV12: - return; - case IMGFMT_420A: - case IMGFMT_IF09: - mpi->num_planes=4; - case IMGFMT_YVU9: - case IMGFMT_444P: - case IMGFMT_422P: - case IMGFMT_411P: - case IMGFMT_440P: - case IMGFMT_444P16_LE: - case IMGFMT_444P16_BE: - case IMGFMT_444P14_LE: - case IMGFMT_444P14_BE: - case IMGFMT_444P12_LE: - case IMGFMT_444P12_BE: - case IMGFMT_444P10_LE: - case IMGFMT_444P10_BE: - case IMGFMT_444P9_LE: - case IMGFMT_444P9_BE: - case IMGFMT_422P16_LE: - case IMGFMT_422P16_BE: - case IMGFMT_422P14_LE: - case IMGFMT_422P14_BE: - case IMGFMT_422P12_LE: - case IMGFMT_422P12_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_420P14_LE: - case IMGFMT_420P14_BE: - case IMGFMT_420P12_LE: - case IMGFMT_420P12_BE: - case IMGFMT_420P10_LE: - case IMGFMT_420P10_BE: - case IMGFMT_420P9_LE: - case IMGFMT_420P9_BE: - return; - case IMGFMT_Y800: - case IMGFMT_Y8: - case IMGFMT_Y16LE: - case IMGFMT_Y16BE: - /* they're planar ones, but for easier handling use them as packed */ - mpi->flags&=~MP_IMGFLAG_PLANAR; - mpi->num_planes=1; - return; - case IMGFMT_UYVY: - mpi->flags|=MP_IMGFLAG_SWAPPED; - case IMGFMT_YUY2: - mpi->chroma_x_shift = 1; - mpi->chroma_y_shift = 1; - mpi->chroma_width=(mpi->w>>1); - mpi->chroma_height=(mpi->h>>1); - mpi->bpp=16; - mpi->num_planes=1; - return; - case IMGFMT_NV12: - mpi->flags|=MP_IMGFLAG_SWAPPED; - case IMGFMT_NV21: - mpi->flags|=MP_IMGFLAG_PLANAR; - mpi->bpp=12; - mpi->num_planes=2; - mpi->chroma_width=(mpi->w>>0); - mpi->chroma_height=(mpi->h>>1); - mpi->chroma_x_shift=0; - mpi->chroma_y_shift=1; - return; - } - mp_msg(MSGT_DECVIDEO,MSGL_WARN,"mp_image: unknown out_fmt: 0x%X\n",out_fmt); - mpi->bpp=0; +void mp_image_setfmt(struct mp_image *mpi, unsigned int out_fmt) +{ + mpi->flags &= ~MP_IMGFLAG_FMT_MASK; + struct mp_imgfmt_desc fmt = mp_imgfmt_get_desc(out_fmt); + mpi->fmt = fmt; + mpi->flags |= fmt.flags; + mpi->imgfmt = fmt.id; + mpi->bpp = fmt.avg_bpp; + mpi->chroma_x_shift = fmt.chroma_xs; + mpi->chroma_y_shift = fmt.chroma_ys; + mpi->num_planes = fmt.num_planes; + mp_image_set_size(mpi, mpi->w, mpi->h); } static int mp_image_destructor(void *ptr) @@ -318,8 +207,12 @@ void mp_image_set_size(struct mp_image *mpi, int w, int h) { mpi->w = w; mpi->h = h; - mpi->chroma_width = mpi->w >> mpi->chroma_x_shift; - mpi->chroma_height = mpi->h >> mpi->chroma_y_shift; + for (int n = 0; n < mpi->num_planes; n++) { + mpi->plane_w[n] = mpi->w >> mpi->fmt.xs[n]; + mpi->plane_h[n] = mpi->h >> mpi->fmt.ys[n]; + } + mpi->chroma_width = mpi->plane_w[1]; + mpi->chroma_height = mpi->plane_h[1]; mpi->display_w = mpi->display_h = 0; } diff --git a/video/mp_image.h b/video/mp_image.h index c8bf113fd2..3a86dc5fcd 100644 --- a/video/mp_image.h +++ b/video/mp_image.h @@ -26,26 +26,14 @@ #include #include "core/mp_msg.h" #include "csputils.h" +#include "video/img_format.h" // Minimum stride alignment in pixels #define MP_STRIDE_ALIGNMENT 32 -//--------- color info (filled by mp_image_setfmt() ) ----------- -// set if number of planes > 1 -#define MP_IMGFLAG_PLANAR 0x100 -// set if it's YUV colorspace -#define MP_IMGFLAG_YUV 0x200 -// set if it's swapped (BGR or YVU) plane/byteorder -#define MP_IMGFLAG_SWAPPED 0x400 -// set if you want memory for palette allocated and managed by vf_get_image etc. -#define MP_IMGFLAG_RGB_PALETTE 0x800 - - // set if buffer is allocated (used in destination images): #define MP_IMGFLAG_ALLOCATED 0x4000 -#define MP_MAX_PLANES 4 - #define MP_IMGFIELD_ORDERED 0x01 #define MP_IMGFIELD_TOP_FIRST 0x02 #define MP_IMGFIELD_REPEAT_FIRST 0x04 @@ -71,23 +59,32 @@ */ typedef struct mp_image { unsigned int flags; + struct mp_imgfmt_desc fmt; + + // fields redundant to fmt, for convenience or compatibility unsigned char bpp; // bits/pixel. NOT depth! for RGB it will be n*8 unsigned int imgfmt; + int num_planes; + int chroma_x_shift; // horizontal + int chroma_y_shift; // vertical + int w,h; // visible dimensions int display_w,display_h; // if set (!= 0), anamorphic size uint8_t *planes[MP_MAX_PLANES]; int stride[MP_MAX_PLANES]; + char * qscale; int qstride; int pict_type; // 0->unknown, 1->I, 2->P, 3->B int fields; int qscale_type; // 0->mpeg1/4/h263, 1->mpeg2 - int num_planes; - /* these are only used by planar formats Y,U(Cb),V(Cr) */ + + /* redundant */ int chroma_width; int chroma_height; - int chroma_x_shift; // horizontal - int chroma_y_shift; // vertical + int plane_w[MP_MAX_PLANES]; + int plane_h[MP_MAX_PLANES]; + enum mp_csp colorspace; enum mp_csp_levels levels; /* only inside filter chain */ -- cgit v1.2.3