⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 image.c

📁 Mobile IP VCEG的信道模拟程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/*!
 *	\file
 *			Image.c
 *	\brief
 *			Decode a Slice
 *
 *	\author
 *			Main contributors (see contributors.h for copyright, address and affiliation details)
 *
 *			Inge Lille-Lang鴜               <inge.lille-langoy@telenor.com>
 *			Rickard Sjoberg                 <rickard.sjoberg@era.ericsson.se>
 *			Jani Lainema                    <jani.lainema@nokia.com>
 *			Sebastian Purreiter             <sebastian.purreiter@mch.siemens.de>
 *			Byeong-Moon Jeon                <jeonbm@lge.com>
 *			Thomas Wedi                     <wedi@tnt.uni-hannover.de>
 *      Gabi Blaettermann               <blaetter@hhi.de>
 */

#include "contributors.h"

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/timeb.h>
#include <string.h>


#include "global.h"
#include "elements.h"
#include "image.h"


#ifdef _ADAPT_LAST_GROUP_
int *last_P_no;
#endif



/************************************************************************
*
*  Name :       decode_one_frame()
*
*  Description: decodes one I- or P-frame
*
************************************************************************/

int decode_one_frame(struct img_par *img,struct inp_par *inp, struct snr_par *snr)
{
    
    int current_header;
    Slice *currSlice = img->currentSlice;

    time_t ltime1;                  /* for time measurement */
	time_t ltime2;

#ifdef WIN32
	struct _timeb tstruct1;
	struct _timeb tstruct2;
#else
	//	struct tm *l_time;
	struct timeb tstruct1;
	struct timeb tstruct2;
	//	time_t now;
#endif

    int tmp_time;                   /* time used by decoding the last frame */

#ifdef WIN32
	_ftime (&tstruct1);				/* start time ms */
#else
	ftime (&tstruct1);				/* start time ms */
#endif
	time( &ltime1 );                /* start time s  */

    currSlice->next_header = 0;
    while (currSlice->next_header != EOS && currSlice->next_header != SOP) 
    {
        
        /* set the  corresponding read functions */
        start_slice(img, inp);

        /* read new slice */
        current_header = read_new_slice(img, inp);
		
		if (inp->symbol_mode == CABAC)
		{
			init_contexts_MotionInfo(img, currSlice->mot_ctx, 1);	
			init_contexts_TextureInfo(img,currSlice->tex_ctx, 1);
		}
		
		if (current_header == EOS)			
			return EOS;
        /* init new frame */
        if (current_header == SOP)
            init_frame(img, inp);

	   // printf("read new slice %d %d %d %d %d %d %d\n",img->currentSlice->start_mb_nr,img->currentSlice->qp, 
       // img->currentSlice->format,	img->currentSlice->picture_id, current_header, img->format,
       // img->current_slice_nr);
        
        /* decode main slice information */
        if (current_header == SOP || current_header == SOS)
            decode_one_slice(img,inp);
        img->current_slice_nr++;
    } 

    loopfilter(img);
    if(img->number == 0)
		copy2mref(img);
/*	else StW
		copy2mref_1(img);
*/
    if (p_ref)
        find_snr(snr,img,p_ref,inp->postfilter);      /* if ref sequence exist */
	
#ifdef WIN32
	_ftime (&tstruct2);		/* end time ms  */
#else
	ftime (&tstruct2);		/* end time ms  */
#endif
	time( &ltime2 );                                /* end time sec */			
	tmp_time=(ltime2*1000+tstruct2.millitm) - (ltime1*1000+tstruct1.millitm);
	tot_time=tot_time + tmp_time;

	if(img->type == INTRA_IMG) // I picture
	    fprintf(stdout,"%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 == INTER_IMG_1 || img->type == INTER_IMG_MULT) // P pictures
		fprintf(stdout,"%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(stdout,"%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);

	fflush(stdout);
// getchar();
    if(img->type == INTER_IMG_1 || img->type == INTER_IMG_MULT) // P pictres
	    copy_Pframe(img, inp->postfilter);	// imgY-->imgY_prev, imgUV-->imgUV_prev
	else // I or B pictures
		write_frame(img,inp->postfilter,p_out);         /* write image to output YUV file */

    if(img->type <= INTRA_IMG)   // I or P pictures
	    img->number++;  
    else
		Bframe_ctr++;    // B pictures

    exit_frame(img, inp);
	
	img->current_mb_nr = 0;
	return (SOP);
}



/************************************************************************
*
*  Name :       copy2mref()
*
*  Description: store reconstructed frames in multiple
*               reference buffer
*
************************************************************************/
void copy2mref(struct img_par *img)
{
  int i,j,uv;
  
  img->frame_cycle=img->number % img->buf_cycle;
  for (j=0; j < img->height; j++)
	for (i=0; i < img->width; i++)
	   mref[img->frame_cycle][j][i]=imgY[j][i];

  for (uv=0; uv < 2; uv++)
	for (i=0; i < img->width_cr; i++)
	  for (j=0; j < img->height_cr; j++)
		mcef[img->frame_cycle][uv][j][i]=imgUV[uv][j][i];/* just copy 1/1 pix, interpolate "online" */

}  



/*!
 *	\fn		find_snr()
 *	\brief	Find PSNR for all three components.Compare decoded frame with
 *          the original sequence. Read inp->jumpd frames to reflect frame skipping.
 */
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 postfilter)			/*!< postfilterin on (=1) or off (=1) */
{
	int i,j;
	int diff_y,diff_u,diff_v;
	int uv;
	int  status;
#ifndef _ADAPT_LAST_GROUP_
	byte       diff;
#else
	static int p_frame_no;
#endif

#ifndef _ADAPT_LAST_GROUP_
	if(img->type<=INTRA_IMG) // I, P pictures
		frame_no=img->number*P_interval;
	else // B pictures
	{
		diff=nextP_tr-img->tr;
		frame_no=(img->number-1)*P_interval-diff;
	}
#else
	if (img->type <= INTRA_IMG) // I, P
	{
		if (img->number > 0)
			frame_no = p_frame_no += (256 + img->tr - last_P_no[0]) % 256;
		else
			frame_no = p_frame_no  = 0;
	}
	else // B
	{
		frame_no = p_frame_no - (256 + nextP_tr - img->tr) % 256;
	}
#endif

	rewind(p_ref);
	status = fseek (p_ref, frame_no*img->height*img->width*3/2, 0);
	if (status != 0) {
		printf(" Error in seeking img->tr: %d\n", img->tr);
		exit (-1);
	}    
	for (j=0; j < img->height; j++) 
		for (i=0; i < img->width; i++) 
			imgY_ref[j][i]=fgetc(p_ref);         
	for (uv=0; uv < 2; uv++) 
		for (j=0; j < img->height_cr ; j++) 
			for (i=0; i < img->width_cr; i++) 
				imgUV_ref[uv][j][i]=fgetc(p_ref);  

	img->quad[0]=0;
	diff_y=0;
	for (i=0; i < img->width; ++i)
	{
		for (j=0; j < img->height; ++j)
		{
			diff_y += img->quad[abs(imgY[j][i]-imgY_ref[j][i])];
		}
	}

	/*  Chroma */
	diff_u=0;
	diff_v=0;

	for (i=0; i < img->width_cr; ++i)
	{
		for (j=0; j < img->height_cr; ++j)
		{
			diff_u += img->quad[abs(imgUV_ref[0][j][i]-imgUV[0][j][i])];
			diff_v += img->quad[abs(imgUV_ref[1][j][i]-imgUV[1][j][i])];
		}
	}

	/*  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 */
	}

	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  */
		snr->snr_v=(float)(10*log10(65025*(float)(img->width)*(img->height)/(float)(4*diff_v)));    /*  chroma snr for current frame  */
	}

	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;
	}
	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  */
	}
}


