Merge commit 'd66e305bd1b4f3e91ae4e7e549148509d0811672'
authorMichael Niedermayer <michaelni@gmx.at>
Mon, 17 Mar 2014 03:59:21 +0000 (04:59 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Mon, 17 Mar 2014 04:08:46 +0000 (05:08 +0100)
* commit 'd66e305bd1b4f3e91ae4e7e549148509d0811672':
  er: move relevant fields from Picture to ERPicture

Conflicts:
libavcodec/error_resilience.c
libavcodec/h264.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavcodec/error_resilience.c
libavcodec/error_resilience.h
libavcodec/h264.c
libavcodec/mpegvideo.c
libavcodec/mpegvideo.h

@@@ -135,70 -135,6 +135,70 @@@ static void guess_dc(ERContext *s, int1
                       int h, int stride, int is_luma)
  {
      int b_x, b_y;
-             int intra_j = IS_INTRA(s->cur_pic->mb_type[mb_index_j]);
 +    int16_t  (*col )[4] = av_malloc(stride*h*sizeof( int16_t)*4);
 +    uint32_t (*dist)[4] = av_malloc(stride*h*sizeof(uint32_t)*4);
 +
 +    if(!col || !dist) {
 +        av_log(s->avctx, AV_LOG_ERROR, "guess_dc() is out of memory\n");
 +        goto fail;
 +    }
 +
 +    for(b_y=0; b_y<h; b_y++){
 +        int color= 1024;
 +        int distance= -1;
 +        for(b_x=0; b_x<w; b_x++){
 +            int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
 +            int error_j= s->error_status_table[mb_index_j];
-             int intra_j = IS_INTRA(s->cur_pic->mb_type[mb_index_j]);
++            int intra_j = IS_INTRA(s->cur_pic.mb_type[mb_index_j]);
 +            if(intra_j==0 || !(error_j&ER_DC_ERROR)){
 +                color= dc[b_x + b_y*stride];
 +                distance= b_x;
 +            }
 +            col [b_x + b_y*stride][1]= color;
 +            dist[b_x + b_y*stride][1]= distance >= 0 ? b_x-distance : 9999;
 +        }
 +        color= 1024;
 +        distance= -1;
 +        for(b_x=w-1; b_x>=0; b_x--){
 +            int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
 +            int error_j= s->error_status_table[mb_index_j];
-             int intra_j = IS_INTRA(s->cur_pic->mb_type[mb_index_j]);
++            int intra_j = IS_INTRA(s->cur_pic.mb_type[mb_index_j]);
 +            if(intra_j==0 || !(error_j&ER_DC_ERROR)){
 +                color= dc[b_x + b_y*stride];
 +                distance= b_x;
 +            }
 +            col [b_x + b_y*stride][0]= color;
 +            dist[b_x + b_y*stride][0]= distance >= 0 ? distance-b_x : 9999;
 +        }
 +    }
 +    for(b_x=0; b_x<w; b_x++){
 +        int color= 1024;
 +        int distance= -1;
 +        for(b_y=0; b_y<h; b_y++){
 +            int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
 +            int error_j= s->error_status_table[mb_index_j];
-             int intra_j = IS_INTRA(s->cur_pic->mb_type[mb_index_j]);
++            int intra_j = IS_INTRA(s->cur_pic.mb_type[mb_index_j]);
 +            if(intra_j==0 || !(error_j&ER_DC_ERROR)){
 +                color= dc[b_x + b_y*stride];
 +                distance= b_y;
 +            }
 +            col [b_x + b_y*stride][3]= color;
 +            dist[b_x + b_y*stride][3]= distance >= 0 ? b_y-distance : 9999;
 +        }
 +        color= 1024;
 +        distance= -1;
 +        for(b_y=h-1; b_y>=0; b_y--){
 +            int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
 +            int error_j= s->error_status_table[mb_index_j];
++            int intra_j = IS_INTRA(s->cur_pic.mb_type[mb_index_j]);
 +            if(intra_j==0 || !(error_j&ER_DC_ERROR)){
 +                color= dc[b_x + b_y*stride];
 +                distance= b_y;
 +            }
 +            col [b_x + b_y*stride][2]= color;
 +            dist[b_x + b_y*stride][2]= distance >= 0 ? distance-b_y : 9999;
 +        }
 +    }
  
      for (b_y = 0; b_y < h; b_y++) {
          for (b_x = 0; b_x < w; b_x++) {
@@@ -396,14 -379,6 +396,14 @@@ static void guess_mv(ERContext *s
          fixed[mb_xy] = f;
          if (f == MV_FROZEN)
              num_avail++;
-         else if(s->last_pic->f.data[0] && s->last_pic->motion_val[0]){
++        else if(s->last_pic.f->data[0] && s->last_pic.motion_val[0]){
 +            const int mb_y= mb_xy / s->mb_stride;
 +            const int mb_x= mb_xy % s->mb_stride;
 +            const int mot_index= (mb_x + mb_y*mot_stride) * mot_step;
-             s->cur_pic->motion_val[0][mot_index][0]= s->last_pic->motion_val[0][mot_index][0];
-             s->cur_pic->motion_val[0][mot_index][1]= s->last_pic->motion_val[0][mot_index][1];
-             s->cur_pic->ref_index[0][4*mb_xy]      = s->last_pic->ref_index[0][4*mb_xy];
++            s->cur_pic.motion_val[0][mot_index][0]= s->last_pic.motion_val[0][mot_index][0];
++            s->cur_pic.motion_val[0][mot_index][1]= s->last_pic.motion_val[0][mot_index][1];
++            s->cur_pic.ref_index[0][4*mb_xy]      = s->last_pic.ref_index[0][4*mb_xy];
 +        }
      }
  
      if ((!(s->avctx->error_concealment&FF_EC_GUESS_MVS)) ||
  
                      if (fixed[mb_xy] == MV_FROZEN)
                          continue;
-                     av_assert1(!IS_INTRA(s->cur_pic->mb_type[mb_xy]));
-                     av_assert1(s->last_pic && s->last_pic->f.data[0]);
 -                    assert(!IS_INTRA(s->cur_pic.mb_type[mb_xy]));
 -                    assert(s->last_pic && s->last_pic.f->data[0]);
++                    av_assert1(!IS_INTRA(s->cur_pic.mb_type[mb_xy]));
++                    av_assert1(s->last_pic.f && s->last_pic.f->data[0]);
  
                      j = 0;
                      if (mb_x > 0             && fixed[mb_xy - 1]         == MV_FROZEN)
@@@ -699,11 -674,15 +699,11 @@@ static int is_intra_more_likely(ERConte
      if (undamaged_count < 5)
          return 0; // almost all MBs damaged -> use temporal prediction
  
 -#if FF_API_XVMC
 -FF_DISABLE_DEPRECATION_WARNINGS
      // prevent dsp.sad() check, that requires access to the image
 -    if (CONFIG_MPEG_XVMC_DECODER    &&
 -        s->avctx->xvmc_acceleration &&
 +    if (CONFIG_XVMC    &&
 +        s->avctx->hwaccel && s->avctx->hwaccel->decode_mb &&
-         s->cur_pic->f.pict_type == AV_PICTURE_TYPE_I)
+         s->cur_pic.f->pict_type == AV_PICTURE_TYPE_I)
          return 1;
 -FF_ENABLE_DEPRECATION_WARNINGS
 -#endif /* FF_API_XVMC */
  
      skip_amount     = FFMAX(undamaged_count / 50, 1); // check only up to 50 MBs
      is_intra_likely = 0;
@@@ -764,17 -741,6 +764,17 @@@ void ff_er_frame_start(ERContext *s
      s->error_occurred = 0;
  }
  
-        !s->cur_pic                                                    ||
-        s->cur_pic->field_picture
 +static int er_supported(ERContext *s)
 +{
 +    if(s->avctx->hwaccel && s->avctx->hwaccel->decode_slice           ||
 +       s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU          ||
++       !s->cur_pic.f                                                  ||
++       s->cur_pic.field_picture
 +    )
 +        return 0;
 +    return 1;
 +}
 +
  /**
   * Add a slice.
   * @param endx   x component of the last macroblock, can be -1
@@@ -870,59 -835,11 +870,42 @@@ void ff_er_frame_end(ERContext *s
          s->error_count == 3 * s->mb_width *
                            (s->avctx->skip_top + s->avctx->skip_bottom)) {
          return;
 -    };
 +    }
 +    for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
 +        int status = s->error_status_table[mb_x + (s->mb_height - 1) * s->mb_stride];
 +        if (status != 0x7F)
 +            break;
 +    }
 +
 +    if (   mb_x == s->mb_width
 +        && s->avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO
 +        && (s->avctx->height&16)
 +        && s->error_count == 3 * s->mb_width * (s->avctx->skip_top + s->avctx->skip_bottom + 1)
 +    ) {
 +        av_log(s->avctx, AV_LOG_DEBUG, "ignoring last missing slice\n");
 +        return;
 +    }
 +
-     if (s->last_pic) {
-         if (s->last_pic->f.width  != s->cur_pic->f.width  ||
-             s->last_pic->f.height != s->cur_pic->f.height ||
-             s->last_pic->f.format != s->cur_pic->f.format) {
++    if (s->last_pic.f) {
++        if (s->last_pic.f->width  != s->cur_pic.f->width  ||
++            s->last_pic.f->height != s->cur_pic.f->height ||
++            s->last_pic.f->format != s->cur_pic.f->format) {
 +            av_log(s->avctx, AV_LOG_WARNING, "Cannot use previous picture in error concealment\n");
-             s->last_pic = NULL;
++            memset(&s->last_pic, 0, sizeof(s->last_pic));
 +        }
 +    }
-     if (s->next_pic) {
-         if (s->next_pic->f.width  != s->cur_pic->f.width  ||
-             s->next_pic->f.height != s->cur_pic->f.height ||
-             s->next_pic->f.format != s->cur_pic->f.format) {
++    if (s->next_pic.f) {
++        if (s->next_pic.f->width  != s->cur_pic.f->width  ||
++            s->next_pic.f->height != s->cur_pic.f->height ||
++            s->next_pic.f->format != s->cur_pic.f->format) {
 +            av_log(s->avctx, AV_LOG_WARNING, "Cannot use next picture in error concealment\n");
-             s->next_pic = NULL;
++            memset(&s->next_pic, 0, sizeof(s->next_pic));
 +        }
 +    }
  
-     if (s->cur_pic->motion_val[0] == NULL) {
-         av_log(s->avctx, AV_LOG_ERROR, "Warning MVs not available\n");
-         for (i = 0; i < 2; i++) {
-             s->cur_pic->ref_index_buf[i]  = av_buffer_allocz(s->mb_stride * s->mb_height * 4 * sizeof(uint8_t));
-             s->cur_pic->motion_val_buf[i] = av_buffer_allocz((size + 4) * 2 * sizeof(uint16_t));
-             if (!s->cur_pic->ref_index_buf[i] || !s->cur_pic->motion_val_buf[i])
-                 break;
-             s->cur_pic->ref_index[i]  = s->cur_pic->ref_index_buf[i]->data;
-             s->cur_pic->motion_val[i] = (int16_t (*)[2])s->cur_pic->motion_val_buf[i]->data + 4;
-         }
-         if (i < 2) {
-             for (i = 0; i < 2; i++) {
-                 av_buffer_unref(&s->cur_pic->ref_index_buf[i]);
-                 av_buffer_unref(&s->cur_pic->motion_val_buf[i]);
-                 s->cur_pic->ref_index[i]  = NULL;
-                 s->cur_pic->motion_val[i] = NULL;
-             }
-             return;
-         }
+     if (!s->cur_pic.motion_val[0] || !s->cur_pic.ref_index[0]) {
+         av_log(s->avctx, AV_LOG_ERROR, "MVs not available, ER not possible.\n");
+         return;
      }
  
      if (s->avctx->debug & FF_DEBUG_ER) {
          if (error & ER_MV_ERROR)
              mv_error++;
      }
 -    av_log(s->avctx, AV_LOG_INFO, "concealing %d DC, %d AC, %d MV errors\n",
 -           dc_error, ac_error, mv_error);
 +    av_log(s->avctx, AV_LOG_INFO, "concealing %d DC, %d AC, %d MV errors in %c frame\n",
-            dc_error, ac_error, mv_error, av_get_picture_type_char(s->cur_pic->f.pict_type));
++           dc_error, ac_error, mv_error, av_get_picture_type_char(s->cur_pic.f->pict_type));
  
      is_intra_likely = is_intra_more_likely(s);
  
                      int time_pp = s->pp_time;
                      int time_pb = s->pb_time;
  
-                     ff_thread_await_progress(&s->next_pic->tf, mb_y, 0);
 +                    av_assert0(s->avctx->codec_id != AV_CODEC_ID_H264);
+                     ff_thread_await_progress(s->next_pic.tf, mb_y, 0);
  
-                     s->mv[0][0][0] = s->next_pic->motion_val[0][xy][0] *  time_pb            / time_pp;
-                     s->mv[0][0][1] = s->next_pic->motion_val[0][xy][1] *  time_pb            / time_pp;
-                     s->mv[1][0][0] = s->next_pic->motion_val[0][xy][0] * (time_pb - time_pp) / time_pp;
-                     s->mv[1][0][1] = s->next_pic->motion_val[0][xy][1] * (time_pb - time_pp) / time_pp;
+                     s->mv[0][0][0] = s->next_pic.motion_val[0][xy][0] *  time_pb            / time_pp;
+                     s->mv[0][0][1] = s->next_pic.motion_val[0][xy][1] *  time_pb            / time_pp;
+                     s->mv[1][0][0] = s->next_pic.motion_val[0][xy][0] * (time_pb - time_pp) / time_pp;
+                     s->mv[1][0][1] = s->next_pic.motion_val[0][xy][1] * (time_pb - time_pp) / time_pp;
                  } else {
                      s->mv[0][0][0] = 0;
                      s->mv[0][0][1] = 0;
Simple merge
@@@ -1989,18 -1885,11 +1989,18 @@@ static int h264_frame_start(H264Contex
  
      h->cur_pic_ptr = pic;
      unref_picture(h, &h->cur_pic);
-         h->er.cur_pic = NULL;
 +    if (CONFIG_ERROR_RESILIENCE) {
++        memset(&h->er.cur_pic, 0, sizeof(h->er.cur_pic));
 +    }
 +
      if ((ret = ref_picture(h, &h->cur_pic, h->cur_pic_ptr)) < 0)
          return ret;
  
 -    if (CONFIG_ERROR_RESILIENCE)
 +    if (CONFIG_ERROR_RESILIENCE) {
          ff_er_frame_start(&h->er);
-         h->er.last_pic =
-         h->er.next_pic = NULL;
++        memset(&h->er.last_pic, 0, sizeof(h->er.last_pic));
++        memset(&h->er.next_pic, 0, sizeof(h->er.next_pic));
 +    }
  
      assert(h->linesize && h->uvlinesize);
  
@@@ -3048,13 -2973,14 +3048,13 @@@ static int field_end(H264Context *h, in
       * past end by one (callers fault) and resync_mb_y != 0
       * causes problems for the first MB line, too.
       */
 -    if (CONFIG_ERROR_RESILIENCE && !FIELD_PICTURE(h)) {
 +    if (CONFIG_ERROR_RESILIENCE && !FIELD_PICTURE(h) && h->current_slice && !h->sps.new) {
-         h->er.cur_pic  = h->cur_pic_ptr;
+         ff_mpeg_set_erpic(&h->er.cur_pic, h->cur_pic_ptr);
 -        ff_mpeg_set_erpic(&h->er.last_pic,
 -                          h->ref_count[0] ? &h->ref_list[0][0] : NULL);
 -        ff_mpeg_set_erpic(&h->er.next_pic,
 -                          h->ref_count[1] ? &h->ref_list[1][0] : NULL);
          ff_er_frame_end(&h->er);
      }
 +    if (!in_setup && !h->droppable)
 +        ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX,
 +                                  h->picture_structure == PICT_BOTTOM_FIELD);
      emms_c();
  
      h->current_slice = 0;
@@@ -4137,14 -3945,6 +4137,15 @@@ static int decode_slice_header(H264Cont
                               (h->ref_list[j][i].reference & 3);
      }
  
-     if (h->ref_count[0]) h->er.last_pic = &h->ref_list[0][0];
-     if (h->ref_count[1]) h->er.next_pic = &h->ref_list[1][0];
++    if (h->ref_count[0]) ff_mpeg_set_erpic(&h->er.last_pic, &h->ref_list[0][0]);
++    if (h->ref_count[1]) ff_mpeg_set_erpic(&h->er.next_pic, &h->ref_list[1][0]);
++
 +    h->er.ref_count = h->ref_count[0];
 +    h0->au_pps_id = pps_id;
 +    h->sps.new =
 +    h0->sps_buffers[h->pps.sps_id]->new = 0;
 +    h->current_sps_id = h->pps.sps_id;
 +
      if (h->avctx->debug & FF_DEBUG_PICT_INFO) {
          av_log(h->avctx, AV_LOG_DEBUG,
                 "slice:%d %s mb:%d %c%s%s pps:%u frame:%d poc:%d/%d ref:%d/%d qp:%d loop:%d:%d:%d weight:%d%s %s\n",
Simple merge
@@@ -830,10 -799,11 +830,12 @@@ void ff_MPV_report_decode_progress(Mpeg
  int ff_mpeg_update_thread_context(AVCodecContext *dst, const AVCodecContext *src);
  void ff_set_qscale(MpegEncContext * s, int qscale);
  
+ /* Error resilience */
  void ff_mpeg_er_frame_start(MpegEncContext *s);
+ void ff_mpeg_set_erpic(ERPicture *dst, Picture *src);
  
  int ff_dct_common_init(MpegEncContext *s);
 +int ff_dct_encode_init(MpegEncContext *s);
  void ff_convert_matrix(DSPContext *dsp, int (*qmat)[64], uint16_t (*qmat16)[2][64],
                         const uint16_t *quant_matrix, int bias, int qmin, int qmax, int intra);
  int ff_dct_quantize_c(MpegEncContext *s, int16_t *block, int n, int qscale, int *overflow);