예제 #1
0
파일: opts.c 프로젝트: NUIM-BCL/QobiScheme
/*===========================================================================*
 *
 * Tune_Init
 *
 *     Do any setup needed before coding stream
 *
 * RETURNS:	nothing
 *
 * SIDE EFFECTS:  varies
 *
 *===========================================================================*/
void Tune_Init()
{
  int i;

  /* Just check for each, and do whats needed */
  if (collect_quant) {
    if (!pureDCT) {
      pureDCT = TRUE;
      init_idctref();
      init_fdct();
    }
    fprintf(collect_quant_fp, "# %s\n", outputFileName);
    fprintf(collect_quant_fp, "#");
    for (i=0; i<64; i++) 
      fprintf(collect_quant_fp, " %d", qtable[i]);
    fprintf(collect_quant_fp, "\n#");
    for (i=0; i<64; i++) 
      fprintf(collect_quant_fp, " %d", niqtable[i]);
    fprintf(collect_quant_fp, "\n# %d %d %d\n\n", 
	    GetIQScale(), GetPQScale(), GetBQScale());
    
  }

  if (DoLaplace) {
    if (!pureDCT) {
      pureDCT = TRUE;
      init_idctref();
      init_fdct();
    }
    decodeRefFrames = TRUE;
    printSNR = TRUE;
  }
    
}
예제 #2
0
/*===========================================================================*
 *
 * GenPFrame
 *
 *	generate a P-frame from previous frame, adding the result to the
 *	given bit bucket
 *
 * RETURNS:	frame appended to bb
 *
 * SIDE EFFECTS:    none
 *
 *===========================================================================*/
void
GenPFrame(BitBucket *bb,
          MpegFrame *current,
          MpegFrame *prev)
{
  extern int **pmvHistogram;
  FlatBlock fba[6], fb[6];
  Block	dec[6];
  int32 y_dc_pred, cr_dc_pred, cb_dc_pred;
  int x, y;
  int	motionX = 0, motionY = 0;
  int	oldMotionX = 0, oldMotionY = 0;
  int	offsetX, offsetY;
  int	tempX, tempY;
  int	motionXrem, motionXquot;
  int	motionYrem, motionYquot;
  int	pattern;
  int	mbAddrInc = 1;
  boolean	useMotion;
  int numIBlocks = 0;
  int	numPBlocks = 0;
  int	numSkipped = 0;
  int	numIBits = 0;
  int numPBits = 0;
  int totalBits;
  int	totalFrameBits;
  int32    startTime, endTime;
  int	lastBlockX, lastBlockY;
  int	lastX, lastY;
  int	fy, fx;
  LumBlock currentBlock;
  register int ix, iy;
  int	mbAddress;
  int slicePos;
  register int index;
  float   snr[3], psnr[3];
  int QScale;
  BlockMV *info;
  int bitstreamMode, newQScale;
  int rc_blockStart = 0;
  boolean overflowChange = FALSE;
  int     overflowValue  = 0;


  if (collect_quant) {fprintf(collect_quant_fp, "# P\n");}
  if (dct==NULL) AllocDctBlocks();
  numFrames++;
  totalFrameBits = bb->cumulativeBits;
  startTime = time_elapsed();

  DBG_PRINT(("Generating pframe\n"));

  QScale = GetPQScale();
  /*   bit allocation for rate control purposes */
  bitstreamMode = getRateMode();
  if (bitstreamMode == FIXED_RATE) {
    targetRateControl(current);
  }
 
  Mhead_GenPictureHeader(bb, P_FRAME, current->id, fCodeP);
  /* Check for Qscale change */  
  if (specificsOn) {
    /* Set a Qscale for this frame? */
    newQScale = SpecLookup(current->id, 0, 0 /* junk */, &info /*junk*/, QScale);
    if (newQScale != -1) {
      QScale = newQScale;
    }
    /* Set for slice? */
    newQScale = SpecLookup(current->id, 1, 1, &info /*junk*/, QScale);
    if (newQScale != -1) {
      QScale = newQScale;
    }
  }

  DBG_PRINT(("Slice Header\n"));
  Mhead_GenSliceHeader(bb, 1, QScale, NULL, 0);

  if ( referenceFrame == DECODED_FRAME ) {
    Frame_AllocDecoded(current, TRUE);
  } else if ( printSNR ) {
    Frame_AllocDecoded(current, FALSE);
  }

  /* don't do dct on blocks yet */
  Frame_AllocBlocks(current);
  BlockifyFrame(current);

  /* for I-blocks */
  y_dc_pred = cr_dc_pred = cb_dc_pred = 128;

  totalBits = bb->cumulativeBits;

  if ( (! pixelFullSearch) && (! prev->halfComputed) ) {
    ComputeHalfPixelData(prev);
  }

  lastBlockX = Fsize_x>>3;
  lastBlockY = Fsize_y>>3;
  lastX = lastBlockX-2;
  lastY = lastBlockY-2;
  mbAddress = 0;

  /* First loop though finding motion/not and DCTing */
  for (y = 0; y < lastBlockY; y += 2) {
    for (x = 0; x < lastBlockX; x += 2) {
      /* compute currentBlock */
      BLOCK_TO_FRAME_COORD(y, x, fy, fx);
      for ( iy = 0; iy < 16; iy++ ) {
	for ( ix = 0; ix < 16; ix++ ) {
	  currentBlock[iy][ix] = (int16)current->orig_y[fy+iy][fx+ix];
	}
      }

      /* See if we have a cached answer */
      if (specificsOn) {
	(void) SpecLookup(current->id, 2, mbAddress, &info, QScale);
	if (info != (BlockMV*)NULL) {
	  if (info->typ == TYP_SKIP) {
	    motionX = motionY = 0;
	    useMotion = TRUE;
	    goto no_search;
	  } else {		/* assume P, since we're a P frame.... */
	    motionX = info->fx;
	    motionY = info->fy;
	    useMotion = TRUE;
	    goto no_search;
	  }}
	/* if unspecified, just look */
      }

      /* see if we should use motion vectors, and if so, what those
       * vectors should be
       */
      if ( ZeroMotionSufficient(currentBlock, prev, y, x) ) {
	motionX = 0;
	motionY = 0;
	useMotion = TRUE;
      } else {
	useMotion = PMotionSearch(currentBlock, prev, y, x,
				  &motionY, &motionX);
	if ( useMotion ) {
	  if ( ZeroMotionBetter(currentBlock, prev, y, x, motionY,
				motionX) ) {
	    motionX = 0;
	    motionY = 0;
	  }
	  if (IntraPBAllowed) 
	    useMotion = (! DoIntraCode(currentBlock, prev, y, x,
				       motionY, motionX));
	}
      }

    no_search:

      dct_data[y][x].useMotion = useMotion;
      if ( ! useMotion ) {
	/* output I-block inside a P-frame */
	numIBlocks++;

	/* calculate forward dct's */
	if (collect_quant && (collect_quant_detailed & 1)) fprintf(collect_quant_fp, "l\n");
	mp_fwd_dct_block2(current->y_blocks[y][x], dct[y][x]);
	mp_fwd_dct_block2(current->y_blocks[y][x+1], dct[y][x+1]);
	mp_fwd_dct_block2(current->y_blocks[y+1][x], dct[y+1][x]);
	mp_fwd_dct_block2(current->y_blocks[y+1][x+1], dct[y+1][x+1]);
	if (collect_quant && (collect_quant_detailed & 1)) fprintf(collect_quant_fp, "c\n");
	mp_fwd_dct_block2(current->cb_blocks[y>>1][x>>1], dctb[y>>1][x>>1]);
	mp_fwd_dct_block2(current->cr_blocks[y>>1][x>>1], dctr[y>>1][x>>1]);

      } else {
	/* USE MOTION VECTORS */
	numPBlocks++;

	pattern = 63;
	ComputeDiffDCTs(current, prev, y, x, motionY, motionX,
			&pattern);

	assert(motionX+searchRangeP+1 >= 0);
	assert(motionY+searchRangeP+1 >= 0);

#ifdef BLEAH
	if ( motionX+searchRangeP+1 > 2*searchRangeP+2 )
	  {
	    fprintf(stdout, "motionX = %d, searchRangeP = %d\n",
		    motionX, searchRangeP);
	  }
#endif

	if ( computeMVHist ) {
	  assert(motionX+searchRangeP+1 <= 2*searchRangeP+2);
	  assert(motionY+searchRangeP+1 <= 2*searchRangeP+2);
	  pmvHistogram[motionX+searchRangeP+1][motionY+searchRangeP+1]++;
	}
	/* Save specs for next loops */
	dct_data[y][x].pattern = pattern;
	dct_data[y][x].fmotionX = motionX;
	dct_data[y][x].fmotionY = motionY;

      }
      mbAddress++;
    }}