/*!
 *	\fn		loopfilter()
 *	\brief	Filter to reduce blocking artifacts. The filter strengh
 *          is QP dependent.
 */

static unsigned char
  overallActivity[256], qp_overallActivity = 255;
static int
  beta;

void loopfilter(struct img_par *img)
{
  static int MAP[32];
 // byte imgY_tmp[288][352];                      /* temp luma image */
 // byte imgUV_tmp[2][144][176];                  /* temp chroma image */

  int x,y,y4,x4,k,uv,str1,str2;

  if (qp_overallActivity != img->qp)
  {
    int
      i, alpha,
      ALPHA_TABLE[32] = {
        0,  0,  0,  0,  0,  0,  0,  0,
        3,  3,  3,  7,  7,  7, 12, 17,
       17, 22, 28, 34, 40, 47, 60, 67,
       82, 89,112,137,153,187,213,249
      },
      BETA_TABLE[32] = {
        0,  0,  0,  0,  0,  0,  0,  0,
        3,  3,  3,  4,  4,  4,  6,  6,
        6,  7,  8,  8,  9,  9, 10, 10,
       11, 11, 12, 12, 13, 13, 14, 14
      };

    for (i=0; i<32; i++)
      MAP[i] = QP2QUANT[i]-1;

    /*
     * ALPHA(img->qp) = ceil(2.0 * MAP(img->qp) * ln(MAP(img->qp)))
     */
    alpha = ALPHA_TABLE[img->qp];

    /*
     * BETA(img->qp) = floor(4.0 * log(MAP[img->qp]) + 0.5)
     */
    beta = BETA_TABLE[img->qp];

    for (k=0; k<256; k++)
      if (2*k >= alpha+(alpha/2))
        overallActivity[k] = 1;
      else if (2*k >= alpha)
        overallActivity[k] = 2;
      else
        overallActivity[k] = 3;

    qp_overallActivity = img->qp;

  }

  /* Luma hor */ 
  for(y=0;y<img->height;y++)
    for(x=0;x<img->width;x++)
      imgY_tmp[y][x]=imgY[y][x];

  for(y=0;y<img->height;y++)
  {
    y4=y/4;
    for(x=4;x<img->width;x=x+4)
    {
      x4=x/4;

      str1 = loopb[x4][y4+1];
      str2 = loopb[x4+1][y4+1];

      if((str1!=0)&&(str2!=0))
      {
        /*
         * Copy one line of 4+4 reconstruction pels into the filtering buffer.
         */
        for(k=0;k<8;k++)
          img->li[k]=imgY_tmp[y][x-4+k];

        /*
         * Check for longer filtering on macroblock border if either block is intracoded.
         */
        if(!(x4%4) && (str1 == 3 || str2 == 3))
        {
          if(loop(img,str1,str2, 1, 0))
          {
            imgY_tmp[y][x-4+6] = img->lu[6];
            imgY[y][x-3]       = img->lu[1];
            imgY[y][x+2]       = img->lu[6];
          }
        }
        else
          loop(img,str1,str2, 0, 0);

        /*
         * Place back the filtered values into the filtered reconstruction buffer.
         */
        for (k=2;k<6;k++)
          imgY[y][x-4+k]=img->lu[k];
      }
    }
  }

  /* Luma vert */ 
  for(y=0;y<img->height;y++)       
    for(x=0;x<img->width;x++)
      imgY_tmp[y][x]=imgY[y][x];

  for(x=0;x<img->width;x++)
  {
    x4=x/4;
    for(y=4;y<img->height;y=y+4)
    {
      y4=y/4;

      str1 = loopb[x4+1][y4];
      str2 = loopb[x4+1][y4+1];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -