• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavformat/act.c

Go to the documentation of this file.
00001 /*
00002  * ACT file format demuxer
00003  * Copyright (c) 2007-2008 Vladimir Voroshilov
00004  *
00005  * This file is part of FFmpeg.
00006  *
00007  * FFmpeg is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * FFmpeg is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with FFmpeg; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 #include "avformat.h"
00022 #include "riff.h"
00023 #include "internal.h"
00024 #include "libavcodec/get_bits.h"
00025 
00026 #define CHUNK_SIZE 512
00027 #define RIFF_TAG MKTAG('R','I','F','F')
00028 #define WAVE_TAG MKTAG('W','A','V','E')
00029 
00030 typedef struct{
00031     int bytes_left_in_chunk;
00032     uint8_t audio_buffer[22];
00033     char second_packet;      
00034 } ACTContext;
00035 
00036 static int probe(AVProbeData *p)
00037 {
00038     int i;
00039 
00040     if ((AV_RL32(&p->buf[0]) != RIFF_TAG) ||
00041         (AV_RL32(&p->buf[8]) != WAVE_TAG) ||
00042         (AV_RL32(&p->buf[16]) != 16))
00043     return 0;
00044 
00045     //We cant be sure that this is ACT and not regular WAV
00046     if (p->buf_size<512)
00047         return 0;
00048 
00049     for(i=44; i<256; i++)
00050         if(p->buf[i])
00051             return 0;
00052 
00053     if(p->buf[256]!=0x84)
00054         return 0;
00055 
00056     for(i=264; i<512; i++)
00057         if(p->buf[i])
00058             return 0;
00059 
00060     return AVPROBE_SCORE_MAX;
00061 }
00062 
00063 static int read_header(AVFormatContext *s,
00064                            AVFormatParameters *ap)
00065 {
00066     ACTContext* ctx = s->priv_data;
00067     AVIOContext *pb = s->pb;
00068     int size;
00069     AVStream* st;
00070 
00071     int min,sec,msec;
00072 
00073     st = avformat_new_stream(s, NULL);
00074     if (!st)
00075         return AVERROR(ENOMEM);
00076 
00077     avio_skip(pb, 16);
00078     size=avio_rl32(pb);
00079     ff_get_wav_header(pb, st->codec, size);
00080 
00081     /*
00082       8000Hz (Fine-rec) file format has 10 bytes long
00083       packets with 10ms of sound data in them
00084     */
00085     if (st->codec->sample_rate != 8000) {
00086         av_log(s, AV_LOG_ERROR, "Sample rate %d is not supported.\n", st->codec->sample_rate);
00087         return AVERROR_INVALIDDATA;
00088     }
00089 
00090     st->codec->frame_size=80;
00091     st->codec->channels=1;
00092     avpriv_set_pts_info(st, 64, 1, 100);
00093 
00094     st->codec->codec_id=CODEC_ID_G729;
00095 
00096     avio_seek(pb, 257, SEEK_SET);
00097     msec=avio_rl16(pb);
00098     sec=avio_r8(pb);
00099     min=avio_rl32(pb);
00100 
00101     st->duration = av_rescale(1000*(min*60+sec)+msec, st->codec->sample_rate, 1000 * st->codec->frame_size);
00102 
00103     ctx->bytes_left_in_chunk=CHUNK_SIZE;
00104 
00105     avio_seek(pb, 512, SEEK_SET);
00106 
00107     return 0;
00108 }
00109 
00110 
00111 static int read_packet(AVFormatContext *s,
00112                           AVPacket *pkt)
00113 {
00114     ACTContext *ctx = s->priv_data;
00115     AVIOContext *pb = s->pb;
00116     int ret;
00117     int frame_size=s->streams[0]->codec->sample_rate==8000?10:22;
00118 
00119 
00120     if(s->streams[0]->codec->sample_rate==8000)
00121         ret=av_new_packet(pkt, 10);
00122     else
00123         ret=av_new_packet(pkt, 11);
00124 
00125     if(ret)
00126         return ret;
00127 
00128     if(s->streams[0]->codec->sample_rate==4400 && !ctx->second_packet)
00129     {
00130         ret = avio_read(pb, ctx->audio_buffer, frame_size);
00131 
00132         if(ret<0)
00133             return ret;
00134         if(ret!=frame_size)
00135             return AVERROR(EIO);
00136 
00137         pkt->data[0]=ctx->audio_buffer[11];
00138         pkt->data[1]=ctx->audio_buffer[0];
00139         pkt->data[2]=ctx->audio_buffer[12];
00140         pkt->data[3]=ctx->audio_buffer[1];
00141         pkt->data[4]=ctx->audio_buffer[13];
00142         pkt->data[5]=ctx->audio_buffer[2];
00143         pkt->data[6]=ctx->audio_buffer[14];
00144         pkt->data[7]=ctx->audio_buffer[3];
00145         pkt->data[8]=ctx->audio_buffer[15];
00146         pkt->data[9]=ctx->audio_buffer[4];
00147         pkt->data[10]=ctx->audio_buffer[16];
00148 
00149         ctx->second_packet=1;
00150     }
00151     else if(s->streams[0]->codec->sample_rate==4400 && ctx->second_packet)
00152     {
00153         pkt->data[0]=ctx->audio_buffer[5];
00154         pkt->data[1]=ctx->audio_buffer[17];
00155         pkt->data[2]=ctx->audio_buffer[6];
00156         pkt->data[3]=ctx->audio_buffer[18];
00157         pkt->data[4]=ctx->audio_buffer[7];
00158         pkt->data[5]=ctx->audio_buffer[19];
00159         pkt->data[6]=ctx->audio_buffer[8];
00160         pkt->data[7]=ctx->audio_buffer[20];
00161         pkt->data[8]=ctx->audio_buffer[9];
00162         pkt->data[9]=ctx->audio_buffer[21];
00163         pkt->data[10]=ctx->audio_buffer[10];
00164 
00165         ctx->second_packet=0;
00166     }
00167     else // 8000 Hz
00168     {
00169         ret = avio_read(pb, ctx->audio_buffer, frame_size);
00170 
00171         if(ret<0)
00172             return ret;
00173         if(ret!=frame_size)
00174             return AVERROR(EIO);
00175 
00176         pkt->data[0]=ctx->audio_buffer[5];
00177         pkt->data[1]=ctx->audio_buffer[0];
00178         pkt->data[2]=ctx->audio_buffer[6];
00179         pkt->data[3]=ctx->audio_buffer[1];
00180         pkt->data[4]=ctx->audio_buffer[7];
00181         pkt->data[5]=ctx->audio_buffer[2];
00182         pkt->data[6]=ctx->audio_buffer[8];
00183         pkt->data[7]=ctx->audio_buffer[3];
00184         pkt->data[8]=ctx->audio_buffer[9];
00185         pkt->data[9]=ctx->audio_buffer[4];
00186     }
00187 
00188     ctx->bytes_left_in_chunk -= frame_size;
00189 
00190     if(ctx->bytes_left_in_chunk < frame_size)
00191     {
00192         avio_skip(pb, ctx->bytes_left_in_chunk);
00193         ctx->bytes_left_in_chunk=CHUNK_SIZE;
00194     }
00195 
00196     pkt->duration=1;
00197 
00198     return ret;
00199 }
00200 
00201 AVInputFormat ff_act_demuxer = {
00202     .name           = "act",
00203     .long_name      = "ACT Voice file format",
00204     .priv_data_size = sizeof(ACTContext),
00205     .read_probe     = probe,
00206     .read_header    = read_header,
00207     .read_packet    = read_packet,
00208 };
Generated on Fri Feb 1 2013 14:34:50 for FFmpeg by doxygen 1.7.1