]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/error_resilience.c
ac3enc: move ff_ac3_encode_frame() to ac3enc_template.c
[ffmpeg] / libavcodec / error_resilience.c
index e0b64b0336f81bc4e1414d0bd49c07ccb82a6d25..8906b49c8058340e02f12363f95e066d13d8ce93 100644 (file)
@@ -32,6 +32,7 @@
 #include "mpegvideo.h"
 #include "h264.h"
 #include "rectangle.h"
+#include "thread.h"
 
 /*
  * H264 redefines mb_intra so it is not mistakely used (its uninitialized in h264)
@@ -428,8 +429,7 @@ int score_sum=0;
                     int best_score=256*256*256*64;
                     int best_pred=0;
                     const int mot_index= (mb_x + mb_y*mot_stride) * mot_step;
-                    int prev_x= s->current_picture.motion_val[0][mot_index][0];
-                    int prev_y= s->current_picture.motion_val[0][mot_index][1];
+                    int prev_x, prev_y, prev_ref;
 
                     if((mb_x^mb_y^pass)&1) continue;
 
@@ -527,11 +527,31 @@ skip_mean_and_median:
                     /* zero MV */
                     pred_count++;
 
+                    if (!fixed[mb_xy]) {
+                        if (s->avctx->codec_id == CODEC_ID_H264) {
+                            // FIXME
+                        } else {
+                            ff_thread_await_progress((AVFrame *) s->last_picture_ptr,
+                                                     mb_y, 0);
+                        }
+                        if (!s->last_picture.motion_val[0] ||
+                            !s->last_picture.ref_index[0])
+                            goto skip_last_mv;
+                        prev_x = s->last_picture.motion_val[0][mot_index][0];
+                        prev_y = s->last_picture.motion_val[0][mot_index][1];
+                        prev_ref = s->last_picture.ref_index[0][4*mb_xy];
+                    } else {
+                        prev_x = s->current_picture.motion_val[0][mot_index][0];
+                        prev_y = s->current_picture.motion_val[0][mot_index][1];
+                        prev_ref = s->current_picture.ref_index[0][4*mb_xy];
+                    }
+
                     /* last MV */
-                    mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index][0];
-                    mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index][1];
-                    ref         [pred_count]   = s->current_picture.ref_index[0][4*mb_xy];
+                    mv_predictor[pred_count][0]= prev_x;
+                    mv_predictor[pred_count][1]= prev_y;
+                    ref         [pred_count]   = prev_ref;
                     pred_count++;
+                skip_last_mv:
 
                     s->mv_dir = MV_DIR_FORWARD;
                     s->mb_intra=0;
@@ -639,7 +659,7 @@ static int is_intra_more_likely(MpegEncContext *s){
     if(undamaged_count < 5) return 0; //almost all MBs damaged -> use temporal prediction
 
     //prevent dsp.sad() check, that requires access to the image
-    if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration && s->pict_type == FF_I_TYPE)
+    if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration && s->pict_type == AV_PICTURE_TYPE_I)
         return 1;
 
     skip_amount= FFMAX(undamaged_count/50, 1); //check only upto 50 MBs
@@ -658,10 +678,16 @@ static int is_intra_more_likely(MpegEncContext *s){
             j++;
             if((j%skip_amount) != 0) continue; //skip a few to speed things up
 
-            if(s->pict_type==FF_I_TYPE){
+            if(s->pict_type==AV_PICTURE_TYPE_I){
                 uint8_t *mb_ptr     = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
                 uint8_t *last_mb_ptr= s->last_picture.data   [0] + mb_x*16 + mb_y*16*s->linesize;
 
+                if (s->avctx->codec_id == CODEC_ID_H264) {
+                    // FIXME
+                } else {
+                    ff_thread_await_progress((AVFrame *) s->last_picture_ptr,
+                                             mb_y, 0);
+                }
                 is_intra_likely += s->dsp.sad[0](NULL, last_mb_ptr, mb_ptr                    , s->linesize, 16);
                 is_intra_likely -= s->dsp.sad[0](NULL, last_mb_ptr, last_mb_ptr+s->linesize*16, s->linesize, 16);
             }else{
@@ -681,6 +707,7 @@ void ff_er_frame_start(MpegEncContext *s){
 
     memset(s->error_status_table, MV_ERROR|AC_ERROR|DC_ERROR|VP_START|AC_END|DC_END|MV_END, s->mb_stride*s->mb_height*sizeof(uint8_t));
     s->error_count= 3*s->mb_num;
+    s->error_occurred = 0;
 }
 
 /**
@@ -720,7 +747,10 @@ void ff_er_add_slice(MpegEncContext *s, int startx, int starty, int endx, int en
         s->error_count -= end_i - start_i + 1;
     }
 
-    if(status & (AC_ERROR|DC_ERROR|MV_ERROR)) s->error_count= INT_MAX;
+    if(status & (AC_ERROR|DC_ERROR|MV_ERROR)) {
+        s->error_occurred = 1;
+        s->error_count= INT_MAX;
+    }
 
     if(mask == ~0x7F){
         memset(&s->error_status_table[start_xy], 0, (end_xy - start_xy) * sizeof(uint8_t));
@@ -972,7 +1002,7 @@ void ff_er_frame_end(MpegEncContext *s){
     }
 
     /* guess MVs */
-    if(s->pict_type==FF_B_TYPE){
+    if(s->pict_type==AV_PICTURE_TYPE_B){
         for(mb_y=0; mb_y<s->mb_height; mb_y++){
             for(mb_x=0; mb_x<s->mb_width; mb_x++){
                 int xy= mb_x*2 + mb_y*2*s->b8_stride;
@@ -995,6 +1025,12 @@ void ff_er_frame_end(MpegEncContext *s){
                     int time_pp= s->pp_time;
                     int time_pb= s->pb_time;
 
+                    if (s->avctx->codec_id == CODEC_ID_H264) {
+                        //FIXME
+                    } else {
+                        ff_thread_await_progress((AVFrame *) s->next_picture_ptr,
+                                                 mb_y, 0);
+                    }
                     s->mv[0][0][0] = s->next_picture.motion_val[0][xy][0]*time_pb/time_pp;
                     s->mv[0][0][1] = s->next_picture.motion_val[0][xy][1]*time_pb/time_pp;
                     s->mv[1][0][0] = s->next_picture.motion_val[0][xy][0]*(time_pb - time_pp)/time_pp;
@@ -1107,7 +1143,7 @@ ec_clean:
         const int mb_xy= s->mb_index2xy[i];
         int error= s->error_status_table[mb_xy];
 
-        if(s->pict_type!=FF_B_TYPE && (error&(DC_ERROR|MV_ERROR|AC_ERROR))){
+        if(s->pict_type!=AV_PICTURE_TYPE_B && (error&(DC_ERROR|MV_ERROR|AC_ERROR))){
             s->mbskip_table[mb_xy]=0;
         }
         s->mbintra_table[mb_xy]=1;