Coverage Report

Created: 2025-12-31 07:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ffmpeg/libavformat/xa.c
Line
Count
Source
1
/*
2
 * Maxis XA (.xa) File Demuxer
3
 * Copyright (c) 2008 Robert Marston
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
/**
23
 * @file
24
 * Maxis XA File Demuxer
25
 * by Robert Marston (rmarston@gmail.com)
26
 * for more information on the XA audio format see
27
 *   http://wiki.multimedia.cx/index.php?title=Maxis_XA
28
 */
29
30
#include "libavutil/intreadwrite.h"
31
#include "avformat.h"
32
#include "demux.h"
33
#include "internal.h"
34
35
793
#define XA00_TAG MKTAG('X', 'A', 0, 0)
36
1.22k
#define XAI0_TAG MKTAG('X', 'A', 'I', 0)
37
1.73k
#define XAJ0_TAG MKTAG('X', 'A', 'J', 0)
38
39
typedef struct MaxisXADemuxContext {
40
    uint32_t out_size;
41
    uint32_t sent_bytes;
42
} MaxisXADemuxContext;
43
44
static int xa_probe(const AVProbeData *p)
45
942k
{
46
942k
    int channels, srate, bits_per_sample;
47
942k
    if (p->buf_size < 24)
48
182k
        return 0;
49
760k
    switch(AV_RL32(p->buf)) {
50
793
    case XA00_TAG:
51
1.22k
    case XAI0_TAG:
52
1.73k
    case XAJ0_TAG:
53
1.73k
        break;
54
758k
    default:
55
758k
        return 0;
56
760k
    }
57
1.73k
    channels        = AV_RL16(p->buf + 10);
58
1.73k
    srate           = AV_RL32(p->buf + 12);
59
1.73k
    bits_per_sample = AV_RL16(p->buf + 22);
60
1.73k
    if (!channels || channels > 8 || !srate || srate > 192000 ||
61
655
        bits_per_sample < 4 || bits_per_sample > 32)
62
1.54k
        return 0;
63
188
    return AVPROBE_SCORE_EXTENSION;
64
1.73k
}
65
66
static int xa_read_header(AVFormatContext *s)
67
1.41k
{
68
1.41k
    MaxisXADemuxContext *xa = s->priv_data;
69
1.41k
    AVIOContext *pb = s->pb;
70
1.41k
    AVStream *st;
71
72
    /*Set up the XA Audio Decoder*/
73
1.41k
    st = avformat_new_stream(s, NULL);
74
1.41k
    if (!st)
75
0
        return AVERROR(ENOMEM);
76
77
1.41k
    st->codecpar->codec_type   = AVMEDIA_TYPE_AUDIO;
78
1.41k
    st->codecpar->codec_id     = AV_CODEC_ID_ADPCM_EA_MAXIS_XA;
79
1.41k
    avio_skip(pb, 4);       /* Skip the XA ID */
80
1.41k
    xa->out_size            =  avio_rl32(pb);
81
1.41k
    avio_skip(pb, 2);       /* Skip the tag */
82
1.41k
    st->codecpar->ch_layout.nb_channels = avio_rl16(pb);
83
1.41k
    st->codecpar->sample_rate  = avio_rl32(pb);
84
1.41k
    avio_skip(pb, 4);       /* Skip average byte rate */
85
1.41k
    avio_skip(pb, 2);       /* Skip block align */
86
1.41k
    avio_skip(pb, 2);       /* Skip bits-per-sample */
87
88
1.41k
    if (!st->codecpar->ch_layout.nb_channels || !st->codecpar->sample_rate)
89
143
        return AVERROR_INVALIDDATA;
90
91
1.27k
    st->codecpar->bit_rate = av_clip(15LL * st->codecpar->ch_layout.nb_channels * 8 *
92
1.27k
                                  st->codecpar->sample_rate / 28, 0, INT_MAX);
93
94
1.27k
    avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
95
1.27k
    st->start_time = 0;
96
97
1.27k
    return 0;
98
1.41k
}
99
100
static int xa_read_packet(AVFormatContext *s,
101
                          AVPacket *pkt)
102
108k
{
103
108k
    MaxisXADemuxContext *xa = s->priv_data;
104
108k
    AVStream *st = s->streams[0];
105
108k
    AVIOContext *pb = s->pb;
106
108k
    unsigned int packet_size;
107
108k
    int ret;
108
109
108k
    if (xa->sent_bytes >= xa->out_size)
110
908
        return AVERROR_EOF;
111
    /* 1 byte header and 14 bytes worth of samples * number channels per block */
112
107k
    packet_size = 15*st->codecpar->ch_layout.nb_channels;
113
114
107k
    ret = av_get_packet(pb, pkt, packet_size);
115
107k
    if(ret < 0)
116
1.43k
        return ret;
117
118
106k
    pkt->stream_index = st->index;
119
106k
    xa->sent_bytes += packet_size;
120
106k
    pkt->duration = 28;
121
122
106k
    return ret;
123
107k
}
124
125
const FFInputFormat ff_xa_demuxer = {
126
    .p.name         = "xa",
127
    .p.long_name    = NULL_IF_CONFIG_SMALL("Maxis XA"),
128
    .priv_data_size = sizeof(MaxisXADemuxContext),
129
    .read_probe     = xa_probe,
130
    .read_header    = xa_read_header,
131
    .read_packet    = xa_read_packet,
132
};