[FFmpeg-cvslog] Support more Avid Meridien / AVUI samples.

Carl Eugen Hoyos git at videolan.org
Wed May 16 08:32:32 CEST 2012


ffmpeg | branch: master | Carl Eugen Hoyos <cehoyos at ag.or.at> | Wed May 16 08:29:56 2012 +0200| [183596fa081cc283c61ba3c0bb8386f9139f761f] | committer: Carl Eugen Hoyos

Support more Avid Meridien / AVUI samples.

Fixes ticket #1288.

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=183596fa081cc283c61ba3c0bb8386f9139f761f
---

 libavcodec/avuidec.c |   45 +++++++++++++++++++++++++++++++--------------
 1 file changed, 31 insertions(+), 14 deletions(-)

diff --git a/libavcodec/avuidec.c b/libavcodec/avuidec.c
index 89cf9b6..d43de33 100644
--- a/libavcodec/avuidec.c
+++ b/libavcodec/avuidec.c
@@ -41,19 +41,31 @@ static int avui_decode_frame(AVCodecContext *avctx, void *data,
 {
     AVFrame *pic = avctx->coded_frame;
     const uint8_t *src = avpkt->data;
-    const uint8_t *srca = src + 2 * (avctx->height + 16) * avctx->width + 9;
+    const uint8_t *srca;
     uint8_t *y, *u, *v, *a;
-    int transparent = 0, i, j, k;
+    int transparent, interlaced = 1, skip[2], i, j, k;
 
     if (pic->data[0])
         avctx->release_buffer(avctx, pic);
 
-    if (avpkt->size < 2 * avctx->width * (avctx->height + 16) + 4) {
+    if (!memcmp(&avctx->extradata[4], "APRGAPRG0001", 12) &&
+        avctx->extradata_size >= 24)
+        interlaced = avctx->extradata[19] != 1;
+    skip[0] = skip[1] = 16;
+    if (avctx->height == 486) {
+        skip[0] =  8;
+        skip[1] = 12;
+    }
+    if (avpkt->size < avctx->width * (2 * avctx->height + skip[0] + skip[1])
+                      + 4 * interlaced) {
         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;
+    transparent = avctx->bits_per_coded_sample == 32 &&
+                  avpkt->size >= (2 * avctx->height + skip[0] + skip[1]) *
+                                 2 * avctx->width + 4 + 8 * interlaced;
+    srca = src + (2 * avctx->height + skip[0] + skip[1]) * avctx->width
+           + 5 + interlaced * 4;
 
     pic->reference = 0;
 
@@ -65,16 +77,21 @@ static int avui_decode_frame(AVCodecContext *avctx, void *data,
     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;
+    if (!interlaced) {
+        src  += avctx->width * skip[1];
+        srca += avctx->width * skip[1];
+    }
+
+    for (i = 0; i < interlaced + 1; i++) {
+        src  += avctx->width * skip[i];
+        srca += avctx->width * skip[i];
         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++) {
+        for (j = 0; j < avctx->height >> interlaced; j++) {
+            for (k = 0; k < avctx->width >> 1; k++) {
                 u[    k    ] = *src++;
                 y[2 * k    ] = *src++;
                 a[2 * k    ] = 0xFF - (transparent ? *srca++ : 0);
@@ -85,10 +102,10 @@ static int avui_decode_frame(AVCodecContext *avctx, void *data,
                 srca++;
             }
 
-            y += 2 * pic->linesize[0];
-            u += 2 * pic->linesize[1];
-            v += 2 * pic->linesize[2];
-            a += 2 * pic->linesize[3];
+            y += (interlaced + 1) * pic->linesize[0];
+            u += (interlaced + 1) * pic->linesize[1];
+            v += (interlaced + 1) * pic->linesize[2];
+            a += (interlaced + 1) * pic->linesize[3];
         }
         src  += 4;
         srca += 4;



More information about the ffmpeg-cvslog mailing list