📄 image.c
字号:
/*
*****************************************************************************
* COPYRIGHT AND WARRANTY INFORMATION
*
* Copyright 2003, Advanced Audio Video Coding Standard, Part II
*
* DISCLAIMER OF WARRANTY
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations under
* the License.
*
* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE AVS PATENT POLICY.
* The AVS Working Group doesn't represent or warrant that the programs
* furnished here under are free of infringement of any third-party patents.
* Commercial implementations of AVS, including shareware, may be
* subject to royalty fees to patent holders. Information regarding
* the AVS patent policy for standardization procedure is available at
* AVS Web site http://www.avs.org.cn. Patent Licensing is outside
* of AVS Working Group.
*
* The Original Code is Reference Software for China National Standard
* GB/T 20090.2-2006 (short for AVS-P2 or AVS Video) at version RM52J.
*
* The Initial Developer of the Original Code is Video subgroup of AVS
* Workinggroup (Audio and Video coding Standard Working Group of China).
* Contributors: Guoping Li, Siwei Ma, Jian Lou, Qiang Wang ,
* Jianwen Chen,Haiwu Zhao, Xiaozhen Zheng, Junhao Zheng, Zhiming Wang
*
******************************************************************************
*/
/*
*************************************************************************************
* File name: image.c
* Function: Decode a Slice
*
*************************************************************************************
*/
#include "contributors.h"
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <sys/timeb.h>
#include <string.h>
#include <assert.h>
#include "global.h"
#include "mbuffer.h"
#include "header.h"
#include "annexb.h"
#include "vlc.h"
#include "memalloc.h"
static void rotate_buffer ();
void store_field_MV(struct img_par *img);
void copy2buffer(struct img_par *img, struct inp_par *inp,int bot);
void replace2buffer(struct img_par *img, struct inp_par *inp,int bot);
extern struct img_par *erc_img;
int *last_P_no;
int *last_P_no_frm;
/*
*************************************************************************
* Function:decodes one I- or P-frame
* Input:
* Output:
* Return:
* Attention:
*************************************************************************
*/
int decode_one_frame(struct img_par *img,struct inp_par *inp, struct snr_par *snr)
{
int current_header;
time_t ltime1; // for time measurement
time_t ltime2;
#ifdef WIN32
struct _timeb tstruct1;
struct _timeb tstruct2;
#else
struct timeb tstruct1;
struct timeb tstruct2;
#endif
int tmp_time; // time used by decoding the last frame
int i;
#ifdef WIN32
_ftime (&tstruct1); // start time ms
#else
ftime (&tstruct1); // start time ms
#endif
time( <ime1 ); // start time s
singlefactor =(float)((Bframe_ctr & 0x01) ? 0.5 : 2);
if(!img->picture_structure)
singlefactor = 1;
img->current_mb_nr = -4711; // initialized to an impossible value for debugging -- correct value is taken from slice header
second_IField=0; //cjw 20051230
//u_v(8, "stuffying bits"); //added by cjw AVS Zhuhai 20070122 //deleted by cjw AVS 20070204
current_header = Header();
if (current_header == EOS)
return EOS;
img->current_mb_nr = 0;
init_frame(img, inp);
if (img->picture_structure)
{
img->types = img->type; // jlzheng 7.15
if(img->type!=B_IMG){ //HiSilicon, 2007.03.21
pre_img_type = img->type;
pre_img_types = img->types;
}
picture_data(img, inp);
if (img->type != B_IMG&&!progressive_sequence)
{
img->height >>= 1;
img->height_cr >>= 1;
init_top_buffer();
split_field_top();
Update_Picture_top_field();
init_bot_buffer();
split_field_bot();
Update_Picture_bot_field();
img->height <<= 1;
img->height_cr <<= 1;
}
imgY = imgY_frm;
imgUV = imgUV_frm;
}
else
{
img->height = vertical_size/2;
img->height_cr = (img->height>>1);
img->PicWidthInMbs = img->width/MB_BLOCK_SIZE;
img->PicHeightInMbs = img->height/MB_BLOCK_SIZE;
img->PicSizeInMbs = img->PicWidthInMbs * img->PicHeightInMbs;
img->types = img->type;
if(img->type!=B_IMG){ //HiSilicon, 2007.03.21
pre_img_type = img->type;
pre_img_types = img->types;
}
init_top(img,inp);
top_field(img,inp);
if(img->type!=B_IMG)
{
Update_Picture_top_field();
}
else
{
for (i=0; i<img->height; i++)
{
memcpy(imgY_frm[i*2], imgY_top[i], img->width); // top field
}
for (i=0; i<img->height_cr; i++)
{
memcpy(imgUV_frm[0][i*2], imgUV_top[0][i], img->width_cr);
memcpy(imgUV_frm[1][i*2], imgUV_top[1][i], img->width_cr);
}
}
/* Commented by Xiaozhen Zheng, HiSilicon, 20070327
if(img->type == I_IMG)
{
img->type = P_IMG;
pre_img_type = P_IMG; //HiSilicon, 2007.03.21
second_IField=1; //cjw 20051230
}
*/
init_bot(img,inp);
bot_field(img,inp);
if(img->type!=B_IMG)
{
Update_Picture_bot_field();
}
else
{
for (i=0; i<img->height; i++)
{
memcpy(imgY_frm[i*2 + 1], imgY_bot[i], img->width); // bottom field
}
for (i=0; i<img->height_cr; i++)
{
memcpy(imgUV_frm[0][i*2 + 1], imgUV_bot[0][i], img->width_cr);
memcpy(imgUV_frm[1][i*2 + 1], imgUV_bot[1][i], img->width_cr);
}
}
init_frame_buffer();
if(img->type!=B_IMG)
combine_field(img);
imgY = imgY_frm;
imgUV = imgUV_frm;
}
img->height = vertical_size;
img->height_cr = vertical_size/2;
img->PicWidthInMbs = img->width/MB_BLOCK_SIZE;
img->PicHeightInMbs = img->height/MB_BLOCK_SIZE;
img->PicSizeInMbs = img->PicWidthInMbs * img->PicHeightInMbs;
if(!progressive_sequence)
{
store_field_MV(img);
}
frame_postprocessing(img);
/* //commented by Zheng Xiaozhen, HiSilicon, 2007.03.21
if (p_ref)
find_snr(snr,img,p_ref); // if ref sequence exist
*/
//added by Zheng Xiaozhen, HiSilicon, 2007.03.21
if (img->type==B_IMG) {
if (p_ref)
find_snr(snr,img,p_ref); // if ref sequence exist
}
#ifdef WIN32
_ftime (&tstruct2); // end time ms
#else
ftime (&tstruct2); // end time ms
#endif
time( <ime2 ); // end time sec
tmp_time=(ltime2*1000+tstruct2.millitm) - (ltime1*1000+tstruct1.millitm);
tot_time=tot_time + tmp_time;
//added by Zheng Xiaozhen, HiSilicon, 2007.03.21
if (img->type!=B_IMG) {
pre_tmp_time = tmp_time;
pre_img_tr = img->tr;
pre_img_qp = img->qp;
}
/* commented by Zheng Xiaozhe, HiSilicon, 2007.03.21
if (vec_pr_flag) {
sprintf(str_vec, "v%d ", vec_ext);
} else {
sprintf(str_vec, " ");
}
if(img->type == I_IMG) // I picture
fprintf(stdout,"%s%3d(I) %3d %5d %7.4f %7.4f %7.4f %5d\n",
str_vec, frame_no, img->tr, img->qp,snr->snr_y,snr->snr_u,snr->snr_v,tmp_time);
else if(img->type == P_IMG) // P pictures
{
//if(frame_no == 0)
if (img->types == I_IMG)
fprintf(stdout,"%s%3d(I) %3d %5d %7.4f %7.4f %7.4f %5d\n",
str_vec, frame_no, img->tr, img->qp,snr->snr_y,snr->snr_u,snr->snr_v,tmp_time); //jlzheng 7.3
else
fprintf(stdout,"%s%3d(P) %3d %5d %7.4f %7.4f %7.4f %5d\n",
str_vec, frame_no, img->tr, img->qp,snr->snr_y,snr->snr_u,snr->snr_v,tmp_time);
}
else // B pictures
fprintf(stdout,"%s%3d(B) %3d %5d %7.4f %7.4f %7.4f %5d\n",
str_vec, frame_no, img->tr, img->qp,snr->snr_y,snr->snr_u,snr->snr_v,tmp_time);
*/
if(img->type==B_IMG)
fprintf(stdout,"%3d(B) %3d %5d %7.4f %7.4f %7.4f %5d\n",
FrameNum, img->tr, img->qp,snr->snr_y,snr->snr_u,snr->snr_v,tmp_time);
fflush(stdout);
if(img->type==B_IMG) //added by Xiaozhen Zheng, Hisilicon, 20070327
report_frame(snr,tmp_time);
if(img->type == I_IMG || img->type == P_IMG) // I or P pictures
{
copy_Pframe(img); // imgY-->imgY_prev, imgUV-->imgUV_prev
Update_Picture_Buffers();
}
else // B pictures
write_frame(img,p_out); // write image to output YUV file
//! TO 19.11.2001 Known Problem: for init_frame we have to know the picture type of the actual frame
//! in case the first slice of the P-Frame following the I-Frame was lost we decode this P-Frame but//! do not write it because it was assumed to be an I-Frame in init_frame.So we force the decoder to
//! guess the right picture type. This is a hack a should be removed by the time there is a clean
//! solution where we do not have to know the picture type for the function init_frame.
//! End TO 19.11.2001//Lou
if(img->type == I_IMG || img->type == P_IMG) // I or P pictures
img->number++;
else
Bframe_ctr++; // B pictures
return (SOP);
}
/*
*************************************************************************
* Function:
* Input:
* Output:
* Return:
* Attention:
*************************************************************************
*/
void report_frame(struct snr_par *snr,int tmp_time)
{
FILE *file;
file = fopen("stat.dat","at");
if(img->type == I_IMG) // I picture
fprintf(file,"%3d(I) %3d %5d %7.4f %7.4f %7.4f %5d\n",
FrameNum, pre_img_tr, pre_img_qp,snr->snr_y,snr->snr_u,snr->snr_v,pre_tmp_time);
/* Commented by HiSilicon, 2007.03.21
fprintf(file,"%3d(I) %3d %5d %7.4f %7.4f %7.4f %5d\n",
frame_no, img->tr, img->qp,snr->snr_y,snr->snr_u,snr->snr_v,tmp_time);*/
else if(img->type == P_IMG) // P pictures
fprintf(file,"%3d(P) %3d %5d %7.4f %7.4f %7.4f %5d\n",
FrameNum, pre_img_tr, pre_img_qp,snr->snr_y,snr->snr_u,snr->snr_v,pre_tmp_time);
/* Commented by HiSilicon, 2007.03.21
fprintf(file,"%3d(P) %3d %5d %7.4f %7.4f %7.4f %5d\n",
frame_no, img->tr, img->qp,snr->snr_y,snr->snr_u,snr->snr_v,tmp_time);*/
else // B pictures
fprintf(file,"%3d(B) %3d %5d %7.4f %7.4f %7.4f %5d\n",
FrameNum, img->tr, img->qp,snr->snr_y,snr->snr_u,snr->snr_v,tmp_time);
/* Commented by HiSilicon, 2007.03.21
fprintf(file,"%3d(B) %3d %5d %7.4f %7.4f %7.4f %5d\n",
frame_no, img->tr, img->qp,snr->snr_y,snr->snr_u,snr->snr_v,tmp_time);
*/
FrameNum++; //HiSilicon
fclose(file);
}
/*
*************************************************************************
* Function:Find PSNR for all three components.Compare decoded frame with
the original sequence. Read inp->jumpd frames to reflect frame skipping.
* Input:
* Output:
* Return:
* Attention:
*************************************************************************
*/
void find_snr(
struct snr_par *snr, //!< pointer to snr parameters
struct img_par *img, //!< pointer to image parameters
FILE *p_ref) //!< filestream to reference YUV file
{
int i,j;
int diff_y,diff_u,diff_v;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -