lavf: Constify the probe function argument.
[ffmpeg.git] / libavformat / brstm.c
1 /*
2  * BRSTM demuxer
3  * Copyright (c) 2012 Paul B Mahol
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 #include "libavutil/intreadwrite.h"
23 #include "libavcodec/bytestream.h"
24 #include "avformat.h"
25 #include "internal.h"
26
27 typedef struct BRSTMDemuxContext {
28     uint32_t    block_size;
29     uint32_t    block_count;
30     uint32_t    current_block;
31     uint32_t    samples_per_block;
32     uint32_t    last_block_used_bytes;
33     uint32_t    last_block_size;
34     uint32_t    last_block_samples;
35     uint32_t    data_start;
36     uint8_t     *table;
37     uint8_t     *adpc;
38     int         little_endian;
39 } BRSTMDemuxContext;
40
41 static int probe(const AVProbeData *p)
42 {
43     if (AV_RL32(p->buf) == MKTAG('R','S','T','M') &&
44         (AV_RL16(p->buf + 4) == 0xFFFE ||
45          AV_RL16(p->buf + 4) == 0xFEFF))
46         return AVPROBE_SCORE_MAX / 3 * 2;
47     return 0;
48 }
49
50 static int probe_bfstm(const AVProbeData *p)
51 {
52     if ((AV_RL32(p->buf) == MKTAG('F','S','T','M') ||
53          AV_RL32(p->buf) == MKTAG('C','S','T','M')) &&
54         (AV_RL16(p->buf + 4) == 0xFFFE ||
55          AV_RL16(p->buf + 4) == 0xFEFF))
56         return AVPROBE_SCORE_MAX / 3 * 2;
57     return 0;
58 }
59
60 static int read_close(AVFormatContext *s)
61 {
62     BRSTMDemuxContext *b = s->priv_data;
63
64     av_freep(&b->table);
65     av_freep(&b->adpc);
66
67     return 0;
68 }
69
70 static av_always_inline unsigned int read16(AVFormatContext *s)
71 {
72     BRSTMDemuxContext *b = s->priv_data;
73     if (b->little_endian)
74         return avio_rl16(s->pb);
75     else
76         return avio_rb16(s->pb);
77 }
78
79 static av_always_inline unsigned int read32(AVFormatContext *s)
80 {
81     BRSTMDemuxContext *b = s->priv_data;
82     if (b->little_endian)
83         return avio_rl32(s->pb);
84     else
85         return avio_rb32(s->pb);
86 }
87
88 static int read_header(AVFormatContext *s)
89 {
90     BRSTMDemuxContext *b = s->priv_data;
91     int bom, major, minor, codec, chunk;
92     int64_t h1offset, pos, toffset;
93     uint32_t size, asize, start = 0;
94     AVStream *st;
95     int ret = AVERROR_EOF;
96     int loop = 0;
97     int bfstm = !strcmp("bfstm", s->iformat->name);
98
99     st = avformat_new_stream(s, NULL);
100     if (!st)
101         return AVERROR(ENOMEM);
102     st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
103
104     avio_skip(s->pb, 4);
105
106     bom = avio_rb16(s->pb);
107     if (bom != 0xFEFF && bom != 0xFFFE) {
108         av_log(s, AV_LOG_ERROR, "invalid byte order: %X\n", bom);
109         return AVERROR_INVALIDDATA;
110     }
111
112     if (bom == 0xFFFE)
113         b->little_endian = 1;
114
115     if (!bfstm) {
116         major = avio_r8(s->pb);
117         minor = avio_r8(s->pb);
118         avio_skip(s->pb, 4); // size of file
119         size = read16(s);
120         if (size < 14)
121             return AVERROR_INVALIDDATA;
122
123         avio_skip(s->pb, size - 14);
124         pos = avio_tell(s->pb);
125         if (avio_rl32(s->pb) != MKTAG('H','E','A','D'))
126             return AVERROR_INVALIDDATA;
127     } else {
128         uint32_t info_offset = 0;
129         uint16_t section_count, header_size, i;
130
131         header_size = read16(s); // 6
132
133         avio_skip(s->pb, 4); // Unknown constant 0x00030000
134         avio_skip(s->pb, 4); // size of file
135         section_count = read16(s);
136         avio_skip(s->pb, 2); // padding
137         for (i = 0; avio_tell(s->pb) < header_size
138                     && !(start && info_offset)
139                     && i < section_count; i++) {
140             uint16_t flag = read16(s);
141             avio_skip(s->pb, 2);
142             switch (flag) {
143             case 0x4000:
144                 info_offset = read32(s);
145                 /*info_size =*/ read32(s);
146                 break;
147             case 0x4001:
148                 avio_skip(s->pb, 4); // seek offset
149                 avio_skip(s->pb, 4); // seek size
150                 break;
151             case 0x4002:
152                 start = read32(s) + 8;
153                 avio_skip(s->pb, 4); //data_size = read32(s);
154                 break;
155             case 0x4003:
156                 avio_skip(s->pb, 4); // REGN offset
157                 avio_skip(s->pb, 4); // REGN size
158                 break;
159             }
160         }
161
162         if (!info_offset || !start)
163             return AVERROR_INVALIDDATA;
164
165         avio_skip(s->pb, info_offset - avio_tell(s->pb));
166         pos = avio_tell(s->pb);
167         if (avio_rl32(s->pb) != MKTAG('I','N','F','O'))
168             return AVERROR_INVALIDDATA;
169     }
170
171     size = read32(s);
172     if (size < 40)
173         return AVERROR_INVALIDDATA;
174     avio_skip(s->pb, 4); // unknown
175     h1offset = read32(s);
176     if (h1offset > size)
177         return AVERROR_INVALIDDATA;
178     avio_skip(s->pb, 12);
179     toffset = read32(s) + 16LL;
180     if (toffset > size)
181         return AVERROR_INVALIDDATA;
182
183     avio_skip(s->pb, pos + h1offset + 8 - avio_tell(s->pb));
184     codec = avio_r8(s->pb);
185
186     switch (codec) {
187     case 0: codec = AV_CODEC_ID_PCM_S8_PLANAR;    break;
188     case 1: codec = b->little_endian ?
189                     AV_CODEC_ID_PCM_S16LE_PLANAR :
190                     AV_CODEC_ID_PCM_S16BE_PLANAR; break;
191     case 2: codec = b->little_endian ?
192                     AV_CODEC_ID_ADPCM_THP_LE :
193                     AV_CODEC_ID_ADPCM_THP;        break;
194     default:
195         avpriv_request_sample(s, "codec %d", codec);
196         return AVERROR_PATCHWELCOME;
197     }
198
199     loop = avio_r8(s->pb); // loop flag
200     st->codecpar->codec_id = codec;
201     st->codecpar->channels = avio_r8(s->pb);
202     if (!st->codecpar->channels)
203         return AVERROR_INVALIDDATA;
204
205     avio_skip(s->pb, 1); // padding
206
207     st->codecpar->sample_rate = bfstm ? read32(s) : read16(s);
208     if (st->codecpar->sample_rate <= 0)
209         return AVERROR_INVALIDDATA;
210
211     if (!bfstm)
212         avio_skip(s->pb, 2); // padding
213
214     if (loop) {
215         if (av_dict_set_int(&s->metadata, "loop_start",
216                             av_rescale(read32(s), AV_TIME_BASE,
217                                        st->codecpar->sample_rate),
218                             0) < 0)
219             return AVERROR(ENOMEM);
220     } else {
221         avio_skip(s->pb, 4);
222     }
223
224     st->start_time = 0;
225     st->duration = read32(s);
226     avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
227
228     if (!bfstm)
229         start = read32(s);
230     b->current_block = 0;
231     b->block_count = read32(s);
232     if (b->block_count > UINT16_MAX) {
233         av_log(s, AV_LOG_WARNING, "too many blocks: %"PRIu32"\n", b->block_count);
234         return AVERROR_INVALIDDATA;
235     }
236
237     b->block_size = read32(s);
238     if (b->block_size > UINT32_MAX / st->codecpar->channels)
239         return AVERROR_INVALIDDATA;
240
241     b->samples_per_block = read32(s);
242     b->last_block_used_bytes = read32(s);
243     b->last_block_samples = read32(s);
244     b->last_block_size = read32(s);
245     if (b->last_block_size > UINT32_MAX / st->codecpar->channels)
246         return AVERROR_INVALIDDATA;
247     if (b->last_block_used_bytes > b->last_block_size)
248         return AVERROR_INVALIDDATA;
249
250
251     if (codec == AV_CODEC_ID_ADPCM_THP || codec == AV_CODEC_ID_ADPCM_THP_LE) {
252         int ch;
253
254         avio_skip(s->pb, pos + toffset - avio_tell(s->pb));
255         if (!bfstm)
256             toffset = read32(s) + 16LL;
257         else
258             toffset = toffset + read32(s) + st->codecpar->channels * 8 - 8;
259         if (toffset > size)
260             return AVERROR_INVALIDDATA;
261
262         avio_skip(s->pb, pos + toffset - avio_tell(s->pb));
263         b->table = av_mallocz(32 * st->codecpar->channels);
264         if (!b->table)
265             return AVERROR(ENOMEM);
266
267         for (ch = 0; ch < st->codecpar->channels; ch++) {
268             if (avio_read(s->pb, b->table + ch * 32, 32) != 32) {
269                 ret = AVERROR_INVALIDDATA;
270                 goto fail;
271             }
272             avio_skip(s->pb, bfstm ? 14 : 24);
273         }
274     }
275
276     if (size < (avio_tell(s->pb) - pos)) {
277         ret = AVERROR_INVALIDDATA;
278         goto fail;
279     }
280
281     avio_skip(s->pb, size - (avio_tell(s->pb) - pos));
282
283     while (!avio_feof(s->pb)) {
284         chunk = avio_rl32(s->pb);
285         size  = read32(s);
286         if (size < 8) {
287             ret = AVERROR_INVALIDDATA;
288             goto fail;
289         }
290         size -= 8;
291         switch (chunk) {
292         case MKTAG('S','E','E','K'):
293         case MKTAG('A','D','P','C'):
294             if (codec != AV_CODEC_ID_ADPCM_THP &&
295                 codec != AV_CODEC_ID_ADPCM_THP_LE)
296                 goto skip;
297
298             asize = b->block_count * st->codecpar->channels * 4;
299             if (size < asize) {
300                 ret = AVERROR_INVALIDDATA;
301                 goto fail;
302             }
303             if (b->adpc) {
304                 av_log(s, AV_LOG_WARNING, "skipping additional ADPC chunk\n");
305                 goto skip;
306             } else {
307                 b->adpc = av_mallocz(asize);
308                 if (!b->adpc) {
309                     ret = AVERROR(ENOMEM);
310                     goto fail;
311                 }
312                 if (bfstm && codec != AV_CODEC_ID_ADPCM_THP_LE) {
313                     // Big-endian BFSTMs have little-endian SEEK tables
314                     // for some strange reason.
315                     int i;
316                     for (i = 0; i < asize; i += 2) {
317                         b->adpc[i+1] = avio_r8(s->pb);
318                         b->adpc[i]   = avio_r8(s->pb);
319                     }
320                 } else {
321                     avio_read(s->pb, b->adpc, asize);
322                 }
323                 avio_skip(s->pb, size - asize);
324             }
325             break;
326         case MKTAG('D','A','T','A'):
327             if ((start < avio_tell(s->pb)) ||
328                 (!b->adpc && (codec == AV_CODEC_ID_ADPCM_THP ||
329                               codec == AV_CODEC_ID_ADPCM_THP_LE))) {
330                 ret = AVERROR_INVALIDDATA;
331                 goto fail;
332             }
333             avio_skip(s->pb, start - avio_tell(s->pb));
334
335             if (bfstm && (codec == AV_CODEC_ID_ADPCM_THP ||
336                           codec == AV_CODEC_ID_ADPCM_THP_LE))
337                 avio_skip(s->pb, 24);
338
339             b->data_start = avio_tell(s->pb);
340
341             if (!bfstm && (major != 1 || minor))
342                 avpriv_request_sample(s, "Version %d.%d", major, minor);
343
344             return 0;
345         default:
346             av_log(s, AV_LOG_WARNING, "skipping unknown chunk: %X\n", chunk);
347 skip:
348             avio_skip(s->pb, size);
349         }
350     }
351
352 fail:
353     read_close(s);
354
355     return ret;
356 }
357
358 static int read_packet(AVFormatContext *s, AVPacket *pkt)
359 {
360     AVCodecParameters *par = s->streams[0]->codecpar;
361     BRSTMDemuxContext *b = s->priv_data;
362     uint32_t samples, size, skip = 0;
363     int ret, i;
364
365     if (avio_feof(s->pb))
366         return AVERROR_EOF;
367     b->current_block++;
368     if (b->current_block == b->block_count) {
369         size    = b->last_block_used_bytes;
370         samples = b->last_block_samples;
371         skip    = b->last_block_size - b->last_block_used_bytes;
372
373         if (samples < size * 14 / 8) {
374             uint32_t adjusted_size = samples / 14 * 8;
375             if (samples % 14)
376                 adjusted_size += (samples % 14 + 1) / 2 + 1;
377
378             skip += size - adjusted_size;
379             size = adjusted_size;
380         }
381     } else if (b->current_block < b->block_count) {
382         size    = b->block_size;
383         samples = b->samples_per_block;
384     } else {
385         return AVERROR_EOF;
386     }
387
388     if (par->codec_id == AV_CODEC_ID_ADPCM_THP ||
389         par->codec_id == AV_CODEC_ID_ADPCM_THP_LE) {
390         uint8_t *dst;
391
392         if (!b->adpc) {
393             av_log(s, AV_LOG_ERROR, "adpcm_thp requires ADPC chunk, but none was found.\n");
394             return AVERROR_INVALIDDATA;
395         }
396         if (!b->table) {
397             b->table = av_mallocz(32 * par->channels);
398             if (!b->table)
399                 return AVERROR(ENOMEM);
400         }
401
402         if (size > (INT_MAX - 32 - 4) ||
403             (32 + 4 + size) > (INT_MAX / par->channels) ||
404             (32 + 4 + size) * par->channels > INT_MAX - 8)
405             return AVERROR_INVALIDDATA;
406         if (av_new_packet(pkt, 8 + (32 + 4 + size) * par->channels) < 0)
407             return AVERROR(ENOMEM);
408         dst = pkt->data;
409         if (par->codec_id == AV_CODEC_ID_ADPCM_THP_LE) {
410             bytestream_put_le32(&dst, size * par->channels);
411             bytestream_put_le32(&dst, samples);
412         } else {
413             bytestream_put_be32(&dst, size * par->channels);
414             bytestream_put_be32(&dst, samples);
415         }
416         bytestream_put_buffer(&dst, b->table, 32 * par->channels);
417         bytestream_put_buffer(&dst, b->adpc + 4 * par->channels *
418                                     (b->current_block - 1), 4 * par->channels);
419
420         for (i = 0; i < par->channels; i++) {
421             ret = avio_read(s->pb, dst, size);
422             dst += size;
423             avio_skip(s->pb, skip);
424             if (ret != size) {
425                 av_packet_unref(pkt);
426                 break;
427             }
428         }
429         pkt->duration = samples;
430     } else {
431         size *= par->channels;
432         ret = av_get_packet(s->pb, pkt, size);
433     }
434
435     pkt->stream_index = 0;
436
437     if (ret != size)
438         ret = AVERROR(EIO);
439
440     return ret;
441 }
442
443 static int read_seek(AVFormatContext *s, int stream_index,
444                      int64_t timestamp, int flags)
445 {
446     AVStream *st = s->streams[stream_index];
447     BRSTMDemuxContext *b = s->priv_data;
448     int64_t ret = 0;
449
450     timestamp /= b->samples_per_block;
451     ret = avio_seek(s->pb, b->data_start + timestamp * b->block_size *
452                            st->codecpar->channels, SEEK_SET);
453     if (ret < 0)
454         return ret;
455
456     b->current_block = timestamp;
457     ff_update_cur_dts(s, st, timestamp * b->samples_per_block);
458     return 0;
459 }
460
461 AVInputFormat ff_brstm_demuxer = {
462     .name           = "brstm",
463     .long_name      = NULL_IF_CONFIG_SMALL("BRSTM (Binary Revolution Stream)"),
464     .priv_data_size = sizeof(BRSTMDemuxContext),
465     .read_probe     = probe,
466     .read_header    = read_header,
467     .read_packet    = read_packet,
468     .read_close     = read_close,
469     .read_seek      = read_seek,
470     .extensions     = "brstm",
471 };
472
473 AVInputFormat ff_bfstm_demuxer = {
474     .name           = "bfstm",
475     .long_name      = NULL_IF_CONFIG_SMALL("BFSTM (Binary Cafe Stream)"),
476     .priv_data_size = sizeof(BRSTMDemuxContext),
477     .read_probe     = probe_bfstm,
478     .read_header    = read_header,
479     .read_packet    = read_packet,
480     .read_close     = read_close,
481     .read_seek      = read_seek,
482     .extensions     = "bfstm,bcstm",
483 };