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

📄 jdcoefct.c

📁 基于Linux的ffmepg decoder
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
 * jdcoefct.c
 *
 * Copyright (C) 1994-1997, Thomas G. Lane.
 * This file is part of the Independent JPEG Group's software.
 * For conditions of distribution and use, see the accompanying README file.
 *
 * This file contains the coefficient buffer controller for decompression.
 * This controller is the top level of the JPEG decompressor proper.
 * The coefficient buffer lies between entropy decoding and inverse-DCT steps.
 *
 * In buffered-image mode, this controller is the interface between
 * input-oriented processing and output-oriented processing.
 * Also, the input side (only) is used when reading a file for transcoding.
 */

#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"

/* Block smoothing is only applicable for progressive JPEG, so: */
#ifndef D_PROGRESSIVE_SUPPORTED
#undef BLOCK_SMOOTHING_SUPPORTED
#endif

/* Private buffer controller object */

typedef struct {
  struct jpeg_d_coef_controller pub; /* public fields */

  /* These variables keep track of the current location of the input side. */
  /* cinfo->input_iMCU_row is also used for this. */
  JDIMENSION MCU_ctr;		/* counts MCUs processed in current row */
  int MCU_vert_offset;		/* counts MCU rows within iMCU row */
  int MCU_rows_per_iMCU_row;	/* number of such rows needed */

  /* The output side's location is represented by cinfo->output_iMCU_row. */

  /* In single-pass modes, it's sufficient to buffer just one MCU.
   * We allocate a workspace of D_MAX_BLOCKS_IN_MCU coefficient blocks,
   * and let the entropy decoder write into that workspace each time.
   * (On 80x86, the workspace is FAR even though it's not really very big;
   * this is to keep the module interfaces unchanged when a large coefficient
   * buffer is necessary.)
   * In multi-pass modes, this array points to the current MCU's blocks
   * within the virtual arrays; it is used only by the input side.
   */
  JBLOCKROW MCU_buffer[D_MAX_BLOCKS_IN_MCU];

#ifdef D_MULTISCAN_FILES_SUPPORTED
  /* In multi-pass modes, we need a virtual block array for each component. */
  jvirt_barray_ptr whole_image[MAX_COMPONENTS];
#endif

#ifdef BLOCK_SMOOTHING_SUPPORTED
  /* When doing block smoothing, we latch coefficient Al values here */
  int * coef_bits_latch;
#define SAVED_COEFS  6		/* we save coef_bits[0..5] */
#endif
} my_coef_controller;

typedef my_coef_controller * my_coef_ptr;

/* Forward declarations */
METHODDEF(int) decompress_onepass
	JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
#ifdef D_MULTISCAN_FILES_SUPPORTED
METHODDEF(int) decompress_data
	JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
#endif
#ifdef BLOCK_SMOOTHING_SUPPORTED
LOCAL(boolean) smoothing_ok JPP((j_decompress_ptr cinfo));
METHODDEF(int) decompress_smooth_data
	JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
#endif


LOCAL(void)
start_iMCU_row (j_decompress_ptr cinfo)
/* Reset within-iMCU-row counters for a new row (input side) */
{
  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;

  /* In an interleaved scan, an MCU row is the same as an iMCU row.
   * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
   * But at the bottom of the image, process only what's left.
   */
  if (cinfo->comps_in_scan > 1) {
    coef->MCU_rows_per_iMCU_row = 1;
  } else {
    if (cinfo->input_iMCU_row < (cinfo->total_iMCU_rows-1))
      coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
    else
      coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
  }

  coef->MCU_ctr = 0;
  coef->MCU_vert_offset = 0;
}


/*
 * Initialize for an input processing pass.
 */

METHODDEF(void)
start_input_pass (j_decompress_ptr cinfo)
{
  cinfo->input_iMCU_row = 0;
  start_iMCU_row(cinfo);
}


/*
 * Initialize for an output processing pass.
 */

METHODDEF(void)
start_output_pass (j_decompress_ptr cinfo)
{
#ifdef BLOCK_SMOOTHING_SUPPORTED
  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;

  /* If multipass, check to see whether to use block smoothing on this pass */
  if (coef->pub.coef_arrays != NULL) {
    if (cinfo->do_block_smoothing && smoothing_ok(cinfo))
      coef->pub.decompress_data = decompress_smooth_data;
    else
      coef->pub.decompress_data = decompress_data;
  }
#endif
  cinfo->output_iMCU_row = 0;
}

