📄 image.c
字号:
}
}
if (input->last_frame && img->number + 1 == input->no_frames)
{
nextP_no = input->last_frame;
img->p_interval = nextP_no - prevP_no;
}
#endif
img->b_interval =
(int) ((float) (input->jumpd + 1) / (input->successive_Bframe + 1.0) +
0.49999);
img->tr = prevP_no + (img->b_interval + 1) * img->b_frame_to_code; // from prev_P
if (img->tr >= nextP_no)
img->tr = nextP_no - 1; // ?????
#ifdef _CHANGE_QP_
if (input->qp2start > 0 && img->tr >= input->qp2start)
img->qp = input->qpB2;
else
#endif
img->qp = input->qpB;
// initialize arrays
for (k = 0; k < 2; k++)
for (i = 0; i < img->height / BLOCK_SIZE; i++)
for (j = 0; j < img->width / BLOCK_SIZE + 4; j++)
{
tmp_fwMV[k][i][j] = 0;
tmp_bwMV[k][i][j] = 0;
dfMV[k][i][j] = 0;
dbMV[k][i][j] = 0;
}
for (i = 0; i < img->height / BLOCK_SIZE; i++)
for (j = 0; j < img->width / BLOCK_SIZE; j++)
{
fw_refFrArr[i][j] = bw_refFrArr[i][j] = -1;
}
}
input->jumpd /= 2;
input->successive_Bframe /= 2;
img->buf_cycle *= 2;
img->number = 2 * img->number + img->fld_type;
if (img->type == BS_IMG)
{
img->num_ref_pic_active_fwd_minus1 =
max (0, min (img->number - 1, img->buf_cycle + img->fld_type - 1));
img->num_ref_pic_active_bwd_minus1 =
max (0, min (img->number - 1, 3 + img->fld_type));
}
else if (img->type == B_IMG)
{
img->num_ref_pic_active_fwd_minus1 =
max (0, min (img->number - 1, img->buf_cycle - 1));
img->num_ref_pic_active_bwd_minus1 = 0;
}
else
{
img->num_ref_pic_active_fwd_minus1 =
max (0, min (img->number - 1, img->buf_cycle + img->fld_type - 1));
img->num_ref_pic_active_bwd_minus1 = 0;
}
img->total_number_mb = (img->width * img->height) / (MB_BLOCK_SIZE * MB_BLOCK_SIZE);
}
#define Clip(min,max,val) (((val)<(min))?(min):(((val)>(max))?(max):(val)))
/*!
************************************************************************
* \brief
* Estimates reference picture weighting factors
************************************************************************
*/
static void estimate_weighting_factor ()
{
int i, j, n;
int x,z;
int dc_org = 0;
int index;
int comp;
int p0, pt;
int fwd_ref[MAX_REFERENCE_PICTURES], bwd_ref[MAX_REFERENCE_PICTURES];
int bframe = (img->type == B_IMG) || (img->type == BS_IMG);
int num_ref = min (img->number-((mref==mref_fld)&&img->fld_type&&bframe), img->buf_cycle);
int dc_ref[MAX_REFERENCE_PICTURES];
int log_weight_denom;
int num_bwd_ref, num_fwd_ref;
pel_t** ref_pic;
pel_t* ref_pic_w;
int default_weight;
int default_weight_chroma;
luma_log_weight_denom = 5;
chroma_log_weight_denom = 5;
wp_luma_round = 1 << (luma_log_weight_denom - 1);
wp_chroma_round = 1 << (chroma_log_weight_denom - 1);
default_weight = 1<<luma_log_weight_denom;
default_weight_chroma = 1<<chroma_log_weight_denom;
/* set all values to defaults */
for (i = 0; i < 2; i++)
for (j = 0; j < MAX_REFERENCE_PICTURES; j++)
for (n = 0; n < 3; n++)
{
wp_weight[i][j][n] = default_weight;
wp_offset[i][j][n] = 0;
}
for (i = 0; i < img->height; i++)
for (j = 0; j < img->width; j++)
{
dc_org += imgY_org[i][j];
}
for (n = 0; n < num_ref; n++)
{
dc_ref[n] = 0;
ref_pic = img->type==B_IMG? Refbuf11 [n] : Refbuf11[n];
ref_pic_w = img->type==B_IMG? Refbuf11_w [n] : Refbuf11_w[n];
// Y
for (i = 0; i < img->height ; i++)
for (j = 0; j< img->width; j++)
{
dc_ref[n] += ref_pic[i][j];
}
if (dc_ref[n] != 0)
weight[n][0] =
(int) (default_weight * (double) dc_org / (double) dc_ref[n] + 0.5);
else
weight[n][0] = 2*default_weight; // only used when reference picture is black
printf("dc_org = %d, dc_ref = %d, weight[%d] = %d\n",dc_org, dc_ref[n],n,weight[n][0]);
/* for now always use default weight for chroma weight */
weight[n][1] = default_weight_chroma;
weight[n][2] = default_weight_chroma;
/* store weighted reference pic for motion estimation */
for (i = 0; i < img->height * img->width; i++)
{
ref_pic_w[i] =
Clip (0, 255, ((int) ref_pic[i] * weight[n][0] + wp_luma_round) / default_weight);
}
for (i = 0; i < 4*(img->height + 2*IMG_PAD_SIZE) ; i++)
{
for (j = 0; j< 4*(img->width + 2*IMG_PAD_SIZE); j++)
{
mref_w[n][i][j] = Clip (0, 255, ((int) mref[n][i][j] * weight[n][0] + wp_luma_round) / default_weight);
}
}
}
if (img->type == INTER_IMG)
{
num_bwd_ref = 0;
num_fwd_ref = num_ref;
}
else
{
num_bwd_ref = (img->type == BS_IMG) ? num_ref : 1;
num_fwd_ref = (img->type == BS_IMG) ? num_ref+1 : num_ref;
}
// printf("num_fwd_ref = %d num_bwd_ref = %d\n",num_fwd_ref,num_bwd_ref);
{ /* forward list */
if (img->type == INTER_IMG && input->WeightedPrediction)
{
for (index = 0; index < num_ref; index++)
{
wp_weight[0][index][0] = weight[index][0];
wp_weight[0][index][1] = weight[index][1];
wp_weight[0][index][2] = weight[index][2];
// printf ("wp weight[%d] = %d \n", index,
// wp_weight[0][index][0]);
}
}
else if (img->type == BS_IMG && (input->WeightedBiprediction == 1))
{
for (index = 0; index < num_ref; index++)
{
wp_weight[0][index][0] = weight[index][0];
wp_weight[0][index][1] = weight[index][1];
wp_weight[0][index][2] = weight[index][2];
}
for (index = 0; index < num_ref; index++)
{ /* backward list */
if (index == 0)
n = 1;
else if (index == 1)
n = 0;
else
n = index;
}
}
else if (img->type == B_IMG && (input->WeightedBiprediction == 1))
{
for (index = 0; index < num_ref - 1; index++)
{
wp_weight[0][index][0] = weight[index + 1][0];
wp_weight[0][index][1] = weight[index + 1][1];
wp_weight[0][index][2] = weight[index + 1][2];
}
wp_weight[1][0][0] = weight[0][0];
wp_weight[1][0][1] = weight[0][1];
wp_weight[1][0][2] = weight[0][2];
}
else
{
for (index = 0; index < num_ref; index++)
{
wp_weight[0][index][0] = 1<<luma_log_weight_denom;
wp_weight[0][index][1] = 1<<chroma_log_weight_denom;
wp_weight[0][index][2] = 1<<chroma_log_weight_denom;
wp_weight[1][index][0] = 1<<luma_log_weight_denom;
wp_weight[1][index][1] = 1<<chroma_log_weight_denom;
wp_weight[1][index][2] = 1<<chroma_log_weight_denom;
}
}
if (input->WeightedBiprediction > 0 && (img->type == B_IMG || img->type == BS_IMG))
{
if (img->type == BS_IMG )
{
for (index = 0; index < num_fwd_ref; index++)
{
fwd_ref[index] = index;
if (index == 0)
n = 1;
else if (index == 1)
n = 0;
else
n = index;
bwd_ref[index] = n;
}
}
else if (img->type == B_IMG)
{
for (index = 0; index < num_fwd_ref; index++)
{
fwd_ref[index] = index+1;
}
bwd_ref[0] = 0; // only one possible backwards ref for traditional B picture in current software
}
}
if (img->type == B_IMG || img->type == BS_IMG) // need to fill in wbp_weight values
{
for (i = 0; i < num_fwd_ref; i++)
{
for (j = 0; j < num_bwd_ref; j++)
{
for (comp = 0; comp < 3; comp++)
{
log_weight_denom = (comp == 0) ? luma_log_weight_denom : chroma_log_weight_denom;
if (input->WeightedBiprediction == 1)
{
wbp_weight[0][i][j][comp] = wp_weight[0][i][comp];
wbp_weight[1][i][j][comp] = wp_weight[1][j][comp];
}
else if (input->WeightedBiprediction == 2)
{ // implicit mode
pt = poc_distance (fwd_ref[i], bwd_ref[j]);
p0 = poc_distance (fwd_ref[i], -1);
if (pt == 0)
{
wbp_weight[1][i][j][comp] = 32 ;
wbp_weight[0][i][j][comp] = 32;
}
else
{
x = (16384 + (pt>>1))/pt;
z = Clip(-1024, 1023, (x*p0 + 32 )>>6);
wbp_weight[1][i][j][comp] = z>>2;
if (wbp_weight[1][i][j][comp] < -64 || wbp_weight[1][i][j][comp] >128)
wbp_weight[1][i][j][comp] = 32;
wbp_weight[0][i][j][comp] = 64 - wbp_weight[1][i][j][comp];
}
// if (comp == 0 )
// printf ("bpw weight[%d][%d] = %d , %d \n", i, j,
// wbp_weight[0][i][j][0], wbp_weight[1][i][j][0]);
}
}
}
}
}
}
}
/*!
************************************************************************
* \brief
* Writes reconstructed image(s) to file
* This can be done more elegant!
************************************************************************
*/
static void write_reconstructed_image ()
{
int i, j, k;
int start = 0, inc = 1;
if (p_dec != NULL)
{
if (img->type != B_IMG)
{
// write reconstructed image (IPPP)
if (input->successive_Bframe == 0)
{
for (i = start; i < img->height; i += inc)
for (j = 0; j < img->width; j++)
fputc (imgY[i][j], p_dec);
for (k = 0; k < 2; ++k)
for (i = start; i < img->height / 2; i += inc)
for (j = 0; j < img->width / 2; j++)
fputc (imgUV[k][i][j], p_dec);
}
// write reconstructed image (IBPBP) : only intra written
else if (IMG_NUMBER == 0 && input->successive_Bframe != 0)
{
for (i = start; i < img->height; i += inc)
for (j = 0; j < img->width; j++)
fputc (imgY[i][j], p_dec);
for (k = 0; k < 2; ++k)
for (i = start; i < img->height / 2; i += inc)
for (j = 0; j < img->width / 2; j++)
fputc (imgUV[k][i][j], p_dec);
}
// next P picture. This is saved with recon B picture after B picture coding
if (IMG_NUMBER != 0 && input->successive_Bframe != 0)
{
for (i = start; i < img->height; i += inc)
for (j = 0; j < img->width; j++)
nextP_imgY[i][j] = imgY[i][j];
for (k = 0; k < 2; ++k)
for (i = start; i < img->height / 2; i += inc)
for (j = 0; j < img->width / 2; j++)
nextP_imgUV[k][i][j] = imgUV[k][i][j];
}
}
else
{
for (i = start; i < img->height; i += inc)
for (j = 0; j < img->width; j++)
fputc (imgY[i][j], p_dec);
for (k = 0; k < 2; ++k)
for (i = start; i < img->height / 2; i += inc)
for (j = 0; j < img->width / 2; j++)
fputc (imgUV[k][i][j], p_dec);
// If this is last B frame also store P frame
if (img->b_frame_to_code == input->successive_Bframe)
{
// save P picture
for (i = start; i < img->height; i += inc)
for (j = 0; j < img->width; j++)
fputc (nextP_imgY[i][j], p_dec);
for (k = 0; k < 2; ++k)
for (i = start; i < img->height / 2; i += inc)
for (j = 0; j < img->width / 2; j++)
fputc (nextP_imgUV[k][i][j], p_dec);
}
}
}
}
/*!
************************************************************************
* \brief
* Choose interpolation method depending on MV-resolution
************************************************************************
*/
static void interpolate_frame_to_fb ()
{ // write to mref[]
add_frame (img);
init_mref ();
init_Refbuf (img);
UnifiedOneForthPix (imgY, imgUV[0], imgUV[1], mref[0], mcef[0][0], mcef[0][1], Refbuf11[0]);
}
/*!
************************************************************************
* \brief
* Choose interpolation method depending on MV-resolution
************************************************************************
*/
static void interpolate_frame ()
{ // write to mref[]
init_mref ();
init_Refbuf (img);
UnifiedOneForthPix (imgY, imgUV[0], imgUV[1],
mref[0], mcef[0][0], mcef[0][1], Refbuf11[0]);
}
static void GenerateFullPelRepresentation (pel_t ** Fourthpel,
pel_t * Fullpel, int xsize,
int ysize)
{
int x, y;
for (y = 0; y < ysize; y++)
for (x = 0; x < xsize; x++)
PutPel_11 (Fullpel, y, x, FastPelY_14 (Fourthpel, y * 4, x * 4));
}
//zdd new version
static void calcabc(byte *pt1,_int16*pt2,_int16*pt3,_int16*pt4,_int16*pt5)
{
static _int64 zero=0;
static _int64 f16=0x0010001000100010;
static _int64 f1=0x0001000100010001;
int imgw=img->width+32;
_asm
{
mov eax,pt1
mov ebx,pt2
mov ecx,pt3
mov edx,pt4
mov edi,pt5
//计算第一列
pxor mm6,mm6
movq mm0,[eax]
PUNPCKLBW mm0,mm6
add eax,imgw
movq mm1,[eax]
PUNPCKLBW mm1,mm6
add eax,imgw
movq mm2,[eax]
PUNPCKLBW mm2,mm6
add eax,imgw
movq mm3,[eax]
PUNPCKLBW mm3,mm6
//转秩
movq mm4,mm0
movq mm5,mm1
movq mm6,mm2
PUNPCKLWD mm0,mm1
PUNPCKLWD mm2,mm3
movq mm1,mm0
PUNPCKLDQ mm0,mm2
PUNPCKHDQ mm1,mm2
PUNPCKHWD mm4,mm5
PUNPCKHWD mm6,mm3
movq mm3,mm4
PUNPCKLDQ mm4,mm6
PUNPCKHDQ mm3,mm6
movq mm2,mm4
movq mm6,mm1
PSLLW mm6,2
paddw mm6,mm1
psubw mm0,mm6
movq mm6,mm2
movq mm7,mm2
PSLLW mm6,4
PSLLW mm7,2
paddw mm6,mm7
paddw mm0,mm6
movq mm6,mm3
movq mm7,mm3
PSLLW mm6,4
PSLLW mm7,2
paddw mm6,mm7
paddw mm0,mm6
//再读入两列
mov eax,pt1
add eax,4
pxor mm7,mm7
movd mm4,[eax]
PUNPCKLBW mm4,mm7
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -