Coverage Report

Created: 2026-10-28 08:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ffmpeg/libavformat/act.c
Line
Count
Source
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
4.33k
#define CHUNK_SIZE 512
30
963k
#define RIFF_TAG MKTAG('R','I','F','F')
31
6.72k
#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
963k
{
41
963k
    int i;
42
43
963k
    if ((AV_RL32(&p->buf[0]) != RIFF_TAG) ||
44
6.72k
        (AV_RL32(&p->buf[8]) != WAVE_TAG) ||
45
3.15k
        (AV_RL32(&p->buf[16]) != 16))
46
961k
    return 0;
47
48
    //We can't be sure that this is ACT and not regular WAV
49
1.74k
    if (p->buf_size<512)
50
1.02k
        return 0;
51
52
69.6k
    for(i=44; i<256; i++)
53
69.3k
        if(p->buf[i])
54
426
            return 0;
55
56
300
    if(p->buf[256]!=0x84)
57
231
        return 0;
58
59
12.3k
    for(i=264; i<512; i++)
60
12.3k
        if(p->buf[i])
61
21
            return 0;
62
63
48
    return AVPROBE_SCORE_MAX;
64
69
}
65
66
static int read_header(AVFormatContext *s)
67
1.92k
{
68
1.92k
    ACTContext* ctx = s->priv_data;
69
1.92k
    AVIOContext *pb = s->pb;
70
1.92k
    int size;
71
1.92k
    AVStream* st;
72
1.92k
    int ret;
73
74
1.92k
    int min,sec,msec;
75
76
1.92k
    st = avformat_new_stream(s, NULL);
77
1.92k
    if (!st)
78
0
        return AVERROR(ENOMEM);
79
80
1.92k
    avio_skip(pb, 16);
81
1.92k
    size=avio_rl32(pb);
82
1.92k
    ret = ff_get_wav_header(s, pb, st->codecpar, size, 0);
83
1.92k
    if (ret < 0)
84
817
        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
1.10k
    if (st->codecpar->sample_rate != 8000) {
91
359
        av_log(s, AV_LOG_ERROR, "Sample rate %d is not supported.\n", st->codecpar->sample_rate);
92
359
        return AVERROR_INVALIDDATA;
93
359
    }
94
95
749
    st->codecpar->frame_size=80;
96
749
    st->codecpar->ch_layout.nb_channels = 1;
97
749
    avpriv_set_pts_info(st, 64, 1, 100);
98
99
749
    st->codecpar->codec_id=AV_CODEC_ID_G729;
100
101
749
    avio_seek(pb, 257, SEEK_SET);
102
749
    msec=avio_rl16(pb);
103
749
    sec=avio_r8(pb);
104
749
    min=avio_rl32(pb);
105
106
749
    st->duration = av_rescale(1000*(min*60+sec)+msec, st->codecpar->sample_rate, 1000 * st->codecpar->frame_size);
107
108
749
    ctx->bytes_left_in_chunk=CHUNK_SIZE;
109
110
749
    avio_seek(pb, 512, SEEK_SET);
111
112
749
    return 0;
113
1.10k
}
114
115
116
static int read_packet(AVFormatContext *s,
117
                          AVPacket *pkt)
118
187k
{
119
187k
    ACTContext *ctx = s->priv_data;
120
187k
    AVIOContext *pb = s->pb;
121
187k
    int ret;
122
187k
    int frame_size=s->streams[0]->codecpar->sample_rate==8000?10:22;
123
124
125
187k
    if(s->streams[0]->codecpar->sample_rate==8000)
126
187k
        ret=av_new_packet(pkt, 10);
127
0
    else
128
0
        ret=av_new_packet(pkt, 11);
129
130
187k
    if(ret)
131
0
        return ret;
132
133
187k
    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
187k
    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
187k
    else // 8000 Hz
171
187k
    {
172
187k
        ret = ffio_read_size(pb, ctx->audio_buffer, frame_size);
173
174
187k
        if(ret<0)
175
1.27k
            return ret;
176
177
186k
        pkt->data[0]=ctx->audio_buffer[5];
178
186k
        pkt->data[1]=ctx->audio_buffer[0];
179
186k
        pkt->data[2]=ctx->audio_buffer[6];
180
186k
        pkt->data[3]=ctx->audio_buffer[1];
181
186k
        pkt->data[4]=ctx->audio_buffer[7];
182
186k
        pkt->data[5]=ctx->audio_buffer[2];
183
186k
        pkt->data[6]=ctx->audio_buffer[8];
184
186k
        pkt->data[7]=ctx->audio_buffer[3];
185
186k
        pkt->data[8]=ctx->audio_buffer[9];
186
186k
        pkt->data[9]=ctx->audio_buffer[4];
187
186k
    }
188
189
186k
    ctx->bytes_left_in_chunk -= frame_size;
190
191
186k
    if(ctx->bytes_left_in_chunk < frame_size)
192
3.58k
    {
193
3.58k
        avio_skip(pb, ctx->bytes_left_in_chunk);
194
3.58k
        ctx->bytes_left_in_chunk=CHUNK_SIZE;
195
3.58k
    }
196
197
186k
    pkt->duration=1;
198
199
186k
    return ret;
200
187k
}
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
};