X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;ds=sidebyside;f=libavcodec%2Fvmdav.c;h=110d19cd9aad08668826e93619330e212993f16e;hb=dad09ff93f5df1ec987493f404d43cd16991e992;hp=48739a726b1038dd65b84f237e0aab05e284fdb6;hpb=8e9027d266ef39ab9f88b4bbad5cf9e425d0696c;p=ffmpeg diff --git a/libavcodec/vmdav.c b/libavcodec/vmdav.c index 48739a726b1..110d19cd9aa 100644 --- a/libavcodec/vmdav.c +++ b/libavcodec/vmdav.c @@ -2,20 +2,20 @@ * Sierra VMD Audio & Video Decoders * Copyright (C) 2004 the ffmpeg project * - * This file is part of FFmpeg. + * This file is part of Libav. * - * FFmpeg is free software; you can redistribute it and/or + * 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. * - * FFmpeg is distributed in the hope that it will be useful, + * 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 FFmpeg; if not, write to the Free Software + * License along with Libav; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -199,7 +199,6 @@ static void vmd_decode(VmdVideoContext *s) int frame_x, frame_y; int frame_width, frame_height; - int dp_size; frame_x = AV_RL16(&s->buf[6]); frame_y = AV_RL16(&s->buf[8]); @@ -247,7 +246,6 @@ static void vmd_decode(VmdVideoContext *s) } dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x]; - dp_size = s->frame.linesize[0] * s->avctx->height; pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x]; switch (meth) { case 1: @@ -420,9 +418,7 @@ static av_cold int vmdvideo_decode_end(AVCodecContext *avctx) typedef struct VmdAudioContext { AVCodecContext *avctx; - int channels; - int bits; - int block_align; + int out_bps; int predictors[2]; } VmdAudioContext; @@ -447,13 +443,16 @@ static av_cold int vmdaudio_decode_init(AVCodecContext *avctx) VmdAudioContext *s = avctx->priv_data; s->avctx = avctx; - s->channels = avctx->channels; - s->bits = avctx->bits_per_coded_sample; - s->block_align = avctx->block_align; - avctx->sample_fmt = AV_SAMPLE_FMT_S16; + if (avctx->bits_per_coded_sample == 16) + avctx->sample_fmt = AV_SAMPLE_FMT_S16; + else + avctx->sample_fmt = AV_SAMPLE_FMT_U8; + s->out_bps = av_get_bytes_per_sample(avctx->sample_fmt); - av_log(s->avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, block align = %d, sample rate = %d\n", - s->channels, s->bits, s->block_align, avctx->sample_rate); + av_log(avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, " + "block align = %d, sample rate = %d\n", + avctx->channels, avctx->bits_per_coded_sample, avctx->block_align, + avctx->sample_rate); return 0; } @@ -477,25 +476,22 @@ static void vmdaudio_decode_audio(VmdAudioContext *s, unsigned char *data, } static int vmdaudio_loadsound(VmdAudioContext *s, unsigned char *data, - const uint8_t *buf, int silence, int data_size) + const uint8_t *buf, int silent_chunks, int data_size) { - int i; + int silent_size = s->avctx->block_align * silent_chunks * s->out_bps; - if (silence) { - memset(data, 0, data_size * 2); - } else { - if (s->bits == 16) - vmdaudio_decode_audio(s, data, buf, data_size, s->channels == 2); - else { - /* copy the data but convert it to signed */ - for (i = 0; i < data_size; i++){ - *data++ = buf[i] + 0x80; - *data++ = buf[i] + 0x80; - } - } + if (silent_chunks) { + memset(data, s->out_bps == 2 ? 0x00 : 0x80, silent_size); + data += silent_size; + } + if (s->avctx->bits_per_coded_sample == 16) + vmdaudio_decode_audio(s, data, buf, data_size, s->avctx->channels == 2); + else { + /* just copy the data */ + memcpy(data, buf, data_size); } - return data_size * 2; + return silent_size + data_size * s->out_bps; } static int vmdaudio_decode_frame(AVCodecContext *avctx, @@ -505,7 +501,7 @@ static int vmdaudio_decode_frame(AVCodecContext *avctx, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; VmdAudioContext *s = avctx->priv_data; - int block_type; + int block_type, silent_chunks; unsigned char *output_samples = (unsigned char *)data; if (buf_size < 16) { @@ -522,29 +518,23 @@ static int vmdaudio_decode_frame(AVCodecContext *avctx, buf += 16; buf_size -= 16; - if (block_type == BLOCK_TYPE_AUDIO) { - /* the chunk contains audio */ - *data_size = vmdaudio_loadsound(s, output_samples, buf, 0, buf_size); - } else if (block_type == BLOCK_TYPE_INITIAL) { - /* initial chunk, may contain audio and silence */ + silent_chunks = 0; + if (block_type == BLOCK_TYPE_INITIAL) { uint32_t flags = AV_RB32(buf); - int raw_block_size = s->block_align * - (av_get_bits_per_sample_fmt(avctx->sample_fmt) / 8); - int silent_chunks = av_popcount(flags); + silent_chunks = av_popcount(flags); buf += 4; buf_size -= 4; - if(*data_size < (s->block_align*silent_chunks + buf_size) * 2) - return -1; - *data_size = 0; - memset(output_samples, 0, raw_block_size * silent_chunks); - output_samples += raw_block_size * silent_chunks; - *data_size = raw_block_size * silent_chunks; - *data_size += vmdaudio_loadsound(s, output_samples, buf, 0, buf_size); } else if (block_type == BLOCK_TYPE_SILENCE) { - /* silent chunk */ - *data_size = vmdaudio_loadsound(s, output_samples, buf, 1, s->block_align); + silent_chunks = 1; + buf_size = 0; // should already be zero but set it just to be sure } + /* ensure output buffer is large enough */ + if (*data_size < (avctx->block_align*silent_chunks + buf_size) * s->out_bps) + return -1; + + *data_size = vmdaudio_loadsound(s, output_samples, buf, silent_chunks, buf_size); + return avpkt->size; } @@ -554,26 +544,23 @@ static int vmdaudio_decode_frame(AVCodecContext *avctx, */ AVCodec ff_vmdvideo_decoder = { - "vmdvideo", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_VMDVIDEO, - sizeof(VmdVideoContext), - vmdvideo_decode_init, - NULL, - vmdvideo_decode_end, - vmdvideo_decode_frame, - CODEC_CAP_DR1, + .name = "vmdvideo", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_VMDVIDEO, + .priv_data_size = sizeof(VmdVideoContext), + .init = vmdvideo_decode_init, + .close = vmdvideo_decode_end, + .decode = vmdvideo_decode_frame, + .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD video"), }; AVCodec ff_vmdaudio_decoder = { - "vmdaudio", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_VMDAUDIO, - sizeof(VmdAudioContext), - vmdaudio_decode_init, - NULL, - NULL, - vmdaudio_decode_frame, + .name = "vmdaudio", + .type = AVMEDIA_TYPE_AUDIO, + .id = CODEC_ID_VMDAUDIO, + .priv_data_size = sizeof(VmdAudioContext), + .init = vmdaudio_decode_init, + .decode = vmdaudio_decode_frame, .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD audio"), };