00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00046 #include "avformat.h"
00047 #include "libavutil/intreadwrite.h"
00048 #include "pcm.h"
00049 #include "riff.h"
00050 #include "id3v2.h"
00051
00052 #define EA3_HEADER_SIZE 96
00053
00054 enum {
00055 OMA_CODECID_ATRAC3 = 0,
00056 OMA_CODECID_ATRAC3P = 1,
00057 OMA_CODECID_MP3 = 3,
00058 OMA_CODECID_LPCM = 4,
00059 OMA_CODECID_WMA = 5,
00060 };
00061
00062 static const AVCodecTag codec_oma_tags[] = {
00063 { CODEC_ID_ATRAC3, OMA_CODECID_ATRAC3 },
00064 { CODEC_ID_ATRAC3P, OMA_CODECID_ATRAC3P },
00065 { CODEC_ID_MP3, OMA_CODECID_MP3 },
00066 };
00067
00068 #define ID3v2_EA3_MAGIC "ea3"
00069
00070 static int oma_read_header(AVFormatContext *s,
00071 AVFormatParameters *ap)
00072 {
00073 static const uint16_t srate_tab[6] = {320,441,480,882,960,0};
00074 int ret, framesize, jsflag, samplerate;
00075 uint32_t codec_params;
00076 int16_t eid;
00077 uint8_t buf[EA3_HEADER_SIZE];
00078 uint8_t *edata;
00079 AVStream *st;
00080
00081 ff_id3v2_read(s, ID3v2_EA3_MAGIC);
00082 ret = avio_read(s->pb, buf, EA3_HEADER_SIZE);
00083 if (ret < EA3_HEADER_SIZE)
00084 return -1;
00085
00086 if (memcmp(buf, ((const uint8_t[]){'E', 'A', '3'}),3) || buf[4] != 0 || buf[5] != EA3_HEADER_SIZE) {
00087 av_log(s, AV_LOG_ERROR, "Couldn't find the EA3 header !\n");
00088 return -1;
00089 }
00090
00091 eid = AV_RB16(&buf[6]);
00092 if (eid != -1 && eid != -128) {
00093 av_log(s, AV_LOG_ERROR, "Encrypted file! Eid: %d\n", eid);
00094 return -1;
00095 }
00096
00097 codec_params = AV_RB24(&buf[33]);
00098
00099 st = av_new_stream(s, 0);
00100 if (!st)
00101 return AVERROR(ENOMEM);
00102
00103 st->start_time = 0;
00104 st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
00105 st->codec->codec_tag = buf[32];
00106 st->codec->codec_id = ff_codec_get_id(codec_oma_tags, st->codec->codec_tag);
00107
00108 switch (buf[32]) {
00109 case OMA_CODECID_ATRAC3:
00110 samplerate = srate_tab[(codec_params >> 13) & 7]*100;
00111 if (samplerate != 44100)
00112 av_log_ask_for_sample(s, "Unsupported sample rate: %d\n",
00113 samplerate);
00114
00115 framesize = (codec_params & 0x3FF) * 8;
00116 jsflag = (codec_params >> 17) & 1;
00117 st->codec->channels = 2;
00118 st->codec->sample_rate = samplerate;
00119 st->codec->bit_rate = st->codec->sample_rate * framesize * 8 / 1024;
00120
00121
00122 st->codec->extradata_size = 14;
00123 edata = av_mallocz(14 + FF_INPUT_BUFFER_PADDING_SIZE);
00124 if (!edata)
00125 return AVERROR(ENOMEM);
00126
00127 st->codec->extradata = edata;
00128 AV_WL16(&edata[0], 1);
00129 AV_WL32(&edata[2], samplerate);
00130 AV_WL16(&edata[6], jsflag);
00131 AV_WL16(&edata[8], jsflag);
00132 AV_WL16(&edata[10], 1);
00133
00134
00135 av_set_pts_info(st, 64, 1, st->codec->sample_rate);
00136 break;
00137 case OMA_CODECID_ATRAC3P:
00138 st->codec->channels = (codec_params >> 10) & 7;
00139 framesize = ((codec_params & 0x3FF) * 8) + 8;
00140 st->codec->sample_rate = srate_tab[(codec_params >> 13) & 7]*100;
00141 st->codec->bit_rate = st->codec->sample_rate * framesize * 8 / 1024;
00142 av_set_pts_info(st, 64, 1, st->codec->sample_rate);
00143 av_log(s, AV_LOG_ERROR, "Unsupported codec ATRAC3+!\n");
00144 break;
00145 case OMA_CODECID_MP3:
00146 st->need_parsing = AVSTREAM_PARSE_FULL;
00147 framesize = 1024;
00148 break;
00149 default:
00150 av_log(s, AV_LOG_ERROR, "Unsupported codec %d!\n",buf[32]);
00151 return -1;
00152 break;
00153 }
00154
00155 st->codec->block_align = framesize;
00156
00157 return 0;
00158 }
00159
00160
00161 static int oma_read_packet(AVFormatContext *s, AVPacket *pkt)
00162 {
00163 int ret = av_get_packet(s->pb, pkt, s->streams[0]->codec->block_align);
00164
00165 pkt->stream_index = 0;
00166 if (ret <= 0)
00167 return AVERROR(EIO);
00168
00169 return ret;
00170 }
00171
00172 static int oma_read_probe(AVProbeData *p)
00173 {
00174 const uint8_t *buf;
00175 unsigned tag_len = 0;
00176
00177 buf = p->buf;
00178
00179 if (ff_id3v2_match(buf, ID3v2_EA3_MAGIC) && buf[3] == 3 && !buf[4])
00180 tag_len = ff_id3v2_tag_len(buf);
00181
00182
00183 if (p->buf_size < tag_len + 5)
00184 return 0;
00185
00186 buf += tag_len;
00187
00188 if (!memcmp(buf, "EA3", 3) && !buf[4] && buf[5] == EA3_HEADER_SIZE)
00189 return AVPROBE_SCORE_MAX;
00190 else
00191 return 0;
00192 }
00193
00194
00195 AVInputFormat ff_oma_demuxer = {
00196 "oma",
00197 NULL_IF_CONFIG_SMALL("Sony OpenMG audio"),
00198 0,
00199 oma_read_probe,
00200 oma_read_header,
00201 oma_read_packet,
00202 0,
00203 pcm_read_seek,
00204 .flags= AVFMT_GENERIC_INDEX,
00205 .extensions = "oma,aa3",
00206 .codec_tag= (const AVCodecTag* const []){codec_oma_tags, 0},
00207 };
00208