mirror of https://git.ffmpeg.org/ffmpeg.git
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){
|
static void guess_dc(MpegEncContext *s, int16_t *dc, int w, int h, int stride, int is_luma){
|
||||||
int b_x, b_y;
|
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_y=0; b_y<h; b_y++){
|
||||||
for(b_x=0; b_x<w; b_x++){
|
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;
|
int mb_index, error, j;
|
||||||
int64_t guess, weight_sum;
|
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(IS_INTER(s->current_picture.f.mb_type[mb_index])) continue; //inter
|
||||||
if(!(error&ER_DC_ERROR)) continue; //dc-ok
|
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;
|
weight_sum=0;
|
||||||
guess=0;
|
guess=0;
|
||||||
for(j=0; j<4; j++){
|
for(j=0; j<4; j++){
|
||||||
int64_t weight= 256*256*256*16/distance[j];
|
int64_t weight= 256*256*256*16/dist[b_x + b_y*stride][j];
|
||||||
guess+= weight*(int64_t)color[j];
|
guess+= weight*(int64_t)col[b_x + b_y*stride][j];
|
||||||
weight_sum+= weight;
|
weight_sum+= weight;
|
||||||
}
|
}
|
||||||
guess= (guess + weight_sum/2) / weight_sum;
|
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;
|
dc[b_x + b_y*stride]= guess;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
av_freep(&col);
|
||||||
|
av_freep(&dist);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue