FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/acedec.c
Date: 2024-04-25 05:10:44
Exec Total Coverage
Lines: 3 58 5.2%
Functions: 1 3 33.3%
Branches: 1 30 3.3%

Line Branch Exec 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 7128 static int ace_probe(const AVProbeData *p)
28 {
29 uint32_t asc;
30
31
1/2
✓ Branch 0 taken 7128 times.
✗ Branch 1 not taken.
7128 if (AV_RB32(p->buf) != MKBETAG('A','A','C',' '))
32 7128 return 0;
33 if (p->buf_size < 0x44)
34 return 0;
35 asc = AV_RB32(p->buf + 0x40);
36 if (asc < 0x44 || asc > p->buf_size - 4)
37 return 0;
38 if (AV_RB32(p->buf + asc) != MKBETAG('A','S','C',' '))
39 return 0;
40
41 return AVPROBE_SCORE_MAX / 2 + 1;
42 }
43
44 static int ace_read_header(AVFormatContext *s)
45 {
46 AVIOContext *pb = s->pb;
47 AVCodecParameters *par;
48 int ret, codec, rate, nb_channels;
49 uint32_t asc_pos, size;
50 AVStream *st;
51
52 avio_skip(pb, 0x40);
53 asc_pos = avio_rb32(pb);
54 if (asc_pos < 0x44)
55 return AVERROR_INVALIDDATA;
56 avio_skip(pb, asc_pos - 0x44);
57 if (avio_rb32(pb) != MKBETAG('A','S','C',' '))
58 return AVERROR_INVALIDDATA;
59 avio_skip(pb, 0xec);
60 codec = avio_rb32(pb);
61 nb_channels = avio_rb32(pb);
62 if (nb_channels <= 0 || nb_channels > 8)
63 return AVERROR_INVALIDDATA;
64 size = avio_rb32(pb);
65 if (size == 0)
66 return AVERROR_INVALIDDATA;
67 rate = avio_rb32(pb);
68 if (rate <= 0)
69 return AVERROR_INVALIDDATA;
70 avio_skip(pb, 16);
71
72 st = avformat_new_stream(s, NULL);
73 if (!st)
74 return AVERROR(ENOMEM);
75 st->start_time = 0;
76 par = st->codecpar;
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;
83
84 ret = ff_alloc_extradata(par, 14);
85 if (ret < 0)
86 return ret;
87
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);
95
96 avpriv_set_pts_info(st, 64, 1, par->sample_rate);
97
98 return 0;
99 }
100
101 static int ace_read_packet(AVFormatContext *s, AVPacket *pkt)
102 {
103 AVCodecParameters *par = s->streams[0]->codecpar;
104
105 return av_get_packet(s->pb, pkt, par->block_align);
106 }
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 };
116