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

libavformat/qcp.c

Go to the documentation of this file.
00001 /*
00002  * QCP format (.qcp) demuxer
00003  * Copyright (c) 2009 Kenan Gillet
00004  *
00005  * This file is part of Libav.
00006  *
00007  * Libav 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  * Libav 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 Libav; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 
00030 #include "libavutil/intreadwrite.h"
00031 #include "avformat.h"
00032 
00033 typedef struct {
00034     uint32_t data_size;                     
00035 
00036 #define QCP_MAX_MODE 4
00037     int16_t rates_per_mode[QCP_MAX_MODE+1]; 
00038 
00039 } QCPContext;
00040 
00045 static const uint8_t guid_qcelp_13k_part[15] = {
00046     0x6d, 0x7f, 0x5e, 0x15, 0xb1, 0xd0, 0x11, 0xba,
00047     0x91, 0x00, 0x80, 0x5f, 0xb4, 0xb9, 0x7e
00048 };
00049 
00053 static const uint8_t guid_evrc[16] = {
00054     0x8d, 0xd4, 0x89, 0xe6, 0x76, 0x90, 0xb5, 0x46,
00055     0x91, 0xef, 0x73, 0x6a, 0x51, 0x00, 0xce, 0xb4
00056 };
00057 
00061 static const uint8_t guid_smv[16] = {
00062     0x75, 0x2b, 0x7c, 0x8d, 0x97, 0xa7, 0x49, 0xed,
00063     0x98, 0x5e, 0xd5, 0x3c, 0x8c, 0xc7, 0x5f, 0x84
00064 };
00065 
00070 static int is_qcelp_13k_guid(const uint8_t *guid) {
00071     return (guid[0] == 0x41 || guid[0] == 0x42)
00072         && !memcmp(guid+1, guid_qcelp_13k_part, sizeof(guid_qcelp_13k_part));
00073 }
00074 
00075 static int qcp_probe(AVProbeData *pd)
00076 {
00077     if (AV_RL32(pd->buf  ) == AV_RL32("RIFF") &&
00078         AV_RL64(pd->buf+8) == AV_RL64("QLCMfmt "))
00079         return AVPROBE_SCORE_MAX;
00080     return 0;
00081 }
00082 
00083 static int qcp_read_header(AVFormatContext *s, AVFormatParameters *ap)
00084 {
00085     AVIOContext *pb = s->pb;
00086     QCPContext    *c  = s->priv_data;
00087     AVStream      *st = avformat_new_stream(s, NULL);
00088     uint8_t       buf[16];
00089     int           i, nb_rates;
00090 
00091     if (!st)
00092         return AVERROR(ENOMEM);
00093 
00094     avio_rb32(pb);                    // "RIFF"
00095     avio_skip(pb, 4 + 8 + 4 + 1 + 1);    // filesize + "QLCMfmt " + chunk-size + major-version + minor-version
00096 
00097     st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
00098     st->codec->channels   = 1;
00099     avio_read(pb, buf, 16);
00100     if (is_qcelp_13k_guid(buf)) {
00101         st->codec->codec_id = CODEC_ID_QCELP;
00102     } else if (!memcmp(buf, guid_evrc, 16)) {
00103         av_log(s, AV_LOG_ERROR, "EVRC codec is not supported.\n");
00104         return AVERROR_PATCHWELCOME;
00105     } else if (!memcmp(buf, guid_smv, 16)) {
00106         av_log(s, AV_LOG_ERROR, "SMV codec is not supported.\n");
00107         return AVERROR_PATCHWELCOME;
00108     } else {
00109         av_log(s, AV_LOG_ERROR, "Unknown codec GUID.\n");
00110         return AVERROR_INVALIDDATA;
00111     }
00112     avio_skip(pb, 2 + 80); // codec-version + codec-name
00113     st->codec->bit_rate = avio_rl16(pb);
00114 
00115     s->packet_size = avio_rl16(pb);
00116     avio_skip(pb, 2); // block-size
00117     st->codec->sample_rate = avio_rl16(pb);
00118     avio_skip(pb, 2); // sample-size
00119 
00120     memset(c->rates_per_mode, -1, sizeof(c->rates_per_mode));
00121     nb_rates = avio_rl32(pb);
00122     nb_rates = FFMIN(nb_rates, 8);
00123     for (i=0; i<nb_rates; i++) {
00124         int size = avio_r8(pb);
00125         int mode = avio_r8(pb);
00126         if (mode > QCP_MAX_MODE) {
00127             av_log(s, AV_LOG_WARNING, "Unknown entry %d=>%d in rate-map-table.\n ", mode, size);
00128         } else
00129             c->rates_per_mode[mode] = size;
00130     }
00131     avio_skip(pb, 16 - 2*nb_rates + 20); // empty entries of rate-map-table + reserved
00132 
00133     return 0;
00134 }
00135 
00136 static int qcp_read_packet(AVFormatContext *s, AVPacket *pkt)
00137 {
00138     AVIOContext *pb = s->pb;
00139     QCPContext    *c  = s->priv_data;
00140     unsigned int  chunk_size, tag;
00141 
00142     while(!pb->eof_reached) {
00143         if (c->data_size) {
00144             int pkt_size, ret, mode = avio_r8(pb);
00145 
00146             if (s->packet_size) {
00147                 pkt_size = s->packet_size - 1;
00148             } else if (mode > QCP_MAX_MODE || (pkt_size = c->rates_per_mode[mode]) < 0) {
00149                 c->data_size--;
00150                 continue;
00151             }
00152 
00153             if (c->data_size <= pkt_size) {
00154                 av_log(s, AV_LOG_WARNING, "Data chunk is too small.\n");
00155                 pkt_size = c->data_size - 1;
00156             }
00157 
00158             if ((ret = av_get_packet(pb, pkt, pkt_size)) >= 0) {
00159                 if (pkt_size != ret)
00160                     av_log(s, AV_LOG_ERROR, "Packet size is too small.\n");
00161 
00162                 c->data_size -= pkt_size + 1;
00163             }
00164             return ret;
00165         }
00166 
00167         if (avio_tell(pb) & 1 && avio_r8(pb))
00168             av_log(s, AV_LOG_WARNING, "Padding should be 0.\n");
00169 
00170         tag        = avio_rl32(pb);
00171         chunk_size = avio_rl32(pb);
00172         switch (tag) {
00173         case MKTAG('v', 'r', 'a', 't'):
00174             if (avio_rl32(pb)) // var-rate-flag
00175                 s->packet_size = 0;
00176             avio_skip(pb, 4); // size-in-packets
00177             break;
00178         case MKTAG('d', 'a', 't', 'a'):
00179             c->data_size = chunk_size;
00180             break;
00181 
00182         default:
00183             avio_skip(pb, chunk_size);
00184         }
00185     }
00186     return AVERROR_EOF;
00187 }
00188 
00189 AVInputFormat ff_qcp_demuxer = {
00190     .name           = "qcp",
00191     .long_name      = NULL_IF_CONFIG_SMALL("QCP format"),
00192     .priv_data_size = sizeof(QCPContext),
00193     .read_probe     = qcp_probe,
00194     .read_header    = qcp_read_header,
00195     .read_packet    = qcp_read_packet,
00196 };
Generated on Sun Apr 22 2012 21:54:08 for Libav by doxygen 1.7.1