mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
error_concealment: optimize guess_dc()
Fixes Ticket811 Bug found by: Oana Stratulat Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
parent
8d960fbc70
commit
a40f43db64
@ -154,11 +154,68 @@ static void filter181(int16_t *data, int width, int height, int stride){
|
||||
*/
|
||||
static void guess_dc(MpegEncContext *s, int16_t *dc, int w, int h, int stride, int is_luma){
|
||||
int b_x, b_y;
|
||||
int16_t (*col )[4] = av_malloc(stride*h*sizeof( int16_t)*4);
|
||||
uint16_t (*dist)[4] = av_malloc(stride*h*sizeof(uint16_t)*4);
|
||||
|
||||
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->current_picture.f.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->current_picture.f.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->current_picture.f.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->current_picture.f.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++){
|
||||
int color[4]={1024,1024,1024,1024};
|
||||
int distance[4]={9999,9999,9999,9999};
|
||||
int mb_index, error, j;
|
||||
int64_t guess, weight_sum;
|
||||
|
||||
@ -169,59 +226,12 @@ static void guess_dc(MpegEncContext *s, int16_t *dc, int w, int h, int stride, i
|
||||
if(IS_INTER(s->current_picture.f.mb_type[mb_index])) continue; //inter
|
||||
if(!(error&ER_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_stride;
|
||||
int error_j= s->error_status_table[mb_index_j];
|
||||
int intra_j = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]);
|
||||
if(intra_j==0 || !(error_j&ER_DC_ERROR)){
|
||||
color[0]= dc[j + b_y*stride];
|
||||
distance[0]= j-b_x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* left block */
|
||||
for(j=b_x-1; j>=0; j--){
|
||||
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 = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]);
|
||||
if(intra_j==0 || !(error_j&ER_DC_ERROR)){
|
||||
color[1]= dc[j + b_y*stride];
|
||||
distance[1]= b_x-j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* bottom block */
|
||||
for(j=b_y+1; j<h; j++){
|
||||
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 = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]);
|
||||
if(intra_j==0 || !(error_j&ER_DC_ERROR)){
|
||||
color[2]= dc[b_x + j*stride];
|
||||
distance[2]= j-b_y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* top block */
|
||||
for(j=b_y-1; j>=0; j--){
|
||||
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 = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]);
|
||||
if(intra_j==0 || !(error_j&ER_DC_ERROR)){
|
||||
color[3]= dc[b_x + j*stride];
|
||||
distance[3]= b_y-j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
weight_sum=0;
|
||||
guess=0;
|
||||
for(j=0; j<4; j++){
|
||||
int64_t weight= 256*256*256*16/distance[j];
|
||||
guess+= weight*(int64_t)color[j];
|
||||
int64_t weight= 256*256*256*16/dist[b_x + b_y*stride][j];
|
||||
guess+= weight*(int64_t)col[b_x + b_y*stride][j];
|
||||
weight_sum+= weight;
|
||||
}
|
||||
guess= (guess + weight_sum/2) / weight_sum;
|
||||
@ -229,6 +239,8 @@ static void guess_dc(MpegEncContext *s, int16_t *dc, int w, int h, int stride, i
|
||||
dc[b_x + b_y*stride]= guess;
|
||||
}
|
||||
}
|
||||
av_freep(&col);
|
||||
av_freep(&dist);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user