Browse code

lavc: move AVRn to a seperate decoder.

The special cases in demuxers and decoders are a mess otherwise (and more
would be needed to support it fully)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>

Michael Niedermayer authored on 2012/08/20 09:19:37
Showing 8 changed files
... ...
@@ -112,6 +112,7 @@ OBJS-$(CONFIG_ATRAC1_DECODER)          += atrac1.o atrac.o
112 112
 OBJS-$(CONFIG_ATRAC3_DECODER)          += atrac3.o atrac.o
113 113
 OBJS-$(CONFIG_AURA_DECODER)            += cyuv.o
114 114
 OBJS-$(CONFIG_AURA2_DECODER)           += aura.o
115
+OBJS-$(CONFIG_AVRP_DECODER)            += avrndec.o
115 116
 OBJS-$(CONFIG_AVRP_DECODER)            += r210dec.o
116 117
 OBJS-$(CONFIG_AVRP_ENCODER)            += r210enc.o
117 118
 OBJS-$(CONFIG_AVS_DECODER)             += avs.o
... ...
@@ -81,6 +81,7 @@ void avcodec_register_all(void)
81 81
     REGISTER_DECODER (AURA, aura);
82 82
     REGISTER_DECODER (AURA2, aura2);
83 83
     REGISTER_ENCDEC  (AVRP, avrp);
84
+    REGISTER_DECODER (AVRN, avrn);
84 85
     REGISTER_DECODER (AVS, avs);
85 86
     REGISTER_ENCDEC  (AVUI, avui);
86 87
     REGISTER_ENCDEC  (AYUV, ayuv);
... ...
@@ -276,6 +276,7 @@ enum AVCodecID {
276 276
     AV_CODEC_ID_YUV4       = MKBETAG('Y','U','V','4'),
277 277
     AV_CODEC_ID_SANM       = MKBETAG('S','A','N','M'),
278 278
     AV_CODEC_ID_PAF_VIDEO  = MKBETAG('P','A','F','V'),
279
+    AV_CODEC_ID_AVRN       = MKBETAG('A','V','R','n'),
279 280
 
280 281
     /* various PCM "codecs" */
281 282
     AV_CODEC_ID_FIRST_AUDIO = 0x10000,     ///< A dummy id pointing at the start of audio codecs
282 283
new file mode 100644
... ...
@@ -0,0 +1,129 @@
0
+/*
1
+ * AVRn decoder
2
+ * Copyright (c) 2012 Michael Niedermayer
3
+ *
4
+ * This file is part of FFmpeg.
5
+ *
6
+ * FFmpeg is free software; you can redistribute it and/or
7
+ * modify it under the terms of the GNU Lesser General Public
8
+ * License as published by the Free Software Foundation; either
9
+ * version 2.1 of the License, or (at your option) any later version.
10
+ *
11
+ * FFmpeg is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
+ * Lesser General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Lesser General Public
17
+ * License along with FFmpeg; if not, write to the Free Software
18
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
+ */
20
+
21
+#include "avcodec.h"
22
+#include "mjpeg.h"
23
+#include "mjpegdec.h"
24
+
25
+typedef struct {
26
+    MJpegDecodeContext mjpeg_ctx;
27
+    AVFrame frame;
28
+    int is_mjpeg;
29
+    int interlace; //FIXME use frame.interlaced_frame
30
+    int tff;
31
+} AVRnContext;
32
+
33
+static av_cold int init(AVCodecContext *avctx)
34
+{
35
+    AVRnContext *a = avctx->priv_data;
36
+
37
+    // Support "Resolution 1:1" for Avid AVI Codec
38
+    a->is_mjpeg = avctx->extradata_size < 31 || memcmp(&avctx->extradata[28], "1:1", 3);
39
+
40
+    if(a->is_mjpeg)
41
+        return ff_mjpeg_decode_init(avctx);
42
+
43
+    if(avctx->width <= 0 || avctx->height <= 0)
44
+        return -1;
45
+
46
+    avcodec_get_frame_defaults(&a->frame);
47
+    avctx->pix_fmt = PIX_FMT_UYVY422;
48
+
49
+    if(avctx->extradata_size >= 9 && avctx->extradata[4]+28 < avctx->extradata_size) {
50
+        int ndx = avctx->extradata[4] + 4;
51
+        a->interlace = !memcmp(avctx->extradata + ndx, "1:1(", 4);
52
+        if(a->interlace) {
53
+            a->tff = avctx->extradata[ndx + 24] == 1;
54
+        }
55
+    }
56
+
57
+    return 0;
58
+}
59
+
60
+static av_cold void end(AVCodecContext *avctx)
61
+{
62
+    AVRnContext *a = avctx->priv_data;
63
+    AVFrame *p = &a->frame;
64
+
65
+    if(p->data[0])
66
+        avctx->release_buffer(avctx, p);
67
+
68
+    if(a->is_mjpeg)
69
+        ff_mjpeg_decode_end(avctx);
70
+}
71
+
72
+static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt)
73
+{
74
+    AVRnContext *a = avctx->priv_data;
75
+    AVFrame *p = &a->frame;
76
+    const uint8_t *buf = avpkt->data;
77
+    int buf_size       = avpkt->size;
78
+    int y;
79
+
80
+    if(a->is_mjpeg)
81
+        return ff_mjpeg_decode_frame(avctx, data, data_size, avpkt);
82
+
83
+    if(p->data[0])
84
+        avctx->release_buffer(avctx, p);
85
+
86
+    if(buf_size < 2*avctx->width * avctx->height) {
87
+        av_log(avctx, AV_LOG_ERROR, "packet too small\n");
88
+        return AVERROR_INVALIDDATA;
89
+    }
90
+
91
+    if(avctx->get_buffer(avctx, p) < 0){
92
+        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
93
+        return -1;
94
+    }
95
+    p->pict_type= AV_PICTURE_TYPE_I;
96
+    p->key_frame= 1;
97
+
98
+    if(a->interlace) {
99
+        int true_height = buf_size / (2*avctx->width);
100
+        buf += (true_height - avctx->height)*avctx->width;
101
+        for(y = 0; y < avctx->height-1; y+=2) {
102
+            memcpy(p->data[0] + (y+ a->tff)*p->linesize[0], buf                             , 2*avctx->width);
103
+            memcpy(p->data[0] + (y+!a->tff)*p->linesize[0], buf + avctx->width*true_height+4, 2*avctx->width);
104
+            buf += 2*avctx->width;
105
+        }
106
+    } else {
107
+        for(y = 0; y < avctx->height; y++) {
108
+            memcpy(p->data[0] + y*p->linesize[0], buf, 2*avctx->width);
109
+            buf += 2*avctx->width;
110
+        }
111
+    }
112
+
113
+    *(AVFrame*)data = a->frame;
114
+    *data_size      = sizeof(AVFrame);
115
+    return buf_size;
116
+}
117
+
118
+AVCodec ff_avrn_decoder = {
119
+    .name           = "AVRn",
120
+    .type           = AVMEDIA_TYPE_VIDEO,
121
+    .id             = AV_CODEC_ID_AVRN,
122
+    .priv_data_size = sizeof(AVRnContext),
123
+    .init           = init,
124
+    .close          = end,
125
+    .decode         = decode_frame,
126
+    .long_name      = NULL_IF_CONFIG_SMALL("AVRn"),
127
+};
128
+
... ...
@@ -1175,6 +1175,12 @@ static const AVCodecDescriptor codec_descriptors[] = {
1175 1175
         .name      = "paf_video",
1176 1176
         .long_name = NULL_IF_CONFIG_SMALL("Amazing Studio Packed Animation File Video"),
1177 1177
     },
1178
+    {
1179
+        .id        = AV_CODEC_ID_AVRN,
1180
+        .type      = AVMEDIA_TYPE_VIDEO,
1181
+        .name      = "AVRn",
1182
+        .long_name = NULL_IF_CONFIG_SMALL("AVRn"),
1183
+    },
1178 1184
 
1179 1185
     /* various PCM "codecs" */
1180 1186
     {
... ...
@@ -39,7 +39,6 @@ typedef struct RawVideoContext {
39 39
     unsigned char * buffer;  /* block of memory for holding one frame */
40 40
     int             length;  /* number of bytes in buffer */
41 41
     int flip;
42
-    int interlace;
43 42
     AVFrame pic;             ///< AVCodecContext.coded_frame
44 43
     int tff;
45 44
 } RawVideoContext;
... ...
@@ -131,17 +130,6 @@ static av_cold int raw_init_decoder(AVCodecContext *avctx)
131 131
         avctx->codec_tag == MKTAG(3, 0, 0, 0) || avctx->codec_tag == MKTAG('W','R','A','W'))
132 132
         context->flip=1;
133 133
 
134
-    if(avctx->extradata_size >= 9 && avctx->extradata[4]+28 < avctx->extradata_size && !context->buffer && avctx->pix_fmt == PIX_FMT_UYVY422) {
135
-        int ndx = avctx->extradata[4] + 4;
136
-        context->interlace = !memcmp(avctx->extradata + ndx, "1:1(", 4);
137
-        if(context->interlace) {
138
-            context->buffer = av_malloc(context->length);
139
-            if (!context->buffer)
140
-                return AVERROR(ENOMEM);
141
-            context->tff = avctx->extradata[ndx + 24] == 1;
142
-        }
143
-    }
144
-
145 134
     return 0;
146 135
 }
147 136
 
