omadec.c 18 KB
Newer Older
Benjamin Larsson's avatar
Benjamin Larsson committed
1 2 3
/*
 * Sony OpenMG (OMA) demuxer
 *
4
 * Copyright (c) 2008, 2013 Maxim Poliakovski
Benjamin Larsson's avatar
Benjamin Larsson committed
5
 *               2008 Benjamin Larsson
6
 *               2011 David Goldwich
Benjamin Larsson's avatar
Benjamin Larsson committed
7
 *
8
 * This file is part of FFmpeg.
Benjamin Larsson's avatar
Benjamin Larsson committed
9
 *
10
 * FFmpeg is free software; you can redistribute it and/or
Benjamin Larsson's avatar
Benjamin Larsson committed
11 12 13 14
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
15
 * FFmpeg is distributed in the hope that it will be useful,
Benjamin Larsson's avatar
Benjamin Larsson committed
16 17 18 19 20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
21
 * License along with FFmpeg; if not, write to the Free Software
Benjamin Larsson's avatar
Benjamin Larsson committed
22 23 24 25
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**
26
 * @file
Benjamin Larsson's avatar
Benjamin Larsson committed
27 28 29 30
 * This is a demuxer for Sony OpenMG Music files
 *
 * Known file extensions: ".oma", "aa3"
 * The format of such files consists of three parts:
31 32
 * - "ea3" header carrying overall info and metadata. Except for starting with
 *   "ea" instead of "ID", it's an ID3v2 header.
Benjamin Larsson's avatar
Benjamin Larsson committed
33 34 35 36 37 38 39
 * - "EA3" header is a Sony-specific header containing information about
 *   the OpenMG file: codec type (usually ATRAC, can also be MP3 or WMA),
 *   codec specific info (packet size, sample rate, channels and so on)
 *   and DRM related info (file encryption, content id).
 * - Sound data organized in packets follow the EA3 header
 *   (can be encrypted using the Sony DRM!).
 *
40
 * Supported decoders: ATRAC3, ATRAC3+, MP3, LPCM
Benjamin Larsson's avatar
Benjamin Larsson committed
41 42
 */

43 44
#include <inttypes.h>

45
#include "libavutil/channel_layout.h"
Benjamin Larsson's avatar
Benjamin Larsson committed
46
#include "avformat.h"
47
#include "internal.h"
Benjamin Larsson's avatar
Benjamin Larsson committed
48
#include "libavutil/intreadwrite.h"
49
#include "libavutil/des.h"
Luca Barbato's avatar
Luca Barbato committed
50
#include "libavutil/mathematics.h"
51
#include "oma.h"
52
#include "pcm.h"
53
#include "id3v2.h"
Benjamin Larsson's avatar
Benjamin Larsson committed
54 55


56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
static const uint64_t leaf_table[] = {
    0xd79e8283acea4620, 0x7a9762f445afd0d8,
    0x354d60a60b8c79f1, 0x584e1cde00b07aee,
    0x1573cd93da7df623, 0x47f98d79620dd535
};

typedef struct OMAContext {
    uint64_t content_start;
    int encrypted;
    uint16_t k_size;
    uint16_t e_size;
    uint16_t i_size;
    uint16_t s_size;
    uint32_t rid;
    uint8_t r_val[24];
    uint8_t n_val[24];
    uint8_t m_val[8];
    uint8_t s_val[8];
    uint8_t sm_val[8];
    uint8_t e_val[8];
    uint8_t iv[8];
77
    struct AVDES *av_des;
78 79

    int (*read_packet)(AVFormatContext *s, AVPacket *pkt);
80 81
} OMAContext;

82 83
static void hex_log(AVFormatContext *s, int level,
                    const char *name, const uint8_t *value, int len)
84 85 86 87 88 89
{
    char buf[33];
    len = FFMIN(len, 16);
    if (av_log_get_level() < level)
        return;
    ff_data_to_hex(buf, value, len, 1);
90
    buf[len << 1] = '\0';
91 92 93
    av_log(s, level, "%s: %s\n", name, buf);
}

94 95
static int kset(AVFormatContext *s, const uint8_t *r_val, const uint8_t *n_val,
                int len)
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
{
    OMAContext *oc = s->priv_data;

    if (!r_val && !n_val)
        return -1;

    len = FFMIN(len, 16);

    /* use first 64 bits in the third round again */
    if (r_val) {
        if (r_val != oc->r_val) {
            memset(oc->r_val, 0, 24);
            memcpy(oc->r_val, r_val, len);
        }
        memcpy(&oc->r_val[16], r_val, 8);
    }
    if (n_val) {
        if (n_val != oc->n_val) {
            memset(oc->n_val, 0, 24);
            memcpy(oc->n_val, n_val, len);
        }
        memcpy(&oc->n_val[16], n_val, 8);
    }

    return 0;
}

