Merge commit 'eb657ecefdeb8b2ed9bfb55d3c2c9e0f568486bf'
authorMichael Niedermayer <michaelni@gmx.at>
Thu, 11 Oct 2012 12:36:30 +0000 (14:36 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Thu, 11 Oct 2012 12:36:36 +0000 (14:36 +0200)
* commit 'eb657ecefdeb8b2ed9bfb55d3c2c9e0f568486bf':
  vc1dec: Set opposite to the correct value for 1REF field pictures

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavcodec/vc1dec.c

diff --combined libavcodec/vc1dec.c
@@@ -4,20 -4,20 +4,20 @@@
   * Copyright (c) 2006-2007 Konstantin Shishkov
   * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer
   *
 - * 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
   */
  
@@@ -38,7 -38,6 +38,7 @@@
  #include "unary.h"
  #include "mathops.h"
  #include "vdpau_internal.h"
 +#include "libavutil/avassert.h"
  
  #undef NDEBUG
  #include <assert.h>
@@@ -369,7 -368,7 +369,7 @@@ static void vc1_mc_1mv(VC1Context *v, i
      }
      if (v->field_mode) { // interlaced field picture
          if (!dir) {
 -            if ((v->cur_field_type != v->ref_field_type[dir]) && v->cur_field_type) {
 +            if ((v->cur_field_type != v->ref_field_type[dir]) && v->second_field) {
                  srcY = s->current_picture.f.data[0];
                  srcU = s->current_picture.f.data[1];
                  srcV = s->current_picture.f.data[2];
          srcY += s->mspel * (1 + s->linesize);
      }
  
 -    if (v->field_mode && v->cur_field_type) {
 +    if (v->field_mode && v->second_field) {
          off    = s->current_picture_ptr->f.linesize[0];
          off_uv = s->current_picture_ptr->f.linesize[1];
      } else {
@@@ -561,7 -560,7 +561,7 @@@ static void vc1_mc_4mv_luma(VC1Context 
  
      if (!dir) {
          if (v->field_mode) {
 -            if ((v->cur_field_type != v->ref_field_type[dir]) && v->cur_field_type)
 +            if ((v->cur_field_type != v->ref_field_type[dir]) && v->second_field)
                  srcY = s->current_picture.f.data[0];
              else
                  srcY = s->last_picture.f.data[0];
          off = ((n > 1) ? s->linesize : 0) + (n & 1) * 8;
      else
          off = s->linesize * 4 * (n & 2) + (n & 1) * 8;
 -    if (v->field_mode && v->cur_field_type)
 +    if (v->field_mode && v->second_field)
          off += s->current_picture_ptr->f.linesize[0];
  
      src_x = s->mb_x * 16 + (n & 1) * 8 + (mx >> 2);
@@@ -862,7 -861,7 +862,7 @@@ static void vc1_mc_4mv_chroma(VC1Contex
              srcU += s->current_picture_ptr->f.linesize[1];
              srcV += s->current_picture_ptr->f.linesize[2];
          }
 -        off = v->cur_field_type ? s->current_picture_ptr->f.linesize[1] : 0;
 +        off = v->second_field ? s->current_picture_ptr->f.linesize[1] : 0;
      }
  
      if (v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP)
@@@ -1139,7 -1138,6 +1139,7 @@@ static av_always_inline void get_mvdata
          }
      }
      else {
 +        av_assert0(index < esc);
          if (extend_x)
              offs_tab = offset_table2;
          else
@@@ -1460,10 -1458,16 +1460,16 @@@ static inline void vc1_pred_mv(VC1Conte
      }
  
      if (v->field_mode) {
-         if (num_samefield <= num_oppfield)
-             opposite = 1 - pred_flag;
-         else
-             opposite = pred_flag;
+         if (!v->numref)
+             // REFFIELD determines if the last field or the second-last field is
+             // to be used as reference
+             opposite = 1 - v->reffield;
+         else {
+             if (num_samefield <= num_oppfield)
+                 opposite = 1 - pred_flag;
+             else
+                 opposite = pred_flag;
+         }
      } else
          opposite = 0;
      if (opposite) {
@@@ -1791,7 -1795,7 +1797,7 @@@ static inline void vc1_pred_mv_intfr(VC
                  } else if (c_valid) {
                      px = C[0];
                      py = C[1];
 -                }
 +                } else px = py = 0;
              }
          } else if (total_valid == 1) {
              px = (a_valid) ? A[0] : ((b_valid) ? B[0] : C[0]);
@@@ -1924,7 -1928,7 +1930,7 @@@ static void vc1_interp_mc(VC1Context *v
          srcY += s->mspel * (1 + s->linesize);
      }
  
 -    if (v->field_mode && v->cur_field_type) {
 +    if (v->field_mode && v->second_field) {
          off    = s->current_picture_ptr->f.linesize[0];
          off_uv = s->current_picture_ptr->f.linesize[1];
      } else {
@@@ -3691,7 -3695,7 +3697,7 @@@ static int vc1_decode_p_mb_intfr(VC1Con
      int idx_mbmode = 0, mvbp;
      int stride_y, fieldtx;
  
 -    mquant = v->pq; /* Loosy initialization */
 +    mquant = v->pq; /* Lossy initialization */
  
      if (v->skip_is_raw)
          skipped = get_bits1(gb);
@@@ -3895,11 -3899,11 +3901,11 @@@ static int vc1_decode_p_mb_intfi(VC1Con
      int val; /* temp values */
      int first_block = 1;
      int dst_idx, off;
 -    int pred_flag;
 +    int pred_flag = 0;
      int block_cbp = 0, pat, block_tt = 0;
      int idx_mbmode = 0;
  
 -    mquant = v->pq; /* Loosy initialization */
 +    mquant = v->pq; /* Lossy initialization */
  
      idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_IF_MBMODE_VLC_BITS, 2);
      if (idx_mbmode <= 1) { // intra MB
                  continue;
              v->vc1dsp.vc1_inv_trans_8x8(s->block[i]);
              off  = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
 -            off += v->cur_field_type ? ((i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0]) : 0;
 +            off += v->second_field ? ((i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0]) : 0;
              s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, (i & 4) ? s->uvlinesize : s->linesize);
              // TODO: loop filter
          }
              dst_idx += i >> 2;
              val = ((cbp >> (5 - i)) & 1);
              off = (i & 4) ? 0 : (i & 1) * 8 + (i & 2) * 4 * s->linesize;
 -            if (v->cur_field_type)
 +            if (v->second_field)
                  off += (i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0];
              if (val) {
                  pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb,
@@@ -4172,7 -4176,7 +4178,7 @@@ static void vc1_decode_b_mb_intfi(VC1Co
      int bmvtype = BMV_TYPE_BACKWARD;
      int idx_mbmode, interpmvp;
  
 -    mquant      = v->pq; /* Loosy initialization */
 +    mquant      = v->pq; /* Lossy initialization */
      s->mb_intra = 0;
  
      idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_IF_MBMODE_VLC_BITS, 2);
                  for (j = 0; j < 64; j++)
                      s->block[i][j] <<= 1;
              off  = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
 -            off += v->cur_field_type ? ((i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0]) : 0;
 +            off += v->second_field ? ((i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0]) : 0;
              s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, (i & 4) ? s->uvlinesize : s->linesize);
              // TODO: yet to perform loop filter
          }
              dst_idx += i >> 2;
              val = ((cbp >> (5 - i)) & 1);
              off = (i & 4) ? 0 : (i & 1) * 8 + (i & 2) * 4 * s->linesize;
 -            if (v->cur_field_type)
 +            if (v->second_field)
                  off += (i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0];
              if (val) {
                  vc1_decode_p_block(v, s->block[i], i, mquant, ttmb,
@@@ -4644,7 -4648,7 +4650,7 @@@ static void vc1_decode_p_blocks(VC1Cont
          if (s->mb_y != s->start_mb_y) ff_draw_horiz_band(s, (s->mb_y - 1) * 16, 16);
          s->first_slice_line = 0;
      }
 -    if (apply_loop_filter) {
 +    if (apply_loop_filter && v->fcm == PROGRESSIVE) {
          s->mb_x = 0;
          ff_init_block_index(s);
          for (; s->mb_x < s->mb_width; s->mb_x++) {
@@@ -5317,16 -5321,13 +5323,16 @@@ static int vc1_decode_frame(AVCodecCont
      AVFrame *pict = data;
      uint8_t *buf2 = NULL;
      const uint8_t *buf_start = buf;
 -    int mb_height, n_slices1;
 +    int mb_height, n_slices1=-1;
      struct {
          uint8_t *buf;
          GetBitContext gb;
          int mby_start;
      } *slices = NULL, *tmp;
  
 +    if(s->flags & CODEC_FLAG_LOW_DELAY)
 +        s->low_delay = 1;
 +
      /* no supplementary picture */
      if (buf_size == 0 || (buf_size == 4 && AV_RB32(buf) == VC1_CODE_ENDOFSEQ)) {
          /* special case for last picture */
              *data_size = sizeof(AVFrame);
          }
  
 -        return 0;
 +        return buf_size;
      }
  
      if (s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) {
      // do parse frame header
      v->pic_header_flag = 0;
      if (v->profile < PROFILE_ADVANCED) {
 -        if (ff_vc1_parse_frame_header(v, &s->gb) == -1) {
 +        if (ff_vc1_parse_frame_header(v, &s->gb) < 0) {
              goto err;
          }
      } else {
 -        if (ff_vc1_parse_frame_header_adv(v, &s->gb) == -1) {
 +        if (ff_vc1_parse_frame_header_adv(v, &s->gb) < 0) {
              goto err;
          }
      }
  
 +    if (avctx->debug & FF_DEBUG_PICT_INFO)
 +        av_log(v->s.avctx, AV_LOG_DEBUG, "pict_type: %c\n", av_get_picture_type_char(s->pict_type));
 +
      if ((avctx->codec_id == AV_CODEC_ID_WMV3IMAGE || avctx->codec_id == AV_CODEC_ID_VC1IMAGE)
          && s->pict_type != AV_PICTURE_TYPE_I) {
          av_log(v->s.avctx, AV_LOG_ERROR, "Sprite decoder: expected I-frame\n");
          goto err;
      }
  
 +    v->s.current_picture_ptr->f.interlaced_frame = (v->fcm != PROGRESSIVE);
 +    v->s.current_picture_ptr->f.top_field_first  = v->tff;
 +
      s->me.qpel_put = s->dsp.put_qpel_pixels_tab;
      s->me.qpel_avg = s->dsp.avg_qpel_pixels_tab;
  
                  s->end_mb_y = (i == n_slices     ) ? mb_height : FFMIN(mb_height, slices[i].mby_start % mb_height);
              else
                  s->end_mb_y = (i <= n_slices1 + 1) ? mb_height : FFMIN(mb_height, slices[i].mby_start % mb_height);
 +            if (s->end_mb_y <= s->start_mb_y) {
 +                av_log(v->s.avctx, AV_LOG_ERROR, "end mb y %d %d invalid\n", s->end_mb_y, s->start_mb_y);
 +                continue;
 +            }
              ff_vc1_decode_blocks(v);
              if (i != n_slices)
                  s->gb = slices[i].gb;
                  get_bits_count(&s->gb), s->gb.size_in_bits);
  //  if (get_bits_count(&s->gb) > buf_size * 8)
  //      return -1;
 -        ff_er_frame_end(s);
 +        if(s->error_occurred && s->pict_type == AV_PICTURE_TYPE_B)
 +            goto err;
 +        if(!v->field_mode)
 +            ff_er_frame_end(s);
      }
  
      ff_MPV_frame_end(s);