Coverage Report

Created: 2025-08-28 07:12

/src/ffmpeg/libavformat/act.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * ACT file format demuxer
3
 * Copyright (c) 2007-2008 Vladimir Voroshilov
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 "avio_internal.h"
25
#include "demux.h"
26
#include "riff.h"
27
#include "internal.h"
28
29
2.17k
#define CHUNK_SIZE 512
30
924k
#define RIFF_TAG MKTAG('R','I','F','F')
31
5.78k
#define WAVE_TAG MKTAG('W','A','V','E')
32
33
typedef struct{
34
    int bytes_left_in_chunk;
35
    uint8_t audio_buffer[22];///< temporary buffer for ACT frame
36
    char second_packet;      ///< 1 - if temporary buffer contains valid (second) G.729 packet
37
} ACTContext;
38
39
static int probe(const AVProbeData *p)
40
924k
{
41
924k
    int i;
42
43
924k
    if ((AV_RL32(&p->buf[0]) != RIFF_TAG) ||
44
924k
        (AV_RL32(&p->buf[8]) != WAVE_TAG) ||
45
924k
        (AV_RL32(&p->buf[16]) != 16))
46
923k
    return 0;
47
48
    //We can't be sure that this is ACT and not regular WAV
49
1.10k
    if (p->buf_size<512)
50
479
        return 0;
51
52
66.0k
    for(i=44; i<256; i++)
53
65.7k
        if(p->buf[i])
54
338
            return 0;
55
56
288
    if(p->buf[256]!=0x84)
57
216
        return 0;
58
59
12.5k
    for(i=264; i<512; i++)
60
12.4k
        if(p->buf[i])
61
23
            return 0;
62
63
49
    return AVPROBE_SCORE_MAX;
64
72
}
65
66
static int read_header(AVFormatContext *s)
67
6.24k
{
68
6.24k
    ACTContext* ctx = s->priv_data;
69
6.24k
    AVIOContext *pb = s->pb;
70
6.24k
    int size;
71
6.24k
    AVStream* st;
72
6.24k
    int ret;
73
74
6.24k
    int min,sec,msec;
75
76
6.24k
    st = avformat_new_stream(s, NULL);
77
6.24k
    if (!st)
78
0
        return AVERROR(ENOMEM);
79
80
6.24k
    avio_skip(pb, 16);
81
6.24k
    size=avio_rl32(pb);
82
6.24k
    ret = ff_get_wav_header(s, pb, st->codecpar, size, 0);
83
6.24k
    if (ret < 0)
84
5.54k
        return ret;
85
86
    /*
87
      8000Hz (Fine-rec) file format has 10 bytes long
88
      packets with 10ms of sound data in them
89
    */
90
696
    if (st->codecpar->sample_rate != 8000) {
91
170
        av_log(s, AV_LOG_ERROR, "Sample rate %d is not supported.\n", st->codecpar->sample_rate);
92
170
        return AVERROR_INVALIDDATA;
93
170
    }
94
95
526
    st->codecpar->frame_size=80;
96
526
    st->codecpar->ch_layout.nb_channels = 1;
97
526
    avpriv_set_pts_info(st, 64, 1, 100);
98
99
526
    st->codecpar->codec_id=AV_CODEC_ID_G729;
100
101
526
    avio_seek(pb, 257, SEEK_SET);
102
526
    msec=avio_rl16(pb);
103
526
    sec=avio_r8(pb);
104
526
    min=avio_rl32(pb);
105
106
526
    st->duration = av_rescale(1000*(min*60+sec)+msec, st->codecpar->sample_rate, 1000 * st->codecpar->frame_size);
107
108
526
    ctx->bytes_left_in_chunk=CHUNK_SIZE;
109
110
526
    avio_seek(pb, 512, SEEK_SET);
111
112
526
    return 0;
113
696
}
114
115
116
static int read_packet(AVFormatContext *s,
117
                          AVPacket *pkt)
