Mercurial > libavformat.hg
annotate oma.c @ 5836:2997c88028cd libavformat
Move the probe loop from av_open_input_file() into its own method
av_probe_input_buffer() so that it can be reused. Here are a few
differences to the original way things were probed:
- maximum probe buffer size can be specified as a parameter.
- offset within the stream to probe from can be specified as a parameter.
- instead of seeking back to the start each time a probe fails, stream
data is appended to the reallocated buffer. This lowers the amount
of data read from the stream (there is no repetition) and results in
fewer closed and reopened streams (when seeking fails).
New attempt after r22296, which was revert in r22315 due to a FATE
failure.
See the thread:
Subject: [FFmpeg-devel] [PATCH] Move av_open_input_file probe loop to its own method
Date: 2010-03-05 03:23:57 GMT
Patch by Micah F. Galizia printf("%s%s@%s.%s", "micah", "galizia", "gmail", "com").
author | stefano |
---|---|
date | Sun, 14 Mar 2010 22:40:16 +0000 |
parents | dde1a233f3f6 |
children | 536e5527c1e0 |
rev | line source |
---|---|
3439 | 1 /* |
2 * Sony OpenMG (OMA) demuxer | |
3 * | |
4 * Copyright (c) 2008 Maxim Poliakovski | |
5 * 2008 Benjamin Larsson | |
6 * | |
7 * This file is part of FFmpeg. | |
8 * | |
9 * FFmpeg is free software; you can redistribute it and/or | |
10 * modify it under the terms of the GNU Lesser General Public | |
11 * License as published by the Free Software Foundation; either | |
12 * version 2.1 of the License, or (at your option) any later version. | |
13 * | |
14 * FFmpeg is distributed in the hope that it will be useful, | |
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
17 * Lesser General Public License for more details. | |
18 * | |
19 * You should have received a copy of the GNU Lesser General Public | |
20 * License along with FFmpeg; if not, write to the Free Software | |
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
22 */ | |
23 | |
24 /** | |
4331
49c1d3b27727
Use full internal pathname in doxygen @file directives.
diego
parents:
3769
diff
changeset
|
25 * @file libavformat/oma.c |
3439 | 26 * This is a demuxer for Sony OpenMG Music files |
27 * | |
28 * Known file extensions: ".oma", "aa3" | |
29 * The format of such files consists of three parts: | |
30 * - "ea3" header carrying overall info and metadata. | |
31 * - "EA3" header is a Sony-specific header containing information about | |
32 * the OpenMG file: codec type (usually ATRAC, can also be MP3 or WMA), | |
33 * codec specific info (packet size, sample rate, channels and so on) | |
34 * and DRM related info (file encryption, content id). | |
35 * - Sound data organized in packets follow the EA3 header | |
36 * (can be encrypted using the Sony DRM!). | |
37 * | |
38 * LIMITATIONS: This version supports only plain (unencrypted) OMA files. | |
39 * If any DRM-protected (encrypted) file is encountered you will get the | |
40 * corresponding error message. Try to remove the encryption using any | |
41 * Sony software (for example SonicStage). | |
42 * CODEC SUPPORT: Only ATRAC3 codec is currently supported! | |
43 */ | |
44 | |
45 #include "avformat.h" | |
46 #include "libavutil/intreadwrite.h" | |
47 #include "raw.h" | |
48 #include "riff.h" | |
49 | |
50 #define EA3_HEADER_SIZE 96 | |
51 | |
52 enum { | |
53 OMA_CODECID_ATRAC3 = 0, | |
54 OMA_CODECID_ATRAC3P = 1, | |
3505 | 55 OMA_CODECID_MP3 = 3, |
56 OMA_CODECID_LPCM = 4, | |
57 OMA_CODECID_WMA = 5, | |
3439 | 58 }; |
59 | |
60 static const AVCodecTag codec_oma_tags[] = { | |
61 { CODEC_ID_ATRAC3, OMA_CODECID_ATRAC3 }, | |
62 { CODEC_ID_ATRAC3P, OMA_CODECID_ATRAC3P }, | |
3505 | 63 { CODEC_ID_MP3, OMA_CODECID_MP3 }, |
3439 | 64 }; |
65 | |
66 static int oma_read_header(AVFormatContext *s, | |
67 AVFormatParameters *ap) | |
68 { | |
69 static const uint16_t srate_tab[6] = {320,441,480,882,960,0}; | |
3506 | 70 int ret, ea3_taglen, EA3_pos, framesize, jsflag, samplerate; |
3439 | 71 uint32_t codec_params; |
72 int16_t eid; | |
73 uint8_t buf[EA3_HEADER_SIZE]; | |
74 uint8_t *edata; | |
75 AVStream *st; | |
76 | |
77 ret = get_buffer(s->pb, buf, 10); | |
78 if (ret != 10) | |
79 return -1; | |
80 | |
5553
d15ba827d5ea
Support demuxing of Sony OpenMG files without metadata header.
cehoyos
parents:
5058
diff
changeset
|
81 if(!memcmp(buf, "ea3", 3)) { |
5554 | 82 ea3_taglen = ((buf[6] & 0x7f) << 21) | ((buf[7] & 0x7f) << 14) | ((buf[8] & 0x7f) << 7) | (buf[9] & 0x7f); |
3439 | 83 |
5554 | 84 EA3_pos = ea3_taglen + 10; |
85 if (buf[5] & 0x10) | |
86 EA3_pos += 10; | |
3439 | 87 |
5554 | 88 url_fseek(s->pb, EA3_pos, SEEK_SET); |
89 ret = get_buffer(s->pb, buf, EA3_HEADER_SIZE); | |
90 if (ret != EA3_HEADER_SIZE) | |
91 return -1; | |
5553
d15ba827d5ea
Support demuxing of Sony OpenMG files without metadata header.
cehoyos
parents:
5058
diff
changeset
|
92 } else { |
d15ba827d5ea
Support demuxing of Sony OpenMG files without metadata header.
cehoyos
parents:
5058
diff
changeset
|
93 ret = get_buffer(s->pb, buf + 10, EA3_HEADER_SIZE - 10); |
d15ba827d5ea
Support demuxing of Sony OpenMG files without metadata header.
cehoyos
parents:
5058
diff
changeset
|
94 EA3_pos = 0; |
d15ba827d5ea
Support demuxing of Sony OpenMG files without metadata header.
cehoyos
parents:
5058
diff
changeset
|
95 } |
3439 | 96 |
4943 | 97 if (memcmp(buf, ((const uint8_t[]){'E', 'A', '3'}),3) || buf[4] != 0 || buf[5] != EA3_HEADER_SIZE) { |
3439 | 98 av_log(s, AV_LOG_ERROR, "Couldn't find the EA3 header !\n"); |
99 return -1; | |
100 } | |
101 | |
102 eid = AV_RB16(&buf[6]); | |
103 if (eid != -1 && eid != -128) { | |
104 av_log(s, AV_LOG_ERROR, "Encrypted file! Eid: %d\n", eid); | |
105 return -1; | |
106 } | |
107 | |
108 codec_params = AV_RB24(&buf[33]); | |
109 | |
110 st = av_new_stream(s, 0); | |
111 if (!st) | |
112 return AVERROR(ENOMEM); | |
113 | |
3506 | 114 st->start_time = 0; |
115 st->codec->codec_type = CODEC_TYPE_AUDIO; | |
116 st->codec->codec_tag = buf[32]; | |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
4943
diff
changeset
|
117 st->codec->codec_id = ff_codec_get_id(codec_oma_tags, st->codec->codec_tag); |
3506 | 118 |
3439 | 119 switch (buf[32]) { |
120 case OMA_CODECID_ATRAC3: | |
3506 | 121 samplerate = srate_tab[(codec_params >> 13) & 7]*100; |
3439 | 122 if (samplerate != 44100) |
123 av_log(s, AV_LOG_ERROR, "Unsupported sample rate, send sample file to developers: %d\n", samplerate); | |
124 | |
125 framesize = (codec_params & 0x3FF) * 8; | |
126 jsflag = (codec_params >> 17) & 1; /* get stereo coding mode, 1 for joint-stereo */ | |
3506 | 127 st->codec->channels = 2; |
128 st->codec->sample_rate = samplerate; | |
129 st->codec->bit_rate = st->codec->sample_rate * framesize * 8 / 1024; | |
3439 | 130 |
131 /* fake the atrac3 extradata (wav format, makes stream copy to wav work) */ | |
132 st->codec->extradata_size = 14; | |
133 edata = av_mallocz(14 + FF_INPUT_BUFFER_PADDING_SIZE); | |
134 if (!edata) | |
135 return AVERROR(ENOMEM); | |
136 | |
137 st->codec->extradata = edata; | |
138 AV_WL16(&edata[0], 1); // always 1 | |
139 AV_WL32(&edata[2], samplerate); // samples rate | |
140 AV_WL16(&edata[6], jsflag); // coding mode | |
141 AV_WL16(&edata[8], jsflag); // coding mode | |
142 AV_WL16(&edata[10], 1); // always 1 | |
143 // AV_WL16(&edata[12], 0); // always 0 | |
3506 | 144 |
145 av_set_pts_info(st, 64, 1, st->codec->sample_rate); | |
3439 | 146 break; |
147 case OMA_CODECID_ATRAC3P: | |
3506 | 148 st->codec->channels = (codec_params >> 10) & 7; |
3439 | 149 framesize = ((codec_params & 0x3FF) * 8) + 8; |
3506 | 150 st->codec->sample_rate = srate_tab[(codec_params >> 13) & 7]*100; |
151 st->codec->bit_rate = st->codec->sample_rate * framesize * 8 / 1024; | |
152 av_set_pts_info(st, 64, 1, st->codec->sample_rate); | |
3439 | 153 av_log(s, AV_LOG_ERROR, "Unsupported codec ATRAC3+!\n"); |
154 break; | |
3507 | 155 case OMA_CODECID_MP3: |
156 st->need_parsing = AVSTREAM_PARSE_FULL; | |
157 framesize = 1024; | |
158 break; | |
3439 | 159 default: |
160 av_log(s, AV_LOG_ERROR, "Unsupported codec %d!\n",buf[32]); | |
161 return -1; | |
162 break; | |
163 } | |
164 | |
165 st->codec->block_align = framesize; | |
166 url_fseek(s->pb, EA3_pos + EA3_HEADER_SIZE, SEEK_SET); | |
167 | |
168 return 0; | |
169 } | |
170 | |
171 | |
172 static int oma_read_packet(AVFormatContext *s, AVPacket *pkt) | |
173 { | |
174 int ret = av_get_packet(s->pb, pkt, s->streams[0]->codec->block_align); | |
175 | |
176 pkt->stream_index = 0; | |
177 if (ret <= 0) | |
178 return AVERROR(EIO); | |
179 | |
180 return ret; | |
181 } | |
182 | |
183 static int oma_read_probe(AVProbeData *p) | |
184 { | |
5553
d15ba827d5ea
Support demuxing of Sony OpenMG files without metadata header.
cehoyos
parents:
5058
diff
changeset
|
185 if (!memcmp(p->buf, ((const uint8_t[]){'e', 'a', '3', 3, 0}), 5) || |
d15ba827d5ea
Support demuxing of Sony OpenMG files without metadata header.
cehoyos
parents:
5058
diff
changeset
|
186 (!memcmp(p->buf, "EA3", 3) && |
d15ba827d5ea
Support demuxing of Sony OpenMG files without metadata header.
cehoyos
parents:
5058
diff
changeset
|
187 !p->buf[4] && p->buf[5] == EA3_HEADER_SIZE)) |
3439 | 188 return AVPROBE_SCORE_MAX; |
189 else | |
190 return 0; | |
191 } | |
192 | |
193 | |
194 AVInputFormat oma_demuxer = { | |
195 "oma", | |
196 NULL_IF_CONFIG_SMALL("Sony OpenMG audio"), | |
197 0, | |
198 oma_read_probe, | |
199 oma_read_header, | |
200 oma_read_packet, | |
201 0, | |
202 pcm_read_seek, | |
203 .flags= AVFMT_GENERIC_INDEX, | |
204 .extensions = "oma,aa3", | |
3766
f062deeedb8d
Change codec_tag type from const struct AVCodecTag ** to const struct AVCodecTag * const *
reimar
parents:
3507
diff
changeset
|
205 .codec_tag= (const AVCodecTag* const []){codec_oma_tags, 0}, |
3439 | 206 }; |
207 |