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

📄 jpeg_dec.c

📁 基于Linux的ffmepg decoder
💻 C
字号:
#include "jpeg_dec.h"#include "cdjpeg.h"		/* Common decls for cjpeg/djpeg applications *///#include "jmemsys.h"		/* import the system-dependent declarations */// reserve space for input bitstream, output YUV, golden bitstream under RTL simulation#ifdef RTL_PLATFORM  // Under RTL simulation, we have to embedded the JPEG bitstream inside executable program.  // So we include the array of JPEG bitstream to compile with program body.  #include "input_stream.h"    // Under RTL simulation, we reserve the output YUV space inside executable program.  // So we include the array of decoded image result to compile with program body.  #include "output_stream.h"    // include the 'golden_stream.h' file for the purpose of automatically comparing decoding  // result durin RTL simulation  #include "golden_stream.h"  unsigned char* goldendata[]={ (unsigned char *) goldenstream0, (unsigned char *) goldenstream1,(unsigned char *) goldenstream2 };  unsigned long int goldendata_len[]={sizeof(goldenstream0),sizeof(goldenstream1),sizeof(goldenstream2)};#endif#ifdef USE_INTERNAL_CPU  //#ifdef FPGA_PLATFORM    //#include "intercpucode_fpga.h"  //#elif defined(RTL_PLATFORM)    //#include "intercpucode_rtl.h"  //#else    //#error "Please define the platfrom flags in project setting (either FPGA_PLATFORM or RTL_PLATFORM)"  //#endif  #include "intercpucode.h"#endif/* Create the add-on message string table. */#define JMESSAGE(code,string)	string ,static const char * const cdjpeg_message_table[] = {#include "cderror.h"  NULL};//struct jpeg_decompress_struct cinfo;//struct jpeg_error_mgr jerr;void Init_FTMCP100(j_decompress_ptr cinfo,FJPEG_DEC_PARAM * ptParam){  unsigned int *inbitstr;  unsigned int vldsts_reg;    // You don't have to free the 'pCodec' since we use the 'alloc_small' function.  FTMCP100_CODEC *pCodec=(FTMCP100_CODEC *) (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,sizeof(FTMCP100_CODEC));    // attach our FTMCP100 Codec object to decompression object  cinfo->pCodec=pCodec;  // To initialize this global variable BASE_ADDRESS in the first place  // or all other reigster access depend on this global variable  pCodec->pCoreBaseAddr=ptParam->pu32BaseAddr;    pCodec->pfnDmaMalloc=(void *)ptParam->pfnDmaMalloc;  pCodec->pfnDmaFree=(void *)ptParam->pfnDmaFree;    #ifdef CORE_VERSION_1    // ten blocks at most.. and each DMA command set occupies 4 words    // and we allocate the system DMA memory about 4*10*4=160 bytes with 16-byte alignment    pCodec->pSDMA_virt=(unsigned char*)(*(DMA_MALLOC_PTR)pCodec->pfnDmaMalloc)(160,16,16,&pCodec->pSDMA_phy);  #endif    pCodec->pingpong_buf[0] = (unsigned short *) (PINGPONG_BUFFER_0_ADDR);  pCodec->pingpong_buf[1] = (unsigned short *) (PINGPONG_BUFFER_1_ADDR);    pCodec->pLDMA = (unsigned int *) (DMA_COMMAND_LOCAL_ADDR+pCodec->pCoreBaseAddr);    #ifdef USE_INTERNAL_CPU    pCodec->pLDMA_INTERNAL_CPU = (unsigned int *) (DMA_COMMAND_INTERNAL_CPU+pCodec->pCoreBaseAddr);  #endif    // initialize the buffer descriptor  pCodec->buf_descriptor1=0; // used to select ping pong buffer for VLD output  pCodec->buf_descriptor2=0; // used to select buffer between DQ-MC stage and DMA stage (indicated by MCIADDR for DQ-MC engine output)      // initialze some varaibles here  #ifdef RTL_PLATFORM    // 'instream' variable is defined in the file 'input_stream.h'    inbitstr = (unsigned int *)instream; // set input bitstream location  #else    inbitstr = (unsigned int *)ptParam->pu8BitstreamAddr; // set input bitstream location  #endif    SET_VLDCTL(1<<5) //stop autobuffer in case previous firmware program did not terminate normally  SET_PYDCR(0)  // set JPEG Previous Y DC Value Register to zero	SET_PUVDCR(0) // set JPEG Previous UV DC Value Register to zero	SET_CKR(CKR_RATIO) // set Coprocessor Clock Control Register	SET_VADR(VLD_AUTOBUFFER_ADDR)  // set VLD Data Address Register (in Local Memory)	SET_BADR(0) // reset the Bitstream Access Data Regsiter	SET_BALR(0) // reset the Bitstream Access Length Register 	SET_ABADR((unsigned int)inbitstr) // set Auto-Buffer System Data Address for VLD read operation	SET_VLDCTL(0x58)  //Autobuffer Start (1011000) , just enable the VLD autobuffer engine and enable endian swapping (bit 6)	SET_MCCADDR(0)  // we set MCCADDR to zero on purpose 	  #ifdef USE_INTERNAL_CPU    // we might need to reset the internal CPU before decoding under embedded-CPU architecture    SET_INCTL(1<<19) // reset internal CPU  #endif  // before read the header, we ought to check if the auto-buffer is ready for access or not  // check autobuffer access is done or not  do {    READ_VLDSTS(vldsts_reg)	} while(!(vldsts_reg&0x0800));}void *FJpegDecCreate(FJPEG_DEC_PARAM * ptParam){   struct jpeg_decompress_struct *cinfo;  struct jpeg_error_mgr *jerr;    #ifdef USE_INTERNAL_CPU    FTMCP100_CODEC *pCodec;    volatile MDMA *pmdma;    unsigned int internal_cpu_code_word_length;    int ci; unsigned int *p;    #endif     #ifdef RTL_PLATFORM    __rt_lib_init(0x50000, 0x200000);        _fp_init();  #endif  // start the out operation  #ifdef VPE_OUTPUT    RTL_DEBUG_OUT(0x91111111) // begin VPE operation  #endif    cinfo=malloc(sizeof(struct jpeg_decompress_struct));  jerr=malloc(sizeof(struct jpeg_error_mgr));  // Initialize the JPEG decompression object with default error handling.  cinfo->err = jpeg_std_error(jerr); //cinfo.err = jpeg_std_error(&jerr);  jpeg_create_decompress(cinfo); //jpeg_create_decompress(&cinfo);  // Add some application-specific error messages (from cderror.h)  jerr->addon_message_table = cdjpeg_message_table; //jerr.addon_message_table = cdjpeg_message_table;  jerr->first_addon_message = JMSG_FIRSTADDONCODE; //jerr.first_addon_message = JMSG_FIRSTADDONCODE;  jerr->last_addon_message = JMSG_LASTADDONCODE; //jerr.last_addon_message = JMSG_LASTADDONCODE;    Init_FTMCP100(cinfo,ptParam);    #ifdef USE_INTERNAL_CPU    pCodec=(FTMCP100_CODEC *)cinfo->pCodec;#ifndef LINUX    pmdma = MDMA1; // used to access the DMA register    pmdma->Status = 1;    // let's set the DMA command buffer for loading the internal CPU code to internal    // local memory, seems not work...let's use data move ...    // improve it by DMA later    internal_cpu_code_word_length=sizeof(InterCPUcode) / sizeof(unsigned int);    #ifdef VPE_OUTPUT      //RTL_DEBUG_OUT(0x90000000 | internal_cpu_code_word_length) // print the word length of internal cpu code    #endif    // copy from Winnie's code    pCodec->pLDMA_INTERNAL_CPU[0]=InterCPUcode;	pCodec->pLDMA_INTERNAL_CPU[1]=pCodec->pCoreBaseAddr;	pCodec->pLDMA_INTERNAL_CPU[2]=0x0;	pCodec->pLDMA_INTERNAL_CPU[3]=0x0<<26 | 0x8<<20 | internal_cpu_code_word_length;	pmdma->CCA = (((unsigned int) pCodec->pLDMA_INTERNAL_CPU)&0xfffffff0) | 0x2;	pmdma->Control = 0xa<<20 | 0x1<<26;				//start DMA#else     memcpy (pCodec->pCoreBaseAddr, InterCPUcode, sizeof(InterCPUcode));#endif    // to print the internal CPU code    /*    p=(unsigned int*)ptParam->pu32BaseAddr;    for(ci=0;ci<internal_cpu_code_word_length;ci++)      {        #ifdef VPE_OUTPUT          //RTL_DEBUG_OUT(0x90000000 | (InterCPUcode[ci]&0x0fffffff))        #endif        *p=InterCPUcode[ci];        p++;      }    */   #endif    // Specify data source for decompression  jpeg_stdio_src(cinfo, NULL); //jpeg_stdio_src(&cinfo, NULL);    return (void *)cinfo;}JPEGDEC_EXPOPRT void FJpegDecReadHeader(void *dec_handle,FJPEG_DEC_RESULT *pDecResult){  int ci;  jpeg_component_info *compptr;  struct jpeg_decompress_struct *cinfo=(struct jpeg_decompress_struct *) dec_handle;    (void) jpeg_read_header(cinfo, TRUE); //(void) jpeg_read_header(&cinfo, TRUE);    // Start decompressor  (void) jpeg_start_decompress(cinfo); //(void) jpeg_start_decompress(&cinfo);    // fill the members of FJPEG_DEC_RESULT data structure for return  pDecResult->u32ImageWidth=cinfo->image_width;  pDecResult->u32ImageHeight=cinfo->image_height;  pDecResult->u8NumComponents=cinfo->num_components;  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;ci++, compptr++)     {      pDecResult->rgComponentInfo[ci].m_u8HSamplingFrequency=compptr->h_samp_factor;      pDecResult->rgComponentInfo[ci].m_u8VSamplingFrequency=compptr->v_samp_factor;      if(jpeg_has_multiple_scans(cinfo))        { // it the image is non-interleaved format , one block per MCU          pDecResult->rgComponentInfo[ci].m_u32ComponentWidth= compptr->width_in_blocks * DCTSIZE;          pDecResult->rgComponentInfo[ci].m_u32ComponentHeight= compptr->height_in_blocks * DCTSIZE;          //m=compptr->MCU_blocks*compptr->width_in_blocks * compptr->height_in_blocks;        }      else        {          pDecResult->rgComponentInfo[ci].m_u32ComponentWidth= cinfo->MCUs_per_row * compptr->MCU_width * DCTSIZE;          pDecResult->rgComponentInfo[ci].m_u32ComponentHeight= cinfo->MCU_rows_in_scan * compptr->MCU_height * DCTSIZE;                    //m=compptr->MCU_blocks*cinfo->MCUs_per_row*cinfo->MCU_rows_in_scan;        }              pDecResult->rgComponentInfo[ci].m_u32ComponentTotalSize=pDecResult->rgComponentInfo[ci].m_u32ComponentWidth * pDecResult->rgComponentInfo[ci].m_u32ComponentHeight;    }}JPEGDEC_EXPOPRT void FJpegDecDecode(void *dec_handle,FJPEG_DEC_PARAM *ptParam){  struct jpeg_decompress_struct *cinfo=(struct jpeg_decompress_struct *) dec_handle;  FTMCP100_CODEC *pCodec=(FTMCP100_CODEC *)cinfo->pCodec;  int ci;  #ifdef USE_INTERNAL_CPU    volatile MDMA *pmdma = MDMA1;  #endif    // And record the output YUV buffer 8-byte aligned address to the pCodec object  #ifdef RTL_PLATFORM    unsigned char* outdata[]={ (unsigned char *) outstream0, (unsigned char *) outstream1,(unsigned char *) outstream2 };    for(ci=0; ci<ptParam->u8NumComponents; ci++)      pCodec->outdata[ci]=outdata[ci];  #else    for(ci=0; ci<ptParam->u8NumComponents; ci++)      pCodec->outdata[ci]=ptParam->pu8YUVAddr[ci];  #endif  // if it is interleaved image, we set the DMA stuff here...  if(! jpeg_has_multiple_scans(cinfo)) //if(! jpeg_has_multiple_scans(&cinfo))      (void) ftmcp100_set_mcu_dma_params(cinfo); //(void) ftmcp100_set_mcu_dma_params(&cinfo); // to set the MCUTIR and MCUBR register   // we need to flush the D cache or the result will be wrong   FA526_CleanInvalidateDCacheAll();    // Process data  #ifdef VPE_OUTPUT    RTL_DEBUG_OUT(0x94000000 | 6) // beginning of decoding  #endif    #ifdef USE_INTERNAL_CPU    // remember that we have start the DMA trasnfer of internal CPU code in    // FJpegDecCreate() function, so we need to check the DMA status right here...   #ifndef LINUX    while(!(pmdma->Status & 0x1)) ; // check DMA is done  #endif  #endif      while (cinfo->output_scanline < cinfo->output_height) { //while (cinfo.output_scanline < cinfo.output_height) {    jpeg_read_scanlines(cinfo, NULL,0);        /*    num_scanlines = jpeg_read_scanlines(&cinfo, dest_mgr->buffer,					dest_mgr->buffer_height);        (*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines);    */  }     #ifdef VPE_OUTPUT    RTL_DEBUG_OUT(0x94000000 | 7) // end of decoding  #endif  // dump the YUV data in System Memory which was moved from Local Memory  //......................   #ifdef VPE_OUTPUT  #ifdef VPE_DUMP_YUV   (void) ftmcp100_dump_yuv(cinfo); // to dump the final result for YUV data  #endif  #endif  SET_VLDCTL(0x28)  //Autobuffer Stop}void FJpegDecDestroy(void *dec_handle){   struct jpeg_decompress_struct *cinfo=(struct jpeg_decompress_struct *) dec_handle;    struct jpeg_error_mgr *jerr=cinfo->err;    #if (defined(RTL_PLATFORM) || defined(CORE_VERSION_1) )    FTMCP100_CODEC *pCodec=(FTMCP100_CODEC *)cinfo->pCodec;  #endif      #ifdef RTL_PLATFORM    if(cinfo->num_components)    {      int ci,gi;      for (ci=0;ci<cinfo->num_components;ci++)        {          int error_flag=0;          for(gi=0;gi<goldendata_len[ci];gi++)            {              // to show bitstream data		      RTL_DEBUG_OUT(0x97000000 | (unsigned int)(pCodec->outdata[ci])[gi]) // dump the encoded bitstream data              if ((pCodec->outdata[ci])[gi]!=(goldendata[ci])[gi])                {                   // to show the gloden data since there is error                  RTL_DEBUG_OUT(0x98000000 | (unsigned int)(goldendata[ci])[gi]) // dump the encoded bitstream data                  error_flag=1;                  break;                }            }          if(error_flag)            { RTL_DEBUG_OUT(0x01234569) break; }  // Fail!          else            RTL_DEBUG_OUT(0x01234568) // Pass!        }    }  #endif      #ifdef CORE_VERSION_1    // ten blocks at most.. and each DMA command set occupies 4 words    // and we free the allocated system DMA memory with physical address and virtual address    (*(DMA_FREE_PTR)pCodec->pfnDmaFree)(pCodec->pSDMA_virt,pCodec->pSDMA_phy);  #endif    #ifdef VPE_OUTPUT    RTL_DEBUG_OUT(0x91222222) // means end of entire jpeg decoder  #endif    (void) jpeg_finish_decompress(cinfo);    #ifdef VPE_OUTPUT    RTL_DEBUG_OUT(0x01234567) // VPE Debug Finish  #endif    jpeg_destroy_decompress(cinfo);  //free(pCodec); // we don't have to free the pCodec since we use (*cinfo->mem->alloc_small) function to allocate the memory  free(jerr);  free(cinfo);}

⌨️ 快捷键说明

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