123 124 125 126
#define OMA_RPROBE_M_VAL 48 + 1

static int rprobe(AVFormatContext *s, uint8_t *enc_header, unsigned size,
                  const uint8_t *r_val)
127 128 129
{
    OMAContext *oc = s->priv_data;
    unsigned int pos;
130
    struct AVDES *av_des;
131

132 133 134
    if (!enc_header || !r_val ||
        size < OMA_ENC_HEADER_SIZE + oc->k_size + oc->e_size + oc->i_size ||
        size < OMA_RPROBE_M_VAL)
135 136
        return -1;

137 138 139 140
    av_des = av_des_alloc();
    if (!av_des)
        return AVERROR(ENOMEM);

141
    /* m_val */
142 143
    av_des_init(av_des, r_val, 192, 1);
    av_des_crypt(av_des, oc->m_val, &enc_header[48], 1, NULL, 1);
144 145

    /* s_val */
146 147
    av_des_init(av_des, oc->m_val, 64, 0);
    av_des_crypt(av_des, oc->s_val, NULL, 1, NULL, 0);
148 149 150

    /* sm_val */
    pos = OMA_ENC_HEADER_SIZE + oc->k_size + oc->e_size;
151 152
    av_des_init(av_des, oc->s_val, 64, 0);
    av_des_mac(av_des, oc->sm_val, &enc_header[pos], (oc->i_size >> 3));
153 154 155

    pos += oc->i_size;

156 157
    av_free(av_des);

158 159 160
    return memcmp(&enc_header[pos], oc->sm_val, 8) ? -1 : 0;
}

161
static int nprobe(AVFormatContext *s, uint8_t *enc_header, unsigned size,
162
                  const uint8_t *n_val)
163 164
{
    OMAContext *oc = s->priv_data;
165 166
    uint64_t pos;
    uint32_t taglen, datalen;
167
    struct AVDES *av_des;
168

169 170
    if (!enc_header || !n_val ||
        size < OMA_ENC_HEADER_SIZE + oc->k_size + 4)
171 172 173 174 175 176
        return -1;

    pos = OMA_ENC_HEADER_SIZE + oc->k_size;
    if (!memcmp(&enc_header[pos], "EKB ", 4))
        pos += 32;

177 178 179
    if (size < pos + 44)
        return -1;

180 181 182
    if (AV_RB32(&enc_header[pos]) != oc->rid)
        av_log(s, AV_LOG_DEBUG, "Mismatching RID\n");

183 184
    taglen  = AV_RB32(&enc_header[pos + 32]);
    datalen = AV_RB32(&enc_header[pos + 36]) >> 4;
185

186
    pos += 44LL + taglen;
187

188
    if (pos + (((uint64_t)datalen) << 4) > size)
189 190
        return -1;

191 192 193 194 195
    av_des = av_des_alloc();
    if (!av_des)
        return AVERROR(ENOMEM);

    av_des_init(av_des, n_val, 192, 1);
196
    while (datalen-- > 0) {
197
        av_des_crypt(av_des, oc->r_val, &enc_header[pos], 2, NULL, 1);
198 199
        kset(s, oc->r_val, NULL, 16);
        if (!rprobe(s, enc_header, size, oc->r_val)) {
200
            av_free(av_des);
201
            return 0;
202
        }
203 204 205
        pos += 16;
    }

206
    av_free(av_des);
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
    return -1;
}

static int decrypt_init(AVFormatContext *s, ID3v2ExtraMeta *em, uint8_t *header)
{
    OMAContext *oc = s->priv_data;
    ID3v2ExtraMetaGEOB *geob = NULL;
    uint8_t *gdata;

    oc->encrypted = 1;
    av_log(s, AV_LOG_INFO, "File is encrypted\n");

    /* find GEOB metadata */
    while (em) {
        if (!strcmp(em->tag, "GEOB") &&
            (geob = em->data) &&
223 224
            (!strcmp(geob->description, "OMG_LSI") ||
             !strcmp(geob->description, "OMG_BKLSI"))) {
225 226 227 228 229 230
            break;
        }
        em = em->next;
    }
    if (!em) {
        av_log(s, AV_LOG_ERROR, "No encryption header found\n");
231
        return AVERROR_INVALIDDATA;
232 233 234
    }

    if (geob->datasize < 64) {
235
        av_log(s, AV_LOG_ERROR,
236
               "Invalid GEOB data size: %"PRIu32"\n", geob->datasize);
237
        return AVERROR_INVALIDDATA;
238 239 240 241 242 243 244 245 246 247 248 249 250 251
    }

    gdata = geob->data;

    if (AV_RB16(gdata) != 1)
        av_log(s, AV_LOG_WARNING, "Unknown version in encryption header\n");

    oc->k_size = AV_RB16(&gdata[2]);
    oc->e_size = AV_RB16(&gdata[4]);
    oc->i_size = AV_RB16(&gdata[6]);
    oc->s_size = AV_RB16(&gdata[8]);

    if (memcmp(&gdata[OMA_ENC_HEADER_SIZE], "KEYRING     ", 12)) {
        av_log(s, AV_LOG_ERROR, "Invalid encryption header\n");
252
        return AVERROR_INVALIDDATA;
253
    }
254 255
    if (OMA_ENC_HEADER_SIZE + oc->k_size + oc->e_size + oc->i_size + 8 > geob->datasize ||
        OMA_ENC_HEADER_SIZE + 48 > geob->datasize) {
256 257 258
        av_log(s, AV_LOG_ERROR, "Too little GEOB data\n");
        return AVERROR_INVALIDDATA;
    }
259
    oc->rid = AV_RB32(&gdata[OMA_ENC_HEADER_SIZE + 28]);
260
    av_log(s, AV_LOG_DEBUG, "RID: %.8"PRIx32"\n", oc->rid);
261 262 263 264

    memcpy(oc->iv, &header[0x58], 8);
    hex_log(s, AV_LOG_DEBUG, "IV", oc->iv, 8);

265 266 267
    hex_log(s, AV_LOG_DEBUG, "CBC-MAC",
            &gdata[OMA_ENC_HEADER_SIZE + oc->k_size + oc->e_size + oc->i_size],
            8);
268 269 270 271 272

    if (s->keylen > 0) {
        kset(s, s->key, s->key, s->keylen);
    }
    if (!memcmp(oc->r_val, (const uint8_t[8]){0}, 8) ||
273
        rprobe(s, gdata, geob->datasize, oc->r_val) < 0 &&
274
        nprobe(s, gdata, geob->datasize, oc->n_val) < 0) {
275
        int i;
276
        for (i = 0; i < FF_ARRAY_ELEMS(leaf_table); i += 2) {
277
            uint8_t buf[16];
278 279
            AV_WL64(buf,     leaf_table[i]);
            AV_WL64(&buf[8], leaf_table[i + 1]);
280
            kset(s, buf, buf, 16);
281
            if (!rprobe(s, gdata, geob->datasize, oc->r_val) ||
282
                !nprobe(s, gdata, geob->datasize, oc->n_val))
283 284
                break;
        }
285
        if (i >= FF_ARRAY_ELEMS(leaf_table)) {
286
            av_log(s, AV_LOG_ERROR, "Invalid key\n");
287
            return AVERROR_INVALIDDATA;
288 289 290
        }
    }

291 292 293 294
    oc->av_des = av_des_alloc();
    if (!oc->av_des)
        return AVERROR(ENOMEM);

295
    /* e_val */
296 297
    av_des_init(oc->av_des, oc->m_val, 64, 0);
    av_des_crypt(oc->av_des, oc->e_val,
298
                 &gdata[OMA_ENC_HEADER_SIZE + 40], 1, NULL, 0);
299 300 301
    hex_log(s, AV_LOG_DEBUG, "EK", oc->e_val, 8);

    /* init e_val */
302
    av_des_init(oc->av_des, oc->e_val, 64, 1);
303 304 305

    return 0;
}
306

307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347
static int read_packet(AVFormatContext *s, AVPacket *pkt)
{
    OMAContext *oc  = s->priv_data;
    AVStream *st    = s->streams[0];
    int packet_size = st->codecpar->block_align;
    int byte_rate   = st->codecpar->bit_rate >> 3;
    int64_t pos     = avio_tell(s->pb);
    int ret         = av_get_packet(s->pb, pkt, packet_size);

    if (ret < packet_size)
        pkt->flags |= AV_PKT_FLAG_CORRUPT;

    if (ret < 0)
        return ret;
    if (!ret)
        return AVERROR_EOF;

    pkt->stream_index = 0;

    if (pos >= oc->content_start && byte_rate > 0) {
        pkt->pts =
        pkt->dts = av_rescale(pos - oc->content_start, st->time_base.den,
                              byte_rate * (int64_t)st->time_base.num);
    }

    if (oc->encrypted) {
        /* previous unencrypted block saved in IV for
         * the next packet (CBC mode) */
        if (ret == packet_size)
            av_des_crypt(oc->av_des, pkt->data, pkt->data,
                         (packet_size >> 3), oc->iv, 1);
        else
            memset(oc->iv, 0, 8);
    }

    return ret;
}

static int aal_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    int64_t pos = avio_tell(s->pb);
348
    int ret, pts;
349 350 351 352 353 354 355 356 357 358 359 360
    int packet_size;
    unsigned tag;

    if (avio_feof(s->pb))
        return AVERROR_EOF;

    tag = avio_rb24(s->pb);
    if (tag == 0)
        return AVERROR_EOF;
    else if (tag != MKBETAG(0,'B','L','K'))
        return AVERROR_INVALIDDATA;

361
    avio_skip(s->pb, 1);
362 363 364 365 366 367 368 369 370 371 372 373 374 375 376
    packet_size = avio_rb16(s->pb);
    avio_skip(s->pb, 2);
    pts = avio_rb32(s->pb);
    avio_skip(s->pb, 12);
    ret = av_get_packet(s->pb, pkt, packet_size);
    if (ret < packet_size)
        pkt->flags |= AV_PKT_FLAG_CORRUPT;

    if (ret < 0)
        return ret;
    if (!ret)
        return AVERROR_EOF;

    pkt->stream_index = 0;
    pkt->pos = pos;
377 378 379 380 381 382 383
    if (s->streams[0]->codecpar->codec_id == AV_CODEC_ID_ATRAC3AL) {
        pkt->duration = 1024;
        pkt->pts = pts * 1024LL;
    } else {
        pkt->duration = 2048;
        pkt->pts = pts * 2048LL;
    }
384 385 386 387

    return ret;
}

