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

📄 bw.c

📁 视频601芯片的驱动源码,你可以完全掌控该芯片了,对于其它多媒体芯片的设计具有参考价值
💻 C
📖 第 1 页 / 共 2 页
字号:
  for (bn=0; bn<NBLOCKS; bn++) {
    bw = bw_cur[bn];
    if (noisebw && (bw < bw_noise[bn]))
      bw = bw_noise[bn];
    bw_fixed =  (unsigned short) FLOAT2HBW(bw);
    if (bw_fixed > 0) {
      bwr = 1.0f/bw;
      bwr_fixed =  (unsigned short) FLOAT2HBWI(bwr);
    }
    else
      bwr_fixed = 0;
    out->BWCoeff[bn]  = bw_fixed;
    out->RBWCoeff[bn] = bwr_fixed;
    out->FieldDecim = 0;
  }

#if 0
  /* DEBUGGING only: map the OldBp to BW(1) : */
  out->BWCoeff[1] = (unsigned short) ((20.0 + in->OldBp) * 256.0f);
  out->BWCoeff[2] = 20*256 + ((in->isrnum) & 0xFF);
#endif

  /* scene change "indicator": leave exagerated red component only */

  if (need_scene_detection_p && sc_field_num > -1) {
    if (sc_field_num > 0) {
      for (bn=0; bn<NBLOCKS; bn+=3) {
	out->BWCoeff[bn]  = 1;  /* smallest possible bin width */
      }
      for (bn=1; bn<NBLOCKS; bn+=3) {
	out->BWCoeff[bn]  = 1;
      }
      for (bn=2; bn<NBLOCKS; bn+=3) {
	out->BWCoeff[bn] = 0xc000;
      }
    }      
    sc_field_num--;
    /******* disable feedback during "screwed up" fields. Be conservative
      and allow up to 4 fields of delay */
    current_feedback_speed = 0.0f;
  }
  else
    current_feedback_speed = feedback_speed;
}

static real bpp_table[NBLOCKS][NPT];

#ifdef BURSTFUSE

/* "burst_fuse" makes sure that the quantized values on average
   (actually square root of average square).
   do not exceed certain value. Bigger values require more bits and thus
   create bigger bursts of data. 
   The bounding value is implicitly stored in config_rec.MaxQVal2Inv.
   */

static void burst_fuse (BWCinput *bi, real bw[] )
{
    int bn;    
    
    for (bn=0; bn<NBLOCKS; bn++) {
	int comp_num = BLOCK_COMP_NUM(bn);
	real
	    scale  = comp_num == 0 ? 3.0 : 6.0,
	    ssq    = ((real)bi->SumOfSq[bn]) + 0.5,
	    bwmin2 = scale * ssq * config_rec.MaxQVal2Inv;

	if (bw[bn] * bw[bn] < bwmin2) {
	    real newbw = sqrt(bwmin2);
#if 0
	    printf ("\nClipped BW for block %d from %f to %f\n", 
		    bn, bw[bn], newbw);
#endif
	    bw[bn] = newbw;
	}
    }
}
#endif

//=========================================================================
// Function to initialize the Bin Width Calculator
//=========================================================================
/* "bw_init" must be called once before the compression can be started. */
DLLEXPORT void bw_init (BWCinit *init_rec)
{
    int bn;

    switch (init_rec->ImgType) {
      case NATURAL:
		memcpy(bpp_table, natural_bpp_table,   sizeof(bpp_table));
		break;
      case SYNTHETIC:
		memcpy(bpp_table, synthetic_bpp_table, sizeof(bpp_table));
		break;
      case GENERAL:
      default:
		memcpy(bpp_table, general_bpp_table,   sizeof(bpp_table));
		break;
    }
    the_rate = init_rec->Bpp;
    rate0 = (1.0f - config_rec.BppPrecision) * init_rec -> Bpp;
    rate1 = (1.0f + config_rec.BppPrecision) * init_rec -> Bpp;
    
    b1log = LOG10(b1);
    lbw_scale = ((real)(NPT-1)) / (b1log - LOG10(b0));

    init_block_sizes(init_rec->ImageWidth, init_rec->ImageHeight);

    for (bn=0; bn<NBLOCKS; bn++) {
	v2scale_log[bn] = LOG10(v2scale[bn]/(real)block_sizes[bn]);
    }
    /* Adjust bpp's according to block size */
    
    for (bn=0; bn<NBLOCKS; bn++) {
	int i;
	real weight = block_weights[bn];
	for (i=0; i<NPT; i++) {
	    bpp_table[bn][i] *= weight;
	}
    }
    feedback_adjustment = 1.0f;
    need_scene_detection_p = init_rec->scene_detection_p;
    for (bn=0; bn<NBLOCKS; bn++)
      old_stat[bn] = 0.0f;
    
    if (init_rec->special_effects_p) {
      feedback_speed = 0.0f;
      current_feedback_speed = 0.0f;
    }
}


/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Internal Stuff @@@@*/

/* "estimate_bpp" estimates and returns the bit rate (bpp, or bits per pixel)
   by estimating it from the tables for each block and adding them up. */

static real estimate_bpp (real bw[])
{
  real total_bpp = 0.0f, bwl;
  int bn;
  for (bn=0; bn<NBLOCKS; bn++) {
    real
      *cb_table = bpp_table[bn],
      cbw = bw[bn],
      bw_log, bpp;

    if (cbw > 0) {
      bw_log  = LOG10(cbw);
      bwl = (b1log - bw_log + v2log[bn]) * lbw_scale;
      if (bwl > NPT-1) {
	bpp = cb_table[NPT-1] + 
	  (bwl-NPT+1) * (cb_table[NPT-1] - cb_table[NPT-2]);
      }
      else if (bwl < 0) {
	bpp = cb_table[0] + bwl * (cb_table[1]-cb_table[0]);
	if (bpp<0)
	  bpp = 0.0f;
      }
      else {
	int 
	  bi0 = (int) bwl,
	  bi1 = bi0+1;
	real bfrac = bwl - bi0;
	    
	bpp = cb_table[bi0] +
	  bfrac * (cb_table[bi1] - cb_table[bi0]);
      }
      total_bpp += bpp;
    }
  }
  return total_bpp * feedback_adjustment;
}

/*** "expand_statistis" does some preprocessing of the statistics ***/

static void expand_statistics (BWCinput *ip)
{
    int bn;
    for (bn=0; bn<NBLOCKS; bn++) {
	real v2;

	/* ADV601 doesn't do the rounding, so we have to adhjust */

	v2 = 0.5f + ((real)(ip->SumOfSq[bn]));
	v2log[bn] = 0.5f * (LOG10(v2) + v2scale_log[bn]) ;
    }
}

/*** "init_block_sizes" computes block sizes from image parameters ***/

static void init_block_sizes (int img_width, int img_height)
{
    real image_size = (real) img_width * (real) img_height;
    int 
	h = img_height, w = img_width,
	w1 = (w+1)/2, w1r = w - w1,
	nn = 0, lev, bn;

    /******** Set Luminance Block Sizes */

    block_sizes[nn] = w1r * h;
    w = w1;
    for (lev=1; lev < 5; lev++) {
	int 
	    h1 = (h+1)/2, h1b = h - h1,
	    w1 = (w+1)/2, w1r = w - w1;
	block_sizes[nn+3] = h1b * w1r;
	block_sizes[nn+6] = h1  * w1r;
	block_sizes[nn+9] = h1b * w1;
	h = h1;
	w = w1;
	nn += 9;
    }
    block_sizes[nn+3] = h * w;
    
    /******** Set Chrominance Block Sizes */
    w = img_width;
    h = img_height;
    w1r = w/2;
    w1 = w-w1r;
    w1r = w1/2;
    w1 = w1-w1r;
    w = w1;
    nn = 1;
    block_sizes[nn] = block_sizes[nn+1] = w1r * h;
    for (lev=1; lev < 5; lev++) {
	int 
	    h1 = (h+1)/2, h1b = h - h1,
	    w1 = (w+1)/2, w1r = w - w1;
	block_sizes[nn+3] = block_sizes[nn+4]  = h1b * w1r;
	block_sizes[nn+6] = block_sizes[nn+7]  = h1  * w1r;
	block_sizes[nn+9] = block_sizes[nn+10] = h1b * w1;
	h = h1;
	w = w1;
	nn += 9;
    }
    block_sizes[nn+3] = block_sizes[nn+4] = h*w;
    for (bn=0; bn<NBLOCKS; bn++) 
	block_weights[bn] = ((real)block_sizes[bn])/image_size;
}

