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

📄 pjmplayerdlg.cpp

📁 程序以及测试文件。 说明: 1.两个程序均可以播放X264生成的264文件,这里先只支持QCIF,文件名固定为test.264,不是这个名称将无法解码 2.PC版将两个文件放在同一个文件夹下即
💻 CPP
📖 第 1 页 / 共 2 页
字号:
 ************************************************************************
 * \brief
 *    Read input from configuration file
 *
 * \par Input:
 *    Name of configuration filename
 *
 * \par Output
 *    none
 ************************************************************************
 */
void init_conf(struct inp_par *inp, char *config_filename)
{
  FILE *fd;
  int NAL_mode;

  // picture error concealment
  int temp;
  char tempval[100];

  // read the decoder configuration file
  if((fd=fopen(config_filename,"r")) == NULL)
  {
    snprintf(errortext, ET_SIZE, "Error: Control file %s not found\n",config_filename);
    error(errortext, 300);
  }

  fscanf(fd,"%s",inp->infile);                // H.264 compressed input bitstream
  fscanf(fd,"%*[^\n]");

  fscanf(fd,"%s",inp->outfile);               // RAW (YUV/RGB) output file
  fscanf(fd,"%*[^\n]");

  fscanf(fd,"%s",inp->reffile);               // reference file
  fscanf(fd,"%*[^\n]");

  fscanf(fd,"%d",&(inp->write_uv));           // write UV in YUV 4:0:0 mode
  fscanf(fd,"%*[^\n]");
  
  fscanf(fd,"%d",&(NAL_mode));                // NAL mode
  fscanf(fd,"%*[^\n]");

  switch(NAL_mode)
  {
  case 0:
    inp->FileFormat = PAR_OF_ANNEXB;
    break;
  case 1:
    inp->FileFormat = PAR_OF_RTP;
    break;
  default:
    snprintf(errortext, ET_SIZE, "NAL mode %i is not supported", NAL_mode);
    error(errortext,400);
  }

  fscanf(fd,"%d,",&inp->ref_offset);   // offset used for SNR computation
  fscanf(fd,"%*[^\n]");

  fscanf(fd,"%d,",&inp->poc_scale);   // offset used for SNR computation
  fscanf(fd,"%*[^\n]");


  if (inp->poc_scale < 1 || inp->poc_scale > 10)
  {
    snprintf(errortext, ET_SIZE, "Poc Scale is %d. It has to be within range 1 to 10",inp->poc_scale);
    error(errortext,1);
  }

  inp->write_uv=1;

  // picture error concealment
  img->conceal_mode = inp->conceal_mode = 0;
  img->ref_poc_gap = inp->ref_poc_gap = 2;
  img->poc_gap = inp->poc_gap = 2;

#ifdef _LEAKYBUCKET_
  fscanf(fd,"%ld,",&inp->R_decoder);             // Decoder rate
  fscanf(fd, "%*[^\n]");
  fscanf(fd,"%ld,",&inp->B_decoder);             // Decoder buffer size
  fscanf(fd, "%*[^\n]");
  fscanf(fd,"%ld,",&inp->F_decoder);             // Decoder initial delay
  fscanf(fd, "%*[^\n]"); 
  fscanf(fd,"%s",inp->LeakyBucketParamFile);    // file where Leaky Bucket params (computed by encoder) are stored
  fscanf(fd,"%*[^\n]");
#endif

  /* since error concealment parameters are added at the end of
  decoder conf file we need to read the leakybucket params to get to 
  those parameters */
#ifndef _LEAKYBUCKET_
  fscanf(fd,"%ld,",&temp);
  fscanf(fd, "%*[^\n]");
  fscanf(fd,"%ld,",&temp);
  fscanf(fd, "%*[^\n]");
  fscanf(fd,"%ld,",&temp);
  fscanf(fd, "%*[^\n]"); 
  fscanf(fd,"%s",tempval);
  fscanf(fd,"%*[^\n]");
#endif

  fscanf(fd,"%d",&inp->conceal_mode);   // Mode of Error Concealment
  fscanf(fd,"%*[^\n]");
  img->conceal_mode = inp->conceal_mode;
  fscanf(fd,"%d",&inp->ref_poc_gap);   // POC gap depending on pattern
  fscanf(fd,"%*[^\n]");
  img->ref_poc_gap = inp->ref_poc_gap;
  fscanf(fd,"%d",&inp->poc_gap);   // POC gap between consecutive frames in display order
  fscanf(fd,"%*[^\n]");
  img->poc_gap = inp->poc_gap;

  fclose (fd);
}

