diff options
author | Uoti Urpala <uau@glyph.nonexistent.invalid> | 2010-01-08 01:05:30 +0200 |
---|---|---|
committer | Uoti Urpala <uau@glyph.nonexistent.invalid> | 2010-01-08 01:05:30 +0200 |
commit | 231b33a02fae95b260120349040106bfa34a3750 (patch) | |
tree | 23c4de0e6263b2d99966348d7003177b3b3e3740 /libmpcodecs | |
parent | 52126e574c7872ca95e7974cfe5445421b74f24c (diff) | |
parent | 92cd6dc3e916ae4275ff05d2b238fc778cfbfc6b (diff) | |
download | mpv-231b33a02fae95b260120349040106bfa34a3750.tar.bz2 mpv-231b33a02fae95b260120349040106bfa34a3750.tar.xz |
Merge svn changes up to r30165
Diffstat (limited to 'libmpcodecs')
-rw-r--r-- | libmpcodecs/img_format.c | 64 | ||||
-rw-r--r-- | libmpcodecs/img_format.h | 32 | ||||
-rw-r--r-- | libmpcodecs/mp_image.c | 59 | ||||
-rw-r--r-- | libmpcodecs/mp_image.h | 48 | ||||
-rw-r--r-- | libmpcodecs/vd_ffmpeg.c | 4 | ||||
-rw-r--r-- | libmpcodecs/vf.c | 39 | ||||
-rw-r--r-- | libmpcodecs/vf_scale.c | 26 |
7 files changed, 173 insertions, 99 deletions
diff --git a/libmpcodecs/img_format.c b/libmpcodecs/img_format.c index 7d20a77cc7..31cb3591bb 100644 --- a/libmpcodecs/img_format.c +++ b/libmpcodecs/img_format.c @@ -37,6 +37,13 @@ const char *vo_format_name(int format) case IMGFMT_CLPL: return "Planar CLPL"; case IMGFMT_Y800: return "Planar Y800"; case IMGFMT_Y8: return "Planar Y8"; + case IMGFMT_420P16_LE: return "Planar 420P 16-bit little-endian"; + case IMGFMT_420P16_BE: return "Planar 420P 16-bit big-endian"; + case IMGFMT_422P16_LE: return "Planar 422P 16-bit little-endian"; + case IMGFMT_422P16_BE: return "Planar 422P 16-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_420A: return "Planar 420P with alpha"; case IMGFMT_444P: return "Planar 444P"; case IMGFMT_422P: return "Planar 422P"; case IMGFMT_411P: return "Planar 411P"; @@ -79,3 +86,60 @@ const char *vo_format_name(int format) 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 xs = 0, ys = 0; + int bpp; + int bpp_factor = 1; + int err = 0; + switch (format) { + case IMGFMT_420P16_LE: + case IMGFMT_420P16_BE: + bpp_factor = 2; + 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_444P16_LE: + case IMGFMT_444P16_BE: + bpp_factor = 2; + case IMGFMT_444P: + xs = 0; + ys = 0; + break; + case IMGFMT_422P16_LE: + case IMGFMT_422P16_BE: + bpp_factor = 2; + case IMGFMT_422P: + xs = 1; + ys = 0; + break; + case IMGFMT_411P: + xs = 2; + ys = 0; + break; + case IMGFMT_440P: + xs = 0; + ys = 1; + break; + default: + err = 1; + break; + } + if (x_shift) *x_shift = xs; + if (y_shift) *y_shift = ys; + bpp = 8 + (16 >> (xs + ys)); + if (format == IMGFMT_420A) + bpp += 8; + bpp *= bpp_factor; + return err ? 0 : bpp; +} diff --git a/libmpcodecs/img_format.h b/libmpcodecs/img_format.h index 4c917b01e4..6bab56632d 100644 --- a/libmpcodecs/img_format.h +++ b/libmpcodecs/img_format.h @@ -71,8 +71,33 @@ #define IMGFMT_444P 0x50343434 #define IMGFMT_422P 0x50323234 #define IMGFMT_411P 0x50313134 +#define IMGFMT_440P 0x50303434 #define IMGFMT_HM12 0x32314D48 +// 4:2:0 planar with alpha +#define IMGFMT_420A 0x41303234 + +#define IMGFMT_444P16_LE 0x51343434 +#define IMGFMT_444P16_BE 0x34343451 +#define IMGFMT_422P16_LE 0x51323234 +#define IMGFMT_422P16_BE 0x34323251 +#define IMGFMT_420P16_LE 0x51303234 +#define IMGFMT_420P16_BE 0x34323051 +#if HAVE_BIGENDIAN +#define IMGFMT_444P16 IMGFMT_444P16_BE +#define IMGFMT_422P16 IMGFMT_422P16_BE +#define IMGFMT_420P16 IMGFMT_420P16_BE +#else +#define IMGFMT_444P16 IMGFMT_444P16_LE +#define IMGFMT_422P16 IMGFMT_422P16_LE +#define IMGFMT_420P16 IMGFMT_420P16_LE +#endif + +#define IMGFMT_IS_YUVP16_LE(fmt) (((fmt ^ IMGFMT_420P16_LE) & 0xff0000ff) == 0) +#define IMGFMT_IS_YUVP16_BE(fmt) (((fmt ^ IMGFMT_420P16_BE) & 0xff0000ff) == 0) +#define IMGFMT_IS_YUVP16_NE(fmt) (((fmt ^ IMGFMT_420P16 ) & 0xff0000ff) == 0) +#define IMGFMT_IS_YUVP16(fmt) (IMGFMT_IS_YUVP16_LE(fmt) || IMGFMT_IS_YUVP16_BE(fmt)) + /* Packed YUV Formats */ #define IMGFMT_IUYV 0x56595549 @@ -133,4 +158,11 @@ typedef struct { const char *vo_format_name(int format); +/** + * Calculates the scale shifts for the chroma planes for planar YUV + * + * \return bits-per-pixel for format if successful (i.e. format is 3 or 4-planes planar YUV), 0 otherwise + */ +int mp_get_chroma_shift(int format, int *x_shift, int *y_shift); + #endif /* MPLAYER_IMG_FORMAT_H */ diff --git a/libmpcodecs/mp_image.c b/libmpcodecs/mp_image.c index 3eb524d491..1bc0492e9c 100644 --- a/libmpcodecs/mp_image.c +++ b/libmpcodecs/mp_image.c @@ -14,37 +14,50 @@ #include "libvo/fastmemcpy.h" -mp_image_t* alloc_mpi(int w, int h, unsigned long int fmt) { - mp_image_t* mpi = new_mp_image(w,h); - - mp_image_setfmt(mpi,fmt); +void mp_image_alloc_planes(mp_image_t *mpi) { // IF09 - allocate space for 4. plane delta info - unused - if (mpi->imgfmt == IMGFMT_IF09) - { - mpi->planes[0]=memalign(64, mpi->bpp*mpi->width*(mpi->height+2)/8+ - mpi->chroma_width*mpi->chroma_height); - /* delta table, just for fun ;) */ - mpi->planes[3]=mpi->planes[0]+2*(mpi->chroma_width*mpi->chroma_height); - } - else + if (mpi->imgfmt == IMGFMT_IF09) { + mpi->planes[0]=memalign(64, mpi->bpp*mpi->width*(mpi->height+2)/8+ + mpi->chroma_width*mpi->chroma_height); + } else mpi->planes[0]=memalign(64, mpi->bpp*mpi->width*(mpi->height+2)/8); - if(mpi->flags&MP_IMGFLAG_PLANAR){ + if (mpi->flags&MP_IMGFLAG_PLANAR) { + int bpp = IMGFMT_IS_YUVP16(mpi->imgfmt)? 2 : 1; // YV12/I420/YVU9/IF09. feel free to add other planar formats here... - if(!mpi->stride[0]) mpi->stride[0]=mpi->width; - if(!mpi->stride[1]) mpi->stride[1]=mpi->stride[2]=mpi->chroma_width; - if(mpi->flags&MP_IMGFLAG_SWAPPED){ - // I420/IYUV (Y,U,V) - mpi->planes[1]=mpi->planes[0]+mpi->width*mpi->height; - mpi->planes[2]=mpi->planes[1]+mpi->chroma_width*mpi->chroma_height; + mpi->stride[0]=mpi->stride[3]=bpp*mpi->width; + if(mpi->num_planes > 2){ + mpi->stride[1]=mpi->stride[2]=bpp*mpi->chroma_width; + if(mpi->flags&MP_IMGFLAG_SWAPPED){ + // I420/IYUV (Y,U,V) + mpi->planes[1]=mpi->planes[0]+mpi->stride[0]*mpi->height; + mpi->planes[2]=mpi->planes[1]+mpi->stride[1]*mpi->chroma_height; + if (mpi->num_planes > 3) + mpi->planes[3]=mpi->planes[2]+mpi->stride[2]*mpi->chroma_height; + } else { + // YV12,YVU9,IF09 (Y,V,U) + mpi->planes[2]=mpi->planes[0]+mpi->stride[0]*mpi->height; + mpi->planes[1]=mpi->planes[2]+mpi->stride[1]*mpi->chroma_height; + if (mpi->num_planes > 3) + mpi->planes[3]=mpi->planes[1]+mpi->stride[1]*mpi->chroma_height; + } } else { - // YV12,YVU9,IF09 (Y,V,U) - mpi->planes[2]=mpi->planes[0]+mpi->width*mpi->height; - mpi->planes[1]=mpi->planes[2]+mpi->chroma_width*mpi->chroma_height; + // NV12/NV21 + mpi->stride[1]=mpi->chroma_width; + mpi->planes[1]=mpi->planes[0]+mpi->stride[0]*mpi->height; } } else { - if(!mpi->stride[0]) mpi->stride[0]=mpi->width*mpi->bpp/8; + mpi->stride[0]=mpi->width*mpi->bpp/8; + if (mpi->flags & MP_IMGFLAG_RGB_PALETTE) + mpi->planes[1] = memalign(64, 1024); } mpi->flags|=MP_IMGFLAG_ALLOCATED; +} + +mp_image_t* alloc_mpi(int w, int h, unsigned long int fmt) { + mp_image_t* mpi = new_mp_image(w,h); + + mp_image_setfmt(mpi,fmt); + mp_image_alloc_planes(mpi); return mpi; } diff --git a/libmpcodecs/mp_image.h b/libmpcodecs/mp_image.h index a62f403e27..667c131719 100644 --- a/libmpcodecs/mp_image.h +++ b/libmpcodecs/mp_image.h @@ -133,51 +133,32 @@ static inline void mp_image_setfmt(mp_image_t* mpi,unsigned int out_fmt){ } mpi->flags|=MP_IMGFLAG_YUV; mpi->num_planes=3; + if (mp_get_chroma_shift(out_fmt, NULL, NULL)) { + mpi->flags|=MP_IMGFLAG_PLANAR; + mpi->bpp = mp_get_chroma_shift(out_fmt, &mpi->chroma_x_shift, &mpi->chroma_y_shift); + mpi->chroma_width = mpi->width >> mpi->chroma_x_shift; + mpi->chroma_height = mpi->height >> mpi->chroma_y_shift; + } switch(out_fmt){ case IMGFMT_I420: case IMGFMT_IYUV: mpi->flags|=MP_IMGFLAG_SWAPPED; case IMGFMT_YV12: - mpi->flags|=MP_IMGFLAG_PLANAR; - mpi->bpp=12; - mpi->chroma_width=(mpi->width>>1); - mpi->chroma_height=(mpi->height>>1); - mpi->chroma_x_shift=1; - mpi->chroma_y_shift=1; return; + case IMGFMT_420A: case IMGFMT_IF09: mpi->num_planes=4; case IMGFMT_YVU9: - mpi->flags|=MP_IMGFLAG_PLANAR; - mpi->bpp=9; - mpi->chroma_width=(mpi->width>>2); - mpi->chroma_height=(mpi->height>>2); - mpi->chroma_x_shift=2; - mpi->chroma_y_shift=2; - return; case IMGFMT_444P: - mpi->flags|=MP_IMGFLAG_PLANAR; - mpi->bpp=24; - mpi->chroma_width=(mpi->width); - mpi->chroma_height=(mpi->height); - mpi->chroma_x_shift=0; - mpi->chroma_y_shift=0; - return; case IMGFMT_422P: - mpi->flags|=MP_IMGFLAG_PLANAR; - mpi->bpp=16; - mpi->chroma_width=(mpi->width>>1); - mpi->chroma_height=(mpi->height); - mpi->chroma_x_shift=1; - mpi->chroma_y_shift=0; - return; case IMGFMT_411P: - mpi->flags|=MP_IMGFLAG_PLANAR; - mpi->bpp=12; - mpi->chroma_width=(mpi->width>>2); - mpi->chroma_height=(mpi->height); - mpi->chroma_x_shift=2; - mpi->chroma_y_shift=0; + case IMGFMT_440P: + case IMGFMT_444P16_LE: + case IMGFMT_444P16_BE: + case IMGFMT_422P16_LE: + case IMGFMT_422P16_BE: + case IMGFMT_420P16_LE: + case IMGFMT_420P16_BE: return; case IMGFMT_Y800: case IMGFMT_Y8: @@ -230,6 +211,7 @@ static inline void free_mp_image(mp_image_t* mpi){ } mp_image_t* alloc_mpi(int w, int h, unsigned long int fmt); +void mp_image_alloc_planes(mp_image_t *mpi); void copy_mpi(mp_image_t *dmpi, mp_image_t *mpi); #endif /* MPLAYER_MP_IMAGE_H */ diff --git a/libmpcodecs/vd_ffmpeg.c b/libmpcodecs/vd_ffmpeg.c index a89e0a4dbe..9b833dac72 100644 --- a/libmpcodecs/vd_ffmpeg.c +++ b/libmpcodecs/vd_ffmpeg.c @@ -579,6 +579,7 @@ static int get_buffer(AVCodecContext *avctx, AVFrame *pic){ pic->data[0]= mpi->planes[0]; pic->data[1]= mpi->planes[1]; pic->data[2]= mpi->planes[2]; + pic->data[3]= mpi->planes[3]; #if 0 assert(mpi->width >= ((width +align)&(~align))); @@ -603,6 +604,7 @@ static int get_buffer(AVCodecContext *avctx, AVFrame *pic){ pic->linesize[0]= mpi->stride[0]; pic->linesize[1]= mpi->stride[1]; pic->linesize[2]= mpi->stride[2]; + pic->linesize[3]= mpi->stride[3]; pic->opaque = mpi; //printf("%X\n", (int)mpi->planes[0]); @@ -837,9 +839,11 @@ static struct mp_image *decode(struct sh_video *sh, void *data, int len, mpi->planes[0]=pic->data[0]; mpi->planes[1]=pic->data[1]; mpi->planes[2]=pic->data[2]; + mpi->planes[3]=pic->data[3]; mpi->stride[0]=pic->linesize[0]; mpi->stride[1]=pic->linesize[1]; mpi->stride[2]=pic->linesize[2]; + mpi->stride[3]=pic->linesize[3]; } if (!mpi->planes[0]) diff --git a/libmpcodecs/vf.c b/libmpcodecs/vf.c index 3c1c5e9538..d753d3d68a 100644 --- a/libmpcodecs/vf.c +++ b/libmpcodecs/vf.c @@ -379,46 +379,9 @@ mp_image_t* vf_get_image(vf_instance_t* vf, unsigned int outfmt, int mp_imgtype, } } - // IF09 - allocate space for 4. plane delta info - unused - if (mpi->imgfmt == IMGFMT_IF09) - { - mpi->planes[0]=memalign(64, mpi->bpp*mpi->width*(mpi->height+2)/8+ - mpi->chroma_width*mpi->chroma_height); - /* export delta table */ - mpi->planes[3]=mpi->planes[0]+(mpi->width*mpi->height)+2*(mpi->chroma_width*mpi->chroma_height); - } - else - mpi->planes[0]=memalign(64, mpi->bpp*mpi->width*(mpi->height+2)/8); - if(mpi->flags&MP_IMGFLAG_PLANAR){ - // YV12/I420/YVU9/IF09. feel free to add other planar formats here... - //if(!mpi->stride[0]) - mpi->stride[0]=mpi->width; - //if(!mpi->stride[1]) - if(mpi->num_planes > 2){ - mpi->stride[1]=mpi->stride[2]=mpi->chroma_width; - if(mpi->flags&MP_IMGFLAG_SWAPPED){ - // I420/IYUV (Y,U,V) - mpi->planes[1]=mpi->planes[0]+mpi->width*mpi->height; - mpi->planes[2]=mpi->planes[1]+mpi->chroma_width*mpi->chroma_height; - } else { - // YV12,YVU9,IF09 (Y,V,U) - mpi->planes[2]=mpi->planes[0]+mpi->width*mpi->height; - mpi->planes[1]=mpi->planes[2]+mpi->chroma_width*mpi->chroma_height; - } - } else { - // NV12/NV21 - mpi->stride[1]=mpi->chroma_width; - mpi->planes[1]=mpi->planes[0]+mpi->width*mpi->height; - } - } else { - //if(!mpi->stride[0]) - mpi->stride[0]=mpi->width*mpi->bpp/8; - if (mpi->flags & MP_IMGFLAG_RGB_PALETTE) - mpi->planes[1] = memalign(64, 1024); - } + mp_image_alloc_planes(mpi); // printf("clearing img!\n"); vf_mpi_clear(mpi,0,0,mpi->width,mpi->height); - mpi->flags|=MP_IMGFLAG_ALLOCATED; } } if(mpi->flags&MP_IMGFLAG_DRAW_CALLBACK) diff --git a/libmpcodecs/vf_scale.c b/libmpcodecs/vf_scale.c index 3a1bae77c8..246624ae3a 100644 --- a/libmpcodecs/vf_scale.c +++ b/libmpcodecs/vf_scale.c @@ -49,9 +49,16 @@ void sws_getFlagsAndFilterFromCmdLine(int *flags, SwsFilter **srcFilterParam, Sw static const unsigned int outfmt_list[]={ // YUV: IMGFMT_444P, + IMGFMT_444P16_LE, + IMGFMT_444P16_BE, IMGFMT_422P, + IMGFMT_422P16_LE, + IMGFMT_422P16_BE, IMGFMT_YV12, IMGFMT_I420, + IMGFMT_420P16_LE, + IMGFMT_420P16_BE, + IMGFMT_420A, IMGFMT_IYUV, IMGFMT_YVU9, IMGFMT_IF09, @@ -60,6 +67,7 @@ static const unsigned int outfmt_list[]={ IMGFMT_NV21, IMGFMT_YUY2, IMGFMT_UYVY, + IMGFMT_440P, // RGB and grayscale (Y8 and Y800): IMGFMT_BGR32, IMGFMT_RGB32, @@ -322,7 +330,7 @@ static void start_slice(struct vf_instance* vf, mp_image_t *mpi){ static void scale(struct SwsContext *sws1, struct SwsContext *sws2, uint8_t *src[MP_MAX_PLANES], int src_stride[MP_MAX_PLANES], int y, int h, uint8_t *dst[MP_MAX_PLANES], int dst_stride[MP_MAX_PLANES], int interlaced){ - uint8_t *src2[MP_MAX_PLANES]={src[0], src[1], src[2]}; + uint8_t *src2[MP_MAX_PLANES]={src[0], src[1], src[2], src[3]}; #if HAVE_BIGENDIAN uint32_t pal2[256]; if (src[1] && !src[2]){ @@ -335,12 +343,12 @@ static void scale(struct SwsContext *sws1, struct SwsContext *sws2, uint8_t *src if(interlaced){ int i; - uint8_t *dst2[MP_MAX_PLANES]={dst[0], dst[1], dst[2]}; - int src_stride2[MP_MAX_PLANES]={2*src_stride[0], 2*src_stride[1], 2*src_stride[2]}; - int dst_stride2[MP_MAX_PLANES]={2*dst_stride[0], 2*dst_stride[1], 2*dst_stride[2]}; + uint8_t *dst2[MP_MAX_PLANES]={dst[0], dst[1], dst[2], dst[3]}; + int src_stride2[MP_MAX_PLANES]={2*src_stride[0], 2*src_stride[1], 2*src_stride[2], 2*src_stride[3]}; + int dst_stride2[MP_MAX_PLANES]={2*dst_stride[0], 2*dst_stride[1], 2*dst_stride[2], 2*dst_stride[3]}; sws_scale_ordered(sws1, src2, src_stride2, y>>1, h>>1, dst2, dst_stride2); - for(i=0; i<3; i++){ + for(i=0; i<MP_MAX_PLANES; i++){ src2[i] += src_stride[i]; dst2[i] += dst_stride[i]; } @@ -471,6 +479,14 @@ static int query_format(struct vf_instance* vf, unsigned int fmt){ case IMGFMT_444P: case IMGFMT_422P: case IMGFMT_411P: + case IMGFMT_440P: + case IMGFMT_420A: + case IMGFMT_444P16_LE: + case IMGFMT_444P16_BE: + case IMGFMT_422P16_LE: + case IMGFMT_422P16_BE: + case IMGFMT_420P16_LE: + case IMGFMT_420P16_BE: case IMGFMT_BGR8: case IMGFMT_RGB8: case IMGFMT_BG4B: |