打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
H.264 display routines for Win32
/************************************************************************
 *
 *  win.c, display routines for Win32 for tmndecode 
 *
 ************************************************************************/
#include "win.h"

/* vdinit.c */
unsigned char *clp = NULL;
unsigned char *clp1 = NULL;

#ifdef __cplusplus
extern "C"
{
#endif

T_VDWINDOW vdWindow;



int initDisplay (int pels, int lines)
{
  int errFlag = 0;
  DWORD dwRetVal;

  init_dither_tab ();
  errFlag |= InitDisplayWindowThread (pels, lines);
  dwRetVal = WaitForSingleObject (vdWindow.hReadyEvt, INFINITE);
  return errFlag;
}


int InitDisplayWindowThread (int width, int height)
{
  int errFlag = 0;

  /* now modify the couple that need it */
  vdWindow.width = width;
  vdWindow.height = height;
  vdWindow.biHeader.biWidth = vdWindow.width;
  vdWindow.biHeader.biHeight = vdWindow.height;
  vdWindow.biHeader.biSize = sizeof (BITMAPINFOHEADER);
  vdWindow.biHeader.biCompression = BI_RGB;
  vdWindow.biHeader.biPlanes = 1;
  vdWindow.biHeader.biBitCount = 24;


  vdWindow.biHeader.biSizeImage = 3 * vdWindow.width * vdWindow.height;
  vdWindow.imageIsReady = FALSE;

  /* allocate the memory needed to hold the RGB and visualization
   * information */
  vdWindow.bufRGB = NULL;

  vdWindow.bufRGB = (unsigned char *)malloc(sizeof(unsigned char)
    *(3 * vdWindow.width * vdWindow.height));

  /* Create synchronization event */
  vdWindow.hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
  vdWindow.hReadyEvt = CreateEvent (NULL, FALSE, FALSE, NULL);
  vdWindow.hReadyQuitEvt = CreateEvent (NULL, FALSE, FALSE, NULL);
  
  vdWindow.hThread =
    CreateThread (
                  NULL,
                  0,
                  (LPTHREAD_START_ROUTINE) DisplayWinMain,
                  (LPVOID) NULL,
                  0,
                  &(vdWindow.dwThreadID)
    );

  if (vdWindow.hThread == NULL)
  {
    errFlag = 1;
    return errFlag;
  }
  return errFlag;
}


/* vddraw.c */

int displayImage (unsigned char *lum, unsigned char *Cr, unsigned char *Cb)
{
  int errFlag = 0;
  DWORD dwRetVal;
  vdWindow.src[0] = lum;
  vdWindow.src[1] = Cb;
  vdWindow.src[2] = Cr;
  /* wait until we have finished drawing the last frame */
  if (vdWindow.windowDismissed == FALSE)
  {
    vdWindow.imageIsReady = TRUE;
    /* Post message to drawing thread's window to draw frame */
    PostMessage (vdWindow.hWnd, VIDEO_DRAW_FRAME, (WPARAM) NULL, (LPARAM) NULL);
    /* wait until the frame has been drawn */
    dwRetVal = WaitForSingleObject (vdWindow.hEvent, INFINITE);
    free(vdWindow.src[0]);
    free(vdWindow.src[1]);
    free(vdWindow.src[2]);
  }
  else
  {
    free(vdWindow.src[0]);
    free(vdWindow.src[1]);
    free(vdWindow.src[2]);
  }
  return errFlag;
}


int DrawDIB ()
{
  int errFlag = 0;

  errFlag |=
    DrawDibDraw (
                 vdWindow.hDrawDib,
                 vdWindow.hDC,
                 0,
                 0,
                 vdWindow.zoom * vdWindow.width,
                 vdWindow.zoom * vdWindow.height,
                 &vdWindow.biHeader,
                 vdWindow.bufRGB,
                 0,
                 0,
                 vdWindow.width,
                 vdWindow.height,
                 DDF_SAME_DRAW
    );


  return errFlag;
}




/* vdwinman.c */

void DisplayWinMain (void *dummy)
{
  int errFlag = 0;
  DWORD dwStyle;

  vdWindow.wc.style = CS_BYTEALIGNWINDOW;
  vdWindow.wc.lpfnWndProc = MainWndProc;
  vdWindow.wc.cbClsExtra = 0;
  vdWindow.wc.cbWndExtra = 0;
  vdWindow.wc.hInstance = 0;
  vdWindow.wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
  vdWindow.wc.hCursor = LoadCursor (NULL, IDC_ARROW);
  vdWindow.wc.hbrBackground = (HBRUSH)(GetStockObject (WHITE_BRUSH));
  vdWindow.wc.lpszMenuName = NULL;
  vdWindow.zoom = 1;
  strcpy (vdWindow.lpszAppName, "H.264 Display");
  vdWindow.wc.lpszClassName = vdWindow.lpszAppName;

  RegisterClass (&vdWindow.wc);


  dwStyle = WS_DLGFRAME | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX;

  vdWindow.hWnd =
    CreateWindow (vdWindow.lpszAppName,
                  vdWindow.lpszAppName,
                  dwStyle,
                  CW_USEDEFAULT,
                  CW_USEDEFAULT,
                  vdWindow.width + 6,
                  vdWindow.height + 25,
                  NULL,
                  NULL,
                  0,
                  NULL
    );

  if (vdWindow.hWnd == NULL)
    ExitThread (errFlag = 1);

  ShowWindow (vdWindow.hWnd, SW_SHOWNOACTIVATE);
  UpdateWindow (vdWindow.hWnd);

  /* Message loop for display window's thread */
  while (GetMessage (&(vdWindow.msg), NULL, 0, 0))
  {
    TranslateMessage (&(vdWindow.msg));
    DispatchMessage (&(vdWindow.msg));
  }

  ExitThread (0);
}


LRESULT APIENTRY MainWndProc (HWND hWnd, UINT msg, UINT wParam, LONG lParam)
{
  LPMINMAXINFO lpmmi;

  switch (msg)
  {
    case VIDEO_BEGIN:
      vdWindow.hDC = GetDC (vdWindow.hWnd);
      vdWindow.hDrawDib = DrawDibOpen ();
      vdWindow.zoom = 1;
      vdWindow.oldzoom = 0;
      DrawDibBegin (
                    vdWindow.hDrawDib,
                    vdWindow.hDC,
                    2 * vdWindow.width,
                    2 * vdWindow.height,
                    &vdWindow.biHeader,
                    vdWindow.width,
                    vdWindow.height,
                    0
        );
      SetEvent (vdWindow.hReadyEvt);
      vdWindow.windowDismissed = FALSE;
      ReleaseDC (vdWindow.hWnd, vdWindow.hDC);
      break;
    case VIDEO_DRAW_FRAME:
      vdWindow.hDC = GetDC (vdWindow.hWnd);
      ConvertYUVtoRGB (
                       vdWindow.src[0],
                       vdWindow.src[1],
                       vdWindow.src[2],
                       vdWindow.bufRGB,
                       vdWindow.width,
                       vdWindow.height
        );
      /* draw the picture onto the screen */
      DrawDIB ();
      SetEvent (vdWindow.hEvent);
      ReleaseDC (vdWindow.hWnd, vdWindow.hDC);
      break;
    case VIDEO_END:
      /* Window has been closed.  The following lines handle the cleanup. */
      vdWindow.hDC = GetDC (vdWindow.hWnd);
      DrawDibEnd (vdWindow.hDrawDib);
      DrawDibClose (vdWindow.hDrawDib);
      ReleaseDC (vdWindow.hWnd, vdWindow.hDC);
      SetEvent (vdWindow.hReadyQuitEvt);
      vdWindow.windowDismissed = TRUE;
      PostQuitMessage (0);
      break;

    case WM_CREATE:
      PostMessage (hWnd, VIDEO_BEGIN, 0, 0);
      break;
    case WM_SIZE:
      switch (wParam)
      {
        case SIZE_MAXIMIZED:
          vdWindow.zoom = 2;
          break;
        case SIZE_MINIMIZED:
          vdWindow.oldzoom = vdWindow.zoom;
          break;
        case SIZE_RESTORED:
          if (vdWindow.oldzoom)
          {
            vdWindow.zoom = vdWindow.oldzoom;
            vdWindow.oldzoom = 0;
          } else
            vdWindow.zoom = 1;
          break;
        case SIZE_MAXHIDE:
          break;
        case SIZE_MAXSHOW:
          break;
      }
      PostMessage (hWnd, WM_PAINT, 0, 0);
      break;
    case WM_GETMINMAXINFO:
      lpmmi = (LPMINMAXINFO) lParam;

      GetWindowRect (hWnd, &vdWindow.rect);
      lpmmi->ptMaxPosition.x = vdWindow.rect.left;
      lpmmi->ptMaxPosition.y = vdWindow.rect.top;

      lpmmi->ptMaxSize.x = 2 * (vdWindow.width) + 6;
      lpmmi->ptMaxSize.y = 2 * (vdWindow.height) + 25;
      break;
    case WM_DESTROY:
      /* Window has been closed.  The following lines handle the cleanup. */
      DrawDibEnd (vdWindow.hDrawDib);
      ReleaseDC (vdWindow.hWnd, vdWindow.hDC);
      DrawDibClose (vdWindow.hDrawDib);

      vdWindow.windowDismissed = TRUE;
      PostQuitMessage (0);
      break;
    case WM_PAINT:
      if (vdWindow.imageIsReady)
      {
        vdWindow.hDC = GetDC (vdWindow.hWnd);
        DrawDIB ();
        ReleaseDC (vdWindow.hWnd, vdWindow.hDC);
      }
      break;

  }
  return DefWindowProc (hWnd, msg, wParam, lParam);
}



/* vdclose.c */

int closeDisplay ()
{
  int errFlag = 0;
  DWORD dwRetVal;
  if (vdWindow.hWnd)
  {
    PostMessage (vdWindow.hWnd, VIDEO_END, (WPARAM) NULL, (LPARAM) NULL);
    dwRetVal = WaitForSingleObject (vdWindow.hReadyQuitEvt, INFINITE);
  }
  if (vdWindow.hEvent)
    CloseHandle (vdWindow.hEvent);
  if (vdWindow.hReadyEvt)
    CloseHandle(vdWindow.hReadyEvt);
  if (vdWindow.hReadyEvt)
    CloseHandle(vdWindow.hReadyQuitEvt);
  if (vdWindow.hThread)
    CloseHandle (vdWindow.hThread);
  
  
  if(vdWindow.bufRGB != NULL)
    free(vdWindow.bufRGB);
  
  if(clp1 != NULL)
    free(clp1);
  return errFlag;
}



#ifdef __cplusplus
}
#endif

/************************************************************************
 *
 *  yuvrgb24.c, colour space conversion for tmndecode (H.264 decoder)
 *
 ************************************************************************/
#ifdef __GCC__
#include "display.h"
#endif

#include <stdio.h>
#include <malloc.h>

/* Data for ConvertYUVtoRGB */

extern unsigned char *clp;
extern unsigned char *clp1;

#ifdef __cplusplus
extern "C"
{
#endif


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)))
    printf("malloc failed\n");
  clp1 = clp;

  clp += 384;

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




/**********************************************************************
 *
 * Name:         ConvertYUVtoRGB
 * Description:     Converts YUV image to RGB (packed mode)
 *
 * Input:         pointer to source luma, Cr, Cb, destination,
 *                       image width and height
 * Returns:
 * Side effects:
 *
 * Date: 951208 Author: Karl.Lillevold@nta.no
 *
 ***********************************************************************/



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

{
  extern long int crv_tab[];
  extern long int cbu_tab[];
  extern long int cgu_tab[];

  extern long int cgv_tab[];
  extern long int tab_76309[];

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

#ifdef __cplusplus
}
#endif

win.h

#include <windows.h>
#include <process.h>
#include <vfw.h>
#include <memory.h>


typedef struct
{
  HANDLE hThread;
  HANDLE hReadyEvt;       //Add for initDisplay()
  HANDLE hReadyQuitEvt;   //Add for closeDisplay()
  HANDLE hEvent;
  HWND hWnd;
  MSG msg;
  WNDCLASS wc;
  HDRAWDIB hDrawDib;
  HDC hDC;
  BITMAPINFOHEADER biHeader;
  char lpszAppName[15];
  DWORD dwThreadID;
  BOOL imageIsReady;
  unsigned char *bufRGB;
  RECT rect;
  unsigned char *src[3];

  int width, height;
  int zoom, oldzoom;
  int windowDismissed;
} T_VDWINDOW;


