Coverage Report

Created: 2026-07-25 07:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ffmpeg/libavformat/acedec.c
Line
Count
Source
1
/*
2
 * ACE demuxer
3
 * Copyright (c) 2020 Paul B Mahol
4
 *
5
 * This file is part of FFmpeg.
6
 *
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.
11
 *
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.
16
 *
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
20
 */
21
22
#include "libavutil/intreadwrite.h"
23
#include "avformat.h"
24
#include "demux.h"
25
#include "internal.h"
26
27
static int ace_probe(const AVProbeData *p)
28
967k
{
29
967k
    uint32_t asc;
30
31
967k
    if (AV_RB32(p->buf) != MKBETAG('A','A','C',' '))
32
966k
        return 0;
33
1.01k
    if (p->buf_size < 0x44)
34
243
        return 0;
35
773
    asc = AV_RB32(p->buf + 0x40);
36
773
    if (asc < 0x44 || asc > p->buf_size - 4)
37
619
        return 0;
38
154
    if (AV_RB32(p->buf + asc) != MKBETAG('A','S','C',' '))
39
154
        return 0;
40
41
0
    return AVPROBE_SCORE_MAX / 2 + 1;
42
154
}
43
44
static int ace_read_header(AVFormatContext *s)
45
1.24k
{
46
1.24k
    AVIOContext *pb = s->pb;
47
1.24k
    AVCodecParameters *par;
48
1.24k
    int ret, codec, rate, nb_channels;
49
1.24k
    uint32_t asc_pos, size;
50
1.24k
    AVStream *st;
51
52
1.24k
    avio_skip(pb, 0x40);
53
1.24k
    asc_pos = avio_rb32(pb);
54
1.24k
    if (asc_pos < 0x44)
55
32
        return AVERROR_INVALIDDATA;
56
1.21k
    avio_skip(pb, asc_pos - 0x44);
57
1.21k
    if (avio_rb32(pb) != MKBETAG('A','S','C',' '))
58
347
        return AVERROR_INVALIDDATA;
59
867
    avio_skip(pb, 0xec);
60
867
    codec = avio_rb32(pb);
61
867
    nb_channels = avio_rb32(pb);
62
867
    if (nb_channels <= 0 || nb_channels > 8)
63
83
        return AVERROR_INVALIDDATA;
64
784
    size = avio_rb32(pb);
65
784
    if (size == 0)
66
3
        return AVERROR_INVALIDDATA;
67
781
    rate = avio_rb32(pb);
68
781
    if (rate <= 0)
69
68
        return AVERROR_INVALIDDATA;
70
713
    avio_skip(pb, 16);
71
72
713
    st = avformat_new_stream(s, NULL);
73
713
    if (!st)
74
0
        return AVERROR(ENOMEM);
75
713
    st->start_time = 0;
76
713
    par = st->codecpar;
77
713
    par->codec_type  = AVMEDIA_TYPE_AUDIO;
78
713
    par->ch_layout.nb_channels = nb_channels;
79
713
    par->sample_rate = rate;
80
713
    par->block_align = (codec == 4 ? 0x60 : codec == 5 ? 0x98 : 0xC0) * nb_channels;
81
713
    st->duration     = (size / par->block_align) * 1024LL;
82
713
    par->codec_id    = AV_CODEC_ID_ATRAC3;
83
84
713
    ret = ff_alloc_extradata(par, 14);
85
713
    if (ret < 0)
86
0
        return ret;
87
88
713
    AV_WL16(st->codecpar->extradata, 1);
89
713
    AV_WL16(st->codecpar->extradata+2, 2048 * nb_channels);
90
713
    AV_WL16(st->codecpar->extradata+4, 0);
91
713
    AV_WL16(st->codecpar->extradata+6, codec == 4 ? 1 : 0);
92
713
    AV_WL16(st->codecpar->extradata+8, codec == 4 ? 1 : 0);
93
713
    AV_WL16(st->codecpar->extradata+10, 1);
94
713
    AV_WL16(st->codecpar->extradata+12, 0);
95
96
713
    avpriv_set_pts_info(st, 64, 1, par->sample_rate);
97
98
713
    return 0;
99
713
}
100
101
static int ace_read_packet(AVFormatContext *s, AVPacket *pkt)
102
148k
{
103
148k
    AVCodecParameters *par = s->streams[0]->codecpar;
104
105
148k
    return av_get_packet(s->pb, pkt, par->block_align);
106
148k
}
107
108
const FFInputFormat ff_ace_demuxer = {
109
    .p.name         = "ace",
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,
115
};