diff options
Diffstat (limited to 'libavcodec/vp8.c')
-rw-r--r-- | libavcodec/vp8.c | 68 |
1 files changed, 44 insertions, 24 deletions
diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c index 833819890d..d68a91ea54 100644 --- a/libavcodec/vp8.c +++ b/libavcodec/vp8.c @@ -5,20 +5,20 @@ * Copyright (C) 2010 Ronald S. Bultje * Copyright (C) 2010 Jason Garrett-Glaser * - * 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 */ @@ -639,9 +639,10 @@ void decode_mb_mode(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y, uint8_ { VP56RangeCoder *c = &s->c; - if (s->segmentation.update_map) - *segment = vp8_rac_get_tree(c, vp8_segmentid_tree, s->prob->segmentid); - else + if (s->segmentation.update_map) { + int bit = vp56_rac_get_prob(c, s->prob->segmentid[0]); + *segment = vp56_rac_get_prob(c, s->prob->segmentid[1+bit]) + 2*bit; + } else *segment = ref ? *ref : *segment; s->segment = *segment; @@ -1560,6 +1561,18 @@ static void release_queued_segmaps(VP8Context *s, int is_close) s->maps_are_invalid = 0; } +/** + * Sets things up for skipping the current frame. + * In particular, removes it from the reference buffers. + */ +static void skipframe_clear(VP8Context *s) +{ + s->invisible = 1; + s->next_framep[VP56_FRAME_CURRENT] = NULL; + if (s->update_last) + s->next_framep[VP56_FRAME_PREVIOUS] = NULL; +} + static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { @@ -1581,10 +1594,6 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *data_size, skip_thresh = !referenced ? AVDISCARD_NONREF : !s->keyframe ? AVDISCARD_NONKEY : AVDISCARD_ALL; - if (avctx->skip_frame >= skip_thresh) { - s->invisible = 1; - goto skip_decode; - } s->deblock_filter = s->filter.level && avctx->skip_loop_filter < skip_thresh; // release no longer referenced frames @@ -1609,16 +1618,6 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *data_size, av_log(avctx, AV_LOG_FATAL, "Ran out of free frames!\n"); abort(); } - if (curframe->data[0]) - vp8_release_frame(s, curframe, 1, 0); - - curframe->key_frame = s->keyframe; - curframe->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; - curframe->reference = referenced ? 3 : 0; - if ((ret = vp8_alloc_frame(s, curframe))) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed!\n"); - return ret; - } // check if golden and altref are swapped if (s->update_altref != VP56_FRAME_NONE) { @@ -1638,7 +1637,11 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *data_size, } s->next_framep[VP56_FRAME_CURRENT] = curframe; - ff_thread_finish_setup(avctx); + if (avctx->skip_frame >= skip_thresh) { + skipframe_clear(s); + ret = avpkt->size; + goto skip_decode; + } // Given that arithmetic probabilities are updated every frame, it's quite likely // that the values we have on a random interframe are complete junk if we didn't @@ -1647,9 +1650,25 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *data_size, !s->framep[VP56_FRAME_GOLDEN] || !s->framep[VP56_FRAME_GOLDEN2])) { av_log(avctx, AV_LOG_WARNING, "Discarding interframe without a prior keyframe!\n"); - return AVERROR_INVALIDDATA; + skipframe_clear(s); + ret = AVERROR_INVALIDDATA; + goto skip_decode; + } + + if (curframe->data[0]) + vp8_release_frame(s, curframe, 1, 0); + + curframe->key_frame = s->keyframe; + curframe->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; + curframe->reference = referenced ? 3 : 0; + if ((ret = vp8_alloc_frame(s, curframe))) { + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed!\n"); + skipframe_clear(s); + goto skip_decode; } + ff_thread_finish_setup(avctx); + s->linesize = curframe->linesize[0]; s->uvlinesize = curframe->linesize[1]; @@ -1759,6 +1778,7 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *data_size, } ff_thread_report_progress(curframe, INT_MAX, 0); + ret = avpkt->size; skip_decode: // if future frames don't use the updated probabilities, // reset them to the values we saved @@ -1772,7 +1792,7 @@ skip_decode: *data_size = sizeof(AVFrame); } - return avpkt->size; + return ret; } static av_cold int vp8_decode_init(AVCodecContext *avctx) |