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