int init_ncheck(char *npsfname, FILE *cfcopy)
{

    FILE *nsconf; 
    int i, bn;
    real bstd, stdcoef;
    
    fprintf(cfcopy, "Attempting to open Noise Config File:%s\n",npsfname);
    nsconf = fopen (npsfname, "r");
    if (nsconf == NULL)     
       return 0;
    fprintf(cfcopy, "Noise Configuration\n");
    for (i = 0; i < NBLOCKS; i++){
      if (fscanf(nsconf, "b%d %f %f\n", &bn, &bstd, &stdcoef)==3){
	  bw_noise[i] = bstd * stdcoef;
	  fprintf(cfcopy, "Block:%d Std:%f Coeff:%f\n", bn,bstd,stdcoef);
      }
      else {
	fclose (nsconf);
	return 1;
      }
    }
    fclose (nsconf);
    return 2;
}

int read_config_file(char *name)
{
#define CFCNAME "bw-copy.cfg"
#define PRCOPY(F,X) fprintf(cfcopy,F,X)
  
  static real *arr[9] = {
    levels0,
    yuv_bias0,
    diag_hor_vert0,
    levels1,
    yuv_bias1,
    diag_hor_vert1,
    clip_levels,
    clip_yuv_bias,
    clip_diag_hor_vert};
  static char *arrname[9] = {
    "levels0",
    "yuv_bias0",
    "diag_hor_vert0",
    "levels1",
    "yuv_bias1",
    "diag_hor_vert1",
    "clip_levels",
    "clip_yuv_bias",
    "clip_diag_hor_vert"};
  static arrlimit[9] = {6,3,3,6,3,3,6,3,3};
  FILE *cf, *cfcopy;
  int arn, i, nfopen;
  float f;

  cf     = fopen (name, "r");
  cfcopy = fopen (CFCNAME, "w");

  if (cfcopy == 0)
    return 0;

  noisebw =  noise_check_p;

  noisebw =  noise_check_p;
  if (noise_check_p == 1){
      nfopen = init_ncheck(npsfname, cfcopy);
      if (nfopen == 0){
         fprintf (cfcopy, "Failed to open noise.cfg,\n");
	 fprintf (cfcopy, "\tInitiating regular bin width calculation\n");
         noisebw = 0;
      }
      else if (nfopen == 1){
         fprintf (cfcopy, "Error in noise.cfg file format,\n");
	 fprintf (cfcopy, "\tInitiating regular bin width calculation\n");
	 noisebw = 0;
      }
      else
         fprintf(cfcopy,
		 "Noise data rate reduction is active with %s\n",npsfname);
  }

  if (cf == 0) {
    PRCOPY("Failed to open %s\n", name);
    fclose(cfcopy);
    return 0;
  }
  for (arn=0; arn<9; arn++) {
    PRCOPY("\n\n%s:\n",arrname[arn]);
    for (i=0; i<arrlimit[arn]; i++) {
      if (fscanf (cf, "%f", &f) != 1) {
	fprintf (cfcopy, "\nFailed to read %s[%d]\n", arrname[arn],i);
	fclose(cfcopy);
	return 0;
      }
      else {
	arr[arn][i] = f;
	PRCOPY(" %f",f);
      }
    }
  }
  

  /* Read feedback control configuration data: */
  
  if (fscanf (cf, "%f", &feedback_speed) == 1)
    fprintf (cfcopy, "\nFeedback Speed = %f\n", 
	     feedback_speed);
  else {
    fprintf (cfcopy, "\nFailed to read Feedback Speed Parameter\n");
    fprintf (cfcopy, "\n\t(Using %f)\n", feedback_speed);
  }
  if (fscanf (cf, "%f", &feedback_scene_thresh) == 1)
    fprintf (cfcopy, "\nFeedback Scene Detection Threshold = %f\n", 
	     feedback_scene_thresh);
  else {
    fprintf (cfcopy,
	     "\nFailed to read Feedback Scene Detection Threshold\n");
    fprintf (cfcopy, "\n\t(Using %f)\n", feedback_scene_thresh);
  }

  if (fscanf (cf, "%f", &scene_thresh) == 1)
    fprintf (cfcopy, "\nScene Detection Threshold = %f\n", 
	     scene_thresh);
  else {
    fprintf (cfcopy, "\nFailed to read Scene Detection Threshold\n");
    fprintf (cfcopy, "\n\t(Using %f)\n", scene_thresh);
  }
  bw_config();

#ifdef DUMPSTAT
#include <fcntl.h>
    {
      static buf[222];
      static fnum = 0;
      if (stat_fd > 0) 
	close (stat_fd);
      sprintf (buf, "statdump.%03d", fnum++);
      stat_fd = open (buf, O_WRONLY | O_CREAT | O_BINARY | O_TRUNC, 0666);
    }
#endif

#ifdef DITHER
    if (cf) {
      if (fscanf (cf, "%f", &dither_range) != 1) {
	fprintf (cfcopy, "\nFailed to read dither range, using %f\n",
		 dither_range);
      }
      else {
	fprintf (cfcopy, "\nDither: Range = %f\n", dither_range);
      }
      dither_scale = 2.0f * dither_range / ((float) RAND_MAX);
      dither_base = 1.0f - dither_range;
      fprintf (cfcopy, "\nDither: Scale=%f, Base=%f\n",
	       dither_scale, dither_base);
    }
    srand(1231);
#endif

  fclose(cfcopy);
  fclose (cf);
  return 1;
}


