Browse code

implemented Id Quake II CIN support

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

Mike Melanson authored on 2003/10/03 14:43:03
Showing 10 changed files
... ...
@@ -6,6 +6,7 @@ version <next>:
6 6
 - Cinepak decoder
7 7
 - Sega FILM (CPK) file demuxer
8 8
 - Westwood multimedia support (VQA/AUD file demuxer, audio decoder)
9
+- Id Quake II CIN playback support
9 10
 
10 11
 version 0.4.8:
11 12
 
... ...
@@ -633,6 +633,8 @@ library:
633 633
 @tab used in many Sega Saturn console games
634 634
 @item Westwood Studios VQA/AUD  @tab    @tab X
635 635
 @tab Multimedia formats used in Westwood Studios games
636
+@item Id Cinematic (.cin) @tab    @tab X
637
+@tab Used in Quake II
636 638
 @end multitable
637 639
 
638 640
 @code{X} means that the encoding (resp. decoding) is supported.
... ...
@@ -692,6 +694,8 @@ following image formats are supported:
692 692
 @item Cinepak                @tab     @tab  X
693 693
 @item Microsoft RLE          @tab     @tab  X
694 694
 @item Microsoft Video-1      @tab     @tab  X
695
+@item Westwood VQA           @tab     @tab  X
696
+@item Id Cinematic Video     @tab     @tab  X @tab used in Quake II
695 697
 @end multitable
696 698
 
697 699
 @code{X} means that the encoding (resp. decoding) is supported.
... ...
@@ -18,7 +18,7 @@ OBJS= common.o utils.o mem.o allcodecs.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 20
       roqvideo.o dpcm.o interplayvideo.o xan.o rpza.o cinepak.o msrle.o \
21
-      msvideo1.o vqavideo.o
21
+      msvideo1.o vqavideo.o idcinvideo.o
22 22
 
23 23
 ifeq ($(AMR_NB),yes)
24 24
 ifeq ($(AMR_NB_FIXED),yes)
... ...
@@ -128,6 +128,7 @@ void avcodec_register_all(void)
128 128
     register_avcodec(&msrle_decoder);
129 129
     register_avcodec(&msvideo1_decoder);
130 130
     register_avcodec(&vqa_decoder);
131
+    register_avcodec(&idcin_decoder);
131 132
 #ifdef CONFIG_AC3
132 133
     register_avcodec(&ac3_decoder);
133 134
 #endif
... ...
@@ -79,6 +79,7 @@ enum CodecID {
79 79
     CODEC_ID_WS_VQA,
80 80
     CODEC_ID_MSRLE,
81 81
     CODEC_ID_MSVIDEO1,
82
+    CODEC_ID_IDCIN,
82 83
 
83 84
     /* various pcm "codecs" */
84 85
     CODEC_ID_PCM_S16LE,
... ...
@@ -1433,6 +1434,7 @@ extern AVCodec cinepak_decoder;
1433 1433
 extern AVCodec msrle_decoder;
1434 1434
 extern AVCodec msvideo1_decoder;
1435 1435
 extern AVCodec vqa_decoder;
1436
+extern AVCodec idcin_decoder;
1436 1437
 extern AVCodec ra_144_decoder;
1437 1438
 extern AVCodec ra_288_decoder;
1438 1439
 extern AVCodec roq_dpcm_decoder;
1439 1440
new file mode 100644
... ...
@@ -0,0 +1,278 @@
0
+/*
1
+ * Id Quake II CIN 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 idcinvideo.c
22
+ * Id Quake II Cin Video Decoder by Dr. Tim Ferguson
23
+ * For more information about the Id CIN format, visit:
24
+ *   http://www.csse.monash.edu.au/~timf/
25
+ *
26
+ * This video decoder outputs PAL8 colorspace data.
27
+ *
28
+ * Id CIN video is purely Huffman-coded, intraframe-only codec. It achieves
29
+ * a little more compression by exploiting the fact that adjacent pixels
30
+ * tend to be similar.
31
+ *
32
+ * Note that this decoder could use ffmpeg's optimized VLC facilities
33
+ * rather than naive, tree-based Huffman decoding. However, there are 256
34
+ * Huffman tables. Plus, the VLC bit coding order is right -> left instead
35
+ * or left -> right, so all of the bits would have to be reversed. Further,
36
+ * the original Quake II implementation likely used a similar naive
37
+ * decoding algorithm and it worked fine on much lower spec machines.
38
+ */
39
+
40
+#include <stdio.h>
41
+#include <stdlib.h>
42
+#include <string.h>
43
+#include <unistd.h>
44
+
45
+#include "common.h"
46
+#include "avcodec.h"
47
+#include "dsputil.h"
48
+
49
+#define HUFFMAN_TABLE_SIZE 64 * 1024
50
+#define HUF_TOKENS 256
51
+#define PALETTE_COUNT 256
52
+
53
+typedef struct
54
+{
55
+  int count;
56
+  unsigned char used;
57
+  int children[2];
58
+} hnode_t;
59
+
60
+typedef struct IdcinContext {
61
+
62
+    AVCodecContext *avctx;
63
+    DSPContext dsp;
64
+    AVFrame frame;
65
+
66
+    unsigned char *buf;
67
+    int size;
68
+
69
+    unsigned char palette[PALETTE_COUNT * 4];
70
+
71
+    hnode_t huff_nodes[256][HUF_TOKENS*2];
72
+    int num_huff_nodes[256];
73
+
74
+} IdcinContext;
75
+
76
+/*
77
+ * Find the lowest probability node in a Huffman table, and mark it as
78
+ * being assigned to a higher probability.
79
+ * Returns the node index of the lowest unused node, or -1 if all nodes
80
+ * are used.
81
+ */
82
+static int huff_smallest_node(hnode_t *hnodes, int num_hnodes) {
83
+    int i;
84
+    int best, best_node;
85
+
86
+    best = 99999999;
87
+    best_node = -1;
88
+    for(i = 0; i < num_hnodes; i++) {
89
+        if(hnodes[i].used)
90
+            continue;
91
+        if(!hnodes[i].count)
92
+            continue;
93
+        if(hnodes[i].count < best) {
94
+            best = hnodes[i].count;
95
+            best_node = i;
96
+        }
97
+    }
98
+
99
+    if(best_node == -1)
100
+        return -1;
101
+    hnodes[best_node].used = 1;
102
+    return best_node;
103
+}
104
+
105
+/*
106
+ * Build the Huffman tree using the generated/loaded probabilities histogram.
107
+ *
108
+ * On completion:
109
+ *  huff_nodes[prev][i < HUF_TOKENS] - are the nodes at the base of the tree.
110
+ *  huff_nodes[prev][i >= HUF_TOKENS] - are used to construct the tree.
111
+ *  num_huff_nodes[prev] - contains the index to the root node of the tree.
112
+ *    That is: huff_nodes[prev][num_huff_nodes[prev]] is the root node.
113
+ */
114
+static void huff_build_tree(IdcinContext *s, int prev) {
115
+    hnode_t *node, *hnodes;
116
+     int num_hnodes, i;
117
+
118
+    num_hnodes = HUF_TOKENS;
119
+    hnodes = s->huff_nodes[prev];
120
+    for(i = 0; i < HUF_TOKENS * 2; i++)
121
+        hnodes[i].used = 0;
122
+
123
+    while (1) {
124
+        node = &hnodes[num_hnodes];             /* next free node */
125
+
126
+        /* pick two lowest counts */
127
+        node->children[0] = huff_smallest_node(hnodes, num_hnodes);
128
+        if(node->children[0] == -1)
129
+            break;      /* reached the root node */
130
+
131
+        node->children[1] = huff_smallest_node(hnodes, num_hnodes);
132
+        if(node->children[1] == -1)
133
+            break;      /* reached the root node */
134
+
135
+        /* combine nodes probability for new node */
136
+        node->count = hnodes[node->children[0]].count +
137
+        hnodes[node->children[1]].count;
138
+        num_hnodes++;
139
+    }
140
+
141
+    s->num_huff_nodes[prev] = num_hnodes - 1;
142
+}
143
+
144
+static int idcin_decode_init(AVCodecContext *avctx)
145
+{
146
+    IdcinContext *s = (IdcinContext *)avctx->priv_data;
147
+    int i, j, histogram_index = 0;
148
+    unsigned char *histograms;
149
+
150
+    s->avctx = avctx;
151
+    avctx->pix_fmt = PIX_FMT_PAL8;
152
+    avctx->has_b_frames = 0;
153
+    dsputil_init(&s->dsp, avctx);
154
+
155
+    /* make sure the Huffman tables make it */
156
+    if (s->avctx->extradata_size != HUFFMAN_TABLE_SIZE) {
157
+        printf("  Id CIN video: expected extradata size of %d\n", HUFFMAN_TABLE_SIZE);
158
+        return -1;
159
+    }
160
+
161
+    /* build the 256 Huffman decode trees */
162
+    histograms = (unsigned char *)s->avctx->extradata;
163
+    for (i = 0; i < 256; i++) {
164
+        for(j = 0; j < HUF_TOKENS; j++)
165
+            s->huff_nodes[i][j].count = histograms[histogram_index++];
166
+        huff_build_tree(s, i);
167
+    }
168
+
169
+    s->frame.data[0] = NULL;
170
+
171
+    return 0;
172
+}
173
+
174
+static void idcin_decode_vlcs(IdcinContext *s)
175
+{
176
+    hnode_t *hnodes;
177
+    long x, y;
178
+    int prev;
179
+    unsigned char v = 0;
180
+    int bit_pos, node_num, dat_pos;
181
+
182
+    prev = bit_pos = dat_pos = 0;
183
+    for (y = 0; y < (s->frame.linesize[0] * s->avctx->height);
184
+        y += s->frame.linesize[0]) {
185
+        for (x = y; x < y + s->avctx->width; x++) {
186
+            node_num = s->num_huff_nodes[prev];
187
+            hnodes = s->huff_nodes[prev];
188
+
189
+            while(node_num >= HUF_TOKENS) {
190
+                if(!bit_pos) {
191
+                    if(dat_pos > s->size) {
192
+                        printf("Huffman decode error.\n");
193
+                        return;
194
+                    }
195
+                    bit_pos = 8;
196
+                    v = s->buf[dat_pos++];
197
+                }
198
+
199
+                node_num = hnodes[node_num].children[v & 0x01];
200
+                v = v >> 1;
201
+                bit_pos--;
202
+            }
203
+
204
+            s->frame.data[0][x] = node_num;
205
+            prev = node_num;
206
+        }
207
+    }
208
+}
209
+
210
+static int idcin_decode_frame(AVCodecContext *avctx,
211
+                              void *data, int *data_size,
212
+                              uint8_t *buf, int buf_size)
213
+{
214
+    IdcinContext *s = (IdcinContext *)avctx->priv_data;
215
+    AVPaletteControl *palette_control = 
216
+        (AVPaletteControl *)avctx->extradata;
217
+    int i;
218
+    unsigned int *palette32;
219
+    int palette_index = 0;
220
+    unsigned char r, g, b;
221
+
222
+    s->buf = buf;
223
+    s->size = buf_size;
224
+
225
+    if (palette_control->palette_changed) {
226
+        palette32 = (unsigned int *)s->palette;
227
+        for (i = 0; i < PALETTE_COUNT; i++) {
228
+            r = palette_control->palette[palette_index++] * 1;
229
+            g = palette_control->palette[palette_index++] * 1;
230
+            b = palette_control->palette[palette_index++] * 1;
231
+            palette32[i] = (r << 16) | (g << 8) | (b);
232
+        }
233
+        palette_control->palette_changed = 0;
234
+    }
235
+
236
+    if (s->frame.data[0])
237
+        avctx->release_buffer(avctx, &s->frame);
238
+
239
+    if (avctx->get_buffer(avctx, &s->frame)) {
240
+        printf ("  Id CIN Video: get_buffer() failed\n");
241
+        return -1;
242
+    }
243
+
244
+    idcin_decode_vlcs(s);
245
+
246
+    /* make the palette available on the way out */
247
+    memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4);
248
+
249
+    *data_size = sizeof(AVFrame);
250
+    *(AVFrame*)data = s->frame;
251
+
252
+    /* report that the buffer was completely consumed */
253
+    return buf_size;
254
+}
255
+
256
+static int idcin_decode_end(AVCodecContext *avctx)
257
+{
258
+    IdcinContext *s = (IdcinContext *)avctx->priv_data;
259
+
260
+    if (s->frame.data[0])
261
+        avctx->release_buffer(avctx, &s->frame);
262
+
263
+    return 0;
264
+}
265
+
266
+AVCodec idcin_decoder = {
267
+    "idcinvideo",
268
+    CODEC_TYPE_VIDEO,
269
+    CODEC_ID_IDCIN,
270
+    sizeof(IdcinContext),
271
+    idcin_decode_init,
272
+    NULL,
273
+    idcin_decode_end,
274
+    idcin_decode_frame,
275
+    CODEC_CAP_DR1,
276
+};
277
+
... ...
@@ -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 westwood.o segafilm.o
18
+      nut.o wc3movie.o mp3.o westwood.o segafilm.o idcin.o
19 19
 
