X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fvocdec.c;h=59c84b705699ff00632003011c5bd39385987dd5;hb=f61cbc22d3ce8ec0e2644d0fa565413c057deaa0;hp=bc9205faa0e71c1e2f3ea7560508bae73e71a268;hpb=cbc09a7d5a570fff61a059c0a6f910f275805e97;p=ffmpeg diff --git a/libavformat/vocdec.c b/libavformat/vocdec.c index bc9205faa0e..59c84b70569 100644 --- a/libavformat/vocdec.c +++ b/libavformat/vocdec.c @@ -16,25 +16,22 @@ * * You should have received a copy of the GNU Lesser General Public * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/intreadwrite.h" #include "voc.h" - - -static const int voc_max_pkt_size = 2048; +#include "internal.h" static int voc_probe(AVProbeData *p) { int version, check; - if (p->buf_size < 26) - return 0; - if (memcmp(p->buf, voc_magic, sizeof(voc_magic) - 1)) + if (memcmp(p->buf, ff_voc_magic, sizeof(ff_voc_magic) - 1)) return 0; - version = p->buf[22] | (p->buf[23] << 8); - check = p->buf[24] | (p->buf[25] << 8); + version = AV_RL16(p->buf + 22); + check = AV_RL16(p->buf + 24); if (~version + 0x1234 != check) return 10; @@ -43,8 +40,8 @@ static int voc_probe(AVProbeData *p) static int voc_read_header(AVFormatContext *s, AVFormatParameters *ap) { - voc_dec_context_t *voc = s->priv_data; - ByteIOContext *pb = &s->pb; + VocDecContext *voc = s->priv_data; + ByteIOContext *pb = s->pb; int header_size; AVStream *st; @@ -52,13 +49,13 @@ static int voc_read_header(AVFormatContext *s, AVFormatParameters *ap) header_size = get_le16(pb) - 22; if (header_size != 4) { av_log(s, AV_LOG_ERROR, "unknown header size: %d\n", header_size); - return AVERROR_NOTSUPP; + return AVERROR(ENOSYS); } url_fskip(pb, header_size); st = av_new_stream(s, 0); if (!st) - return AVERROR_NOMEM; - st->codec->codec_type = CODEC_TYPE_AUDIO; + return AVERROR(ENOMEM); + st->codec->codec_type = AVMEDIA_TYPE_AUDIO; voc->remaining_size = 0; return 0; @@ -67,19 +64,24 @@ static int voc_read_header(AVFormatContext *s, AVFormatParameters *ap) int voc_get_packet(AVFormatContext *s, AVPacket *pkt, AVStream *st, int max_size) { - voc_dec_context_t *voc = s->priv_data; + VocDecContext *voc = s->priv_data; AVCodecContext *dec = st->codec; - ByteIOContext *pb = &s->pb; - voc_type_t type; - int size; + ByteIOContext *pb = s->pb; + VocType type; + int size, tmp_codec=-1; int sample_rate = 0; int channels = 1; while (!voc->remaining_size) { type = get_byte(pb); if (type == VOC_TYPE_EOF) - return AVERROR_IO; + return AVERROR(EIO); voc->remaining_size = get_le24(pb); + if (!voc->remaining_size) { + if (url_is_streamed(s->pb)) + return AVERROR(EIO); + voc->remaining_size = url_fsize(pb) - url_ftell(pb); + } max_size -= 4; switch (type) { @@ -88,8 +90,8 @@ voc_get_packet(AVFormatContext *s, AVPacket *pkt, AVStream *st, int max_size) if (sample_rate) dec->sample_rate = sample_rate; dec->channels = channels; - dec->codec_id = codec_get_id(voc_codec_tags, get_byte(pb)); - dec->bits_per_sample = av_get_bits_per_sample(dec->codec_id); + tmp_codec = get_byte(pb); + dec->bits_per_coded_sample = av_get_bits_per_sample(dec->codec_id); voc->remaining_size -= 2; max_size -= 2; channels = 1; @@ -109,9 +111,9 @@ voc_get_packet(AVFormatContext *s, AVPacket *pkt, AVStream *st, int max_size) case VOC_TYPE_NEW_VOICE_DATA: dec->sample_rate = get_le32(pb); - dec->bits_per_sample = get_byte(pb); + dec->bits_per_coded_sample = get_byte(pb); dec->channels = get_byte(pb); - dec->codec_id = codec_get_id(voc_codec_tags, get_le16(pb)); + tmp_codec = get_le16(pb); url_fskip(pb, 4); voc->remaining_size -= 12; max_size -= 12; @@ -125,10 +127,25 @@ voc_get_packet(AVFormatContext *s, AVPacket *pkt, AVStream *st, int max_size) } } - dec->bit_rate = dec->sample_rate * dec->bits_per_sample; + if (tmp_codec >= 0) { + tmp_codec = ff_codec_get_id(ff_voc_codec_tags, tmp_codec); + if (dec->codec_id == 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 == CODEC_ID_NONE) { + if (s->audio_codec_id == 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 = voc_max_pkt_size; + max_size = 2048; size = FFMIN(voc->remaining_size, max_size); voc->remaining_size -= size; return av_get_packet(pb, pkt, size); @@ -139,18 +156,12 @@ static int voc_read_packet(AVFormatContext *s, AVPacket *pkt) return voc_get_packet(s, pkt, s->streams[0], 0); } -static int voc_read_close(AVFormatContext *s) -{ - return 0; -} - AVInputFormat voc_demuxer = { "voc", - "Creative Voice File format", - sizeof(voc_dec_context_t), + NULL_IF_CONFIG_SMALL("Creative Voice file format"), + sizeof(VocDecContext), voc_probe, voc_read_header, voc_read_packet, - voc_read_close, - .codec_tag=(const AVCodecTag*[]){voc_codec_tags, 0}, + .codec_tag=(const AVCodecTag* const []){ff_voc_codec_tags, 0}, };