main.cpp

来自「SVC最新更新代码」· C++ 代码 · 共 773 行 · 第 1/3 页

CPP
773
字号
  {
    writeColorComponent( f.y, file, width,      height,      true );
    writeColorComponent( f.u, file, width >> 1, height >> 1, true );
    writeColorComponent( f.v, file, width >> 1, height >> 1, true );
  }
}


void 
print_usage_and_exit( int test, const char* name, const char* message = 0 )
{
  if( test )
  {
    if( message )
    {
      fprintf ( stderr, "\nERROR: %s\n", message );
    }
    fprintf (   stderr, "\nUsage: %s <win> <hin> <in> <wout> <hout> <out> [<method> [<t> [<skip> [<frms>]]]] [[-crop <args>] [-phase <args>] [-resample_mode <arg>]]\n\n", name );
    fprintf (   stderr, "  win     : input width  (luma samples)\n" );
    fprintf (   stderr, "  hin     : input height (luma samples)\n" );
    fprintf (   stderr, "  in      : input file\n" );
	  fprintf (   stderr, "  wout    : output width  (luma samples)\n" );
    fprintf (   stderr, "  hout    : output height (luma samples)\n" );
    fprintf (   stderr, "  out     : output file\n" );
    fprintf (   stderr, "\n--------------------------- OPTIONAL ---------------------------\n\n" );
	  fprintf (   stderr, "  method  : rescaling methods (default: 0)\n" );
	  fprintf (   stderr, "            0: normative upsampling\n" );
 	  fprintf (   stderr, "               non-normative downsampling (JVT-R006)\n" );
    fprintf (   stderr, "            1: dyadic upsampling (AVC 6-tap (1/2 pel) on odd samples\n" );
    fprintf (   stderr, "               dyadic downsampling (MPEG-4 downsampling filter)\n" );
    fprintf (   stderr, "            2: crop only\n" );
    fprintf (   stderr, "            3: upsampling (Three-lobed Lanczos-windowed sinc)\n" );
    fprintf (   stderr, "            4: upsampling (JVT-O041: AVC 6-tap 1/2 pel + bilinear 1/4 pel)\n" );
    fprintf (   stderr, "  t       : number of temporal downsampling stages (default: 0)\n" );
    fprintf (   stderr, "  skip    : number of frames to skip at start (default: 0)\n" );
    fprintf (   stderr, "  frms    : number of frames wanted in output file (default: max)\n" );
    fprintf (   stderr, "\n-------------------------- OVERLOADED --------------------------\n\n" );
    fprintf (   stderr, " -crop  <type> <params>\n");
    fprintf (   stderr, "   type   : 0: Sequence level,    1: Picture level\n");
    fprintf (   stderr, "   params : IF Sequence level: <x_orig> <y_orig> <crop_width> <crop_height>\n");
    fprintf (   stderr, "               cropping window origin (x,y) and dimensions (width and height)\n");
    fprintf (   stderr, "            IF Picture level: <crop_file>\n");
    fprintf (   stderr, "                 input file containing cropping window parameters.\n" );
    fprintf (   stderr, "                 each line has four integer numbers separated by a comma\n" );
    fprintf (   stderr, "                 as following: \"x_orig, y_orig, crop_width, crop_height\"\n");
    fprintf (   stderr, "                 for each picture to be resampled;\n" );
    fprintf (   stderr, "\n");
    fprintf (   stderr, " -phase <in_uv_ph_x> <in_uv_ph_y> <out_uv_ph_x> <out_uv_ph_y>\n");
    fprintf (   stderr, "   in_uv_ph_x : input  chroma phase shift in horizontal direction (default:-1)\n" );
    fprintf (   stderr, "   in_uv_ph_y : input  chroma phase shift in vertical   direction (default: 0)\n" );
    fprintf (   stderr, "   out_uv_ph_x: output chroma phase shift in horizontal direction (default:-1)\n" );
    fprintf (   stderr, "   out_uv_ph_y: output chroma phase shift in vertical   direction (default: 0)\n" );
    fprintf (   stderr, "\n");
    fprintf (   stderr, " -resample_mode <resample_mode>\n");
    fprintf (   stderr, "   resample_mode : resampling modes, present when method==0 (default: 0)\n" );
    fprintf (   stderr, "                 0: low-res-frm  = progressive, high-res-frm = progressive\n" );
    fprintf (   stderr, "                 1: low-res-frm  = interlaced,  high-res-frm = interlaced\n" );
    fprintf (   stderr, "                 2: low-res-frm  = progressive  (top-coincided)\n" );
    fprintf (   stderr, "                    high-res-frm = interlaced\n" );
    fprintf (   stderr, "                 3: low-res-frm  = progressive  (bot-coincided)\n" );
    fprintf (   stderr, "                    high-res-frm = interlaced\n" );
    fprintf (   stderr, "                 4: low-res-frm  = interlaced   (top-first)\n" );
    fprintf (   stderr, "                    high-res-frm = progressive  (double frm rate)\n" );
    fprintf (   stderr, "                 5: low-res-frm  = interlaced   (bot-first)\n" );
    fprintf (   stderr, "                    high-res-frm = progressive  (double frm rate)\n" );
    fprintf (   stderr, "\n\n");
    exit    (   1 );
  }
}


void 
updateCropParametersFromFile( ResizeParameters& cRP, FILE* cropFile, int resamplingMethod, char* name )
{
  int crop_x0;
  int crop_y0;
  int crop_w;
  int crop_h;
  if( fscanf( cropFile, "%d,%d,%d,%d\n", &crop_x0, &crop_y0, &crop_w, &crop_h ) != EOF )
  {
    cRP.m_iLeftFrmOffset      = crop_x0;
    cRP.m_iTopFrmOffset       = crop_y0;
    cRP.m_iScaledRefFrmWidth  = crop_w;
    cRP.m_iScaledRefFrmHeight = crop_h;
  }
  print_usage_and_exit( cRP.m_iLeftFrmOffset     & 1 || cRP.m_iTopFrmOffset       & 1,                                              name, "cropping parameters must be even values" );
  print_usage_and_exit( cRP.m_iScaledRefFrmWidth & 1 || cRP.m_iScaledRefFrmHeight & 1,                                              name, "cropping parameters must be even values" );
  print_usage_and_exit( resamplingMethod == 2 && cRP.m_iScaledRefFrmWidth  != min( cRP.m_iRefLayerFrmWidth,  cRP.m_iFrameWidth  ),  name, "crop dimensions must be the same as the minimal dimensions" );
  print_usage_and_exit( resamplingMethod == 2 && cRP.m_iScaledRefFrmHeight != min( cRP.m_iRefLayerFrmHeight, cRP.m_iFrameHeight ),  name, "crop dimensions must be the same as the minimal dimensions" );
  print_usage_and_exit( cRP.m_iScaledRefFrmWidth  > max( cRP.m_iRefLayerFrmWidth,  cRP.m_iFrameWidth  ),                            name, "wrong crop window size" );
  print_usage_and_exit( cRP.m_iScaledRefFrmHeight > max( cRP.m_iRefLayerFrmHeight, cRP.m_iFrameHeight ),                            name, "wrong crop window size" );
  print_usage_and_exit( cRP.m_iScaledRefFrmWidth  < min( cRP.m_iRefLayerFrmWidth,  cRP.m_iFrameWidth  ),                            name, "wrong crop window size" );
  print_usage_and_exit( cRP.m_iScaledRefFrmHeight < min( cRP.m_iRefLayerFrmHeight, cRP.m_iFrameHeight ),                            name, "wrong crop window size" );
  print_usage_and_exit( cRP.m_iLeftFrmOffset + cRP.m_iScaledRefFrmWidth  > max( cRP.m_iRefLayerFrmWidth,  cRP.m_iFrameWidth  ),     name, "wrong crop window size and origin" );
  print_usage_and_exit( cRP.m_iTopFrmOffset  + cRP.m_iScaledRefFrmHeight > max( cRP.m_iRefLayerFrmHeight, cRP.m_iFrameHeight ),     name, "wrong crop window size and origin" );
}


void
resampleFrame( YuvFrame&          rcFrame, 
               DownConvert&       rcDownConvert,
               ResizeParameters&  rcRP,
               int                resamplingMethod,
               int                resamplingMode,
               bool               resampling,
               bool               upsampling,
               bool               bSecondInputFrame )
{
  //===== cropping only =====
  if( ! resampling && ! upsampling )
  {
    rcDownConvert.cropping              ( rcFrame.y.data,  rcFrame.y.stride, rcFrame.u.data,  rcFrame.u.stride, rcFrame.v.data,  rcFrame.v.stride, &rcRP );
    return;
  }
  
  //===== upsampling ====
  if( upsampling )
  {
    ResizeParameters cRP = rcRP;
    {
      Int iRefVerMbShift        = ( cRP.m_bRefLayerFrameMbsOnlyFlag ? 4 : 5 );
      Int iScaledVerShift       = ( cRP.m_bFrameMbsOnlyFlag         ? 1 : 2 );
      Int iHorDiv               = ( cRP.m_iRefLayerFrmWidth    <<               1 );
      Int iVerDiv               = ( cRP.m_iRefLayerFrmHeight   << iScaledVerShift );
      Int iRefFrmW              = ( ( cRP.m_iRefLayerFrmWidth   + ( 1 <<               4 ) - 1 ) >>               4 ) <<               4;  // round to next multiple of 16
      Int iRefFrmH              = ( ( cRP.m_iRefLayerFrmHeight  + ( 1 <<  iRefVerMbShift ) - 1 ) >>  iRefVerMbShift ) <<  iRefVerMbShift;  // round to next multiple of 16 or 32 (for interlaced)
      Int iScaledRefFrmW        = ( ( cRP.m_iScaledRefFrmWidth  * iRefFrmW + ( iHorDiv >> 1 ) ) / iHorDiv ) <<               1;  // scale and round to next multiple of  2
      Int iScaledRefFrmH        = ( ( cRP.m_iScaledRefFrmHeight * iRefFrmH + ( iVerDiv >> 1 ) ) / iVerDiv ) << iScaledVerShift;  // scale and round to next multiple of  2 or  4 (for interlaced)
      cRP.m_iRefLayerFrmWidth   = iRefFrmW;
      cRP.m_iRefLayerFrmHeight  = iRefFrmH;
      cRP.m_iScaledRefFrmWidth  = iScaledRefFrmW;
      cRP.m_iScaledRefFrmHeight = iScaledRefFrmH;
    }
    if( resamplingMethod == 1 )
    {
      rcDownConvert.upsamplingDyadic    ( rcFrame.y.data,  rcFrame.y.stride, rcFrame.u.data,  rcFrame.u.stride, rcFrame.v.data,  rcFrame.v.stride, &rcRP );
      return;
    }
    if( resamplingMethod == 3 )
    {
      rcDownConvert.upsamplingLanczos   ( rcFrame.y.data,  rcFrame.y.stride, rcFrame.u.data,  rcFrame.u.stride, rcFrame.v.data,  rcFrame.v.stride, &cRP );
      return;
    }
    if( resamplingMethod == 4 )
    {
      rcDownConvert.upsampling6tapBilin ( rcFrame.y.data,  rcFrame.y.stride, rcFrame.u.data,  rcFrame.u.stride, rcFrame.v.data,  rcFrame.v.stride, &cRP );
      return;
    }
    if( resamplingMode < 4 )
    {
      rcDownConvert.upsamplingSVC       ( rcFrame.y.data,  rcFrame.y.stride, rcFrame.u.data,  rcFrame.u.stride, rcFrame.v.data,  rcFrame.v.stride, &cRP, resamplingMode == 3 );
      return;
    }
    {
      duplicateFrame( rcFrame );
      cRP.m_bRefLayerBotFieldFlag  = ( resamplingMode == 5 );
      rcDownConvert.upsamplingSVC    ( rcFrame.y.data,  rcFrame.y.stride, rcFrame.u.data,  rcFrame.u.stride, rcFrame.v.data,  rcFrame.v.stride, &cRP );
      cRP.m_bRefLayerBotFieldFlag  = ( resamplingMode != 5 );
      rcDownConvert.upsamplingSVC    ( rcFrame.y.data2, rcFrame.y.stride, rcFrame.u.data2, rcFrame.u.stride, rcFrame.v.data2, rcFrame.v.stride, &cRP );
      return;
    }
  }

  //===== downsampling =====
  ResizeParameters cRP = rcRP;
  {
    Int iRefVerMbShift        = ( cRP.m_bRefLayerFrameMbsOnlyFlag ? 4 : 5 );
    Int iScaledVerShift       = ( cRP.m_bFrameMbsOnlyFlag         ? 1 : 2 );
    Int iHorDiv               = ( cRP.m_iFrameWidth    <<               1 );
    Int iVerDiv               = ( cRP.m_iFrameHeight   << iScaledVerShift );
    Int iRefFrmW              = ( ( cRP.m_iFrameWidth   + ( 1 <<               4 ) - 1 ) >>               4 ) <<               4;        // round to next multiple of 16
    Int iRefFrmH              = ( ( cRP.m_iFrameHeight  + ( 1 <<  iRefVerMbShift ) - 1 ) >>  iRefVerMbShift ) <<  iRefVerMbShift;        // round to next multiple of 16 or 32 (for interlaced)
    Int iScaledRefFrmW        = ( ( cRP.m_iScaledRefFrmWidth  * iRefFrmW + ( iHorDiv >> 1 ) ) / iHorDiv ) <<               1;  // scale and round to next multiple of  2
    Int iScaledRefFrmH        = ( ( cRP.m_iScaledRefFrmHeight * iRefFrmH + ( iVerDiv >> 1 ) ) / iVerDiv ) << iScaledVerShift;  // scale and round to next multiple of  2 or  4 (for interlaced)
    cRP.m_iFrameWidth         = iRefFrmW;
    cRP.m_iFrameHeight        = iRefFrmH;
    cRP.m_iScaledRefFrmWidth  = iScaledRefFrmW;
    cRP.m_iScaledRefFrmHeight = iScaledRefFrmH;
  }
  if( resamplingMethod == 1 )
  {
    rcDownConvert.downsamplingDyadic    ( rcFrame.y.data,  rcFrame.y.stride, rcFrame.u.data,  rcFrame.u.stride, rcFrame.v.data,  rcFrame.v.stride, &rcRP );
    return;
  }
  if( resamplingMode < 4 )
  {
    rcDownConvert.downsamplingSVC       ( rcFrame.y.data,  rcFrame.y.stride, rcFrame.u.data,  rcFrame.u.stride, rcFrame.v.data,  rcFrame.v.stride, &cRP, resamplingMode == 3 );
    return;
  }
  if( ! bSecondInputFrame )
  {
    cRP.m_bRefLayerBotFieldFlag  = ( resamplingMode == 5 );
    rcDownConvert.downsamplingSVC  ( rcFrame.y.data,  rcFrame.y.stride, rcFrame.u.data,  rcFrame.u.stride, rcFrame.v.data,  rcFrame.v.stride, &cRP );
  }
  else
  {
    cRP.m_bRefLayerBotFieldFlag  = ( resamplingMode == 4 );
    rcDownConvert.downsamplingSVC  ( rcFrame.y.data2, rcFrame.y.stride, rcFrame.u.data2, rcFrame.u.stride, rcFrame.v.data2, rcFrame.v.stride, &cRP );
    combineTopAndBottomInFrame     ( rcFrame, resamplingMode == 4 );
  }
}