388
static int oma_read_header(AVFormatContext *s)
Benjamin Larsson's avatar
Benjamin Larsson committed
389
{
390
    int     ret, framesize, jsflag, samplerate;
391
    uint32_t codec_params, channel_id;
Benjamin Larsson's avatar
Benjamin Larsson committed
392 393 394 395
    int16_t eid;
    uint8_t buf[EA3_HEADER_SIZE];
    uint8_t *edata;
    AVStream *st;
396 397
    ID3v2ExtraMeta *extra_meta = NULL;
    OMAContext *oc = s->priv_data;
Benjamin Larsson's avatar
Benjamin Larsson committed
398

399
    ff_id3v2_read(s, ID3v2_EA3_MAGIC, &extra_meta, 0);
Lukas Stabe's avatar
Lukas Stabe committed
400 401 402 403 404
    if ((ret = ff_id3v2_parse_chapters(s, &extra_meta)) < 0) {
        ff_id3v2_free_extra_meta(&extra_meta);
        return ret;
    }

405
    ret = avio_read(s->pb, buf, EA3_HEADER_SIZE);
406 407
    if (ret < EA3_HEADER_SIZE)
        return -1;
Benjamin Larsson's avatar
Benjamin Larsson committed
408

409 410
    if (memcmp(buf, ((const uint8_t[]){'E', 'A', '3'}), 3) ||
        buf[4] != 0 || buf[5] != EA3_HEADER_SIZE) {
Benjamin Larsson's avatar
Benjamin Larsson committed
411
        av_log(s, AV_LOG_ERROR, "Couldn't find the EA3 header !\n");
412
        return AVERROR_INVALIDDATA;
Benjamin Larsson's avatar
Benjamin Larsson committed
413 414
    }

415 416 417
    oc->content_start = avio_tell(s->pb);

    /* encrypted file */
Benjamin Larsson's avatar
Benjamin Larsson committed
418
    eid = AV_RB16(&buf[6]);
419 420
    if (eid != -1 && eid != -128 && decrypt_init(s, extra_meta, buf) < 0) {
        ff_id3v2_free_extra_meta(&extra_meta);
Benjamin Larsson's avatar
Benjamin Larsson committed
421 422 423
        return -1;
    }

424 425
    ff_id3v2_free_extra_meta(&extra_meta);

Benjamin Larsson's avatar
Benjamin Larsson committed
426 427
    codec_params = AV_RB24(&buf[33]);

428
    st = avformat_new_stream(s, NULL);
Benjamin Larsson's avatar
Benjamin Larsson committed
429 430 431
    if (!st)
        return AVERROR(ENOMEM);

432
    st->start_time = 0;
433 434 435 436
    st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
    st->codecpar->codec_tag  = buf[32];
    st->codecpar->codec_id   = ff_codec_get_id(ff_oma_codec_tags,
                                               st->codecpar->codec_tag);
437

438 439
    oc->read_packet = read_packet;

Benjamin Larsson's avatar
Benjamin Larsson committed
440
    switch (buf[32]) {
441 442 443 444 445 446 447 448 449 450 451 452 453 454
    case OMA_CODECID_ATRAC3:
        samplerate = ff_oma_srate_tab[(codec_params >> 13) & 7] * 100;
        if (!samplerate) {
            av_log(s, AV_LOG_ERROR, "Unsupported sample rate\n");
            return AVERROR_INVALIDDATA;
        }
        if (samplerate != 44100)
            avpriv_request_sample(s, "Sample rate %d", samplerate);

        framesize = (codec_params & 0x3FF) * 8;

        /* get stereo coding mode, 1 for joint-stereo */
        jsflag = (codec_params >> 17) & 1;

455 456 457
        st->codecpar->channels    = 2;
        st->codecpar->channel_layout = AV_CH_LAYOUT_STEREO;
        st->codecpar->sample_rate = samplerate;
458
        st->codecpar->bit_rate    = st->codecpar->sample_rate * framesize / (1024 / 8);
459

460
        /* fake the ATRAC3 extradata
461
         * (wav format, makes stream copy to wav work) */
462
        if (ff_alloc_extradata(st->codecpar, 14))
463 464
            return AVERROR(ENOMEM);

465
        edata = st->codecpar->extradata;
466 467 468 469 470 471 472
        AV_WL16(&edata[0],  1);             // always 1
        AV_WL32(&edata[2],  samplerate);    // samples rate
        AV_WL16(&edata[6],  jsflag);        // coding mode
        AV_WL16(&edata[8],  jsflag);        // coding mode
        AV_WL16(&edata[10], 1);             // always 1
        // AV_WL16(&edata[12], 0);          // always 0

473
        avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
474 475
        break;
    case OMA_CODECID_ATRAC3P:
476 477 478
        channel_id = (codec_params >> 10) & 7;
        if (!channel_id) {
            av_log(s, AV_LOG_ERROR,
479
                   "Invalid ATRAC-X channel id: %"PRIu32"\n", channel_id);
480 481
            return AVERROR_INVALIDDATA;
        }
482 483
        st->codecpar->channel_layout = ff_oma_chid_to_native_layout[channel_id - 1];
        st->codecpar->channels       = ff_oma_chid_to_num_channels[channel_id - 1];
484 485 486 487 488 489
        framesize = ((codec_params & 0x3FF) * 8) + 8;
        samplerate = ff_oma_srate_tab[(codec_params >> 13) & 7] * 100;
        if (!samplerate) {
            av_log(s, AV_LOG_ERROR, "Unsupported sample rate\n");
            return AVERROR_INVALIDDATA;
        }
490
        st->codecpar->sample_rate = samplerate;
491
        st->codecpar->bit_rate    = samplerate * framesize / (2048 / 8);
492 493 494
        avpriv_set_pts_info(st, 64, 1, samplerate);
        break;
    case OMA_CODECID_MP3:
495
        st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
496 497 498 499
        framesize = 1024;
        break;
    case OMA_CODECID_LPCM:
        /* PCM 44.1 kHz 16 bit stereo big-endian */
500 501 502
        st->codecpar->channels = 2;
        st->codecpar->channel_layout = AV_CH_LAYOUT_STEREO;
        st->codecpar->sample_rate = 44100;
503 504
        framesize = 1024;
        /* bit rate = sample rate x PCM block align (= 4) x 8 */
505 506 507 508
        st->codecpar->bit_rate = st->codecpar->sample_rate * 32;
        st->codecpar->bits_per_coded_sample =
            av_get_bits_per_sample(st->codecpar->codec_id);
        avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
509
        break;
510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525
    case OMA_CODECID_ATRAC3AL:
        st->codecpar->channels    = 2;
        st->codecpar->channel_layout = AV_CH_LAYOUT_STEREO;
        st->codecpar->sample_rate = 44100;
        avpriv_set_pts_info(st, 64, 1, 44100);
        oc->read_packet = aal_read_packet;
        framesize = 4096;
        break;
    case OMA_CODECID_ATRAC3PAL:
        st->codecpar->channel_layout = AV_CH_LAYOUT_STEREO;
        st->codecpar->channels       = 2;
        st->codecpar->sample_rate = 44100;
        avpriv_set_pts_info(st, 64, 1, 44100);
        oc->read_packet = aal_read_packet;
        framesize = 4096;
        break;
526 527
    default:
        av_log(s, AV_LOG_ERROR, "Unsupported codec %d!\n", buf[32]);
528
        return AVERROR(ENOSYS);
Benjamin Larsson's avatar
Benjamin Larsson committed
529 530
    }

531
    st->codecpar->block_align = framesize;
Benjamin Larsson's avatar
Benjamin Larsson committed
532 533 534 535 536 537

    return 0;
}