118
87.7k
{
119
87.7k
    ACTContext *ctx = s->priv_data;
120
87.7k
    AVIOContext *pb = s->pb;
121
87.7k
    int ret;
122
87.7k
    int frame_size=s->streams[0]->codecpar->sample_rate==8000?10:22;
123
124
125
87.7k
    if(s->streams[0]->codecpar->sample_rate==8000)
126
87.7k
        ret=av_new_packet(pkt, 10);
127
0
    else
128
0
        ret=av_new_packet(pkt, 11);
129
130
87.7k
    if(ret)
131
0
        return ret;
132
133
87.7k
    if(s->streams[0]->codecpar->sample_rate==4400 && !ctx->second_packet)
134
0
    {
135
0
        ret = ffio_read_size(pb, ctx->audio_buffer, frame_size);
136
137
0
        if(ret<0)
138
0
            return ret;
139
140
0
        pkt->data[0]=ctx->audio_buffer[11];
141
0
        pkt->data[1]=ctx->audio_buffer[0];
142
0
        pkt->data[2]=ctx->audio_buffer[12];
143
0
        pkt->data[3]=ctx->audio_buffer[1];
144
0
        pkt->data[4]=ctx->audio_buffer[13];
145
0
        pkt->data[5]=ctx->audio_buffer[2];
146
0
        pkt->data[6]=ctx->audio_buffer[14];
147
0
        pkt->data[7]=ctx->audio_buffer[3];
148
0
        pkt->data[8]=ctx->audio_buffer[15];
149
0
        pkt->data[9]=ctx->audio_buffer[4];
150
0
        pkt->data[10]=ctx->audio_buffer[16];
151
152
0
        ctx->second_packet=1;
153
0
    }
154
87.7k
    else if(s->streams[0]->codecpar->sample_rate==4400 && ctx->second_packet)
155
0
    {
156
0
        pkt->data[0]=ctx->audio_buffer[5];
157
0
        pkt->data[1]=ctx->audio_buffer[17];
158
0
        pkt->data[2]=ctx->audio_buffer[6];
159
0
        pkt->data[3]=ctx->audio_buffer[18];
160
0
        pkt->data[4]=ctx->audio_buffer[7];
161
0
        pkt->data[5]=ctx->audio_buffer[19];
162
0
        pkt->data[6]=ctx->audio_buffer[8];
163
0
        pkt->data[7]=ctx->audio_buffer[20];
164
0
        pkt->data[8]=ctx->audio_buffer[9];
165
0
        pkt->data[9]=ctx->audio_buffer[21];
166
0
        pkt->data[10]=ctx->audio_buffer[10];
167
168
0
        ctx->second_packet=0;
169
0
    }
170
87.7k
    else // 8000 Hz
171
87.7k
    {
172
87.7k
        ret = ffio_read_size(pb, ctx->audio_buffer, frame_size);
173
174
87.7k
        if(ret<0)
175
918
            return ret;
176
177
86.8k
        pkt->data[0]=ctx->audio_buffer[5];
178
86.8k
        pkt->data[1]=ctx->audio_buffer[0];
179
86.8k
        pkt->data[2]=ctx->audio_buffer[6];
180
86.8k
        pkt->data[3]=ctx->audio_buffer[1];
181
86.8k
        pkt->data[4]=ctx->audio_buffer[7];
182
86.8k
        pkt->data[5]=ctx->audio_buffer[2];
183
86.8k
        pkt->data[6]=ctx->audio_buffer[8];
184
86.8k
        pkt->data[7]=ctx->audio_buffer[3];
185
86.8k
        pkt->data[8]=ctx->audio_buffer[9];
186
86.8k
        pkt->data[9]=ctx->audio_buffer[4];
187
86.8k
    }
188
189
86.8k
    ctx->bytes_left_in_chunk -= frame_size;
190
191
86.8k
    if(ctx->bytes_left_in_chunk < frame_size)
192
1.65k
    {
193
1.65k
        avio_skip(pb, ctx->bytes_left_in_chunk);
194
1.65k
        ctx->bytes_left_in_chunk=CHUNK_SIZE;
195
1.65k
    }
196
197
86.8k
    pkt->duration=1;
198
199
86.8k
    return ret;
200
87.7k
}
201
202
const FFInputFormat ff_act_demuxer = {
203
    .p.name         = "act",
204
    .p.long_name    = "ACT Voice file format",
205
    .priv_data_size = sizeof(ACTContext),
206
    .read_probe     = probe,
207
    .read_header    = read_header,
208
    .read_packet    = read_packet,
209
};