📄 image.c
字号:
if ((p->chroma_format_idc==YUV400) && input->write_uv)
{
comp_size_x[1] = comp_size_x[2] = (p->size_x >> 1);
comp_size_y[1] = comp_size_y[2] = (p->size_y >> 1);
}
else
{
// These could be computed once and attached to the StorablePicture structure
comp_size_x[1] = comp_size_x[2] = (p->size_x_cr - crop_left - crop_right);
comp_size_y[1] = comp_size_y[2] = (p->size_y_cr - crop_top - crop_bottom);
}
framesize_in_bytes = (((int64) comp_size_x[0] * comp_size_y[0]) + ((int64) comp_size_x[1] * comp_size_y[1] ) * 2) * symbol_size_in_bytes;
// KS: this buffer should actually be allocated only once, but this is still much faster than the previous version
buf = malloc ( comp_size_x[0] * comp_size_y[0] * symbol_size_in_bytes );
if (NULL == buf)
{
no_mem_exit("find_snr: buf");
}
status = lseek (p_ref, framesize_in_bytes * frame_no, SEEK_SET);
if (status == -1)
{
fprintf(stderr, "Error in seeking frame number: %d\n", frame_no);
free (buf);
return;
}
if(rgb_output)
lseek (p_ref, framesize_in_bytes/3, SEEK_CUR);
for (k = 0; k < ((p->chroma_format_idc != YUV400) ? 3 : 1); k++)
{
if(rgb_output && k == 2)
lseek (p_ref, -framesize_in_bytes, SEEK_CUR);
read(p_ref, buf, comp_size_x[k] * comp_size_y[k] * symbol_size_in_bytes);
buf2img(cur_ref[k], buf, comp_size_x[k], comp_size_y[k], symbol_size_in_bytes);
for (j=0; j < comp_size_y[k]; ++j)
{
for (i=0; i < comp_size_x[k]; ++i)
{
diff_comp[k] += iabs2(cur_comp[k][j][i] - cur_ref[k][j][i]);
}
}
#if ZEROSNR
diff_comp[k] = max(diff_comp[k], 1);
#endif
// Collecting SNR statistics
if (diff_comp[k] != 0)
snr->snr[k]=(float)(10*log10(max_pix_value_sqd[k]*(double)((double)(comp_size_x[k])*(comp_size_y[k]) / diff_comp[k])));
else
snr->snr[k]=0.0;
if (img->number == 0) // first
{
snr->snra[k]=snr->snr1[k]=snr->snr[k]; // keep luma snr for first frame
}
else
{
snr->snra[k]=(float)(snr->snra[k]*(snr->frame_ctr)+snr->snr[k])/(snr->frame_ctr + 1); // average snr chroma for all frames
}
}
if(rgb_output)
lseek (p_ref, framesize_in_bytes*2/3, SEEK_CUR);
free (buf);
// picture error concealment
if(p->concealed_pic)
{
fprintf(stdout,"%04d(P) %8d %5d %5d %7.4f %7.4f %7.4f %s %5d\n",
frame_no, p->frame_poc, p->pic_num, p->qp,
snr->snr[0], snr->snr[1], snr->snr[2], yuv_types[p->chroma_format_idc], 0);
}
}
/*!
************************************************************************
* \brief
* Interpolation of 1/4 subpixel
************************************************************************
*/
void get_block(int ref_frame, StorablePicture **list, int x_pos, int y_pos, struct img_par *img, int block[MB_BLOCK_SIZE][MB_BLOCK_SIZE])
{
int dx, dy;
int i, j;
int maxold_x,maxold_y;
int result;
int pres_x, pres_y;
int tmp_res[9][9];
static const int COEF[6] = { 1, -5, 20, 20, -5, 1 };
StorablePicture *curr_ref = list[ref_frame];
static imgpel **cur_imgY, *cur_lineY;
static int jpos_m2, jpos_m1, jpos, jpos_p1, jpos_p2, jpos_p3;
static int ipos_m2, ipos_m1, ipos, ipos_p1, ipos_p2, ipos_p3;
if (curr_ref == no_reference_picture && img->framepoc < img->recovery_poc)
{
printf("list[ref_frame] is equal to 'no reference picture' before RAP\n");
/* fill the block with sample value 128 */
for (j = 0; j < BLOCK_SIZE; j++)
for (i = 0; i < BLOCK_SIZE; i++)
block[j][i] = 128;
return;
}
cur_imgY = curr_ref->imgY;
dx = x_pos&3;
dy = y_pos&3;
x_pos = (x_pos-dx)>>2;
y_pos = (y_pos-dy)>>2;
maxold_x = dec_picture->size_x_m1;
maxold_y = dec_picture->size_y_m1;
if (dec_picture->mb_field[img->current_mb_nr])
maxold_y = (dec_picture->size_y >> 1) - 1;
if (dx == 0 && dy == 0)
{ /* fullpel position */
for (j = 0; j < BLOCK_SIZE; j++)
{
cur_lineY = cur_imgY[iClip3(0,maxold_y,y_pos+j)];
block[j][0] = cur_lineY[iClip3(0,maxold_x,x_pos )];
block[j][1] = cur_lineY[iClip3(0,maxold_x,x_pos+1)];
block[j][2] = cur_lineY[iClip3(0,maxold_x,x_pos+2)];
block[j][3] = cur_lineY[iClip3(0,maxold_x,x_pos+3)];
}
}
else
{ /* other positions */
if (dy == 0)
{ /* No vertical interpolation */
for (i = 0; i < BLOCK_SIZE; i++)
{
ipos_m2 = iClip3(0, maxold_x, x_pos + i - 2);
ipos_m1 = iClip3(0, maxold_x, x_pos + i - 1);
ipos = iClip3(0, maxold_x, x_pos + i );
ipos_p1 = iClip3(0, maxold_x, x_pos + i + 1);
ipos_p2 = iClip3(0, maxold_x, x_pos + i + 2);
ipos_p3 = iClip3(0, maxold_x, x_pos + i + 3);
for (j = 0; j < BLOCK_SIZE; j++)
{
cur_lineY = cur_imgY[iClip3(0,maxold_y,y_pos+j)];
result = (cur_lineY[ipos_m2] + cur_lineY[ipos_p3]) * COEF[0];
result += (cur_lineY[ipos_m1] + cur_lineY[ipos_p2]) * COEF[1];
result += (cur_lineY[ipos ] + cur_lineY[ipos_p1]) * COEF[2];
block[j][i] = iClip1(img->max_imgpel_value, ((result+16)>>5));
}
}
if ((dx&1) == 1)
{
for (j = 0; j < BLOCK_SIZE; j++)
{
cur_lineY = cur_imgY[iClip3(0,maxold_y,y_pos+j)];
block[j][0] = (block[j][0] + cur_lineY[iClip3(0,maxold_x,x_pos +(dx>>1))] + 1 )>>1;
block[j][1] = (block[j][1] + cur_lineY[iClip3(0,maxold_x,x_pos+1+(dx>>1))] + 1 )>>1;
block[j][2] = (block[j][2] + cur_lineY[iClip3(0,maxold_x,x_pos+2+(dx>>1))] + 1 )>>1;
block[j][3] = (block[j][3] + cur_lineY[iClip3(0,maxold_x,x_pos+3+(dx>>1))] + 1 )>>1;
}
}
}
else if (dx == 0)
{ /* No horizontal interpolation */
for (j = 0; j < BLOCK_SIZE; j++)
{
jpos_m2 = iClip3(0, maxold_y, y_pos + j - 2);
jpos_m1 = iClip3(0, maxold_y, y_pos + j - 1);
jpos = iClip3(0, maxold_y, y_pos + j );
jpos_p1 = iClip3(0, maxold_y, y_pos + j + 1);
jpos_p2 = iClip3(0, maxold_y, y_pos + j + 2);
jpos_p3 = iClip3(0, maxold_y, y_pos + j + 3);
for (i = 0; i < BLOCK_SIZE; i++)
{
pres_x = iClip3(0,maxold_x,x_pos+i);
result = (cur_imgY[jpos_m2][pres_x] + cur_imgY[jpos_p3][pres_x]) * COEF[0];
result += (cur_imgY[jpos_m1][pres_x] + cur_imgY[jpos_p2][pres_x]) * COEF[1];
result += (cur_imgY[jpos ][pres_x] + cur_imgY[jpos_p1][pres_x]) * COEF[2];
block[j][i] = iClip1(img->max_imgpel_value, ((result+16)>>5));
}
}
if ((dy&1) == 1)
{
for (j = 0; j < BLOCK_SIZE; j++)
{
cur_lineY = cur_imgY[iClip3(0,maxold_y,y_pos+j+(dy>>1))];
block[j][0] = (block[j][0] + cur_lineY[iClip3(0,maxold_x,x_pos )] + 1 )>>1;
block[j][1] = (block[j][1] + cur_lineY[iClip3(0,maxold_x,x_pos+1)] + 1 )>>1;
block[j][2] = (block[j][2] + cur_lineY[iClip3(0,maxold_x,x_pos+2)] + 1 )>>1;
block[j][3] = (block[j][3] + cur_lineY[iClip3(0,maxold_x,x_pos+3)] + 1 )>>1;
}
}
}
else if (dx == 2)
{ /* Vertical & horizontal interpolation */
for (i = 0; i < BLOCK_SIZE; i++)
{
ipos_m2 = iClip3(0, maxold_x, x_pos + i - 2);
ipos_m1 = iClip3(0, maxold_x, x_pos + i - 1);
ipos = iClip3(0, maxold_x, x_pos + i );
ipos_p1 = iClip3(0, maxold_x, x_pos + i + 1);
ipos_p2 = iClip3(0, maxold_x, x_pos + i + 2);
ipos_p3 = iClip3(0, maxold_x, x_pos + i + 3);
for (j = 0; j < BLOCK_SIZE + 5; j++)
{
cur_lineY = cur_imgY[iClip3(0,maxold_y,y_pos + j - 2)];
tmp_res[j][i] = (cur_lineY[ipos_m2] + cur_lineY[ipos_p3]) * COEF[0];
tmp_res[j][i] += (cur_lineY[ipos_m1] + cur_lineY[ipos_p2]) * COEF[1];
tmp_res[j][i] += (cur_lineY[ipos ] + cur_lineY[ipos_p1]) * COEF[2];
}
}
for (j = 0; j < BLOCK_SIZE; j++)
{
jpos_m2 = j ;
jpos_m1 = j + 1;
jpos = j + 2;
jpos_p1 = j + 3;
jpos_p2 = j + 4;
jpos_p3 = j + 5;
for (i = 0; i < BLOCK_SIZE; i++)
{
result = (tmp_res[jpos_m2][i] + tmp_res[jpos_p3][i]) * COEF[0];
result += (tmp_res[jpos_m1][i] + tmp_res[jpos_p2][i]) * COEF[1];
result += (tmp_res[jpos ][i] + tmp_res[jpos_p1][i]) * COEF[2];
block[j][i] = iClip1(img->max_imgpel_value, ((result+512)>>10));
}
}
if ((dy&1) == 1)
{
for (j = 0; j < BLOCK_SIZE; j++)
{
pres_y = j+2+(dy>>1);
block[j][0] = (block[j][0] + iClip1(img->max_imgpel_value, ((tmp_res[pres_y][0]+16)>>5)) +1 )>>1;
block[j][1] = (block[j][1] + iClip1(img->max_imgpel_value, ((tmp_res[pres_y][1]+16)>>5)) +1 )>>1;
block[j][2] = (block[j][2] + iClip1(img->max_imgpel_value, ((tmp_res[pres_y][2]+16)>>5)) +1 )>>1;
block[j][3] = (block[j][3] + iClip1(img->max_imgpel_value, ((tmp_res[pres_y][3]+16)>>5)) +1 )>>1;
}
}
}
else if (dy == 2)
{ /* Horizontal & vertical interpolation */
for (j = 0; j < BLOCK_SIZE; j++)
{
jpos_m2 = iClip3(0, maxold_y, y_pos + j - 2);
jpos_m1 = iClip3(0, maxold_y, y_pos + j - 1);
jpos = iClip3(0, maxold_y, y_pos + j );
jpos_p1 = iClip3(0, maxold_y, y_pos + j + 1);
jpos_p2 = iClip3(0, maxold_y, y_pos + j + 2);
jpos_p3 = iClip3(0, maxold_y, y_pos + j + 3);
for (i = 0; i < BLOCK_SIZE+5; i++)
{
pres_x = iClip3(0,maxold_x,x_pos+i - 2);
tmp_res[j][i] = (cur_imgY[jpos_m2][pres_x] + cur_imgY[jpos_p3][pres_x])*COEF[0];
tmp_res[j][i] += (cur_imgY[jpos_m1][pres_x] + cur_imgY[jpos_p2][pres_x])*COEF[1];
tmp_res[j][i] += (cur_imgY[jpos ][pres_x] + cur_imgY[jpos_p1][pres_x])*COEF[2];
}
}
for (j = 0; j < BLOCK_SIZE; j++)
{
for (i = 0; i < BLOCK_SIZE; i++)
{
result = (tmp_res[j][i ] + tmp_res[j][i + 5]) * COEF[0];
result += (tmp_res[j][i + 1] + tmp_res[j][i + 4]) * COEF[1];
result += (tmp_res[j][i + 2] + tmp_res[j][i + 3]) * COEF[2];
block[j][i] = iClip1(img->max_imgpel_value, ((result+512)>>10));
}
}
if ((dx&1) == 1)
{
for (j = 0; j < BLOCK_SIZE; j++)
{
block[j][0] = (block[j][0] + iClip1(img->max_imgpel_value, ((tmp_res[j][2+(dx>>1)]+16)>>5))+1)>>1;
block[j][1] = (block[j][1] + iClip1(img->max_imgpel_value, ((tmp_res[j][3+(dx>>1)]+16)>>5))+1)>>1;
block[j][2] = (block[j][2] + iClip1(img->max_imgpel_value, ((tmp_res[j][4+(dx>>1)]+16)>>5))+1)>>1;
block[j][3] = (block[j][3] + iClip1(img->max_imgpel_value, ((tmp_res[j][5+(dx>>1)]+16)>>5))+1)>>1;
}
}
}
else
{ /* Diagonal interpolation */
for (i = 0; i < BLOCK_SIZE; i++)
{
ipos_m2 = iClip3(0, maxold_x, x_pos + i - 2);
ipos_m1 = iClip3(0, maxold_x, x_pos + i - 1);
ipos = iClip3(0, maxold_x, x_pos + i );
ipos_p1 = iClip3(0, maxold_x, x_pos + i + 1);
ipos_p2 = iClip3(0, maxold_x, x_pos + i + 2);
ipos_p3 = iClip3(0, maxold_x, x_pos + i + 3);
for (j = 0; j < BLOCK_SIZE; j++)
{
cur_lineY = cur_imgY[iClip3(0,maxold_y,(dy == 1 ? y_pos+j : y_pos+j+1))];
result = (cur_lineY[ipos_m2] + cur_lineY[ipos_p3]) * COEF[0];
result += (cur_lineY[ipos_m1] + cur_lineY[ipos_p2]) * COEF[1];
result += (cur_lineY[ipos ] + cur_lineY[ipos_p1]) * COEF[2];
block[j][i] = iClip1(img->max_imgpel_value, ((result+16)>>5));
}
}
for (j = 0; j < BLOCK_SIZE; j++)
{
jpos_m2 = iClip3(0, maxold_y, y_pos + j - 2);
jpos_m1 = iClip3(0, maxold_y, y_pos + j - 1);
jpos = iClip3(0, maxold_y, y_pos + j );
jpos_p1 = iClip3(0, maxold_y, y_pos + j + 1);
jpos_p2 = iClip3(0, maxold_y, y_pos + j + 2);
jpos_p3 = iClip3(0, maxold_y, y_pos + j + 3);
for (i = 0; i < BLOCK_SIZE; i++)
{
pres_x = dx == 1 ? x_pos+i : x_pos+i+1;
pres_x = iClip3(0,maxold_x,pres_x);
result = (cur_imgY[jpos_m2][pres_x] + cur_imgY[jpos_p3][pres_x]) * COEF[0];
result += (cur_imgY[jpos_m1][pres_x] + cur_imgY[jpos_p2][pres_x]) * COEF[1];
result += (cur_imgY[jpos ][pres_x] + cur_imgY[jpos_p1][pres_x]) * COEF[2];
block[j][i] = (block[j][i] + iClip1(img->max_imgpel_value, ((result+16)>>5)) +1 ) >>1;
}
}
}
}
}
void reorder_lists(int currSliceType, Slice * currSlice)
{
if ((currSliceType != I_SLICE)&&(currSliceType != SI_SLICE))
{
if (currSlice->ref_pic_list_reordering_flag_l0)
{
reorder_ref_pic_list(listX[0], &listXsize[0],
img->num_ref_idx_l0_active - 1,
currSlice->reordering_of_pic_nums_idc_l0,
currSlice->abs_diff_pic_num_minus1_l0,
currSlice->long_term_pic_idx_l0);
}
if (no_reference_picture == listX[0][img->num_ref_idx_l0_active-1])
{
if (non_conforming_stream)
printf("RefPicList0[ num_ref_idx_l0_active_minus1 ] is equal to 'no reference picture'\n");
else
error("RefPicList0[ num_ref_idx_l0_active_minus1 ] is equal to 'no reference picture', invalid bitstream",500);
}
// that's a definition
listXsize[0] = img->num_ref_idx_l0_active;
}
if (currSliceType == B_SLICE)
{
if (currSlice->ref_pic_list_reordering_flag_l1)
{
reorder_ref_pic_list(listX[1], &listXsize[1],
img->num_ref_idx_l1_active - 1,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -