Browse code

New demuxers: Sega FILM/CPK, Westwood VQA & AUD; new decoders: MS RLE & Video-1, Apple RPZA, Cinepak, Westwood IMA ADPCM

Originally committed as revision 2324 to svn://svn.ffmpeg.org/ffmpeg/trunk

Mike Melanson authored on 2003/10/01 13:39:38
Showing 18 changed files
... ...
@@ -16,4 +16,6 @@ Michael Niedermayer
16 16

                
17 17
 Dieter Shirley
18 18
 Juan J. Sierralta
19
+Ewald Snel
20
+Roberto Togni
19 21
 Lionel Ulmer
... ...
@@ -1,3 +1,11 @@
1
+version <next>:
2
+- Microsoft RLE video decoder
3
+- Microsoft Video-1 decoder
4
+- Apple Video (RPZA) decoder
5
+- Cinepak decoder
6
+- Sega FILM (CPK) file demuxer
7
+- Westwood multimedia support (VQA/AUD file demuxer, audio decoder)
8
+
1 9
 version 0.4.8:
2 10
 
3 11
 - MPEG2 video encoding (Michael)
... ...
@@ -628,6 +628,10 @@ library:
628 628
 @tab format used in various Interplay computer games
629 629
 @item WC3 Movie        @tab    @tab X
630 630
 @tab multimedia format used in Origin's Wing Commander III computer game
631
+@item Sega FILM/CPK    @tab    @tab X
632
+@tab used in many Sega Saturn console games
633
+@item Westwood Studios VQA/AUD  @tab    @tab X
634
+@tab Multimedia formats used in Westwood Studios games
631 635
 @end multitable
632 636
 
633 637
 @code{X} means that the encoding (resp. decoding) is supported.
... ...
@@ -682,6 +686,10 @@ following image formats are supported:
682 682
 @item Id RoQ                 @tab     @tab  X @tab used in Quake III, Jedi Knight 2, other computer games
683 683
 @item Xan/WC3                @tab     @tab  X @tab used in Wing Commander III .MVE files
684 684
 @item Interplay Video        @tab     @tab  X @tab used in Interplay .MVE files
685
+@item Apple Video            @tab     @tab  X @tab fourcc: rpza
686
+@item Cinepak                @tab     @tab  X
687
+@item Microsoft RLE          @tab     @tab  X
688
+@item Microsoft Video-1      @tab     @tab  X
685 689
 @end multitable
686 690
 
687 691
 @code{X} means that the encoding (resp. decoding) is supported.
... ...
@@ -710,6 +718,8 @@ solutions.
710 710
 @tab used in some Sega Saturn console games
711 711
 @item Duck DK4 IMA ADPCM     @tab      @tab X
712 712
 @tab used in some Sega Saturn console games
713
+@item Westwood Studios IMA ADPCM @tab      @tab X
714
+@tab used in Westwood Studios games likes Command and Conquer
713 715
 @item RA144                  @tab      @tab X
714 716
 @tab Real 14400 bit/s codec
715 717
 @item RA288                  @tab      @tab X
... ...
@@ -17,7 +17,8 @@ OBJS= common.o utils.o mem.o allcodecs.o \
17 17
       ratecontrol.o adpcm.o eval.o dv.o error_resilience.o \
18 18
       fft.o mdct.o mace.o huffyuv.o cyuv.o opts.o raw.o h264.o golomb.o \
19 19
       vp3.o asv1.o 4xm.o cabac.o ffv1.o ra144.o ra288.o vcr1.o cljr.o \
20
-      roqvideo.o dpcm.o interplayvideo.o xan.o
20
+      roqvideo.o dpcm.o interplayvideo.o xan.o rpza.o cinepak.o msrle.o \
21
+      msvideo1.o
21 22
 
22 23
 ifeq ($(AMR_NB),yes)
23 24
 ifeq ($(AMR_NB_FIXED),yes)
... ...
@@ -22,7 +22,7 @@
22 22
  * @file adpcm.c
23 23
  * ADPCM codecs.
24 24
  * First version by Francois Revol revol@free.fr
25
- * Fringe ADPCM codecs (e.g., DK3 and DK4) 
25
+ * Fringe ADPCM codecs (e.g., DK3, DK4, Westwood)
26 26
  *   by Mike Melanson (melanson@pcisys.net)
27 27
  *
28 28
  * Features and limitations:
... ...
@@ -658,6 +658,25 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
658 658
             *samples++ = c->status[0].predictor - c->status[1].predictor;
659 659
         }
660 660
         break;
661
+    case CODEC_ID_ADPCM_IMA_WS:
662
+        /* no per-block initialization; just start decoding the data */
663
+        while (src < buf + buf_size) {
664
+
665
+            if (st) {
666
+                *samples++ = adpcm_ima_expand_nibble(&c->status[0], 
667
+                    (src[0] >> 4) & 0x0F);
668
+                *samples++ = adpcm_ima_expand_nibble(&c->status[1], 
669
+                    src[0] & 0x0F);
670
+            } else {
671
+                *samples++ = adpcm_ima_expand_nibble(&c->status[0], 
672
+                    (src[0] >> 4) & 0x0F);
673
+                *samples++ = adpcm_ima_expand_nibble(&c->status[0], 
674
+                    src[0] & 0x0F);
675
+            }
676
+
677
+            src++;
678
+        }
679
+        break;
661 680
     default:
662 681
         *data_size = 0;
663 682
         return -1;
... ...
@@ -692,6 +711,7 @@ ADPCM_CODEC(CODEC_ID_ADPCM_IMA_QT, adpcm_ima_qt);
692 692
 ADPCM_CODEC(CODEC_ID_ADPCM_IMA_WAV, adpcm_ima_wav);
693 693
 ADPCM_CODEC(CODEC_ID_ADPCM_IMA_DK3, adpcm_ima_dk3);
694 694
 ADPCM_CODEC(CODEC_ID_ADPCM_IMA_DK4, adpcm_ima_dk4);
695
+ADPCM_CODEC(CODEC_ID_ADPCM_IMA_WS, adpcm_ima_ws);
695 696
 ADPCM_CODEC(CODEC_ID_ADPCM_MS, adpcm_ms);
696 697
 ADPCM_CODEC(CODEC_ID_ADPCM_4XM, adpcm_4xm);
697 698
 
... ...
@@ -123,6 +123,10 @@ void avcodec_register_all(void)
123 123
     register_avcodec(&roq_decoder);
124 124
     register_avcodec(&interplay_video_decoder);
125 125
     register_avcodec(&xan_wc3_decoder);
126
+    register_avcodec(&rpza_decoder);
127
+    register_avcodec(&cinepak_decoder);
128
+    register_avcodec(&msrle_decoder);
129
+    register_avcodec(&msvideo1_decoder);
126 130
 #ifdef CONFIG_AC3
127 131
     register_avcodec(&ac3_decoder);
128 132
 #endif
... ...
@@ -163,6 +167,7 @@ PCM_CODEC(CODEC_ID_ADPCM_IMA_QT, adpcm_ima_qt);
163 163
 PCM_CODEC(CODEC_ID_ADPCM_IMA_WAV, adpcm_ima_wav);
164 164
 PCM_CODEC(CODEC_ID_ADPCM_IMA_DK3, adpcm_ima_dk3);
165 165
 PCM_CODEC(CODEC_ID_ADPCM_IMA_DK4, adpcm_ima_dk4);
166
+PCM_CODEC(CODEC_ID_ADPCM_IMA_WS, adpcm_ima_ws);
166 167
 PCM_CODEC(CODEC_ID_ADPCM_MS, adpcm_ms);
167 168
 PCM_CODEC(CODEC_ID_ADPCM_4XM, adpcm_4xm);
168 169
 
... ...
@@ -74,6 +74,11 @@ enum CodecID {
74 74
     CODEC_ID_INTERPLAY_VIDEO,
75 75
     CODEC_ID_XAN_WC3,
76 76
     CODEC_ID_XAN_WC4,
77
+    CODEC_ID_RPZA,
78
+    CODEC_ID_CINEPAK,
79
+    CODEC_ID_WS_VQA,
80
+    CODEC_ID_MSRLE,
81
+    CODEC_ID_MSVIDEO1,
77 82
 
78 83
     /* various pcm "codecs" */
79 84
     CODEC_ID_PCM_S16LE,
... ...
@@ -90,6 +95,7 @@ enum CodecID {
90 90
     CODEC_ID_ADPCM_IMA_WAV,
91 91
     CODEC_ID_ADPCM_IMA_DK3,
92 92
     CODEC_ID_ADPCM_IMA_DK4,
93
+    CODEC_ID_ADPCM_IMA_WS,
93 94
     CODEC_ID_ADPCM_MS,
94 95
     CODEC_ID_ADPCM_4XM,
95 96
 
... ...
@@ -1419,6 +1425,10 @@ extern AVCodec mdec_decoder;
1419 1419
 extern AVCodec roq_decoder;
1420 1420
 extern AVCodec interplay_video_decoder;
1421 1421
 extern AVCodec xan_wc3_decoder;
1422
+extern AVCodec rpza_decoder;
1423
+extern AVCodec cinepak_decoder;
1424
+extern AVCodec msrle_decoder;
1425
+extern AVCodec msvideo1_decoder;
1422 1426
 extern AVCodec ra_144_decoder;
1423 1427
 extern AVCodec ra_288_decoder;
1424 1428
 extern AVCodec roq_dpcm_decoder;
... ...
@@ -1445,6 +1455,7 @@ PCM_CODEC(CODEC_ID_ADPCM_IMA_QT, adpcm_ima_qt);
1445 1445
 PCM_CODEC(CODEC_ID_ADPCM_IMA_WAV, adpcm_ima_wav);
1446 1446
 PCM_CODEC(CODEC_ID_ADPCM_IMA_DK3, adpcm_ima_dk3);
1447 1447
 PCM_CODEC(CODEC_ID_ADPCM_IMA_DK4, adpcm_ima_dk4);
1448
+PCM_CODEC(CODEC_ID_ADPCM_IMA_WS, adpcm_ima_ws);
1448 1449
 PCM_CODEC(CODEC_ID_ADPCM_MS, adpcm_ms);
1449 1450
 PCM_CODEC(CODEC_ID_ADPCM_4XM, adpcm_4xm);
1450 1451
 
1451 1452
new file mode 100644
... ...
@@ -0,0 +1,456 @@
0
+/*
1
+ * Cinepak Video Decoder
2
+ * Copyright (C) 2003 the ffmpeg project
3
+ *
4
+ * This library is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU Lesser General Public
6
+ * License as published by the Free Software Foundation; either
7
+ * version 2 of the License, or (at your option) any later version.
8
+ *
9
+ * This library is distributed in the hope that it will be useful,
10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * Lesser General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU Lesser General Public
15
+ * License along with this library; if not, write to the Free Software
16
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
+ *
18
+ */
19
+
20
+/**
21
+ * @file cinepak.c
22
+ * Cinepak video decoder
23
+ * by Ewald Snel <ewald@rambo.its.tudelft.nl>
24
+ * For more information on the Cinepak algorithm, visit:
25
+ *   http://www.csse.monash.edu.au/~timf/
26
+ */
27
+
28
+#include <stdio.h>
29
+#include <stdlib.h>
30
+#include <string.h>
31
+#include <unistd.h>
32
+
33
+#include "common.h"
34
+#include "avcodec.h"
35
+#include "dsputil.h"
36
+
37
+#define PALETTE_COUNT 256
38
+
39
+#define BE_16(x)  ((((uint8_t*)(x))[0] << 8) | ((uint8_t*)(x))[1])
40
+#define BE_32(x)  ((((uint8_t*)(x))[0] << 24) | \
41
+                   (((uint8_t*)(x))[1] << 16) | \
42
+                   (((uint8_t*)(x))[2] << 8) | \
43
+                    ((uint8_t*)(x))[3])
44
+
45
+typedef struct {
46
+    uint8_t  y0, y1, y2, y3;
47
+    uint8_t  u, v;
48
+} cvid_codebook_t;
49
+
50
+#define MAX_STRIPS      32
51
+
52
+typedef struct {
53
+    uint16_t          id;
54
+    uint16_t          x1, y1;
55
+    uint16_t          x2, y2;
56
+    cvid_codebook_t   v4_codebook[256];
57
+    cvid_codebook_t   v1_codebook[256];
58
+} cvid_strip_t;
59
+
60
+typedef struct CinepakContext {
61
+
62
+    AVCodecContext *avctx;
63
+    DSPContext dsp;
64
+    AVFrame frame;
65
+    AVFrame prev_frame;
66
+
67
+    unsigned char *data;
68
+    int size;
69
+
70
+    unsigned char palette[PALETTE_COUNT * 4];
71
+    int palette_video;
72
+    cvid_strip_t strips[MAX_STRIPS];
73
+
74
+} CinepakContext;
75
+
76
+static void cinepak_decode_codebook (cvid_codebook_t *codebook,
77
+                                     int chunk_id, int size, uint8_t *data)
78
+{
79
+    uint8_t *eod = (data + size);
80
+    uint32_t flag, mask;
81
+    int      i, n;
82
+
83
+    /* check if this chunk contains 4- or 6-element vectors */
84
+    n    = (chunk_id & 0x0400) ? 4 : 6;
85
+    flag = 0;
86
+    mask = 0;
87
+
88
+    for (i=0; i < 256; i++) {
89
+        if ((chunk_id & 0x0100) && !(mask >>= 1)) {
90
+            if ((data + 4) > eod)
91
+                break;
92
+
93
+            flag  = BE_32 (data);
94
+            data += 4;
95
+            mask  = 0x80000000;
96
+        }
97
+
98
+        if (!(chunk_id & 0x0100) || (flag & mask)) {
99
+            if ((data + n) > eod)
100
+                break;
101
+
102
+            if (n == 6) {
103
+                codebook[i].y0 = *data++;
104
+                codebook[i].y1 = *data++;
105
+                codebook[i].y2 = *data++;
106
+                codebook[i].y3 = *data++;
107
+                codebook[i].u  = 128 + *data++;
108
+                codebook[i].v  = 128 + *data++;
109
+            } else {
110
+                /* this codebook type indicates either greyscale or 
111
+                 * palettized video; if palettized, U & V components will
112
+                 * not be used so it is safe to set them to 128 for the
113
+                 * benefit of greyscale rendering in YUV420P */
114
+                codebook[i].y0 = *data++;
115
+                codebook[i].y1 = *data++;
116
+                codebook[i].y2 = *data++;
117
+                codebook[i].y3 = *data++;
118
+                codebook[i].u  = 128;
119
+                codebook[i].v  = 128;
120
+            }
121
+        }
122
+    }
123
+}
124
+
125
+static int cinepak_decode_vectors (CinepakContext *s, cvid_strip_t *strip,
126
+                                   int chunk_id, int size, uint8_t *data)
127
+{
128
+    uint8_t         *eod = (data + size);
129
+    uint32_t         flag, mask;
130
+    cvid_codebook_t *codebook;
131
+    unsigned int     i, j, x, y;
132
+    uint32_t         iy[4];
133
+    uint32_t         iu[2];
134
+    uint32_t         iv[2];
135
+
136
+    flag = 0;
137
+    mask = 0;
138
+
139
+    for (y=strip->y1; y < strip->y2; y+=4) {
140
+
141
+        iy[0] = strip->x1 + (y * s->frame.linesize[0]);
142
+        iy[1] = iy[0] + s->frame.linesize[0];
143
+        iy[2] = iy[1] + s->frame.linesize[0];
144
+        iy[3] = iy[2] + s->frame.linesize[0];
145
+        iu[0] = (strip->x1/2) + ((y/2) * s->frame.linesize[1]);
146
+        iu[1] = iu[0] + s->frame.linesize[1];
147
+        iv[0] = (strip->x1/2) + ((y/2) * s->frame.linesize[2]);
148
+        iv[1] = iv[0] + s->frame.linesize[2];
149
+
150
+        for (x=strip->x1; x < strip->x2; x+=4) {
151
+            if ((chunk_id & 0x0100) && !(mask >>= 1)) {
152
+                if ((data + 4) > eod)
153
+                    return -1;
154
+
155
+                flag  = BE_32 (data);
156
+                data += 4;
157
+                mask  = 0x80000000;
158
+            }
159
+
160
+            if (!(chunk_id & 0x0100) || (flag & mask)) {
161
+                if (!(chunk_id & 0x0200) && !(mask >>= 1)) {
162
+                    if ((data + 4) > eod)
163
+                        return -1;
164
+
165
+                    flag  = BE_32 (data);
166
+                    data += 4;
167
+                    mask  = 0x80000000;
168
+                }
169
+
170
+                if ((chunk_id & 0x0200) || (~flag & mask)) {
171
+                    if (data >= eod)
172
+                        return -1;
173
+
174
+                    codebook = &strip->v1_codebook[*data++];
175
+                    s->frame.data[0][iy[0] + 0] = codebook->y0;
176
+                    s->frame.data[0][iy[0] + 1] = codebook->y0;
177
+                    s->frame.data[0][iy[1] + 0] = codebook->y0;
178
+                    s->frame.data[0][iy[1] + 1] = codebook->y0;
179
+                    if (!s->palette_video) {
180
+                        s->frame.data[1][iu[0]] = codebook->u;
181
+                        s->frame.data[2][iv[0]] = codebook->v;
182
+                    }
183
+
184
+                    s->frame.data[0][iy[0] + 2] = codebook->y0;
185
+                    s->frame.data[0][iy[0] + 3] = codebook->y0;
186
+                    s->frame.data[0][iy[1] + 2] = codebook->y0;
187
+                    s->frame.data[0][iy[1] + 3] = codebook->y0;
188
+                    if (!s->palette_video) {
189
+                        s->frame.data[1][iu[0] + 1] = codebook->u;
190
+                        s->frame.data[2][iv[0] + 1] = codebook->v;
191
+                    }
192
+
193
+                    s->frame.data[0][iy[2] + 0] = codebook->y0;
194
+                    s->frame.data[0][iy[2] + 1] = codebook->y0;
195
+                    s->frame.data[0][iy[3] + 0] = codebook->y0;
196
+                    s->frame.data[0][iy[3] + 1] = codebook->y0;
197
+                    if (!s->palette_video) {
198
+                        s->frame.data[1][iu[1]] = codebook->u;
199
+                        s->frame.data[2][iv[1]] = codebook->v;
200
+                    }
201
+
202
+                    s->frame.data[0][iy[2] + 2] = codebook->y0;
203
+                    s->frame.data[0][iy[2] + 3] = codebook->y0;
204
+                    s->frame.data[0][iy[3] + 2] = codebook->y0;
205
+                    s->frame.data[0][iy[3] + 3] = codebook->y0;
206
+                    if (!s->palette_video) {
207
+                        s->frame.data[1][iu[1] + 1] = codebook->u;
208
+                        s->frame.data[2][iv[1] + 1] = codebook->v;
209
+                    }
210
+
211
+                } else if (flag & mask) {
212
+                    if ((data + 4) > eod)
213
+                        return -1;
214
+
215
+                    codebook = &strip->v4_codebook[*data++];
216
+                    s->frame.data[0][iy[0] + 0] = codebook->y0;
217
+                    s->frame.data[0][iy[0] + 1] = codebook->y1;
218
+                    s->frame.data[0][iy[1] + 0] = codebook->y2;
219
+                    s->frame.data[0][iy[1] + 1] = codebook->y3;
220
+                    if (!s->palette_video) {
221
+                        s->frame.data[1][iu[0]] = codebook->u;
222
+                        s->frame.data[2][iv[0]] = codebook->v;
223
+                    }
224
+
225
+                    codebook = &strip->v4_codebook[*data++];
226
+                    s->frame.data[0][iy[0] + 2] = codebook->y0;
227
+                    s->frame.data[0][iy[0] + 3] = codebook->y1;
228
+                    s->frame.data[0][iy[1] + 2] = codebook->y2;
229
+                    s->frame.data[0][iy[1] + 3] = codebook->y3;
230
+                    if (!s->palette_video) {
231
+                        s->frame.data[1][iu[0] + 1] = codebook->u;
232
+                        s->frame.data[2][iv[0] + 1] = codebook->v;
233
+                    }
234
+
235
+                    codebook = &strip->v4_codebook[*data++];
236
+                    s->frame.data[0][iy[2] + 0] = codebook->y0;
237
+                    s->frame.data[0][iy[2] + 1] = codebook->y1;
238
+                    s->frame.data[0][iy[3] + 0] = codebook->y2;
239
+                    s->frame.data[0][iy[3] + 1] = codebook->y3;
240
+                    if (!s->palette_video) {
241
+                        s->frame.data[1][iu[1]] = codebook->u;
242
+                        s->frame.data[2][iv[1]] = codebook->v;
243
+                    }
244
+
245
+                    codebook = &strip->v4_codebook[*data++];
246
+                    s->frame.data[0][iy[2] + 2] = codebook->y0;
247
+                    s->frame.data[0][iy[2] + 3] = codebook->y1;
248
+                    s->frame.data[0][iy[3] + 2] = codebook->y2;
249
+                    s->frame.data[0][iy[3] + 3] = codebook->y3;
250
+                    if (!s->palette_video) {
251
+                        s->frame.data[1][iu[1] + 1] = codebook->u;
252
+                        s->frame.data[2][iv[1] + 1] = codebook->v;
253
+                    }
254
+
255
+                }
256
+            } else {
257
+                /* copy from the previous frame */
258
+                for (i = 0; i < 4; i++) {
259
+                    for (j = 0; j < 4; j++) {
260
+                        s->frame.data[0][iy[i] + j] =
261
+                            s->prev_frame.data[0][iy[i] + j];
262
+                    }
263
+                }
264
+                for (i = 0; i < 2; i++) {
265
+                    for (j = 0; j < 2; j++) {
266
+                        s->frame.data[1][iu[i] + j] =
267
+                            s->prev_frame.data[1][iu[i] + j];
268
+                        s->frame.data[2][iv[i] + j] =
269
+                            s->prev_frame.data[2][iv[i] + j];
270
+                    }
271
+                }
272
+            }
273
+
274
+            iy[0] += 4;  iy[1] += 4;
275
+            iy[2] += 4;  iy[3] += 4;
276
+            iu[0] += 2;  iu[1] += 2;
277
+            iv[0] += 2;  iv[1] += 2;
278
+        }
279
+    }
280
+
281
+    return 0;
282
+}
283
+
284
+static int cinepak_decode_strip (CinepakContext *s,
285
+                                 cvid_strip_t *strip, uint8_t *data, int size)
286
+{
287
+    uint8_t *eod = (data + size);
288
+    int      chunk_id, chunk_size;
289
+
290
+    /* coordinate sanity checks */
291
+    if (strip->x1 >= s->avctx->width  || strip->x2 > s->avctx->width  ||
292
+        strip->y1 >= s->avctx->height || strip->y2 > s->avctx->height ||
293
+        strip->x1 >= strip->x2        || strip->y1 >= strip->y2)
294
+        return -1;
295
+
296
+    while ((data + 4) <= eod) {
297
+        chunk_id   = BE_16 (&data[0]);
298
+        chunk_size = BE_16 (&data[2]) - 4;
299
+        data      += 4;
300
+        chunk_size = ((data + chunk_size) > eod) ? (eod - data) : chunk_size;
301
+
302
+        switch (chunk_id) {
303
+
304
+        case 0x2000:
305
+        case 0x2100:
306
+        case 0x2400:
307
+        case 0x2500:
308
+            cinepak_decode_codebook (strip->v4_codebook, chunk_id, 
309
+                chunk_size, data);
310
+            break;
311
+
312
+        case 0x2200:
313
+        case 0x2300:
314
+        case 0x2600:
315
+        case 0x2700:
316
+            cinepak_decode_codebook (strip->v1_codebook, chunk_id, 
317
+                chunk_size, data);
318
+            break;
319
+
320
+        case 0x3000:
321
+        case 0x3100:
322
+        case 0x3200:
323
+            return cinepak_decode_vectors (s, strip, chunk_id, 
324
+                chunk_size, data);
325
+        }
326
+
327
+        data += chunk_size;
328
+    }
329
+
330
+    return -1;
331
+}
332
+
333
+static int cinepak_decode (CinepakContext *s)
334
+{
335
+    uint8_t      *eod = (s->data + s->size);
336
+    int           i, result, strip_size, frame_flags, num_strips;
337
+    int           y0 = 0;
338
+
339
+    if (s->size < 10)
340
+        return -1;
341
+
342
+    frame_flags = s->data[0];
343
+    num_strips  = BE_16 (&s->data[8]);
344
+    s->data    += 10;
345
+
346
+    if (num_strips > MAX_STRIPS)
347
+        num_strips = MAX_STRIPS;
348
+
349
+    for (i=0; i < num_strips; i++) {
350
+        if ((s->data + 12) > eod)
351
+            return -1;
352
+
353
+        s->strips[i].id = BE_16 (s->data);
354
+        s->strips[i].y1 = y0;
355
+        s->strips[i].x1 = 0;
356
+        s->strips[i].y2 = y0 + BE_16 (&s->data[8]);
357
+        s->strips[i].x2 = s->avctx->width;
358
+
359
+        strip_size = BE_16 (&s->data[2]) - 12;
360
+        s->data   += 12;
361
+        strip_size = ((s->data + strip_size) > eod) ? (eod - s->data) : strip_size;
362
+
363
+        if ((i > 0) && !(frame_flags & 0x01)) {
364
+            memcpy (s->strips[i].v4_codebook, s->strips[i-1].v4_codebook,
365
+                sizeof(s->strips[i].v4_codebook));
366
+            memcpy (s->strips[i].v1_codebook, s->strips[i-1].v1_codebook,
367
+                sizeof(s->strips[i].v1_codebook));
368
+        }
369
+
370
+        result = cinepak_decode_strip (s, &s->strips[i], s->data, strip_size);
371
+
372
+        if (result != 0)
373
+            return result;
374
+
375
+        s->data += strip_size;
376
+        y0    = s->strips[i].y2;
377
+    }
378
+    return 0;
379
+}
380
+
381
+static int cinepak_decode_init(AVCodecContext *avctx)
382
+{
383
+    CinepakContext *s = (CinepakContext *)avctx->priv_data;
384
+/*
385
+    int i;
386
+    unsigned char r, g, b;
387
+    unsigned char *raw_palette;
388
+    unsigned int *palette32;
389
+*/
390
+
391
+    s->avctx = avctx;
392
+
393
+// check for paletted data
394
+s->palette_video = 0;
395
+
396
+
397
+    avctx->pix_fmt = PIX_FMT_YUV420P;
398
+    avctx->has_b_frames = 0;
399
+    dsputil_init(&s->dsp, avctx);
400
+
401
+    s->frame.data[0] = s->prev_frame.data[0] = NULL;
402
+
403
+    return 0;
404
+}
405
+
406
+static int cinepak_decode_frame(AVCodecContext *avctx,
407
+                                void *data, int *data_size,
408
+                                uint8_t *buf, int buf_size)
409
+{
410
+    CinepakContext *s = (CinepakContext *)avctx->priv_data;
411
+
412
+    s->data = buf;
413
+    s->size = buf_size;
414
+
415
+    if (avctx->get_buffer(avctx, &s->frame)) {
416
+        printf ("  Cinepak: get_buffer() failed\n");
417
+        return -1;
418
+    }
419
+
420
+    cinepak_decode(s);
421
+
422
+    if (s->prev_frame.data[0])
423
+        avctx->release_buffer(avctx, &s->prev_frame);
424
+
425
+    /* shuffle frames */
426
+    s->prev_frame = s->frame;
427
+
428
+    *data_size = sizeof(AVFrame);
429
+    *(AVFrame*)data = s->frame;
430
+
431
+    /* report that the buffer was completely consumed */
432
+    return buf_size;
433
+}
434
+
435
+static int cinepak_decode_end(AVCodecContext *avctx)
436
+{
437
+    CinepakContext *s = (CinepakContext *)avctx->priv_data;
438
+
439
+    if (s->prev_frame.data[0])
440
+        avctx->release_buffer(avctx, &s->prev_frame);
441
+
442
+    return 0;
443
+}
444
+
445
+AVCodec cinepak_decoder = {
446
+    "cinepak",
447
+    CODEC_TYPE_VIDEO,
448
+    CODEC_ID_CINEPAK,
449
+    sizeof(CinepakContext),
450
+    cinepak_decode_init,
451
+    NULL,
452
+    cinepak_decode_end,
453
+    cinepak_decode_frame,
454
+    CODEC_CAP_DR1,
455
+};
0 456
new file mode 100644
... ...
@@ -0,0 +1,219 @@
0
+/*
1
+ * Micrsoft RLE Video Decoder
2
+ * Copyright (C) 2003 the ffmpeg project
3
+ *
4
+ * This library is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU Lesser General Public
6
+ * License as published by the Free Software Foundation; either
7
+ * version 2 of the License, or (at your option) any later version.
8
+ *
9
+ * This library is distributed in the hope that it will be useful,
10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * Lesser General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU Lesser General Public
15
+ * License along with this library; if not, write to the Free Software
16
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
+ */
18
+
19
+/**
20
+ * @file msrle.c
21
+ * MS RLE Video Decoder by Mike Melanson (melanson@pcisys.net)
22
+ * For more information about the MS RLE format, visit:
23
+ *   http://www.pcisys.net/~melanson/codecs/
24
+ *
25
+ * The MS RLE decoder outputs PAL8 colorspace data.
26
+ *
27
+ * Note that this decoder expects the palette colors from the end of the
28
+ * BITMAPINFO header passed through extradata.
29
+ */
30
+
31
+#include <stdio.h>
32
+#include <stdlib.h>
33
+#include <string.h>
34
+#include <unistd.h>
35
+
36
+#include "common.h"
37
+#include "avcodec.h"
38
+#include "dsputil.h"
39
+
40
+typedef struct MsrleContext {
41
+    AVCodecContext *avctx;
42
+    AVFrame frame;
43
+    AVFrame prev_frame;
44
+
45
+    unsigned char *buf;
46
+    int size;
47
+
48
+    unsigned int palette[256];
49
+} MsrleContext;
50
+
51
+#define FETCH_NEXT_STREAM_BYTE() \
52
+    if (stream_ptr >= s->size) \
53
+    { \
54
+      printf(" MS RLE: stream ptr just went out of bounds (1)\n"); \
55
+      return; \
56
+    } \
57
+    stream_byte = s->buf[stream_ptr++];
58
+
59
+static void msrle_decode_pal8(MsrleContext *s)
60
+{
61
+    int stream_ptr = 0;
62
+    unsigned char rle_code;
63
+    unsigned char extra_byte;
64
+    unsigned char stream_byte;
65
+    int pixel_ptr = 0;
66
+    int row_dec = s->frame.linesize[0];
67
+    int row_ptr = (s->avctx->height - 1) * row_dec;
68
+    int frame_size = row_dec * s->avctx->height;
69
+
70
+    while (row_ptr >= 0) {
71
+        FETCH_NEXT_STREAM_BYTE();
72
+        rle_code = stream_byte;
73
+        if (rle_code == 0) {
74
+            /* fetch the next byte to see how to handle escape code */
75
+            FETCH_NEXT_STREAM_BYTE();
76
+            if (stream_byte == 0) {
77
+                /* line is done, goto the next one */
78
+                row_ptr -= row_dec;
79
+                pixel_ptr = 0;
80
+            } else if (stream_byte == 1) {
81
+                /* decode is done */
82
+                return;
83
+            } else if (stream_byte == 2) {
84
+                /* reposition frame decode coordinates */
85
+                FETCH_NEXT_STREAM_BYTE();
86
+                pixel_ptr += stream_byte;
87
+                FETCH_NEXT_STREAM_BYTE();
88
+                row_ptr -= stream_byte * row_dec;
89
+            } else {
90
+                /* copy pixels from encoded stream */
91
+                if ((row_ptr + pixel_ptr + stream_byte > frame_size) ||
92
+                    (row_ptr < 0)) {
93
+                    printf(" MS RLE: frame ptr just went out of bounds (1)\n");
94
+                    return;
95
+                }
96
+
97
+                rle_code = stream_byte;
98
+                extra_byte = stream_byte & 0x01;
99
+                if (stream_ptr + rle_code + extra_byte > s->size) {
100
+                    printf(" MS RLE: stream ptr just went out of bounds (2)\n");
101
+                    return;
102
+                }
103
+
104
+                while (rle_code--) {
105
+                    FETCH_NEXT_STREAM_BYTE();
106
+                    s->frame.data[0][row_ptr + pixel_ptr] = stream_byte;
107
+                    pixel_ptr++;
108
+                }
109
+
110
+                /* if the RLE code is odd, skip a byte in the stream */
111
+                if (extra_byte)
112
+                    stream_ptr++;
113
+            }
114
+        } else {
115
+            /* decode a run of data */
116
+            if ((row_ptr + pixel_ptr + stream_byte > frame_size) ||
117
+                (row_ptr < 0)) {
118
+                printf(" MS RLE: frame ptr just went out of bounds (2)\n");
119
+                return;
120
+            }
121
+
122
+            FETCH_NEXT_STREAM_BYTE();
123
+
124
+            while(rle_code--) {
125
+                s->frame.data[0][row_ptr + pixel_ptr] = stream_byte;
126
+                pixel_ptr++;
127
+            }
128
+        }
129
+    }
130
+
131
+    /* make the palette available */
132
+    memcpy(s->frame.data[1], s->palette, 256 * 4);
133
+
134
+    /* one last sanity check on the way out */
135
+    if (stream_ptr < s->size)
136
+        printf(" MS RLE: ended frame decode with bytes left over (%d < %d)\n",
137
+            stream_ptr, s->size);
138
+}
139
+
140
+static int msrle_decode_init(AVCodecContext *avctx)
141
+{
142
+    MsrleContext *s = (MsrleContext *)avctx->priv_data;
143
+    int i, j;
144
+    unsigned char *palette;
145
+
146
+    s->avctx = avctx;
147
+
148
+    avctx->pix_fmt = PIX_FMT_PAL8;
149
+    avctx->has_b_frames = 0;
150
+    s->frame.data[0] = s->prev_frame.data[0] = NULL;
151
+
152
+    /* convert palette */
153
+    palette = (unsigned char *)s->avctx->extradata;
154
+    memset (s->palette, 0, 256 * 4);
155
+    for (i = 0, j = 0; i < s->avctx->extradata_size / 4; i++, j += 4)
156
+        s->palette[i] = 
157
+            (palette[j + 2] << 16) |
158
+            (palette[j + 1] <<  8) |
159
+            (palette[j + 0] <<  0);
160
+
161
+    return 0;
162
+}
163
+
164
+static int msrle_decode_frame(AVCodecContext *avctx,
165
+                              void *data, int *data_size,
166
+                              uint8_t *buf, int buf_size)
167
+{
168
+    MsrleContext *s = (MsrleContext *)avctx->priv_data;
169
+
170
+    s->buf = buf;
171
+    s->size = buf_size;
172
+
173
+    if (avctx->get_buffer(avctx, &s->frame)) {
174
+        printf ("  MS RLE: get_buffer() failed\n");
175
+        return -1;
176
+    }
177
+
178
+    /* grossly inefficient, but...oh well */
179
+    memcpy(s->frame.data[0], s->prev_frame.data[0], 
180
+        s->frame.linesize[0] * s->avctx->height);
181
+
182
+    msrle_decode_pal8(s);
183
+
184
+    if (s->frame.data[0])
185
+        avctx->release_buffer(avctx, &s->frame);
186
+
187
+    /* shuffle frames */
188
+    s->prev_frame = s->frame;
189
+
190
+    *data_size = sizeof(AVFrame);
191
+    *(AVFrame*)data = s->frame;
192
+
193
+    /* report that the buffer was completely consumed */
194
+    return buf_size;
195
+}
196
+
197
+static int msrle_decode_end(AVCodecContext *avctx)
198
+{
199
+    MsrleContext *s = (MsrleContext *)avctx->priv_data;
200
+
201
+    /* release the last frame */
202
+    if (s->prev_frame.data[0])
203
+        avctx->release_buffer(avctx, &s->prev_frame);
204
+
205
+    return 0;
206
+}
207
+
208
+AVCodec msrle_decoder = {
209
+    "msrle",
210
+    CODEC_TYPE_VIDEO,
211
+    CODEC_ID_MSRLE,
212
+    sizeof(MsrleContext),
213
+    msrle_decode_init,
214
+    NULL,
215
+    msrle_decode_end,
216
+    msrle_decode_frame,
217
+    CODEC_CAP_DR1,
218
+};
0 219
new file mode 100644
... ...
@@ -0,0 +1,378 @@
0
+/*
1
+ * Microsoft Video-1 Decoder
2
+ * Copyright (C) 2003 the ffmpeg project
3
+ *
4
+ * This library is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU Lesser General Public
6
+ * License as published by the Free Software Foundation; either
7
+ * version 2 of the License, or (at your option) any later version.
8
+ *
9
+ * This library is distributed in the hope that it will be useful,
10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * Lesser General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU Lesser General Public
15
+ * License along with this library; if not, write to the Free Software
16
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
+ *
18
+ */
19
+
20
+/**
21
+ * @file msvideo1.c
22
+ * Microsoft Video-1 Decoder by Mike Melanson (melanson@pcisys.net)
23
+ * For more information about the MS Video-1 format, visit:
24
+ *   http://www.pcisys.net/~melanson/codecs/
25
+ *
26
+ * This decoder outputs either PAL8 or RGB555 data, depending on the
27
+ * whether a RGB palette was passed through via extradata; if the extradata
28
+ * is present, then the data is PAL8; RGB555 otherwise.
29
+ */
30
+
31
+#include <stdio.h>
32
+#include <stdlib.h>
33
+#include <string.h>
34
+#include <unistd.h>
35
+
36
+#include "common.h"
37
+#include "avcodec.h"
38
+#include "dsputil.h"
39
+
40
+#define PALETTE_COUNT 256
41
+#define LE_16(x)  ((((uint8_t*)(x))[1] << 8) | ((uint8_t*)(x))[0])
42
+#define CHECK_STREAM_PTR(n) \
43
+  if ((stream_ptr + n) > s->size ) { \
44
+    printf (" MS Video-1 warning: stream_ptr out of bounds (%d >= %d)\n", \
45
+      stream_ptr + n, s->size); \
46
+    return; \
47
+  }
48
+
49
+#define COPY_PREV_BLOCK() \
50
+    pixel_ptr = block_ptr; \
51
+    for (pixel_y = 0; pixel_y < 4; pixel_y++) { \
52
+        for (pixel_x = 0; pixel_x < 4; pixel_x++, pixel_ptr++) \
53
+            pixels[pixel_ptr] = prev_pixels[pixel_ptr]; \
54
+        pixel_ptr -= row_dec; \
55
+    }
56
+
57
+typedef struct Msvideo1Context {
58
+
59
+    AVCodecContext *avctx;
60
+    DSPContext dsp;
61
+    AVFrame frame;
62
+    AVFrame prev_frame;
63
+
64
+    unsigned char *buf;
65
+    int size;
66
+
67
+    int mode_8bit;  /* if it's not 8-bit, it's 16-bit */
68
+    unsigned char palette[PALETTE_COUNT * 4];
69
+
70
+} Msvideo1Context;
71
+
72
+static int msvideo1_decode_init(AVCodecContext *avctx)
73
+{
74
+    Msvideo1Context *s = (Msvideo1Context *)avctx->priv_data;
75
+    int i;
76
+    unsigned char r, g, b;
77
+    unsigned char *raw_palette;
78
+    unsigned int *palette32;
79
+
80
+    s->avctx = avctx;
81
+
82
+    /* figure out the colorspace based on the presence of a palette in
83
+     * extradata */
84
+    if (s->avctx->extradata_size) {
85
+        s->mode_8bit = 1;
86
+        /* load up the palette */
87
+        palette32 = (unsigned int *)s->palette;
88
+        raw_palette = (unsigned char *)s->avctx->extradata;
89
+        for (i = 0; i < s->avctx->extradata_size / 4; i++) {
90
+            b = *raw_palette++;
91
+            g = *raw_palette++;
92
+            r = *raw_palette++;
93
+            raw_palette++;
94
+            palette32[i] = (r << 16) | (g << 8) | (b);
95
+        }
96
+        avctx->pix_fmt = PIX_FMT_PAL8;
97
+    } else {
98
+        s->mode_8bit = 0;
99
+        avctx->pix_fmt = PIX_FMT_RGB555;
100
+    }
101
+
102
+    avctx->has_b_frames = 0;
103
+    dsputil_init(&s->dsp, avctx);
104
+
105
+    s->frame.data[0] = s->prev_frame.data[0] = NULL;
106
+
107
+    return 0;
108
+}
109
+
110
+static void msvideo1_decode_8bit(Msvideo1Context *s)
111
+{
112
+    int block_ptr, pixel_ptr;
113
+    int total_blocks;
114
+    int pixel_x, pixel_y;  /* pixel width and height iterators */
115
+    int block_x, block_y;  /* block width and height iterators */
116
+    int blocks_wide, blocks_high;  /* width and height in 4x4 blocks */
117
+    int block_inc;
118
+    int row_dec;
119
+
120
+    /* decoding parameters */
121
+    int stream_ptr;
122
+    unsigned char byte_a, byte_b;
123
+    unsigned short flags;
124
+    int skip_blocks;
125
+    unsigned char colors[8];
126
+    unsigned char *pixels = s->frame.data[0];
127
+    unsigned char *prev_pixels = s->prev_frame.data[0];
128
+    int stride = s->frame.linesize[0];
129
+
130
+    stream_ptr = 0;
131
+    skip_blocks = 0;
132
+    blocks_wide = s->avctx->width / 4;
133
+    blocks_high = s->avctx->height / 4;
134
+    total_blocks = blocks_wide * blocks_high;
135
+    block_inc = 4;
136
+    row_dec = stride + 4;
137
+
138
+    for (block_y = blocks_high; block_y > 0; block_y--) {
139
+        block_ptr = ((block_y * 4) - 1) * stride;
140
+        for (block_x = blocks_wide; block_x > 0; block_x--) {
141
+            /* check if this block should be skipped */
142
+            if (skip_blocks) {
143
+                COPY_PREV_BLOCK();
144
+                block_ptr += block_inc;
145
+                skip_blocks--;
146
+                total_blocks--;
147
+                continue;
148
+            }
149
+
150
+            pixel_ptr = block_ptr;
151
+
152
+            /* get the next two bytes in the encoded data stream */
153
+            CHECK_STREAM_PTR(2);
154
+            byte_a = s->buf[stream_ptr++];
155
+            byte_b = s->buf[stream_ptr++];
156
+
157
+            /* check if the decode is finished */
158
+            if ((byte_a == 0) && (byte_b == 0) && (total_blocks == 0))
159
+                return;
160
+            else if ((byte_b & 0xFC) == 0x84) {
161
+                /* skip code, but don't count the current block */
162
+                skip_blocks = ((byte_b - 0x84) << 8) + byte_a - 1;
163
+                COPY_PREV_BLOCK();
164
+            } else if (byte_b < 0x80) {
165
+                /* 2-color encoding */
166
+                flags = (byte_b << 8) | byte_a;
167
+
168
+                CHECK_STREAM_PTR(2);
169
+                colors[0] = s->buf[stream_ptr++];
170
+                colors[1] = s->buf[stream_ptr++];
171
+
172
+                for (pixel_y = 0; pixel_y < 4; pixel_y++) {
173
+                    for (pixel_x = 0; pixel_x < 4; pixel_x++, flags >>= 1)
174
+                        pixels[pixel_ptr++] = colors[(flags & 0x1) ^ 1];
175
+                    pixel_ptr -= row_dec;
176
+                }
177
+            } else if (byte_b >= 0x90) {
178
+                /* 8-color encoding */
179
+                flags = (byte_b << 8) | byte_a;
180
+
181
+                CHECK_STREAM_PTR(8);
182
+                memcpy(colors, &s->buf[stream_ptr], 8);
183
+                stream_ptr += 8;
184
+
185
+                for (pixel_y = 0; pixel_y < 4; pixel_y++) {
186
+                    for (pixel_x = 0; pixel_x < 4; pixel_x++, flags >>= 1)
187
+                        pixels[pixel_ptr++] = 
188
+                            colors[((pixel_y & 0x2) << 1) + 
189
+                                (pixel_x & 0x2) + ((flags & 0x1) ^ 1)];
190
+                    pixel_ptr -= row_dec;
191
+                }
192
+            } else {
193
+                /* 1-color encoding */
194
+                colors[0] = byte_a;
195
+
196
+                for (pixel_y = 0; pixel_y < 4; pixel_y++) {
197
+                    for (pixel_x = 0; pixel_x < 4; pixel_x++)
198
+                        pixels[pixel_ptr++] = colors[0];
199
+                    pixel_ptr -= row_dec;
200
+                }
201
+            }
202
+
203
+            block_ptr += block_inc;
204
+            total_blocks--;
205
+        }
206
+    }
207
+
208
+    /* make the palette available on the way out */
209
+    if (s->avctx->pix_fmt == PIX_FMT_PAL8)
210
+        memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4);
211
+}
212
+
213
+static void msvideo1_decode_16bit(Msvideo1Context *s)
214
+{
215
+    int block_ptr, pixel_ptr;
216
+    int total_blocks;
217
+    int pixel_x, pixel_y;  /* pixel width and height iterators */
218
+    int block_x, block_y;  /* block width and height iterators */
219
+    int blocks_wide, blocks_high;  /* width and height in 4x4 blocks */
220
+    int block_inc;
221
+    int row_dec;
222
+
223
+    /* decoding parameters */
224
+    int stream_ptr;
225
+    unsigned char byte_a, byte_b;
226
+    unsigned short flags;
227
+    int skip_blocks;
228
+    unsigned short colors[8];
229
+    unsigned short *pixels = (unsigned short *)s->frame.data[0];
230
+    unsigned short *prev_pixels = (unsigned short *)s->prev_frame.data[0];
231
+    int stride = s->frame.linesize[0] / 2;
232
+
233
+    stream_ptr = 0;
234
+    skip_blocks = 0;
235
+    blocks_wide = s->avctx->width / 4;
236
+    blocks_high = s->avctx->height / 4;
237
+    total_blocks = blocks_wide * blocks_high;
238
+    block_inc = 4;
239
+    row_dec = stride + 4;
240
+
241
+    for (block_y = blocks_high; block_y > 0; block_y--) {
242
+        block_ptr = ((block_y * 4) - 1) * stride;
243
+        for (block_x = blocks_wide; block_x > 0; block_x--) {
244
+            /* check if this block should be skipped */
245
+            if (skip_blocks) {
246
+                COPY_PREV_BLOCK();
247
+                block_ptr += block_inc;
248
+                skip_blocks--;
249
+                total_blocks--;
250
+                continue;
251
+            }
252
+
253
+            pixel_ptr = block_ptr;
254
+
255
+            /* get the next two bytes in the encoded data stream */
256
+            CHECK_STREAM_PTR(2);
257
+            byte_a = s->buf[stream_ptr++];
258
+            byte_b = s->buf[stream_ptr++];
259
+
260
+            /* check if the decode is finished */
261
+            if ((byte_a == 0) && (byte_b == 0) && (total_blocks == 0)) {
262
+                return;
263
+            } else if ((byte_b & 0xFC) == 0x84) {
264
+                /* skip code, but don't count the current block */
265
+                skip_blocks = ((byte_b - 0x84) << 8) + byte_a - 1;
266
+                COPY_PREV_BLOCK();
267
+            } else if (byte_b < 0x80) {
268
+                /* 2- or 8-color encoding modes */
269
+                flags = (byte_b << 8) | byte_a;
270
+
271
+                CHECK_STREAM_PTR(4);
272
+                colors[0] = LE_16(&s->buf[stream_ptr]);
273
+                stream_ptr += 2;
274
+                colors[1] = LE_16(&s->buf[stream_ptr]);
275
+                stream_ptr += 2;
276
+
277
+                if (colors[0] & 0x8000) {
278
+                    /* 8-color encoding */
279
+                    CHECK_STREAM_PTR(12);
280
+                    colors[2] = LE_16(&s->buf[stream_ptr]);
281
+                    stream_ptr += 2;
282
+                    colors[3] = LE_16(&s->buf[stream_ptr]);
283
+                    stream_ptr += 2;
284
+                    colors[4] = LE_16(&s->buf[stream_ptr]);
285
+                    stream_ptr += 2;
286
+                    colors[5] = LE_16(&s->buf[stream_ptr]);
287
+                    stream_ptr += 2;
288
+                    colors[6] = LE_16(&s->buf[stream_ptr]);
289
+                    stream_ptr += 2;
290
+                    colors[7] = LE_16(&s->buf[stream_ptr]);
291
+                    stream_ptr += 2;
292
+
293
+                    for (pixel_y = 0; pixel_y < 4; pixel_y++) {
294
+                        for (pixel_x = 0; pixel_x < 4; pixel_x++, flags >>= 1)
295
+                            pixels[pixel_ptr++] = 
296
+                                colors[((pixel_y & 0x2) << 1) + 
297
+                                    (pixel_x & 0x2) + ((flags & 0x1) ^ 1)];
298
+                        pixel_ptr -= row_dec;
299
+                    }
300
+                } else {
301
+                    /* 2-color encoding */
302
+                    for (pixel_y = 0; pixel_y < 4; pixel_y++) {
303
+                        for (pixel_x = 0; pixel_x < 4; pixel_x++, flags >>= 1)
304
+                            pixels[pixel_ptr++] = colors[(flags & 0x1) ^ 1];
305
+                        pixel_ptr -= row_dec;
306
+                    }
307
+                }
308
+            } else {
309
+                /* otherwise, it's a 1-color block */
310
+                colors[0] = (byte_b << 8) | byte_a;
311
+
312
+                for (pixel_y = 0; pixel_y < 4; pixel_y++) {
313
+                    for (pixel_x = 0; pixel_x < 4; pixel_x++)
314
+                        pixels[pixel_ptr++] = colors[0];
315
+                    pixel_ptr -= row_dec;
316
+                }
317
+            }
318
+
319
+            block_ptr += block_inc;
320
+            total_blocks--;
321
+        }
322
+    }
323
+}
324
+
325
+static int msvideo1_decode_frame(AVCodecContext *avctx,
326
+                                void *data, int *data_size,
327
+                                uint8_t *buf, int buf_size)
328
+{
329
+    Msvideo1Context *s = (Msvideo1Context *)avctx->priv_data;
330
+
331
+    s->buf = buf;
332
+    s->size = buf_size;
333
+
334
+    if (avctx->get_buffer(avctx, &s->frame)) {
335
+        printf ("  MS Video-1 Video: get_buffer() failed\n");
336
+        return -1;
337
+    }
338
+
339
+    if (s->mode_8bit)
340
+        msvideo1_decode_8bit(s);
341
+    else
342
+        msvideo1_decode_16bit(s);
343
+
344
+    if (s->prev_frame.data[0])
345
+        avctx->release_buffer(avctx, &s->prev_frame);
346
+
347
+    /* shuffle frames */
348
+    s->prev_frame = s->frame;
349
+
350
+    *data_size = sizeof(AVFrame);
351
+    *(AVFrame*)data = s->frame;
352
+
353
+    /* report that the buffer was completely consumed */
354
+    return buf_size;
355
+}
356
+
357
+static int msvideo1_decode_end(AVCodecContext *avctx)
358
+{
359
+    Msvideo1Context *s = (Msvideo1Context *)avctx->priv_data;
360
+
361
+    if (s->prev_frame.data[0])
362
+        avctx->release_buffer(avctx, &s->prev_frame);
363
+
364
+    return 0;
365
+}
366
+
367
+AVCodec msvideo1_decoder = {
368
+    "msvideo1",
369
+    CODEC_TYPE_VIDEO,
370
+    CODEC_ID_MSVIDEO1,
371
+    sizeof(Msvideo1Context),
372
+    msvideo1_decode_init,
373
+    NULL,
374
+    msvideo1_decode_end,
375
+    msvideo1_decode_frame,
376
+    CODEC_CAP_DR1,
377
+};
0 378
new file mode 100644
... ...
@@ -0,0 +1,310 @@
0
+/*
1
+ * Quicktime Video (RPZA) Video Decoder
2
+ * Copyright (C) 2003 the ffmpeg project
3
+ *
4
+ * This library is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU Lesser General Public
6
+ * License as published by the Free Software Foundation; either
7
+ * version 2 of the License, or (at your option) any later version.
8
+ *
9
+ * This library is distributed in the hope that it will be useful,
10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * Lesser General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU Lesser General Public
15
+ * License along with this library; if not, write to the Free Software
16
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
+ *
18
+ */
19
+
20
+/**
21
+ * @file rpza.c
22
+ * QT RPZA Video Decoder by Roberto Togni <rtogni@bresciaonline.it>
23
+ * For more information about the RPZA format, visit:
24
+ *   http://www.pcisys.net/~melanson/codecs/
25
+ *
26
+ * The RPZA decoder outputs RGB555 colorspace data.
27
+ *
28
+ * Note that this decoder reads big endian RGB555 pixel values from the
29
+ * bytestream, arranges them in the host's endian order, and outputs
30
+ * them to the final rendered map in the same host endian order. This is
31
+ * intended behavior as the ffmpeg documentation states that RGB555 pixels
32
+ * shall be stored in native CPU endianness.
33
+ */
34
+
35
+#include <stdio.h>
36
+#include <stdlib.h>
37
+#include <string.h>
38
+#include <unistd.h>
39
+
40
+#include "common.h"
41
+#include "avcodec.h"
42
+#include "dsputil.h"
43
+
44
+typedef struct RpzaContext {
45
+
46
+    AVCodecContext *avctx;
47
+    DSPContext dsp;
48
+    AVFrame frame;
49
+    AVFrame prev_frame;
50
+
51
+    unsigned char *buf;
52
+    int size;
53
+
54
+} RpzaContext;
55
+
56
+#define BE_16(x)  ((((uint8_t*)(x))[0] << 8) | ((uint8_t*)(x))[1])
57
+#define BE_32(x)  ((((uint8_t*)(x))[0] << 24) | \
58
+                   (((uint8_t*)(x))[1] << 16) | \
59
+                   (((uint8_t*)(x))[2] << 8) | \
60
+                    ((uint8_t*)(x))[3])
61
+
62
+#define ADVANCE_BLOCK() \
63
+{ \
64
+    pixel_ptr += 4; \
65
+    if (pixel_ptr >= width) \
66
+    { \
67
+        pixel_ptr = 0; \
68
+        row_ptr += stride * 4; \
69
+    } \
70
+    total_blocks--; \
71
+    if (total_blocks < 0) \
72
+    { \
73
+        printf("warning: block counter just went negative (this should not happen)\n"); \
74
+        return; \
75
+    } \
76
+}
77
+
78
+static void rpza_decode_stream(RpzaContext *s)
79
+{
80
+    int width = s->avctx->width;
81
+    int stride = s->frame.linesize[0] / 2;
82
+    int row_inc = stride - 4;
83
+    int stream_ptr = 0;
84
+    int chunk_size;
85
+    unsigned char opcode;
86
+    int n_blocks;
87
+    unsigned short colorA = 0, colorB;
88
+    unsigned short color4[4];
89
+    unsigned char index, idx;
90
+    unsigned short ta, tb;
91
+    unsigned short *pixels = (unsigned short *)s->frame.data[0];
92
+    unsigned short *prev_pixels = (unsigned short *)s->prev_frame.data[0];
93
+
94
+    int row_ptr = 0;
95
+    int pixel_ptr = 0;
96
+    int block_ptr;
97
+    int pixel_x, pixel_y;
98
+    int total_blocks;
99
+
100
+    /* First byte is always 0xe1. Warn if it's different */
101
+    if (s->buf[stream_ptr] != 0xe1)
102
+        printf("First chunk byte is 0x%02x instead of 0x1e\n",
103
+            s->buf[stream_ptr]);
104
+
105
+    /* Get chunk size, ingnoring first byte */
106
+    chunk_size = BE_32(&s->buf[stream_ptr]) & 0x00FFFFFF;
107
+    stream_ptr += 4;
108
+
109
+    /* If length mismatch use size from MOV file and try to decode anyway */
110
+    if (chunk_size != s->size)
111
+        printf("MOV chunk size != encoded chunk size; using MOV chunk size\n");
112
+
113
+    chunk_size = s->size;
114
+
115
+    /* Number of 4x4 blocks in frame. */
116
+    total_blocks = (s->avctx->width * s->avctx->height) / (4 * 4);
117
+
118
+    /* Process chunk data */
119
+    while (stream_ptr < chunk_size) {
120
+        opcode = s->buf[stream_ptr++]; /* Get opcode */
121
+
122
+        n_blocks = (opcode & 0x1f) + 1; /* Extract block counter from opcode */
123
+
124
+        /* If opcode MSbit is 0, we need more data to decide what to do */
125
+        if ((opcode & 0x80) == 0) {
126
+            colorA = (opcode << 8) | (s->buf[stream_ptr++]);
127
+            opcode = 0;
128
+            if ((s->buf[stream_ptr] & 0x80) != 0) {
129
+                /* Must behave as opcode 110xxxxx, using colorA computed 
130
+                 * above. Use fake opcode 0x20 to enter switch block at 
131
+                 * the right place */
132
+                opcode = 0x20;
133
+                n_blocks = 1;
134
+            }
135
+        }
136
+
137
+        switch (opcode & 0xe0) {
138
+
139
+        /* Skip blocks */
140
+        case 0x80:
141
+            while (n_blocks--) {
142
+                block_ptr = row_ptr + pixel_ptr;
143
+                for (pixel_y = 0; pixel_y < 4; pixel_y++) {
144
+                    for (pixel_x = 0; pixel_x < 4; pixel_x++){
145
+                        pixels[block_ptr] = prev_pixels[block_ptr];
146
+                        block_ptr++;
147
+                    }
148
+                    block_ptr += row_inc;
149
+                }
150
+                ADVANCE_BLOCK();
151
+            }
152
+            break;
153
+
154
+        /* Fill blocks with one color */
155
+        case 0xa0:
156
+            colorA = BE_16 (&s->buf[stream_ptr]);
157
+            stream_ptr += 2;
158
+            while (n_blocks--) {
159
+                block_ptr = row_ptr + pixel_ptr;
160
+                for (pixel_y = 0; pixel_y < 4; pixel_y++) {
161
+                    for (pixel_x = 0; pixel_x < 4; pixel_x++){
162
+                        pixels[block_ptr] = colorA;
163
+                        block_ptr++;
164
+                    }
165
+                    block_ptr += row_inc;
166
+                }
167
+                ADVANCE_BLOCK();
168
+            }
169
+            break;
170
+
171
+        /* Fill blocks with 4 colors */
172
+        case 0xc0:
173
+            colorA = BE_16 (&s->buf[stream_ptr]);
174
+            stream_ptr += 2;
175
+        case 0x20:
176
+            colorB = BE_16 (&s->buf[stream_ptr]);
177
+            stream_ptr += 2;
178
+
179
+            /* sort out the colors */
180
+            color4[0] = colorB;
181
+            color4[1] = 0;
182
+            color4[2] = 0;
183
+            color4[3] = colorA;
184
+
185
+            /* red components */
186
+            ta = (colorA >> 10) & 0x1F;
187
+            tb = (colorB >> 10) & 0x1F;
188
+            color4[1] |= ((11 * ta + 21 * tb) >> 5) << 10;
189
+            color4[2] |= ((21 * ta + 11 * tb) >> 5) << 10;
190
+
191
+            /* green components */
192
+            ta = (colorA >> 5) & 0x1F;
193
+            tb = (colorB >> 5) & 0x1F;
194
+            color4[1] |= ((11 * ta + 21 * tb) >> 5) << 5;
195
+            color4[2] |= ((21 * ta + 11 * tb) >> 5) << 5;
196
+
197
+            /* blue components */
198
+            ta = colorA & 0x1F;
199
+            tb = colorB & 0x1F;
200
+            color4[1] |= ((11 * ta + 21 * tb) >> 5);
201
+            color4[2] |= ((21 * ta + 11 * tb) >> 5);
202
+
203
+            while (n_blocks--) {
204
+                block_ptr = row_ptr + pixel_ptr;
205
+                for (pixel_y = 0; pixel_y < 4; pixel_y++) {
206
+                    index = s->buf[stream_ptr++];
207
+                    for (pixel_x = 0; pixel_x < 4; pixel_x++){
208
+                        idx = (index >> (2 * (3 - pixel_x))) & 0x03;
209
+                        pixels[block_ptr] = color4[idx];
210
+                        block_ptr++;
211
+                    }
212
+                    block_ptr += row_inc;
213
+                }
214
+                ADVANCE_BLOCK();
215
+            }
216
+            break;
217
+
218
+        /* Fill block with 16 colors */
219
+        case 0x00:
220
+            block_ptr = row_ptr + pixel_ptr;
221
+            for (pixel_y = 0; pixel_y < 4; pixel_y++) {
222
+                for (pixel_x = 0; pixel_x < 4; pixel_x++){
223
+                    /* We already have color of upper left pixel */
224
+                    if ((pixel_y != 0) || (pixel_x !=0)) {
225
+                        colorA = BE_16 (&s->buf[stream_ptr]);
226
+                        stream_ptr += 2;
227
+                    }
228
+                    pixels[block_ptr] = colorA;
229
+                    block_ptr++;
230
+                }
231
+                block_ptr += row_inc;
232
+            }
233
+            ADVANCE_BLOCK();
234
+            break;
235
+
236
+        /* Unknown opcode */
237
+        default:
238
+            printf("Unknown opcode %d in rpza chunk."
239
+                 " Skip remaining %d bytes of chunk data.\n", opcode,
240
+                 chunk_size - stream_ptr);
241
+            return;
242
+        } /* Opcode switch */
243
+    }
244
+}
245
+
246
+static int rpza_decode_init(AVCodecContext *avctx)
247
+{
248
+    RpzaContext *s = (RpzaContext *)avctx->priv_data;
249
+
250
+    s->avctx = avctx;
251
+    avctx->pix_fmt = PIX_FMT_RGB555;
252
+    avctx->has_b_frames = 0;
253
+    dsputil_init(&s->dsp, avctx);
254
+
255
+    s->frame.data[0] = s->prev_frame.data[0] = NULL;
256
+
257
+    return 0;
258
+}
259
+
260
+static int rpza_decode_frame(AVCodecContext *avctx,
261
+                             void *data, int *data_size,
262
+                             uint8_t *buf, int buf_size)
263
+{
264
+    RpzaContext *s = (RpzaContext *)avctx->priv_data;
265
+
266
+    s->buf = buf;
267
+    s->size = buf_size;
268
+
269
+    if (avctx->get_buffer(avctx, &s->frame)) {
270
+        printf ("  RPZA Video: get_buffer() failed\n");
271
+        return -1;
272
+    }
273
+
274
+    rpza_decode_stream(s);
275
+
276
+    if (s->prev_frame.data[0])
277
+        avctx->release_buffer(avctx, &s->prev_frame);
278
+
279
+    /* shuffle frames */
280
+    s->prev_frame = s->frame;
281
+
282
+    *data_size = sizeof(AVFrame);
283
+    *(AVFrame*)data = s->frame;
284
+
285
+    /* always report that the buffer was completely consumed */
286
+    return buf_size;
287
+}
288
+
289
+static int rpza_decode_end(AVCodecContext *avctx)
290
+{
291
+    RpzaContext *s = (RpzaContext *)avctx->priv_data;
292
+
293
+    if (s->prev_frame.data[0])
294
+        avctx->release_buffer(avctx, &s->prev_frame);
295
+
296
+    return 0;
297
+}
298
+
299
+AVCodec rpza_decoder = {
300
+    "rpza",
301
+    CODEC_TYPE_VIDEO,
302
+    CODEC_ID_RPZA,
303
+    sizeof(RpzaContext),
304
+    rpza_decode_init,
305
+    NULL,
306
+    rpza_decode_end,
307
+    rpza_decode_frame,
308
+    CODEC_CAP_DR1,
309
+};
... ...
@@ -15,7 +15,7 @@ PPOBJS=
15 15
 OBJS+=mpeg.o mpegts.o mpegtsenc.o ffm.o crc.o img.o raw.o rm.o \
