diff --git a/libavformat/Makefile b/libavformat/Makefile index 27053f2814..b497b9398e 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -84,12 +84,12 @@ OBJS-$(CONFIG_AVI_DEMUXER) += avidec.o OBJS-$(CONFIG_AVI_MUXER) += avienc.o OBJS-$(CONFIG_AVISYNTH) += avisynth.o OBJS-$(CONFIG_AVM2_MUXER) += swfenc.o swf.o -OBJS-$(CONFIG_AVS_DEMUXER) += avs.o vocdec.o voc.o +OBJS-$(CONFIG_AVS_DEMUXER) += avs.o voc_packet.o voc.o OBJS-$(CONFIG_BETHSOFTVID_DEMUXER) += bethsoftvid.o OBJS-$(CONFIG_BFI_DEMUXER) += bfi.o OBJS-$(CONFIG_BINK_DEMUXER) += bink.o OBJS-$(CONFIG_BMV_DEMUXER) += bmv.o -OBJS-$(CONFIG_C93_DEMUXER) += c93.o vocdec.o voc.o +OBJS-$(CONFIG_C93_DEMUXER) += c93.o voc_packet.o voc.o OBJS-$(CONFIG_CAF_DEMUXER) += cafdec.o caf.o mov.o mov_chan.o \ replaygain.o OBJS-$(CONFIG_CAVSVIDEO_DEMUXER) += cavsvideodec.o rawdec.o @@ -350,7 +350,7 @@ OBJS-$(CONFIG_VC1_DEMUXER) += rawdec.o OBJS-$(CONFIG_VC1T_DEMUXER) += vc1test.o OBJS-$(CONFIG_VC1T_MUXER) += vc1testenc.o OBJS-$(CONFIG_VMD_DEMUXER) += sierravmd.o -OBJS-$(CONFIG_VOC_DEMUXER) += vocdec.o voc.o +OBJS-$(CONFIG_VOC_DEMUXER) += vocdec.o voc_packet.o voc.o OBJS-$(CONFIG_VOC_MUXER) += vocenc.o voc.o OBJS-$(CONFIG_VQF_DEMUXER) += vqf.o OBJS-$(CONFIG_W64_DEMUXER) += wavdec.o pcm.o diff --git a/libavformat/voc_packet.c b/libavformat/voc_packet.c new file mode 100644 index 0000000000..9e1c7469da --- /dev/null +++ b/libavformat/voc_packet.c @@ -0,0 +1,119 @@ +/* + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "avformat.h" +#include "internal.h" +#include "voc.h" + +int +ff_voc_get_packet(AVFormatContext *s, AVPacket *pkt, AVStream *st, int max_size) +{ + VocDecContext *voc = s->priv_data; + AVCodecContext *dec = st->codec; + AVIOContext *pb = s->pb; + VocType type; + int size, tmp_codec=-1; + int sample_rate = 0; + int channels = 1; + + while (!voc->remaining_size) { + type = avio_r8(pb); + if (type == VOC_TYPE_EOF) + return AVERROR(EIO); + voc->remaining_size = avio_rl24(pb); + if (!voc->remaining_size) { + if (!s->pb->seekable) + return AVERROR(EIO); + voc->remaining_size = avio_size(pb) - avio_tell(pb); + } + max_size -= 4; + + switch (type) { + case VOC_TYPE_VOICE_DATA: + if (!dec->sample_rate) { + dec->sample_rate = 1000000 / (256 - avio_r8(pb)); + if (sample_rate) + dec->sample_rate = sample_rate; + avpriv_set_pts_info(st, 64, 1, dec->sample_rate); + dec->channels = channels; + dec->bits_per_coded_sample = av_get_bits_per_sample(dec->codec_id); + } else + avio_skip(pb, 1); + tmp_codec = avio_r8(pb); + voc->remaining_size -= 2; + max_size -= 2; + channels = 1; + break; + + case VOC_TYPE_VOICE_DATA_CONT: + break; + + case VOC_TYPE_EXTENDED: + sample_rate = avio_rl16(pb); + avio_r8(pb); + channels = avio_r8(pb) + 1; + sample_rate = 256000000 / (channels * (65536 - sample_rate)); + voc->remaining_size = 0; + max_size -= 4; + break; + + case VOC_TYPE_NEW_VOICE_DATA: + if (!dec->sample_rate) { + dec->sample_rate = avio_rl32(pb); + avpriv_set_pts_info(st, 64, 1, dec->sample_rate); + dec->bits_per_coded_sample = avio_r8(pb); + dec->channels = avio_r8(pb); + } else + avio_skip(pb, 6); + tmp_codec = avio_rl16(pb); + avio_skip(pb, 4); + voc->remaining_size -= 12; + max_size -= 12; + break; + + default: + avio_skip(pb, voc->remaining_size); + max_size -= voc->remaining_size; + voc->remaining_size = 0; + break; + } + } + + if (tmp_codec >= 0) { + tmp_codec = ff_codec_get_id(ff_voc_codec_tags, tmp_codec); + if (dec->codec_id == AV_CODEC_ID_NONE) + dec->codec_id = tmp_codec; + else if (dec->codec_id != tmp_codec) + av_log(s, AV_LOG_WARNING, "Ignoring mid-stream change in audio codec\n"); + if (dec->codec_id == AV_CODEC_ID_NONE) { + if (s->audio_codec_id == AV_CODEC_ID_NONE) { + av_log(s, AV_LOG_ERROR, "unknown codec tag\n"); + return AVERROR(EINVAL); + } + av_log(s, AV_LOG_WARNING, "unknown codec tag\n"); + } + } + + dec->bit_rate = dec->sample_rate * dec->bits_per_coded_sample; + + if (max_size <= 0) + max_size = 2048; + size = FFMIN(voc->remaining_size, max_size); + voc->remaining_size -= size; + return av_get_packet(pb, pkt, size); +} diff --git a/libavformat/vocdec.c b/libavformat/vocdec.c index 459952203e..aca77ced63 100644 --- a/libavformat/vocdec.c +++ b/libavformat/vocdec.c @@ -23,105 +23,6 @@ #include "voc.h" #include "internal.h" -int -ff_voc_get_packet(AVFormatContext *s, AVPacket *pkt, AVStream *st, int max_size) -{ - VocDecContext *voc = s->priv_data; - AVCodecContext *dec = st->codec; - AVIOContext *pb = s->pb; - VocType type; - int size, tmp_codec=-1; - int sample_rate = 0; - int channels = 1; - - while (!voc->remaining_size) { - type = avio_r8(pb); - if (type == VOC_TYPE_EOF) - return AVERROR(EIO); - voc->remaining_size = avio_rl24(pb); - if (!voc->remaining_size) { - if (!s->pb->seekable) - return AVERROR(EIO); - voc->remaining_size = avio_size(pb) - avio_tell(pb); - } - max_size -= 4; - - switch (type) { - case VOC_TYPE_VOICE_DATA: - if (!dec->sample_rate) { - dec->sample_rate = 1000000 / (256 - avio_r8(pb)); - if (sample_rate) - dec->sample_rate = sample_rate; - avpriv_set_pts_info(st, 64, 1, dec->sample_rate); - dec->channels = channels; - dec->bits_per_coded_sample = av_get_bits_per_sample(dec->codec_id); - } else - avio_skip(pb, 1); - tmp_codec = avio_r8(pb); - voc->remaining_size -= 2; - max_size -= 2; - channels = 1; - break; - - case VOC_TYPE_VOICE_DATA_CONT: - break; - - case VOC_TYPE_EXTENDED: - sample_rate = avio_rl16(pb); - avio_r8(pb); - channels = avio_r8(pb) + 1; - sample_rate = 256000000 / (channels * (65536 - sample_rate)); - voc->remaining_size = 0; - max_size -= 4; - break; - - case VOC_TYPE_NEW_VOICE_DATA: - if (!dec->sample_rate) { - dec->sample_rate = avio_rl32(pb); - avpriv_set_pts_info(st, 64, 1, dec->sample_rate); - dec->bits_per_coded_sample = avio_r8(pb); - dec->channels = avio_r8(pb); - } else - avio_skip(pb, 6); - tmp_codec = avio_rl16(pb); - avio_skip(pb, 4); - voc->remaining_size -= 12; - max_size -= 12; - break; - - default: - avio_skip(pb, voc->remaining_size); - max_size -= voc->remaining_size; - voc->remaining_size = 0; - break; - } - } - - if (tmp_codec >= 0) { - tmp_codec = ff_codec_get_id(ff_voc_codec_tags, tmp_codec); - if (dec->codec_id == AV_CODEC_ID_NONE) - dec->codec_id = tmp_codec; - else if (dec->codec_id != tmp_codec) - av_log(s, AV_LOG_WARNING, "Ignoring mid-stream change in audio codec\n"); - if (dec->codec_id == AV_CODEC_ID_NONE) { - if (s->audio_codec_id == AV_CODEC_ID_NONE) { - av_log(s, AV_LOG_ERROR, "unknown codec tag\n"); - return AVERROR(EINVAL); - } - av_log(s, AV_LOG_WARNING, "unknown codec tag\n"); - } - } - - dec->bit_rate = dec->sample_rate * dec->bits_per_coded_sample; - - if (max_size <= 0) - max_size = 2048; - size = FFMIN(voc->remaining_size, max_size); - voc->remaining_size -= size; - return av_get_packet(pb, pkt, size); -} - -#if CONFIG_VOC_DEMUXER static int voc_probe(AVProbeData *p) { int version, check; @@ -176,4 +77,3 @@ AVInputFormat ff_voc_demuxer = { .read_packet = voc_read_packet, .codec_tag = (const AVCodecTag* const []){ ff_voc_codec_tags, 0 }, }; -#endif /* CONFIG_VOC_DEMUXER */