summaryrefslogtreecommitdiffstats
path: root/libmpcodecs
diff options
context:
space:
mode:
authorUoti Urpala <uau@glyph.nonexistent.invalid>2010-01-08 01:05:30 +0200
committerUoti Urpala <uau@glyph.nonexistent.invalid>2010-01-08 01:05:30 +0200
commit231b33a02fae95b260120349040106bfa34a3750 (patch)
tree23c4de0e6263b2d99966348d7003177b3b3e3740 /libmpcodecs
parent52126e574c7872ca95e7974cfe5445421b74f24c (diff)
parent92cd6dc3e916ae4275ff05d2b238fc778cfbfc6b (diff)
downloadmpv-231b33a02fae95b260120349040106bfa34a3750.tar.bz2
mpv-231b33a02fae95b260120349040106bfa34a3750.tar.xz
Merge svn changes up to r30165
Diffstat (limited to 'libmpcodecs')
-rw-r--r--libmpcodecs/img_format.c64
-rw-r--r--libmpcodecs/img_format.h32
-rw-r--r--libmpcodecs/mp_image.c59
-rw-r--r--libmpcodecs/mp_image.h48
-rw-r--r--libmpcodecs/vd_ffmpeg.c4
-rw-r--r--libmpcodecs/vf.c39
-rw-r--r--libmpcodecs/vf_scale.c26
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: