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

📄 tmp4.cpp

📁 mpeg4编解码器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/******************************************************** * Some code. Copyright (C) 2003 by Pascal Massimino.   * * All Rights Reserved.      (http://skal.planet-d.net) * * For Educational/Academic use ONLY. See 'LICENSE.TXT'.* ********************************************************//* * MPEG4 codec front end example * ********************************************************/#include "skl_utils.h"#include "skl_syst/skl_mpg4.h"#include "skl_syst/skl_dyn_load.h"#include "skl_syst/skl_exception.h"#include "skl_syst/skl_ptimer.h"#include "skl_syst/skl_mem_trc.h"#include "skl_syst/skl_dsp.h"#include "skl_syst/skl_cpu_specs.h"#include "skl_2d/skl_btm.h"#include "skl_2d/skl_window.h"#include <math.h>//////////////////////////////////////////////////////////// DLL declaration for codecs//////////////////////////////////////////////////////////    // plug-in to use for codec#ifndef _WINDOWS#define SKL_MP4_DLL_NAME "libskl_mp4"#else#define SKL_MP4_DLL_NAME "skl_drv_mpg"#endifSKL_DYN_LIBRARY(SKL_MP4_DLL, SKL_MP4_DLL_NAME, 0100);    // DLL symbols to mapSKL_MP4_NEW_DEC MP4_New_Decoder;SKL_MP4_DELETE_DEC MP4_Delete_Decoder;SKL_MP4_NEW_ENC MP4_New_Encoder;SKL_MP4_DELETE_ENC MP4_Delete_Encoder;////////////////////////////////////////////////////////////// -- global params////////////////////////////////////////////////////////////#define VERSION 0.23fint Save, Show, With_Slices, From_Mem, Trace_Mem, MPEG12;int To_RGB;int Nb_Frames, Skip_Frames;int Streaming;int Sequence_Codes;long Jump_To;int Global_Q;int Interlace_DCT;     // 0=disabled, 1=decide, 2=forceint Interlace_Field;   // 0=disabled, 1=decide, 2=forceint Sub_Pixel;float dQuant_Amp;float Lambda;int Inter_Thresh;int Use_Trellis;int Intra_Max;int Inter4V_Probing, Field_Pred_Probing;int SAD_Skip_Limit;int SAD_Intra_Limit;int Search_Metric;int MV_Size;int Enc_Buf_Size;int Use_GMC;int Hi_Mem;int GMC_Accuracy;int Use_Reduced;int Quant_Type;int Bit_Rate;float FPS;int System_Stream;    // 0: none, 1:AVI, 2:MPGint Search_Method;int Intra_Limit;int Delay;int VTrace, Debug, ADebug, Quiet;int Show_PSNR;int Transfer_Type;int Edge_Detect;int YUV_Input, YUV_W, YUV_H;SKL_CST_STRING In_File, Out_File, Pass_File, Ref_YUV_File;SKL_CPU_FEATURE Cpu;SKL_IMG_DSP Img_Dsp = {0};SKL_YUV_DSP YUV_Dsp = {0};int Pass_Nb;float Pass_RF;const char *Custom_Matrix = 0;SKL_MEM_I *All_Mem = 0;   //  memory pool////////////////////////////////////////////////////////////// YUV/PGM input and output////////////////////////////////////////////////////////////static void YUV_Out(SKL_MP4_PIC *Pic){  SKL_BYTE *Src = Pic->Y;  int k = Pic->Height;  while(k-->0) {    fwrite(Src, Pic->Width, 1, stdout);    Src += Pic->BpS;  }  Src = Pic->U;  for(k = Pic->Height/2; k>0; --k) {    fwrite(Src, Pic->Width/2, 1, stdout);    Src += Pic->BpS;  }  Src = Pic->V;  for(k = Pic->Height/2; k>0; --k) {      fwrite(Src, Pic->Width/2, 1, stdout);    Src += Pic->BpS;  }}static void PGM_Out(SKL_MP4_PIC *Pic){  fprintf(stdout, "P5\n\n%d %d\n255\n", Pic->Width, Pic->Height*3/2 );  SKL_BYTE *Src = Pic->Y;  int k = Pic->Height;  while(k-->0) {    fwrite(Src, Pic->Width, 1, stdout);    Src += Pic->BpS;  }  k = Pic->Height/2;  SKL_BYTE *USrc = Pic->U;  SKL_BYTE *VSrc = Pic->V;  while(k-->0) {    fwrite(USrc, Pic->Width/2, 1, stdout);    fwrite(VSrc, Pic->Width/2, 1, stdout);    USrc += Pic->BpS;    VSrc += Pic->BpS;  }}static int PGM_In(SKL_MP4_ENC *Enc, FILE *In, int *W, int *H, double Time){  const SKL_MP4_PIC *Pic;  SKL_BYTE *Dst;  int k;  if (!YUV_Input)  {    int Tmp;    if (fscanf(In, "P5\n%d %d\n%d", W, H, &Tmp )!=3)      return 0;    if (Tmp!=255 || *W<=0 || *H<=0)      return 0;    fgetc(In);  // skips the '\n'    Pic = Enc->Prepare_Next_Frame(*W, (*H)*2/3);    if (Pic==0) return 0;    for(Dst = Pic->Y, k=0; k<Pic->Height; ++k) {      if (fread(Dst, Pic->Width, 1, In)!=1) return 0;      Dst += Pic->BpS;    }    SKL_BYTE *DstU = Pic->U;    SKL_BYTE *DstV = Pic->V;    for(k=0; k<Pic->Height/2; ++k) {      if (fread(DstU, Pic->Width/2, 1, In)!=1) return 0;      if (fread(DstV, Pic->Width/2, 1, In)!=1) return 0;      DstU += Pic->BpS;      DstV += Pic->BpS;    }  }  else {    *W = YUV_W;    *H = YUV_H * 3/2;    Pic = Enc->Prepare_Next_Frame(YUV_W, YUV_H);    if (Pic==0) return 0;        for(Dst = Pic->Y, k=0; k<Pic->Height; ++k) {      if (fread(Dst, Pic->Width, 1, In)!=1) return 0;      Dst += Pic->BpS;    }    for(Dst = Pic->U, k=0; k<Pic->Height/2; ++k) {      if (fread(Dst, Pic->Width/2, 1, In)!=1) return 0;      Dst += Pic->BpS;    }    for(Dst = Pic->V, k=0; k<Pic->Height/2; ++k) {      if (fread(Dst, Pic->Width/2, 1, In)!=1) return 0;      Dst += Pic->BpS;    }  }  if (Edge_Detect==1) {    if (Img_Dsp.Name==0) Skl_Init_Img_DSP(&Img_Dsp, Cpu);    SKL_BYTE *Dst = Pic->Y;    const int BpS = Pic->BpS;    int x, y;    for(y=0; y<Pic->Height/16; y++)      for(x=0; x<Pic->Width/16; x++)        Img_Dsp.Grad2_18x18_To_8x8(Dst+(x+y*BpS)*8, BpS, Dst+(x+y*BpS)*16, BpS);  }  return 1;}////////////////////////////////////////////////////////////// YUV => RGB and display////////////////////////////////////////////////////////////static void YUV_To_RGB32(SKL_BTM &Btm, const SKL_MP4_PIC &Pic){  if (YUV_Dsp.Name==0) {    Skl_Init_YUV_DSP(&YUV_Dsp, Cpu);    YUV_Dsp.Init(Transfer_Type);  }  SKL_BYTE *Dst = Btm.Lock();  const int BpS = Btm.BpS();  if (Btm.Format()==0x40888)    YUV_Dsp.YUV_TO_RGB32(Dst, BpS, Pic.Y, Pic.U, Pic.V, Pic.BpS, Pic.Width, Pic.Height);  else if (Btm.Format()==0x20565)    YUV_Dsp.YUV_TO_RGB565(Dst, BpS, Pic.Y, Pic.U, Pic.V, Pic.BpS, Pic.Width, Pic.Height);  YUV_Dsp.Switch_Off();  /* else: not supported yet */  Btm.Unlock();}static void Deal_With_Pic(SKL_MP4_PIC &Pic, int Nb){  int W   = Pic.Width;  int H   = Pic.Height;  int BpS = Pic.BpS;  SKL_BYTE *Src = Pic.Y;  if (VTrace==2) {    Src = Pic.U; H /= 2;  }  else if (VTrace==3) {     Src = Pic.Y - 16 - 16*BpS;    W += 2*16;    H = H+16+16 + H/2+8+8;   }  if (Save==2) PGM_Out(&Pic);  else if (Save==3) YUV_Out(&Pic);  if (Show && VTrace==0) {#ifndef SKL_NO_VIDEO    if (To_RGB==0x40888) {      SKL_WINDOW *Vid = Sku_Get_Video(W, H, 0x40888);      YUV_To_RGB32(*Vid, Pic);      if (Save==1) Sku_Dump_Pic(Vid);    }    else if (To_RGB==0x20565) {      SKL_WINDOW *Vid = Sku_Get_Video(W, H, 0x20565);      YUV_To_RGB32(*Vid, Pic);      if (Save==1) Sku_Dump_Pic(Vid);    }#endif  }  else if (Show||Save) {    static SKL_CMAP_X Cmap;    static int Ok = 0;    if (!Ok) {      Cmap.Ramp( SKL_COLOR_BLACK, SKL_COLOR_WHITE );      Ok = 1;    }    SKL_BTM Btm(All_Mem);    Btm.Set_Virtual(W, H, 0x10000, Src, BpS, &Cmap);#ifndef SKL_NO_VIDEO    if (Show) Sku_Show_Pic(&Btm);#endif    if (Save==1) Sku_Dump_Pic(&Btm);  }}////////////////////////////////////////////////////////////// Decoding////////////////////////////////////////////////////////////struct PSNR_INFOS{   double     PSNR_Y,PSNR_U,PSNR_V,PSNR_A;  double     pY,    pU,    pV,    pA;  size_t Size;  int Cnt;  SKL_BYTE *Y, *U, *V;  FILE *_File;  void Store(SKL_BYTE *Dst, const SKL_BYTE *Src, int W, int H, int BpS) {    W = (W+7) & ~7;    for(int y=0; y<H; ++y, Src+=BpS, Dst+=BpS)      SKL_MEMCPY(Dst, Src, W);  }  void Load(SKL_BYTE *Dst, SKL_CST_STRING YUV_In, int W, int H, int BpS) {    if (_File==0) {      _File = fopen( YUV_In, "rb" );      if (_File==0)        Skl_Throw( SKL_EXCEPTION( "Can't open Reference YUV file\n" ) );    }    const int W_Padded = (W+7) & ~7;    for(int y=0; y<H; ++y, Dst+=BpS) {      fread(Dst, W, 1, _File);      for(int x=W; x<W_Padded; ++x) Dst[x] = 0;    }  }  SKL_UINT32 Get_SSE(SKL_BYTE *Ref, const SKL_BYTE *Src, int W, int H, int BpS) {    SKL_UINT32 SSE = 0;    int x,y;    for(y=0; (y+16)<=H; y+=16) {      for(x=0; (x+16)<=W; x+=16) SSE += Img_Dsp.SSD_16x16(Ref+x,Src+x,BpS);      if ((x+8)<=W) SSE += Img_Dsp.SSD_8x8(Ref+x,Src+x,BpS);      Src += 16*BpS;      Ref += 16*BpS;    }    if ((y+8)<=H)      for(x=0; x<W; x+=8) SSE += Img_Dsp.SSD_8x8(Ref+x,Src+x,BpS);    return SSE;  }  double Compute_PSNR(int Val, int Size) {    return Val>0. ? -4.3429448*log( 1.*Val / (255.*255.*Size) ) : 0.;  }  void Check(int W, int H, int BpS) {    const size_t Needed = BpS*H + 2*(BpS/2)*(H/2);    if (Y==0 || Size!=Needed) {      Clear();      Y = (SKL_BYTE*)All_Mem->New(Needed);      U = Y + BpS*H;      V = U + BpS/2;      Size = Needed;    }    if (Img_Dsp.Name==0) Skl_Init_Img_DSP(&Img_Dsp, Cpu);  }  void Clear() { if (Y!=0) { All_Mem->Delete( Y, Size ); Y=0; Size=0; } }  void Print_Infos() {    SKL_ASSERT(Cnt>0);    if (Cnt==1) printf( "#frm  \tY      U      V      All   avrg:Y      U      V      All\n" );    printf( "%d  \t%.3f %.3f %.3f %.3f    \t%.3f %.3f %.3f %.3f\n",       Cnt,       pY, pU, pV, pA,      PSNR_Y/Cnt,      PSNR_U/Cnt,      PSNR_V/Cnt,      PSNR_A/Cnt);  }  PSNR_INFOS() {     Size = 0;     Y=U=V=0;    Cnt = 0;     PSNR_Y = PSNR_U = PSNR_V = PSNR_A = 0.;    _File = 0;  }  ~PSNR_INFOS() {    if (_File!=0) fclose(_File);    Clear();  }};////////////////////////////////////////////////////////////// compare PSNR against ref file////////////////////////////////////////////////////////////static void Compare_PSNR_External(const SKL_MP4_PIC *Pic, PSNR_INFOS *I){  SKL_ASSERT(Ref_YUV_File!=0);  I->Check(Pic->Width, Pic->Height, Pic->BpS);  I->Load(I->Y, Ref_YUV_File, Pic->Width,   Pic->Height,   Pic->BpS);  I->Load(I->U, Ref_YUV_File, Pic->Width/2, Pic->Height/2, Pic->BpS);  I->Load(I->V, Ref_YUV_File, Pic->Width/2, Pic->Height/2, Pic->BpS);  SKL_UINT32 SSE_Y = I->Get_SSE(I->Y, Pic->Y, Pic->Width,   Pic->Height,   Pic->BpS);  SKL_UINT32 SSE_U = I->Get_SSE(I->U, Pic->U, Pic->Width/2, Pic->Height/2, Pic->BpS);  SKL_UINT32 SSE_V = I->Get_SSE(I->V, Pic->V, Pic->Width/2, Pic->Height/2, Pic->BpS);  Img_Dsp.Switch_Off();  I->PSNR_Y += I->pY = I->Compute_PSNR(SSE_Y, Pic->Width*Pic->Height);  I->PSNR_U += I->pU = I->Compute_PSNR(SSE_U, Pic->Width*Pic->Height/4);  I->PSNR_V += I->pV = I->Compute_PSNR(SSE_V, Pic->Width*Pic->Height/4);  I->PSNR_A += I->pA = I->Compute_PSNR(SSE_Y+SSE_U+SSE_V, 3*Pic->Width*Pic->Height/2);  I->Cnt++;  if (I->Cnt==10000) {      // reset every ~10000 frames, to avoid overflow...      // (yeah, I know, we won't end up with the real PSNR :)    I->PSNR_Y /= I->Cnt;    I->PSNR_U /= I->Cnt;    I->PSNR_V /= I->Cnt;    I->PSNR_A /= I->Cnt;    I->Cnt = 1;  }  I->Print_Infos();}////////////////////////////////////////////////////////////// simple empty example of slicer hook////////////////////////////////////////////////////////////static void Display_Slice(const SKL_MP4_PIC *Pic, int y, int Height, SKL_ANY Data){  printf( "Slice y=%3d/%3d (height=%d)\n", y, Pic->Height, Height );}////////////////////////////////////////////////////////////// naive AVI parsing////////////////////////////////////////////////////////////static SKL_UINT32 Get32b_LE(FILE *f) {  return ((SKL_UINT32)fgetc(f)<<0) | (fgetc(f)<<8) | (fgetc(f)<<24) | (fgetc(f)<<24);}static SKL_UINT16 Get16b_LE(FILE *f) {  return (fgetc(f)<<0) | (fgetc(f)<<8);}static SKL_UINT32 TwoCC(const char * const S) {  return (S[0]<<0) | (S[1]<<8);}static SKL_UINT32 FourCC(const char * const S) {  return (S[0]<<24) | (S[1]<<16) | (S[2]<<8) | (S[3]<<0);}static int Locate_Marker(SKL_UINT32 Marker, FILE *f) {

⌨️ 快捷键说明

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