//进行YUV->RGB转换以及显示视频的函数
//用来显示的全局变量
unsigned char *src[3];
BOOL PlayingVideo=FALSE;
unsigned char *clp = NULL;
unsigned char *clp1;
int width,height;
unsigned char bufRGB[80000];

//进行YUV->RGB转换的函数
long int crv_tab[256];
long int cbu_tab[256];
long int cgu_tab[256];

long int cgv_tab[256];
long int tab_76309[256];

void init_dither_tab ()
{
  long int crv, cbu, cgu, cgv;
  int i;

  crv = 104597;
  cbu = 132201;                 /* fra matrise i global.h */
  cgu = 25675;
  cgv = 53279;

  for (i = 0; i < 256; i++)
  {
    crv_tab[i] = (i - 128) * crv;
    cbu_tab[i] = (i - 128) * cbu;
    cgu_tab[i] = (i - 128) * cgu;
    cgv_tab[i] = (i - 128) * cgv;
    tab_76309[i] = 76309 * (i - 16);
  }
  if (!(clp = (unsigned char *)malloc(sizeof(unsigned char)*1024)))
  {
    AfxMessageBox(L"安排解码码表内存失败!");
  }
  clp1 = clp;

  clp += 384;

  for (i = -384; i < 640; i++)
    clp[i] = (i < 0) ? 0 : ((i > 255) ? 255 : i);
}

void ConvertYUVtoRGB (unsigned char *src0, unsigned char *src1, unsigned char *src2,
                      unsigned char *dst_ori,int width,int height)

{

  int y11, y21;
  int y12, y22;
  int y13, y23;
  int y14, y24;
  int u, v;
  int i, j;
  int c11, c21, c31, c41;
  int c12, c22, c32, c42;
  unsigned int DW;
  unsigned int *id1, *id2;
  unsigned char *py1, *py2, *pu, *pv;
  unsigned char *d1, *d2;

  d1 = dst_ori;
  d1 += width * height * 3 - width * 3;
  d2 = d1 - width * 3;

  py1 = src0;
  pu = src1;
  pv = src2;
  py2 = py1 + width;

  id1 = (unsigned int *) d1;
  id2 = (unsigned int *) d2;

  for (j = 0; j < height; j += 2)
  {
    /* line j + 0 */
    for (i = 0; i < width; i += 4)
    {
      u = *pu++;
      v = *pv++;
      c11 = crv_tab[v];
      c21 = cgu_tab[u];
      c31 = cgv_tab[v];
      c41 = cbu_tab[u];
      u = *pu++;
      v = *pv++;
      c12 = crv_tab[v];
      c22 = cgu_tab[u];
      c32 = cgv_tab[v];
      c42 = cbu_tab[u];

      y11 = tab_76309[*py1++];  /* (255/219)*65536 */
      y12 = tab_76309[*py1++];
      y13 = tab_76309[*py1++];  /* (255/219)*65536 */
      y14 = tab_76309[*py1++];

      y21 = tab_76309[*py2++];
      y22 = tab_76309[*py2++];
      y23 = tab_76309[*py2++];
      y24 = tab_76309[*py2++];

      /* RGBR */
      DW = ((clp[(y11 + c41) >> 16])) |
        ((clp[(y11 - c21 - c31) >> 16]) << 8) |
        ((clp[(y11 + c11) >> 16]) << 16) |
        ((clp[(y12 + c41) >> 16]) << 24);
      *id1++ = DW;

      /* GBRG */
      DW = ((clp[(y12 - c21 - c31) >> 16])) |
        ((clp[(y12 + c11) >> 16]) << 8) |
        ((clp[(y13 + c42) >> 16]) << 16) |
        ((clp[(y13 - c22 - c32) >> 16]) << 24);
      *id1++ = DW;

      /* BRGB */
      DW = ((clp[(y13 + c12) >> 16])) |
        ((clp[(y14 + c42) >> 16]) << 8) |
        ((clp[(y14 - c22 - c32) >> 16]) << 16) |
        ((clp[(y14 + c12) >> 16]) << 24);
      *id1++ = DW;

      /* RGBR */
      DW = ((clp[(y21 + c41) >> 16])) |
        ((clp[(y21 - c21 - c31) >> 16]) << 8) |
        ((clp[(y21 + c11) >> 16]) << 16) |
        ((clp[(y22 + c41) >> 16]) << 24);
      *id2++ = DW;

      /* GBRG */
      DW = ((clp[(y22 - c21 - c31) >> 16])) |
        ((clp[(y22 + c11) >> 16]) << 8) |
        ((clp[(y23 + c42) >> 16]) << 16) |
        ((clp[(y23 - c22 - c32) >> 16]) << 24);
      *id2++ = DW;

      /* BRGB */
      DW = ((clp[(y23 + c12) >> 16])) |
        ((clp[(y24 + c42) >> 16]) << 8) |
        ((clp[(y24 - c22 - c32) >> 16]) << 16) |
        ((clp[(y24 + c12) >> 16]) << 24);
      *id2++ = DW;
    }
    id1 -= (9 * width) >> 2;
    id2 -= (9 * width) >> 2;
    py1 += width;
    py2 += width;
  }
}

/////////////////////////////////////////////////////////////////////////////
// CPJMPlayerDlg dialog

CPJMPlayerDlg::CPJMPlayerDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CPJMPlayerDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CPJMPlayerDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CPJMPlayerDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CPJMPlayerDlg)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CPJMPlayerDlg, CDialog)
	//{{AFX_MSG_MAP(CPJMPlayerDlg)
	ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
	ON_WM_TIMER()
	ON_WM_DESTROY()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CPJMPlayerDlg message handlers

BOOL CPJMPlayerDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	CenterWindow(GetDesktopWindow());	// center to the hpc screen

	// TODO: Add extra initialization here
	//初始化视频窗口
	// Adjust display windows	

	// For remote video display window
	wnd=this->GetDlgItem(IDC_REMOTEVIDEO);	// Video display window
   	bwnd=this->GetDlgItem(IDC_REMOTEBORDER); // Border window...
   	bwnd->GetWindowRect(brect);
	ScreenToClient(brect);

	remote_wnd_x=brect.TopLeft().x+(brect.Width()-IMAGE_WIDTH)/2;
	remote_wnd_y=brect.TopLeft().y+(brect.Height()-IMAGE_HEIGHT)/2;
	
	// Centre the remote video window
	wnd->SetWindowPos(&wndTop,remote_wnd_x-4,remote_wnd_y-4,IMAGE_WIDTH+9,IMAGE_HEIGHT+9,SWP_SHOWWINDOW | SWP_DRAWFRAME);

	
	//初始化JM
	int argc;char **argv;
	
	// allocate memory for the structures
	if ((input =  (struct inp_par *)calloc(1, sizeof(struct inp_par)))==NULL) no_mem_exit("main: input");
	if ((snr   =  (struct snr_par *)calloc(1, sizeof(struct snr_par)))==NULL) no_mem_exit("main: snr");
	if ((img   =  (struct img_par *)calloc(1, sizeof(struct img_par)))==NULL) no_mem_exit("main: img");
	
	
	Configure (argc, argv);

	//初始化显示
	width=IMAGE_WIDTH;height=IMAGE_HEIGHT;
	//bufRGB = (unsigned char *)malloc(sizeof(unsigned char)*(3 * width * height));
	init_dither_tab();

	m_bDecoding=FALSE;
	hDecodeThread=NULL;
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}



void CPJMPlayerDlg::OnButton1() 
{
	if(!m_bDecoding)
	{
		//如果有的话,停止解码线程
		if(hDecodeThread)
		{
			TerminateThread(hDecodeThread,0);
			CloseHandle(hDecodeThread);
			hDecodeThread=NULL;
		}

		//开始解码线程
		Ready=0;
		SetTimer(123,20,NULL);
		m_bDecoding=TRUE;
		SetDlgItemText(IDC_BUTTON1,_T("停止解码"));
		hDecodeThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)DecodeThread,(void *)this,0,&dwThreadID);
	}
	else
	{
		SetDlgItemText(IDC_BUTTON1,_T("解码"));
		//停止编码线程
		if(hDecodeThread)
		{
			TerminateThread(hDecodeThread,0);
			CloseHandle(hDecodeThread);
			hDecodeThread=NULL;
		}
		m_bDecoding=FALSE;
	}
}