... ...
@@ -185,41 +173,23 @@ static int raw_decode(AVCodecContext *avctx,
185 185
     if (context->buffer) {
186 186
         int i;
187 187
         uint8_t *dst = context->buffer;
188
-        if(avctx->pix_fmt == PIX_FMT_PAL8){
189
-            buf_size = context->length - AVPALETTE_SIZE;
190
-            if (avctx->bits_per_coded_sample == 4){
191
-                for(i=0; 2*i+1 < buf_size && i<avpkt->size; i++){
192
-                    dst[2*i+0]= buf[i]>>4;
193
-                    dst[2*i+1]= buf[i]&15;
194
-                }
195
-                linesize_align = 8;
196
-            } else {
197
-                av_assert0(avctx->bits_per_coded_sample == 2);
198
-                for(i=0; 4*i+3 < buf_size && i<avpkt->size; i++){
199
-                    dst[4*i+0]= buf[i]>>6;
200
-                    dst[4*i+1]= buf[i]>>4&3;
201
-                    dst[4*i+2]= buf[i]>>2&3;
202
-                    dst[4*i+3]= buf[i]   &3;
203
-                }
204
-                linesize_align = 16;
188
+        buf_size = context->length - AVPALETTE_SIZE;
189
+        if (avctx->bits_per_coded_sample == 4){
190
+            for(i=0; 2*i+1 < buf_size && i<avpkt->size; i++){
191
+                dst[2*i+0]= buf[i]>>4;
192
+                dst[2*i+1]= buf[i]&15;
205 193
             }
206
-        } else if(context->interlace && avctx->pix_fmt == PIX_FMT_UYVY422) {
207
-            int x, y;
208
-            int true_height = buf_size / (2*avctx->width);
209
-            int tff = !!context->tff;
210
-            av_assert0(avctx->height * avctx->width * 2 == context->length);
211
-            if (buf_size < context->length) {
212
-                av_log(avctx, AV_LOG_ERROR, "Invalid buffer size, packet size %d < context length %d\n", buf_size, context->length);
213
-                return AVERROR(EINVAL);
194
+            linesize_align = 8;
195
+        } else {
196
+            av_assert0(avctx->bits_per_coded_sample == 2);
197
+            for(i=0; 4*i+3 < buf_size && i<avpkt->size; i++){
198
+                dst[4*i+0]= buf[i]>>6;
199
+                dst[4*i+1]= buf[i]>>4&3;
200
+                dst[4*i+2]= buf[i]>>2&3;
201
+                dst[4*i+3]= buf[i]   &3;
214 202
             }
215
-            buf += (true_height - avctx->height)*avctx->width;
216
-            for(y = 0; y < avctx->height-1; y+=2) {
217
-                memcpy(dst + (y+ tff)*2*avctx->width, buf                             , 2*avctx->width);
218
-                memcpy(dst + (y+!tff)*2*avctx->width, buf + avctx->width*true_height+4, 2*avctx->width);
219
-                buf += 2*avctx->width;
220
-            }
221
-        }else
222
-            av_assert0(0);
203
+            linesize_align = 16;
204
+        }
223 205
         buf= dst;
224 206
     }
225 207
 
... ...
@@ -635,11 +635,6 @@ static int avi_read_header(AVFormatContext *s)
635 635
                     st->codec->codec_tag = tag1;
636 636
                     st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tag1);
637 637
                     st->need_parsing = AVSTREAM_PARSE_HEADERS; // This is needed to get the pict type which is necessary for generating correct pts.
638
-                    // Support "Resolution 1:1" for Avid AVI Codec
639
-                    if(tag1 == MKTAG('A', 'V', 'R', 'n') &&
640
-                       st->codec->extradata_size >= 31 &&
641
-                       !memcmp(&st->codec->extradata[28], "1:1", 3))
642
-                        st->codec->codec_id = AV_CODEC_ID_RAWVIDEO;
643 638
 
644 639
                     if(st->codec->codec_tag==0 && st->codec->height > 0 && st->codec->extradata_size < 1U<<30){
645 640
                         st->codec->extradata_size+= 9;
... ...
@@ -154,7 +154,7 @@ const AVCodecTag ff_codec_bmp_tags[] = {
154 154
     { AV_CODEC_ID_MJPEG,        MKTAG('M', 'J', 'L', 'S') }, /* JPEG-LS custom FOURCC for avi - decoder */
155 155
     { AV_CODEC_ID_MJPEG,        MKTAG('j', 'p', 'e', 'g') },
156 156
     { AV_CODEC_ID_MJPEG,        MKTAG('I', 'J', 'P', 'G') },
157
-    { AV_CODEC_ID_MJPEG,        MKTAG('A', 'V', 'R', 'n') },
157
+    { AV_CODEC_ID_AVRN,         MKTAG('A', 'V', 'R', 'n') },
158 158
     { AV_CODEC_ID_MJPEG,        MKTAG('A', 'C', 'D', 'V') },
159 159
     { AV_CODEC_ID_MJPEG,        MKTAG('Q', 'I', 'V', 'G') },
160 160
     { AV_CODEC_ID_MJPEG,        MKTAG('S', 'L', 'M', 'J') }, /* SL M-JPEG */