16 16
       avienc.o avidec.o wav.o swf.o au.o gif.o mov.o mpjpeg.o dv.o \
17 17
       yuv4mpeg.o 4xm.o flvenc.o flvdec.o movenc.o psxstr.o idroq.o ipmovie.o \
18
-      nut.o wc3movie.o mp3.o
18
+      nut.o wc3movie.o mp3.o westwood.o segafilm.o
19 19
 
20 20
 ifeq ($(CONFIG_RISKY),yes)
21 21
 OBJS+= asf.o
... ...
@@ -56,6 +56,8 @@ void av_register_all(void)
56 56
     roq_init();
57 57
     ipmovie_init();
58 58
     wc3_init();
59
+    westwood_init();
60
+    film_init();
59 61
 
60 62
 #if defined(AMR_NB) || defined(AMR_NB_FIXED) || defined(AMR_WB)
61 63
     amr_init();
... ...
@@ -406,6 +406,12 @@ int nut_init(void);
406 406
 /* wc3movie.c */
407 407
 int wc3_init(void);
408 408
 
409
+/* westwood.c */
410
+int westwood_init(void);
411
+
412
+/* segafilm.c */
413
+int film_init(void);
414
+
409 415
 #include "rtp.h"
410 416
 
411 417
 #include "rtsp.h"