static int oma_read_packet(AVFormatContext *s, AVPacket *pkt)
{
Luca Barbato's avatar
Luca Barbato committed
538
    OMAContext *oc  = s->priv_data;
539
    return oc->read_packet(s, pkt);
Benjamin Larsson's avatar
Benjamin Larsson committed
540 541 542 543
}

static int oma_read_probe(AVProbeData *p)
{
544
    const uint8_t *buf = p->buf;
545 546
    unsigned tag_len = 0;

547 548
    if (p->buf_size >= ID3v2_HEADER_SIZE && ff_id3v2_match(buf, ID3v2_EA3_MAGIC))
        tag_len = ff_id3v2_tag_len(buf);
549 550 551 552

    /* This check cannot overflow as tag_len has at most 28 bits */
    if (p->buf_size < tag_len + 5)
        /* EA3 header comes late, might be outside of the probe buffer */
553
        return tag_len ? AVPROBE_SCORE_EXTENSION/2 : 0;
554

555 556 557
    buf += tag_len;

    if (!memcmp(buf, "EA3", 3) && !buf[4] && buf[5] == EA3_HEADER_SIZE)
Benjamin Larsson's avatar
Benjamin Larsson committed
558 559 560 561 562
        return AVPROBE_SCORE_MAX;
    else
        return 0;
}

563 564
static int oma_read_seek(struct AVFormatContext *s,
                         int stream_index, int64_t timestamp, int flags)
565 566
{
    OMAContext *oc = s->priv_data;
567 568 569 570 571 572
    AVStream *st = s->streams[0];
    int64_t err;

    if (st->codecpar->codec_id == AV_CODEC_ID_ATRAC3PAL ||
        st->codecpar->codec_id == AV_CODEC_ID_ATRAC3AL)
        return -1;
573

574
    err = ff_pcm_read_seek(s, stream_index, timestamp, flags);
575 576 577 578 579 580 581 582 583 584 585 586
    if (!oc->encrypted)
        return err;

    /* readjust IV for CBC */
    if (err || avio_tell(s->pb) < oc->content_start)
        goto wipe;
    if ((err = avio_seek(s->pb, -8, SEEK_CUR)) < 0)
        goto wipe;
    if ((err = avio_read(s->pb, oc->iv, 8)) < 8) {
        if (err >= 0)
            err = AVERROR_EOF;
        goto wipe;
587 588 589
    }

    return 0;
590 591 592
wipe:
    memset(oc->iv, 0, 8);
    return err;
593
}
Benjamin Larsson's avatar
Benjamin Larsson committed
594

595 596 597 598 599 600 601
static int oma_read_close(AVFormatContext *s)
{
    OMAContext *oc = s->priv_data;
    av_free(oc->av_des);
    return 0;
}

602
AVInputFormat ff_oma_demuxer = {
603 604
    .name           = "oma",
    .long_name      = NULL_IF_CONFIG_SMALL("Sony OpenMG audio"),
605
    .priv_data_size = sizeof(OMAContext),
606 607 608
    .read_probe     = oma_read_probe,
    .read_header    = oma_read_header,
    .read_packet    = oma_read_packet,
609
    .read_seek      = oma_read_seek,
610
    .read_close     = oma_read_close,
611 612
    .flags          = AVFMT_GENERIC_INDEX,
    .extensions     = "oma,omg,aa3",
613
    .codec_tag      = (const AVCodecTag* const []){ff_oma_codec_tags, 0},
Benjamin Larsson's avatar
Benjamin Larsson committed
614
};