#ifdef USE_INTERNAL_CPU
void store_embedded_cpu_parameters(j_decompress_ptr cinfo,j_decompress_embedded_ptr pdecinfo)
{
  int ci;
  jpeg_component_info *compptr;
  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
  FTMCP100_CODEC *pCodec=(FTMCP100_CODEC *)cinfo->pCodec;
  
  
  #ifdef VPE_OUTPUT
    RTL_DEBUG_OUT(0x90000000 | 0x100) // beginning of storing embedded cpu parameter
  #endif
  
  //pdecinfo->pCoreBaseAddr=pCodec->pCoreBaseAddr;
  
  // set the parameters for internal CPU firmware execution
  /**** process_data_context_main() or process_data_simple_main () function's related variables ****/
  //iMCU_row_ctr // we don't need to set this parameter, used for internal CPU
  pdecinfo->total_iMCU_rows=cinfo->total_iMCU_rows;
  pdecinfo->max_v_samp_factor=cinfo->max_v_samp_factor;
  /**** decompress_onepass() function's related variables ****/
  pdecinfo->MCUs_per_row=cinfo->MCUs_per_row;
  pdecinfo->MCU_ctr=coef->MCU_ctr;
  pdecinfo->blocks_in_MCU=cinfo->blocks_in_MCU;
  pdecinfo->invalid_next_restart_marker=cinfo->invalid_next_restart_marker;
  
  #ifdef VPE_OUTPUT
    RTL_DEBUG_OUT(0x90000000 | (pdecinfo->total_iMCU_rows))  
  #endif
  
  for(ci=0;ci<cinfo->comps_in_scan;ci++)
    {
      compptr = cinfo->cur_comp_info[ci];
      pdecinfo->cur_comp_info[ci].component_index=compptr->component_index;
      pdecinfo->cur_comp_info[ci].MCU_height=compptr->MCU_height;
      pdecinfo->cur_comp_info[ci].MCU_width=compptr->MCU_width;
      pdecinfo->cur_comp_info[ci].MCU_sample_width=compptr->MCU_sample_width;
    };
  pdecinfo->comps_in_scan=cinfo->comps_in_scan;
  
  #ifdef VPE_OUTPUT
    RTL_DEBUG_OUT(0x90000000 | 0x101) 
  #endif
  
  //for(ci=0;ci<3;ci++) pdecinfo->outdata[ci]=outdata[ci];
  for(ci=0;ci<3;ci++) pdecinfo->outdata[ci]=pCodec->outdata[ci];  
  
  pdecinfo->restarts_to_go=cinfo->restart_interval;
  pdecinfo->restart_interval=cinfo->restart_interval;
  pdecinfo->next_restart_num=cinfo->marker->next_restart_num;
  
  pdecinfo->restart_flag=FALSE; // initalize the restart interval flag to false
  
  pdecinfo->input_iMCU_row=cinfo->input_iMCU_row;
  
  #ifdef VPE_OUTPUT
    RTL_DEBUG_OUT(0x90000000 | 0x102) 
  #endif
  
  pdecinfo->MCU_rows_per_iMCU_row=coef->MCU_rows_per_iMCU_row;
  pdecinfo->cur_comp_info_0_v_samp_factor=cinfo->cur_comp_info[0]->v_samp_factor;
  pdecinfo->cur_comp_info_0_last_row_height=cinfo->cur_comp_info[0]->last_row_height;
  pdecinfo->MCU_vert_offset=coef->MCU_vert_offset;
  
  
  #ifdef VPE_OUTPUT
    RTL_DEBUG_OUT(0x90000000 | 0x1ff) // end of storing embedded cpu parameter
  #endif
}
#endif


/*
 * Decompress and return some data in the single-pass case.
 * Always attempts to emit one fully interleaved MCU row ("iMCU" row).
 * Input and output must run in lockstep since we have only a one-MCU buffer.
 * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
 *
 * NB: output_buf contains a plane for each component in image,
 * which we index according to the component's SOF position.
 */

/*
 * This function is designed for pipeline processing in order to fully utilize
 * hardware's capability
 */
