annotate ffmpeg/libavformat/omadec.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents f445c3017523
children
rev   line source
yading@11 1 /*
yading@11 2 * Sony OpenMG (OMA) demuxer
yading@11 3 *
yading@11 4 * Copyright (c) 2008 Maxim Poliakovski
yading@11 5 * 2008 Benjamin Larsson
yading@11 6 * 2011 David Goldwich
yading@11 7 *
yading@11 8 * This file is part of FFmpeg.
yading@11 9 *
yading@11 10 * FFmpeg is free software; you can redistribute it and/or
yading@11 11 * modify it under the terms of the GNU Lesser General Public
yading@11 12 * License as published by the Free Software Foundation; either
yading@11 13 * version 2.1 of the License, or (at your option) any later version.
yading@11 14 *
yading@11 15 * FFmpeg is distributed in the hope that it will be useful,
yading@11 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@11 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@11 18 * Lesser General Public License for more details.
yading@11 19 *
yading@11 20 * You should have received a copy of the GNU Lesser General Public
yading@11 21 * License along with FFmpeg; if not, write to the Free Software
yading@11 22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@11 23 */
yading@11 24
yading@11 25 /**
yading@11 26 * @file
yading@11 27 * This is a demuxer for Sony OpenMG Music files
yading@11 28 *
yading@11 29 * Known file extensions: ".oma", "aa3"
yading@11 30 * The format of such files consists of three parts:
yading@11 31 * - "ea3" header carrying overall info and metadata. Except for starting with
yading@11 32 * "ea" instead of "ID", it's an ID3v2 header.
yading@11 33 * - "EA3" header is a Sony-specific header containing information about
yading@11 34 * the OpenMG file: codec type (usually ATRAC, can also be MP3 or WMA),
yading@11 35 * codec specific info (packet size, sample rate, channels and so on)
yading@11 36 * and DRM related info (file encryption, content id).
yading@11 37 * - Sound data organized in packets follow the EA3 header
yading@11 38 * (can be encrypted using the Sony DRM!).
yading@11 39 *
yading@11 40 */
yading@11 41
yading@11 42 #include "libavutil/channel_layout.h"
yading@11 43 #include "avformat.h"
yading@11 44 #include "internal.h"
yading@11 45 #include "libavutil/intreadwrite.h"
yading@11 46 #include "libavutil/des.h"
yading@11 47 #include "oma.h"
yading@11 48 #include "pcm.h"
yading@11 49 #include "id3v2.h"
yading@11 50
yading@11 51
yading@11 52 static const uint64_t leaf_table[] = {
yading@11 53 0xd79e8283acea4620, 0x7a9762f445afd0d8,
yading@11 54 0x354d60a60b8c79f1, 0x584e1cde00b07aee,
yading@11 55 0x1573cd93da7df623, 0x47f98d79620dd535
yading@11 56 };
yading@11 57
yading@11 58 typedef struct OMAContext {
yading@11 59 uint64_t content_start;
yading@11 60 int encrypted;
yading@11 61 uint16_t k_size;
yading@11 62 uint16_t e_size;
yading@11 63 uint16_t i_size;
yading@11 64 uint16_t s_size;
yading@11 65 uint32_t rid;
yading@11 66 uint8_t r_val[24];
yading@11 67 uint8_t n_val[24];
yading@11 68 uint8_t m_val[8];
yading@11 69 uint8_t s_val[8];
yading@11 70 uint8_t sm_val[8];
yading@11 71 uint8_t e_val[8];
yading@11 72 uint8_t iv[8];
yading@11 73 struct AVDES av_des;
yading@11 74 } OMAContext;
yading@11 75
yading@11 76 static void hex_log(AVFormatContext *s, int level, const char *name, const uint8_t *value, int len)
yading@11 77 {
yading@11 78 char buf[33];
yading@11 79 len = FFMIN(len, 16);
yading@11 80 if (av_log_get_level() < level)
yading@11 81 return;
yading@11 82 ff_data_to_hex(buf, value, len, 1);
yading@11 83 buf[len<<1] = '\0';
yading@11 84 av_log(s, level, "%s: %s\n", name, buf);
yading@11 85 }
yading@11 86
yading@11 87 static int kset(AVFormatContext *s, const uint8_t *r_val, const uint8_t *n_val, int len)
yading@11 88 {
yading@11 89 OMAContext *oc = s->priv_data;
yading@11 90
yading@11 91 if (!r_val && !n_val)
yading@11 92 return -1;
yading@11 93
yading@11 94 len = FFMIN(len, 16);
yading@11 95
yading@11 96 /* use first 64 bits in the third round again */
yading@11 97 if (r_val) {
yading@11 98 if (r_val != oc->r_val) {
yading@11 99 memset(oc->r_val, 0, 24);
yading@11 100 memcpy(oc->r_val, r_val, len);
yading@11 101 }
yading@11 102 memcpy(&oc->r_val[16], r_val, 8);
yading@11 103 }
yading@11 104 if (n_val) {
yading@11 105 if (n_val != oc->n_val) {
yading@11 106 memset(oc->n_val, 0, 24);
yading@11 107 memcpy(oc->n_val, n_val, len);
yading@11 108 }
yading@11 109 memcpy(&oc->n_val[16], n_val, 8);
yading@11 110 }
yading@11 111
yading@11 112 return 0;
yading@11 113 }
yading@11 114
yading@11 115 static int rprobe(AVFormatContext *s, uint8_t *enc_header, const uint8_t *r_val)
yading@11 116 {
yading@11 117 OMAContext *oc = s->priv_data;
yading@11 118 unsigned int pos;
yading@11 119 struct AVDES av_des;
yading@11 120
yading@11 121 if (!enc_header || !r_val)
yading@11 122 return -1;
yading@11 123
yading@11 124 /* m_val */
yading@11 125 av_des_init(&av_des, r_val, 192, 1);
yading@11 126 av_des_crypt(&av_des, oc->m_val, &enc_header[48], 1, NULL, 1);
yading@11 127
yading@11 128 /* s_val */
yading@11 129 av_des_init(&av_des, oc->m_val, 64, 0);
yading@11 130 av_des_crypt(&av_des, oc->s_val, NULL, 1, NULL, 0);
yading@11 131
yading@11 132 /* sm_val */
yading@11 133 pos = OMA_ENC_HEADER_SIZE + oc->k_size + oc->e_size;
yading@11 134 av_des_init(&av_des, oc->s_val, 64, 0);
yading@11 135 av_des_mac(&av_des, oc->sm_val, &enc_header[pos], (oc->i_size >> 3));
yading@11 136
yading@11 137 pos += oc->i_size;
yading@11 138
yading@11 139 return memcmp(&enc_header[pos], oc->sm_val, 8) ? -1 : 0;
yading@11 140 }
yading@11 141
yading@11 142 static int nprobe(AVFormatContext *s, uint8_t *enc_header, int size, const uint8_t *n_val)
yading@11 143 {
yading@11 144 OMAContext *oc = s->priv_data;
yading@11 145 uint32_t pos, taglen, datalen;
yading@11 146 struct AVDES av_des;
yading@11 147
yading@11 148 if (!enc_header || !n_val)
yading@11 149 return -1;
yading@11 150
yading@11 151 pos = OMA_ENC_HEADER_SIZE + oc->k_size;
yading@11 152 if (!memcmp(&enc_header[pos], "EKB ", 4))
yading@11 153 pos += 32;
yading@11 154
yading@11 155 if (AV_RB32(&enc_header[pos]) != oc->rid)
yading@11 156 av_log(s, AV_LOG_DEBUG, "Mismatching RID\n");
yading@11 157
yading@11 158 taglen = AV_RB32(&enc_header[pos+32]);
yading@11 159 datalen = AV_RB32(&enc_header[pos+36]) >> 4;
yading@11 160
yading@11 161 if(pos + (uint64_t)taglen + (((uint64_t)datalen)<<4) + 44 > size)
yading@11 162 return -1;
yading@11 163
yading@11 164 pos += 44 + taglen;
yading@11 165
yading@11 166 av_des_init(&av_des, n_val, 192, 1);
yading@11 167 while (datalen-- > 0) {
yading@11 168 av_des_crypt(&av_des, oc->r_val, &enc_header[pos], 2, NULL, 1);
yading@11 169 kset(s, oc->r_val, NULL, 16);
yading@11 170 if (!rprobe(s, enc_header, oc->r_val))
yading@11 171 return 0;
yading@11 172 pos += 16;
yading@11 173 }
yading@11 174
yading@11 175 return -1;
yading@11 176 }
yading@11 177
yading@11 178 static int decrypt_init(AVFormatContext *s, ID3v2ExtraMeta *em, uint8_t *header)
yading@11 179 {
yading@11 180 OMAContext *oc = s->priv_data;
yading@11 181 ID3v2ExtraMetaGEOB *geob = NULL;
yading@11 182 uint8_t *gdata;
yading@11 183
yading@11 184 oc->encrypted = 1;
yading@11 185 av_log(s, AV_LOG_INFO, "File is encrypted\n");
yading@11 186
yading@11 187 /* find GEOB metadata */
yading@11 188 while (em) {
yading@11 189 if (!strcmp(em->tag, "GEOB") &&
yading@11 190 (geob = em->data) &&
yading@11 191 (!strcmp(geob->description, "OMG_LSI") ||
yading@11 192 !strcmp(geob->description, "OMG_BKLSI"))) {
yading@11 193 break;
yading@11 194 }
yading@11 195 em = em->next;
yading@11 196 }
yading@11 197 if (!em) {
yading@11 198 av_log(s, AV_LOG_ERROR, "No encryption header found\n");
yading@11 199 return -1;
yading@11 200 }
yading@11 201
yading@11 202 if (geob->datasize < 64) {
yading@11 203 av_log(s, AV_LOG_ERROR, "Invalid GEOB data size: %u\n", geob->datasize);
yading@11 204 return -1;
yading@11 205 }
yading@11 206
yading@11 207 gdata = geob->data;
yading@11 208
yading@11 209 if (AV_RB16(gdata) != 1)
yading@11 210 av_log(s, AV_LOG_WARNING, "Unknown version in encryption header\n");
yading@11 211
yading@11 212 oc->k_size = AV_RB16(&gdata[2]);
yading@11 213 oc->e_size = AV_RB16(&gdata[4]);
yading@11 214 oc->i_size = AV_RB16(&gdata[6]);
yading@11 215 oc->s_size = AV_RB16(&gdata[8]);
yading@11 216
yading@11 217 if (memcmp(&gdata[OMA_ENC_HEADER_SIZE], "KEYRING ", 12)) {
yading@11 218 av_log(s, AV_LOG_ERROR, "Invalid encryption header\n");
yading@11 219 return -1;
yading@11 220 }
yading@11 221 if ( OMA_ENC_HEADER_SIZE + oc->k_size + oc->e_size + oc->i_size + 8 > geob->datasize
yading@11 222 || OMA_ENC_HEADER_SIZE + 48 > geob->datasize
yading@11 223 ) {
yading@11 224 av_log(s, AV_LOG_ERROR, "Too little GEOB data\n");
yading@11 225 return AVERROR_INVALIDDATA;
yading@11 226 }
yading@11 227 oc->rid = AV_RB32(&gdata[OMA_ENC_HEADER_SIZE + 28]);
yading@11 228 av_log(s, AV_LOG_DEBUG, "RID: %.8x\n", oc->rid);
yading@11 229
yading@11 230 memcpy(oc->iv, &header[0x58], 8);
yading@11 231 hex_log(s, AV_LOG_DEBUG, "IV", oc->iv, 8);
yading@11 232
yading@11 233 hex_log(s, AV_LOG_DEBUG, "CBC-MAC", &gdata[OMA_ENC_HEADER_SIZE+oc->k_size+oc->e_size+oc->i_size], 8);
yading@11 234
yading@11 235 if (s->keylen > 0) {
yading@11 236 kset(s, s->key, s->key, s->keylen);
yading@11 237 }
yading@11 238 if (!memcmp(oc->r_val, (const uint8_t[8]){0}, 8) ||
yading@11 239 rprobe(s, gdata, oc->r_val) < 0 &&
yading@11 240 nprobe(s, gdata, geob->datasize, oc->n_val) < 0) {
yading@11 241 int i;
yading@11 242 for (i = 0; i < FF_ARRAY_ELEMS(leaf_table); i += 2) {
yading@11 243 uint8_t buf[16];
yading@11 244 AV_WL64(buf, leaf_table[i]);
yading@11 245 AV_WL64(&buf[8], leaf_table[i+1]);
yading@11 246 kset(s, buf, buf, 16);
yading@11 247 if (!rprobe(s, gdata, oc->r_val) || !nprobe(s, gdata, geob->datasize, oc->n_val))
yading@11 248 break;
yading@11 249 }
yading@11 250 if (i >= FF_ARRAY_ELEMS(leaf_table)) {
yading@11 251 av_log(s, AV_LOG_ERROR, "Invalid key\n");
yading@11 252 return -1;
yading@11 253 }
yading@11 254 }
yading@11 255
yading@11 256 /* e_val */
yading@11 257 av_des_init(&oc->av_des, oc->m_val, 64, 0);
yading@11 258 av_des_crypt(&oc->av_des, oc->e_val, &gdata[OMA_ENC_HEADER_SIZE + 40], 1, NULL, 0);
yading@11 259 hex_log(s, AV_LOG_DEBUG, "EK", oc->e_val, 8);
yading@11 260
yading@11 261 /* init e_val */
yading@11 262 av_des_init(&oc->av_des, oc->e_val, 64, 1);
yading@11 263
yading@11 264 return 0;
yading@11 265 }
yading@11 266
yading@11 267 static int oma_read_header(AVFormatContext *s)
yading@11 268 {
yading@11 269 int ret, framesize, jsflag, samplerate;
yading@11 270 uint32_t codec_params;
yading@11 271 int16_t eid;
yading@11 272 uint8_t buf[EA3_HEADER_SIZE];
yading@11 273 uint8_t *edata;
yading@11 274 AVStream *st;
yading@11 275 ID3v2ExtraMeta *extra_meta = NULL;
yading@11 276 OMAContext *oc = s->priv_data;
yading@11 277
yading@11 278 ff_id3v2_read(s, ID3v2_EA3_MAGIC, &extra_meta);
yading@11 279 ret = avio_read(s->pb, buf, EA3_HEADER_SIZE);
yading@11 280 if (ret < EA3_HEADER_SIZE)
yading@11 281 return -1;
yading@11 282
yading@11 283 if (memcmp(buf, ((const uint8_t[]){'E', 'A', '3'}),3) || buf[4] != 0 || buf[5] != EA3_HEADER_SIZE) {
yading@11 284 av_log(s, AV_LOG_ERROR, "Couldn't find the EA3 header !\n");
yading@11 285 return -1;
yading@11 286 }
yading@11 287
yading@11 288 oc->content_start = avio_tell(s->pb);
yading@11 289
yading@11 290 /* encrypted file */
yading@11 291 eid = AV_RB16(&buf[6]);
yading@11 292 if (eid != -1 && eid != -128 && decrypt_init(s, extra_meta, buf) < 0) {
yading@11 293 ff_id3v2_free_extra_meta(&extra_meta);
yading@11 294 return -1;
yading@11 295 }
yading@11 296
yading@11 297 ff_id3v2_free_extra_meta(&extra_meta);
yading@11 298
yading@11 299 codec_params = AV_RB24(&buf[33]);
yading@11 300
yading@11 301 st = avformat_new_stream(s, NULL);
yading@11 302 if (!st)
yading@11 303 return AVERROR(ENOMEM);
yading@11 304
yading@11 305 st->start_time = 0;
yading@11 306 st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
yading@11 307 st->codec->codec_tag = buf[32];
yading@11 308 st->codec->codec_id = ff_codec_get_id(ff_oma_codec_tags, st->codec->codec_tag);
yading@11 309
yading@11 310 switch (buf[32]) {
yading@11 311 case OMA_CODECID_ATRAC3:
yading@11 312 samplerate = ff_oma_srate_tab[(codec_params >> 13) & 7] * 100;
yading@11 313 if (!samplerate) {
yading@11 314 av_log(s, AV_LOG_ERROR, "Unsupported sample rate\n");
yading@11 315 return AVERROR_INVALIDDATA;
yading@11 316 }
yading@11 317 if (samplerate != 44100)
yading@11 318 avpriv_request_sample(s, "Sample rate %d", samplerate);
yading@11 319
yading@11 320 framesize = (codec_params & 0x3FF) * 8;
yading@11 321 jsflag = (codec_params >> 17) & 1; /* get stereo coding mode, 1 for joint-stereo */
yading@11 322 st->codec->channels = 2;
yading@11 323 st->codec->channel_layout = AV_CH_LAYOUT_STEREO;
yading@11 324 st->codec->sample_rate = samplerate;
yading@11 325 st->codec->bit_rate = st->codec->sample_rate * framesize * 8 / 1024;
yading@11 326
yading@11 327 /* fake the atrac3 extradata (wav format, makes stream copy to wav work) */
yading@11 328 st->codec->extradata_size = 14;
yading@11 329 edata = av_mallocz(14 + FF_INPUT_BUFFER_PADDING_SIZE);
yading@11 330 if (!edata)
yading@11 331 return AVERROR(ENOMEM);
yading@11 332
yading@11 333 st->codec->extradata = edata;
yading@11 334 AV_WL16(&edata[0], 1); // always 1
yading@11 335 AV_WL32(&edata[2], samplerate); // samples rate
yading@11 336 AV_WL16(&edata[6], jsflag); // coding mode
yading@11 337 AV_WL16(&edata[8], jsflag); // coding mode
yading@11 338 AV_WL16(&edata[10], 1); // always 1
yading@11 339 // AV_WL16(&edata[12], 0); // always 0
yading@11 340
yading@11 341 avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
yading@11 342 break;
yading@11 343 case OMA_CODECID_ATRAC3P:
yading@11 344 st->codec->channels = (codec_params >> 10) & 7;
yading@11 345 framesize = ((codec_params & 0x3FF) * 8) + 8;
yading@11 346 samplerate = ff_oma_srate_tab[(codec_params >> 13) & 7] * 100;
yading@11 347 if (!samplerate) {
yading@11 348 av_log(s, AV_LOG_ERROR, "Unsupported sample rate\n");
yading@11 349 return AVERROR_INVALIDDATA;
yading@11 350 }
yading@11 351 st->codec->sample_rate = samplerate;
yading@11 352 st->codec->bit_rate = samplerate * framesize * 8 / 1024;
yading@11 353 avpriv_set_pts_info(st, 64, 1, samplerate);
yading@11 354 av_log(s, AV_LOG_ERROR, "Unsupported codec ATRAC3+!\n");
yading@11 355 break;
yading@11 356 case OMA_CODECID_MP3:
yading@11 357 st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
yading@11 358 framesize = 1024;
yading@11 359 break;
yading@11 360 case OMA_CODECID_LPCM:
yading@11 361 /* PCM 44.1 kHz 16 bit stereo big-endian */
yading@11 362 st->codec->channels = 2;
yading@11 363 st->codec->channel_layout = AV_CH_LAYOUT_STEREO;
yading@11 364 st->codec->sample_rate = 44100;
yading@11 365 framesize = 1024;
yading@11 366 /* bit rate = sample rate x PCM block align (= 4) x 8 */
yading@11 367 st->codec->bit_rate = st->codec->sample_rate * 32;
yading@11 368 st->codec->bits_per_coded_sample = av_get_bits_per_sample(st->codec->codec_id);
yading@11 369 avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
yading@11 370 break;
yading@11 371 default:
yading@11 372 av_log(s, AV_LOG_ERROR, "Unsupported codec %d!\n",buf[32]);
yading@11 373 return -1;
yading@11 374 }
yading@11 375
yading@11 376 st->codec->block_align = framesize;
yading@11 377
yading@11 378 return 0;
yading@11 379 }
yading@11 380
yading@11 381
yading@11 382 static int oma_read_packet(AVFormatContext *s, AVPacket *pkt)
yading@11 383 {
yading@11 384 OMAContext *oc = s->priv_data;
yading@11 385 int packet_size = s->streams[0]->codec->block_align;
yading@11 386 int ret = av_get_packet(s->pb, pkt, packet_size);
yading@11 387
yading@11 388 if (ret <= 0)
yading@11 389 return AVERROR(EIO);
yading@11 390
yading@11 391 pkt->stream_index = 0;
yading@11 392
yading@11 393 if (oc->encrypted) {
yading@11 394 /* previous unencrypted block saved in IV for the next packet (CBC mode) */
yading@11 395 av_des_crypt(&oc->av_des, pkt->data, pkt->data, (ret >> 3), oc->iv, 1);
yading@11 396 }
yading@11 397
yading@11 398 return ret;
yading@11 399 }
yading@11 400
yading@11 401 static int oma_read_probe(AVProbeData *p)
yading@11 402 {
yading@11 403 const uint8_t *buf;
yading@11 404 unsigned tag_len = 0;
yading@11 405
yading@11 406 buf = p->buf;
yading@11 407
yading@11 408 if (p->buf_size < ID3v2_HEADER_SIZE ||
yading@11 409 !ff_id3v2_match(buf, ID3v2_EA3_MAGIC) ||
yading@11 410 buf[3] != 3 || // version must be 3
yading@11 411 buf[4]) // flags byte zero
yading@11 412 return 0;
yading@11 413
yading@11 414 tag_len = ff_id3v2_tag_len(buf);
yading@11 415
yading@11 416 /* This check cannot overflow as tag_len has at most 28 bits */
yading@11 417 if (p->buf_size < tag_len + 5)
yading@11 418 /* EA3 header comes late, might be outside of the probe buffer */
yading@11 419 return AVPROBE_SCORE_MAX / 2;
yading@11 420
yading@11 421 buf += tag_len;
yading@11 422
yading@11 423 if (!memcmp(buf, "EA3", 3) && !buf[4] && buf[5] == EA3_HEADER_SIZE)
yading@11 424 return AVPROBE_SCORE_MAX;
yading@11 425 else
yading@11 426 return 0;
yading@11 427 }
yading@11 428
yading@11 429 static int oma_read_seek(struct AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
yading@11 430 {
yading@11 431 OMAContext *oc = s->priv_data;
yading@11 432
yading@11 433 ff_pcm_read_seek(s, stream_index, timestamp, flags);
yading@11 434
yading@11 435 if (oc->encrypted) {
yading@11 436 /* readjust IV for CBC */
yading@11 437 int64_t pos = avio_tell(s->pb);
yading@11 438 if (pos < oc->content_start)
yading@11 439 memset(oc->iv, 0, 8);
yading@11 440 else {
yading@11 441 if (avio_seek(s->pb, -8, SEEK_CUR) < 0 || avio_read(s->pb, oc->iv, 8) < 8) {
yading@11 442 memset(oc->iv, 0, 8);
yading@11 443 return -1;
yading@11 444 }
yading@11 445 }
yading@11 446 }
yading@11 447
yading@11 448 return 0;
yading@11 449 }
yading@11 450
yading@11 451 AVInputFormat ff_oma_demuxer = {
yading@11 452 .name = "oma",
yading@11 453 .long_name = NULL_IF_CONFIG_SMALL("Sony OpenMG audio"),
yading@11 454 .priv_data_size = sizeof(OMAContext),
yading@11 455 .read_probe = oma_read_probe,
yading@11 456 .read_header = oma_read_header,
yading@11 457 .read_packet = oma_read_packet,
yading@11 458 .read_seek = oma_read_seek,
yading@11 459 .flags = AVFMT_GENERIC_INDEX,
yading@11 460 .extensions = "oma,omg,aa3",
yading@11 461 .codec_tag = (const AVCodecTag* const []){ff_oma_codec_tags, 0},
yading@11 462 };