Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(244)

Side by Side Diff: patched-ffmpeg-mt/libavformat/bink.c

Issue 789004: ffmpeg roll of source to mar 9 version... (Closed) Base URL: svn://chrome-svn/chrome/trunk/deps/third_party/ffmpeg/
Patch Set: '' Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Bink demuxer 2 * Bink demuxer
3 * Copyright (c) 2008-2010 Peter Ross (pross@xvid.org) 3 * Copyright (c) 2008-2010 Peter Ross (pross@xvid.org)
4 * Copyright (c) 2009 Daniel Verkamp (daniel@drv.nu) 4 * Copyright (c) 2009 Daniel Verkamp (daniel@drv.nu)
5 * 5 *
6 * This file is part of FFmpeg. 6 * This file is part of FFmpeg.
7 * 7 *
8 * FFmpeg is free software; you can redistribute it and/or 8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public 9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either 10 * License as published by the Free Software Foundation; either
(...skipping 26 matching lines...) Expand all
37 BINK_AUD_USEDCT = 0x1000, 37 BINK_AUD_USEDCT = 0x1000,
38 }; 38 };
39 39
40 #define BINK_EXTRADATA_SIZE 1 40 #define BINK_EXTRADATA_SIZE 1
41 #define BINK_MAX_AUDIO_TRACKS 256 41 #define BINK_MAX_AUDIO_TRACKS 256
42 #define BINK_MAX_WIDTH 7680 42 #define BINK_MAX_WIDTH 7680
43 #define BINK_MAX_HEIGHT 4800 43 #define BINK_MAX_HEIGHT 4800
44 44
45 typedef struct { 45 typedef struct {
46 uint32_t file_size; 46 uint32_t file_size;
47 uint32_t total_frames;
48 47
49 uint32_t num_audio_tracks; 48 uint32_t num_audio_tracks;
50 int current_track; ///< audio track to return in next packet 49 int current_track; ///< audio track to return in next packet
51 int64_t video_pts; 50 int64_t video_pts;
52 int64_t audio_pts[BINK_MAX_AUDIO_TRACKS]; 51 int64_t audio_pts[BINK_MAX_AUDIO_TRACKS];
53 52
54 uint32_t remain_packet_size; 53 uint32_t remain_packet_size;
55 } BinkDemuxContext; 54 } BinkDemuxContext;
56 55
57 static int probe(AVProbeData *p) 56 static int probe(AVProbeData *p)
(...skipping 10 matching lines...) Expand all
68 return 0; 67 return 0;
69 } 68 }
70 69
71 static int read_header(AVFormatContext *s, AVFormatParameters *ap) 70 static int read_header(AVFormatContext *s, AVFormatParameters *ap)
72 { 71 {
73 BinkDemuxContext *bink = s->priv_data; 72 BinkDemuxContext *bink = s->priv_data;
74 ByteIOContext *pb = s->pb; 73 ByteIOContext *pb = s->pb;
75 uint32_t fps_num, fps_den; 74 uint32_t fps_num, fps_den;
76 AVStream *vst, *ast; 75 AVStream *vst, *ast;
77 unsigned int i; 76 unsigned int i;
78 uint32_t pos, prev_pos; 77 uint32_t pos, next_pos;
79 uint16_t flags; 78 uint16_t flags;
80 int keyframe; 79 int keyframe;
81 80
82 vst = av_new_stream(s, 0); 81 vst = av_new_stream(s, 0);
83 if (!vst) 82 if (!vst)
84 return AVERROR(ENOMEM); 83 return AVERROR(ENOMEM);
85 84
86 vst->codec->codec_tag = get_le32(pb); 85 vst->codec->codec_tag = get_le32(pb);
87 86
88 bink->file_size = get_le32(pb) + 8; 87 bink->file_size = get_le32(pb) + 8;
89 bink->total_frames = get_le32(pb); 88 vst->duration = get_le32(pb);
90 89
91 if (bink->total_frames > 1000000) { 90 if (vst->duration > 1000000) {
92 av_log(s, AV_LOG_ERROR, "invalid header: more than 1000000 frames\n"); 91 av_log(s, AV_LOG_ERROR, "invalid header: more than 1000000 frames\n");
93 return AVERROR(EIO); 92 return AVERROR(EIO);
94 } 93 }
95 94
96 if (get_le32(pb) > bink->file_size) { 95 if (get_le32(pb) > bink->file_size) {
97 av_log(s, AV_LOG_ERROR, 96 av_log(s, AV_LOG_ERROR,
98 "invalid header: largest frame size greater than file size\n"); 97 "invalid header: largest frame size greater than file size\n");
99 return AVERROR(EIO); 98 return AVERROR(EIO);
100 } 99 }
101 100
102 url_fskip(pb, 4); 101 url_fskip(pb, 4);
103 102
104 vst->codec->width = get_le32(pb); 103 vst->codec->width = get_le32(pb);
105 vst->codec->height = get_le32(pb); 104 vst->codec->height = get_le32(pb);
106 105
107 fps_num = get_le32(pb); 106 fps_num = get_le32(pb);
108 fps_den = get_le32(pb); 107 fps_den = get_le32(pb);
109 if (fps_num == 0 || fps_den == 0) { 108 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); 109 av_log(s, AV_LOG_ERROR, "invalid header: invalid fps (%d/%d)\n", fps_num , fps_den);
111 return AVERROR(EIO); 110 return AVERROR(EIO);
112 } 111 }
113 av_set_pts_info(vst, 64, fps_den, fps_num); 112 av_set_pts_info(vst, 64, fps_den, fps_num);
114 113
115 url_fskip(pb, 4);
116
117 vst->codec->codec_type = CODEC_TYPE_VIDEO; 114 vst->codec->codec_type = CODEC_TYPE_VIDEO;
118 vst->codec->codec_id = CODEC_ID_BINKVIDEO; 115 vst->codec->codec_id = CODEC_ID_BINKVIDEO;
116 vst->codec->extradata = av_mallocz(4 + FF_INPUT_BUFFER_PADDING_SIZE);
117 vst->codec->extradata_size = 4;
118 get_buffer(pb, vst->codec->extradata, 4);
119
119 bink->num_audio_tracks = get_le32(pb); 120 bink->num_audio_tracks = get_le32(pb);
120 121
121 if (bink->num_audio_tracks > BINK_MAX_AUDIO_TRACKS) { 122 if (bink->num_audio_tracks > BINK_MAX_AUDIO_TRACKS) {
122 av_log(s, AV_LOG_ERROR, 123 av_log(s, AV_LOG_ERROR,
123 "invalid header: more than "AV_STRINGIFY(BINK_MAX_AUDIO_TRACKS)" audio tracks (%d)\n", 124 "invalid header: more than "AV_STRINGIFY(BINK_MAX_AUDIO_TRACKS)" audio tracks (%d)\n",
124 bink->num_audio_tracks); 125 bink->num_audio_tracks);
125 return AVERROR(EIO); 126 return AVERROR(EIO);
126 } 127 }
127 128
128 if (bink->num_audio_tracks) { 129 if (bink->num_audio_tracks) {
(...skipping 10 matching lines...) Expand all
139 flags = get_le16(pb); 140 flags = get_le16(pb);
140 ast->codec->codec_id = flags & BINK_AUD_USEDCT ? 141 ast->codec->codec_id = flags & BINK_AUD_USEDCT ?
141 CODEC_ID_BINKAUDIO_DCT : CODEC_ID_BINKAUDIO_R DFT; 142 CODEC_ID_BINKAUDIO_DCT : CODEC_ID_BINKAUDIO_R DFT;
142 ast->codec->channels = flags & BINK_AUD_STEREO ? 2 : 1; 143 ast->codec->channels = flags & BINK_AUD_STEREO ? 2 : 1;
143 } 144 }
144 145
145 url_fskip(pb, 4 * bink->num_audio_tracks); 146 url_fskip(pb, 4 * bink->num_audio_tracks);
146 } 147 }
147 148
148 /* frame index table */ 149 /* frame index table */
149 pos = get_le32(pb) & ~1; 150 next_pos = get_le32(pb);
150 for (i = 0; i < bink->total_frames; i++) { 151 for (i = 0; i < vst->duration; i++) {
151 prev_pos = pos; 152 pos = next_pos;
152 if (i == bink->total_frames - 1) { 153 if (i == vst->duration - 1) {
153 pos = bink->file_size; 154 next_pos = bink->file_size;
154 keyframe = 0; 155 keyframe = 0;
155 } else { 156 } else {
156 pos = get_le32(pb); 157 next_pos = get_le32(pb);
157 keyframe = pos & 1; 158 keyframe = pos & 1;
158 pos &= ~1;
159 } 159 }
160 if (pos <= prev_pos) { 160 pos &= ~1;
161 next_pos &= ~1;
162
163 if (next_pos <= pos) {
161 av_log(s, AV_LOG_ERROR, "invalid frame index table\n"); 164 av_log(s, AV_LOG_ERROR, "invalid frame index table\n");
162 return AVERROR(EIO); 165 return AVERROR(EIO);
163 } 166 }
164 av_add_index_entry(vst, pos, i, pos - prev_pos, 0, 167 av_add_index_entry(vst, pos, i, next_pos - pos, 0,
165 keyframe ? AVINDEX_KEYFRAME : 0); 168 keyframe ? AVINDEX_KEYFRAME : 0);
166 } 169 }
167 170
168 url_fskip(pb, 4); 171 url_fskip(pb, 4);
169 172
170 bink->current_track = -1; 173 bink->current_track = -1;
171 return 0; 174 return 0;
172 } 175 }
173 176
174 static int read_packet(AVFormatContext *s, AVPacket *pkt) 177 static int read_packet(AVFormatContext *s, AVPacket *pkt)
175 { 178 {
176 BinkDemuxContext *bink = s->priv_data; 179 BinkDemuxContext *bink = s->priv_data;
177 ByteIOContext *pb = s->pb; 180 ByteIOContext *pb = s->pb;
178 int ret; 181 int ret;
179 182
180 if (bink->current_track < 0) { 183 if (bink->current_track < 0) {
181 int index_entry; 184 int index_entry;
182 AVStream *st = s->streams[0]; // stream 0 is video stream with index 185 AVStream *st = s->streams[0]; // stream 0 is video stream with index
183 186
184 if (bink->video_pts >= bink->total_frames) 187 if (bink->video_pts >= st->duration)
185 return AVERROR(EIO); 188 return AVERROR(EIO);
186 189
187 index_entry = av_index_search_timestamp(st, bink->video_pts, 190 index_entry = av_index_search_timestamp(st, bink->video_pts,
188 AVSEEK_FLAG_ANY); 191 AVSEEK_FLAG_ANY);
189 if (index_entry < 0) { 192 if (index_entry < 0) {
190 av_log(s, AV_LOG_ERROR, 193 av_log(s, AV_LOG_ERROR,
191 "could not find index entry for frame %"PRId64"\n", 194 "could not find index entry for frame %"PRId64"\n",
192 bink->video_pts); 195 bink->video_pts);
193 return AVERROR(EIO); 196 return AVERROR(EIO);
194 } 197 }
195 198
196 bink->remain_packet_size = st->index_entries[index_entry].size; 199 bink->remain_packet_size = st->index_entries[index_entry].size;
197 bink->current_track = 0; 200 bink->current_track = 0;
198 } 201 }
199 202
200 if (bink->current_track < bink->num_audio_tracks) { 203 while (bink->current_track < bink->num_audio_tracks) {
201 uint32_t audio_size = get_le32(pb); 204 uint32_t audio_size = get_le32(pb);
202 if (audio_size > bink->remain_packet_size - 4) { 205 if (audio_size > bink->remain_packet_size - 4) {
203 av_log(s, AV_LOG_ERROR, 206 av_log(s, AV_LOG_ERROR,
204 "frame %"PRId64": audio size in header (%u) > size of packet left (%u)\n", 207 "frame %"PRId64": audio size in header (%u) > size of packet left (%u)\n",
205 bink->video_pts, audio_size, bink->remain_packet_size); 208 bink->video_pts, audio_size, bink->remain_packet_size);
206 return AVERROR(EIO); 209 return AVERROR(EIO);
207 } 210 }
208 bink->remain_packet_size -= 4 + audio_size; 211 bink->remain_packet_size -= 4 + audio_size;
209 bink->current_track++; 212 bink->current_track++;
210 if (audio_size > 0) { 213 if (audio_size >= 4) {
214 /* get one audio packet per track */
215 if ((ret = av_get_packet(pb, pkt, audio_size)) <= 0)
216 return ret;
217 pkt->stream_index = bink->current_track;
218 pkt->pts = bink->audio_pts[bink->current_track - 1];
219
211 /* Each audio packet reports the number of decompressed samples 220 /* Each audio packet reports the number of decompressed samples
212 (in bytes). We use this value to calcuate the audio PTS */ 221 (in bytes). We use this value to calcuate the audio PTS */
213 int reported_size = get_le32(pb) / (2 * s->streams[bink->current_tra ck]->codec->channels); 222 bink->audio_pts[bink->current_track -1] +=
214 url_fseek(pb, -4, SEEK_CUR); 223 AV_RL32(pkt->data) / (2 * s->streams[bink->current_track]->codec ->channels);
215
216 /* get one audio packet per track */
217 if ((ret = av_get_packet(pb, pkt, audio_size))
218 != audio_size)
219 return ret;
220 pkt->stream_index = bink->current_track;
221 pkt->pts = bink->audio_pts[bink->current_track - 1] += reported_size ;
222 return 0; 224 return 0;
225 } else {
226 url_fseek(pb, audio_size, SEEK_CUR);
223 } 227 }
224 } 228 }
225 229
226 /* get video packet */ 230 /* get video packet */
227 if ((ret = av_get_packet(pb, pkt, bink->remain_packet_size)) 231 if ((ret = av_get_packet(pb, pkt, bink->remain_packet_size))
228 != bink->remain_packet_size) 232 != bink->remain_packet_size)
229 return ret; 233 return ret;
230 pkt->stream_index = 0; 234 pkt->stream_index = 0;
231 pkt->pts = bink->video_pts++; 235 pkt->pts = bink->video_pts++;
232 pkt->flags |= PKT_FLAG_KEY; 236 pkt->flags |= PKT_FLAG_KEY;
233 237
234 /* -1 instructs the next call to read_packet() to read the next frame */ 238 /* -1 instructs the next call to read_packet() to read the next frame */
235 bink->current_track = -1; 239 bink->current_track = -1;
236 240
237 return 0; 241 return 0;
238 } 242 }
239 243
244 static int read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, in t flags)
245 {
246 BinkDemuxContext *bink = s->priv_data;
247 AVStream *vst = s->streams[0];
248
249 if (url_is_streamed(s->pb))
250 return -1;
251
252 /* seek to the first frame */
253 url_fseek(s->pb, vst->index_entries[0].pos, SEEK_SET);
254 bink->video_pts = 0;
255 memset(bink->audio_pts, 0, sizeof(bink->audio_pts));
256 bink->current_track = -1;
257 return 0;
258 }
259
240 AVInputFormat bink_demuxer = { 260 AVInputFormat bink_demuxer = {
241 "bink", 261 "bink",
242 NULL_IF_CONFIG_SMALL("Bink"), 262 NULL_IF_CONFIG_SMALL("Bink"),
243 sizeof(BinkDemuxContext), 263 sizeof(BinkDemuxContext),
244 probe, 264 probe,
245 read_header, 265 read_header,
246 read_packet, 266 read_packet,
267 NULL,
268 read_seek,
247 }; 269 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698