3 * Copyright (c) 2020 Paul B Mahol
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 #include "libavutil/intreadwrite.h"
27 static int ace_probe(const AVProbeData
*p
)
31 if (AV_RB32(p
->buf
) != MKBETAG('A','A','C',' '))
33 if (p
->buf_size
< 0x44)
35 asc
= AV_RB32(p
->buf
+ 0x40);
36 if (asc
< 0x44 || asc
> p
->buf_size
- 4)
38 if (AV_RB32(p
->buf
+ asc
) != MKBETAG('A','S','C',' '))
41 return AVPROBE_SCORE_MAX
/ 2 + 1;
44 static int ace_read_header(AVFormatContext
*s
)
46 AVIOContext
*pb
= s
->pb
;
47 AVCodecParameters
*par
;
48 int ret
, codec
, rate
, nb_channels
;
49 uint32_t asc_pos
, size
;
53 asc_pos
= avio_rb32(pb
);
55 return AVERROR_INVALIDDATA
;
56 avio_skip(pb
, asc_pos
- 0x44);
57 if (avio_rb32(pb
) != MKBETAG('A','S','C',' '))
58 return AVERROR_INVALIDDATA
;
60 codec
= avio_rb32(pb
);
61 nb_channels
= avio_rb32(pb
);
62 if (nb_channels
<= 0 || nb_channels
> 8)
63 return AVERROR_INVALIDDATA
;
66 return AVERROR_INVALIDDATA
;
69 return AVERROR_INVALIDDATA
;
72 st
= avformat_new_stream(s
, NULL
);
74 return AVERROR(ENOMEM
);
77 par
->codec_type
= AVMEDIA_TYPE_AUDIO
;
78 par
->ch_layout
.nb_channels
= nb_channels
;
79 par
->sample_rate
= rate
;
80 par
->block_align
= (codec
== 4 ? 0x60 : codec
== 5 ? 0x98 : 0xC0) * nb_channels
;
81 st
->duration
= (size
/ par
->block_align
) * 1024LL;
82 par
->codec_id
= AV_CODEC_ID_ATRAC3
;
84 ret
= ff_alloc_extradata(par
, 14);
88 AV_WL16(st
->codecpar
->extradata
, 1);
89 AV_WL16(st
->codecpar
->extradata
+2, 2048 * nb_channels
);
90 AV_WL16(st
->codecpar
->extradata
+4, 0);
91 AV_WL16(st
->codecpar
->extradata
+6, codec
== 4 ? 1 : 0);
92 AV_WL16(st
->codecpar
->extradata
+8, codec
== 4 ? 1 : 0);
93 AV_WL16(st
->codecpar
->extradata
+10, 1);
94 AV_WL16(st
->codecpar
->extradata
+12, 0);
96 avpriv_set_pts_info(st
, 64, 1, par
->sample_rate
);
101 static int ace_read_packet(AVFormatContext
*s
, AVPacket
*pkt
)
103 AVCodecParameters
*par
= s
->streams
[0]->codecpar
;
105 return av_get_packet(s
->pb
, pkt
, par
->block_align
);
108 const FFInputFormat ff_ace_demuxer
= {
110 .p
.long_name
= NULL_IF_CONFIG_SMALL("tri-Ace Audio Container"),
111 .p
.flags
= AVFMT_GENERIC_INDEX
,
112 .read_probe
= ace_probe
,
113 .read_header
= ace_read_header
,
114 .read_packet
= ace_read_packet
,