1/* 2 * Creative Voice File demuxer. 3 * Copyright (c) 2006 Aurelien Jacobs <aurel@gnuage.org> 4 * 5 * This file is part of Libav. 6 * 7 * Libav 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 * Libav 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 Libav; 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 "voc.h" 24#include "internal.h" 25 26 27static int voc_probe(AVProbeData *p) 28{ 29 int version, check; 30 31 if (memcmp(p->buf, ff_voc_magic, sizeof(ff_voc_magic) - 1)) 32 return 0; 33 version = AV_RL16(p->buf + 22); 34 check = AV_RL16(p->buf + 24); 35 if (~version + 0x1234 != check) 36 return 10; 37 38 return AVPROBE_SCORE_MAX; 39} 40 41static int voc_read_header(AVFormatContext *s, AVFormatParameters *ap) 42{ 43 VocDecContext *voc = s->priv_data; 44 AVIOContext *pb = s->pb; 45 int header_size; 46 AVStream *st; 47 48 avio_skip(pb, 20); 49 header_size = avio_rl16(pb) - 22; 50 if (header_size != 4) { 51 av_log(s, AV_LOG_ERROR, "unknown header size: %d\n", header_size); 52 return AVERROR(ENOSYS); 53 } 54 avio_skip(pb, header_size); 55 st = avformat_new_stream(s, NULL); 56 if (!st) 57 return AVERROR(ENOMEM); 58 st->codec->codec_type = AVMEDIA_TYPE_AUDIO; 59 60 voc->remaining_size = 0; 61 return 0; 62} 63 64int 65voc_get_packet(AVFormatContext *s, AVPacket *pkt, AVStream *st, int max_size) 66{ 67 VocDecContext *voc = s->priv_data; 68 AVCodecContext *dec = st->codec; 69 AVIOContext *pb = s->pb; 70 VocType type; 71 int size, tmp_codec=-1; 72 int sample_rate = 0; 73 int channels = 1; 74 75 while (!voc->remaining_size) { 76 type = avio_r8(pb); 77 if (type == VOC_TYPE_EOF) 78 return AVERROR(EIO); 79 voc->remaining_size = avio_rl24(pb); 80 if (!voc->remaining_size) { 81 if (!s->pb->seekable) 82 return AVERROR(EIO); 83 voc->remaining_size = avio_size(pb) - avio_tell(pb); 84 } 85 max_size -= 4; 86 87 switch (type) { 88 case VOC_TYPE_VOICE_DATA: 89 dec->sample_rate = 1000000 / (256 - avio_r8(pb)); 90 if (sample_rate) 91 dec->sample_rate = sample_rate; 92 dec->channels = channels; 93 tmp_codec = avio_r8(pb); 94 dec->bits_per_coded_sample = av_get_bits_per_sample(dec->codec_id); 95 voc->remaining_size -= 2; 96 max_size -= 2; 97 channels = 1; 98 break; 99 100 case VOC_TYPE_VOICE_DATA_CONT: 101 break; 102 103 case VOC_TYPE_EXTENDED: 104 sample_rate = avio_rl16(pb); 105 avio_r8(pb); 106 channels = avio_r8(pb) + 1; 107 sample_rate = 256000000 / (channels * (65536 - sample_rate)); 108 voc->remaining_size = 0; 109 max_size -= 4; 110 break; 111 112 case VOC_TYPE_NEW_VOICE_DATA: 113 dec->sample_rate = avio_rl32(pb); 114 dec->bits_per_coded_sample = avio_r8(pb); 115 dec->channels = avio_r8(pb); 116 tmp_codec = avio_rl16(pb); 117 avio_skip(pb, 4); 118 voc->remaining_size -= 12; 119 max_size -= 12; 120 break; 121 122 default: 123 avio_skip(pb, voc->remaining_size); 124 max_size -= voc->remaining_size; 125 voc->remaining_size = 0; 126 break; 127 } 128 } 129 130 if (tmp_codec >= 0) { 131 tmp_codec = ff_codec_get_id(ff_voc_codec_tags, tmp_codec); 132 if (dec->codec_id == CODEC_ID_NONE) 133 dec->codec_id = tmp_codec; 134 else if (dec->codec_id != tmp_codec) 135 av_log(s, AV_LOG_WARNING, "Ignoring mid-stream change in audio codec\n"); 136 if (dec->codec_id == CODEC_ID_NONE) { 137 if (s->audio_codec_id == CODEC_ID_NONE) { 138 av_log(s, AV_LOG_ERROR, "unknown codec tag\n"); 139 return AVERROR(EINVAL); 140 } 141 av_log(s, AV_LOG_WARNING, "unknown codec tag\n"); 142 } 143 } 144 145 dec->bit_rate = dec->sample_rate * dec->bits_per_coded_sample; 146 147 if (max_size <= 0) 148 max_size = 2048; 149 size = FFMIN(voc->remaining_size, max_size); 150 voc->remaining_size -= size; 151 return av_get_packet(pb, pkt, size); 152} 153 154static int voc_read_packet(AVFormatContext *s, AVPacket *pkt) 155{ 156 return voc_get_packet(s, pkt, s->streams[0], 0); 157} 158 159AVInputFormat ff_voc_demuxer = { 160 .name = "voc", 161 .long_name = NULL_IF_CONFIG_SMALL("Creative Voice file format"), 162 .priv_data_size = sizeof(VocDecContext), 163 .read_probe = voc_probe, 164 .read_header = voc_read_header, 165 .read_packet = voc_read_packet, 166 .codec_tag=(const AVCodecTag* const []){ff_voc_codec_tags, 0}, 167}; 168