[MPlayer-dev-eng] [PATCH] some support for NV12 and NV21 image format
Angelo Cano
angelo_cano at fastmail.fm
Fri Apr 18 18:36:46 CEST 2003
I have a tv card that outputs yuv420p using NV12 format, this patch
enables NV12/NV21 -> YV12 conversion.
-------------- next part --------------
diff -Nur main/DOCS/de/mplayer.1 work/DOCS/de/mplayer.1
--- main/DOCS/de/mplayer.1 Sat Mar 22 07:01:47 2003
+++ work/DOCS/de/mplayer.1 Fri Apr 18 11:02:10 2003
@@ -756,7 +756,7 @@
Gibt die Frequenz an, auf die der Tuner gesetzt wird (z.B.\& 511.250).
Kann nicht zusammen mit 'channels' benutzt werden.
.IPs outfmt=<Wert>
-Ausgabeformat des Tuners (yv12, rgb32, rgb24, rgb16, rgb15, uyvy, yuy2, i420)
+Ausgabeformat des Tuners (yv12, rgb32, rgb24, rgb16, rgb15, uyvy, yuy2, i420, nv12, nv21)
.IPs width=<Wert>
Breite des Ausgabefensters
.IPs height=<Wert>
diff -Nur main/DOCS/en/mplayer.1 work/DOCS/en/mplayer.1
--- main/DOCS/en/mplayer.1 Fri Apr 11 05:27:31 2003
+++ work/DOCS/en/mplayer.1 Fri Apr 18 11:02:10 2003
@@ -726,7 +726,7 @@
Not compatible with channels parameter.
.IPs outfmt=<value>
output format of the tuner (yv12, rgb32, rgb24, rgb16, rgb15, uyvy, yuy2,
-i420)
+i420, nv12, nv21)
.IPs width=<value>
width of the output window
.IPs height=<value>
diff -Nur main/DOCS/fr/mplayer.1 work/DOCS/fr/mplayer.1
--- main/DOCS/fr/mplayer.1 Fri Apr 11 12:15:15 2003
+++ work/DOCS/fr/mplayer.1 Fri Apr 18 11:02:10 2003
@@ -751,7 +751,7 @@
Non compatible avec le param?tre channels.
.IPs outfmt=<valeur>
format de sortie du tuner (yv12, rgb32, rgb24, rgb16, rgb15, uyvy, yuy2,
-i420)
+i420, nv12, nv21)
.IPs width=<valeur>
largeur de la fen?tre
.IPs height=<valeur>
diff -Nur main/DOCS/hu/mplayer.1 work/DOCS/hu/mplayer.1
--- main/DOCS/hu/mplayer.1 Mon Mar 31 11:48:54 2003
+++ work/DOCS/hu/mplayer.1 Fri Apr 18 11:02:10 2003
@@ -718,7 +718,7 @@
Nem haszn?lhat? a channels opci?val.
.IPs outfmt=<?rt?k>
A tuner kimeneti form?tum?nak megv?ltoztat?sa
-(yv12, rgb32, rgb24, rgb16, rgb15, uyvy, yuy2, i420)
+(yv12, rgb32, rgb24, rgb16, rgb15, uyvy, yuy2, i420, nv12, nv21)
.IPs width=<?rt?k>
a kimeneti ablak sz?less?ge
.IPs height=<?rt?k>
diff -Nur main/DOCS/pl/mplayer.1 work/DOCS/pl/mplayer.1
--- main/DOCS/pl/mplayer.1 Sun Mar 30 11:09:25 2003
+++ work/DOCS/pl/mplayer.1 Fri Apr 18 11:02:10 2003
@@ -726,7 +726,7 @@
Not compatible with channels parameter.
.IPs outfmt=<value>
output format of the tuner (yv12, rgb32, rgb24, rgb16, rgb15, uyvy, yuy2,
-i420)
+i420, nv12, nv21)
.IPs width=<value>
width of the output window
.IPs height=<value>
diff -Nur main/DOCS/zh/mplayer.1 work/DOCS/zh/mplayer.1
--- main/DOCS/zh/mplayer.1 Sun Apr 6 08:27:10 2003
+++ work/DOCS/zh/mplayer.1 Fri Apr 18 11:02:10 2003
@@ -638,7 +638,7 @@
????????????????.
.IPs outfmt=<????>
????????????????????(yv12, rgb32, rgb24, rgb16, rgb15, uyvy, yuy2,
-i420)
+i420, nv12, nv21)
.IPs width=<????>
??????????????
.IPs height=<????>
diff -Nur main/codec-cfg.c work/codec-cfg.c
--- main/codec-cfg.c Sun Dec 15 21:22:37 2002
+++ work/codec-cfg.c Fri Apr 18 11:02:10 2003
@@ -132,6 +132,8 @@
{"YV12", IMGFMT_YV12},
{"I420", IMGFMT_I420},
{"IYUV", IMGFMT_IYUV},
+ {"NV12", IMGFMT_NV12},
+ {"NV21", IMGFMT_NV21},
{"YVU9", IMGFMT_YVU9},
{"IF09", IMGFMT_IF09},
{"444P", IMGFMT_444P},
diff -Nur main/etc/codecs.conf work/etc/codecs.conf
--- main/etc/codecs.conf Tue Apr 15 15:40:11 2003
+++ work/etc/codecs.conf Fri Apr 18 11:04:06 2003
@@ -1429,6 +1429,24 @@
fourcc yvu9,YVU9
out YVU9
+videocodec rawnv12
+ info "RAW NV12"
+ status working
+ driver raw
+ format 0x0 0x3231564E
+ format 0x20776172
+ fourcc nv12,NV12
+ out NV12
+
+videocodec rawnv21
+ info "RAW NV21"
+ status working
+ driver raw
+ format 0x0 0x3132564E
+ format 0x20776172
+ fourcc nv21,NV21
+ out NV21
+
; NULL codec - for testing.
videocodec null
diff -Nur main/libmpcodecs/img_format.c work/libmpcodecs/img_format.c
--- main/libmpcodecs/img_format.c Thu Jan 30 04:14:58 2003
+++ work/libmpcodecs/img_format.c Fri Apr 18 11:02:10 2003
@@ -32,6 +32,7 @@
case IMGFMT_422P: return("Planar 422P");
case IMGFMT_411P: return("Planar 411P");
case IMGFMT_NV12: return("Planar NV12");
+ case IMGFMT_NV21: return("Planar NV21");
case IMGFMT_IUYV: return("Packed IUYV");
case IMGFMT_IY41: return("Packed IY41");
case IMGFMT_IYU1: return("Packed IYU1");
diff -Nur main/libmpcodecs/img_format.h work/libmpcodecs/img_format.h
--- main/libmpcodecs/img_format.h Thu Jan 30 04:14:58 2003
+++ work/libmpcodecs/img_format.h Fri Apr 18 11:02:10 2003
@@ -44,6 +44,7 @@
#define IMGFMT_Y800 0x30303859
#define IMGFMT_Y8 0x20203859
#define IMGFMT_NV12 0x3231564E
+#define IMGFMT_NV21 0x3132564E
/* unofficial Planar Formats, FIXME if official 4CC exists */
#define IMGFMT_444P 0x50343434
diff -Nur main/libmpcodecs/mp_image.h work/libmpcodecs/mp_image.h
--- main/libmpcodecs/mp_image.h Fri Apr 18 08:18:59 2003
+++ work/libmpcodecs/mp_image.h Fri Apr 18 11:06:04 2003
@@ -114,6 +114,17 @@
mpi->flags|=MP_IMGFLAG_YUV;
mpi->num_planes=3;
switch(out_fmt){
+ case IMGFMT_NV12:
+ mpi->flags|=MP_IMGFLAG_SWAPPED;
+ case IMGFMT_NV21:
+ mpi->num_planes=2;
+ 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_I420:
case IMGFMT_IYUV:
mpi->flags|=MP_IMGFLAG_SWAPPED;
diff -Nur main/libmpcodecs/vf_eq.c work/libmpcodecs/vf_eq.c
--- main/libmpcodecs/vf_eq.c Sat Mar 15 15:45:03 2003
+++ work/libmpcodecs/vf_eq.c Fri Apr 18 11:02:10 2003
@@ -188,6 +188,7 @@
case IMGFMT_Y800:
case IMGFMT_Y8:
case IMGFMT_NV12:
+ case IMGFMT_NV21:
case IMGFMT_444P:
case IMGFMT_422P:
case IMGFMT_411P:
diff -Nur main/libmpcodecs/vf_scale.c work/libmpcodecs/vf_scale.c
--- main/libmpcodecs/vf_scale.c Thu Mar 27 11:04:51 2003
+++ work/libmpcodecs/vf_scale.c Fri Apr 18 11:02:10 2003
@@ -63,6 +63,8 @@
IMGFMT_YV12,
IMGFMT_I420,
IMGFMT_IYUV,
+ IMGFMT_NV12,
+ IMGFMT_NV21,
IMGFMT_YVU9,
IMGFMT_IF09,
IMGFMT_411P,
@@ -315,13 +317,15 @@
//===========================================================================//
-// supported Input formats: YV12, I420, IYUV, YUY2, UYVY, BGR32, BGR24, BGR16, BGR15, RGB32, RGB24, Y8, Y800
+// supported Input formats: YV12, I420, IYUV, NV12, NV21, YUY2, UYVY, BGR32, BGR24, BGR16, BGR15, RGB32, RGB24, Y8, Y800
static int query_format(struct vf_instance_s* vf, unsigned int fmt){
switch(fmt){
case IMGFMT_YV12:
case IMGFMT_I420:
case IMGFMT_IYUV:
+ case IMGFMT_NV12:
+ case IMGFMT_NV21:
case IMGFMT_UYVY:
case IMGFMT_YUY2:
case IMGFMT_BGR32:
diff -Nur main/libmpdemux/tv.c work/libmpdemux/tv.c
--- main/libmpdemux/tv.c Wed Apr 9 11:07:45 2003
+++ work/libmpdemux/tv.c Fri Apr 18 11:02:10 2003
@@ -149,6 +149,10 @@
picture_format = IMGFMT_RGB16;
else if (!strcasecmp(tv_param_outfmt, "rgb15"))
picture_format = IMGFMT_RGB15;
+ else if (!strcasecmp(tv_param_outfmt, "nv12"))
+ picture_format = IMGFMT_NV12;
+ else if (!strcasecmp(tv_param_outfmt, "nv21"))
+ picture_format = IMGFMT_NV21;
else
{
mp_msg(MSGT_TV, MSGL_ERR, "Unknown format given: %s\n", tv_param_outfmt);
diff -Nur main/libmpdemux/tvi_v4l.c work/libmpdemux/tvi_v4l.c
--- main/libmpdemux/tvi_v4l.c Sun Mar 30 12:05:58 2003
+++ work/libmpdemux/tvi_v4l.c Fri Apr 18 11:02:10 2003
@@ -151,7 +151,7 @@
static const char *device_palette2name[] = {
"-", "grey", "hi240", "rgb16", "rgb24", "rgb32", "rgb15", "yuv422",
"yuyv", "uyvy", "yuv420", "yuv411", "raw", "yuv422p", "yuv411p",
- "yuv420p", "yuv410p"
+ "yuv420p", "yuv410p", "nv12", "nv21"
};
#define PALETTE(x) ((x < sizeof(device_palette2name)/sizeof(char*)) ? device_palette2name[x] : "UNKNOWN")
@@ -234,6 +234,8 @@
return(VIDEO_PALETTE_RGB32);
case IMGFMT_YV12:
case IMGFMT_I420:
+ case IMGFMT_NV12:
+ case IMGFMT_NV21:
return(VIDEO_PALETTE_YUV420P);
case IMGFMT_YUY2:
return(VIDEO_PALETTE_YUV422);
diff -Nur main/libvo/vo_x11.c work/libvo/vo_x11.c
--- main/libvo/vo_x11.c Thu Mar 27 11:04:30 2003
+++ work/libvo/vo_x11.c Fri Apr 18 11:02:10 2003
@@ -586,6 +586,8 @@
// case IMGFMT_BGR32:
// return 0x2;
// case IMGFMT_YUY2:
+ case IMGFMT_NV12:
+ case IMGFMT_NV21:
case IMGFMT_I420:
case IMGFMT_IYUV:
case IMGFMT_YV12:
diff -Nur main/postproc/swscale.c work/postproc/swscale.c
--- main/postproc/swscale.c Thu Apr 17 14:32:46 2003
+++ work/postproc/swscale.c Fri Apr 18 11:21:17 2003
@@ -105,7 +105,7 @@
//FIXME replace this with something faster
#define isPlanarYUV(x) ((x)==IMGFMT_YV12 || (x)==IMGFMT_YVU9 \
- || (x)==IMGFMT_444P || (x)==IMGFMT_422P || (x)==IMGFMT_411P)
+ || (x)==IMGFMT_444P || (x)==IMGFMT_422P || (x)==IMGFMT_411P || (x)==IMGFMT_NV12 || (x)==IMGFMT_NV21)
#define isYUV(x) ((x)==IMGFMT_UYVY || (x)==IMGFMT_YUY2 || isPlanarYUV(x))
#define isGray(x) ((x)==IMGFMT_Y800)
#define isRGB(x) (((x)&IMGFMT_RGB_MASK)==IMGFMT_RGB)
@@ -114,7 +114,7 @@
|| (x)==IMGFMT_BGR32|| (x)==IMGFMT_BGR24|| (x)==IMGFMT_BGR16|| (x)==IMGFMT_BGR15\
|| (x)==IMGFMT_RGB32|| (x)==IMGFMT_RGB24\
|| (x)==IMGFMT_Y800 || (x)==IMGFMT_YVU9\
- || (x)==IMGFMT_444P || (x)==IMGFMT_422P || (x)==IMGFMT_411P)
+ || (x)==IMGFMT_444P || (x)==IMGFMT_422P || (x)==IMGFMT_411P || (x)==IMGFMT_NV12 || (x)==IMGFMT_NV21)
#define isSupportedOut(x) ((x)==IMGFMT_YV12 || (x)==IMGFMT_YUY2\
|| (x)==IMGFMT_444P || (x)==IMGFMT_422P || (x)==IMGFMT_411P\
|| isRGB(x) || isBGR(x)\
@@ -1474,6 +1474,50 @@
#endif //!RUNTIME_CPUDETECT
}
+static int NVxxToYV12Wrapper(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t* dstParam[], int dstStride[]) {
+ uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY;
+ /* Copy Y plane */
+ if(dstStride[0]==srcStride[0])
+ memcpy(dst, src[0], srcSliceH*dstStride[0]);
+ else
+ {
+ int i;
+ uint8_t *srcPtr= src[0];
+ uint8_t *dstPtr= dst;
+ for(i=0; i<srcSliceH; i++)
+ {
+ memcpy(dstPtr, srcPtr, srcStride[0]);
+ srcPtr+= srcStride[0];
+ dstPtr+= dstStride[0];
+ }
+ }
+ // de-interleaveBytes ()
+ {
+ int i,w;
+ uint8_t *srcPtr=src[1];
+ uint8_t *uPtr=dstParam[1] + dstStride[1]*srcSliceY;
+ uint8_t *vPtr=dstParam[2] + dstStride[1]*srcSliceY;
+ for(i=0; i<srcSliceH; i++)
+ {
+ for(w=0; w<c->srcW / 2; w++)
+ {
+ uPtr[w] = srcPtr[2*w+0];
+ vPtr[w] = srcPtr[2*w+1];
+ }
+ uPtr += dstStride[1] / 2;
+ vPtr += dstStride[2] / 2;
+ srcPtr += srcStride[1];
+ }
+ }
+ if (c->srcFormat==IMGFMT_NV12) {
+ uint8_t *tmpPtr=dstParam[1];
+ dstParam[1]=dstParam[2];
+ dstParam[2]=tmpPtr;
+ }
+
+ return srcSliceH;
+}
+
static int PlanarToNV12Wrapper(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
int srcSliceH, uint8_t* dstParam[], int dstStride[]){
uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY;
@@ -1942,9 +1986,21 @@
sws_setColorspaceDetails(c, Inverse_Table_6_9[SWS_CS_DEFAULT], 0, Inverse_Table_6_9[SWS_CS_DEFAULT] /* FIXME*/, 0, 0, 1<<16, 1<<16);
+ //FIXME maybe not the best place for this kind of check
+ if((srcFormat==IMGFMT_NV12 || srcFormat==IMGFMT_NV21) && (!unscaled || usesFilter || dstFormat!=IMGFMT_YV12))
+ {
+ MSG_ERR("swScaler: only unscaled and unfiltered NV12/NV21 -> YV12 supported, %s and %s %s -> %s isn't supported yet\n", unscaled ? "unscaled" : "scaled", usesFilter ? "filtered" : "unfiltered", vo_format_name(srcFormat), vo_format_name(dstFormat));
+ free (c);
+ return NULL;
+ }
+
/* unscaled special Cases */
if(unscaled && !usesFilter)
{
+ if((srcFormat==IMGFMT_NV12 || srcFormat==IMGFMT_NV21) && dstFormat==IMGFMT_YV12)
+ {
+ c->swScale= NVxxToYV12Wrapper;
+ }
/* yv12_to_nv12 */
if(srcFormat == IMGFMT_YV12 && dstFormat == IMGFMT_NV12)
{
More information about the MPlayer-dev-eng
mailing list