annotate bink.c @ 5910:536e5527c1e0 libavformat

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