Add Avid Meridien (AVUI) decoder.
authorCarl Eugen Hoyos <cehoyos@ag.or.at>
Tue, 8 May 2012 06:41:26 +0000 (08:41 +0200)
committerCarl Eugen Hoyos <cehoyos@ag.or.at>
Tue, 8 May 2012 06:41:26 +0000 (08:41 +0200)
Changelog
libavcodec/Makefile
libavcodec/allcodecs.c
libavcodec/avcodec.h
libavcodec/avuidec.c [new file with mode: 0644]
libavcodec/version.h
libavformat/isom.c

index 1987bff..c071637 100644 (file)
--- a/Changelog
+++ b/Changelog
@@ -28,6 +28,7 @@ version next:
 - super2xsai filter ported from libmpcodecs
 - add libavresample audio conversion library for compatibility
 - MicroDVD decoder
+- Avid Meridien (AVUI) decoder
 
 
 version 0.10:
index df4d908..74c6b0d 100644 (file)
@@ -103,6 +103,7 @@ OBJS-$(CONFIG_AURA2_DECODER)           += aura.o
 OBJS-$(CONFIG_AVRP_DECODER)            += r210dec.o
 OBJS-$(CONFIG_AVRP_ENCODER)            += r210enc.o
 OBJS-$(CONFIG_AVS_DECODER)             += avs.o
+OBJS-$(CONFIG_AVUI_DECODER)            += avuidec.o
 OBJS-$(CONFIG_AYUV_DECODER)            += v408dec.o
 OBJS-$(CONFIG_AYUV_ENCODER)            += v408enc.o
 OBJS-$(CONFIG_BETHSOFTVID_DECODER)     += bethsoftvideo.o
index 5390410..b2d8ea5 100644 (file)
@@ -81,6 +81,7 @@ void avcodec_register_all(void)
     REGISTER_DECODER (AURA2, aura2);
     REGISTER_ENCDEC  (AVRP, avrp);
     REGISTER_DECODER (AVS, avs);
+    REGISTER_DECODER (AVUI, avui);
     REGISTER_ENCDEC  (AYUV, ayuv);
     REGISTER_DECODER (BETHSOFTVID, bethsoftvid);
     REGISTER_DECODER (BFI, bfi);
index 21bd608..fd0007a 100644 (file)
@@ -263,6 +263,7 @@ enum CodecID {
     CODEC_ID_AVRP       = MKBETAG('A','V','R','P'),
 
     CODEC_ID_G2M        = MKBETAG( 0 ,'G','2','M'),
+    CODEC_ID_AVUI       = MKBETAG('A','V','U','I'),
     CODEC_ID_AYUV       = MKBETAG('A','Y','U','V'),
     CODEC_ID_V308       = MKBETAG('V','3','0','8'),
     CODEC_ID_V408       = MKBETAG('V','4','0','8'),
diff --git a/libavcodec/avuidec.c b/libavcodec/avuidec.c
new file mode 100644 (file)
index 0000000..89cf9b6
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * AVID Meridien decoder
+ *
+ * Copyright (c) 2012 Carl Eugen Hoyos
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "avcodec.h"
+
+static av_cold int avui_decode_init(AVCodecContext *avctx)
+{
+    avctx->pix_fmt = PIX_FMT_YUVA422P;
+
+    avctx->coded_frame = avcodec_alloc_frame();
+
+    if (!avctx->coded_frame) {
+        av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n");
+        return AVERROR(ENOMEM);
+    }
+
+    return 0;
+}
+
+static int avui_decode_frame(AVCodecContext *avctx, void *data,
+                             int *data_size, AVPacket *avpkt)
+{
+    AVFrame *pic = avctx->coded_frame;
+    const uint8_t *src = avpkt->data;
+    const uint8_t *srca = src + 2 * (avctx->height + 16) * avctx->width + 9;
+    uint8_t *y, *u, *v, *a;
+    int transparent = 0, i, j, k;
+
+    if (pic->data[0])
+        avctx->release_buffer(avctx, pic);
+
+    if (avpkt->size < 2 * avctx->width * (avctx->height + 16) + 4) {
+        av_log(avctx, AV_LOG_ERROR, "Insufficient input data.\n");
+        return AVERROR(EINVAL);
+    }
+    if (avpkt->size >= 4 * avctx->width * (avctx->height + 16) + 13)
+        transparent = 1;
+
+    pic->reference = 0;
+
+    if (avctx->get_buffer(avctx, pic) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
+        return AVERROR(ENOMEM);
+    }
+
+    pic->key_frame = 1;
+    pic->pict_type = AV_PICTURE_TYPE_I;
+
+    for (i = 0; i < 2; i++) {
+        src  += avctx->width * 16;
+        srca += avctx->width * 16;
+        y = pic->data[0] + i * pic->linesize[0];
+        u = pic->data[1] + i * pic->linesize[1];
+        v = pic->data[2] + i * pic->linesize[2];
+        a = pic->data[3] + i * pic->linesize[3];
+
+        for (j = 0; j < (avctx->height + 1) >> 1; j++) {
+            for (k = 0; k < (avctx->width + 1) >> 1; k++) {
+                u[    k    ] = *src++;
+                y[2 * k    ] = *src++;
+                a[2 * k    ] = 0xFF - (transparent ? *srca++ : 0);
+                srca++;
+                v[    k    ] = *src++;
+                y[2 * k + 1] = *src++;
+                a[2 * k + 1] = 0xFF - (transparent ? *srca++ : 0);
+                srca++;
+            }
+
+            y += 2 * pic->linesize[0];
+            u += 2 * pic->linesize[1];
+            v += 2 * pic->linesize[2];
+            a += 2 * pic->linesize[3];
+        }
+        src  += 4;
+        srca += 4;
+    }
+    *data_size = sizeof(AVFrame);
+    *(AVFrame *)data = *pic;
+
+    return avpkt->size;
+}
+
+static av_cold int avui_decode_close(AVCodecContext *avctx)
+{
+    if (avctx->coded_frame->data[0])
+        avctx->release_buffer(avctx, avctx->coded_frame);
+
+    av_freep(&avctx->coded_frame);
+
+    return 0;
+}
+
+AVCodec ff_avui_decoder = {
+    .name         = "avui",
+    .type         = AVMEDIA_TYPE_VIDEO,
+    .id           = CODEC_ID_AVUI,
+    .init         = avui_decode_init,
+    .decode       = avui_decode_frame,
+    .close        = avui_decode_close,
+    .capabilities = CODEC_CAP_DR1,
+    .long_name    = NULL_IF_CONFIG_SMALL("AVID Meridien"),
+};
index 016cfef..0ee3fd0 100644 (file)
@@ -27,7 +27,7 @@
  */
 
 #define LIBAVCODEC_VERSION_MAJOR 54
-#define LIBAVCODEC_VERSION_MINOR  20
+#define LIBAVCODEC_VERSION_MINOR  21
 #define LIBAVCODEC_VERSION_MICRO 100
 
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
index bb2237a..601be8c 100644 (file)
@@ -71,7 +71,6 @@ const AVCodecTag ff_codec_movvideo_tags[] = {
 
     { CODEC_ID_RAWVIDEO, MKTAG('r', 'a', 'w', ' ') }, /* Uncompressed RGB */
     { CODEC_ID_RAWVIDEO, MKTAG('y', 'u', 'v', '2') }, /* Uncompressed YUV422 */
-    { CODEC_ID_RAWVIDEO, MKTAG('A', 'V', 'U', 'I') }, /* AVID Uncompressed deinterleaved UYVY422 */
     { CODEC_ID_RAWVIDEO, MKTAG('2', 'v', 'u', 'y') }, /* UNCOMPRESSED 8BIT 4:2:2 */
     { CODEC_ID_RAWVIDEO, MKTAG('y', 'u', 'v', 's') }, /* same as 2vuy but byte swapped */
 
@@ -89,6 +88,7 @@ const AVCodecTag ff_codec_movvideo_tags[] = {
     { CODEC_ID_R10K,   MKTAG('R', '1', '0', 'k') }, /* UNCOMPRESSED 10BIT RGB */
     { CODEC_ID_R10K,   MKTAG('R', '1', '0', 'g') }, /* UNCOMPRESSED 10BIT RGB */
     { CODEC_ID_R210,   MKTAG('r', '2', '1', '0') }, /* UNCOMPRESSED 10BIT RGB */
+    { CODEC_ID_AVUI,   MKTAG('A', 'V', 'U', 'I') }, /* AVID Uncompressed deinterleaved UYVY422 */
     { CODEC_ID_AVRP,   MKTAG('A', 'V', 'r', 'p') }, /* Avid 1:1 10-bit RGB Packer */
     { CODEC_ID_AVRP,   MKTAG('S', 'U', 'D', 'S') }, /* Avid DS Uncompressed */
     { CODEC_ID_V210,   MKTAG('v', '2', '1', '0') }, /* UNCOMPRESSED 10BIT 4:2:2 */