Mercurial > libavformat.hg
annotate oma.c @ 6129:fec869707e4f libavformat
Reindent
Patch by Josh Allmann, joshua dot allmann at gmail
author | mstorsjo |
---|---|
date | Mon, 14 Jun 2010 08:12:40 +0000 |
parents | 178de7695c6c |
children | 0abe94ef06ce |
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 /** | |
5969
178de7695c6c
Remove explicit filename from Doxygen @file commands.
diego
parents:
5910
diff
changeset
|
25 * @file |
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; |
5910
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5554
diff
changeset
|
115 st->codec->codec_type = AVMEDIA_TYPE_AUDIO; |
3506 | 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 |