[FFmpeg-cvslog] vp9: just disallow temporal or no-update segmentation on size-change.
Ronald S. Bultje
git at videolan.org
Sun Feb 9 18:13:56 CET 2014
ffmpeg | branch: master | Ronald S. Bultje <rsbultje at gmail.com> | Sat Feb 8 20:47:44 2014 -0500| [9aeca1c572dcd446bba340eb6c5fa4f65e18d1e8] | committer: Clément Bœsch
vp9: just disallow temporal or no-update segmentation on size-change.
The spec doesn't describe how it should be decoded so this is probably
the safest thing to do. Fixes valgrind errors on fuzzed11.ivf and fixes
valgrind errors on fuzzed10.ivf differently.
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=9aeca1c572dcd446bba340eb6c5fa4f65e18d1e8
---
libavcodec/vp9.c | 21 ++++++++++++---------
1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c
index 7080658..8099c76 100644
--- a/libavcodec/vp9.c
+++ b/libavcodec/vp9.c
@@ -110,7 +110,6 @@ typedef struct VP9Context {
uint8_t keyframe, last_keyframe;
uint8_t invisible;
uint8_t use_last_frame_mvs;
- uint8_t use_last_frame_segmap;
uint8_t errorres;
uint8_t colorspace;
uint8_t fullrange;
@@ -279,7 +278,7 @@ static int vp9_alloc_frame(AVCodecContext *ctx, VP9Frame *f)
// retain segmentation map if it doesn't update
if (s->segmentation.enabled && !s->segmentation.update_map &&
- s->use_last_frame_segmap) {
+ !s->intraonly && !s->keyframe) {
memcpy(f->segmentation_map, s->frames[LAST_FRAME].segmentation_map, sz);
}
@@ -622,14 +621,19 @@ static int decode_frame_header(AVCodecContext *ctx,
for (i = 0; i < 7; i++)
s->prob.seg[i] = get_bits1(&s->gb) ?
get_bits(&s->gb, 8) : 255;
- if ((s->segmentation.temporal = get_bits1(&s->gb)))
+ if ((s->segmentation.temporal = get_bits1(&s->gb))) {
for (i = 0; i < 3; i++)
s->prob.segpred[i] = get_bits1(&s->gb) ?
get_bits(&s->gb, 8) : 255;
- } else {
- s->use_last_frame_segmap = !s->keyframe && !s->intraonly &&
- s->frames[CUR_FRAME].tf.f->width == w &&
- s->frames[CUR_FRAME].tf.f->height == h;
+ }
+ }
+ if ((!s->segmentation.update_map || s->segmentation.temporal) &&
+ (w != s->frames[CUR_FRAME].tf.f->width ||
+ h != s->frames[CUR_FRAME].tf.f->height)) {
+ av_log(ctx, AV_LOG_ERROR,
+ "Reference segmap (temp=%d,update=%d) enabled on size-change!\n",
+ s->segmentation.temporal, s->segmentation.update_map);
+ return AVERROR_INVALIDDATA;
}
if (get_bits1(&s->gb)) {
@@ -1284,8 +1288,7 @@ static void decode_mode(AVCodecContext *ctx)
int h4 = FFMIN(s->rows - row, bwh_tab[1][b->bs][1]), y;
int have_a = row > 0, have_l = col > s->tiling.tile_col_start;
- if (!s->segmentation.enabled ||
- (!s->segmentation.update_map && !s->use_last_frame_segmap)) {
+ if (!s->segmentation.enabled) {
b->seg_id = 0;
} else if (s->keyframe || s->intraonly) {
b->seg_id = vp8_rac_get_tree(&s->c, vp9_segmentation_tree, s->prob.seg);
More information about the ffmpeg-cvslog
mailing list