blob: fa53636f1a112d6921b9ff85ba6bce874a2df04e
1 | /* |
2 | * Sony OpenMG (OMA) demuxer |
3 | * |
4 | * Copyright (c) 2008, 2013 Maxim Poliakovski |
5 | * 2008 Benjamin Larsson |
6 | * 2011 David Goldwich |
7 | * |
8 | * This file is part of FFmpeg. |
9 | * |
10 | * FFmpeg is free software; you can redistribute it and/or |
11 | * modify it under the terms of the GNU Lesser General Public |
12 | * License as published by the Free Software Foundation; either |
13 | * version 2.1 of the License, or (at your option) any later version. |
14 | * |
15 | * FFmpeg is distributed in the hope that it will be useful, |
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
18 | * Lesser General Public License for more details. |
19 | * |
20 | * You should have received a copy of the GNU Lesser General Public |
21 | * License along with FFmpeg; if not, write to the Free Software |
22 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
23 | */ |
24 | |
25 | /** |
26 | * @file |
27 | * This is a demuxer for Sony OpenMG Music files |
28 | * |
29 | * Known file extensions: ".oma", "aa3" |
30 | * The format of such files consists of three parts: |
31 | * - "ea3" header carrying overall info and metadata. Except for starting with |
32 | * "ea" instead of "ID", it's an ID3v2 header. |
33 | * - "EA3" header is a Sony-specific header containing information about |
34 | * the OpenMG file: codec type (usually ATRAC, can also be MP3 or WMA), |
35 | * codec specific info (packet size, sample rate, channels and so on) |
36 | * and DRM related info (file encryption, content id). |
37 | * - Sound data organized in packets follow the EA3 header |
38 | * (can be encrypted using the Sony DRM!). |
39 | * |
40 | * Supported decoders: ATRAC3, ATRAC3+, MP3, LPCM |
41 | */ |
42 | |
43 | #include <inttypes.h> |
44 | |
45 | #include "libavutil/channel_layout.h" |
46 | #include "avformat.h" |
47 | #include "internal.h" |
48 | #include "libavutil/intreadwrite.h" |
49 | #include "libavutil/des.h" |
50 | #include "libavutil/mathematics.h" |
51 | #include "oma.h" |
52 | #include "pcm.h" |
53 | #include "id3v2.h" |
54 | |
55 | |
56 | static const uint64_t leaf_table[] = { |
57 | 0xd79e8283acea4620, 0x7a9762f445afd0d8, |
58 | 0x354d60a60b8c79f1, 0x584e1cde00b07aee, |
59 | 0x1573cd93da7df623, 0x47f98d79620dd535 |
60 | }; |
61 | |
62 | typedef struct OMAContext { |
63 | uint64_t content_start; |
64 | int encrypted; |
65 | uint16_t k_size; |
66 | uint16_t e_size; |
67 | uint16_t i_size; |
68 | uint16_t s_size; |
69 | uint32_t rid; |
70 | uint8_t r_val[24]; |
71 | uint8_t n_val[24]; |
72 | uint8_t m_val[8]; |
73 | uint8_t s_val[8]; |
74 | uint8_t sm_val[8]; |
75 | uint8_t e_val[8]; |
76 | uint8_t iv[8]; |
77 | struct AVDES *av_des; |
78 | |
79 | int (*read_packet)(AVFormatContext *s, AVPacket *pkt); |
80 | } OMAContext; |
81 | |
82 | static void hex_log(AVFormatContext *s, int level, |
83 | const char *name, const uint8_t *value, int len) |
84 | { |
85 | char buf[33]; |
86 | len = FFMIN(len, 16); |
87 | if (av_log_get_level() < level) |
88 | return; |
89 | ff_data_to_hex(buf, value, len, 1); |
90 | buf[len << 1] = '\0'; |
91 | av_log(s, level, "%s: %s\n", name, buf); |
92 | } |
93 | |
94 | static int kset(AVFormatContext *s, const uint8_t *r_val, const uint8_t *n_val, |
95 | int len) |
96 | { |
97 | OMAContext *oc = s->priv_data; |
98 | |
99 | if (!r_val && !n_val) |
100 | return -1; |
101 | |
102 | len = FFMIN(len, 16); |
103 | |
104 | /* use first 64 bits in the third round again */ |
105 | if (r_val) { |
106 | if (r_val != oc->r_val) { |
107 | memset(oc->r_val, 0, 24); |
108 | memcpy(oc->r_val, r_val, len); |
109 | } |
110 | memcpy(&oc->r_val[16], r_val, 8); |
111 | } |
112 | if (n_val) { |
113 | if (n_val != oc->n_val) { |
114 | memset(oc->n_val, 0, 24); |
115 | memcpy(oc->n_val, n_val, len); |
116 | } |
117 | memcpy(&oc->n_val[16], n_val, 8); |
118 | } |
119 | |
120 | return 0; |
121 | } |
122 | |
123 | #define OMA_RPROBE_M_VAL 48 + 1 |
124 | |
125 | static int rprobe(AVFormatContext *s, uint8_t *enc_header, unsigned size, |
126 | const uint8_t *r_val) |
127 | { |
128 | OMAContext *oc = s->priv_data; |
129 | unsigned int pos; |
130 | struct AVDES *av_des; |
131 | |
132 | if (!enc_header || !r_val || |
133 | size < OMA_ENC_HEADER_SIZE + oc->k_size + oc->e_size + oc->i_size || |
134 | size < OMA_RPROBE_M_VAL) |
135 | return -1; |
136 | |
137 | av_des = av_des_alloc(); |
138 | if (!av_des) |
139 | return AVERROR(ENOMEM); |
140 | |
141 | /* m_val */ |
142 | av_des_init(av_des, r_val, 192, 1); |
143 | av_des_crypt(av_des, oc->m_val, &enc_header[48], 1, NULL, 1); |
144 | |
145 | /* s_val */ |
146 | av_des_init(av_des, oc->m_val, 64, 0); |
147 | av_des_crypt(av_des, oc->s_val, NULL, 1, NULL, 0); |
148 | |
149 | /* sm_val */ |
150 | pos = OMA_ENC_HEADER_SIZE + oc->k_size + oc->e_size; |
151 | av_des_init(av_des, oc->s_val, 64, 0); |
152 | av_des_mac(av_des, oc->sm_val, &enc_header[pos], (oc->i_size >> 3)); |
153 | |
154 | pos += oc->i_size; |
155 | |
156 | av_free(av_des); |
157 | |
158 | return memcmp(&enc_header[pos], oc->sm_val, 8) ? -1 : 0; |
159 | } |
160 | |
161 | static int nprobe(AVFormatContext *s, uint8_t *enc_header, unsigned size, |
162 | const uint8_t *n_val) |
163 | { |
164 | OMAContext *oc = s->priv_data; |
165 | uint64_t pos; |
166 | uint32_t taglen, datalen; |
167 | struct AVDES *av_des; |
168 | |
169 | if (!enc_header || !n_val || |
170 | size < OMA_ENC_HEADER_SIZE + oc->k_size + 4) |
171 | return -1; |
172 | |
173 | pos = OMA_ENC_HEADER_SIZE + oc->k_size; |
174 | if (!memcmp(&enc_header[pos], "EKB ", 4)) |
175 | pos += 32; |
176 | |
177 | if (size < pos + 44) |
178 | return -1; |
179 | |
180 | if (AV_RB32(&enc_header[pos]) != oc->rid) |
181 | av_log(s, AV_LOG_DEBUG, "Mismatching RID\n"); |
182 | |
183 | taglen = AV_RB32(&enc_header[pos + 32]); |
184 | datalen = AV_RB32(&enc_header[pos + 36]) >> 4; |
185 | |
186 | pos += 44LL + taglen; |
187 | |
188 | if (pos + (((uint64_t)datalen) << 4) > size) |
189 | return -1; |
190 | |
191 | av_des = av_des_alloc(); |
192 | if (!av_des) |
193 | return AVERROR(ENOMEM); |
194 | |
195 | av_des_init(av_des, n_val, 192, 1); |
196 | while (datalen-- > 0) { |
197 | av_des_crypt(av_des, oc->r_val, &enc_header[pos], 2, NULL, 1); |
198 | kset(s, oc->r_val, NULL, 16); |
199 | if (!rprobe(s, enc_header, size, oc->r_val)) { |
200 | av_free(av_des); |
201 | return 0; |
202 | } |
203 | pos += 16; |
204 | } |
205 | |
206 | av_free(av_des); |
207 | return -1; |
208 | } |
209 | |
210 | static int decrypt_init(AVFormatContext *s, ID3v2ExtraMeta *em, uint8_t *header) |
211 | { |
212 | OMAContext *oc = s->priv_data; |
213 | ID3v2ExtraMetaGEOB *geob = NULL; |
214 | uint8_t *gdata; |
215 | |
216 | oc->encrypted = 1; |
217 | av_log(s, AV_LOG_INFO, "File is encrypted\n"); |
218 | |
219 | /* find GEOB metadata */ |
220 | while (em) { |
221 | if (!strcmp(em->tag, "GEOB") && |
222 | (geob = em->data) && |
223 | (!strcmp(geob->description, "OMG_LSI") || |
224 | !strcmp(geob->description, "OMG_BKLSI"))) { |
225 | break; |
226 | } |
227 | em = em->next; |
228 | } |
229 | if (!em) { |
230 | av_log(s, AV_LOG_ERROR, "No encryption header found\n"); |
231 | return AVERROR_INVALIDDATA; |
232 | } |
233 | |
234 | if (geob->datasize < 64) { |
235 | av_log(s, AV_LOG_ERROR, |
236 | "Invalid GEOB data size: %"PRIu32"\n", geob->datasize); |
237 | return AVERROR_INVALIDDATA; |
238 | } |
239 | |
240 | gdata = geob->data; |
241 | |
242 | if (AV_RB16(gdata) != 1) |
243 | av_log(s, AV_LOG_WARNING, "Unknown version in encryption header\n"); |
244 | |
245 | oc->k_size = AV_RB16(&gdata[2]); |
246 | oc->e_size = AV_RB16(&gdata[4]); |
247 | oc->i_size = AV_RB16(&gdata[6]); |
248 | oc->s_size = AV_RB16(&gdata[8]); |
249 | |
250 | if (memcmp(&gdata[OMA_ENC_HEADER_SIZE], "KEYRING ", 12)) { |
251 | av_log(s, AV_LOG_ERROR, "Invalid encryption header\n"); |
252 | return AVERROR_INVALIDDATA; |
253 | } |
254 | if (OMA_ENC_HEADER_SIZE + oc->k_size + oc->e_size + oc->i_size + 8 > geob->datasize || |
255 | OMA_ENC_HEADER_SIZE + 48 > geob->datasize) { |
256 | av_log(s, AV_LOG_ERROR, "Too little GEOB data\n"); |
257 | return AVERROR_INVALIDDATA; |
258 | } |
259 | oc->rid = AV_RB32(&gdata[OMA_ENC_HEADER_SIZE + 28]); |
260 | av_log(s, AV_LOG_DEBUG, "RID: %.8"PRIx32"\n", oc->rid); |
261 | |
262 | memcpy(oc->iv, &header[0x58], 8); |
263 | hex_log(s, AV_LOG_DEBUG, "IV", oc->iv, 8); |
264 | |
265 | hex_log(s, AV_LOG_DEBUG, "CBC-MAC", |
266 | &gdata[OMA_ENC_HEADER_SIZE + oc->k_size + oc->e_size + oc->i_size], |
267 | 8); |
268 | |
269 | if (s->keylen > 0) { |
270 | kset(s, s->key, s->key, s->keylen); |
271 | } |
272 | if (!memcmp(oc->r_val, (const uint8_t[8]){0}, 8) || |
273 | rprobe(s, gdata, geob->datasize, oc->r_val) < 0 && |
274 | nprobe(s, gdata, geob->datasize, oc->n_val) < 0) { |
275 | int i; |
276 | for (i = 0; i < FF_ARRAY_ELEMS(leaf_table); i += 2) { |
277 | uint8_t buf[16]; |
278 | AV_WL64(buf, leaf_table[i]); |
279 | AV_WL64(&buf[8], leaf_table[i + 1]); |
280 | kset(s, buf, buf, 16); |
281 | if (!rprobe(s, gdata, geob->datasize, oc->r_val) || |
282 | !nprobe(s, gdata, geob->datasize, oc->n_val)) |
283 | break; |
284 | } |
285 | if (i >= FF_ARRAY_ELEMS(leaf_table)) { |
286 | av_log(s, AV_LOG_ERROR, "Invalid key\n"); |
287 | return AVERROR_INVALIDDATA; |
288 | } |
289 | } |
290 | |
291 | oc->av_des = av_des_alloc(); |
292 | if (!oc->av_des) |
293 | return AVERROR(ENOMEM); |
294 | |
295 | /* e_val */ |
296 | av_des_init(oc->av_des, oc->m_val, 64, 0); |
297 | av_des_crypt(oc->av_des, oc->e_val, |
298 | &gdata[OMA_ENC_HEADER_SIZE + 40], 1, NULL, 0); |
299 | hex_log(s, AV_LOG_DEBUG, "EK", oc->e_val, 8); |
300 | |
301 | /* init e_val */ |
302 | av_des_init(oc->av_des, oc->e_val, 64, 1); |
303 | |
304 | return 0; |
305 | } |
306 | |
307 | static int read_packet(AVFormatContext *s, AVPacket *pkt) |
308 | { |
309 | OMAContext *oc = s->priv_data; |
310 | AVStream *st = s->streams[0]; |
311 | int packet_size = st->codecpar->block_align; |
312 | int byte_rate = st->codecpar->bit_rate >> 3; |
313 | int64_t pos = avio_tell(s->pb); |
314 | int ret = av_get_packet(s->pb, pkt, packet_size); |
315 | |
316 | if (ret < packet_size) |
317 | pkt->flags |= AV_PKT_FLAG_CORRUPT; |
318 | |
319 | if (ret < 0) |
320 | return ret; |
321 | if (!ret) |
322 | return AVERROR_EOF; |
323 | |
324 | pkt->stream_index = 0; |
325 | |
326 | if (pos >= oc->content_start && byte_rate > 0) { |
327 | pkt->pts = |
328 | pkt->dts = av_rescale(pos - oc->content_start, st->time_base.den, |
329 | byte_rate * (int64_t)st->time_base.num); |
330 | } |
331 | |
332 | if (oc->encrypted) { |
333 | /* previous unencrypted block saved in IV for |
334 | * the next packet (CBC mode) */ |
335 | if (ret == packet_size) |
336 | av_des_crypt(oc->av_des, pkt->data, pkt->data, |
337 | (packet_size >> 3), oc->iv, 1); |
338 | else |
339 | memset(oc->iv, 0, 8); |
340 | } |
341 | |
342 | return ret; |
343 | } |
344 | |
345 | static int aal_read_packet(AVFormatContext *s, AVPacket *pkt) |
346 | { |
347 | int64_t pos = avio_tell(s->pb); |
348 | int ret, pts; |
349 | int packet_size; |
350 | unsigned tag; |
351 | |
352 | if (avio_feof(s->pb)) |
353 | return AVERROR_EOF; |
354 | |
355 | tag = avio_rb24(s->pb); |
356 | if (tag == 0) |
357 | return AVERROR_EOF; |
358 | else if (tag != MKBETAG(0,'B','L','K')) |
359 | return AVERROR_INVALIDDATA; |
360 | |
361 | avio_skip(s->pb, 1); |
362 | packet_size = avio_rb16(s->pb); |
363 | avio_skip(s->pb, 2); |
364 | pts = avio_rb32(s->pb); |
365 | avio_skip(s->pb, 12); |
366 | ret = av_get_packet(s->pb, pkt, packet_size); |
367 | if (ret < packet_size) |
368 | pkt->flags |= AV_PKT_FLAG_CORRUPT; |
369 | |
370 | if (ret < 0) |
371 | return ret; |
372 | if (!ret) |
373 | return AVERROR_EOF; |
374 | |
375 | pkt->stream_index = 0; |
376 | pkt->pos = pos; |
377 | if (s->streams[0]->codecpar->codec_id == AV_CODEC_ID_ATRAC3AL) { |
378 | pkt->duration = 1024; |
379 | pkt->pts = pts * 1024LL; |
380 | } else { |
381 | pkt->duration = 2048; |
382 | pkt->pts = pts * 2048LL; |
383 | } |
384 | |
385 | return ret; |
386 | } |
387 | |
388 | static int oma_read_header(AVFormatContext *s) |
389 | { |
390 | int ret, framesize, jsflag, samplerate; |
391 | uint32_t codec_params, channel_id; |
392 | int16_t eid; |
393 | uint8_t buf[EA3_HEADER_SIZE]; |
394 | uint8_t *edata; |
395 | AVStream *st; |
396 | ID3v2ExtraMeta *extra_meta = NULL; |
397 | OMAContext *oc = s->priv_data; |
398 | |
399 | ff_id3v2_read(s, ID3v2_EA3_MAGIC, &extra_meta, 0); |
400 | ret = avio_read(s->pb, buf, EA3_HEADER_SIZE); |
401 | if (ret < EA3_HEADER_SIZE) |
402 | return -1; |
403 | |
404 | if (memcmp(buf, ((const uint8_t[]){'E', 'A', '3'}), 3) || |
405 | buf[4] != 0 || buf[5] != EA3_HEADER_SIZE) { |
406 | av_log(s, AV_LOG_ERROR, "Couldn't find the EA3 header !\n"); |
407 | return AVERROR_INVALIDDATA; |
408 | } |
409 | |
410 | oc->content_start = avio_tell(s->pb); |
411 | |
412 | /* encrypted file */ |
413 | eid = AV_RB16(&buf[6]); |
414 | if (eid != -1 && eid != -128 && decrypt_init(s, extra_meta, buf) < 0) { |
415 | ff_id3v2_free_extra_meta(&extra_meta); |
416 | return -1; |
417 | } |
418 | |
419 | ff_id3v2_free_extra_meta(&extra_meta); |
420 | |
421 | codec_params = AV_RB24(&buf[33]); |
422 | |
423 | st = avformat_new_stream(s, NULL); |
424 | if (!st) |
425 | return AVERROR(ENOMEM); |
426 | |
427 | st->start_time = 0; |
428 | st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; |
429 | st->codecpar->codec_tag = buf[32]; |
430 | st->codecpar->codec_id = ff_codec_get_id(ff_oma_codec_tags, |
431 | st->codecpar->codec_tag); |
432 | |
433 | oc->read_packet = read_packet; |
434 | |
435 | switch (buf[32]) { |
436 | case OMA_CODECID_ATRAC3: |
437 | samplerate = ff_oma_srate_tab[(codec_params >> 13) & 7] * 100; |
438 | if (!samplerate) { |
439 | av_log(s, AV_LOG_ERROR, "Unsupported sample rate\n"); |
440 | return AVERROR_INVALIDDATA; |
441 | } |
442 | if (samplerate != 44100) |
443 | avpriv_request_sample(s, "Sample rate %d", samplerate); |
444 | |
445 | framesize = (codec_params & 0x3FF) * 8; |
446 | |
447 | /* get stereo coding mode, 1 for joint-stereo */ |
448 | jsflag = (codec_params >> 17) & 1; |
449 | |
450 | st->codecpar->channels = 2; |
451 | st->codecpar->channel_layout = AV_CH_LAYOUT_STEREO; |
452 | st->codecpar->sample_rate = samplerate; |
453 | st->codecpar->bit_rate = st->codecpar->sample_rate * framesize / (1024 / 8); |
454 | |
455 | /* fake the ATRAC3 extradata |
456 | * (wav format, makes stream copy to wav work) */ |
457 | if (ff_alloc_extradata(st->codecpar, 14)) |
458 | return AVERROR(ENOMEM); |
459 | |
460 | edata = st->codecpar->extradata; |
461 | AV_WL16(&edata[0], 1); // always 1 |
462 | AV_WL32(&edata[2], samplerate); // samples rate |
463 | AV_WL16(&edata[6], jsflag); // coding mode |
464 | AV_WL16(&edata[8], jsflag); // coding mode |
465 | AV_WL16(&edata[10], 1); // always 1 |
466 | // AV_WL16(&edata[12], 0); // always 0 |
467 | |
468 | avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate); |
469 | break; |
470 | case OMA_CODECID_ATRAC3P: |
471 | channel_id = (codec_params >> 10) & 7; |
472 | if (!channel_id) { |
473 | av_log(s, AV_LOG_ERROR, |
474 | "Invalid ATRAC-X channel id: %"PRIu32"\n", channel_id); |
475 | return AVERROR_INVALIDDATA; |
476 | } |
477 | st->codecpar->channel_layout = ff_oma_chid_to_native_layout[channel_id - 1]; |
478 | st->codecpar->channels = ff_oma_chid_to_num_channels[channel_id - 1]; |
479 | framesize = ((codec_params & 0x3FF) * 8) + 8; |
480 | samplerate = ff_oma_srate_tab[(codec_params >> 13) & 7] * 100; |
481 | if (!samplerate) { |
482 | av_log(s, AV_LOG_ERROR, "Unsupported sample rate\n"); |
483 | return AVERROR_INVALIDDATA; |
484 | } |
485 | st->codecpar->sample_rate = samplerate; |
486 | st->codecpar->bit_rate = samplerate * framesize / (2048 / 8); |
487 | avpriv_set_pts_info(st, 64, 1, samplerate); |
488 | break; |
489 | case OMA_CODECID_MP3: |
490 | st->need_parsing = AVSTREAM_PARSE_FULL_RAW; |
491 | framesize = 1024; |
492 | break; |
493 | case OMA_CODECID_LPCM: |
494 | /* PCM 44.1 kHz 16 bit stereo big-endian */ |
495 | st->codecpar->channels = 2; |
496 | st->codecpar->channel_layout = AV_CH_LAYOUT_STEREO; |
497 | st->codecpar->sample_rate = 44100; |
498 | framesize = 1024; |
499 | /* bit rate = sample rate x PCM block align (= 4) x 8 */ |
500 | st->codecpar->bit_rate = st->codecpar->sample_rate * 32; |
501 | st->codecpar->bits_per_coded_sample = |
502 | av_get_bits_per_sample(st->codecpar->codec_id); |
503 | avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate); |
504 | break; |
505 | case OMA_CODECID_ATRAC3AL: |
506 | st->codecpar->channels = 2; |
507 | st->codecpar->channel_layout = AV_CH_LAYOUT_STEREO; |
508 | st->codecpar->sample_rate = 44100; |
509 | avpriv_set_pts_info(st, 64, 1, 44100); |
510 | oc->read_packet = aal_read_packet; |
511 | framesize = 4096; |
512 | break; |
513 | case OMA_CODECID_ATRAC3PAL: |
514 | st->codecpar->channel_layout = AV_CH_LAYOUT_STEREO; |
515 | st->codecpar->channels = 2; |
516 | st->codecpar->sample_rate = 44100; |
517 | avpriv_set_pts_info(st, 64, 1, 44100); |
518 | oc->read_packet = aal_read_packet; |
519 | framesize = 4096; |
520 | break; |
521 | default: |
522 | av_log(s, AV_LOG_ERROR, "Unsupported codec %d!\n", buf[32]); |
523 | return AVERROR(ENOSYS); |
524 | } |
525 | |
526 | st->codecpar->block_align = framesize; |
527 | |
528 | return 0; |
529 | } |
530 | |
531 | static int oma_read_packet(AVFormatContext *s, AVPacket *pkt) |
532 | { |
533 | OMAContext *oc = s->priv_data; |
534 | return oc->read_packet(s, pkt); |
535 | } |
536 | |
537 | static int oma_read_probe(AVProbeData *p) |
538 | { |
539 | const uint8_t *buf = p->buf; |
540 | unsigned tag_len = 0; |
541 | |
542 | if (p->buf_size >= ID3v2_HEADER_SIZE && ff_id3v2_match(buf, ID3v2_EA3_MAGIC)) |
543 | tag_len = ff_id3v2_tag_len(buf); |
544 | |
545 | /* This check cannot overflow as tag_len has at most 28 bits */ |
546 | if (p->buf_size < tag_len + 5) |
547 | /* EA3 header comes late, might be outside of the probe buffer */ |
548 | return tag_len ? AVPROBE_SCORE_EXTENSION/2 : 0; |
549 | |
550 | buf += tag_len; |
551 | |
552 | if (!memcmp(buf, "EA3", 3) && !buf[4] && buf[5] == EA3_HEADER_SIZE) |
553 | return AVPROBE_SCORE_MAX; |
554 | else |
555 | return 0; |
556 | } |
557 | |
558 | static int oma_read_seek(struct AVFormatContext *s, |
559 | int stream_index, int64_t timestamp, int flags) |
560 | { |
561 | OMAContext *oc = s->priv_data; |
562 | AVStream *st = s->streams[0]; |
563 | int64_t err; |
564 | |
565 | if (st->codecpar->codec_id == AV_CODEC_ID_ATRAC3PAL || |
566 | st->codecpar->codec_id == AV_CODEC_ID_ATRAC3AL) |
567 | return -1; |
568 | |
569 | err = ff_pcm_read_seek(s, stream_index, timestamp, flags); |
570 | if (!oc->encrypted) |
571 | return err; |
572 | |
573 | /* readjust IV for CBC */ |
574 | if (err || avio_tell(s->pb) < oc->content_start) |
575 | goto wipe; |
576 | if ((err = avio_seek(s->pb, -8, SEEK_CUR)) < 0) |
577 | goto wipe; |
578 | if ((err = avio_read(s->pb, oc->iv, 8)) < 8) { |
579 | if (err >= 0) |
580 | err = AVERROR_EOF; |
581 | goto wipe; |
582 | } |
583 | |
584 | return 0; |
585 | wipe: |
586 | memset(oc->iv, 0, 8); |
587 | return err; |
588 | } |
589 | |
590 | static int oma_read_close(AVFormatContext *s) |
591 | { |
592 | OMAContext *oc = s->priv_data; |
593 | av_free(oc->av_des); |
594 | return 0; |
595 | } |
596 | |
597 | AVInputFormat ff_oma_demuxer = { |
598 | .name = "oma", |
599 | .long_name = NULL_IF_CONFIG_SMALL("Sony OpenMG audio"), |
600 | .priv_data_size = sizeof(OMAContext), |
601 | .read_probe = oma_read_probe, |
602 | .read_header = oma_read_header, |
603 | .read_packet = oma_read_packet, |
604 | .read_seek = oma_read_seek, |
605 | .read_close = oma_read_close, |
606 | .flags = AVFMT_GENERIC_INDEX, |
607 | .extensions = "oma,omg,aa3", |
608 | .codec_tag = (const AVCodecTag* const []){ff_oma_codec_tags, 0}, |
609 | }; |
610 |