xref: /third_party/ffmpeg/libavformat/omadec.c (revision cabdff1a)
1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * Sony OpenMG (OMA) demuxer
3cabdff1aSopenharmony_ci *
4cabdff1aSopenharmony_ci * Copyright (c) 2008, 2013 Maxim Poliakovski
5cabdff1aSopenharmony_ci *               2008 Benjamin Larsson
6cabdff1aSopenharmony_ci *               2011 David Goldwich
7cabdff1aSopenharmony_ci *
8cabdff1aSopenharmony_ci * This file is part of FFmpeg.
9cabdff1aSopenharmony_ci *
10cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
11cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
12cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
13cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
14cabdff1aSopenharmony_ci *
15cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
16cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
17cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18cabdff1aSopenharmony_ci * Lesser General Public License for more details.
19cabdff1aSopenharmony_ci *
20cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
21cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
22cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23cabdff1aSopenharmony_ci */
24cabdff1aSopenharmony_ci
25cabdff1aSopenharmony_ci/**
26cabdff1aSopenharmony_ci * @file
27cabdff1aSopenharmony_ci * This is a demuxer for Sony OpenMG Music files
28cabdff1aSopenharmony_ci *
29cabdff1aSopenharmony_ci * Known file extensions: ".oma", "aa3"
30cabdff1aSopenharmony_ci * The format of such files consists of three parts:
31cabdff1aSopenharmony_ci * - "ea3" header carrying overall info and metadata. Except for starting with
32cabdff1aSopenharmony_ci *   "ea" instead of "ID", it's an ID3v2 header.
33cabdff1aSopenharmony_ci * - "EA3" header is a Sony-specific header containing information about
34cabdff1aSopenharmony_ci *   the OpenMG file: codec type (usually ATRAC, can also be MP3 or WMA),
35cabdff1aSopenharmony_ci *   codec specific info (packet size, sample rate, channels and so on)
36cabdff1aSopenharmony_ci *   and DRM related info (file encryption, content id).
37cabdff1aSopenharmony_ci * - Sound data organized in packets follow the EA3 header
38cabdff1aSopenharmony_ci *   (can be encrypted using the Sony DRM!).
39cabdff1aSopenharmony_ci *
40cabdff1aSopenharmony_ci * Supported decoders: ATRAC3, ATRAC3+, MP3, LPCM
41cabdff1aSopenharmony_ci */
42cabdff1aSopenharmony_ci
43cabdff1aSopenharmony_ci#include <inttypes.h>
44cabdff1aSopenharmony_ci
45cabdff1aSopenharmony_ci#include "libavutil/channel_layout.h"
46cabdff1aSopenharmony_ci#include "avformat.h"
47cabdff1aSopenharmony_ci#include "internal.h"
48cabdff1aSopenharmony_ci#include "libavutil/intreadwrite.h"
49cabdff1aSopenharmony_ci#include "libavutil/des.h"
50cabdff1aSopenharmony_ci#include "libavutil/mathematics.h"
51cabdff1aSopenharmony_ci#include "oma.h"
52cabdff1aSopenharmony_ci#include "pcm.h"
53cabdff1aSopenharmony_ci#include "id3v2.h"
54cabdff1aSopenharmony_ci
55cabdff1aSopenharmony_ci
56cabdff1aSopenharmony_cistatic const uint64_t leaf_table[] = {
57cabdff1aSopenharmony_ci    0xd79e8283acea4620, 0x7a9762f445afd0d8,
58cabdff1aSopenharmony_ci    0x354d60a60b8c79f1, 0x584e1cde00b07aee,
59cabdff1aSopenharmony_ci    0x1573cd93da7df623, 0x47f98d79620dd535
60cabdff1aSopenharmony_ci};
61cabdff1aSopenharmony_ci
62cabdff1aSopenharmony_ci/** map ATRAC-X channel id to internal channel layout */
63cabdff1aSopenharmony_cistatic const AVChannelLayout  oma_chid_to_native_layout[7] = {
64cabdff1aSopenharmony_ci    AV_CHANNEL_LAYOUT_MONO,
65cabdff1aSopenharmony_ci    AV_CHANNEL_LAYOUT_STEREO,
66cabdff1aSopenharmony_ci    AV_CHANNEL_LAYOUT_SURROUND,
67cabdff1aSopenharmony_ci    AV_CHANNEL_LAYOUT_4POINT0,
68cabdff1aSopenharmony_ci    AV_CHANNEL_LAYOUT_5POINT1_BACK,
69cabdff1aSopenharmony_ci    AV_CHANNEL_LAYOUT_6POINT1_BACK,
70cabdff1aSopenharmony_ci    AV_CHANNEL_LAYOUT_7POINT1
71cabdff1aSopenharmony_ci};
72cabdff1aSopenharmony_ci
73cabdff1aSopenharmony_citypedef struct OMAContext {
74cabdff1aSopenharmony_ci    uint64_t content_start;
75cabdff1aSopenharmony_ci    int encrypted;
76cabdff1aSopenharmony_ci    uint16_t k_size;
77cabdff1aSopenharmony_ci    uint16_t e_size;
78cabdff1aSopenharmony_ci    uint16_t i_size;
79cabdff1aSopenharmony_ci    uint16_t s_size;
80cabdff1aSopenharmony_ci    uint32_t rid;
81cabdff1aSopenharmony_ci    uint8_t r_val[24];
82cabdff1aSopenharmony_ci    uint8_t n_val[24];
83cabdff1aSopenharmony_ci    uint8_t m_val[8];
84cabdff1aSopenharmony_ci    uint8_t s_val[8];
85cabdff1aSopenharmony_ci    uint8_t sm_val[8];
86cabdff1aSopenharmony_ci    uint8_t e_val[8];
87cabdff1aSopenharmony_ci    uint8_t iv[8];
88cabdff1aSopenharmony_ci    struct AVDES *av_des;
89cabdff1aSopenharmony_ci
90cabdff1aSopenharmony_ci    int (*read_packet)(AVFormatContext *s, AVPacket *pkt);
91cabdff1aSopenharmony_ci} OMAContext;
92cabdff1aSopenharmony_ci
93cabdff1aSopenharmony_cistatic int oma_read_close(AVFormatContext *s)
94cabdff1aSopenharmony_ci{
95cabdff1aSopenharmony_ci    OMAContext *oc = s->priv_data;
96cabdff1aSopenharmony_ci    av_freep(&oc->av_des);
97cabdff1aSopenharmony_ci    return 0;
98cabdff1aSopenharmony_ci}
99cabdff1aSopenharmony_ci
100cabdff1aSopenharmony_cistatic void hex_log(AVFormatContext *s, int level,
101cabdff1aSopenharmony_ci                    const char *name, const uint8_t *value, int len)
102cabdff1aSopenharmony_ci{
103cabdff1aSopenharmony_ci    char buf[33];
104cabdff1aSopenharmony_ci    len = FFMIN(len, 16);
105cabdff1aSopenharmony_ci    if (av_log_get_level() < level)
106cabdff1aSopenharmony_ci        return;
107cabdff1aSopenharmony_ci    ff_data_to_hex(buf, value, len, 1);
108cabdff1aSopenharmony_ci    av_log(s, level, "%s: %s\n", name, buf);
109cabdff1aSopenharmony_ci}
110cabdff1aSopenharmony_ci
111cabdff1aSopenharmony_cistatic int kset(AVFormatContext *s, const uint8_t *r_val, const uint8_t *n_val,
112cabdff1aSopenharmony_ci                int len)
113cabdff1aSopenharmony_ci{
114cabdff1aSopenharmony_ci    OMAContext *oc = s->priv_data;
115cabdff1aSopenharmony_ci
116cabdff1aSopenharmony_ci    if (!r_val && !n_val)
117cabdff1aSopenharmony_ci        return -1;
118cabdff1aSopenharmony_ci
119cabdff1aSopenharmony_ci    len = FFMIN(len, 16);
120cabdff1aSopenharmony_ci
121cabdff1aSopenharmony_ci    /* use first 64 bits in the third round again */
122cabdff1aSopenharmony_ci    if (r_val) {
123cabdff1aSopenharmony_ci        if (r_val != oc->r_val) {
124cabdff1aSopenharmony_ci            memset(oc->r_val, 0, 24);
125cabdff1aSopenharmony_ci            memcpy(oc->r_val, r_val, len);
126cabdff1aSopenharmony_ci        }
127cabdff1aSopenharmony_ci        memcpy(&oc->r_val[16], r_val, 8);
128cabdff1aSopenharmony_ci    }
129cabdff1aSopenharmony_ci    if (n_val) {
130cabdff1aSopenharmony_ci        if (n_val != oc->n_val) {
131cabdff1aSopenharmony_ci            memset(oc->n_val, 0, 24);
132cabdff1aSopenharmony_ci            memcpy(oc->n_val, n_val, len);
133cabdff1aSopenharmony_ci        }
134cabdff1aSopenharmony_ci        memcpy(&oc->n_val[16], n_val, 8);
135cabdff1aSopenharmony_ci    }
136cabdff1aSopenharmony_ci
137cabdff1aSopenharmony_ci    return 0;
138cabdff1aSopenharmony_ci}
139cabdff1aSopenharmony_ci
140cabdff1aSopenharmony_ci#define OMA_RPROBE_M_VAL 48 + 1
141cabdff1aSopenharmony_ci
142cabdff1aSopenharmony_cistatic int rprobe(AVFormatContext *s, uint8_t *enc_header, unsigned size,
143cabdff1aSopenharmony_ci                  const uint8_t *r_val)
144cabdff1aSopenharmony_ci{
145cabdff1aSopenharmony_ci    OMAContext *oc = s->priv_data;
146cabdff1aSopenharmony_ci    unsigned int pos;
147cabdff1aSopenharmony_ci    struct AVDES *av_des;
148cabdff1aSopenharmony_ci
149cabdff1aSopenharmony_ci    if (!enc_header || !r_val ||
150cabdff1aSopenharmony_ci        size < OMA_ENC_HEADER_SIZE + oc->k_size + oc->e_size + oc->i_size ||
151cabdff1aSopenharmony_ci        size < OMA_RPROBE_M_VAL)
152cabdff1aSopenharmony_ci        return -1;
153cabdff1aSopenharmony_ci
154cabdff1aSopenharmony_ci    av_des = av_des_alloc();
155cabdff1aSopenharmony_ci    if (!av_des)
156cabdff1aSopenharmony_ci        return AVERROR(ENOMEM);
157cabdff1aSopenharmony_ci
158cabdff1aSopenharmony_ci    /* m_val */
159cabdff1aSopenharmony_ci    av_des_init(av_des, r_val, 192, 1);
160cabdff1aSopenharmony_ci    av_des_crypt(av_des, oc->m_val, &enc_header[48], 1, NULL, 1);
161cabdff1aSopenharmony_ci
162cabdff1aSopenharmony_ci    /* s_val */
163cabdff1aSopenharmony_ci    av_des_init(av_des, oc->m_val, 64, 0);
164cabdff1aSopenharmony_ci    av_des_crypt(av_des, oc->s_val, NULL, 1, NULL, 0);
165cabdff1aSopenharmony_ci
166cabdff1aSopenharmony_ci    /* sm_val */
167cabdff1aSopenharmony_ci    pos = OMA_ENC_HEADER_SIZE + oc->k_size + oc->e_size;
168cabdff1aSopenharmony_ci    av_des_init(av_des, oc->s_val, 64, 0);
169cabdff1aSopenharmony_ci    av_des_mac(av_des, oc->sm_val, &enc_header[pos], (oc->i_size >> 3));
170cabdff1aSopenharmony_ci
171cabdff1aSopenharmony_ci    pos += oc->i_size;
172cabdff1aSopenharmony_ci
173cabdff1aSopenharmony_ci    av_free(av_des);
174cabdff1aSopenharmony_ci
175cabdff1aSopenharmony_ci    return memcmp(&enc_header[pos], oc->sm_val, 8) ? -1 : 0;
176cabdff1aSopenharmony_ci}
177cabdff1aSopenharmony_ci
178cabdff1aSopenharmony_cistatic int nprobe(AVFormatContext *s, uint8_t *enc_header, unsigned size,
179cabdff1aSopenharmony_ci                  const uint8_t *n_val)
180cabdff1aSopenharmony_ci{
181cabdff1aSopenharmony_ci    OMAContext *oc = s->priv_data;
182cabdff1aSopenharmony_ci    uint64_t pos;
183cabdff1aSopenharmony_ci    uint32_t taglen, datalen;
184cabdff1aSopenharmony_ci    struct AVDES *av_des;
185cabdff1aSopenharmony_ci
186cabdff1aSopenharmony_ci    if (!enc_header || !n_val ||
187cabdff1aSopenharmony_ci        size < OMA_ENC_HEADER_SIZE + oc->k_size + 4)
188cabdff1aSopenharmony_ci        return -1;
189cabdff1aSopenharmony_ci
190cabdff1aSopenharmony_ci    pos = OMA_ENC_HEADER_SIZE + oc->k_size;
191cabdff1aSopenharmony_ci    if (!memcmp(&enc_header[pos], "EKB ", 4))
192cabdff1aSopenharmony_ci        pos += 32;
193cabdff1aSopenharmony_ci
194cabdff1aSopenharmony_ci    if (size < pos + 44)
195cabdff1aSopenharmony_ci        return -1;
196cabdff1aSopenharmony_ci
197cabdff1aSopenharmony_ci    if (AV_RB32(&enc_header[pos]) != oc->rid)
198cabdff1aSopenharmony_ci        av_log(s, AV_LOG_DEBUG, "Mismatching RID\n");
199cabdff1aSopenharmony_ci
200cabdff1aSopenharmony_ci    taglen  = AV_RB32(&enc_header[pos + 32]);
201cabdff1aSopenharmony_ci    datalen = AV_RB32(&enc_header[pos + 36]) >> 4;
202cabdff1aSopenharmony_ci
203cabdff1aSopenharmony_ci    pos += 44LL + taglen;
204cabdff1aSopenharmony_ci
205cabdff1aSopenharmony_ci    if (pos + (((uint64_t)datalen) << 4) > size)
206cabdff1aSopenharmony_ci        return -1;
207cabdff1aSopenharmony_ci
208cabdff1aSopenharmony_ci    av_des = av_des_alloc();
209cabdff1aSopenharmony_ci    if (!av_des)
210cabdff1aSopenharmony_ci        return AVERROR(ENOMEM);
211cabdff1aSopenharmony_ci
212cabdff1aSopenharmony_ci    av_des_init(av_des, n_val, 192, 1);
213cabdff1aSopenharmony_ci    while (datalen-- > 0) {
214cabdff1aSopenharmony_ci        av_des_crypt(av_des, oc->r_val, &enc_header[pos], 2, NULL, 1);
215cabdff1aSopenharmony_ci        kset(s, oc->r_val, NULL, 16);
216cabdff1aSopenharmony_ci        if (!rprobe(s, enc_header, size, oc->r_val)) {
217cabdff1aSopenharmony_ci            av_free(av_des);
218cabdff1aSopenharmony_ci            return 0;
219cabdff1aSopenharmony_ci        }
220cabdff1aSopenharmony_ci        pos += 16;
221cabdff1aSopenharmony_ci    }
222cabdff1aSopenharmony_ci
223cabdff1aSopenharmony_ci    av_free(av_des);
224cabdff1aSopenharmony_ci    return -1;
225cabdff1aSopenharmony_ci}
226cabdff1aSopenharmony_ci
227cabdff1aSopenharmony_cistatic int decrypt_init(AVFormatContext *s, ID3v2ExtraMeta *em, uint8_t *header)
228cabdff1aSopenharmony_ci{
229cabdff1aSopenharmony_ci    OMAContext *oc = s->priv_data;
230cabdff1aSopenharmony_ci    ID3v2ExtraMetaGEOB *geob = NULL;
231cabdff1aSopenharmony_ci    uint8_t *gdata;
232cabdff1aSopenharmony_ci
233cabdff1aSopenharmony_ci    oc->encrypted = 1;
234cabdff1aSopenharmony_ci    av_log(s, AV_LOG_INFO, "File is encrypted\n");
235cabdff1aSopenharmony_ci
236cabdff1aSopenharmony_ci    /* find GEOB metadata */
237cabdff1aSopenharmony_ci    for (; em; em = em->next) {
238cabdff1aSopenharmony_ci        if (strcmp(em->tag, "GEOB"))
239cabdff1aSopenharmony_ci            continue;
240cabdff1aSopenharmony_ci        geob = &em->data.geob;
241cabdff1aSopenharmony_ci        if (!strcmp(geob->description, "OMG_LSI") ||
242cabdff1aSopenharmony_ci            !strcmp(geob->description, "OMG_BKLSI"))
243cabdff1aSopenharmony_ci            break;
244cabdff1aSopenharmony_ci    }
245cabdff1aSopenharmony_ci    if (!em) {
246cabdff1aSopenharmony_ci        av_log(s, AV_LOG_ERROR, "No encryption header found\n");
247cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
248cabdff1aSopenharmony_ci    }
249cabdff1aSopenharmony_ci
250cabdff1aSopenharmony_ci    if (geob->datasize < 64) {
251cabdff1aSopenharmony_ci        av_log(s, AV_LOG_ERROR,
252cabdff1aSopenharmony_ci               "Invalid GEOB data size: %"PRIu32"\n", geob->datasize);
253cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
254cabdff1aSopenharmony_ci    }
255cabdff1aSopenharmony_ci
256cabdff1aSopenharmony_ci    gdata = geob->data;
257cabdff1aSopenharmony_ci
258cabdff1aSopenharmony_ci    if (AV_RB16(gdata) != 1)
259cabdff1aSopenharmony_ci        av_log(s, AV_LOG_WARNING, "Unknown version in encryption header\n");
260cabdff1aSopenharmony_ci
261cabdff1aSopenharmony_ci    oc->k_size = AV_RB16(&gdata[2]);
262cabdff1aSopenharmony_ci    oc->e_size = AV_RB16(&gdata[4]);
263cabdff1aSopenharmony_ci    oc->i_size = AV_RB16(&gdata[6]);
264cabdff1aSopenharmony_ci    oc->s_size = AV_RB16(&gdata[8]);
265cabdff1aSopenharmony_ci
266cabdff1aSopenharmony_ci    if (memcmp(&gdata[OMA_ENC_HEADER_SIZE], "KEYRING     ", 12)) {
267cabdff1aSopenharmony_ci        av_log(s, AV_LOG_ERROR, "Invalid encryption header\n");
268cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
269cabdff1aSopenharmony_ci    }
270cabdff1aSopenharmony_ci    if (OMA_ENC_HEADER_SIZE + oc->k_size + oc->e_size + oc->i_size + 8 > geob->datasize ||
271cabdff1aSopenharmony_ci        OMA_ENC_HEADER_SIZE + 48 > geob->datasize) {
272cabdff1aSopenharmony_ci        av_log(s, AV_LOG_ERROR, "Too little GEOB data\n");
273cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
274cabdff1aSopenharmony_ci    }
275cabdff1aSopenharmony_ci    oc->rid = AV_RB32(&gdata[OMA_ENC_HEADER_SIZE + 28]);
276cabdff1aSopenharmony_ci    av_log(s, AV_LOG_DEBUG, "RID: %.8"PRIx32"\n", oc->rid);
277cabdff1aSopenharmony_ci
278cabdff1aSopenharmony_ci    memcpy(oc->iv, &header[0x58], 8);
279cabdff1aSopenharmony_ci    hex_log(s, AV_LOG_DEBUG, "IV", oc->iv, 8);
280cabdff1aSopenharmony_ci
281cabdff1aSopenharmony_ci    hex_log(s, AV_LOG_DEBUG, "CBC-MAC",
282cabdff1aSopenharmony_ci            &gdata[OMA_ENC_HEADER_SIZE + oc->k_size + oc->e_size + oc->i_size],
283cabdff1aSopenharmony_ci            8);
284cabdff1aSopenharmony_ci
285cabdff1aSopenharmony_ci    if (s->keylen > 0) {
286cabdff1aSopenharmony_ci        kset(s, s->key, s->key, s->keylen);
287cabdff1aSopenharmony_ci    }
288cabdff1aSopenharmony_ci    if (!memcmp(oc->r_val, (const uint8_t[8]){0}, 8) ||
289cabdff1aSopenharmony_ci        rprobe(s, gdata, geob->datasize, oc->r_val) < 0 &&
290cabdff1aSopenharmony_ci        nprobe(s, gdata, geob->datasize, oc->n_val) < 0) {
291cabdff1aSopenharmony_ci        int i;
292cabdff1aSopenharmony_ci        for (i = 0; i < FF_ARRAY_ELEMS(leaf_table); i += 2) {
293cabdff1aSopenharmony_ci            uint8_t buf[16];
294cabdff1aSopenharmony_ci            AV_WL64(buf,     leaf_table[i]);
295cabdff1aSopenharmony_ci            AV_WL64(&buf[8], leaf_table[i + 1]);
296cabdff1aSopenharmony_ci            kset(s, buf, buf, 16);
297cabdff1aSopenharmony_ci            if (!rprobe(s, gdata, geob->datasize, oc->r_val) ||
298cabdff1aSopenharmony_ci                !nprobe(s, gdata, geob->datasize, oc->n_val))
299cabdff1aSopenharmony_ci                break;
300cabdff1aSopenharmony_ci        }
301cabdff1aSopenharmony_ci        if (i >= FF_ARRAY_ELEMS(leaf_table)) {
302cabdff1aSopenharmony_ci            av_log(s, AV_LOG_ERROR, "Invalid key\n");
303cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
304cabdff1aSopenharmony_ci        }
305cabdff1aSopenharmony_ci    }
306cabdff1aSopenharmony_ci
307cabdff1aSopenharmony_ci    oc->av_des = av_des_alloc();
308cabdff1aSopenharmony_ci    if (!oc->av_des)
309cabdff1aSopenharmony_ci        return AVERROR(ENOMEM);
310cabdff1aSopenharmony_ci
311cabdff1aSopenharmony_ci    /* e_val */
312cabdff1aSopenharmony_ci    av_des_init(oc->av_des, oc->m_val, 64, 0);
313cabdff1aSopenharmony_ci    av_des_crypt(oc->av_des, oc->e_val,
314cabdff1aSopenharmony_ci                 &gdata[OMA_ENC_HEADER_SIZE + 40], 1, NULL, 0);
315cabdff1aSopenharmony_ci    hex_log(s, AV_LOG_DEBUG, "EK", oc->e_val, 8);
316cabdff1aSopenharmony_ci
317cabdff1aSopenharmony_ci    /* init e_val */
318cabdff1aSopenharmony_ci    av_des_init(oc->av_des, oc->e_val, 64, 1);
319cabdff1aSopenharmony_ci
320cabdff1aSopenharmony_ci    return 0;
321cabdff1aSopenharmony_ci}
322cabdff1aSopenharmony_ci
323cabdff1aSopenharmony_cistatic int read_packet(AVFormatContext *s, AVPacket *pkt)
324cabdff1aSopenharmony_ci{
325cabdff1aSopenharmony_ci    OMAContext *oc  = s->priv_data;
326cabdff1aSopenharmony_ci    AVStream *st    = s->streams[0];
327cabdff1aSopenharmony_ci    int packet_size = st->codecpar->block_align;
328cabdff1aSopenharmony_ci    int byte_rate   = st->codecpar->bit_rate >> 3;
329cabdff1aSopenharmony_ci    int64_t pos     = avio_tell(s->pb);
330cabdff1aSopenharmony_ci    int ret         = av_get_packet(s->pb, pkt, packet_size);
331cabdff1aSopenharmony_ci
332cabdff1aSopenharmony_ci    if (ret < packet_size)
333cabdff1aSopenharmony_ci        pkt->flags |= AV_PKT_FLAG_CORRUPT;
334cabdff1aSopenharmony_ci
335cabdff1aSopenharmony_ci    if (ret < 0)
336cabdff1aSopenharmony_ci        return ret;
337cabdff1aSopenharmony_ci    if (!ret)
338cabdff1aSopenharmony_ci        return AVERROR_EOF;
339cabdff1aSopenharmony_ci
340cabdff1aSopenharmony_ci    pkt->stream_index = 0;
341cabdff1aSopenharmony_ci
342cabdff1aSopenharmony_ci    if (pos >= oc->content_start && byte_rate > 0) {
343cabdff1aSopenharmony_ci        pkt->pts =
344cabdff1aSopenharmony_ci        pkt->dts = av_rescale(pos - oc->content_start, st->time_base.den,
345cabdff1aSopenharmony_ci                              byte_rate * (int64_t)st->time_base.num);
346cabdff1aSopenharmony_ci    }
347cabdff1aSopenharmony_ci
348cabdff1aSopenharmony_ci    if (oc->encrypted) {
349cabdff1aSopenharmony_ci        /* previous unencrypted block saved in IV for
350cabdff1aSopenharmony_ci         * the next packet (CBC mode) */
351cabdff1aSopenharmony_ci        if (ret == packet_size)
352cabdff1aSopenharmony_ci            av_des_crypt(oc->av_des, pkt->data, pkt->data,
353cabdff1aSopenharmony_ci                         (packet_size >> 3), oc->iv, 1);
354cabdff1aSopenharmony_ci        else
355cabdff1aSopenharmony_ci            memset(oc->iv, 0, 8);
356cabdff1aSopenharmony_ci    }
357cabdff1aSopenharmony_ci
358cabdff1aSopenharmony_ci    return ret;
359cabdff1aSopenharmony_ci}
360cabdff1aSopenharmony_ci
361cabdff1aSopenharmony_cistatic int aal_read_packet(AVFormatContext *s, AVPacket *pkt)
362cabdff1aSopenharmony_ci{
363cabdff1aSopenharmony_ci    int64_t pos = avio_tell(s->pb);
364cabdff1aSopenharmony_ci    int ret, pts;
365cabdff1aSopenharmony_ci    int packet_size;
366cabdff1aSopenharmony_ci    unsigned tag;
367cabdff1aSopenharmony_ci
368cabdff1aSopenharmony_ci    if (avio_feof(s->pb))
369cabdff1aSopenharmony_ci        return AVERROR_EOF;
370cabdff1aSopenharmony_ci
371cabdff1aSopenharmony_ci    tag = avio_rb24(s->pb);
372cabdff1aSopenharmony_ci    if (tag == 0)
373cabdff1aSopenharmony_ci        return AVERROR_EOF;
374cabdff1aSopenharmony_ci    else if (tag != MKBETAG(0,'B','L','K'))
375cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
376cabdff1aSopenharmony_ci
377cabdff1aSopenharmony_ci    avio_skip(s->pb, 1);
378cabdff1aSopenharmony_ci    packet_size = avio_rb16(s->pb);
379cabdff1aSopenharmony_ci    avio_skip(s->pb, 2);
380cabdff1aSopenharmony_ci    pts = avio_rb32(s->pb);
381cabdff1aSopenharmony_ci    avio_skip(s->pb, 12);
382cabdff1aSopenharmony_ci    ret = av_get_packet(s->pb, pkt, packet_size);
383cabdff1aSopenharmony_ci    if (ret < packet_size)
384cabdff1aSopenharmony_ci        pkt->flags |= AV_PKT_FLAG_CORRUPT;
385cabdff1aSopenharmony_ci
386cabdff1aSopenharmony_ci    if (ret < 0)
387cabdff1aSopenharmony_ci        return ret;
388cabdff1aSopenharmony_ci    if (!ret)
389cabdff1aSopenharmony_ci        return AVERROR_EOF;
390cabdff1aSopenharmony_ci
391cabdff1aSopenharmony_ci    pkt->stream_index = 0;
392cabdff1aSopenharmony_ci    pkt->pos = pos;
393cabdff1aSopenharmony_ci    if (s->streams[0]->codecpar->codec_id == AV_CODEC_ID_ATRAC3AL) {
394cabdff1aSopenharmony_ci        pkt->duration = 1024;
395cabdff1aSopenharmony_ci        pkt->pts = pts * 1024LL;
396cabdff1aSopenharmony_ci    } else {
397cabdff1aSopenharmony_ci        pkt->duration = 2048;
398cabdff1aSopenharmony_ci        pkt->pts = pts * 2048LL;
399cabdff1aSopenharmony_ci    }
400cabdff1aSopenharmony_ci
401cabdff1aSopenharmony_ci    return ret;
402cabdff1aSopenharmony_ci}
403cabdff1aSopenharmony_ci
404cabdff1aSopenharmony_cistatic int oma_read_header(AVFormatContext *s)
405cabdff1aSopenharmony_ci{
406cabdff1aSopenharmony_ci    int     ret, framesize, jsflag, samplerate;
407cabdff1aSopenharmony_ci    uint32_t codec_params, channel_id;
408cabdff1aSopenharmony_ci    int16_t eid;
409cabdff1aSopenharmony_ci    uint8_t buf[EA3_HEADER_SIZE];
410cabdff1aSopenharmony_ci    uint8_t *edata;
411cabdff1aSopenharmony_ci    AVStream *st;
412cabdff1aSopenharmony_ci    ID3v2ExtraMeta *extra_meta;
413cabdff1aSopenharmony_ci    OMAContext *oc = s->priv_data;
414cabdff1aSopenharmony_ci
415cabdff1aSopenharmony_ci    ff_id3v2_read(s, ID3v2_EA3_MAGIC, &extra_meta, 0);
416cabdff1aSopenharmony_ci    if ((ret = ff_id3v2_parse_chapters(s, extra_meta)) < 0) {
417cabdff1aSopenharmony_ci        ff_id3v2_free_extra_meta(&extra_meta);
418cabdff1aSopenharmony_ci        return ret;
419cabdff1aSopenharmony_ci    }
420cabdff1aSopenharmony_ci
421cabdff1aSopenharmony_ci    ret = avio_read(s->pb, buf, EA3_HEADER_SIZE);
422cabdff1aSopenharmony_ci    if (ret < EA3_HEADER_SIZE) {
423cabdff1aSopenharmony_ci        ff_id3v2_free_extra_meta(&extra_meta);
424cabdff1aSopenharmony_ci        return -1;
425cabdff1aSopenharmony_ci    }
426cabdff1aSopenharmony_ci
427cabdff1aSopenharmony_ci    if (memcmp(buf, ((const uint8_t[]){'E', 'A', '3'}), 3) ||
428cabdff1aSopenharmony_ci        buf[4] != 0 || buf[5] != EA3_HEADER_SIZE) {
429cabdff1aSopenharmony_ci        ff_id3v2_free_extra_meta(&extra_meta);
430cabdff1aSopenharmony_ci        av_log(s, AV_LOG_ERROR, "Couldn't find the EA3 header !\n");
431cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
432cabdff1aSopenharmony_ci    }
433cabdff1aSopenharmony_ci
434cabdff1aSopenharmony_ci    oc->content_start = avio_tell(s->pb);
435cabdff1aSopenharmony_ci
436cabdff1aSopenharmony_ci    /* encrypted file */
437cabdff1aSopenharmony_ci    eid = AV_RB16(&buf[6]);
438cabdff1aSopenharmony_ci    if (eid != -1 && eid != -128 && decrypt_init(s, extra_meta, buf) < 0) {
439cabdff1aSopenharmony_ci        ff_id3v2_free_extra_meta(&extra_meta);
440cabdff1aSopenharmony_ci        return -1;
441cabdff1aSopenharmony_ci    }
442cabdff1aSopenharmony_ci
443cabdff1aSopenharmony_ci    ff_id3v2_free_extra_meta(&extra_meta);
444cabdff1aSopenharmony_ci
445cabdff1aSopenharmony_ci    codec_params = AV_RB24(&buf[33]);
446cabdff1aSopenharmony_ci
447cabdff1aSopenharmony_ci    st = avformat_new_stream(s, NULL);
448cabdff1aSopenharmony_ci    if (!st)
449cabdff1aSopenharmony_ci        return AVERROR(ENOMEM);
450cabdff1aSopenharmony_ci
451cabdff1aSopenharmony_ci    st->start_time = 0;
452cabdff1aSopenharmony_ci    st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
453cabdff1aSopenharmony_ci    st->codecpar->codec_tag  = buf[32];
454cabdff1aSopenharmony_ci    st->codecpar->codec_id   = ff_codec_get_id(ff_oma_codec_tags,
455cabdff1aSopenharmony_ci                                               st->codecpar->codec_tag);
456cabdff1aSopenharmony_ci
457cabdff1aSopenharmony_ci    oc->read_packet = read_packet;
458cabdff1aSopenharmony_ci
459cabdff1aSopenharmony_ci    switch (buf[32]) {
460cabdff1aSopenharmony_ci    case OMA_CODECID_ATRAC3:
461cabdff1aSopenharmony_ci        samplerate = ff_oma_srate_tab[(codec_params >> 13) & 7] * 100;
462cabdff1aSopenharmony_ci        if (!samplerate) {
463cabdff1aSopenharmony_ci            av_log(s, AV_LOG_ERROR, "Unsupported sample rate\n");
464cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
465cabdff1aSopenharmony_ci        }
466cabdff1aSopenharmony_ci        if (samplerate != 44100)
467cabdff1aSopenharmony_ci            avpriv_request_sample(s, "Sample rate %d", samplerate);
468cabdff1aSopenharmony_ci
469cabdff1aSopenharmony_ci        framesize = (codec_params & 0x3FF) * 8;
470cabdff1aSopenharmony_ci
471cabdff1aSopenharmony_ci        /* get stereo coding mode, 1 for joint-stereo */
472cabdff1aSopenharmony_ci        jsflag = (codec_params >> 17) & 1;
473cabdff1aSopenharmony_ci
474cabdff1aSopenharmony_ci        st->codecpar->ch_layout   = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO;
475cabdff1aSopenharmony_ci        st->codecpar->sample_rate = samplerate;
476cabdff1aSopenharmony_ci        st->codecpar->bit_rate    = st->codecpar->sample_rate * framesize / (1024 / 8);
477cabdff1aSopenharmony_ci
478cabdff1aSopenharmony_ci        /* fake the ATRAC3 extradata
479cabdff1aSopenharmony_ci         * (wav format, makes stream copy to wav work) */
480cabdff1aSopenharmony_ci        if ((ret = ff_alloc_extradata(st->codecpar, 14)) < 0)
481cabdff1aSopenharmony_ci            return ret;
482cabdff1aSopenharmony_ci
483cabdff1aSopenharmony_ci        edata = st->codecpar->extradata;
484cabdff1aSopenharmony_ci        AV_WL16(&edata[0],  1);             // always 1
485cabdff1aSopenharmony_ci        AV_WL32(&edata[2],  samplerate);    // samples rate
486cabdff1aSopenharmony_ci        AV_WL16(&edata[6],  jsflag);        // coding mode
487cabdff1aSopenharmony_ci        AV_WL16(&edata[8],  jsflag);        // coding mode
488cabdff1aSopenharmony_ci        AV_WL16(&edata[10], 1);             // always 1
489cabdff1aSopenharmony_ci        AV_WL16(&edata[12], 0);             // always 0
490cabdff1aSopenharmony_ci
491cabdff1aSopenharmony_ci        avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
492cabdff1aSopenharmony_ci        break;
493cabdff1aSopenharmony_ci    case OMA_CODECID_ATRAC3P:
494cabdff1aSopenharmony_ci        channel_id = (codec_params >> 10) & 7;
495cabdff1aSopenharmony_ci        if (!channel_id) {
496cabdff1aSopenharmony_ci            av_log(s, AV_LOG_ERROR,
497cabdff1aSopenharmony_ci                   "Invalid ATRAC-X channel id: %"PRIu32"\n", channel_id);
498cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
499cabdff1aSopenharmony_ci        }
500cabdff1aSopenharmony_ci        av_channel_layout_copy(&st->codecpar->ch_layout,
501cabdff1aSopenharmony_ci                               &oma_chid_to_native_layout[channel_id - 1]);
502cabdff1aSopenharmony_ci        framesize = ((codec_params & 0x3FF) * 8) + 8;
503cabdff1aSopenharmony_ci        samplerate = ff_oma_srate_tab[(codec_params >> 13) & 7] * 100;
504cabdff1aSopenharmony_ci        if (!samplerate) {
505cabdff1aSopenharmony_ci            av_log(s, AV_LOG_ERROR, "Unsupported sample rate\n");
506cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
507cabdff1aSopenharmony_ci        }
508cabdff1aSopenharmony_ci        st->codecpar->sample_rate = samplerate;
509cabdff1aSopenharmony_ci        st->codecpar->bit_rate    = samplerate * framesize / (2048 / 8);
510cabdff1aSopenharmony_ci        avpriv_set_pts_info(st, 64, 1, samplerate);
511cabdff1aSopenharmony_ci        break;
512cabdff1aSopenharmony_ci    case OMA_CODECID_MP3:
513cabdff1aSopenharmony_ci        ffstream(st)->need_parsing = AVSTREAM_PARSE_FULL_RAW;
514cabdff1aSopenharmony_ci        framesize = 1024;
515cabdff1aSopenharmony_ci        break;
516cabdff1aSopenharmony_ci    case OMA_CODECID_LPCM:
517cabdff1aSopenharmony_ci        /* PCM 44.1 kHz 16 bit stereo big-endian */
518cabdff1aSopenharmony_ci        st->codecpar->ch_layout   = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO;
519cabdff1aSopenharmony_ci        st->codecpar->sample_rate = 44100;
520cabdff1aSopenharmony_ci        framesize = 1024;
521cabdff1aSopenharmony_ci        /* bit rate = sample rate x PCM block align (= 4) x 8 */
522cabdff1aSopenharmony_ci        st->codecpar->bit_rate = st->codecpar->sample_rate * 32;
523cabdff1aSopenharmony_ci        st->codecpar->bits_per_coded_sample =
524cabdff1aSopenharmony_ci            av_get_bits_per_sample(st->codecpar->codec_id);
525cabdff1aSopenharmony_ci        avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
526cabdff1aSopenharmony_ci        break;
527cabdff1aSopenharmony_ci    case OMA_CODECID_ATRAC3AL:
528cabdff1aSopenharmony_ci        st->codecpar->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO;
529cabdff1aSopenharmony_ci        st->codecpar->sample_rate = 44100;
530cabdff1aSopenharmony_ci        avpriv_set_pts_info(st, 64, 1, 44100);
531cabdff1aSopenharmony_ci        oc->read_packet = aal_read_packet;
532cabdff1aSopenharmony_ci        framesize = 4096;
533cabdff1aSopenharmony_ci        break;
534cabdff1aSopenharmony_ci    case OMA_CODECID_ATRAC3PAL:
535cabdff1aSopenharmony_ci        st->codecpar->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO;
536cabdff1aSopenharmony_ci        st->codecpar->sample_rate = 44100;
537cabdff1aSopenharmony_ci        avpriv_set_pts_info(st, 64, 1, 44100);
538cabdff1aSopenharmony_ci        oc->read_packet = aal_read_packet;
539cabdff1aSopenharmony_ci        framesize = 4096;
540cabdff1aSopenharmony_ci        break;
541cabdff1aSopenharmony_ci    default:
542cabdff1aSopenharmony_ci        av_log(s, AV_LOG_ERROR, "Unsupported codec %d!\n", buf[32]);
543cabdff1aSopenharmony_ci        return AVERROR(ENOSYS);
544cabdff1aSopenharmony_ci    }
545cabdff1aSopenharmony_ci
546cabdff1aSopenharmony_ci    st->codecpar->block_align = framesize;
547cabdff1aSopenharmony_ci
548cabdff1aSopenharmony_ci    return 0;
549cabdff1aSopenharmony_ci}
550cabdff1aSopenharmony_ci
551cabdff1aSopenharmony_cistatic int oma_read_packet(AVFormatContext *s, AVPacket *pkt)
552cabdff1aSopenharmony_ci{
553cabdff1aSopenharmony_ci    OMAContext *oc  = s->priv_data;
554cabdff1aSopenharmony_ci    return oc->read_packet(s, pkt);
555cabdff1aSopenharmony_ci}
556cabdff1aSopenharmony_ci
557cabdff1aSopenharmony_cistatic int oma_read_probe(const AVProbeData *p)
558cabdff1aSopenharmony_ci{
559cabdff1aSopenharmony_ci    const uint8_t *buf = p->buf;
560cabdff1aSopenharmony_ci    unsigned tag_len = 0;
561cabdff1aSopenharmony_ci
562cabdff1aSopenharmony_ci    if (p->buf_size >= ID3v2_HEADER_SIZE && ff_id3v2_match(buf, ID3v2_EA3_MAGIC))
563cabdff1aSopenharmony_ci        tag_len = ff_id3v2_tag_len(buf);
564cabdff1aSopenharmony_ci
565cabdff1aSopenharmony_ci    /* This check cannot overflow as tag_len has at most 28 bits */
566cabdff1aSopenharmony_ci    if (p->buf_size < tag_len + 5)
567cabdff1aSopenharmony_ci        /* EA3 header comes late, might be outside of the probe buffer */
568cabdff1aSopenharmony_ci        return tag_len ? AVPROBE_SCORE_EXTENSION/2 : 0;
569cabdff1aSopenharmony_ci
570cabdff1aSopenharmony_ci    buf += tag_len;
571cabdff1aSopenharmony_ci
572cabdff1aSopenharmony_ci    if (!memcmp(buf, "EA3", 3) && !buf[4] && buf[5] == EA3_HEADER_SIZE)
573cabdff1aSopenharmony_ci        return AVPROBE_SCORE_MAX;
574cabdff1aSopenharmony_ci    else
575cabdff1aSopenharmony_ci        return 0;
576cabdff1aSopenharmony_ci}
577cabdff1aSopenharmony_ci
578cabdff1aSopenharmony_cistatic int oma_read_seek(struct AVFormatContext *s,
579cabdff1aSopenharmony_ci                         int stream_index, int64_t timestamp, int flags)
580cabdff1aSopenharmony_ci{
581cabdff1aSopenharmony_ci    OMAContext *oc = s->priv_data;
582cabdff1aSopenharmony_ci    AVStream *st = s->streams[0];
583cabdff1aSopenharmony_ci    int64_t err;
584cabdff1aSopenharmony_ci
585cabdff1aSopenharmony_ci    if (st->codecpar->codec_id == AV_CODEC_ID_ATRAC3PAL ||
586cabdff1aSopenharmony_ci        st->codecpar->codec_id == AV_CODEC_ID_ATRAC3AL)
587cabdff1aSopenharmony_ci        return -1;
588cabdff1aSopenharmony_ci
589cabdff1aSopenharmony_ci    err = ff_pcm_read_seek(s, stream_index, timestamp, flags);
590cabdff1aSopenharmony_ci    if (!oc->encrypted)
591cabdff1aSopenharmony_ci        return err;
592cabdff1aSopenharmony_ci
593cabdff1aSopenharmony_ci    /* readjust IV for CBC */
594cabdff1aSopenharmony_ci    if (err || avio_tell(s->pb) < oc->content_start)
595cabdff1aSopenharmony_ci        goto wipe;
596cabdff1aSopenharmony_ci    if ((err = avio_seek(s->pb, -8, SEEK_CUR)) < 0)
597cabdff1aSopenharmony_ci        goto wipe;
598cabdff1aSopenharmony_ci    if ((err = avio_read(s->pb, oc->iv, 8)) < 8) {
599cabdff1aSopenharmony_ci        if (err >= 0)
600cabdff1aSopenharmony_ci            err = AVERROR_EOF;
601cabdff1aSopenharmony_ci        goto wipe;
602cabdff1aSopenharmony_ci    }
603cabdff1aSopenharmony_ci
604cabdff1aSopenharmony_ci    return 0;
605cabdff1aSopenharmony_ciwipe:
606cabdff1aSopenharmony_ci    memset(oc->iv, 0, 8);
607cabdff1aSopenharmony_ci    return err;
608cabdff1aSopenharmony_ci}
609cabdff1aSopenharmony_ci
610cabdff1aSopenharmony_ciconst AVInputFormat ff_oma_demuxer = {
611cabdff1aSopenharmony_ci    .name           = "oma",
612cabdff1aSopenharmony_ci    .long_name      = NULL_IF_CONFIG_SMALL("Sony OpenMG audio"),
613cabdff1aSopenharmony_ci    .priv_data_size = sizeof(OMAContext),
614cabdff1aSopenharmony_ci    .flags_internal = FF_FMT_INIT_CLEANUP,
615cabdff1aSopenharmony_ci    .read_probe     = oma_read_probe,
616cabdff1aSopenharmony_ci    .read_header    = oma_read_header,
617cabdff1aSopenharmony_ci    .read_packet    = oma_read_packet,
618cabdff1aSopenharmony_ci    .read_seek      = oma_read_seek,
619cabdff1aSopenharmony_ci    .read_close     = oma_read_close,
620cabdff1aSopenharmony_ci    .flags          = AVFMT_GENERIC_INDEX,
621cabdff1aSopenharmony_ci    .extensions     = "oma,omg,aa3",
622cabdff1aSopenharmony_ci    .codec_tag      = ff_oma_codec_tags_list,
623cabdff1aSopenharmony_ci};
624