#define VIDEO_BEGIN    (WM_USER + 0)
#define VIDEO_DRAW_FRAME  (WM_USER + 1)
#define VIDEO_REDRAW_FRAME (WM_USER + 2)
#define VIDEO_END      (WM_USER + 3)


#ifdef __cplusplus
extern "C"
{
#endif


int initDisplay (int pels, int lines);
int displayImage (unsigned char *lum, unsigned char *Cr, unsigned char *Cb);
int closeDisplay ();

void DisplayWinMain (void *);
LONG APIENTRY MainWndProc (HWND, UINT, UINT, LONG);
int DrawDIB ();
void init_dither_tab();
void ConvertYUVtoRGB(
  unsigned char *src0,
  unsigned char *src1,
  unsigned char *src2,
  unsigned char *dst_ori,
  int width,
  int height
);
int InitDisplayWindowThread (int,int);

#pragma comment(lib, "vfw32.lib")

#ifdef __cplusplus
}
#endif


/*****************************************************************************
*
*  VM_H264 AVC CODEC
*
****************************************************************************/
// h264.c : Defines the entry point for the console application.
//

//#define USE_DISPLAY
#include "config.h"

#ifdef USE_DISPLAY
#ifndef __GCC__
#include "win.h"
#else
#include "display.h"
#endif
#endif

#include "stdio.h"
#include "sys/timeb.h"
#include "time.h"

#include "stdlib.h"
#include "memory.h"
#include "math.h"
#include "vm_h264.h"
#include "utility.h"
#include "string.h"


// parameters begin
int32_t total_no = 300;
char src_path[256];
char out_path[256];
char rec_path[256];
// for decoder PSNR
char ref_path[256];
static int  ref_skip;

// parameters end

#ifdef USE_DISPLAY
//将一帧数据写到YUV中并显示
void winDisplay(H264_t* t, H264_frame_t* f)
{
    uint8_t* p;
    unsigned char* buffer1, *buffer2, *buffer3, *Y, *U, *V;
    unsigned char *src[3];
    int32_t i;

    src[0] = Y = buffer1 = malloc(t->width*t->height*sizeof(char));
    p = f->Y[0];
    for (i = 0 ; i < t->height ; i++)
    {
        memcpy(buffer1, p, t->width);
        buffer1 += t->width;
        p += t->edged_stride;
    }

    src[2] = V = buffer2 = malloc((t->width*t->height*sizeof(char))>>2);
    p = f->V;
    for (i = 0 ; i < (t->height >> 1); i++)
    {
        memcpy(buffer2, p, t->width >> 1);
        buffer2 += (t->width >> 1);
        p += t->edged_stride_uv;
    }

    src[1] = U = buffer3 = malloc((t->width*t->height*sizeof(char))>>2);
    p = f->U;
    for (i = 0 ; i < (t->height >> 1); i++)
    {
        memcpy(buffer3, p, t->width >> 1);
        buffer3 += (t->width >> 1);
        p += t->edged_stride_uv;
    }
#ifndef __GCC__
    displayImage(Y,V,U);
#else
    dither(src);
    free(src[1]);
    free(src[2]);
    free(src[0]);
#endif
}

void
uninit_display()
{
#ifndef __GCC__
    closeDisplay ();
#else
    exit_display();
#endif
}
#endif

void
init_param(H264_param_t* param, const char* file)
{
    FILE* fd; 
    char line[255];
    int32_t b;
    if (!(fd = fopen(file,"r")))
    {
        printf("Couldn't open parameter file %s.\n", file);
        exit(-1);
    }

    memset(param, 0, sizeof(*param));
    fgets(line, 254, fd); sscanf(line,"%d", &b);
    if (b != 4)
    {
        printf("wrong param file version, expect v4.0\n");
        exit(-1);
    }
    fgets(line, 254, fd); sscanf(line,"%d", &param->width);
    fgets(line, 254, fd); sscanf(line,"%d", &param->height);
    fgets(line, 254, fd); sscanf(line,"%d", &param->search_x);
    fgets(line, 254, fd); sscanf(line,"%d", &param->search_y);
    fgets(line, 254, fd); sscanf(line,"%d", &total_no);
    fgets(line, 254, fd); sscanf(line,"%d", &param->iframe);
    fgets(line, 254, fd); sscanf(line,"%d", &param->idrframe);
    fgets(line, 254, fd); sscanf(line,"%d", &param->b_num);
    fgets(line, 254, fd); sscanf(line,"%d", &param->ref_num);
    fgets(line, 254, fd); sscanf(line,"%d", &param->enable_rc);
    fgets(line, 254, fd); sscanf(line,"%d", &param->bitrate);
    fgets(line, 254, fd); sscanf(line,"%f", &param->framerate);
    fgets(line, 254, fd); sscanf(line,"%d", &param->qp);
    fgets(line, 254, fd); sscanf(line,"%d", &param->min_qp);
    fgets(line, 254, fd); sscanf(line,"%d", &param->max_qp);
    fgets(line, 254, fd); sscanf(line,"%d", &param->enable_stat);
    fgets(line, 254, fd); sscanf(line,"%d", &param->disable_filter);
    fgets(line, 254, fd); sscanf(line,"%d", &param->aspect_ratio);
    fgets(line, 254, fd); sscanf(line,"%d", &param->video_format);
    fgets(line, 254, fd); sscanf(line,"%d", &param->luma_coeff_cost);
    fgets(line, 254, fd); sscanf(line,"%d", &b);
    param->flags |= (USE_INTRA16x16) * (!!b);
    fgets(line, 254, fd); sscanf(line,"%d", &b);
    param->flags |= (USE_INTRA4x4) * (!!b);
    fgets(line, 254, fd); sscanf(line,"%d", &b);
    param->flags |= (USE_INTRAININTER) * (!!b);
    fgets(line, 254, fd); sscanf(line,"%d", &b);
    param->flags |= (USE_HALFPEL) * (!!b);
    fgets(line, 254, fd); sscanf(line,"%d", &b);
    param->flags |= (USE_QUARTPEL) * (!!b);
    fgets(line, 254, fd); sscanf(line,"%d", &b);
    param->flags |= (USE_SUBBLOCK) * (!!b);
    fgets(line, 254, fd); sscanf(line,"%d", &b);
    param->flags |= (USE_FULLSEARCH) * (!!b);
    fgets(line, 254, fd); sscanf(line,"%d", &b);
    param->flags |= (USE_DIAMONDSEACH) * (!!b);
    fgets(line, 254, fd); sscanf(line,"%d", &b);
    param->flags |= (USE_FORCEBLOCKSIZE) * (!!b);
    fgets(line, 254, fd); sscanf(line,"%d", &b);
    param->flags |= (USE_FASTINTERPOLATE) * (!!b);
    fgets(line, 254, fd); sscanf(line,"%d", &b);
    param->flags |= (USE_SAD) * (!!b);
    fgets(line, 254, fd); sscanf(line,"%d", &b);
    param->flags |= (USE_EXTRASUBPELSEARCH) * (!!b);
    fgets(line, 254, fd); sscanf(line,"%d", &b);
    param->flags |= (USE_SCENEDETECT) * (!!b);
    fgets(line, 254, fd); sscanf(line,"%d", &b);
    param->block_size |= (SEARCH_16x16P) * (!!b);
    fgets(line, 254, fd); sscanf(line,"%d", &b);
    param->block_size |= (SEARCH_16x8P) * (!!b);
    fgets(line, 254, fd); sscanf(line,"%d", &b);
    param->block_size |= (SEARCH_8x16P) * (!!b);
    fgets(line, 254, fd); sscanf(line,"%d", &b);
    param->block_size |= (SEARCH_8x8P) * (!!b);
    fgets(line, 254, fd); sscanf(line,"%d", &b);
    param->block_size |= (SEARCH_8x4P) * (!!b);
    fgets(line, 254, fd); sscanf(line,"%d", &b);
    param->block_size |= (SEARCH_4x8P) * (!!b);
    fgets(line, 254, fd); sscanf(line,"%d", &b);
    param->block_size |= (SEARCH_4x4P) * (!!b);
    fgets(line, 254, fd); sscanf(line,"%d", &b);
    param->block_size |= (SEARCH_16x16B) * (!!b);
    fgets(line, 254, fd); sscanf(line,"%d", &b);
    param->block_size |= (SEARCH_16x8B) * (!!b);
    fgets(line, 254, fd); sscanf(line,"%d", &b);
    param->block_size |= (SEARCH_8x16B) * (!!b);
    fgets(line, 254, fd); sscanf(line,"%d", &b);
    param->block_size |= (SEARCH_8x8B) * (!!b);
    fgets(line, 254, fd); sscanf(line,"%d", &param->cpu);
    fgets(line, 254, fd); sscanf(line, "%d", &param->cabac);

    fgets(line, 254, fd); sscanf(line,"%s", src_path);
    fgets(line, 254, fd); sscanf(line,"%s", out_path);
    fgets(line, 254, fd); sscanf(line,"%s", rec_path);
    param->rec_name = rec_path;

    fclose(fd);
}

//将frame中的数据写到文件f_rec中
void write_frame(H264_t* t,H264_frame_t *frame,FILE *f_rec)
{
    int i;
    uint8_t* p;

    if (f_rec)
    {
        p = frame->Y[0];
        for(i = 0 ; i < t->height ; i ++)
        {
            fwrite(p, t->width, 1, f_rec);
            p += t->edged_stride;
        }
        p = frame->U;
        for(i = 0 ; i < t->height >> 1 ; i ++)
        {
            fwrite(p, t->width >> 1, 1, f_rec);
            p += t->edged_stride_uv;
        }
        p = frame->V;
        for(i = 0 ; i < t->height >> 1 ; i ++)
        {
            fwrite(p, t->width >> 1, 1, f_rec);
            p += t->edged_stride_uv;
        }
    }
}
static float __inline
dec_psnr(uint8_t* p1, uint8_t* p2, int32_t width1, int32_t width2, int32_t height, int print)
{
float sad = 0, psnr;
int32_t i, j, size, ii, jj, diff, iii, jjj;
uint8_t* p11, *p22;
for(j=0; j<height; j+=16)
{
for (i = 0 ; i < width2 ; i +=16)
{
p11 = p1+i;
p22 = p2+i;
diff = 0;
for(jj=0; jj<16; jj++)
{
for(ii=0; ii<16; ii++)
{
int32_t tmp;
tmp = (p11[ii] - p22[ii]);
sad += tmp * tmp;
if(tmp != 0 && diff != 1)
{
if(print)
printf("%2d != %2d ", p11[ii], p22[ii]);
iii = ii;
jjj = jj;
diff = 1;
}
}
p11 += width1;
p22 += width2;
}
if(diff && print)
{
printf("%4d, %2d, %2d\n", (j)*(width2>>4) + (i), iii, jjj);
print = 0;
}
}
p1 += width1*16;
p2 += width2*16;
}
size = width2 * height;
if(sad < 1e-6)
psnr = 0.0f;
else
psnr = (float)(10 * log10(65025.0f * size / sad));
return psnr;
}

int32_t 
decode(const char* filename)
{
    /* just for show how to drive the decoder */
#define BUFFER_SIZE 4096
    H264_t* t = H264dec_open();
    uint8_t buffer[BUFFER_SIZE + 4];
    int32_t run = 1,screen = 0;
    FILE* src_file = fopen(filename, "rb");
    size_t size;
    FILE* f_rec = 0;
//for decoder PSNR
int frame_num = 0;
FILE* f_ref = 0;
uint8_t *ref_buf = NULL;
    int32_t frame_nums = 0;

    float total_time;
#ifdef _WIN32
    struct _timeb beg, end;
#endif
    // xxx
    printf("Current fully support h264 encoder's bitstream.\n");

    if (!src_file)
    {
        printf("cannot open file %s.\n", filename);
        return -1;
    }
    if (rec_path[0])
    {
        f_rec = fopen(rec_path, "wb");
        if (!f_rec)
        {
            printf("cannot open rec file %s.\n", rec_path);
        }
    }
//for decoder PSNR
if(ref_path[0])
{
f_ref = fopen(ref_path, "rb");
if(!f_ref)
{
printf("cannot open ref file %s.\n", ref_path);
}
}

#ifdef _WIN32
    _ftime(&beg);
#endif
    while (run) 
    {
        decoder_state_t state = H264dec_parse(t);
        switch(state) 
        {
        case DEC_STATE_BUFFER:
            /* read more data */
            size = fread(buffer, 1, BUFFER_SIZE, src_file);
            if (size > 0)
            {
                if (size != BUFFER_SIZE)
                {
                    buffer[size] = 0;
                    buffer[size + 1] = 0;
                    buffer[size + 2] = 0;
                    buffer[size + 3] = 1;
                    size += 4;
                }

                H264dec_buffer(t, buffer, size);
            }
            else
            {
                /* if all data has readed, here we will return */
                run = 0;
                /* NOTE: here we should get the last frame */
                write_frame(t, H264dec_flush_frame(t), f_rec);
#ifdef USE_DISPLAY
                winDisplay(t, H264dec_flush_frame(t));
#endif
                frame_nums ++;
            }
            break;
        case DEC_STATE_PIC:
            /* write one pic */
            break;
        case DEC_STATE_SEQ:

#ifdef USE_DISPLAY
            if (screen == 0)
            {
#ifndef __GCC__
                initDisplay(t->width, t->height);
#else
                init_display("",t->width, t->height);
#endif
                screen++;
            }

#endif
            if (t->frame_id > 0)
            {
                /* NOTE: here we should get the last frame */
                write_frame(t, H264dec_flush_frame(t), f_rec);
    #ifdef USE_DISPLAY
                winDisplay(t, H264dec_flush_frame(t));
    #endif
                frame_nums ++;
            }
            printf("ref frames num: %d.\n", t->ss.num_ref_frames);
            printf("width: %d.\n", (t->ss.pic_width_in_mbs_minus1 + 1) << 4);
            printf("height: %d.\n", (t->ss.pic_height_in_mbs_minus1 + 1) << 4);
            break;
        case DEC_STATE_SLICE:
            {
                if (t->output.poc >= 0)
                {
                    write_frame(t, &t->output, f_rec);
//for decoder PSNR
if(f_ref)
{
float psnr_y, psnr_u, psnr_v;
int size;
size = t->width*t->height;
if(ref_buf == NULL)
{
ref_buf = (uint8_t *)malloc(size);
}
if(ref_buf != NULL)
{
uint8_t *p;
p = t->output.Y[0];
fread(ref_buf, 1, size, f_ref);
psnr_y = dec_psnr(p, ref_buf, t->edged_stride, t->width, t->height, 0);

size >>= 2;
p = t->output.U;
fread(ref_buf, 1, size, f_ref);
psnr_u = dec_psnr(p, ref_buf, t->edged_stride_uv, t->width>>1, t->height>>1, 0);
p = t->output.V;
fread(ref_buf, 1, size, f_ref);
psnr_v = dec_psnr(p, ref_buf, t->edged_stride_uv, t->width>>1, t->height>>1, 0);
printf("%4d, %.2f, %.2f, %.2f\n", frame_num++, psnr_y, psnr_u, psnr_v);
if(ref_skip > 0)
{
fseek(f_ref, ref_skip*size*6, SEEK_CUR);
}
}
}
#ifdef USE_DISPLAY
                    winDisplay(t, &t->output);
#endif
                    frame_nums ++;                
                }
            };
            break;
        case DEC_STATE_CUSTOM_SET:
            {
                printf("used fast interpolate: %s.\n", t->flags & USE_FASTINTERPOLATE ? "yes" : "no");
            }
            break;
        default:
            /* do not care */
            break;
        }
    };

#ifndef CHIP_DM642
#ifdef _WIN32
    _ftime(&end);
    total_time = (float)(end.time - beg.time) + (float)(end.millitm - beg.millitm) / 1000;
#endif
    printf("fps: %.2ffps(total decode: %d frames).\n", (float)frame_nums / total_time, frame_nums);
#endif    
#ifdef CHIP_DM642
printf("fps: %.2ffps(total decode: %d frames).\n", (float)frame_nums / total_time, frame_nums);
#endif
    H264dec_close(t);
    fclose(src_file);
    if (f_rec)
        fclose(f_rec);
if (f_ref)
fclose(f_ref);
if(ref_buf != NULL)
free(ref_buf);
#ifdef USE_DISPLAY
    uninit_display();
#endif

    return 0;
}

void
help()
{
    //printf("Usage:\n"
    //    "\th264_decoder -d vmdata.264 [rec_path] [reference_path] [skip_num](to decode a 264 file.)\n");
printf("Usage:\n"
        "\th264_decoder -d vmdata.264 [decoded_file] [reference_file] [skip_num]\n"
"or\n"
"\th264_decoder -d vmdata.264 [decoded_file]");
}

int 
main(int argc, char* argv[])
{
    int32_t i;
    int32_t is_encode = 0;
    int32_t is_decode = 0;
    char* file_name;

    printf("VM_H264 ver: %d.%02d\n", H264_MAJOR, H264_MINOR);
    if (argc < 3)
    {
        help();
        return 0;
    }

    for (i = 1 ; i < 3 ; i ++)
    {
        if (strcmp(argv[i], "-d") == 0)
        {
            is_decode = 1;
        }
        else
        {
            file_name = argv[i];
        }
    }

    if (is_decode)
    {
        if (argc <= 3)
            rec_path[0] = 0;
        else
{
strcpy(rec_path, argv[3]);
}
if(argc <= 4)
{
ref_path[0] = 0;
}
else
{
strcpy(ref_path, argv[4]);
}
if(argc > 5)
{
ref_skip = atoi(argv[5]);
}
        return decode(file_name);
    }

    help();

    return -1;
}


本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
ppm图像格式
Linked list
C语言的格式化输入---总结
均值滤波器 ( Mean Filter ) C++ 实现
图像锐化算法 C++ 实现
视音频数据处理入门:RGB、YUV像素数据处理
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服