... ...
@@ -141,6 +141,15 @@ const CodecTag codec_bmp_tags[] = {
141 141
     { CODEC_ID_VCR1, MKTAG('V', 'C', 'R', '1') },
142 142
     { CODEC_ID_FFV1, MKTAG('F', 'F', 'V', '1') },
143 143
     { CODEC_ID_XAN_WC4, MKTAG('X', 'x', 'a', 'n') },
144
+    { CODEC_ID_MSRLE, MKTAG('m', 'r', 'l', 'e') },
145
+    { CODEC_ID_MSRLE, MKTAG(0x1, 0x0, 0x0, 0x0) },
146
+    { CODEC_ID_MSVIDEO1, MKTAG('M', 'S', 'V', 'C') },
147
+    { CODEC_ID_MSVIDEO1, MKTAG('m', 's', 'v', 'c') },
148
+    { CODEC_ID_MSVIDEO1, MKTAG('C', 'R', 'A', 'M') },
149
+    { CODEC_ID_MSVIDEO1, MKTAG('c', 'r', 'a', 'm') },
150
+    { CODEC_ID_MSVIDEO1, MKTAG('W', 'H', 'A', 'M') },
151
+    { CODEC_ID_MSVIDEO1, MKTAG('w', 'h', 'a', 'm') },
152
+    { CODEC_ID_CINEPAK, MKTAG('c', 'v', 'i', 'd') },
144 153
     { 0, 0 },
145 154
 };