20 20
 ifeq ($(CONFIG_RISKY),yes)
21 21
 OBJS+= asf.o
... ...
@@ -58,6 +58,7 @@ void av_register_all(void)
58 58
     wc3_init();
59 59
     westwood_init();
60 60
     film_init();
61
+    idcin_init();
61 62
 
62 63
 #if defined(AMR_NB) || defined(AMR_NB_FIXED) || defined(AMR_WB)
63 64
     amr_init();
... ...
@@ -412,6 +412,9 @@ int westwood_init(void);
412 412
 /* segafilm.c */
413 413
 int film_init(void);
414 414
 
415
+/* idcin.c */
416
+int idcin_init(void);
417
+
415 418
 #include "rtp.h"
416 419
 
417 420
 #include "rtsp.h"
418 421
new file mode 100644
... ...
@@ -0,0 +1,313 @@
0
+/*
1
+ * Id Quake II CIN File 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 idcin.c
21
+ * Id Quake II CIN file demuxer by Mike Melanson (melanson@pcisys.net)
22
+ * For more information about the Id CIN format, visit:
23
+ *   http://www.csse.monash.edu.au/~timf/
24
+ *
25
+ * CIN is a somewhat quirky and ill-defined format. Here are some notes
26
+ * for anyone trying to understand the technical details of this format:
27
+ *
28
+ * The format has no definite file signature. This is problematic for a
29
+ * general-purpose media player that wants to automatically detect file
30
+ * types. However, a CIN file does start with 5 32-bit numbers that
31
+ * specify audio and video parameters. This demuxer gets around the lack
32
+ * of file signature by performing sanity checks on those parameters.
33
+ * Probabalistically, this is a reasonable solution since the number of
34
+ * valid combinations of the 5 parameters is a very small subset of the
35
+ * total 160-bit number space.
36
+ *
37
+ * Refer to the function idcin_probe() for the precise A/V parameters
38
+ * that this demuxer allows.
39
+ *
40
+ * Next, each audio and video frame has a duration of 1/14 sec. If the
41
+ * audio sample rate is a multiple of the common frequency 22050 Hz it will
42
+ * divide evenly by 14. However, if the sample rate is 11025 Hz:
43
+ *   11025 (samples/sec) / 14 (frames/sec) = 787.5 (samples/frame)
44
+ * The way the CIN stores audio in this case is by storing 787 sample
45
+ * frames in the first audio frame and 788 sample frames in the second
46
+ * audio frame. Therefore, the total number of bytes in an audio frame
47
+ * is given as:
48
+ *   audio frame #0: 787 * (bytes/sample) * (# channels) bytes in frame
49
+ *   audio frame #1: 788 * (bytes/sample) * (# channels) bytes in frame
50
+ *   audio frame #2: 787 * (bytes/sample) * (# channels) bytes in frame
51
+ *   audio frame #3: 788 * (bytes/sample) * (# channels) bytes in frame
52
+ *
53
+ * Finally, not all Id CIN creation tools agree on the resolution of the
54
+ * color palette, apparently. Some creation tools specify red, green, and
55
+ * blue palette components in terms of 6-bit VGA color DAC values which
56
+ * range from 0..63. Other tools specify the RGB components as full 8-bit
57
+ * values that range from 0..255. Since there are no markers in the file to
58
+ * differentiate between the two variants, this demuxer uses the following
59
+ * heuristic:
60
+ *   - load the 768 palette bytes from disk
61
+ *   - assume that they will need to be shifted left by 2 bits to
62
+ *     transform them from 6-bit values to 8-bit values
63
+ *   - scan through all 768 palette bytes
64
+ *     - if any bytes exceed 63, do not shift the bytes at all before
65
+ *       transmitting them to the video decoder
66
+ */
67
+
68
+#include "avformat.h"
69
+
70
+#define LE_16(x)  ((((uint8_t*)(x))[1] << 8) | ((uint8_t*)(x))[0])
71
+#define LE_32(x)  ((((uint8_t*)(x))[3] << 24) | \
72
+                   (((uint8_t*)(x))[2] << 16) | \
73
+                   (((uint8_t*)(x))[1] << 8) | \
74
+                    ((uint8_t*)(x))[0])
75
+
76
+#define HUFFMAN_TABLE_SIZE (64 * 1024)
77
+#define FRAME_PTS_INC (90000 / 14)
78
+
79
+typedef struct IdcinDemuxContext {
80
+    int video_stream_index;
81
+    int audio_stream_index;
82
+    int audio_chunk_size1;
83
+    int audio_chunk_size2;
84
+
85
+    /* demux state variables */
86
+    int current_audio_chunk;
87
+    int next_chunk_is_video;
88
+    int audio_present;
89
+
90
+    int64_t pts;
91
+
92
+    /* keep reference to extradata but never free it */
93
+    void *extradata;
94
+} IdcinDemuxContext;
95
+
96
+static int idcin_probe(AVProbeData *p)
97
+{
98
+    unsigned int number;
99
+
100
+    /*
101
+     * This is what you could call a "probabilistic" file check: Id CIN
102
+     * files don't have a definite file signature. In lieu of such a marker,
103
+     * perform sanity checks on the 5 32-bit header fields:
104
+     *  width, height: greater than 0, less than or equal to 1024
105
+     * audio sample rate: greater than or equal to 8000, less than or
106
+     *  equal to 48000, or 0 for no audio
107
+     * audio sample width (bytes/sample): 0 for no audio, or 1 or 2
108
+     * audio channels: 0 for no audio, or 1 or 2
109
+     */
110
+
111
+    /* cannot proceed without 20 bytes */
112
+    if (p->buf_size < 20)
113
+        return 0;
114
+
115
+    /* check the video width */
116
+    number = LE_32(&p->buf[0]);
117
+    if ((number == 0) || (number > 1024))
118
+       return 0;
119
+
120
+    /* check the video height */
121
+    number = LE_32(&p->buf[4]);
122
+    if ((number == 0) || (number > 1024))
123
+       return 0;
124
+
125
+    /* check the audio sample rate */
126
+    number = LE_32(&p->buf[8]);
127
+    if ((number != 0) && ((number < 8000) | (number > 48000)))
128
+        return 0;
129
+
130
+    /* check the audio bytes/sample */
131
+    number = LE_32(&p->buf[12]);
132
+    if (number > 2)
133
+        return 0;
134
+
135
+    /* check the audio channels */
136
+    number = LE_32(&p->buf[16]);
137
+    if (number > 2)
138
+        return 0;
139
+
140
+    /* return half certainly since this check is a bit sketchy */
141
+    return AVPROBE_SCORE_MAX / 2;
142
+}
143
+
144
+static int idcin_read_header(AVFormatContext *s,
145
+                             AVFormatParameters *ap)
146
+{
147
+    ByteIOContext *pb = &s->pb;
148
+    IdcinDemuxContext *idcin = (IdcinDemuxContext *)s->priv_data;
149
+    AVStream *st;
150
+    unsigned int width, height;
151
+    unsigned int sample_rate, bytes_per_sample, channels;
152
+
153
+    /* get the 5 header parameters */
154
+    width = get_le32(pb);
155
+    height = get_le32(pb);
156
+    sample_rate = get_le32(pb);
157
+    bytes_per_sample = get_le32(pb);
158
+    channels = get_le32(pb);
159
+
160
+    st = av_new_stream(s, 0);
161
+    if (!st)
162
+        return AVERROR_NOMEM;
163
+    idcin->video_stream_index = st->index;
164
+    st->codec.codec_type = CODEC_TYPE_VIDEO;
165
+    st->codec.codec_id = CODEC_ID_IDCIN;
166
+    st->codec.codec_tag = 0;  /* no fourcc */
167
+    st->codec.width = width;
168
+    st->codec.height = height;
169
+
170
+    /* load up the Huffman tables into extradata */
171
+    st->codec.extradata_size = HUFFMAN_TABLE_SIZE;
172
+    st->codec.extradata = av_malloc(HUFFMAN_TABLE_SIZE);
173
+    if (get_buffer(pb, st->codec.extradata, HUFFMAN_TABLE_SIZE) !=
174
+        HUFFMAN_TABLE_SIZE)
175
+        return -EIO;
176
+    /* save a reference in order to transport the palette */
177
+    idcin->extradata = st->codec.extradata;
178
+
179
+    /* if sample rate is 0, assume no audio */
180
+    if (sample_rate) {
181
+        idcin->audio_present = 1;
182
+        st = av_new_stream(s, 0);
183
+        if (!st)
184
+            return AVERROR_NOMEM;
185
+        idcin->audio_stream_index = st->index;
186
+        st->codec.codec_type = CODEC_TYPE_AUDIO;
187
+        st->codec.codec_tag = 1;
188
+        st->codec.channels = channels;
189
+        st->codec.sample_rate = sample_rate;
190
+        st->codec.bits_per_sample = bytes_per_sample * 8;
191
+        st->codec.bit_rate = sample_rate * bytes_per_sample * 8 * channels;
192
+        st->codec.block_align = bytes_per_sample * channels;
193
+        if (bytes_per_sample == 1)
194
+            st->codec.codec_id = CODEC_ID_PCM_U8;
195
+        else
196
+            st->codec.codec_id = CODEC_ID_PCM_S16LE;
197
+
198
+        if (sample_rate % 14 != 0) {
199
+            idcin->audio_chunk_size1 = (sample_rate / 14) *
200
+            bytes_per_sample * channels;
201
+            idcin->audio_chunk_size2 = (sample_rate / 14 + 1) *
202
+                bytes_per_sample * channels;
203
+        } else {
204
+            idcin->audio_chunk_size1 = idcin->audio_chunk_size2 =
205
+                (sample_rate / 14) * bytes_per_sample * channels;
206
+        }
207
+        idcin->current_audio_chunk = 0;
208
+    } else
209
+        idcin->audio_present = 1;
210
+
211
+    idcin->next_chunk_is_video = 1;
212
+    idcin->pts = 0;
213
+
214
+    /* set the pts reference (1 pts = 1/90000) */
215
+    s->pts_num = 1;
216
+    s->pts_den = 90000;
217
+
218
+    return 0;
219
+}
220
+
221
+static int idcin_read_packet(AVFormatContext *s,
222
+                             AVPacket *pkt)
223
+{
224
+    int ret;
225
+    unsigned int command;
226
+    unsigned int chunk_size;
227
+    IdcinDemuxContext *idcin = (IdcinDemuxContext *)s->priv_data;
228
+    ByteIOContext *pb = &s->pb;
229
+    AVPaletteControl *palette_control = (AVPaletteControl *)idcin->extradata;
230
+    int i;
231
+    int palette_scale;
232
+
233
+    if (url_feof(&s->pb))
234
+        return -EIO;
235
+
236
+    if (idcin->next_chunk_is_video) {
237
+        command = get_le32(pb);
238
+        if (command == 2) {
239
+            return -EIO;
240
+        } else if (command == 1) {
241
+            /* trigger a palette change */
242
+            palette_control->palette_changed = 1;
243
+            if (get_buffer(pb, palette_control->palette, 768) != 768)
244
+                return -EIO;
245
+            /* scale the palette as necessary */
246
+            palette_scale = 2;
247
+            for (i = 0; i < 768; i++)
248
+                if (palette_control->palette[i] > 63) {
249
+                    palette_scale = 0;
250
+                    break;
251
+                }
252
+
253
+            if (palette_scale)
254
+                for (i = 0; i < 768; i++)
255
+                    palette_control->palette[i] <<= palette_scale;
256
+        }
257
+
258
+        chunk_size = get_le32(pb);
259
+        /* skip the number of decoded bytes (always equal to width * height) */
260
+        url_fseek(pb, 4, SEEK_CUR);
261
+        chunk_size -= 4;
262
+        if (av_new_packet(pkt, chunk_size))
263
+            ret = -EIO;
264
+        pkt->stream_index = idcin->video_stream_index;
265
+        pkt->pts = idcin->pts;
266
+        ret = get_buffer(pb, pkt->data, chunk_size);
267
+        if (ret != chunk_size)
268
+            ret = -EIO;
269
+    } else {
270
+        /* send out the audio chunk */
271
+        if (idcin->current_audio_chunk)
272
+            chunk_size = idcin->audio_chunk_size2;
273
+        else
274
+            chunk_size = idcin->audio_chunk_size1;
275
+        if (av_new_packet(pkt, chunk_size))
276
+            return -EIO;
277
+        pkt->stream_index = idcin->audio_stream_index;
278
+        pkt->pts = idcin->pts;
279
+        ret = get_buffer(&s->pb, pkt->data, chunk_size);
280
+        if (ret != chunk_size)
281
+            ret = -EIO;
282
+
283
+        idcin->current_audio_chunk ^= 1;
284
+        idcin->pts += FRAME_PTS_INC;
285
+    }
286
+
287
+    if (idcin->audio_present)
288
+        idcin->next_chunk_is_video ^= 1;
289
+
290
+    return ret;
291
+}
292
+
293
+static int idcin_read_close(AVFormatContext *s)
294
+{
295
+    return 0;
296
+}
297
+
298
+static AVInputFormat idcin_iformat = {
299
+    "idcin",
300
+    "Id CIN format",
301
+    sizeof(IdcinDemuxContext),
302
+    idcin_probe,
303
+    idcin_read_header,
304
+    idcin_read_packet,
305
+    idcin_read_close,
306
+};
307
+
308
+int idcin_init(void)
309
+{
310
+    av_register_input_format(&idcin_iformat);
311
+    return 0;
312
+}