summaryrefslogtreecommitdiff
path: root/libavcodec/error_resilience.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2003-04-10 13:18:38 +0000
committerMichael Niedermayer <michaelni@gmx.at>2003-04-10 13:18:38 +0000
commit7bc9090a4176de2bc834e2a7df131047b944f3b5 (patch)
tree1d57ac078ac227d652202cc1077ac565b8e36122 /libavcodec/error_resilience.c
parent84876d36774b6633c2950291fbfb3db5922273fb (diff)
simplified adressing of most mb based arrays (mb_x + mb_y*s->mb_stride) now instead of mb_x + mb_y*mb_width and 1+mb_x + (1+mb_y)*(mb_width+2) and ... mixture
more direct use of the new mb_type stuff instead of codec specific stuff runtime mb_type debug output h264/h263 variants/mpeg1/2/4 error concealment /resilience for mpeg1/2 various minor optimizations Originally committed as revision 1746 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/error_resilience.c')
-rw-r--r--libavcodec/error_resilience.c304
1 files changed, 162 insertions, 142 deletions
diff --git a/libavcodec/error_resilience.c b/libavcodec/error_resilience.c
index 486f5670a2..6a940ed0aa 100644
--- a/libavcodec/error_resilience.c
+++ b/libavcodec/error_resilience.c
@@ -23,6 +23,8 @@
* Error resilience / concealment.
*/
+#include <limits.h>
+
#include "avcodec.h"
#include "dsputil.h"
#include "mpegvideo.h"
@@ -111,18 +113,18 @@ static void guess_dc(MpegEncContext *s, int16_t *dc, int w, int h, int stride, i
int mb_index, error, j;
int64_t guess, weight_sum;
- mb_index= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_width;
+ mb_index= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
error= s->error_status_table[mb_index];
- if(!(s->mb_type[mb_index]&MB_TYPE_INTRA)) continue; //inter
+ if(IS_INTER(s->current_picture.mb_type[mb_index])) continue; //inter
if(!(error&DC_ERROR)) continue; //dc-ok
/* right block */
for(j=b_x+1; j<w; j++){
- int mb_index_j= (j>>is_luma) + (b_y>>is_luma)*s->mb_width;
+ int mb_index_j= (j>>is_luma) + (b_y>>is_luma)*s->mb_stride;
int error_j= s->error_status_table[mb_index_j];
- int intra_j= s->mb_type[mb_index_j]&MB_TYPE_INTRA;
+ int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]);
if(intra_j==0 || !(error_j&DC_ERROR)){
color[0]= dc[j + b_y*stride];
distance[0]= j-b_x;
@@ -132,9 +134,9 @@ static void guess_dc(MpegEncContext *s, int16_t *dc, int w, int h, int stride, i
/* left block */
for(j=b_x-1; j>=0; j--){
- int mb_index_j= (j>>is_luma) + (b_y>>is_luma)*s->mb_width;
+ int mb_index_j= (j>>is_luma) + (b_y>>is_luma)*s->mb_stride;
int error_j= s->error_status_table[mb_index_j];
- int intra_j= s->mb_type[mb_index_j]&MB_TYPE_INTRA;
+ int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]);
if(intra_j==0 || !(error_j&DC_ERROR)){
color[1]= dc[j + b_y*stride];
distance[1]= b_x-j;
@@ -144,9 +146,9 @@ static void guess_dc(MpegEncContext *s, int16_t *dc, int w, int h, int stride, i
/* bottom block */
for(j=b_y+1; j<h; j++){
- int mb_index_j= (b_x>>is_luma) + (j>>is_luma)*s->mb_width;
+ int mb_index_j= (b_x>>is_luma) + (j>>is_luma)*s->mb_stride;
int error_j= s->error_status_table[mb_index_j];
- int intra_j= s->mb_type[mb_index_j]&MB_TYPE_INTRA;
+ int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]);
if(intra_j==0 || !(error_j&DC_ERROR)){
color[2]= dc[b_x + j*stride];
distance[2]= j-b_y;
@@ -156,9 +158,9 @@ static void guess_dc(MpegEncContext *s, int16_t *dc, int w, int h, int stride, i
/* top block */
for(j=b_y-1; j>=0; j--){
- int mb_index_j= (b_x>>is_luma) + (j>>is_luma)*s->mb_width;
+ int mb_index_j= (b_x>>is_luma) + (j>>is_luma)*s->mb_stride;
int error_j= s->error_status_table[mb_index_j];
- int intra_j= s->mb_type[mb_index_j]&MB_TYPE_INTRA;
+ int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]);
if(intra_j==0 || !(error_j&DC_ERROR)){
color[3]= dc[b_x + j*stride];
distance[3]= b_y-j;
@@ -192,10 +194,10 @@ static void h_block_filter(MpegEncContext *s, uint8_t *dst, int w, int h, int st
for(b_y=0; b_y<h; b_y++){
for(b_x=0; b_x<w-1; b_x++){
int y;
- int left_status = s->error_status_table[( b_x >>is_luma) + (b_y>>is_luma)*s->mb_width];
- int right_status= s->error_status_table[((b_x+1)>>is_luma) + (b_y>>is_luma)*s->mb_width];
- int left_intra= s->mb_type [( b_x >>is_luma) + (b_y>>is_luma)*s->mb_width]&MB_TYPE_INTRA;
- int right_intra= s->mb_type [((b_x+1)>>is_luma) + (b_y>>is_luma)*s->mb_width]&MB_TYPE_INTRA;
+ int left_status = s->error_status_table[( b_x >>is_luma) + (b_y>>is_luma)*s->mb_stride];
+ int right_status= s->error_status_table[((b_x+1)>>is_luma) + (b_y>>is_luma)*s->mb_stride];
+ int left_intra= IS_INTRA(s->current_picture.mb_type [( b_x >>is_luma) + (b_y>>is_luma)*s->mb_stride]);
+ int right_intra= IS_INTRA(s->current_picture.mb_type [((b_x+1)>>is_luma) + (b_y>>is_luma)*s->mb_stride]);
int left_damage = left_status&(DC_ERROR|AC_ERROR|MV_ERROR);
int right_damage= right_status&(DC_ERROR|AC_ERROR|MV_ERROR);
int offset= b_x*8 + b_y*stride*8;
@@ -252,10 +254,10 @@ static void v_block_filter(MpegEncContext *s, uint8_t *dst, int w, int h, int st
for(b_y=0; b_y<h-1; b_y++){
for(b_x=0; b_x<w; b_x++){
int x;
- int top_status = s->error_status_table[(b_x>>is_luma) + ( b_y >>is_luma)*s->mb_width];
- int bottom_status= s->error_status_table[(b_x>>is_luma) + ((b_y+1)>>is_luma)*s->mb_width];
- int top_intra= s->mb_type [(b_x>>is_luma) + ( b_y >>is_luma)*s->mb_width]&MB_TYPE_INTRA;
- int bottom_intra= s->mb_type [(b_x>>is_luma) + ((b_y+1)>>is_luma)*s->mb_width]&MB_TYPE_INTRA;
+ int top_status = s->error_status_table[(b_x>>is_luma) + ( b_y >>is_luma)*s->mb_stride];
+ int bottom_status= s->error_status_table[(b_x>>is_luma) + ((b_y+1)>>is_luma)*s->mb_stride];
+ int top_intra= IS_INTRA(s->current_picture.mb_type [(b_x>>is_luma) + ( b_y >>is_luma)*s->mb_stride]);
+ int bottom_intra= IS_INTRA(s->current_picture.mb_type [(b_x>>is_luma) + ((b_y+1)>>is_luma)*s->mb_stride]);
int top_damage = top_status&(DC_ERROR|AC_ERROR|MV_ERROR);
int bottom_damage= bottom_status&(DC_ERROR|AC_ERROR|MV_ERROR);
int offset= b_x*8 + b_y*stride*8;
@@ -301,36 +303,37 @@ static void v_block_filter(MpegEncContext *s, uint8_t *dst, int w, int h, int st
}
static void guess_mv(MpegEncContext *s){
- uint8_t fixed[s->mb_num];
+ uint8_t fixed[s->mb_stride * s->mb_height];
#define MV_FROZEN 3
#define MV_CHANGED 2
#define MV_UNCHANGED 1
+ const int mb_stride = s->mb_stride;
const int mb_width = s->mb_width;
const int mb_height= s->mb_height;
int i, depth, num_avail;
+ int mb_x, mb_y;
num_avail=0;
for(i=0; i<s->mb_num; i++){
+ const int mb_xy= s->mb_index2xy[ i ];
int f=0;
- int error= s->error_status_table[i];
+ int error= s->error_status_table[mb_xy];
- if(s->mb_type[i]&MB_TYPE_INTRA) f=MV_FROZEN; //intra //FIXME check
+ if(IS_INTRA(s->current_picture.mb_type[mb_xy])) f=MV_FROZEN; //intra //FIXME check
if(!(error&MV_ERROR)) f=MV_FROZEN; //inter with undamaged MV
- fixed[i]= f;
+ fixed[mb_xy]= f;
if(f==MV_FROZEN)
num_avail++;
}
if((!(s->avctx->error_concealment&FF_EC_GUESS_MVS)) || num_avail <= mb_width/2){
- int mb_x, mb_y;
- i= -1;
for(mb_y=0; mb_y<s->mb_height; mb_y++){
for(mb_x=0; mb_x<s->mb_width; mb_x++){
- i++;
+ const int mb_xy= mb_x + mb_y*s->mb_stride;
- if(s->mb_type[i]&MB_TYPE_INTRA) continue;
- if(!(s->error_status_table[i]&MV_ERROR)) continue;
+ if(IS_INTRA(s->current_picture.mb_type[mb_xy])) continue;
+ if(!(s->error_status_table[mb_xy]&MV_ERROR)) continue;
s->mv_dir = MV_DIR_FORWARD;
s->mb_intra=0;
@@ -355,13 +358,13 @@ static void guess_mv(MpegEncContext *s){
none_left=1;
changed=1;
for(pass=0; (changed || pass<2) && pass<10; pass++){
- int i,mb_x, mb_y;
+ int mb_x, mb_y;
int score_sum=0;
changed=0;
- i= -1;
for(mb_y=0; mb_y<s->mb_height; mb_y++){
for(mb_x=0; mb_x<s->mb_width; mb_x++){
+ const int mb_xy= mb_x + mb_y*s->mb_stride;
int mv_predictor[8][2]={{0}};
int pred_count=0;
int j;
@@ -372,43 +375,44 @@ int score_sum=0;
int prev_x= s->motion_val[mot_index][0];
int prev_y= s->motion_val[mot_index][1];
- i++;
if((mb_x^mb_y^pass)&1) continue;
- if(fixed[i]==MV_FROZEN) continue;
+ if(fixed[mb_xy]==MV_FROZEN) continue;
+ assert(!IS_INTRA(s->current_picture.mb_type[mb_xy]));
+ assert(s->last_picture_ptr && s->last_picture_ptr->data[0]);
j=0;
- if(mb_x>0 && fixed[i-1 ]==MV_FROZEN) j=1;
- if(mb_x+1<mb_width && fixed[i+1 ]==MV_FROZEN) j=1;
- if(mb_y>0 && fixed[i-mb_width]==MV_FROZEN) j=1;
- if(mb_y+1<mb_height && fixed[i+mb_width]==MV_FROZEN) j=1;
+ if(mb_x>0 && fixed[mb_xy-1 ]==MV_FROZEN) j=1;
+ if(mb_x+1<mb_width && fixed[mb_xy+1 ]==MV_FROZEN) j=1;
+ if(mb_y>0 && fixed[mb_xy-mb_stride]==MV_FROZEN) j=1;
+ if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]==MV_FROZEN) j=1;
if(j==0) continue;
j=0;
- if(mb_x>0 && fixed[i-1 ]==MV_CHANGED) j=1;
- if(mb_x+1<mb_width && fixed[i+1 ]==MV_CHANGED) j=1;
- if(mb_y>0 && fixed[i-mb_width]==MV_CHANGED) j=1;
- if(mb_y+1<mb_height && fixed[i+mb_width]==MV_CHANGED) j=1;
+ if(mb_x>0 && fixed[mb_xy-1 ]==MV_CHANGED) j=1;
+ if(mb_x+1<mb_width && fixed[mb_xy+1 ]==MV_CHANGED) j=1;
+ if(mb_y>0 && fixed[mb_xy-mb_stride]==MV_CHANGED) j=1;
+ if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]==MV_CHANGED) j=1;
if(j==0 && pass>1) continue;
none_left=0;
- if(mb_x>0 && fixed[i-1]){
+ if(mb_x>0 && fixed[mb_xy-1]){
mv_predictor[pred_count][0]= s->motion_val[mot_index - 2][0];
mv_predictor[pred_count][1]= s->motion_val[mot_index - 2][1];
pred_count++;
}
- if(mb_x+1<mb_width && fixed[i+1]){
+ if(mb_x+1<mb_width && fixed[mb_xy+1]){
mv_predictor[pred_count][0]= s->motion_val[mot_index + 2][0];
mv_predictor[pred_count][1]= s->motion_val[mot_index + 2][1];
pred_count++;
}
- if(mb_y>0 && fixed[i-mb_width]){
+ if(mb_y>0 && fixed[mb_xy-mb_stride]){
mv_predictor[pred_count][0]= s->motion_val[mot_index - mot_stride*2][0];
mv_predictor[pred_count][1]= s->motion_val[mot_index - mot_stride*2][1];
pred_count++;
}
- if(mb_y+1<mb_height && fixed[i+mb_width]){
+ if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]){
mv_predictor[pred_count][0]= s->motion_val[mot_index + mot_stride*2][0];
mv_predictor[pred_count][1]= s->motion_val[mot_index + mot_stride*2][1];
pred_count++;
@@ -468,30 +472,32 @@ int score_sum=0;
s->mb_x= mb_x;
s->mb_y= mb_y;
+
for(j=0; j<pred_count; j++){
int score=0;
uint8_t *src= s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
s->motion_val[mot_index][0]= s->mv[0][0][0]= mv_predictor[j][0];
s->motion_val[mot_index][1]= s->mv[0][0][1]= mv_predictor[j][1];
+
MPV_decode_mb(s, s->block);
- if(mb_x>0 && fixed[i-1]){
+ if(mb_x>0 && fixed[mb_xy-1]){
int k;
for(k=0; k<16; k++)
score += ABS(src[k*s->linesize-1 ]-src[k*s->linesize ]);
}
- if(mb_x+1<mb_width && fixed[i+1]){
+ if(mb_x+1<mb_width && fixed[mb_xy+1]){
int k;
for(k=0; k<16; k++)
score += ABS(src[k*s->linesize+15]-src[k*s->linesize+16]);
}
- if(mb_y>0 && fixed[i-mb_width]){
+ if(mb_y>0 && fixed[mb_xy-mb_stride]){
int k;
for(k=0; k<16; k++)
score += ABS(src[k-s->linesize ]-src[k ]);
}
- if(mb_y+1<mb_height && fixed[i+mb_width]){
+ if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]){
int k;
for(k=0; k<16; k++)
score += ABS(src[k+s->linesize*15]-src[k+s->linesize*16]);
@@ -511,10 +517,10 @@ score_sum+= best_score;
if(s->mv[0][0][0] != prev_x || s->mv[0][0][1] != prev_y){
- fixed[i]=MV_CHANGED;
+ fixed[mb_xy]=MV_CHANGED;
changed++;
}else
- fixed[i]=MV_UNCHANGED;
+ fixed[mb_xy]=MV_UNCHANGED;
}
}
@@ -525,8 +531,9 @@ score_sum+= best_score;
return;
for(i=0; i<s->mb_num; i++){
- if(fixed[i])
- fixed[i]=MV_FROZEN;
+ int mb_xy= s->mb_index2xy[i];
+ if(fixed[mb_xy])
+ fixed[mb_xy]=MV_FROZEN;
}
// printf(":"); fflush(stdout);
}
@@ -539,7 +546,8 @@ static int is_intra_more_likely(MpegEncContext *s){
undamaged_count=0;
for(i=0; i<s->mb_num; i++){
- int error= s->error_status_table[i];
+ const int mb_xy= s->mb_index2xy[i];
+ const int error= s->error_status_table[mb_xy];
if(!((error&DC_ERROR) && (error&MV_ERROR)))
undamaged_count++;
}
@@ -550,13 +558,12 @@ static int is_intra_more_likely(MpegEncContext *s){
is_intra_likely=0;
j=0;
- i=-1;
for(mb_y= 0; mb_y<s->mb_height-1; mb_y++){
for(mb_x= 0; mb_x<s->mb_width; mb_x++){
int error;
+ const int mb_xy= mb_x + mb_y*s->mb_stride;
- i++;
- error= s->error_status_table[i];
+ error= s->error_status_table[mb_xy];
if((error&DC_ERROR) && (error&MV_ERROR))
continue; //skip damaged
@@ -570,7 +577,7 @@ static int is_intra_more_likely(MpegEncContext *s){
is_intra_likely += s->dsp.pix_abs16x16(last_mb_ptr, mb_ptr , s->linesize);
is_intra_likely -= s->dsp.pix_abs16x16(last_mb_ptr, last_mb_ptr+s->linesize*16, s->linesize);
}else{
- if(s->mbintra_table[i]) //HACK (this is allways inited but we should use mb_type[])
+ if(IS_INTRA(s->current_picture.mb_type[mb_xy]))
is_intra_likely++;
else
is_intra_likely--;
@@ -584,7 +591,8 @@ static int is_intra_more_likely(MpegEncContext *s){
void ff_er_frame_start(MpegEncContext *s){
if(!s->error_resilience) return;
- memset(s->error_status_table, MV_ERROR|AC_ERROR|DC_ERROR|VP_START|AC_END|DC_END|MV_END, s->mb_num*sizeof(uint8_t));
+ 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;
}
/**
@@ -594,33 +602,54 @@ void ff_er_frame_start(MpegEncContext *s){
* error of the same type occured
*/
void ff_er_add_slice(MpegEncContext *s, int startx, int starty, int endx, int endy, int status){
- const int start_xy= clip(startx + starty * s->mb_width, 0, s->mb_num-1);
- const int end_xy = clip(endx + endy * s->mb_width, 0, s->mb_num);
- const int mb_count= end_xy - start_xy;
+ const int start_i= clip(startx + starty * s->mb_width , 0, s->mb_num-1);
+ const int end_i = clip(endx + endy * s->mb_width , 0, s->mb_num);
+ const int start_xy= s->mb_index2xy[start_i];
+ const int end_xy = s->mb_index2xy[end_i];
int mask= -1;
if(!s->error_resilience) return;
mask &= ~VP_START;
- if(status & (AC_ERROR|AC_END)) mask &= ~(AC_ERROR|AC_END);
- if(status & (DC_ERROR|DC_END)) mask &= ~(DC_ERROR|DC_END);
- if(status & (MV_ERROR|MV_END)) mask &= ~(MV_ERROR|MV_END);
+ if(status & (AC_ERROR|AC_END)){
+ mask &= ~(AC_ERROR|AC_END);
+ s->error_count -= end_i - start_i + 1;
+ }
+ if(status & (DC_ERROR|DC_END)){
+ mask &= ~(DC_ERROR|DC_END);
+ s->error_count -= end_i - start_i + 1;
+ }
+ if(status & (MV_ERROR|MV_END)){
+ mask &= ~(MV_ERROR|MV_END);
+ s->error_count -= end_i - start_i + 1;
+ }
+
+ if(status & (AC_ERROR|DC_ERROR|MV_ERROR)) s->error_count= INT_MAX;
if(mask == ~0x7F){
- memset(&s->error_status_table[start_xy], 0, mb_count * sizeof(uint8_t));
+ memset(&s->error_status_table[start_xy], 0, (end_xy - start_xy) * sizeof(uint8_t));
}else{
int i;
for(i=start_xy; i<end_xy; i++){
- s->error_status_table[i] &= mask;
+ s->error_status_table[ i ] &= mask;
}
}
-
- if(end_xy < s->mb_num){
+
+ if(end_i == s->mb_num)
+ s->error_count= INT_MAX;
+ else{
s->error_status_table[end_xy] &= mask;
s->error_status_table[end_xy] |= status;
}
s->error_status_table[start_xy] |= VP_START;
+
+ if(start_xy > 0){
+ int prev_status= s->error_status_table[ s->mb_index2xy[start_i - 1] ];
+
+ prev_status &= ~ VP_START;
+ if(prev_status != (MV_END|DC_END|AC_END)) s->error_count= INT_MAX;
+ }
}
void ff_er_frame_end(MpegEncContext *s){
@@ -629,41 +658,27 @@ void ff_er_frame_end(MpegEncContext *s){
int threshold_part[4]= {100,100,100};
int threshold= 50;
int is_intra_likely;
- int num_end_markers=0;
- if(!s->error_resilience) return;
+ if(!s->error_resilience || s->error_count==0) return;
- error=0;
- for(i=0; i<s->mb_num; i++){
- int status= s->error_status_table[i];
+ fprintf(stderr, "concealing errors\n");
+
+ if(s->motion_val == NULL){
+ int size = (2 * s->mb_width + 2) * (2 * s->mb_height + 2);
- if(status==0) continue;
-
- if(status&(DC_ERROR|AC_ERROR|MV_ERROR))
- error=1;
- if(status&VP_START){
- if(num_end_markers)
- error=1;
- num_end_markers=3;
- }
- if(status&AC_END)
- num_end_markers--;
- if(status&DC_END)
- num_end_markers--;
- if(status&MV_END)
- num_end_markers--;
+ fprintf(stderr, "Warning MVs not available\n");
+
+ s->motion_val= av_mallocz(size * 2 * sizeof(int16_t));
}
- if(num_end_markers==0 && error==0)
- return;
-
- fprintf(stderr, "concealing errors\n");
-
- if(s->avctx->debug&FF_DEBUG_ER){
- for(i=0; i<s->mb_num; i++){
- int status= s->error_status_table[i];
+
+ if(s->avctx->debug&FF_DEBUG_ER){
+ for(mb_y=0; mb_y<s->mb_height; mb_y++){
+ for(mb_x=0; mb_x<s->mb_width; mb_x++){
+ int status= s->error_status_table[mb_x + mb_y*s->mb_stride];
- if(i%s->mb_width == 0) printf("\n");
- printf("%2X ", status);
+ printf("%2X ", status);
+ }
+ printf("\n");
}
}
@@ -673,7 +688,8 @@ void ff_er_frame_end(MpegEncContext *s){
int end_ok=0;
for(i=s->mb_num-1; i>=0; i--){
- int error= s->error_status_table[i];
+ const int mb_xy= s->mb_index2xy[i];
+ int error= s->error_status_table[mb_xy];
if(error&(1<<error_type))
end_ok=1;
@@ -681,7 +697,7 @@ void ff_er_frame_end(MpegEncContext *s){
end_ok=1;
if(!end_ok)
- s->error_status_table[i]|= 1<<error_type;
+ s->error_status_table[mb_xy]|= 1<<error_type;
if(error&VP_START)
end_ok=0;
@@ -694,7 +710,8 @@ void ff_er_frame_end(MpegEncContext *s){
int end_ok=0;
for(i=s->mb_num-1; i>=0; i--){
- int error= s->error_status_table[i];
+ const int mb_xy= s->mb_index2xy[i];
+ int error= s->error_status_table[mb_xy];
if(error&AC_END)
end_ok=0;
@@ -702,7 +719,7 @@ void ff_er_frame_end(MpegEncContext *s){
end_ok=1;
if(!end_ok)
- s->error_status_table[i]|= AC_ERROR;
+ s->error_status_table[mb_xy]|= AC_ERROR;
if(error&VP_START)
end_ok=0;
@@ -714,8 +731,9 @@ void ff_er_frame_end(MpegEncContext *s){
int end_ok=1;
for(i=s->mb_num-2; i>=s->mb_width+100; i--){ //FIXME +100 hack
- int error1= s->error_status_table[i ];
- int error2= s->error_status_table[i+1];
+ const int mb_xy= s->mb_index2xy[i];
+ int error1= s->error_status_table[mb_xy ];
+ int error2= s->error_status_table[mb_xy+1];
if(error1&VP_START)
end_ok=1;
@@ -727,7 +745,7 @@ void ff_er_frame_end(MpegEncContext *s){
}
if(!end_ok)
- s->error_status_table[i]|= DC_ERROR|AC_ERROR|MV_ERROR;
+ s->error_status_table[mb_xy]|= DC_ERROR|AC_ERROR|MV_ERROR;
}
}
@@ -736,19 +754,20 @@ void ff_er_frame_end(MpegEncContext *s){
distance=9999999;
for(error_type=1; error_type<=3; error_type++){
for(i=s->mb_num-1; i>=0; i--){
- int error= s->error_status_table[i];
+ const int mb_xy= s->mb_index2xy[i];
+ int error= s->error_status_table[mb_xy];
- if(!s->mbskip_table[i]) //FIXME partition specific
+ if(!s->mbskip_table[mb_xy]) //FIXME partition specific
distance++;
if(error&(1<<error_type))
distance= 0;
if(s->partitioned_frame){
if(distance < threshold_part[error_type-1])
- s->error_status_table[i]|= 1<<error_type;
+ s->error_status_table[mb_xy]|= 1<<error_type;
}else{
if(distance < threshold)
- s->error_status_table[i]|= 1<<error_type;
+ s->error_status_table[mb_xy]|= 1<<error_type;
}
if(error&VP_START)
@@ -760,23 +779,25 @@ void ff_er_frame_end(MpegEncContext *s){
/* forward mark errors */
error=0;
for(i=0; i<s->mb_num; i++){
- int old_error= s->error_status_table[i];
+ const int mb_xy= s->mb_index2xy[i];
+ int old_error= s->error_status_table[mb_xy];
if(old_error&VP_START)
error= old_error& (DC_ERROR|AC_ERROR|MV_ERROR);
else{
error|= old_error& (DC_ERROR|AC_ERROR|MV_ERROR);
- s->error_status_table[i]|= error;
+ s->error_status_table[mb_xy]|= error;
}
}
#if 1
/* handle not partitioned case */
if(!s->partitioned_frame){
for(i=0; i<s->mb_num; i++){
- error= s->error_status_table[i];
+ const int mb_xy= s->mb_index2xy[i];
+ error= s->error_status_table[mb_xy];
if(error&(AC_ERROR|DC_ERROR|MV_ERROR))
error|= AC_ERROR|DC_ERROR|MV_ERROR;
- s->error_status_table[i]= error;
+ s->error_status_table[mb_xy]= error;
}
}
#endif
@@ -784,34 +805,32 @@ void ff_er_frame_end(MpegEncContext *s){
/* set unknown mb-type to most likely */
for(i=0; i<s->mb_num; i++){
- int intra;
- error= s->error_status_table[i];
- if((error&DC_ERROR) && (error&MV_ERROR))
- intra= is_intra_likely;
- else
- intra= s->mbintra_table[i];
+ const int mb_xy= s->mb_index2xy[i];
+ error= s->error_status_table[mb_xy];
+ if(!((error&DC_ERROR) && (error&MV_ERROR)))
+ continue;
- if(intra)
- s->mb_type[i]|= MB_TYPE_INTRA;
+ if(is_intra_likely)
+ s->current_picture.mb_type[mb_xy]= MB_TYPE_INTRA4x4;
else
- s->mb_type[i]&= ~MB_TYPE_INTRA;
+ s->current_picture.mb_type[mb_xy]= MB_TYPE_16x16 | MB_TYPE_L0;
}
/* handle inter blocks with damaged AC */
- i= -1;
for(mb_y=0; mb_y<s->mb_height; mb_y++){
for(mb_x=0; mb_x<s->mb_width; mb_x++){
- i++;
- error= s->error_status_table[i];
+ const int mb_xy= mb_x + mb_y * s->mb_stride;
+ const int mb_type= s->current_picture.mb_type[mb_xy];
+ error= s->error_status_table[mb_xy];
- if(s->mb_type[i]&MB_TYPE_INTRA) continue; //intra
+ if(IS_INTRA(mb_type)) continue; //intra
if(error&MV_ERROR) continue; //inter with damaged MV
if(!(error&AC_ERROR)) continue; //undamaged inter
s->mv_dir = MV_DIR_FORWARD;
s->mb_intra=0;
s->mb_skiped=0;
- if(s->mb_type[i]&MB_TYPE_INTER4V){
+ if(IS_8X8(mb_type)){
int mb_index= mb_x*2+1 + (mb_y*2+1)*s->block_wrap[0];
int j;
s->mv_type = MV_TYPE_8X8;
@@ -835,14 +854,14 @@ void ff_er_frame_end(MpegEncContext *s){
/* guess MVs */
if(s->pict_type==B_TYPE){
- i= -1;
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+1 + (mb_y*2+1)*s->block_wrap[0];
- i++;
- error= s->error_status_table[i];
+ const int mb_xy= mb_x + mb_y * s->mb_stride;
+ const int mb_type= s->current_picture.mb_type[mb_xy];
+ error= s->error_status_table[mb_xy];
- if(s->mb_type[i]&MB_TYPE_INTRA) continue; //intra
+ if(IS_INTRA(mb_type)) continue;
if(!(error&MV_ERROR)) continue; //inter with undamaged MV
if(!(error&AC_ERROR)) continue; //undamaged inter
@@ -876,17 +895,17 @@ void ff_er_frame_end(MpegEncContext *s){
guess_mv(s);
/* fill DC for inter blocks */
- i= -1;
for(mb_y=0; mb_y<s->mb_height; mb_y++){
for(mb_x=0; mb_x<s->mb_width; mb_x++){
int dc, dcu, dcv, y, n;
int16_t *dc_ptr;
uint8_t *dest_y, *dest_cb, *dest_cr;
+ const int mb_xy= mb_x + mb_y * s->mb_stride;
+ const int mb_type= s->current_picture.mb_type[mb_xy];
- i++;
- error= s->error_status_table[i];
+ error= s->error_status_table[mb_xy];
- if(s->mb_type[i]&MB_TYPE_INTRA) continue; //intra
+ if(IS_INTRA(mb_type) && s->partitioned_frame) continue;
// if(error&MV_ERROR) continue; //inter data damaged FIXME is this good?
dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
@@ -928,15 +947,15 @@ void ff_er_frame_end(MpegEncContext *s){
#if 1
/* render DC only intra */
- i= -1;
for(mb_y=0; mb_y<s->mb_height; mb_y++){
for(mb_x=0; mb_x<s->mb_width; mb_x++){
uint8_t *dest_y, *dest_cb, *dest_cr;
-
- i++;
- error= s->error_status_table[i];
+ const int mb_xy= mb_x + mb_y * s->mb_stride;
+ const int mb_type= s->current_picture.mb_type[mb_xy];
+
+ error= s->error_status_table[mb_xy];
- if(!(s->mb_type[i]&MB_TYPE_INTRA)) continue; //inter
+ if(IS_INTER(mb_type)) continue;
if(!(error&AC_ERROR)) continue; //undamaged
dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
@@ -962,11 +981,12 @@ void ff_er_frame_end(MpegEncContext *s){
/* clean a few tables */
for(i=0; i<s->mb_num; i++){
- int error= s->error_status_table[i];
+ const int mb_xy= s->mb_index2xy[i];
+ int error= s->error_status_table[mb_xy];
if(s->pict_type!=B_TYPE && (error&(DC_ERROR|MV_ERROR|AC_ERROR))){
- s->mbskip_table[i]=0;
+ s->mbskip_table[mb_xy]=0;
}
- s->mbintra_table[i]=1;
+ s->mbintra_table[mb_xy]=1;
}
}