]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/vp9.c
Merge commit '380146924ecad2e05e9dcc5c3c2e1b5ba47c51e8'
[ffmpeg] / libavcodec / vp9.c
index 25e7419f843002390d9b33b2c31dd95e19bb2fa0..f1183e8e751eb30020eb4325aad6e74aed1cfb70 100644 (file)
@@ -153,7 +153,6 @@ typedef struct VP9Context {
         uint8_t temporal;
         uint8_t absolute_vals;
         uint8_t update_map;
-        uint8_t ignore_refmap;
         struct {
             uint8_t q_enabled;
             uint8_t lf_enabled;
@@ -361,7 +360,7 @@ static int update_size(AVCodecContext *ctx, int w, int h, enum AVPixelFormat fmt
     av_freep(&s->block_base);
 
     if (s->bpp != s->last_bpp) {
-        ff_vp9dsp_init(&s->dsp, s->bpp);
+        ff_vp9dsp_init(&s->dsp, s->bpp, ctx->flags & AV_CODEC_FLAG_BITEXACT);
         ff_videodsp_init(&s->vdsp, s->bpp);
         s->last_bpp = s->bpp;
     }
@@ -743,7 +742,6 @@ static int decode_frame_header(AVCodecContext *ctx,
         ctx->properties |= FF_CODEC_PROPERTY_LOSSLESS;
 
     /* segmentation header info */
-    s->segmentation.ignore_refmap = 0;
     if ((s->segmentation.enabled = get_bits1(&s->gb))) {
         if ((s->segmentation.update_map = get_bits1(&s->gb))) {
             for (i = 0; i < 7; i++)
@@ -755,15 +753,6 @@ static int decode_frame_header(AVCodecContext *ctx,
                                          get_bits(&s->gb, 8) : 255;
             }
         }
-        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_WARNING,
-                   "Reference segmap (temp=%d,update=%d) enabled on size-change!\n",
-                   s->segmentation.temporal, s->segmentation.update_map);
-            s->segmentation.ignore_refmap = 1;
-            //return AVERROR_INVALIDDATA;
-        }
 
         if (get_bits1(&s->gb)) {
             s->segmentation.absolute_vals = get_bits1(&s->gb);
@@ -834,7 +823,7 @@ static int decode_frame_header(AVCodecContext *ctx,
         return res;
     }
     for (s->tiling.log2_tile_cols = 0;
-         (s->sb_cols >> s->tiling.log2_tile_cols) > 64;
+         s->sb_cols > (64 << s->tiling.log2_tile_cols);
          s->tiling.log2_tile_cols++) ;
     for (max = 0; (s->sb_cols >> max) >= 4; max++) ;
     max = FFMAX(0, max - 1);
@@ -1490,7 +1479,7 @@ static void decode_mode(AVCodecContext *ctx)
                 vp56_rac_get_prob_branchy(&s->c,
                     s->prob.segpred[s->above_segpred_ctx[col] +
                                     s->left_segpred_ctx[row7]]))) {
-        if (!s->errorres && !s->segmentation.ignore_refmap) {
+        if (!s->errorres && s->frames[REF_FRAME_SEGMAP].segmentation_map) {
             int pred = 8, x;
             uint8_t *refsegmap = s->frames[REF_FRAME_SEGMAP].segmentation_map;
 
@@ -3312,9 +3301,9 @@ static void decode_b(AVCodecContext *ctx, int row, int col,
     // emulated overhangs if the stride of the target buffer can't hold. This
     // makes it possible to support emu-edge and so on even if we have large block
     // overhangs
-    emu[0] = (col + w4) * 8 > f->linesize[0] ||
+    emu[0] = (col + w4) * 8 * bytesperpixel > f->linesize[0] ||
              (row + h4) > s->rows;
-    emu[1] = (col + w4) * 4 > f->linesize[1] ||
+    emu[1] = ((col + w4) * 8 >> s->ss_h) * bytesperpixel > f->linesize[1] ||
              (row + h4) > s->rows;
     if (emu[0]) {
         s->dst[0] = s->tmp_y;
@@ -4064,6 +4053,12 @@ static int vp9_decode_frame(AVCodecContext *ctx, void *frame,
     ls_y = f->linesize[0];
     ls_uv =f->linesize[1];
 
+    if (s->frames[REF_FRAME_SEGMAP].tf.f->data[0] &&
+        (s->frames[REF_FRAME_MVPAIR].tf.f->width  != s->frames[CUR_FRAME].tf.f->width ||
+         s->frames[REF_FRAME_MVPAIR].tf.f->height != s->frames[CUR_FRAME].tf.f->height)) {
+        vp9_unref_frame(ctx, &s->frames[REF_FRAME_SEGMAP]);
+    }
+
     // ref frame setup
     for (i = 0; i < 8; i++) {
         if (s->next_refs[i].f->data[0])
@@ -4324,7 +4319,8 @@ static int vp9_decode_update_thread_context(AVCodecContext *dst, const AVCodecCo
 
     // detect size changes in other threads
     if (s->intra_pred_data[0] &&
-        (!ssrc->intra_pred_data[0] || s->cols != ssrc->cols || s->rows != ssrc->rows)) {
+        (!ssrc->intra_pred_data[0] || s->cols != ssrc->cols ||
+         s->rows != ssrc->rows || s->bpp != ssrc->bpp)) {
         free_buffers(s);
     }