Libav 0.7.1
libavformat/oma.c
Go to the documentation of this file.
00001 /*
00002  * Sony OpenMG (OMA) demuxer
00003  *
00004  * Copyright (c) 2008 Maxim Poliakovski
00005  *               2008 Benjamin Larsson
00006  *
00007  * This file is part of Libav.
00008  *
00009  * Libav is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU Lesser General Public
00011  * License as published by the Free Software Foundation; either
00012  * version 2.1 of the License, or (at your option) any later version.
00013  *
00014  * Libav is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017  * Lesser General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU Lesser General Public
00020  * License along with Libav; if not, write to the Free Software
00021  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
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; /* get stereo coding mode, 1 for joint-stereo */
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             /* fake the atrac3 extradata (wav format, makes stream copy to wav work) */
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);             // always 1
00129             AV_WL32(&edata[2],  samplerate);    // samples rate
00130             AV_WL16(&edata[6],  jsflag);        // coding mode
00131             AV_WL16(&edata[8],  jsflag);        // coding mode
00132             AV_WL16(&edata[10], 1);             // always 1
00133             // AV_WL16(&edata[12], 0);          // always 0
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     /* version must be 3 and flags byte zero */
00179     if (ff_id3v2_match(buf, ID3v2_EA3_MAGIC) && buf[3] == 3 && !buf[4])
00180         tag_len = ff_id3v2_tag_len(buf);
00181 
00182     // This check cannot overflow as tag_len has at most 28 bits
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