void CPJMPlayerDlg::DisplayVideo()
{
	ConvertYUVtoRGB ((unsigned char*)displaybuf,(unsigned char*)(displaybuf+25344),(unsigned char*)(displaybuf+31680),bufRGB,width,height);
	
	unsigned char* rgbdata=bufRGB;
	
	int x,y;
	unsigned char temp;
	{
		for(y=0;y<144;y++)
		{
			for(x=0;x<88;x++)
			{			
				temp=rgbdata[(176*y+x)*3];
				rgbdata[(176*y+x)*3]=rgbdata[(176*y+176-x)*3];
				rgbdata[(176*y+176-x)*3]=temp;
				
				temp=rgbdata[(176*y+x)*3+1];
				rgbdata[(176*y+x)*3+1]=rgbdata[(176*y+176-x)*3+1];
				rgbdata[(176*y+176-x)*3+1]=temp;
				
				temp=rgbdata[(176*y+x)*3+2];
				rgbdata[(176*y+x)*3+2]=rgbdata[(176*y+176-x)*3+2];
				rgbdata[(176*y+176-x)*3+2]=temp;
			}
		}
		for(x=0;x<38016;x++)
		{
			temp=rgbdata[x];
			rgbdata[x]=rgbdata[76032-x];
			rgbdata[76032-x]=temp;
		}
	}

	CBitmap bitmap;
	
	bitmap.CreateBitmap(176,144,1,24,rgbdata);

	CWnd* pWnd=GetDlgItem(IDC_REMOTEVIDEO);
	pWnd->UpdateWindow();

	CDC* pDC=pWnd->GetDC();
	CDC bitmapDC;
	
	bitmapDC.CreateCompatibleDC(pDC);
	CBitmap* pOldBitmap = bitmapDC.SelectObject(&bitmap);
	//pDC->StretchBlt(0,0,176,144,&bitmapDC,0,0,176,144,SRCCOPY);
	pDC->BitBlt(0,0,176,144,&bitmapDC,0,0,SRCCOPY);
	bitmapDC.SelectObject(pOldBitmap);
	bitmap.DeleteObject();
}


//解码线程
DWORD CPJMPlayerDlg::DecodeThread(void *pDlg)
{
	init_old_slice();
	
	switch (input->FileFormat)
	{
	case 0:
		OpenBitstreamFile (input->infile);
		break;
	case 1:
		OpenRTPFile (input->infile);
		break;
	default:
		printf ("Unsupported file format %d, exit\n", input->FileFormat);
	}

	// Allocate Slice data struct
  malloc_slice(input,img);

  init(img);

  dec_picture = NULL;

  dpb.init_done = 0;
  g_nFrame = 0;

  init_out_buffer();

  img->idr_psnr_number=input->ref_offset;
  img->psnr_number=0;

  img->number=0;
  img->type = I_SLICE;
  img->dec_ref_pic_marking_buffer = NULL;

  // B pictures
  Bframe_ctr=snr->frame_ctr=0;

  // time for total decoding session
  tot_time = 0;
  
  while (decode_one_frame(img, input, snr) != EOS)
    ;

  //report(input, img, snr);
  free_slice(input,img);
  FmoFinit();
  free_global_buffers();

  flush_dpb();

#ifdef PAIR_FIELDS_IN_OUTPUT
  flush_pending_output(p_out);
#endif

  CloseBitstreamFile();

  close(p_out);
//  fclose(p_out2);
  if (p_ref)
    close(p_ref);
#if TRACE
  fclose(p_trace);
#endif

  ercClose(erc_errorVar);

  free_dpb();
  uninit_out_buffer();

  free_colocated(Co_located);
  free (input);
  free (snr);
  free (img);

	return 0;
}

void CPJMPlayerDlg::OnTimer(UINT nIDEvent) 
{
	if(Ready==1)
	{
		DisplayVideo();
		Ready=0;
	}
	
	CDialog::OnTimer(nIDEvent);
}

void CPJMPlayerDlg::OnDestroy() 
{
	CDialog::OnDestroy();
	
	free(clp1);
}

⌨️ 快捷键说明

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