int
main( int argc, char *argv[] )
{
  //===== set standard resize parameters =====
  ResizeParameters cRP;
  cRP.m_bRefLayerFrameMbsOnlyFlag   = true;
  cRP.m_bFrameMbsOnlyFlag           = true;
  cRP.m_bRefLayerFieldPicFlag       = false;
  cRP.m_bFieldPicFlag               = false;
  cRP.m_bRefLayerBotFieldFlag       = false;
  cRP.m_bBotFieldFlag               = false;
  cRP.m_bRefLayerIsMbAffFrame       = false;
  cRP.m_bIsMbAffFrame               = false;
  cRP.m_iRefLayerChromaPhaseX       = -1;
  cRP.m_iRefLayerChromaPhaseY       = 0;
  cRP.m_iChromaPhaseX               = -1;
  cRP.m_iChromaPhaseY               = 0;
  cRP.m_iRefLayerFrmWidth           = 0;
  cRP.m_iRefLayerFrmHeight          = 0;
  cRP.m_iScaledRefFrmWidth          = 0;
  cRP.m_iScaledRefFrmHeight         = 0;
  cRP.m_iFrameWidth                 = 0;
  cRP.m_iFrameHeight                = 0;
  cRP.m_iLeftFrmOffset              = 0;
  cRP.m_iTopFrmOffset               = 0;
  cRP.m_iExtendedSpatialScalability = 0;
  cRP.m_iLevelIdc                   = 0;

  //===== init parameters =====
  FILE* inputFile                   = 0;
  FILE* outputFile                  = 0;
  FILE* croppingParametersFile      = 0;
  int   resamplingMethod            = 0;
  int   resamplingMode              = 0;
  bool  croppingInitialized         = false;
  bool  phaseInitialized            = false;
  bool  methodInitialized           = false;
  bool  resampling                  = false;
  bool  upsampling                  = false;
  int   numSpatialDyadicStages      = 0;
  int   skipBetween                 = 0;
  int   skipAtStart                 = 0;
  int   maxNumOutputFrames          = 0;


  //===== read input parameters =====
  print_usage_and_exit( ( argc < 7 || argc > 24 ), argv[0], "wrong number of arguments" );
  cRP.m_iRefLayerFrmWidth   = atoi  ( argv[1] );
  cRP.m_iRefLayerFrmHeight  = atoi  ( argv[2] );
  inputFile                 = fopen ( argv[3], "rb" );
  cRP.m_iFrameWidth         = atoi  ( argv[4] );
  cRP.m_iFrameHeight        = atoi  ( argv[5] );
  outputFile                = fopen ( argv[6], "wb" );
  print_usage_and_exit( ! inputFile,  argv[0], "failed to open input file" );

⌨️ 快捷键说明

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