/******************************************************************/
/*** This is simply a unit test. It is not part of the driver !! ***/
/* The statistics is take from a file in hex -- the same format in 
   which the simulator dumps them. */

#if BWTEST

void read_statistics (BWCinput *irec)
{
    int i;
    char field1[33], field2[33], field3[33];

    /* read 2-nd moments for the first 39 blocks */
    /* Scan the title */
    scanf("%s %s %s", field1, field2, field3);
    for (i=0; i<NBLOCKS-3; i++) {
	long x;
	scanf("%s %s %s", field1, field2, field3);
	sscanf (field3, "%x", &x);
	irec->SumOfSq[i] = x>>16;
    }

    /** Read 1-st and 2-nd moments for 3 lower blocks */
	
    for (i=NBLOCKS-3; i<NBLOCKS; i++) {
	long x1, x2;
	scanf("%s %s %s", field1, field2, field3);
	sscanf (field2, "%x", &x1);
	sscanf (field3, "%x", &x2);
	irec->SumValue[i] = x1;
	irec->SumOfSq[i] = x2>>16;
    }
}


#include <sys/time.h>

void main (int argc, char *argv[])
{
    int i, n, ntimes, nsec = 20;
    struct timeval tm0, tm1;
    float elapsed;
    BWCinput inrec;
    BWCoutput outrec;
    BWCinit init_rec;

    real rate = 1.0f;  /* bits per pixel */
    int models[100];

    if (argc > 1) {
	if (sscanf (argv[1], "%d", &nsec) != 1) {
	    fprintf (stderr, "Usage: %s [# seconds]\n", argv[0]);
	    exit(5);
	}
    }
    
    read_statistics(&inrec);
    init_rec.Bpp = 1.0f;
    init_rec.ImgType = NATURAL;
    init_rec.ImageWidth  = 720;
    init_rec.ImageHeight = 243;

    bw_config();
    bw_init(&init_rec);

    ntimes = 60*nsec;

    gettimeofday (&tm0);

    for (n=0; n<ntimes; n++) {
	bw_compute (&inrec, &outrec);
    }
    gettimeofday (&tm1);
    
    elapsed = 1000000.0 * (tm1.tv_sec  - tm0.tv_sec) +
	tm1.tv_usec - tm0.tv_usec;
    
    elapsed *= 0.000001;

    
    printf ("\n");
    printf
	("Elapsed: %f sec, %d frames, %d video seconds %f of \"real\" time\n",
	    elapsed, nsec * 60, nsec, elapsed / nsec);

    for (i=0; i<NBLOCKS; i++) {
	printf ("%04x\n", outrec.BWCoeff[i]);
    }
}
#endif

⌨️ 快捷键说明

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