X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;ds=sidebyside;f=libavcodec%2Fvp3.c;h=738ae9fd258d9afba32ff7a07b5ed26dc856c26b;hb=bd36ec55bef7c446079e192655d065fd86483876;hp=ce14e63735ce85c28f6487516da16677484e0af8;hpb=8370e426e42f2e4b9d14a1fb8107ecfe5163ce7f;p=ffmpeg diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c index ce14e63735c..738ae9fd258 100644 --- a/libavcodec/vp3.c +++ b/libavcodec/vp3.c @@ -1,20 +1,20 @@ /* * Copyright (C) 2003-2004 the ffmpeg project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg 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, + * FFmpeg 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 + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -35,6 +35,7 @@ #include "libavutil/imgutils.h" #include "avcodec.h" +#include "internal.h" #include "dsputil.h" #include "get_bits.h" @@ -44,9 +45,6 @@ #define FRAGMENT_PIXELS 8 -static av_cold int vp3_decode_end(AVCodecContext *avctx); -static void vp3_decode_flush(AVCodecContext *avctx); - //FIXME split things out into their own arrays typedef struct Vp3Fragment { int16_t dc; @@ -255,6 +253,63 @@ typedef struct Vp3DecodeContext { * VP3 specific functions ************************************************************************/ +static void vp3_decode_flush(AVCodecContext *avctx) +{ + Vp3DecodeContext *s = avctx->priv_data; + + if (s->golden_frame.data[0]) { + if (s->golden_frame.data[0] == s->last_frame.data[0]) + memset(&s->last_frame, 0, sizeof(AVFrame)); + if (s->current_frame.data[0] == s->golden_frame.data[0]) + memset(&s->current_frame, 0, sizeof(AVFrame)); + ff_thread_release_buffer(avctx, &s->golden_frame); + } + if (s->last_frame.data[0]) { + if (s->current_frame.data[0] == s->last_frame.data[0]) + memset(&s->current_frame, 0, sizeof(AVFrame)); + ff_thread_release_buffer(avctx, &s->last_frame); + } + if (s->current_frame.data[0]) + ff_thread_release_buffer(avctx, &s->current_frame); +} + +static av_cold int vp3_decode_end(AVCodecContext *avctx) +{ + Vp3DecodeContext *s = avctx->priv_data; + int i; + + av_free(s->superblock_coding); + av_free(s->all_fragments); + av_free(s->coded_fragment_list[0]); + av_free(s->dct_tokens_base); + av_free(s->superblock_fragments); + av_free(s->macroblock_coding); + av_free(s->motion_val[0]); + av_free(s->motion_val[1]); + av_free(s->edge_emu_buffer); + + if (avctx->internal->is_copy) + return 0; + + for (i = 0; i < 16; i++) { + free_vlc(&s->dc_vlc[i]); + free_vlc(&s->ac_vlc_1[i]); + free_vlc(&s->ac_vlc_2[i]); + free_vlc(&s->ac_vlc_3[i]); + free_vlc(&s->ac_vlc_4[i]); + } + + free_vlc(&s->superblock_run_length_vlc); + free_vlc(&s->fragment_run_length_vlc); + free_vlc(&s->mode_code_vlc); + free_vlc(&s->motion_vector_vlc); + + /* release all frames */ + vp3_decode_flush(avctx); + + return 0; +} + /* * This function sets up all of the various blocks mappings: * superblocks <-> fragments, macroblocks <-> fragments, @@ -1308,6 +1363,10 @@ static inline int vp3_dequant(Vp3DecodeContext *s, Vp3Fragment *frag, case 1: // zero run s->dct_tokens[plane][i]++; i += (token >> 2) & 0x7f; + if (i > 63) { + av_log(s->avctx, AV_LOG_ERROR, "Coefficient index overflow\n"); + return i; + } block[perm[i]] = (token >> 9) * dequantizer[perm[i]]; i++; break; @@ -1319,6 +1378,8 @@ static inline int vp3_dequant(Vp3DecodeContext *s, Vp3Fragment *frag, return i; } } while (i < 64); + // return value is expected to be a valid level + i--; end: // the actual DC+prediction is in the fragment structure block[0] = frag->dc * s->qmat[0][inter][plane][0]; @@ -1330,8 +1391,8 @@ end: */ static void vp3_draw_horiz_band(Vp3DecodeContext *s, int y) { - int h, cy; - int offset[4]; + int h, cy, i; + int offset[AV_NUM_DATA_POINTERS]; if (HAVE_THREADS && s->avctx->active_thread_type&FF_THREAD_FRAME) { int y_flipped = s->flipped_image ? s->avctx->height-y : y; @@ -1357,7 +1418,8 @@ static void vp3_draw_horiz_band(Vp3DecodeContext *s, int y) offset[0] = s->current_frame.linesize[0]*y; offset[1] = s->current_frame.linesize[1]*cy; offset[2] = s->current_frame.linesize[2]*cy; - offset[3] = 0; + for (i = 3; i < AV_NUM_DATA_POINTERS; i++) + offset[i] = 0; emms_c(); s->avctx->draw_horiz_band(s->avctx, &s->current_frame, offset, y, 3, h); @@ -1588,9 +1650,6 @@ static av_cold int allocate_tables(AVCodecContext *avctx) return 0; } -/* - * This is the ffmpeg/libavcodec API init function. - */ static av_cold int vp3_decode_init(AVCodecContext *avctx) { Vp3DecodeContext *s = avctx->priv_data; @@ -1842,9 +1901,6 @@ static int vp3_update_thread_context(AVCodecContext *dst, const AVCodecContext * return 0; } -/* - * This is the ffmpeg/libavcodec API frame decode function. - */ static int vp3_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) @@ -1897,6 +1953,7 @@ static int vp3_decode_frame(AVCodecContext *avctx, s->current_frame.reference = 3; s->current_frame.pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; + s->current_frame.key_frame = s->keyframe; if (ff_thread_get_buffer(avctx, &s->current_frame) < 0) { av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); goto error; @@ -1999,45 +2056,6 @@ error: return -1; } -/* - * This is the ffmpeg/libavcodec API module cleanup function. - */ -static av_cold int vp3_decode_end(AVCodecContext *avctx) -{ - Vp3DecodeContext *s = avctx->priv_data; - int i; - - av_free(s->superblock_coding); - av_free(s->all_fragments); - av_free(s->coded_fragment_list[0]); - av_free(s->dct_tokens_base); - av_free(s->superblock_fragments); - av_free(s->macroblock_coding); - av_free(s->motion_val[0]); - av_free(s->motion_val[1]); - av_free(s->edge_emu_buffer); - - if (avctx->is_copy) return 0; - - for (i = 0; i < 16; i++) { - free_vlc(&s->dc_vlc[i]); - free_vlc(&s->ac_vlc_1[i]); - free_vlc(&s->ac_vlc_2[i]); - free_vlc(&s->ac_vlc_3[i]); - free_vlc(&s->ac_vlc_4[i]); - } - - free_vlc(&s->superblock_run_length_vlc); - free_vlc(&s->fragment_run_length_vlc); - free_vlc(&s->mode_code_vlc); - free_vlc(&s->motion_vector_vlc); - - /* release all frames */ - vp3_decode_flush(avctx); - - return 0; -} - static int read_huffman_tree(AVCodecContext *avctx, GetBitContext *gb) { Vp3DecodeContext *s = avctx->priv_data; @@ -2072,6 +2090,23 @@ static int read_huffman_tree(AVCodecContext *avctx, GetBitContext *gb) return 0; } +static int vp3_init_thread_copy(AVCodecContext *avctx) +{ + Vp3DecodeContext *s = avctx->priv_data; + + s->superblock_coding = NULL; + s->all_fragments = NULL; + s->coded_fragment_list[0] = NULL; + s->dct_tokens_base = NULL; + s->superblock_fragments = NULL; + s->macroblock_coding = NULL; + s->motion_val[0] = NULL; + s->motion_val[1] = NULL; + s->edge_emu_buffer = NULL; + + return 0; +} + #if CONFIG_THEORA_DECODER static const enum PixelFormat theora_pix_fmts[4] = { PIX_FMT_YUV420P, PIX_FMT_NONE, PIX_FMT_YUV422P, PIX_FMT_YUV444P @@ -2333,43 +2368,6 @@ static av_cold int theora_decode_init(AVCodecContext *avctx) return vp3_decode_init(avctx); } -static void vp3_decode_flush(AVCodecContext *avctx) -{ - Vp3DecodeContext *s = avctx->priv_data; - - if (s->golden_frame.data[0]) { - if (s->golden_frame.data[0] == s->last_frame.data[0]) - memset(&s->last_frame, 0, sizeof(AVFrame)); - if (s->current_frame.data[0] == s->golden_frame.data[0]) - memset(&s->current_frame, 0, sizeof(AVFrame)); - ff_thread_release_buffer(avctx, &s->golden_frame); - } - if (s->last_frame.data[0]) { - if (s->current_frame.data[0] == s->last_frame.data[0]) - memset(&s->current_frame, 0, sizeof(AVFrame)); - ff_thread_release_buffer(avctx, &s->last_frame); - } - if (s->current_frame.data[0]) - ff_thread_release_buffer(avctx, &s->current_frame); -} - -static int vp3_init_thread_copy(AVCodecContext *avctx) -{ - Vp3DecodeContext *s = avctx->priv_data; - - s->superblock_coding = NULL; - s->all_fragments = NULL; - s->coded_fragment_list[0] = NULL; - s->dct_tokens_base = NULL; - s->superblock_fragments = NULL; - s->macroblock_coding = NULL; - s->motion_val[0] = NULL; - s->motion_val[1] = NULL; - s->edge_emu_buffer = NULL; - - return 0; -} - AVCodec ff_theora_decoder = { .name = "theora", .type = AVMEDIA_TYPE_VIDEO,