1/*
2 * Bink demuxer
3 * Copyright (c) 2008-2010 Peter Ross (pross@xvid.org)
4 * Copyright (c) 2009 Daniel Verkamp (daniel@drv.nu)
5 *
6 * This file is part of Libav.
7 *
8 * Libav is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * Libav is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with Libav; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23/**
24 * @file
25 * Bink demuxer
26 *
27 * Technical details here:
28 *  http://wiki.multimedia.cx/index.php?title=Bink_Container
29 */
30
31#include "libavutil/intreadwrite.h"
32#include "avformat.h"
33#include "internal.h"
34
35enum BinkAudFlags {
36    BINK_AUD_16BITS = 0x4000, ///< prefer 16-bit output
37    BINK_AUD_STEREO = 0x2000,
38    BINK_AUD_USEDCT = 0x1000,
39};
40
41#define BINK_EXTRADATA_SIZE     1
42#define BINK_MAX_AUDIO_TRACKS   256
43#define BINK_MAX_WIDTH          7680
44#define BINK_MAX_HEIGHT         4800
45
46typedef struct {
47    uint32_t file_size;
48
49    uint32_t num_audio_tracks;
50    int current_track;      ///< audio track to return in next packet
51    int64_t video_pts;
52    int64_t audio_pts[BINK_MAX_AUDIO_TRACKS];
53
54    uint32_t remain_packet_size;
55} BinkDemuxContext;
56
57static int probe(AVProbeData *p)
58{
59    const uint8_t *b = p->buf;
60
61    if ( b[0] == 'B' && b[1] == 'I' && b[2] == 'K' &&
62        (b[3] == 'b' || b[3] == 'f' || b[3] == 'g' || b[3] == 'h' || b[3] == 'i') &&
63        AV_RL32(b+8) > 0 &&  // num_frames
64        AV_RL32(b+20) > 0 && AV_RL32(b+20) <= BINK_MAX_WIDTH &&
65        AV_RL32(b+24) > 0 && AV_RL32(b+24) <= BINK_MAX_HEIGHT &&
66        AV_RL32(b+28) > 0 && AV_RL32(b+32) > 0)  // fps num,den
67        return AVPROBE_SCORE_MAX;
68    return 0;
69}
70
71static int read_header(AVFormatContext *s, AVFormatParameters *ap)
72{
73    BinkDemuxContext *bink = s->priv_data;
74    AVIOContext *pb = s->pb;
75    uint32_t fps_num, fps_den;
76    AVStream *vst, *ast;
77    unsigned int i;
78    uint32_t pos, next_pos;
79    uint16_t flags;
80    int keyframe;
81
82    vst = avformat_new_stream(s, NULL);
83    if (!vst)
84        return AVERROR(ENOMEM);
85
86    vst->codec->codec_tag = avio_rl32(pb);
87
88    bink->file_size = avio_rl32(pb) + 8;
89    vst->duration   = avio_rl32(pb);
90
91    if (vst->duration > 1000000) {
92        av_log(s, AV_LOG_ERROR, "invalid header: more than 1000000 frames\n");
93        return AVERROR(EIO);
94    }
95
96    if (avio_rl32(pb) > bink->file_size) {
97        av_log(s, AV_LOG_ERROR,
98               "invalid header: largest frame size greater than file size\n");
99        return AVERROR(EIO);
100    }
101
102    avio_skip(pb, 4);
103
104    vst->codec->width  = avio_rl32(pb);
105    vst->codec->height = avio_rl32(pb);
106
107    fps_num = avio_rl32(pb);
108    fps_den = avio_rl32(pb);
109    if (fps_num == 0 || fps_den == 0) {
110        av_log(s, AV_LOG_ERROR, "invalid header: invalid fps (%d/%d)\n", fps_num, fps_den);
111        return AVERROR(EIO);
112    }
113    avpriv_set_pts_info(vst, 64, fps_den, fps_num);
114
115    vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
116    vst->codec->codec_id   = CODEC_ID_BINKVIDEO;
117    vst->codec->extradata  = av_mallocz(4 + FF_INPUT_BUFFER_PADDING_SIZE);
118    vst->codec->extradata_size = 4;
119    avio_read(pb, vst->codec->extradata, 4);
120
121    bink->num_audio_tracks = avio_rl32(pb);
122
123    if (bink->num_audio_tracks > BINK_MAX_AUDIO_TRACKS) {
124        av_log(s, AV_LOG_ERROR,
125               "invalid header: more than "AV_STRINGIFY(BINK_MAX_AUDIO_TRACKS)" audio tracks (%d)\n",
126               bink->num_audio_tracks);
127        return AVERROR(EIO);
128    }
129
130    if (bink->num_audio_tracks) {
131        avio_skip(pb, 4 * bink->num_audio_tracks);
132
133        for (i = 0; i < bink->num_audio_tracks; i++) {
134            ast = avformat_new_stream(s, NULL);
135            if (!ast)
136                return AVERROR(ENOMEM);
137            ast->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
138            ast->codec->codec_tag   = 0;
139            ast->codec->sample_rate = avio_rl16(pb);
140            avpriv_set_pts_info(ast, 64, 1, ast->codec->sample_rate);
141            flags = avio_rl16(pb);
142            ast->codec->codec_id = flags & BINK_AUD_USEDCT ?
143                                   CODEC_ID_BINKAUDIO_DCT : CODEC_ID_BINKAUDIO_RDFT;
144            ast->codec->channels = flags & BINK_AUD_STEREO ? 2 : 1;
145            ast->codec->extradata = av_mallocz(4 + FF_INPUT_BUFFER_PADDING_SIZE);
146            if (!ast->codec->extradata)
147                return AVERROR(ENOMEM);
148            ast->codec->extradata_size = 4;
149            AV_WL32(ast->codec->extradata, vst->codec->codec_tag);
150        }
151
152        for (i = 0; i < bink->num_audio_tracks; i++)
153            s->streams[i + 1]->id = avio_rl32(pb);
154    }
155
156    /* frame index table */
157    next_pos = avio_rl32(pb);
158    for (i = 0; i < vst->duration; i++) {
159        pos = next_pos;
160        if (i == vst->duration - 1) {
161            next_pos = bink->file_size;
162            keyframe = 0;
163        } else {
164            next_pos = avio_rl32(pb);
165            keyframe = pos & 1;
166        }
167        pos &= ~1;
168        next_pos &= ~1;
169
170        if (next_pos <= pos) {
171            av_log(s, AV_LOG_ERROR, "invalid frame index table\n");
172            return AVERROR(EIO);
173        }
174        av_add_index_entry(vst, pos, i, next_pos - pos, 0,
175                           keyframe ? AVINDEX_KEYFRAME : 0);
176    }
177
178    avio_skip(pb, 4);
179
180    bink->current_track = -1;
181    return 0;
182}
183
184static int read_packet(AVFormatContext *s, AVPacket *pkt)
185{
186    BinkDemuxContext *bink = s->priv_data;
187    AVIOContext *pb = s->pb;
188    int ret;
189
190    if (bink->current_track < 0) {
191        int index_entry;
192        AVStream *st = s->streams[0]; // stream 0 is video stream with index
193
194        if (bink->video_pts >= st->duration)
195            return AVERROR(EIO);
196
197        index_entry = av_index_search_timestamp(st, bink->video_pts,
198                                                AVSEEK_FLAG_ANY);
199        if (index_entry < 0) {
200            av_log(s, AV_LOG_ERROR,
201                   "could not find index entry for frame %"PRId64"\n",
202                   bink->video_pts);
203            return AVERROR(EIO);
204        }
205
206        bink->remain_packet_size = st->index_entries[index_entry].size;
207        bink->current_track = 0;
208    }
209
210    while (bink->current_track < bink->num_audio_tracks) {
211        uint32_t audio_size = avio_rl32(pb);
212        if (audio_size > bink->remain_packet_size - 4) {
213            av_log(s, AV_LOG_ERROR,
214                   "frame %"PRId64": audio size in header (%u) > size of packet left (%u)\n",
215                   bink->video_pts, audio_size, bink->remain_packet_size);
216            return AVERROR(EIO);
217        }
218        bink->remain_packet_size -= 4 + audio_size;
219        bink->current_track++;
220        if (audio_size >= 4) {
221            /* get one audio packet per track */
222            if ((ret = av_get_packet(pb, pkt, audio_size)) < 0)
223                return ret;
224            pkt->stream_index = bink->current_track;
225            pkt->pts = bink->audio_pts[bink->current_track - 1];
226
227            /* Each audio packet reports the number of decompressed samples
228               (in bytes). We use this value to calcuate the audio PTS */
229            if (pkt->size >= 4)
230                bink->audio_pts[bink->current_track -1] +=
231                    AV_RL32(pkt->data) / (2 * s->streams[bink->current_track]->codec->channels);
232            return 0;
233        } else {
234            avio_skip(pb, audio_size);
235        }
236    }
237
238    /* get video packet */
239    if ((ret = av_get_packet(pb, pkt, bink->remain_packet_size)) < 0)
240        return ret;
241    pkt->stream_index = 0;
242    pkt->pts = bink->video_pts++;
243    pkt->flags |= AV_PKT_FLAG_KEY;
244
245    /* -1 instructs the next call to read_packet() to read the next frame */
246    bink->current_track = -1;
247
248    return 0;
249}
250
251static int read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
252{
253    BinkDemuxContext *bink = s->priv_data;
254    AVStream *vst = s->streams[0];
255
256    if (!s->pb->seekable)
257        return -1;
258
259    /* seek to the first frame */
260    avio_seek(s->pb, vst->index_entries[0].pos, SEEK_SET);
261    bink->video_pts = 0;
262    memset(bink->audio_pts, 0, sizeof(bink->audio_pts));
263    bink->current_track = -1;
264    return 0;
265}
266
267AVInputFormat ff_bink_demuxer = {
268    .name           = "bink",
269    .long_name      = NULL_IF_CONFIG_SMALL("Bink"),
270    .priv_data_size = sizeof(BinkDemuxContext),
271    .read_probe     = probe,
272    .read_header    = read_header,
273    .read_packet    = read_packet,
274    .read_seek      = read_seek,
275};
276