📄 image.c
字号:
if (diff_u == 0)
diff_u = 1;
if (diff_v == 0)
diff_v = 1; */
// Collecting SNR statistics
if (diff_y != 0)
snr->snr_y=(float)(10*log10(65025*(float)(img->width)*(img->height)/(float)diff_y)); // luma snr for current frame
else
snr->snr_y=0;
if (diff_u != 0)
snr->snr_u=(float)(10*log10(65025*(float)(img->width)*(img->height)/(float)(4*diff_u))); // chroma snr for current frame
else
snr->snr_u=0;
if (diff_v != 0)
snr->snr_v=(float)(10*log10(65025*(float)(img->width)*(img->height)/(float)(4*diff_v))); // chroma snr for current frame
else
snr->snr_v=0;
if (img->number == 0) // first
{
snr->snr_y1=(float)(10*log10(65025*(float)(img->width)*(img->height)/(float)diff_y)); // keep luma snr for first frame
snr->snr_u1=(float)(10*log10(65025*(float)(img->width)*(img->height)/(float)(4*diff_u))); // keep chroma snr for first frame
snr->snr_v1=(float)(10*log10(65025*(float)(img->width)*(img->height)/(float)(4*diff_v))); // keep chroma snr for first frame
snr->snr_ya=snr->snr_y1;
snr->snr_ua=snr->snr_u1;
snr->snr_va=snr->snr_v1;
if (diff_y == 0)
snr->snr_ya=50; // need to assign a reasonable large number so avg snr of entire sequece isn't infinite
if (diff_u == 0)
snr->snr_ua=50;
if (diff_v == 0)
snr->snr_va=50;
}
/* else
{
snr->snr_ya=(float)(snr->snr_ya*(img->number+Bframe_ctr)+snr->snr_y)/(img->number+Bframe_ctr+1); // average snr chroma for all frames
snr->snr_ua=(float)(snr->snr_ua*(img->number+Bframe_ctr)+snr->snr_u)/(img->number+Bframe_ctr+1); // average snr luma for all frames
snr->snr_va=(float)(snr->snr_va*(img->number+Bframe_ctr)+snr->snr_v)/(img->number+Bframe_ctr+1); // average snr luma for all frames
} */
else
{
snr->snr_ya=(float)(snr->snr_ya*(img->number - 1 + Bframe_ctr)+snr->snr_y)/(img->number+Bframe_ctr); // average snr luma for all frames
snr->snr_ua=(float)(snr->snr_ua*(img->number - 1 + Bframe_ctr)+snr->snr_u)/(img->number+Bframe_ctr); // average snr chroma for all frames
snr->snr_va=(float)(snr->snr_va*(img->number - 1 + Bframe_ctr)+snr->snr_v)/(img->number+Bframe_ctr); // average snr chromafor all frames
}
}
/*!
************************************************************************
* \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[BLOCK_SIZE][BLOCK_SIZE])
{
int dx, dy;
int x, y;
int i, j;
int maxold_x,maxold_y;
int result;
int pres_x;
int pres_y;
int tmp_res[4][9];
static const int COEF[6] = {
1, -5, 20, 20, -5, 1
};
dx = x_pos&3;
dy = y_pos&3;
x_pos = (x_pos-dx)/4;
y_pos = (y_pos-dy)/4;
maxold_x = img->width-1;
maxold_y = img->height-1;
if (dec_picture->mb_field[img->current_mb_nr])
maxold_y = img->height/2 - 1;
if (dx == 0 && dy == 0) { /* fullpel position */
for (j = 0; j < BLOCK_SIZE; j++)
for (i = 0; i < BLOCK_SIZE; i++)
block[i][j] = list[ref_frame]->imgY[max(0,min(maxold_y,y_pos+j))][max(0,min(maxold_x,x_pos+i))];
}
else { /* other positions */
if (dy == 0) { /* No vertical interpolation */
for (j = 0; j < BLOCK_SIZE; j++) {
for (i = 0; i < BLOCK_SIZE; i++) {
for (result = 0, x = -2; x < 4; x++)
result += list[ref_frame]->imgY[max(0,min(maxold_y,y_pos+j))][max(0,min(maxold_x,x_pos+i+x))]*COEF[x+2];
block[i][j] = max(0, min(255, (result+16)/32));
}
}
if ((dx&1) == 1) {
for (j = 0; j < BLOCK_SIZE; j++)
for (i = 0; i < BLOCK_SIZE; i++)
block[i][j] = (block[i][j] + list[ref_frame]->imgY[max(0,min(maxold_y,y_pos+j))][max(0,min(maxold_x,x_pos+i+dx/2))] +1 )/2;
}
}
else if (dx == 0) { /* No horizontal interpolation */
for (j = 0; j < BLOCK_SIZE; j++) {
for (i = 0; i < BLOCK_SIZE; i++) {
for (result = 0, y = -2; y < 4; y++)
result += list[ref_frame]->imgY[max(0,min(maxold_y,y_pos+j+y))][max(0,min(maxold_x,x_pos+i))]*COEF[y+2];
block[i][j] = max(0, min(255, (result+16)/32));
}
}
if ((dy&1) == 1) {
for (j = 0; j < BLOCK_SIZE; j++)
for (i = 0; i < BLOCK_SIZE; i++)
block[i][j] = (block[i][j] + list[ref_frame]->imgY[max(0,min(maxold_y,y_pos+j+dy/2))][max(0,min(maxold_x,x_pos+i))] +1 )/2;
}
}
else if (dx == 2) { /* Vertical & horizontal interpolation */
for (j = -2; j < BLOCK_SIZE+3; j++) {
for (i = 0; i < BLOCK_SIZE; i++)
for (tmp_res[i][j+2] = 0, x = -2; x < 4; x++)
tmp_res[i][j+2] += list[ref_frame]->imgY[max(0,min(maxold_y,y_pos+j))][max(0,min(maxold_x,x_pos+i+x))]*COEF[x+2];
}
for (j = 0; j < BLOCK_SIZE; j++) {
for (i = 0; i < BLOCK_SIZE; i++) {
for (result = 0, y = -2; y < 4; y++)
result += tmp_res[i][j+y+2]*COEF[y+2];
block[i][j] = max(0, min(255, (result+512)/1024));
}
}
if ((dy&1) == 1) {
for (j = 0; j < BLOCK_SIZE; j++)
for (i = 0; i < BLOCK_SIZE; i++)
block[i][j] = (block[i][j] + max(0, min(255, (tmp_res[i][j+2+dy/2]+16)/32)) +1 )/2;
}
}
else if (dy == 2) { /* Horizontal & vertical interpolation */
for (j = 0; j < BLOCK_SIZE; j++) {
for (i = -2; i < BLOCK_SIZE+3; i++)
for (tmp_res[j][i+2] = 0, y = -2; y < 4; y++)
tmp_res[j][i+2] += list[ref_frame]->imgY[max(0,min(maxold_y,y_pos+j+y))][max(0,min(maxold_x,x_pos+i))]*COEF[y+2];
}
for (j = 0; j < BLOCK_SIZE; j++) {
for (i = 0; i < BLOCK_SIZE; i++) {
for (result = 0, x = -2; x < 4; x++)
result += tmp_res[j][i+x+2]*COEF[x+2];
block[i][j] = max(0, min(255, (result+512)/1024));
}
}
if ((dx&1) == 1) {
for (j = 0; j < BLOCK_SIZE; j++)
for (i = 0; i < BLOCK_SIZE; i++)
block[i][j] = (block[i][j] + max(0, min(255, (tmp_res[j][i+2+dx/2]+16)/32))+1)/2;
}
}
else { /* Diagonal interpolation */
for (j = 0; j < BLOCK_SIZE; j++) {
for (i = 0; i < BLOCK_SIZE; i++) {
pres_y = dy == 1 ? y_pos+j : y_pos+j+1;
pres_y = max(0,min(maxold_y,pres_y));
for (result = 0, x = -2; x < 4; x++)
result += list[ref_frame]->imgY[pres_y][max(0,min(maxold_x,x_pos+i+x))]*COEF[x+2];
block[i][j] = max(0, min(255, (result+16)/32));
}
}
for (j = 0; j < BLOCK_SIZE; j++) {
for (i = 0; i < BLOCK_SIZE; i++) {
pres_x = dx == 1 ? x_pos+i : x_pos+i+1;
pres_x = max(0,min(maxold_x,pres_x));
for (result = 0, y = -2; y < 4; y++)
result += list[ref_frame]->imgY[max(0,min(maxold_y,y_pos+j+y))][pres_x]*COEF[y+2];
block[i][j] = (block[i][j] + max(0, min(255, (result+16)/32)) +1 ) / 2;
}
}
}
}
}
static 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->remapping_of_pic_nums_idc_l0,
currSlice->abs_diff_pic_num_minus1_l0,
currSlice->long_term_pic_idx_l0);
}
}
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,
currSlice->remapping_of_pic_nums_idc_l1,
currSlice->abs_diff_pic_num_minus1_l1,
currSlice->long_term_pic_idx_l1);
}
}
free_ref_pic_list_reordering_buffer(currSlice);
}
/*!
************************************************************************
* \brief
* Reads new slice from bit_stream
************************************************************************
*/
int read_new_slice()
{
NALU_t *nalu = AllocNALU(MAX_CODED_FRAME_SIZE);
int current_header;
int ret;
int BitsUsedByHeader;
Slice *currSlice = img->currentSlice;
Bitstream *currStream;
int newframe;
int slice_id_a, slice_id_b, slice_id_c;
int redundant_pic_cnt_a, redundant_pic_cnt_b, redundant_pic_cnt_c;
long ftell_position, expected_slice_type;
// int i;
expected_slice_type = NALU_TYPE_DPA;
while (1)
{
ftell_position = ftell(bits);
if (input->FileFormat == PAR_OF_ANNEXB)
ret=GetAnnexbNALU (nalu);
else
ret=GetRTPNALU (nalu);
NALUtoRBSP(nalu);
// printf ("nalu->len %d\n", nalu->len);
if (ret < 0)
printf ("Error while getting the NALU in file format %s, exit\n", input->FileFormat==PAR_OF_ANNEXB?"Annex B":"RTP");
if (ret == 0)
{
// printf ("read_new_slice: returning %s\n", "EOS");
if(expected_slice_type != NALU_TYPE_DPA)
{
/* oops... we found the next slice, go back! */
fseek(bits, ftell_position, SEEK_SET);
FreeNALU(nalu);
return current_header;
}
else
return EOS;
}
// Got a NALU
if (nalu->forbidden_bit)
{
printf ("Found NALU w/ forbidden_bit set, bit error? Let's try...\n");
}
switch (nalu->nal_unit_type)
{
case NALU_TYPE_SLICE:
case NALU_TYPE_IDR:
img->idr_flag = (nalu->nal_unit_type == NALU_TYPE_IDR);
img->nal_reference_idc = nalu->nal_reference_idc;
img->disposable_flag = (nalu->nal_reference_idc == NALU_PRIORITY_DISPOSABLE);
currSlice->dp_mode = PAR_DP_1;
currSlice->max_part_nr = 1;
currSlice->ei_flag = 0;
currStream = currSlice->partArr[0].bitstream;
currStream->ei_flag = 0;
currStream->frame_bitoffset = currStream->read_len = 0;
memcpy (currStream->streamBuffer, &nalu->buf[1], nalu->len-1);
currStream->code_len = currStream->bitstream_length = RBSPtoSODB(currStream->streamBuffer, nalu->len-1);
// Some syntax of the Slice Header depends on the parameter set, which depends on
// the parameter set ID of the SLice header. Hence, read the pic_parameter_set_id
// of the slice header first, then setup the active parameter sets, and then read
// the rest of the slice header
BitsUsedByHeader = FirstPartOfSliceHeader();
UseParameterSet (currSlice->pic_parameter_set_id);
BitsUsedByHeader+= RestOfSliceHeader ();
FmoInit (active_pps, active_sps);
init_lists(img->type, img->currentSlice->structure);
reorder_lists (img->type, img->currentSlice);
/* if (img->frame_num==1) // write a reference list
{
count ++;
if (count==1)
for (i=0; i<listXsize[0]; i++)
write_picture(listX[0][i], p_out2);
}
*/
if (img->MbaffFrameFlag)
{
init_mbaff_lists();
}
if (img->currentSlice->structure!=0)
{
img->height /=2 ;
img->height_cr /=2;
}
// From here on, active_sps, active_pps and the slice header are valid
img->current_mb_nr = currSlice->start_mb_nr;
if (img->tr_old != img->ThisPOC)
{
newframe=1;
img->tr_old = img->ThisPOC;
}
else
newframe = 0;
if (newframe)
current_header = SOP;
else
current_header = SOS;
if(img->structure != img->structure_old)
newframe |= 1;
img->structure_old = img->structure;
//! new stuff StW
if(newframe || g_new_frame)
{
current_header = SOP;
g_new_frame=0;
}
else
current_header = SOS;
if (active_pps->entropy_coding_mode_flag)
{
int ByteStartPosition = currStream->frame_bitoffset/8;
if (currStream->frame_bitoffset%8 != 0)
{
ByteStartPosition++;
}
arideco_start_decoding (&currSlice->partArr[0].de_cabac, currStream->streamBuffer, ByteStartPosition, &currStream->read_len, img->type);
}
// printf ("read_new_slice: returning %s\n", current_header == SOP?"SOP":"SOS");
FreeNALU(nalu);
return current_header;
break;
case NALU_TYPE_DPA:
//! The state machine here should follow the same ideas as the old readSliceRTP()
//! basically:
//! work on DPA (as above)
//! read and process all following SEI/SPS/PPS/PD/Filler NALUs
//! if next video NALU is dpB,
//! then read and check whether it belongs to DPA, if yes, use it
//! else
//! ; // nothing
//! read and process all following SEI/SPS/PPS/PD/Filler NALUs
//! if next video NALU is dpC
//! then read and check whether it belongs to DPA (and DPB, if present), if yes, use it, done
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -