]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/raw.c
lavc: move SANE_NB_CHANNELS to internal.h and use it in the PCM decoders
[ffmpeg] / libavcodec / raw.c
index fd70cc9782b1e78a728b7a138236355108652638..4ccc6cc0750922fcb393ae26b559848f30eacbb2 100644 (file)
 /*
  * Raw Video Codec
- * Copyright (c) 2001 Fabrice Bellard.
+ * Copyright (c) 2001 Fabrice Bellard
  *
- * This library is free software; you can redistribute it and/or
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * version 2.1 of the License, or (at your option) any later version.
  *
- * This library is distributed in the hope that it will be useful,
+ * Libav is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
+
 /**
- * @file raw.c
+ * @file
  * Raw Video Codec
  */
-#include "avcodec.h"
 
-
-typedef struct PixleFormatTag {
-    int pix_fmt;
-    unsigned int fourcc;
-} PixelFormatTag;
-
-const PixelFormatTag pixelFormatTags[] = {
-    { PIX_FMT_YUV422, MKTAG('Y', '4', '2', '2') },
-    { PIX_FMT_YUV420P, MKTAG('I', '4', '2', '0') },
-    { -1, 0 },
+#include "avcodec.h"
+#include "raw.h"
+#include "libavutil/common.h"
+
+const PixelFormatTag ff_raw_pix_fmt_tags[] = {
+    { AV_PIX_FMT_YUV420P, MKTAG('I', '4', '2', '0') }, /* Planar formats */
+    { AV_PIX_FMT_YUV420P, MKTAG('I', 'Y', 'U', 'V') },
+    { AV_PIX_FMT_YUV420P, MKTAG('Y', 'V', '1', '2') },
+    { AV_PIX_FMT_YUV410P, MKTAG('Y', 'U', 'V', '9') },
+    { AV_PIX_FMT_YUV410P, MKTAG('Y', 'V', 'U', '9') },
+    { AV_PIX_FMT_YUV411P, MKTAG('Y', '4', '1', 'B') },
+    { AV_PIX_FMT_YUV422P, MKTAG('Y', '4', '2', 'B') },
+    { AV_PIX_FMT_YUV422P, MKTAG('P', '4', '2', '2') },
+    { AV_PIX_FMT_YUV422P, MKTAG('Y', 'V', '1', '6') },
+    /* yuvjXXX formats are deprecated hacks specific to libav*,
+       they are identical to yuvXXX  */
+    { AV_PIX_FMT_YUVJ420P, MKTAG('I', '4', '2', '0') }, /* Planar formats */
+    { AV_PIX_FMT_YUVJ420P, MKTAG('I', 'Y', 'U', 'V') },
+    { AV_PIX_FMT_YUVJ420P, MKTAG('Y', 'V', '1', '2') },
+    { AV_PIX_FMT_YUVJ422P, MKTAG('Y', '4', '2', 'B') },
+    { AV_PIX_FMT_YUVJ422P, MKTAG('P', '4', '2', '2') },
+    { AV_PIX_FMT_GRAY8,    MKTAG('Y', '8', '0', '0') },
+    { AV_PIX_FMT_GRAY8,    MKTAG('Y', '8', ' ', ' ') },
+
+    { AV_PIX_FMT_YUYV422, MKTAG('Y', 'U', 'Y', '2') }, /* Packed formats */
+    { AV_PIX_FMT_YUYV422, MKTAG('Y', '4', '2', '2') },
+    { AV_PIX_FMT_YUYV422, MKTAG('V', '4', '2', '2') },
+    { AV_PIX_FMT_YUYV422, MKTAG('V', 'Y', 'U', 'Y') },
+    { AV_PIX_FMT_YUYV422, MKTAG('Y', 'U', 'N', 'V') },
+    { AV_PIX_FMT_UYVY422, MKTAG('U', 'Y', 'V', 'Y') },
+    { AV_PIX_FMT_UYVY422, MKTAG('H', 'D', 'Y', 'C') },
+    { AV_PIX_FMT_UYVY422, MKTAG('U', 'Y', 'N', 'V') },
+    { AV_PIX_FMT_UYVY422, MKTAG('U', 'Y', 'N', 'Y') },
+    { AV_PIX_FMT_UYVY422, MKTAG('u', 'y', 'v', '1') },
+    { AV_PIX_FMT_UYVY422, MKTAG('2', 'V', 'u', '1') },
+    { AV_PIX_FMT_UYVY422, MKTAG('A', 'V', 'R', 'n') }, /* Avid AVI Codec 1:1 */
+    { AV_PIX_FMT_UYVY422, MKTAG('A', 'V', '1', 'x') }, /* Avid 1:1x */
+    { AV_PIX_FMT_UYVY422, MKTAG('A', 'V', 'u', 'p') },
+    { AV_PIX_FMT_UYVY422, MKTAG('V', 'D', 'T', 'Z') }, /* SoftLab-NSK VideoTizer */
+    { AV_PIX_FMT_UYVY422, MKTAG('a', 'u', 'v', '2') },
+    { AV_PIX_FMT_UYYVYY411, MKTAG('Y', '4', '1', '1') },
+    { AV_PIX_FMT_GRAY8,   MKTAG('G', 'R', 'E', 'Y') },
+    { AV_PIX_FMT_NV12,    MKTAG('N', 'V', '1', '2') },
+    { AV_PIX_FMT_NV21,    MKTAG('N', 'V', '2', '1') },
+
+    /* nut */
+    { AV_PIX_FMT_RGB555LE, MKTAG('R', 'G', 'B', 15) },
+    { AV_PIX_FMT_BGR555LE, MKTAG('B', 'G', 'R', 15) },
+    { AV_PIX_FMT_RGB565LE, MKTAG('R', 'G', 'B', 16) },
+    { AV_PIX_FMT_BGR565LE, MKTAG('B', 'G', 'R', 16) },
+    { AV_PIX_FMT_RGB555BE, MKTAG(15 , 'B', 'G', 'R') },
+    { AV_PIX_FMT_BGR555BE, MKTAG(15 , 'R', 'G', 'B') },
+    { AV_PIX_FMT_RGB565BE, MKTAG(16 , 'B', 'G', 'R') },
+    { AV_PIX_FMT_BGR565BE, MKTAG(16 , 'R', 'G', 'B') },
+    { AV_PIX_FMT_RGB444LE, MKTAG('R', 'G', 'B', 12) },
+    { AV_PIX_FMT_BGR444LE, MKTAG('B', 'G', 'R', 12) },
+    { AV_PIX_FMT_RGB444BE, MKTAG(12 , 'B', 'G', 'R') },
+    { AV_PIX_FMT_BGR444BE, MKTAG(12 , 'R', 'G', 'B') },
+    { AV_PIX_FMT_RGBA,     MKTAG('R', 'G', 'B', 'A') },
+    { AV_PIX_FMT_BGRA,     MKTAG('B', 'G', 'R', 'A') },
+    { AV_PIX_FMT_ABGR,     MKTAG('A', 'B', 'G', 'R') },
+    { AV_PIX_FMT_ARGB,     MKTAG('A', 'R', 'G', 'B') },
+    { AV_PIX_FMT_RGB24,    MKTAG('R', 'G', 'B', 24 ) },
+    { AV_PIX_FMT_BGR24,    MKTAG('B', 'G', 'R', 24 ) },
+    { AV_PIX_FMT_YUV411P,  MKTAG('4', '1', '1', 'P') },
+    { AV_PIX_FMT_YUV422P,  MKTAG('4', '2', '2', 'P') },
+    { AV_PIX_FMT_YUVJ422P, MKTAG('4', '2', '2', 'P') },
+    { AV_PIX_FMT_YUV440P,  MKTAG('4', '4', '0', 'P') },
+    { AV_PIX_FMT_YUVJ440P, MKTAG('4', '4', '0', 'P') },
+    { AV_PIX_FMT_YUV444P,  MKTAG('4', '4', '4', 'P') },
+    { AV_PIX_FMT_YUVJ444P, MKTAG('4', '4', '4', 'P') },
+    { AV_PIX_FMT_MONOWHITE,MKTAG('B', '1', 'W', '0') },
+    { AV_PIX_FMT_MONOBLACK,MKTAG('B', '0', 'W', '1') },
+    { AV_PIX_FMT_BGR8,     MKTAG('B', 'G', 'R',  8 ) },
+    { AV_PIX_FMT_RGB8,     MKTAG('R', 'G', 'B',  8 ) },
+    { AV_PIX_FMT_BGR4,     MKTAG('B', 'G', 'R',  4 ) },
+    { AV_PIX_FMT_RGB4,     MKTAG('R', 'G', 'B',  4 ) },
+    { AV_PIX_FMT_RGB4_BYTE,MKTAG('B', '4', 'B', 'Y') },
+    { AV_PIX_FMT_BGR4_BYTE,MKTAG('R', '4', 'B', 'Y') },
+    { AV_PIX_FMT_RGB48LE,  MKTAG('R', 'G', 'B', 48 ) },
+    { AV_PIX_FMT_RGB48BE,  MKTAG( 48, 'R', 'G', 'B') },
+    { AV_PIX_FMT_BGR48LE,  MKTAG('B', 'G', 'R', 48 ) },
+    { AV_PIX_FMT_BGR48BE,  MKTAG( 48, 'B', 'G', 'R') },
+    { AV_PIX_FMT_GRAY16LE,    MKTAG('Y', '1',  0 , 16 ) },
+    { AV_PIX_FMT_GRAY16BE,    MKTAG(16 ,  0 , '1', 'Y') },
+    { AV_PIX_FMT_YUV420P10LE, MKTAG('Y', '3', 11 , 10 ) },
+    { AV_PIX_FMT_YUV420P10BE, MKTAG(10 , 11 , '3', 'Y') },
+    { AV_PIX_FMT_YUV422P10LE, MKTAG('Y', '3', 10 , 10 ) },
+    { AV_PIX_FMT_YUV422P10BE, MKTAG(10 , 10 , '3', 'Y') },
+    { AV_PIX_FMT_YUV444P10LE, MKTAG('Y', '3',  0 , 10 ) },
+    { AV_PIX_FMT_YUV444P10BE, MKTAG(10 ,  0 , '3', 'Y') },
+    { AV_PIX_FMT_YUV420P16LE, MKTAG('Y', '3', 11 , 16 ) },
+    { AV_PIX_FMT_YUV420P16BE, MKTAG(16 , 11 , '3', 'Y') },
+    { AV_PIX_FMT_YUV422P16LE, MKTAG('Y', '3', 10 , 16 ) },
+    { AV_PIX_FMT_YUV422P16BE, MKTAG(16 , 10 , '3', 'Y') },
+    { AV_PIX_FMT_YUV444P16LE, MKTAG('Y', '3',  0 , 16 ) },
+    { AV_PIX_FMT_YUV444P16BE, MKTAG(16 ,  0 , '3', 'Y') },
+    { AV_PIX_FMT_YUVA420P,    MKTAG('Y', '4', 11 ,  8 ) },
+    { AV_PIX_FMT_Y400A,       MKTAG('Y', '2',  0 ,  8 ) },
+
+    { AV_PIX_FMT_YUVA420P9LE,  MKTAG('Y', '4', 11 ,  9 ) },
+    { AV_PIX_FMT_YUVA420P9BE,  MKTAG( 9 , 11 , '4', 'Y') },
+    { AV_PIX_FMT_YUVA422P9LE,  MKTAG('Y', '4', 10 ,  9 ) },
+    { AV_PIX_FMT_YUVA422P9BE,  MKTAG( 9 , 10 , '4', 'Y') },
+    { AV_PIX_FMT_YUVA444P9LE,  MKTAG('Y', '4',  0 ,  9 ) },
+    { AV_PIX_FMT_YUVA444P9BE,  MKTAG( 9 ,  0 , '4', 'Y') },
+    { AV_PIX_FMT_YUVA420P10LE, MKTAG('Y', '4', 11 , 10 ) },
+    { AV_PIX_FMT_YUVA420P10BE, MKTAG(10 , 11 , '4', 'Y') },
+    { AV_PIX_FMT_YUVA422P10LE, MKTAG('Y', '4', 10 , 10 ) },
+    { AV_PIX_FMT_YUVA422P10BE, MKTAG(10 , 10 , '4', 'Y') },
+    { AV_PIX_FMT_YUVA444P10LE, MKTAG('Y', '4',  0 , 10 ) },
+    { AV_PIX_FMT_YUVA444P10BE, MKTAG(10 ,  0 , '4', 'Y') },
+    { AV_PIX_FMT_YUVA420P16LE, MKTAG('Y', '4', 11 , 16 ) },
+    { AV_PIX_FMT_YUVA420P16BE, MKTAG(16 , 11 , '4', 'Y') },
+    { AV_PIX_FMT_YUVA422P16LE, MKTAG('Y', '4', 10 , 16 ) },
+    { AV_PIX_FMT_YUVA422P16BE, MKTAG(16 , 10 , '4', 'Y') },
+    { AV_PIX_FMT_YUVA444P16LE, MKTAG('Y', '4',  0 , 16 ) },
+    { AV_PIX_FMT_YUVA444P16BE, MKTAG(16 ,  0 , '4', 'Y') },
+
+    /* quicktime */
+    { AV_PIX_FMT_UYVY422, MKTAG('2', 'v', 'u', 'y') },
+    { AV_PIX_FMT_UYVY422, MKTAG('2', 'V', 'u', 'y') },
+    { AV_PIX_FMT_UYVY422, MKTAG('A', 'V', 'U', 'I') }, /* FIXME merge both fields */
+    { AV_PIX_FMT_YUYV422, MKTAG('y', 'u', 'v', '2') },
+    { AV_PIX_FMT_YUYV422, MKTAG('y', 'u', 'v', 's') },
+    { AV_PIX_FMT_YUYV422, MKTAG('D', 'V', 'O', 'O') }, /* Digital Voodoo SD 8 Bit */
+    { AV_PIX_FMT_RGB555LE,MKTAG('L', '5', '5', '5') },
+    { AV_PIX_FMT_RGB565LE,MKTAG('L', '5', '6', '5') },
+    { AV_PIX_FMT_RGB565BE,MKTAG('B', '5', '6', '5') },
+    { AV_PIX_FMT_BGR24,   MKTAG('2', '4', 'B', 'G') },
+    { AV_PIX_FMT_BGRA,    MKTAG('B', 'G', 'R', 'A') },
+    { AV_PIX_FMT_RGBA,    MKTAG('R', 'G', 'B', 'A') },
+    { AV_PIX_FMT_ABGR,    MKTAG('A', 'B', 'G', 'R') },
+    { AV_PIX_FMT_GRAY16BE,MKTAG('b', '1', '6', 'g') },
+    { AV_PIX_FMT_RGB48BE, MKTAG('b', '4', '8', 'r') },
+
+    /* special */
+    { AV_PIX_FMT_RGB565LE,MKTAG( 3 ,  0 ,  0 ,  0 ) }, /* flipped RGB565LE */
+    { AV_PIX_FMT_YUV444P, MKTAG('Y', 'V', '2', '4') }, /* YUV444P, swapped UV */
+
+    { AV_PIX_FMT_NONE, 0 },
 };
 
-static int findPixelFormat(unsigned int fourcc)
+unsigned int avcodec_pix_fmt_to_codec_tag(enum AVPixelFormat fmt)
 {
-    const PixelFormatTag * tags = pixelFormatTags;
+    const PixelFormatTag *tags = ff_raw_pix_fmt_tags;
     while (tags->pix_fmt >= 0) {
-        if (tags->fourcc == fourcc)
-            return tags->pix_fmt;
+        if (tags->pix_fmt == fmt)
+            return tags->fourcc;
         tags++;
     }
-    return PIX_FMT_YUV420P;
-}
-
-
-typedef struct RawVideoContext {
-    unsigned char * buffer;  /* block of memory for holding one frame */
-    unsigned char * p;       /* current position in buffer */
-    int             length;  /* number of bytes in buffer */
-} RawVideoContext;
-
-
-static int raw_init(AVCodecContext *avctx)
-{
-    RawVideoContext *context = avctx->priv_data;
-
-    if (avctx->codec_tag) {
-           avctx->pix_fmt = findPixelFormat(avctx->codec_tag);
-    }
-
-       context->length = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height);
-       context->buffer = av_malloc(context->length);
-       context->p      = context->buffer;
-
-    if (! context->buffer) {
-        return -1;
-    }
-
-    return 0;
-}
-
-static int raw_decode(AVCodecContext *avctx,
-                           void *data, int *data_size,
-                           uint8_t *buf, int buf_size)
-{
-    RawVideoContext *context = avctx->priv_data;
-    int bytesNeeded;
-
-    AVPicture * picture = (AVPicture *) data;
-
-    /* Early out without copy if packet size == frame size */
-    if (buf_size == context->length  &&  context->p == context->buffer) {
-        avpicture_fill(picture, buf, avctx->pix_fmt, avctx->width, avctx->height);
-        *data_size = sizeof(AVPicture);
-        return buf_size;
-    }
-
-    bytesNeeded = context->length - (context->p - context->buffer);
-    if (buf_size < bytesNeeded) {
-        memcpy(context->p, buf, buf_size);
-        context->p += buf_size;
-        *data_size = 0;
-        return buf_size;
-    }
-
-    memcpy(context->p, buf, bytesNeeded);
-    context->p = context->buffer;
-    avpicture_fill(picture, context->buffer, avctx->pix_fmt, avctx->width, avctx->height);
-    *data_size = sizeof(AVPicture);
-    return bytesNeeded;
-}
-
-static int raw_close(AVCodecContext *avctx)
-{
-    RawVideoContext *context = avctx->priv_data;
-
-    av_freep(& context->buffer);
-
     return 0;
 }
-
-static int raw_encode(AVCodecContext *avctx,
-                           unsigned char *frame, int buf_size, void *data)
-{
-       AVPicture * picture = data;
-
-    unsigned char *src;
-       unsigned char *dest = frame;
-    int i, j;
-
-       int w = avctx->width;
-       int h = avctx->height;
-       int size = avpicture_get_size(avctx->pix_fmt, w, h);
-
-    if (size > buf_size) {
-        return -1;
-    }
-
-    switch(avctx->pix_fmt) {
-    case PIX_FMT_YUV420P:
-        for(i=0;i<3;i++) {
-            if (i == 1) {
-                w >>= 1;
-                h >>= 1;
-            }
-            src = picture->data[i];
-            for(j=0;j<h;j++) {
-                memcpy(dest, src, w);
-                dest += w;
-                src += picture->linesize[i];
-            }
-        }
-        break;
-    case PIX_FMT_YUV422P:
-        for(i=0;i<3;i++) {
-            if (i == 1) {
-                w >>= 1;
-            }
-            src = picture->data[i];
-            for(j=0;j<h;j++) {
-                memcpy(dest, src, w);
-                dest += w;
-                src += picture->linesize[i];
-            }
-        }
-        break;
-    case PIX_FMT_YUV444P:
-        for(i=0;i<3;i++) {
-            src = picture->data[i];
-            for(j=0;j<h;j++) {
-                memcpy(dest, src, w);
-                dest += w;
-                src += picture->linesize[i];
-            }
-        }
-        break;
-    case PIX_FMT_YUV422:
-        src = picture->data[0];
-        for(j=0;j<h;j++) {
-            memcpy(dest, src, w * 2);
-            dest += w * 2;
-            src += picture->linesize[0];
-        }
-        break;
-    case PIX_FMT_RGB24:
-    case PIX_FMT_BGR24:
-        src = picture->data[0];
-        for(j=0;j<h;j++) {
-            memcpy(dest, src, w * 3);
-            dest += w * 3;
-            src += picture->linesize[0];
-        }
-        break;
-    default:
-        return -1;
-    }
-
-    return size;
-}
-
-
-AVCodec rawvideo_codec = {
-    "rawvideo",
-    CODEC_TYPE_VIDEO,
-    CODEC_ID_RAWVIDEO,
-    sizeof(RawVideoContext),
-    raw_init,
-    raw_encode,
-    raw_close,
-    raw_decode,
-};