146 155
 
... ...
@@ -98,6 +98,8 @@ static const CodecTag mov_video_tags[] = {
98 98
     { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'c', 'p') }, /* DV PAL */
99 99
 /*    { CODEC_ID_DVVIDEO, MKTAG('A', 'V', 'd', 'v') }, *//* AVID dv */
100 100
     { CODEC_ID_VP3, MKTAG('V', 'P', '3', '1') }, /* On2 VP3 */
101
+    { CODEC_ID_RPZA, MKTAG('r', 'p', 'z', 'a') }, /* Apple Video (RPZA) */
102
+    { CODEC_ID_CINEPAK, MKTAG('c', 'v', 'i', 'd') }, /* Cinepak */
101 103
     { CODEC_ID_NONE, 0 },
102 104
 };
103 105
 
104 106
new file mode 100644
... ...
@@ -0,0 +1,323 @@
0
+/*
1
+ * Sega FILM Format (CPK) Demuxer
2
+ * Copyright (c) 2003 The ffmpeg Project
3
+ *
4
+ * This library is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU Lesser General Public
6
+ * License as published by the Free Software Foundation; either
7
+ * version 2 of the License, or (at your option) any later version.
8
+ *
9
+ * This library is distributed in the hope that it will be useful,
10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * Lesser General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU Lesser General Public
15
+ * License along with this library; if not, write to the Free Software
16
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
+ */
18
+
19
+/**
20
+ * @file segafilm.c
21
+ * Sega FILM (.cpk) file demuxer
22
+ * by Mike Melanson (melanson@pcisys.net)
23
+ * For more information regarding the Sega FILM file format, visit:
24
+ *   http://www.pcisys.net/~melanson/codecs/
25
+ */
26
+
27
+#include "avformat.h"
28
+
29
+#define BE_16(x)  ((((uint8_t*)(x))[0] << 8) | ((uint8_t*)(x))[1])
30
+#define BE_32(x)  ((((uint8_t*)(x))[0] << 24) | \
31
+                   (((uint8_t*)(x))[1] << 16) | \
32
+                   (((uint8_t*)(x))[2] << 8) | \
33
+                    ((uint8_t*)(x))[3])
34
+
35
+#define FOURCC_TAG( ch0, ch1, ch2, ch3 ) \
36
+        ( (long)(unsigned char)(ch3) | \
37
+        ( (long)(unsigned char)(ch2) << 8 ) | \
38
+        ( (long)(unsigned char)(ch1) << 16 ) | \
39
+        ( (long)(unsigned char)(ch0) << 24 ) )
40
+
41
+#define FILM_TAG FOURCC_TAG('F', 'I', 'L', 'M')
42
+#define FDSC_TAG FOURCC_TAG('F', 'D', 'S', 'C')
43
+#define STAB_TAG FOURCC_TAG('S', 'T', 'A', 'B')
44
+#define CVID_TAG FOURCC_TAG('c', 'v', 'i', 'd')
45
+
46
+typedef struct {
47
+  int stream;
48
+  off_t sample_offset;
49
+  unsigned int sample_size;
50
+  int64_t pts;
51
+  int keyframe;
52
+} film_sample_t;
53
+
54
+typedef struct FilmDemuxContext {
55
+    int video_stream_index;
56
+    int audio_stream_index;
57
+
58
+    unsigned int audio_type;
59
+    unsigned int audio_samplerate;
60
+    unsigned int audio_bits;
61
+    unsigned int audio_channels;
62
+
63
+    unsigned int video_type;
64
+    unsigned int sample_count;
65
+    film_sample_t *sample_table;
66
+    unsigned int current_sample;
67
+
68
+    unsigned int base_clock;
69
+    unsigned int version;
70
+    int cvid_extra_bytes;  /* the number of bytes thrown into the Cinepak
71
+                            * chunk header to throw off decoders */
72
+
73
+    /* buffer used for interleaving stereo PCM data */
74
+    unsigned char *stereo_buffer;
75
+    int stereo_buffer_size;
76
+} FilmDemuxContext;
77
+
78
+static int film_probe(AVProbeData *p)
79
+{
80
+    if (p->buf_size < 4)
81
+        return 0;
82
+
83
+    if (BE_32(&p->buf[0]) != FILM_TAG)
84
+        return 0;
85
+
86
+    return AVPROBE_SCORE_MAX;
87
+}
88
+
89
+static int film_read_header(AVFormatContext *s,
90
+                            AVFormatParameters *ap)
91
+{
92
+    FilmDemuxContext *film = (FilmDemuxContext *)s->priv_data;
93
+    ByteIOContext *pb = &s->pb;
94
+    AVStream *st;
95
+    unsigned char scratch[256];
96
+    int i;
97
+    unsigned int data_offset;
98
+    unsigned int audio_frame_counter;
99
+
100
+    film->sample_table = NULL;
101
+    film->stereo_buffer = NULL;
102
+    film->stereo_buffer_size = 0;
103
+
104
+    /* load the main FILM header */
105
+    if (get_buffer(pb, scratch, 16) != 16)
106
+        return -EIO;
107
+    data_offset = BE_32(&scratch[4]);
108
+    film->version = BE_32(&scratch[8]);
109
+
110
+    /* load the FDSC chunk */
111
+    if (film->version == 0) {
112
+        /* special case for Lemmings .film files; 20-byte header */
113
+        if (get_buffer(pb, scratch, 20) != 20)
114
+            return -EIO;
115
+        /* make some assumptions about the audio parameters */
116
+        film->audio_type = CODEC_ID_PCM_S8;
117
+        film->audio_samplerate = 22050;
118
+        film->audio_channels = 1;
119
+        film->audio_bits = 8;
120
+    } else {
121
+        /* normal Saturn .cpk files; 32-byte header */
122
+        if (get_buffer(pb, scratch, 32) != 32)
123
+            return -EIO;
124
+        film->audio_samplerate = BE_16(&scratch[24]);;
125
+        film->audio_channels = scratch[21];
126
+        film->audio_bits = scratch[22];
127
+        if (film->audio_bits == 8)
128
+            film->audio_type = CODEC_ID_PCM_S8;
129
+        else if (film->audio_bits == 16)
130
+            film->audio_type = CODEC_ID_PCM_S16BE;
131
+        else
132
+            film->audio_type = 0;
133
+    }
134
+
135
+    if (BE_32(&scratch[0]) != FDSC_TAG)
136
+        return AVERROR_INVALIDDATA;
137
+
138
+    film->cvid_extra_bytes = 0;
139
+    if (BE_32(&scratch[8]) == CVID_TAG) {
140
+        film->video_type = CODEC_ID_CINEPAK;
141
+        if (film->version)
142
+            film->cvid_extra_bytes = 2;
143
+        else
144
+            film->cvid_extra_bytes = 6;  /* Lemmings 3DO case */
145
+    } else
146
+        film->video_type = 0;
147
+
148
+    /* initialize the decoder streams */
149
+    if (film->video_type) {
150
+        st = av_new_stream(s, 0);
151
+        if (!st)
152
+            return AVERROR_NOMEM;
153
+        film->video_stream_index = st->index;
154
+        st->codec.codec_type = CODEC_TYPE_VIDEO;
155
+        st->codec.codec_id = film->video_type;
156
+        st->codec.codec_tag = 0;  /* no fourcc */
157
+        st->codec.width = BE_32(&scratch[16]);
158
+        st->codec.height = BE_32(&scratch[12]);
159
+    }
160
+
161
+    if (film->audio_type) {
162
+        st = av_new_stream(s, 0);
163
+        if (!st)
164
+            return AVERROR_NOMEM;
165
+        film->audio_stream_index = st->index;
166
+        st->codec.codec_type = CODEC_TYPE_AUDIO;
167
+        st->codec.codec_id = film->audio_type;
168
+        st->codec.codec_tag = 1;
169
+        st->codec.channels = film->audio_channels;
170
+        st->codec.bits_per_sample = film->audio_bits;
171
+        st->codec.sample_rate = film->audio_samplerate;
172
+        st->codec.bit_rate = st->codec.channels * st->codec.sample_rate *
173
+            st->codec.bits_per_sample;
174
+        st->codec.block_align = st->codec.channels * 
175
+            st->codec.bits_per_sample / 8;
176
+    }
177
+
178
+    /* load the sample table */
179
+    if (get_buffer(pb, scratch, 16) != 16)
180
+        return -EIO;
181
+    if (BE_32(&scratch[0]) != STAB_TAG)
182
+        return AVERROR_INVALIDDATA;
183
+    film->base_clock = BE_32(&scratch[8]);
184
+    film->sample_count = BE_32(&scratch[12]);
185
+    film->sample_table = av_malloc(film->sample_count * sizeof(film_sample_t));
186
+    
187
+    audio_frame_counter = 0;
188
+    for (i = 0; i < film->sample_count; i++) {
189
+        /* load the next sample record and transfer it to an internal struct */
190
+        if (get_buffer(pb, scratch, 16) != 16) {
191
+            av_free(film->sample_table);
192
+            return -EIO;
193
+        }
194
+        film->sample_table[i].sample_offset = 
195
+            data_offset + BE_32(&scratch[0]);
196
+        film->sample_table[i].sample_size = BE_32(&scratch[4]);
197
+        if (BE_32(&scratch[8]) == 0xFFFFFFFF) {
198
+            film->sample_table[i].stream = film->audio_stream_index;
199
+            film->sample_table[i].pts = audio_frame_counter;
200
+            film->sample_table[i].pts *= film->base_clock;
201
+            film->sample_table[i].pts /= film->audio_samplerate;
202
+
203
+            audio_frame_counter += (film->sample_table[i].sample_size /
204
+                (film->audio_channels * film->audio_bits / 8));
205
+        } else {
206
+            film->sample_table[i].stream = film->video_stream_index;
207
+            film->sample_table[i].pts = BE_32(&scratch[8]) & 0x7FFFFFFF;
208
+            film->sample_table[i].keyframe = (scratch[8] & 0x80) ? 0 : 1;
209
+        }
210
+    }
211
+
212
+    film->current_sample = 0;
213
+
214
+    /* set the pts reference to match the tick rate of the file */
215
+    s->pts_num = 1;
216
+    s->pts_den = film->base_clock;
217
+
218
+    return 0;
219
+}
220
+
221
+static int film_read_packet(AVFormatContext *s,
222
+                            AVPacket *pkt)
223
+{
224
+    FilmDemuxContext *film = (FilmDemuxContext *)s->priv_data;
225
+    ByteIOContext *pb = &s->pb;
226
+    film_sample_t *sample;
227
+    int ret = 0;
228
+    int i;
229
+    int left, right;
230
+
231
+    if (film->current_sample >= film->sample_count)
232
+        return -EIO;
233
+
234
+    sample = &film->sample_table[film->current_sample];
235
+
236
+    /* position the stream (will probably be there anyway) */
237
+    url_fseek(pb, sample->sample_offset, SEEK_SET);
238
+
239
+    /* do a special song and dance when loading FILM Cinepak chunks */
240
+    if ((sample->stream == film->video_stream_index) && 
241
+        (film->video_type == CODEC_ID_CINEPAK)) {
242
+        if (av_new_packet(pkt, sample->sample_size - film->cvid_extra_bytes))
243
+            return AVERROR_NOMEM;
244
+        ret = get_buffer(pb, pkt->data, 10);
245
+        /* skip the non-spec CVID bytes */
246
+        url_fseek(pb, film->cvid_extra_bytes, SEEK_CUR);
247
+        ret += get_buffer(pb, pkt->data + 10, 
248
+            sample->sample_size - 10 - film->cvid_extra_bytes);
249
+        if (ret != sample->sample_size - film->cvid_extra_bytes)
250
+            ret = -EIO;
251
+    } else if ((sample->stream == film->audio_stream_index) &&
252
+        (film->audio_channels == 2)) {
253
+        /* stereo PCM needs to be interleaved */
254
+
255
+        if (av_new_packet(pkt, sample->sample_size))
256
+            return AVERROR_NOMEM;
257
+
258
+        /* make sure the interleave buffer is large enough */
259
+        if (sample->sample_size > film->stereo_buffer_size) {
260
+            av_free(film->stereo_buffer);
261
+            film->stereo_buffer_size = sample->sample_size;
262
+            film->stereo_buffer = av_malloc(film->stereo_buffer_size);
263
+        }
264
+
265
+        ret = get_buffer(pb, film->stereo_buffer, sample->sample_size);
266
+        if (ret != sample->sample_size)
267
+            ret = -EIO;
268
+
269
+        left = 0;
270
+        right = sample->sample_size / 2;
271
+        for (i = 0; i < sample->sample_size; ) {
272
+            if (film->audio_bits == 8) {
273
+                pkt->data[i++] = film->stereo_buffer[left++];
274
+                pkt->data[i++] = film->stereo_buffer[right++];
275
+            } else {
276
+                pkt->data[i++] = film->stereo_buffer[left++];
277
+                pkt->data[i++] = film->stereo_buffer[left++];
278
+                pkt->data[i++] = film->stereo_buffer[right++];
279
+                pkt->data[i++] = film->stereo_buffer[right++];
280
+            }
281
+        }
282
+    } else {
283
+        if (av_new_packet(pkt, sample->sample_size))
284
+            return AVERROR_NOMEM;
285
+        ret = get_buffer(pb, pkt->data, sample->sample_size);
286
+        if (ret != sample->sample_size)
287
+            ret = -EIO;
288
+    }
289
+
290
+    pkt->stream_index = sample->stream;
291
+    pkt->pts = sample->pts;
292
+
293
+    film->current_sample++;
294
+
295
+    return ret;
296
+}
297
+
298
+static int film_read_close(AVFormatContext *s)
299
+{
300
+    FilmDemuxContext *film = (FilmDemuxContext *)s->priv_data;
301
+
302
+    av_free(film->sample_table);
303
+    av_free(film->stereo_buffer);
304
+
305
+    return 0;
306
+}
307
+
308
+static AVInputFormat film_iformat = {
309
+    "film_cpk",
310
+    "Sega FILM/CPK format",
311
+    sizeof(FilmDemuxContext),
312
+    film_probe,
313
+    film_read_header,
314
+    film_read_packet,
315
+    film_read_close,
316
+};
317
+
318
+int film_init(void)
319
+{
320
+    av_register_input_format(&film_iformat);
321
+    return 0;
322
+}
0 323
new file mode 100644
... ...
@@ -0,0 +1,375 @@
0
+/*
1
+ * Westwood Studios Multimedia Formats Demuxer (VQA, AUD)
2
+ * Copyright (c) 2003 The ffmpeg Project
3
+ *
4
+ * This library is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU Lesser General Public
6
+ * License as published by the Free Software Foundation; either
7
+ * version 2 of the License, or (at your option) any later version.
8
+ *
9
+ * This library is distributed in the hope that it will be useful,
10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * Lesser General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU Lesser General Public
15
+ * License along with this library; if not, write to the Free Software
16
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
+ */
18
+
19
+/**
20
+ * @file westwood.c
21
+ * Westwood Studios VQA & AUD file demuxers
22
+ * by Mike Melanson (melanson@pcisys.net)
23
+ * for more information on the Westwood file formats, visit:
24
+ *   http://www.pcisys.net/~melanson/codecs/
25
+ *   http://www.geocities.com/SiliconValley/8682/aud3.txt
26
+ *
27
+ * Implementation note: There is no definite file signature for AUD files.
28
+ * The demuxer uses a probabilistic strategy for content detection. This
29
+ * entails performing sanity checks on certain header values in order to
30
+ * qualify a file. Refer to wsaud_probe() for the precise parameters.
31
+ */
32
+
33
+#include "avformat.h"
34
+
35
+#define LE_16(x)  ((((uint8_t*)(x))[1] << 8) | ((uint8_t*)(x))[0])
36
+#define LE_32(x)  ((((uint8_t*)(x))[3] << 24) | \
37
+                   (((uint8_t*)(x))[2] << 16) | \
38
+                   (((uint8_t*)(x))[1] << 8) | \
39
+                    ((uint8_t*)(x))[0])
40
+#define BE_32(x)  ((((uint8_t*)(x))[0] << 24) | \
41
+                   (((uint8_t*)(x))[1] << 16) | \
42
+                   (((uint8_t*)(x))[2] << 8) | \
43
+                    ((uint8_t*)(x))[3])
44
+
45
+#define AUD_HEADER_SIZE 12
46
+#define AUD_CHUNK_PREAMBLE_SIZE 8
47
+#define AUD_CHUNK_SIGNATURE 0x0000DEAF
48
+
49
+#define FOURCC_TAG( ch0, ch1, ch2, ch3 ) \
50
+        ( (long)(unsigned char)(ch3) | \
51
+        ( (long)(unsigned char)(ch2) << 8 ) | \
52
+        ( (long)(unsigned char)(ch1) << 16 ) | \
53
+        ( (long)(unsigned char)(ch0) << 24 ) )
54
+
55
+#define FORM_TAG FOURCC_TAG('F', 'O', 'R', 'M')
56
+#define WVQA_TAG FOURCC_TAG('W', 'V', 'Q', 'A')
57
+#define VQHD_TAG FOURCC_TAG('V', 'Q', 'H', 'D')
58
+#define FINF_TAG FOURCC_TAG('F', 'I', 'N', 'F')
59
+#define SND0_TAG FOURCC_TAG('S', 'N', 'D', '0')
60
+#define SND2_TAG FOURCC_TAG('S', 'N', 'D', '2')
61
+#define VQFR_TAG FOURCC_TAG('V', 'Q', 'F', 'R')
62
+
63
+#define VQA_HEADER_SIZE 0x2A
64
+#define VQA_FRAMERATE 15
65
+#define VQA_VIDEO_PTS_INC (90000 / VQA_FRAMERATE)
66
+#define VQA_PREAMBLE_SIZE 8
67
+
68
+typedef struct WsAudDemuxContext {
69
+    int audio_samplerate;
70
+    int audio_channels;
71
+    int audio_bits;
72
+    int audio_type;
73
+    int audio_stream_index;
74
+    int64_t audio_frame_counter;
75
+} WsAudDemuxContext;
76
+
77
+typedef struct WsVqaDemuxContext {
78
+    int audio_samplerate;
79
+    int audio_channels;
80
+    int audio_bits;
81
+
82
+    int audio_stream_index;
83
+    int video_stream_index;
84
+
85
+    int64_t audio_frame_counter;
86
+    int64_t video_pts;
87
+} WsVqaDemuxContext;
88
+
89
+static int wsaud_probe(AVProbeData *p)
90
+{
91
+    int field;
92
+
93
+    /* Probabilistic content detection strategy: There is no file signature
94
+     * so perform sanity checks on various header parameters:
95
+     *   8000 <= sample rate (16 bits) <= 48000  ==> 40001 acceptable numbers
96
+     *   compression type (8 bits) = 1 or 99     ==> 2 acceptable numbers
97
+     * There is a total of 24 bits. The number space contains 2^24 =
98
+     * 16777216 numbers. There are 40001 * 2 = 80002 acceptable combinations
99
+     * of numbers. There is a 80002/16777216 = 0.48% chance of a false
100
+     * positive.
101
+     */
102
+
103
+    if (p->buf_size < AUD_HEADER_SIZE)
104
+        return 0;
105
+
106
+    /* check sample rate */
107
+    field = LE_16(&p->buf[0]);
108
+    if ((field < 8000) || (field > 48000))
109
+        return 0;
110
+
111
+    /* note: only check for WS IMA (type 99) right now since there is no 
112
+     * support for type 1 */
113
+    if (p->buf[11] != 99)
114
+        return 0;
115
+
116
+    /* return 1/2 certainty since this file check is a little sketchy */
117
+    return AVPROBE_SCORE_MAX / 2;
118
+}
119
+
120
+static int wsaud_read_header(AVFormatContext *s,
121
+                             AVFormatParameters *ap)
122
+{
123
+    WsAudDemuxContext *wsaud = (WsAudDemuxContext *)s->priv_data;
124
+    ByteIOContext *pb = &s->pb;
125
+    AVStream *st;
126
+    unsigned char header[AUD_HEADER_SIZE];
127
+
128
+    if (get_buffer(pb, header, AUD_HEADER_SIZE) != AUD_HEADER_SIZE)
129
+        return -EIO;
130
+    wsaud->audio_samplerate = LE_16(&header[0]);
131
+    if (header[11] == 99)
132
+        wsaud->audio_type = CODEC_ID_ADPCM_IMA_WS;
133
+    else
134
+        return AVERROR_INVALIDDATA;
135
+
136
+    /* flag 0 indicates stereo */
137
+    wsaud->audio_channels = (header[10] & 0x1) + 1;
138
+    /* flag 1 indicates 16 bit audio */
139
+    wsaud->audio_bits = (((header[10] & 0x2) >> 1) + 1) * 8;
140
+
141
+    /* set the pts reference the same as the sample rate */
142
+    s->pts_num = 1;
143
+    s->pts_den = wsaud->audio_samplerate;
144
+
145
+    /* initialize the audio decoder stream */
146
+    st = av_new_stream(s, 0);
147
+    if (!st)
148
+        return AVERROR_NOMEM;
149
+    st->codec.codec_type = CODEC_TYPE_AUDIO;
150
+    st->codec.codec_id = wsaud->audio_type;
151
+    st->codec.codec_tag = 0;  /* no tag */
152
+    st->codec.channels = wsaud->audio_channels;
153
+    st->codec.sample_rate = wsaud->audio_samplerate;
154
+    st->codec.bits_per_sample = wsaud->audio_bits;
155
+    st->codec.bit_rate = st->codec.channels * st->codec.sample_rate *
156
+        st->codec.bits_per_sample / 4;
157
+    st->codec.block_align = st->codec.channels * st->codec.bits_per_sample;
158
+
159
+    wsaud->audio_stream_index = st->index;
160
+    wsaud->audio_frame_counter = 0;
161
+
162
+    return 0;
163
+}
164
+
165
+static int wsaud_read_packet(AVFormatContext *s,
166
+                             AVPacket *pkt)
167
+{
168
+    WsAudDemuxContext *wsaud = (WsAudDemuxContext *)s->priv_data;
169
+    ByteIOContext *pb = &s->pb;
170
+    unsigned char preamble[AUD_CHUNK_PREAMBLE_SIZE];
171
+    unsigned int chunk_size;
172
+    int ret = 0;
173
+
174
+    if (get_buffer(pb, preamble, AUD_CHUNK_PREAMBLE_SIZE) !=
175
+        AUD_CHUNK_PREAMBLE_SIZE)
176
+        return -EIO;
177
+
178
+    /* validate the chunk */
179
+    if (LE_32(&preamble[4]) != AUD_CHUNK_SIGNATURE)
180
+        return AVERROR_INVALIDDATA;
181
+
182
+    chunk_size = LE_16(&preamble[0]);
183
+    if (av_new_packet(pkt, chunk_size))
184
+        return -EIO;
185
+    pkt->stream_index = wsaud->audio_stream_index;
186
+    pkt->pts = wsaud->audio_frame_counter;
187
+    pkt->pts /= wsaud->audio_samplerate;
188
+    if ((ret = get_buffer(pb, pkt->data, chunk_size)) != chunk_size) {
189
+        av_free_packet(pkt);
190
+        ret = -EIO;
191
+    }
192
+
193
+    /* 2 samples/byte, 1 or 2 samples per frame depending on stereo */
194
+    wsaud->audio_frame_counter += (chunk_size * 2) / wsaud->audio_channels;
195
+
196
+    return ret;
197
+}
198
+
199
+static int wsaud_read_close(AVFormatContext *s)
200
+{
201
+//    WsAudDemuxContext *wsaud = (WsAudDemuxContext *)s->priv_data;
202
+
203
+    return 0;
204
+}
205
+
206
+
207
+static int wsvqa_probe(AVProbeData *p)
208
+{
209
+    /* need 12 bytes to qualify */
210
+    if (p->buf_size < 12)
211
+        return 0;
212
+
213
+    /* check for the VQA signatures */
214
+    if ((BE_32(&p->buf[0]) != FORM_TAG) ||
215
+        (BE_32(&p->buf[8]) != WVQA_TAG))
216
+        return 0;
217
+
218
+    return AVPROBE_SCORE_MAX;
219
+}
220
+
221
+static int wsvqa_read_header(AVFormatContext *s,
222
+                             AVFormatParameters *ap)
223
+{
224
+    WsVqaDemuxContext *wsvqa = (WsVqaDemuxContext *)s->priv_data;
225
+    ByteIOContext *pb = &s->pb;
226
+    AVStream *st;
227
+    unsigned char *header;
228
+    unsigned char scratch[VQA_PREAMBLE_SIZE];
229
+
230
+    /* set the pts reference (1 pts = 1/90000) */
231
+    s->pts_num = 1;
232
+    s->pts_den = 90000;
233
+
234
+    /* initialize the video decoder stream */
235
+    st = av_new_stream(s, 0);
236
+    if (!st)
237
+        return AVERROR_NOMEM;
238
+    wsvqa->video_stream_index = st->index;
239
+    st->codec.codec_type = CODEC_TYPE_VIDEO;
240
+    st->codec.codec_id = CODEC_ID_WS_VQA;
241
+    st->codec.codec_tag = 0;  /* no fourcc */
242
+
243
+    /* skip to the start of the VQA header */
244
+    url_fseek(pb, 20, SEEK_SET);
245
+
246
+    /* the VQA header needs to go to the decoder */
247
+    st->codec.extradata_size = VQA_HEADER_SIZE;
248
+    st->codec.extradata = av_malloc(VQA_HEADER_SIZE);
249
+    header = (unsigned char *)st->codec.extradata;
250
+    if (get_buffer(pb, st->codec.extradata, VQA_HEADER_SIZE) !=
251
+        VQA_HEADER_SIZE) {
252
+        av_free(st->codec.extradata);
253
+        return -EIO;
254
+    }
255
+    st->codec.width = LE_16(&header[6]);
256
+    st->codec.height = LE_16(&header[8]);
257
+
258
+    /* initialize the audio decoder stream */
259
+    st = av_new_stream(s, 0);
260
+    if (!st)
261
+        return AVERROR_NOMEM;
262
+    st->codec.codec_type = CODEC_TYPE_AUDIO;
263
+    st->codec.codec_id = CODEC_ID_ADPCM_IMA_WS;
264
+    st->codec.codec_tag = 0;  /* no tag */
265
+    st->codec.sample_rate = LE_16(&header[24]);
266
+    st->codec.channels = header[26];
267
+    st->codec.bits_per_sample = 16;
268
+    st->codec.bit_rate = st->codec.channels * st->codec.sample_rate *
269
+        st->codec.bits_per_sample / 4;
270
+    st->codec.block_align = st->codec.channels * st->codec.bits_per_sample;
271
+
272
+    wsvqa->audio_stream_index = st->index;
273
+    wsvqa->audio_samplerate = st->codec.sample_rate;
274
+    wsvqa->audio_channels = st->codec.channels;
275
+    wsvqa->audio_frame_counter = 0;
276
+
277
+    /* skip the useless FINF chunk index */
278
+    if (get_buffer(pb, scratch, VQA_PREAMBLE_SIZE) != VQA_PREAMBLE_SIZE) {
279
+        av_free(st->codec.extradata);
280
+        return -EIO;
281
+    }
282
+    url_fseek(pb, BE_32(&scratch[4]), SEEK_CUR);
283
+    wsvqa->video_pts = wsvqa->audio_frame_counter = 0;
284
+
285
+    return 0;
286
+}
287
+
288
+static int wsvqa_read_packet(AVFormatContext *s,
289
+                             AVPacket *pkt)
290
+{
291
+    WsVqaDemuxContext *wsvqa = (WsVqaDemuxContext *)s->priv_data;
292
+    ByteIOContext *pb = &s->pb;
293
+    int ret = 0;
294
+    unsigned char preamble[VQA_PREAMBLE_SIZE];
295
+    unsigned int chunk_type;
296
+    unsigned int chunk_size;
297
+    int skip_byte;
298
+
299
+    if (get_buffer(pb, preamble, VQA_PREAMBLE_SIZE) != VQA_PREAMBLE_SIZE)
300
+        return -EIO;
301
+
302
+    chunk_type = BE_32(&preamble[0]);
303
+    chunk_size = BE_32(&preamble[4]);
304
+    skip_byte = chunk_size & 0x01;
305
+
306
+    if ((chunk_type == SND2_TAG) || (chunk_type == VQFR_TAG)) {
307
+
308
+        if (av_new_packet(pkt, chunk_size))
309
+            return -EIO;
310
+        ret = get_buffer(pb, pkt->data, chunk_size);
311
+        if (ret != chunk_size) {
312
+            av_free_packet(pkt);
313
+            ret = -EIO;
314
+        }
315
+
316
+        if (chunk_type == SND2_TAG) {
317
+            pkt->stream_index = wsvqa->audio_stream_index;
318
+
319
+            pkt->pts = 90000;
320
+            pkt->pts *= wsvqa->audio_frame_counter;
321
+            pkt->pts /= wsvqa->audio_samplerate;
322
+
323
+            /* 2 samples/byte, 1 or 2 samples per frame depending on stereo */
324
+            wsvqa->audio_frame_counter += (chunk_size * 2) / 
325
+                wsvqa->audio_channels;
326
+        } else {
327
+            pkt->stream_index = wsvqa->video_stream_index;
328
+            pkt->pts = wsvqa->video_pts;
329
+            wsvqa->video_pts += VQA_VIDEO_PTS_INC;
330
+        }
331
+
332
+    } else
333
+        return AVERROR_INVALIDDATA;
334
+
335
+    /* stay on 16-bit alignment */
336
+    if (skip_byte)
337
+        url_fseek(pb, 1, SEEK_CUR);
338
+
339
+    return ret;
340
+}
341
+
342
+static int wsvqa_read_close(AVFormatContext *s)
343
+{
344
+//    WsVqaDemuxContext *wsvqa = (WsVqaDemuxContext *)s->priv_data;
345
+
346
+    return 0;
347
+}
348
+
349
+static AVInputFormat wsaud_iformat = {
350
+    "wsaud",
351
+    "Westwood Studios audio format",
352
+    sizeof(WsAudDemuxContext),
353
+    wsaud_probe,
354
+    wsaud_read_header,
355
+    wsaud_read_packet,
356
+    wsaud_read_close,
357
+};
358
+
359
+static AVInputFormat wsvqa_iformat = {
360
+    "wsvqa",
361
+    "Westwood Studios VQA format",
362
+    sizeof(WsVqaDemuxContext),
363
+    wsvqa_probe,
364
+    wsvqa_read_header,
365
+    wsvqa_read_packet,
366
+    wsvqa_read_close,
367
+};
368
+
369
+int westwood_init(void)
370
+{
371
+    av_register_input_format(&wsaud_iformat);
372
+    av_register_input_format(&wsvqa_iformat);
373
+    return 0;
374
+}