| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Sony OpenMG (OMA) demuxer | 2 * Sony OpenMG (OMA) demuxer |
| 3 * | 3 * |
| 4 * Copyright (c) 2008 Maxim Poliakovski | 4 * Copyright (c) 2008 Maxim Poliakovski |
| 5 * 2008 Benjamin Larsson | 5 * 2008 Benjamin Larsson |
| 6 * | 6 * |
| 7 * This file is part of FFmpeg. | 7 * This file is part of FFmpeg. |
| 8 * | 8 * |
| 9 * FFmpeg is free software; you can redistribute it and/or | 9 * FFmpeg is free software; you can redistribute it and/or |
| 10 * modify it under the terms of the GNU Lesser General Public | 10 * modify it under the terms of the GNU Lesser General Public |
| 11 * License as published by the Free Software Foundation; either | 11 * License as published by the Free Software Foundation; either |
| 12 * version 2.1 of the License, or (at your option) any later version. | 12 * version 2.1 of the License, or (at your option) any later version. |
| 13 * | 13 * |
| 14 * FFmpeg is distributed in the hope that it will be useful, | 14 * FFmpeg is distributed in the hope that it will be useful, |
| 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 17 * Lesser General Public License for more details. | 17 * Lesser General Public License for more details. |
| 18 * | 18 * |
| 19 * You should have received a copy of the GNU Lesser General Public | 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 | 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 | 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 22 */ | 22 */ |
| 23 | 23 |
| 24 /** | 24 /** |
| 25 * @file | 25 * @file |
| 26 * This is a demuxer for Sony OpenMG Music files | 26 * This is a demuxer for Sony OpenMG Music files |
| 27 * | 27 * |
| 28 * Known file extensions: ".oma", "aa3" | 28 * Known file extensions: ".oma", "aa3" |
| 29 * The format of such files consists of three parts: | 29 * The format of such files consists of three parts: |
| 30 * - "ea3" header carrying overall info and metadata. | 30 * - "ea3" header carrying overall info and metadata. Except for starting with |
| 31 * "ea" instead of "ID", it's an ID3v2 header. |
| 31 * - "EA3" header is a Sony-specific header containing information about | 32 * - "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 * 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 * codec specific info (packet size, sample rate, channels and so on) |
| 34 * and DRM related info (file encryption, content id). | 35 * and DRM related info (file encryption, content id). |
| 35 * - Sound data organized in packets follow the EA3 header | 36 * - Sound data organized in packets follow the EA3 header |
| 36 * (can be encrypted using the Sony DRM!). | 37 * (can be encrypted using the Sony DRM!). |
| 37 * | 38 * |
| 38 * LIMITATIONS: This version supports only plain (unencrypted) OMA files. | 39 * LIMITATIONS: This version supports only plain (unencrypted) OMA files. |
| 39 * If any DRM-protected (encrypted) file is encountered you will get the | 40 * If any DRM-protected (encrypted) file is encountered you will get the |
| 40 * corresponding error message. Try to remove the encryption using any | 41 * corresponding error message. Try to remove the encryption using any |
| 41 * Sony software (for example SonicStage). | 42 * Sony software (for example SonicStage). |
| 42 * CODEC SUPPORT: Only ATRAC3 codec is currently supported! | 43 * CODEC SUPPORT: Only ATRAC3 codec is currently supported! |
| 43 */ | 44 */ |
| 44 | 45 |
| 45 #include "avformat.h" | 46 #include "avformat.h" |
| 46 #include "libavutil/intreadwrite.h" | 47 #include "libavutil/intreadwrite.h" |
| 47 #include "raw.h" | 48 #include "raw.h" |
| 48 #include "riff.h" | 49 #include "riff.h" |
| 50 #include "id3v2.h" |
| 49 | 51 |
| 50 #define EA3_HEADER_SIZE 96 | 52 #define EA3_HEADER_SIZE 96 |
| 51 | 53 |
| 52 enum { | 54 enum { |
| 53 OMA_CODECID_ATRAC3 = 0, | 55 OMA_CODECID_ATRAC3 = 0, |
| 54 OMA_CODECID_ATRAC3P = 1, | 56 OMA_CODECID_ATRAC3P = 1, |
| 55 OMA_CODECID_MP3 = 3, | 57 OMA_CODECID_MP3 = 3, |
| 56 OMA_CODECID_LPCM = 4, | 58 OMA_CODECID_LPCM = 4, |
| 57 OMA_CODECID_WMA = 5, | 59 OMA_CODECID_WMA = 5, |
| 58 }; | 60 }; |
| 59 | 61 |
| 60 static const AVCodecTag codec_oma_tags[] = { | 62 static const AVCodecTag codec_oma_tags[] = { |
| 61 { CODEC_ID_ATRAC3, OMA_CODECID_ATRAC3 }, | 63 { CODEC_ID_ATRAC3, OMA_CODECID_ATRAC3 }, |
| 62 { CODEC_ID_ATRAC3P, OMA_CODECID_ATRAC3P }, | 64 { CODEC_ID_ATRAC3P, OMA_CODECID_ATRAC3P }, |
| 63 { CODEC_ID_MP3, OMA_CODECID_MP3 }, | 65 { CODEC_ID_MP3, OMA_CODECID_MP3 }, |
| 64 }; | 66 }; |
| 65 | 67 |
| 68 #define ID3v2_EA3_MAGIC "ea3" |
| 69 |
| 66 static int oma_read_header(AVFormatContext *s, | 70 static int oma_read_header(AVFormatContext *s, |
| 67 AVFormatParameters *ap) | 71 AVFormatParameters *ap) |
| 68 { | 72 { |
| 69 static const uint16_t srate_tab[6] = {320,441,480,882,960,0}; | 73 static const uint16_t srate_tab[6] = {320,441,480,882,960,0}; |
| 70 int ret, ea3_taglen, EA3_pos, framesize, jsflag, samplerate; | 74 int ret, framesize, jsflag, samplerate; |
| 71 uint32_t codec_params; | 75 uint32_t codec_params; |
| 72 int16_t eid; | 76 int16_t eid; |
| 73 uint8_t buf[EA3_HEADER_SIZE]; | 77 uint8_t buf[EA3_HEADER_SIZE]; |
| 74 uint8_t *edata; | 78 uint8_t *edata; |
| 75 AVStream *st; | 79 AVStream *st; |
| 76 | 80 |
| 77 ret = get_buffer(s->pb, buf, 10); | 81 ff_id3v2_read(s, ID3v2_EA3_MAGIC); |
| 78 if (ret != 10) | 82 ret = get_buffer(s->pb, buf, EA3_HEADER_SIZE); |
| 79 return -1; | |
| 80 | |
| 81 if(!memcmp(buf, "ea3", 3)) { | |
| 82 ea3_taglen = ((buf[6] & 0x7f) << 21) | ((buf[7] & 0x7f) << 14) | ((buf[8
] & 0x7f) << 7) | (buf[9] & 0x7f); | |
| 83 | |
| 84 EA3_pos = ea3_taglen + 10; | |
| 85 if (buf[5] & 0x10) | |
| 86 EA3_pos += 10; | |
| 87 | |
| 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; | |
| 92 } else { | |
| 93 ret = get_buffer(s->pb, buf + 10, EA3_HEADER_SIZE - 10); | |
| 94 EA3_pos = 0; | |
| 95 } | |
| 96 | 83 |
| 97 if (memcmp(buf, ((const uint8_t[]){'E', 'A', '3'}),3) || buf[4] != 0 || buf[
5] != EA3_HEADER_SIZE) { | 84 if (memcmp(buf, ((const uint8_t[]){'E', 'A', '3'}),3) || buf[4] != 0 || buf[
5] != EA3_HEADER_SIZE) { |
| 98 av_log(s, AV_LOG_ERROR, "Couldn't find the EA3 header !\n"); | 85 av_log(s, AV_LOG_ERROR, "Couldn't find the EA3 header !\n"); |
| 99 return -1; | 86 return -1; |
| 100 } | 87 } |
| 101 | 88 |
| 102 eid = AV_RB16(&buf[6]); | 89 eid = AV_RB16(&buf[6]); |
| 103 if (eid != -1 && eid != -128) { | 90 if (eid != -1 && eid != -128) { |
| 104 av_log(s, AV_LOG_ERROR, "Encrypted file! Eid: %d\n", eid); | 91 av_log(s, AV_LOG_ERROR, "Encrypted file! Eid: %d\n", eid); |
| 105 return -1; | 92 return -1; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 156 st->need_parsing = AVSTREAM_PARSE_FULL; | 143 st->need_parsing = AVSTREAM_PARSE_FULL; |
| 157 framesize = 1024; | 144 framesize = 1024; |
| 158 break; | 145 break; |
| 159 default: | 146 default: |
| 160 av_log(s, AV_LOG_ERROR, "Unsupported codec %d!\n",buf[32]); | 147 av_log(s, AV_LOG_ERROR, "Unsupported codec %d!\n",buf[32]); |
| 161 return -1; | 148 return -1; |
| 162 break; | 149 break; |
| 163 } | 150 } |
| 164 | 151 |
| 165 st->codec->block_align = framesize; | 152 st->codec->block_align = framesize; |
| 166 url_fseek(s->pb, EA3_pos + EA3_HEADER_SIZE, SEEK_SET); | |
| 167 | 153 |
| 168 return 0; | 154 return 0; |
| 169 } | 155 } |
| 170 | 156 |
| 171 | 157 |
| 172 static int oma_read_packet(AVFormatContext *s, AVPacket *pkt) | 158 static int oma_read_packet(AVFormatContext *s, AVPacket *pkt) |
| 173 { | 159 { |
| 174 int ret = av_get_packet(s->pb, pkt, s->streams[0]->codec->block_align); | 160 int ret = av_get_packet(s->pb, pkt, s->streams[0]->codec->block_align); |
| 175 | 161 |
| 176 pkt->stream_index = 0; | 162 pkt->stream_index = 0; |
| 177 if (ret <= 0) | 163 if (ret <= 0) |
| 178 return AVERROR(EIO); | 164 return AVERROR(EIO); |
| 179 | 165 |
| 180 return ret; | 166 return ret; |
| 181 } | 167 } |
| 182 | 168 |
| 183 static int oma_read_probe(AVProbeData *p) | 169 static int oma_read_probe(AVProbeData *p) |
| 184 { | 170 { |
| 185 if (!memcmp(p->buf, ((const uint8_t[]){'e', 'a', '3', 3, 0}), 5) || | 171 const uint8_t *buf; |
| 186 (!memcmp(p->buf, "EA3", 3) && | 172 unsigned tag_len = 0; |
| 187 !p->buf[4] && p->buf[5] == EA3_HEADER_SIZE)) | 173 |
| 174 buf = p->buf; |
| 175 /* version must be 3 and flags byte zero */ |
| 176 if (ff_id3v2_match(buf, ID3v2_EA3_MAGIC) && buf[3] == 3 && !buf[4]) |
| 177 tag_len = ff_id3v2_tag_len(buf); |
| 178 |
| 179 // This check cannot overflow as tag_len has at most 28 bits |
| 180 if (p->buf_size < tag_len + 5) |
| 181 return 0; |
| 182 |
| 183 buf += tag_len; |
| 184 |
| 185 if (!memcmp(buf, "EA3", 3) && !buf[4] && buf[5] == EA3_HEADER_SIZE) |
| 188 return AVPROBE_SCORE_MAX; | 186 return AVPROBE_SCORE_MAX; |
| 189 else | 187 else |
| 190 return 0; | 188 return 0; |
| 191 } | 189 } |
| 192 | 190 |
| 193 | 191 |
| 194 AVInputFormat oma_demuxer = { | 192 AVInputFormat oma_demuxer = { |
| 195 "oma", | 193 "oma", |
| 196 NULL_IF_CONFIG_SMALL("Sony OpenMG audio"), | 194 NULL_IF_CONFIG_SMALL("Sony OpenMG audio"), |
| 197 0, | 195 0, |
| 198 oma_read_probe, | 196 oma_read_probe, |
| 199 oma_read_header, | 197 oma_read_header, |
| 200 oma_read_packet, | 198 oma_read_packet, |
| 201 0, | 199 0, |
| 202 pcm_read_seek, | 200 pcm_read_seek, |
| 203 .flags= AVFMT_GENERIC_INDEX, | 201 .flags= AVFMT_GENERIC_INDEX, |
| 204 .extensions = "oma,aa3", | 202 .extensions = "oma,aa3", |
| 205 .codec_tag= (const AVCodecTag* const []){codec_oma_tags, 0}, | 203 .codec_tag= (const AVCodecTag* const []){codec_oma_tags, 0}, |
| 204 .metadata_conv = ff_id3v2_metadata_conv, |
| 206 }; | 205 }; |
| 207 | 206 |
| OLD | NEW |