METHODDEF(int)
decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
{
#ifdef USE_INTERNAL_CPU
  FTMCP100_CODEC *pCodec=(FTMCP100_CODEC *)cinfo->pCodec;
  unsigned int start_inter_cpu;
  //int ci; unsigned int *p;
  struct jpeg_decompress_embedded_struct *pdecinfo=(struct jpeg_decompress_embedded_struct *)JPG_DEC_INFO;

  // store the parameters used for internal CPU  
  store_embedded_cpu_parameters(cinfo,pdecinfo);
  
  pdecinfo->internal_cpu_command=1; // to instruct the internal CPU to do interleaved decoding
  pdecinfo->external_cpu_response=0;
  // to start the internal CPU  
  start_inter_cpu = 1<<18;
  
  //#ifdef VPE_OUTPUT
  //  RTL_DEBUG_OUT(0x90000000 | 0x200) // begin to start the internal CPU
  //#endif

  /*
  #ifdef VPE_OUTPUT
    // to print the internal CPU code
    p=(unsigned int*)CPU_BASE_ADDRESS;
    for(ci=0;ci<sizeof(InterCPUcode)/sizeof(unsigned int);ci++)
      { 
        RTL_DEBUG_OUT(0x90000000 | ((*p++)&0x0fffffff))
      }
  #endif
  */
  
  //__asm{		
    SET_INCTL(start_inter_cpu)
  //}

  // to wait for internal CPU's response by querying the 'pdecinfo->external_cpu_response' variable
  POLL_EXTERNAL_CPU_RESPONSE_START
  
  while(pdecinfo->external_cpu_response!=1) 
    { int i;  for(i=0;i<10000; i++) { } 
      //#ifdef VPE_OUTPUT
      //RTL_DEBUG_OUT(0x90000000 | 0x201) // still querying the extrenal CPU
      //#endif
      //printf("external respose is %d\n",pdecinfo->external_cpu_response);
    }
    
  POLL_EXTERNAL_CPU_RESPONSE_END
  
  //#ifdef VPE_OUTPUT
    //RTL_DEBUG_OUT(0x90000000 | 0x2ff) // end of starting the internal CPU
  //#endif
  
#else  // else of #ifdef USE_INTERNAL_CPU

  FTMCP100_CODEC *pCodec=(FTMCP100_CODEC *)cinfo->pCodec;
  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
  JDIMENSION MCU_col_num;	// index of current MCU within row 
  JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
  
  //JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
  //  int blkn, ci, xindex, yindex, yoffset, useful_width;
  //  JSAMPARRAY output_ptr;
  //  JDIMENSION start_col, output_col;
  //  jpeg_component_info *compptr;
  //  inverse_DCT_method_ptr inverse_DCT;

  boolean stage_active[3]= { FALSE,FALSE,FALSE }; // VLD-DZ , DQ-MC , DMA stages
  JDIMENSION m[3]={ 0, 0, 0 };  // the MCU_col_num stack (to serve as pipeline register)
  
  // we made it static since we usually need to reserve descriptor status because of restart marker
  //static int buf_descriptor1=0; // used to select ping pong buffer for VLD output
  //static int buf_descriptor2=0; // used to select buffer between DQ-MC stage and DMA stage (indicated by MCIADDR for DQ-MC engine output)
  
  unsigned int cpsts_reg,vldsts_reg,vldctl_reg;
  unsigned int dzar_qar;
  unsigned int *mciaddr_ptr;
  volatile MDMA *pmdma = MDMA1; // used to access the DMA register
  
  const unsigned int start_VLD=((1 << 9) | (1 << 5) | (1<<1));  //set JPEG_mode and DEC_GO and INTRA
  const unsigned int start_DQ_MC=((1 << 9) | (1<<10) | (1 << 1));  //set JPEG_mode and DMC_GO and INTRA
  
  //#ifdef VPE_OUTPUT
  //static MCU_num=0; // mainly used for VPE out....RTL simulation debug usage
  //#endif
  
  //static unsigned int MCU_num_VLD=0,MCU_num_DQ_MC=0; // mainly used for debug usage
  //unsigned int v,s,last_bit,bitlen; // mainly used for debug

  // Loop to process as much as one whole iMCU row
  for (MCU_col_num = coef->MCU_ctr; MCU_col_num <= last_MCU_col || (stage_active[0] | stage_active[1] | stage_active[2]);MCU_col_num++)
    {
      //#ifdef FPGA_PLATFORM
      //printf("MCU Column Number : %d\n",MCU_col_num);
      //#endif

⌨️ 快捷键说明

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