/* Skip over an unknown or uninteresting variable-length marker */ LOCAL JPEG_RET_E SkipVariable(JPEG_DEC_INPUT_PARA_T *jpeg_dec_input) { uint16 length = 0; //int32 read_bytes = 0; if (!get_short_word(&length) || length < 2) { JPEG_TRACE("[SkipVariable] read length failed, length = %d", length); return JPEG_FAILED; } JPEG_TRACE("JPEG: Skipping length %d\n", length); for(length-=2; length > 0; length--) { uint8 c; if (!get_char(&c)) { JPEG_TRACE("[SkipVariable] skip failed"); return JPEG_FAILED; } } return JPEG_SUCCESS; }
LOCAL JPEG_RET_E GetDRI() { uint16 length = 0; uint16 restart_interval = 0; JPEG_CODEC_T *jpeg_fw_codec = Get_JPEGDecCodec(); if (!get_short_word(&length) || 4 != length) { JPEG_TRACE("[GetDRI] read length failed, length = %d", length); return JPEG_FAILED; } if (!get_short_word(&restart_interval)) { JPEG_TRACE("[GetDRI] read restart interval failed"); return JPEG_FAILED; } jpeg_fw_codec->restart_interval = restart_interval; jpeg_fw_codec->restart_to_go = jpeg_fw_codec->restart_interval; jpeg_fw_codec->next_restart_num = 0; return JPEG_SUCCESS; }
/***************************************************************************** * func : JPEG_HDEC_Resume * description : suspend resume CNcomment: ´ý»ú»½ÐÑ CNend\n * param[in] : cinfo CNcomment: ½âÂë¶ÔÏó CNend\n * retval : NA * others: : NA *****************************************************************************/ HI_VOID JPEG_HDEC_Resume(const struct jpeg_decompress_struct *cinfo) { HI_S32 s32RetVal = 0; HI_JPG_SAVEINFO_S stResumeValue; JPEG_HDEC_HANDLE_S_PTR pJpegHandle = (JPEG_HDEC_HANDLE_S_PTR)(cinfo->client_data); memset(&stResumeValue,0,sizeof(HI_JPG_SAVEINFO_S)); /** ** cancel reset ** CNcomment:³·Ïû¸´Î» CNend\n **/ s32RetVal = ioctl(pJpegHandle->s32JpegDev, CMD_JPG_CANCEL_RESET); if(HI_SUCCESS != s32RetVal) { return; } /** ** waite cancel reset success ** CNcomment:µÈ´ý³·Ïû¸´Î»³É¹¦ CNend\n **/ usleep(1); /** 1ms at least **/ s32RetVal = ioctl(pJpegHandle->s32JpegDev, CMD_JPG_GETRESUMEVALUE, &stResumeValue); if(HI_SUCCESS != s32RetVal) { return; } pJpegHandle->u32ResByteConsum = stResumeValue.u32ResByteConsu; s32RetVal = JPEG_HDEC_SetPara(cinfo); if(HI_SUCCESS != s32RetVal) { return; } JPEG_HDEC_WriteReg(pJpegHandle->pJpegRegVirAddr,JPGD_REG_BSRES_DATA0_CFG, (HI_S32)stResumeValue.u32ResumeData0); JPEG_HDEC_WriteReg(pJpegHandle->pJpegRegVirAddr,JPGD_REG_BSRES_DATA1_CFG, (HI_S32)stResumeValue.u32ResumeData1); JPEG_HDEC_WriteReg(pJpegHandle->pJpegRegVirAddr,JPGD_REG_BSRES_BIT_CFG, (HI_S32)stResumeValue.u32ResBitRemain); JPEG_HDEC_WriteReg(pJpegHandle->pJpegRegVirAddr,JPGD_REG_MCUY_CFG, (HI_S32)stResumeValue.u32ResMcuy); JPEG_HDEC_WriteReg(pJpegHandle->pJpegRegVirAddr,JPGD_REG_PD_Y_CFG, (HI_S32)stResumeValue.u32Pdy); JPEG_HDEC_WriteReg(pJpegHandle->pJpegRegVirAddr,JPGD_REG_PD_CBCR_CFG, (HI_S32)stResumeValue.u32Pdcbcr); #if 0 JPEG_TRACE("===============================================================\n"); JPEG_TRACE("pJpegHandle->u32ResByteConsum = %d\n",pJpegHandle->u32ResByteConsum); JPEG_TRACE("stResumeValue.u32ResumeData0 = %d\n",stResumeValue.u32ResumeData0); JPEG_TRACE("stResumeValue.u32ResumeData1 = %d\n",stResumeValue.u32ResumeData1); JPEG_TRACE("stResumeValue.u32ResBitRemain = %d\n",stResumeValue.u32ResBitRemain); JPEG_TRACE("stResumeValue.u32ResMcuy = %d\n",stResumeValue.u32ResMcuy); JPEG_TRACE("stResumeValue.u32Pdy = %d\n",stResumeValue.u32Pdy); JPEG_TRACE("stResumeValue.u32Pdcbcr = %d\n",stResumeValue.u32Pdcbcr); JPEG_TRACE("===============================================================\n"); #endif }
LOCAL JPEG_RET_E GetAPP0() { #define JFIF_LEN 14 uint16 length = 0; uint8 b[JFIF_LEN]; uint16 buffp = 0; uint8 c = 0; if( !get_short_word(&length) || length < 2) { JPEG_TRACE("[GetAPP0] get length error, length = %d", length); return JPEG_FAILED; } length -= 2; /* See if a JFIF APP0 marker is present */ if (length >= JFIF_LEN) { for (buffp = 0; buffp < JFIF_LEN; buffp++) { if (!get_char(&c)) { JPEG_TRACE("[GetAPP0] get app0 error " ); return JPEG_FAILED; } b[buffp] = c; } length -= JFIF_LEN; while (length-- > 0)/* skip any remaining data */ { if (!get_char(&c)) { JPEG_TRACE("[GetAPP0] skip error " ); return JPEG_FAILED; } } } return JPEG_SUCCESS; }
/* but it will never be 0 or FF */ LOCAL BOOLEAN GetNextMarker(uint32 *ret) { uint8 c = 0; int32 nbytes = 0; do { /* skip any non-FF bytes */ do { nbytes++; if (!get_char(&c)) { JPEG_TRACE("[GetNextMarker] get next marker failed !"); return FALSE; } } while (c != 0xFF); do { /* skip any duplicate FFs */ nbytes++; if (!get_char(&c)) { JPEG_TRACE("[GetNextMarker] get next marker failed !"); return FALSE; } } while(c == 0xFF); }while (c == 0); /* repeat if it was a stuffed FF/00 */ if(nbytes != 2) { JPEG_TRACE("Warning!There are some bytes is stuffed in the head!\n"); } *ret = c; return TRUE; }
jpeg_build_huffman_index_baseline(j_decompress_ptr cinfo, huffman_index *index) { if (cinfo->global_state == DSTATE_READY) { JPEG_TRACE("Baseline Mode\n"); /* First call: initialize active modules */ transdecode_master_selection(cinfo); cinfo->global_state = DSTATE_RDCOEFS; } if (cinfo->global_state == DSTATE_RDCOEFS) { /* Absorb whole file into the coef buffer */ for (;;) { int retcode; /* Call progress monitor hook if present */ if (cinfo->progress != NULL) (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); /* Absorb some more input */ retcode = (*cinfo->inputctl->consume_input_build_huffman_index) (cinfo, index, 0); if (retcode == JPEG_SUSPENDED) return FALSE; if (retcode == JPEG_REACHED_EOI) break; if (retcode == JPEG_SCAN_COMPLETED) break; /* Advance progress counter if appropriate */ if (cinfo->progress != NULL && (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) { if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) { /* startup underestimated number of scans; ratchet up one scan */ cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows; } } } /* Set state so that jpeg_finish_decompress does the right thing */ cinfo->global_state = DSTATE_STOPPING; } /* At this point we should be in state DSTATE_STOPPING if being used * standalone, or in state DSTATE_BUFIMAGE if being invoked to get access * to the coefficients during a full buffered-image-mode decompression. */ if ((cinfo->global_state == DSTATE_STOPPING || cinfo->global_state == DSTATE_BUFIMAGE) && cinfo->buffered_image) { return TRUE; } /* Oops, improper usage */ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); return FALSE; /* keep compiler happy */ }
PUBLIC JPEG_RET_E ParseHead(JPEG_DEC_INPUT_PARA_T *jpeg_dec_input) { uint32 c = 0; /* Expect an SOI marker first */ while(1)/*lint !e716*/ { if ((!GetNextMarker(&c)) || (c == M_EOI) ) { JPEG_TRACE("[JPEG_HWParseHead] find the SOI marker error: %x", c); return JPEG_FAILED; } if(c == M_SOI) { break; } } /* Process markers until SOF */ c = ProcessTables(jpeg_dec_input); switch (c) { case M_ERROR: return JPEG_FAILED; case M_SOS: if(GetSOS() != JPEG_SUCCESS) { return JPEG_FAILED; } break; case M_EOI: return JPEG_FAILED; default: return JPEG_FAILED; } return JPEG_SUCCESS; }
/* Return when an SOI, EOI, SOFn, or SOS is found */ PUBLIC JPEG_MARKER_E ProcessTables(JPEG_DEC_INPUT_PARA_T *jpeg_dec_input) { uint32 c = 0; while (TRUE)/*lint !e716*/ { if(!GetNextMarker(&c)) { return M_ERROR; } switch (c) { case M_SOF0: case M_SOF1: if(GetSOF(FALSE, jpeg_dec_input) != JPEG_SUCCESS) { return M_ERROR; } break; case M_SOF2: if(GetSOF(TRUE, jpeg_dec_input) != JPEG_SUCCESS) { return M_ERROR; } JPEG_TRACE("Sorry, we can not support the Progressive image!\n"); break; //return M_ERROR; case M_SOI: case M_EOI: case M_SOS: return c; case M_DHT: if(GetHuffTbl() != JPEG_SUCCESS) { return M_ERROR; } break; case M_DQT: if(GetQuantTbl() != JPEG_SUCCESS) { return M_ERROR; } break; case M_APP0: if(GetAPP0() != JPEG_SUCCESS) { return M_ERROR; } break; case M_DRI: if(GetDRI() != JPEG_SUCCESS) { return M_ERROR; } break; // case M_SOF1: case M_SOF3: case M_SOF5: case M_SOF6: case M_SOF7: case M_JPG: case M_SOF9: case M_SOF10: case M_SOF11: case M_SOF13: case M_SOF14: case M_SOF15: case M_DAC: case M_RST0: case M_RST1: case M_RST2: case M_RST3: case M_RST4: case M_RST5: case M_RST6: case M_RST7: case M_TEM: JPEG_TRACE("Unexpected marker 0x%02x\n", c); return M_ERROR; default: /* must be DNL, DHP, EXP, APPn, JPGn, COM, or RESn */ if(SkipVariable(jpeg_dec_input) != JPEG_SUCCESS) { return M_ERROR; } break; } } }
LOCAL JPEG_RET_E GetSOF(BOOLEAN isProgressive, JPEG_DEC_INPUT_PARA_T *jpeg_dec_input) { uint16 length = 0; uint16 width = 0; uint16 height = 0; uint8 ci = 0, c = 0; uint8 component_num = 0; int8 yuv_id = 0; jpeg_component_info *compptr; JPEG_CODEC_T *jpeg_fw_codec = Get_JPEGDecCodec(); jpeg_dec_input->progressive_mode = isProgressive; if(isProgressive) { JPEG_TRACE("\nJPEG Mode is: Progressive\n"); } else { JPEG_TRACE("JPEG Mode is: Baseline\n"); } if (!get_short_word(&length) || length < 8) /*get length*/ { JPEG_TRACE("GetSOF get length error %d", length); return JPEG_FAILED; } if (!get_char(&c)) /*get sample precision*/ { JPEG_TRACE("GetSOF pricision error, %d", c); return JPEG_FAILED; } if (c !=8 ) { JPEG_TRACE("ERROR!!! pricision = %d\n", c); return JPEG_FAILED; } if (!get_short_word(&height) || !get_short_word(&width)) { JPEG_TRACE("GetSOF get size error "); return JPEG_FAILED; } jpeg_dec_input->input_height = height; jpeg_dec_input->input_width = width; if ((jpeg_dec_input->input_height < 8)||(jpeg_dec_input->input_width < 8)) { JPEG_TRACE("WARNING!!! width =%d, height = %d\n", jpeg_dec_input->input_height, jpeg_dec_input->input_width); } if (!get_char(&component_num)) /*get the component number*/ { JPEG_TRACE("GetSOF get component num error"); return JPEG_FAILED; } if(component_num != 3) { JPEG_TRACE("WARNING!!! component num = %d\n", component_num); } /*check length*/ if (length != (component_num * 3 + 8)) { JPEG_TRACE("Error!!! length = %d\n", length); return JPEG_FAILED; } jpeg_fw_codec->num_components = component_num; JPEG_TRACE("JPEG: GetSOF, width=%d, height=%d\n",jpeg_dec_input->input_width, jpeg_dec_input->input_height); /*Caution: current we only support the YUV format, sequence is Y..U..V*/ // if (jpeg_dec_input->comp_info == NULL) /* do only once, even if suspend */ { jpeg_fw_codec->comp_info = (jpeg_component_info *)JpegDec_ExtraMemAlloc(component_num * sizeof(jpeg_component_info)); } for(ci = 0, compptr = jpeg_fw_codec->comp_info; ci < component_num; ci++, compptr++) { if (!get_char(&c)) { JPEG_TRACE("[GetSOF] get yuvid error = %d", c); return JPEG_FAILED; } yuv_id = c; compptr->component_index = ci; compptr->component_id = yuv_id; //index starts from 1, but in our program, ratio and tbl_map starts from 0, //so we need minus yuv_id to 1 before use it. Noted by xiaowei.luo@20090107 yuv_id--; if((yuv_id<0)||(yuv_id>2)) { JPEG_TRACE("Error!!! component id = %d\n", yuv_id); return JPEG_FAILED; } if (!get_char(&c)) /*get sample ratio*/ { JPEG_TRACE("Get sample ratio error"); return JPEG_FAILED; } compptr->h_samp_factor = (c >> 4) & 0x0F; compptr->v_samp_factor = (c ) & 0x0F; if(ci == 0) { compptr->MCU_width = compptr->h_samp_factor; compptr->MCU_height = compptr->v_samp_factor; }else { compptr->MCU_width = 1; compptr->MCU_height = 1; } if (!get_char(&c)) /*get quant table*/ { JPEG_TRACE("Get quant table error"); return JPEG_FAILED; } if(c >= 2/*JPEG_FW_CHR_ID*/) //be compliant with two chroma quant table. { #if 0 //JPEG_ERROR(JPEG_EID_MISSQUANT, "quant id = %d\n", c); return JPEG_FAILED; #else c -= 2; #endif } jpeg_fw_codec->tbl_map[yuv_id].quant_tbl_id = c; } c = (jpeg_fw_codec->comp_info[0].h_samp_factor << 4) | (jpeg_fw_codec->comp_info[0].v_samp_factor); if (1 == component_num) { jpeg_dec_input->input_mcu_info = JPEG_FW_YUV400; JPEG_TRACE("YUV Mode is: 4:0:0\n"); } else // componet num is 2 or 3 { switch(c) { case 0x11: jpeg_dec_input->input_mcu_info = JPEG_FW_YUV444; JPEG_TRACE("YUV Mode is: 4:4:4\n"); break; case 0x21: jpeg_dec_input->input_mcu_info = JPEG_FW_YUV422; JPEG_TRACE("YUV Mode is: 4:2:2, V1,H2\n"); break; case 0x41: jpeg_dec_input->input_mcu_info = JPEG_FW_YUV411; JPEG_TRACE("YUV Mode is: 4:1:1\n"); break; case 0x14: jpeg_dec_input->input_mcu_info = JPEG_FW_YUV411_R; JPEG_TRACE("YUV Mode is: 4:1:1, V4, H1\n"); break; case 0x22: jpeg_dec_input->input_mcu_info = JPEG_FW_YUV420; JPEG_TRACE("YUV Mode is: 4:2:0\n"); break; case 0x12: jpeg_dec_input->input_mcu_info = JPEG_FW_YUV422_R; JPEG_TRACE("YUV Mode is: 4:2:2, V2,H1\n"); break; default: // JPEG_ERROR(JPEG_EID_SAMPLEFORMAT, "format = %d\n", sample_format); JPEG_TRACE("unsupport format = %d", c); return JPEG_FAILED; } //check u sample ratio c = (jpeg_fw_codec->comp_info[1].h_samp_factor << 4) | (jpeg_fw_codec->comp_info[1].v_samp_factor); if (0x11 != c) { JPEG_TRACE("unsupport u sample ratio = %d", c); return JPEG_FAILED; } //check v sample ratio if (component_num > 2) { //check u sample ratio c = (jpeg_fw_codec->comp_info[2].h_samp_factor << 4) | (jpeg_fw_codec->comp_info[2].v_samp_factor); if (0x11 != c) { JPEG_TRACE("unsupport v sample ratio = %d", c); return JPEG_FAILED; } } } return JPEG_SUCCESS; }
LOCAL JPEG_RET_E GetQuantTbl() { uint16 length = 0; uint8 n = 0, j = 0, prec = 0; uint8 *quant_ptr = NULL; int32 has_two_chroma_quant_tbl = FALSE; JPEG_CODEC_T *jpeg_fw_codec = Get_JPEGDecCodec(); jpeg_fw_codec->using_default_quant_tab = FALSE; if (!get_short_word(&length) || length < 2) { JPEG_TRACE("[GetHuffTbl] get length error, length = %d", length); return JPEG_FAILED; } length -= 2; while (length > 0) { if (!get_char(&n)) { JPEG_TRACE("[GetQuantTbl] get table error"); return JPEG_FAILED; } prec = n>>4; n &= 0x0F; if (prec) { JPEG_TRACE("error quant table precision = %d\n", prec); // return JPEG_FAILED; } if (n >= 2) { #if 0 JPEG_TRACE("warning: error quant table id = %d\n", n); return JPEG_FAILED; #else n -= 2; #endif } if (n > 1) { JPEG_TRACE("warning: error quant table id = %d\n", n); //return JPEG_SUCCESS; //removed by xwluo, @20090330 has_two_chroma_quant_tbl = TRUE; } jpeg_fw_codec->quant_tbl[n] = (uint8*)JpegDec_ExtraMemAlloc((sizeof(uint8))*64); quant_ptr = &jpeg_fw_codec->quant_tbl[n][0]; if (prec == 0) { for(j = 0; j < 64; j+=4) { uint8 c = 0; if (!get_char(&c)) { JPEG_TRACE("[GetQuantTbl] get table error"); return JPEG_FAILED; } quant_ptr[jpeg_fw_zigzag_order[j]] = c; if (!get_char(&c)) { JPEG_TRACE("[GetQuantTbl] get table error"); return JPEG_FAILED; } quant_ptr[jpeg_fw_zigzag_order[j+1]] = c; if (!get_char(&c)) { JPEG_TRACE("[GetQuantTbl] get table error"); return JPEG_FAILED; } quant_ptr[jpeg_fw_zigzag_order[j+2]] = c; if (!get_char(&c)) { JPEG_TRACE("[GetQuantTbl] get table error"); return JPEG_FAILED; } quant_ptr[jpeg_fw_zigzag_order[j+3]] = c; } } else { for(j = 0; j < 64; j+=4) { uint16 c = 0; if (!get_short_word(&c)) { JPEG_TRACE("[GetQuantTbl] get table error"); return JPEG_FAILED; } quant_ptr[jpeg_fw_zigzag_order[j]] = (uint8)c; if (!get_short_word(&c)) { JPEG_TRACE("[GetQuantTbl] get table error"); return JPEG_FAILED; } quant_ptr[jpeg_fw_zigzag_order[j+1]] = (uint8)c; if (!get_short_word(&c)) { JPEG_TRACE("[GetQuantTbl] get table error"); return JPEG_FAILED; } quant_ptr[jpeg_fw_zigzag_order[j+2]] = (uint8)c; if (!get_short_word(&c)) { JPEG_TRACE("[GetQuantTbl] get table error"); return JPEG_FAILED; } quant_ptr[jpeg_fw_zigzag_order[j+3]] = (uint8)c; } } if (length < (64 + 1 + 64 * prec)) { JPEG_TRACE("[GetQuantTbl] huffman table error!"); return JPEG_FAILED; } else { length -= (64 + 1 + 64 * prec); } } #if 0 if(has_two_chroma_quant_tbl) //check if these two chroma quant tables are same or not. { uint8 *u_tbl_ptr = &jpeg_fw_codec->quant_tbl[1][0]; uint8 *v_tbl_ptr = &jpeg_fw_codec->quant_tbl[2][0]; for(j = 0; j < 64; j++) { if(u_tbl_ptr[j] != v_tbl_ptr[j]) { return JPEG_FAILED; } } JPEG_TRACE("U and V quant table is same\n"); } #endif return JPEG_SUCCESS; }
LOCAL JPEG_RET_E GetHuffTbl() { uint16 length = 0; uint16 i = 0, index = 0, count = 0; HUFF_TBL_T *htblptr = NULL; uint8 *bits; uint8 *huffval; uint8 *default_bits; uint8 *default_huffval; JPEG_CODEC_T *jpeg_fw_codec = Get_JPEGDecCodec(); uint8 c = 0; if(!g_huff_tbl_malloced) { for(i = 0; i < NUM_HUFF_TBLS; i++) { jpeg_fw_codec->dc_huff_tbl[i].bits = (uint8*)JpegDec_ExtraMemAlloc((sizeof(uint8))*(MAX_BITS_SIZE+1)); jpeg_fw_codec->dc_huff_tbl[i].huffval = (uint8*)JpegDec_ExtraMemAlloc((sizeof(uint8))*(AC_SYMBOL_NUM+1)); jpeg_fw_codec->ac_huff_tbl[i].bits = (uint8*)JpegDec_ExtraMemAlloc((sizeof(uint8))*(MAX_BITS_SIZE+1)); jpeg_fw_codec->ac_huff_tbl[i].huffval = (uint8*)JpegDec_ExtraMemAlloc((sizeof(uint8))*(AC_SYMBOL_NUM+1)); } g_huff_tbl_malloced = TRUE; } if (!get_short_word(&length) || length < 2) { JPEG_TRACE("[GetHuffTbl] get length error, length = %d", length); return JPEG_FAILED; } length -= 2; while (length > 0) { if (!get_char(&c)) { JPEG_TRACE("[GetHuffTbl] get table error"); return JPEG_FAILED; } //clear the invalid bits index = c & 0x13; if (index & 0x10) { index -= 0x10; /* AC table definition */ htblptr = &(jpeg_fw_codec->ac_huff_tbl[index]); bits = htblptr->bits; huffval = htblptr->huffval; if(index == 00) //luma { default_bits = jpeg_fw_lum_ac_bits_default; default_huffval = jpeg_fw_lum_ac_huffvalue_default; } else //chroma { default_bits = jpeg_fw_chr_ac_bits_default; default_huffval = jpeg_fw_chr_ac_huffvalue_default; } } else { /* DC table definition */ htblptr = &(jpeg_fw_codec->dc_huff_tbl[index]); bits = htblptr->bits; huffval = htblptr->huffval; if(index == 00) //luma { default_bits = jpeg_fw_lum_dc_bits_default; default_huffval = jpeg_fw_lum_dc_huffvalue_default; } else //chroma { default_bits = jpeg_fw_chr_dc_bits_default; default_huffval = jpeg_fw_chr_dc_huffvalue_default; } } /*read bits*/ bits[0] = 0; count = 0; for (i = 1; i <= 16; i++) { if (!get_char(&c)) { JPEG_TRACE("[GetHuffTbl] get table error"); return JPEG_FAILED; } bits[i] = c; if(bits[i] != default_bits[i]) { jpeg_fw_codec->using_default_huff_tab = FALSE; } count += bits[i]; } if (count > 256) { JPEG_TRACE("huff value table len = %d is larger than 256\n", count); return JPEG_FAILED; } for (i = 0; i < count; i++) { if (!get_char(&c)) { JPEG_TRACE("[GetHuffTbl] get table error"); return JPEG_FAILED; } huffval[i] = c; if(huffval[i] != default_huffval[i]) { jpeg_fw_codec->using_default_huff_tab = FALSE; } } if (length < (1 + 16 + count)) { JPEG_TRACE("[GetHuffTbl] huffman table error!"); return JPEG_FAILED; } else { length -= (1 + 16 + count); } // htblptr->bits = bits; // htblptr->huffval = huffval; } return JPEG_SUCCESS; }
PUBLIC void JpegEnc_HwTopRegCfg(void) { int32 cmd = 0; JPEG_CODEC_T *jpeg_fw_codec = Get_JPEGEncCodec(); // uint32 pTableAddr = (uint32)VSP_MEMO10_ADDR; uint32 int_mask = 0; uint32 endian_sel = 0; SCI_ASSERT(jpeg_fw_codec != PNULL); #if _CMODEL_ // AllocMCUBuf(); // enc_init_bitstream(jpeg_fw_codec); VSP_Init_CModel(); // Generate_VlcTable(); #endif //_CMODEL_ #if 0 VSP_Reset(); #else //backup the INT register for the VSP reset will clear it int_mask = JPG_READ_REG(JPG_GLB_REG_BASE+GLB_INT_EN_OFFSET, "GLB_INT_EN_OFFSET: read INT bit"); // JPEG_TRACE("[JpegEnc_VspTopRegCfg] int mask = 0x%x", int_mask); /*reset vsp*/ JPG_Reset(); #endif // cmd = (1<<3); // VSP_WRITE_REG(VSP_DCAM_REG_BASE+DCAM_CFG_OFF, cmd, "DCAM_CFG: DCAM init"); //Source Size init cmd = (jpeg_fw_codec->c_width & 0x01fff); JPG_WRITE_REG(JPG_GLB_REG_BASE+GLB_PITCH_OFFSET, cmd, "configure jpeg pitch, pixel unit"); #if defined(_VSP_) && defined(SMALL_SYS) //enable dcam interrupt //*(volatile uint32 *)0x60b00024 |= (1<<42); *(volatile uint32 *)0x60b00024 |= (1<<3) | (1 << 1); // #endif #if 0 //INT Enable cmd = (1 << 7) | (1 << 8) | (1 << 14); JPG_WRITE_REG(VSP_DCAM_REG_BASE+DCAM_INT_MASK_OFF, cmd, "DCAM_INT_MASK: enable related INT bit"); #else //restore the INT int_mask |= (1 << 3) |(1 << 1)| (1 << 0); JPG_WRITE_REG(JPG_GLB_REG_BASE+GLB_INT_EN_OFFSET, int_mask, "GLB_INT_EN_OFFSET: enable related INT bit"); JPEG_TRACE("[JpegEnc_HwTopRegCfg] after reset, int mask = 0x%x", JPG_READ_REG(JPG_GLB_REG_BASE+GLB_INT_EN_OFFSET, "GLB_INT_EN_OFFSET: read INT bit")); #endif #ifndef DCAM_VSP_LCD #if defined(SMALL_SYS) && defined(_ARM_) *(volatile uint32 *)0x7130000 |= (1<<20); //INTC1 enable *(volatile uint32 *)0x7150008 |= (1<<10) //JPEG interrupt is bit10 of INTC1 //enable dcam interrupt //*(volatile uint32 *)0x20a00010 |= (1<<27); //INT Enable //cmd = (1 << 7) | (1 << 8) | (1 << 9); //init int DCAMMODULE_Init(); // VSP_WRITE_REG(VSP_DCAM_REG_BASE+DCAM_INT_MASK_OFF, cmd, "DCAM_INT_MASK: enable related INT bit"); //register the int fun; DCAMMODULE_RegisterIntFunc(VSP_BSM_DONE_ID, BSM_INT_PROC); DCAMMODULE_RegisterIntFunc(VSP_MEA_DONE_ID, MBIO_INT_PROC); // DCAMMODULE_RegisterIntFunc(VSP_TIMEOUT_ID, TIME_OUT_INT_PROC); DCAMMODULE_RegisterIntFunc(VSP_VLC_DONE_ID, VLC_DONE_INT_PROC); #endif #endif #if _CMODEL_ //Source Buffer0 and Buffer1 Addr Init JPG_WRITE_REG(JPG_GLB_REG_BASE+GLB_FRM_ADDR0_OFFSET, SRC_FRAME0_Y>>2, "Source Y0 Frame buffer "); JPG_WRITE_REG(JPG_GLB_REG_BASE+GLB_FRM_ADDR1_OFFSET, SRC_FRAME0_UV>>2, "Source UV0 Frame buffer "); JPG_WRITE_REG(JPG_GLB_REG_BASE+GLB_FRM_ADDR2_OFFSET, SRC_FRAME1_Y>>2, "Source Y1 Frame buffer "); JPG_WRITE_REG(JPG_GLB_REG_BASE+GLB_FRM_ADDR3_OFFSET, SRC_FRAME1_UV>>2, "Source UV1 Frame buffer "); // VSP_WRITE_REG(VSP_AHBM_REG_BASE+AHBM_BASE_ADDR_OFFSET, (uint32)/*jpeg_fw_codec->stream_0*/0>>26, "AHBM_BASE_ADDR: PSRAM base address offset"); //encoded bitstream addr0 and addr1 JPG_WRITE_REG(JPG_GLB_REG_BASE+GLB_FRM_ADDR4_OFFSET, BIT_STREAM_ENC_0>>2, "Encoded bit stream buffer0 "); JPG_WRITE_REG(JPG_GLB_REG_BASE+GLB_FRM_ADDR5_OFFSET, BIT_STREAM_ENC_1>>2, "Encoded bit stream buffer1 "); #else //Source Buffer0 and Buffer1 Addr Init // VSP_WRITE_REG(pTableAddr+ 16, (uint32)(jpeg_fw_codec->YUV_Info_0.y_data_ptr)>>2, "Source Y0 Frame buffer "); // VSP_WRITE_REG(pTableAddr+ 20, (uint32)(jpeg_fw_codec->YUV_Info_1.y_data_ptr)>>2, "Source Y1 Frame buffer "); JPG_WRITE_REG(JPG_GLB_REG_BASE+GLB_FRM_ADDR0_OFFSET, (uint32)(jpeg_fw_codec->YUV_Info_0.y_data_ptr), "Source Y0 Frame buffer "); JPG_WRITE_REG(JPG_GLB_REG_BASE+GLB_FRM_ADDR1_OFFSET, (uint32)(jpeg_fw_codec->YUV_Info_0.u_data_ptr), "Source U0 Frame buffer "); JPG_WRITE_REG(JPG_GLB_REG_BASE+GLB_FRM_ADDR6_OFFSET, (uint32)(jpeg_fw_codec->YUV_Info_0.v_data_ptr), "Source V0 Frame buffer "); JPG_WRITE_REG(JPG_GLB_REG_BASE+GLB_FRM_ADDR0_OFFSET, (uint32)(jpeg_fw_codec->YUV_Info_1.y_data_ptr), "Source Y1 Frame buffer "); JPG_WRITE_REG(JPG_GLB_REG_BASE+GLB_FRM_ADDR1_OFFSET, (uint32)(jpeg_fw_codec->YUV_Info_1.u_data_ptr), "Source U1 Frame buffer "); JPG_WRITE_REG(JPG_GLB_REG_BASE+GLB_FRM_ADDR6_OFFSET, (uint32)(jpeg_fw_codec->YUV_Info_1.v_data_ptr), "Source V1 Frame buffer "); // VSP_WRITE_REG(VSP_AHBM_REG_BASE+AHBM_BASE_ADDR_OFFSET, (uint32)jpeg_fw_codec->stream_0>>26, "AHBM_BASE_ADDR: PSRAM base address offset"); //encoded bitstream addr0 and addr1 JPG_WRITE_REG(JPG_GLB_REG_BASE+GLB_FRM_ADDR4_OFFSET, (uint32)(jpeg_fw_codec->stream_0), "Encoded bit stream buffer0 "); JPG_WRITE_REG(JPG_GLB_REG_BASE+GLB_FRM_ADDR5_OFFSET, (uint32)(jpeg_fw_codec->stream_1), "Encoded bit stream buffer1 "); #endif //_CMODEL_ SCI_TRACE_LOW("stream0: %x, stream1: %x.\n", (uint32_t)jpeg_fw_codec->stream_0,(uint32_t)jpeg_fw_codec->stream_1); //VSP_CFG0 cmd = (1 << 6) | (0 << 4) | (1 << 2)| (1 << 1) | (1 << 0); JPG_WRITE_REG(JPG_GLB_REG_BASE+GLB_CTRL_OFFSET, cmd, "GLB_CTRL: enable JPEG encoder"); //VSP_CFG1 jpeg_fw_codec->uv_interleaved = (jpeg_fw_codec->YUV_Info_0.v_data_ptr == NULL)?1:0;//1: uv_interleaved, two plane, 0: three plane cmd = (((!jpeg_fw_codec->uv_interleaved) << 27)) | (jpeg_fw_codec->input_mcu_info << 24) | ((jpeg_fw_codec->mcu_num_y & 0x3ff) << 12) | (jpeg_fw_codec->mcu_num_x & 0x3ff); JPG_WRITE_REG(JPG_GLB_REG_BASE+MB_CFG_OFFSET, cmd, "uv_interleaved, input mcu infor, mcu max number x and y"); //cmd = ((uint32)0xffff << 0) | (0 << 16); // cmd = (0<< 31)|(0 << 30)|((uint32)TIME_OUT_CLK); // VSP_WRITE_REG(VSP_DCAM_REG_BASE+DCAM_VSP_TIME_OUT_OFF, cmd, "DCAM_VSP_TIME_OUT: disable hardware timer out"); // cmd = (cmd<<27)|0x1ff; JPG_WRITE_REG(JPG_GLB_REG_BASE+BUS_GAP_OFFSET, 0, "BUS_GAP: 0"); #if 0 cmd |= (1<<18)|(1<<21); #endif // cmd = VSP_READ_REG(VSP_AHBM_REG_BASE,"READ VSP_AHBM_REG_BASE"); // cmd |= (1<<21); // VSP_WRITE_REG(VSP_AHBM_REG_BASE,cmd,"configure interleave mode of input yuv(bit21):0,uvuv;1,vuvu"); //now, for uv_interleaved // cmd = ((jpeg_fw_codec->c_height>>jpeg_fw_codec->scale_factor) * (jpeg_fw_codec->c_width>>jpeg_fw_codec->scale_factor))>>2; //word unit #if 0 //def CHIP_ENDIAN_LITTLE if (jpeg_fw_codec->YUV_Info_0.input_endian == 1) { //little endian endian_sel = 0x5; }else { //big endian endian_sel = 0x4; } #endif // VSP_WRITE_REG(VSP_AHBM_REG_BASE+AHBM_ENDAIN_SEL_OFFSET, cmd, "configure uv offset"); //MEA // VSP_WRITE_REG(VSP_MEA_REG_BASE+MEA_REF_CFG_OFF, (0), "MEA_REF_CFG: transfer_en disable"); // VSP_WRITE_REG(VSP_MEA_REG_BASE+MEA_CFG1_OFF, (1<<5), "MEA_CFG1: Use hardware pipeline"); return; }
LOCAL JPEG_RET_E GetSOS() { uint16 length = 0; uint8 i = 0, c = 0, cc = 0, n = 0, ci = 0; uint8 yuv_id = 0; jpeg_component_info *compptr; JPEG_CODEC_T *jpeg_fw_codec = Get_JPEGDecCodec(); if (!get_short_word(&length) || length < 3) { JPEG_TRACE("[GetSOS] get length error"); return JPEG_FAILED; } if (!get_char(&n))/* Number of components */ { JPEG_TRACE("[GetSOS] get number of component error"); return JPEG_FAILED; } JPEG_PRINTF("component = %d\n", n); length -= 3; if (length != ( n* 2 + 3)) { JPEG_PRINTF("error length = %d\n", length); return JPEG_FAILED; } jpeg_fw_codec->comps_in_scan = n; /*CAUTION: current we only support YUV format, and the scan sequence is Y..U..V*/ for (i = 0, yuv_id = 1; i < n; i++, yuv_id++) { if (!get_char(&cc)) /*get component id*/ { JPEG_TRACE("[GetSOS] get component id error"); return JPEG_FAILED; } if (!get_char(&c)) /*get dc/ac table*/ { JPEG_TRACE("[GetSOS] get dc/ac table error"); return JPEG_FAILED; } length -= 2; if(cc != yuv_id) { JPEG_TRACE("sorry, this scan sequence not support\n"); return JPEG_FAILED; } /*set huffman table*/ jpeg_fw_codec->tbl_map[i].dc_huff_tbl_id = (c>>4)&0x0F; jpeg_fw_codec->tbl_map[i].ac_huff_tbl_id = c&0x0F; for (ci = 0, compptr = jpeg_fw_codec->comp_info; ci < jpeg_fw_codec->num_components; ci++, compptr++) { if (cc == compptr->component_id) { jpeg_fw_codec->comp_id_map[i] = cc; goto id_found; } } id_found: JPEG_TRACE("JPEG Component Info: component id = %d, dc_tbl_no = %d, ac_tbl_no = %d\n", jpeg_fw_codec->comp_id_map[i],jpeg_fw_codec->tbl_map[i].dc_huff_tbl_id, jpeg_fw_codec->tbl_map[i].ac_huff_tbl_id); } /* Collect the additional scan parameters Ss, Se, Ah/Al. */ if (!get_char(&c) || ! get_char(&cc)) { JPEG_TRACE("[GetSOS] get ss/se error"); return JPEG_FAILED; } jpeg_fw_codec->Ss = c; jpeg_fw_codec->Se = cc; if (!get_char(&c)) { JPEG_TRACE("[GetSOS] get ah/al error"); return JPEG_FAILED; } jpeg_fw_codec->Ah = (c >> 4) & 15; jpeg_fw_codec->Al = (c ) & 15; JPEG_TRACE("JTRC_SOS_PARAMS: Ss = %d, Se = %d, Ah = %d, Al = %d\n", jpeg_fw_codec->Ss, jpeg_fw_codec->Se, jpeg_fw_codec->Ah, jpeg_fw_codec->Al); /* Prepare to scan data & restart markers */ jpeg_fw_codec->next_restart_num = 0; /* Count another SOS marker */ jpeg_fw_codec->input_scan_number++; return JPEG_SUCCESS; }
void START_SW_ENCODE(uint16 total_mcu_num) { JPEG_CODEC_T *JpegCodec = Get_JPEGEncCodec(); uint32 raw_height = total_mcu_num * JpegCodec->mcu_height * JpegCodec->mcu_width/JpegCodec->width; uint16 x = 0, y = 0; uint8 *y_coeff = JpegCodec->YUV_Info_0.y_data_ptr; uint8 *u_coeff = JpegCodec->YUV_Info_0.u_data_ptr; uint8 *v_coeff = JpegCodec->YUV_Info_0.v_data_ptr; uint16 mcu_num_x = JpegCodec->mcu_num_x; uint16 mcu_num_y = (uint16)(raw_height / (JpegCodec->mcu_height)); int32 clock_time = 1000; // JPEG_CallBack_Frame_To_MCU CopyMCUToCoeff; if(JpegCodec->mea_bfr1_valid) { y_coeff = JpegCodec->YUV_Info_1.y_data_ptr; u_coeff = JpegCodec->YUV_Info_1.u_data_ptr; v_coeff = JpegCodec->YUV_Info_1.v_data_ptr; } g_mea_reg_ptr->MEA_CFG2 = 0; //reset! switch(JpegCodec->input_mcu_info) { case JPEG_FW_YUV422: // CopyMCUToCoeff = CopyCoeffToMCU422_UV; g_block_num_in_one_mcu = 4; break; case JPEG_FW_YUV420: // CopyMCUToCoeff = CopyCoeffToMCU420_UV; g_block_num_in_one_mcu = 6; break; default: break; } /*for every MCU do following*/ for (y = 0; y < mcu_num_y; y++) { for (x = 0; x < mcu_num_x; x++) { // fprintf (g_pfVlcEvent, "y: %d x: %d\n", y, x); if(x==7 && y == 15) { PRINTF(""); } /*1, copy coeff data to correspondig blocks*/ // CopyMCUToCoeff((uint8 *)y_coeff, (uint8 *)u_coeff, (uint8 *)v_coeff, x, y); /*quantilization is done in huffman encode*/ /*2, call EncodeMCU*/ JPEG_EncodeMCU(); } } if((JpegCodec->work_mode == SWITCH_MODE) || ((JpegCodec->is_last_slice)&&(JpegCodec->work_mode == ALONE_MODE))) { g_int_vlc_done = 1; clear_vlc(); // clear_bsm_bfr(1, 1); g_pre_dc_value[0] = 0; g_pre_dc_value[1] = 0; g_pre_dc_value[2] = 0; } #if 0//defined(TEST_VECTOR) // clear_vlc_buffer(); /*byte align*/ { extern uint32 jremain_bit_num; int stuffingBis; int nBits = 32 - jremain_bit_num; //left bits in bsm nBits = nBits & 7; stuffingBis = 8 - nBits; //if(stuffingBis < 8) { outputBits_vrf(0, stuffingBis); } } #endif // jpeg_end: if(raw_height < JpegCodec->c_height) { JPEG_TRACE("Slice encoding end...\n"); }else { JPEG_TRACE("JPEG encoding Finished...\n\n"); } MEA_INT_PROC(); }
/***************************************************************************** * func : JPEG_HDEC_SendStreamFromFile * description : CNcomment: 码流来源文件 * param[in] : cinfo CNcomment: 解码对象 * param[in] : NA * retval : HI_SUCCESS CNcomment: 成功 * retval : HI_FAILURE CNcomment: 失败 * others: : NA *****************************************************************************/ HI_S32 JPEG_HDEC_SendStreamFromFile(j_decompress_ptr cinfo) { JPG_INTTYPE_E eIntStatus = JPG_INTTYPE_NONE; HI_BOOL bRetVal = HI_FALSE; HI_BOOL bReachEOF = HI_FALSE; HI_BOOL bStartDec = HI_FALSE; HI_S32 s32Cnt = 0; #ifdef CONFIG_JPEG_FPGA_TEST_SAVE_SCEN_ENABLE HI_BOOL bStartFirst = HI_TRUE; #endif #ifdef CONFIG_JPEG_SUSPEND HI_BOOL bSuspendSingal = HI_FALSE; HI_BOOL bResumeSingal = HI_FALSE; HI_BOOL bResumeOk = HI_FALSE; #endif HI_U32 u32ReadDataSize = 0; HI_U32 u32ResumeSize = 0; /** ** the continue stream size should big than 16bytes ** CNcomment:每一段续码流必须大于16个字节,保守 CNend\n **/ HI_U32 u32NeedDecCnt = 0; HI_CHAR* pStreamStartPhyAddr = NULL; HI_CHAR* pStreamStartVirAddr = NULL; HI_CHAR* pStreamEndPhyAddr = NULL; HI_S32 s32Ret = HI_SUCCESS; JPEG_HDEC_HANDLE_S_PTR pJpegHandle = (JPEG_HDEC_HANDLE_S_PTR)(cinfo->client_data); #ifdef CONFIG_JPEG_FPGA_TEST_SAVE_SCEN_ENABLE /** ** output the scen message to file ** CNcomment:导解码现场 CNend\n **/ if(HI_TRUE == pJpegHandle->bSaveScen) { HI_JPEG_OpenScenFile(cinfo); } #endif /** ** tell the hard the stream is end. ** CNcomment:这个是必须的,要告诉硬件码流已经读完了,否则硬件会一直解 ** 硬件本省无法判断读码流结束 CNend\n **/ bReachEOF = HI_FALSE; pStreamStartVirAddr = pJpegHandle->stHDecDataBuf.pSaveStreamVirBuf; u32ReadDataSize = pJpegHandle->stHDecDataBuf.u32ReadDataSize; /** ** if suspend happen before hard decode,here not deal with this instance. ** because this instance should check whether is suspend and set para again. ** it cost many times.it can return to soft decode,just ok to see the show. ** CNcomment:如果是解码之前进行待机,这里就不做处理了,因为会耗时间,硬件解码要是失败 ** 会自动退回软件解码,照样可以正常显示 CNend\n **/ do { /** ** the consume stream size ** CNcomment:消耗的码流数 CNend\n **/ #ifdef CONFIG_JPEG_SUSPEND if(HI_TRUE == bResumeOk) { /** ** the consume stream size ** CNcomment:消耗的码流数 CNend\n **/ u32ResumeSize = u32NeedDecCnt - pJpegHandle->u32ResByteConsum; memcpy(pJpegHandle->stHDecDataBuf.pSaveStreamVirBuf, \ pJpegHandle->stHDecDataBuf.pSaveStreamVirBuf + pJpegHandle->u32ResByteConsum,\ u32ResumeSize); } #endif if(0 != cinfo->src->bytes_in_buffer) { /** ** copy the leave stream to save stream buffer and start decode ** CNcomment:拷贝剩余码流到码流buffer中,然后启动解码 CNend\n **/ u32NeedDecCnt = cinfo->src->bytes_in_buffer; memcpy(pJpegHandle->stHDecDataBuf.pSaveStreamVirBuf, \ (char*)cinfo->src->next_input_byte, \ u32NeedDecCnt); if( (0xFF == (*(cinfo->src->next_input_byte + u32NeedDecCnt - 2))) &&(0xD9 == (*(cinfo->src->next_input_byte + u32NeedDecCnt - 1)))) { bReachEOF = HI_TRUE; } else { pJpegHandle->stHDecDataBuf.bReadToDataBuf = HI_TRUE; pJpegHandle->stHDecDataBuf.pSaveStreamVirBuf = pStreamStartVirAddr + u32NeedDecCnt; pJpegHandle->stHDecDataBuf.u32ReadDataSize = \ pJpegHandle->stHDecDataBuf.u32ReadDataSize - u32NeedDecCnt; bRetVal = (*cinfo->src->fill_input_buffer)(cinfo);/*lint !e64 ignore by y00181162, because return value is ok */ if(HI_FALSE == bRetVal) { goto FAIL; } u32NeedDecCnt = u32NeedDecCnt + cinfo->src->bytes_in_buffer; /** 还原码流首地址 **/ pJpegHandle->stHDecDataBuf.pSaveStreamVirBuf = pStreamStartVirAddr; pJpegHandle->stHDecDataBuf.u32ReadDataSize = u32ReadDataSize; } } if(0 == cinfo->src->bytes_in_buffer) { /** ** there is not stream,should read data to save stream buffer ** CNcomment:没有码流了,需要读码流,这时候直接读码流大小字节到码流buffer中 CNend\n **/ pJpegHandle->stHDecDataBuf.bReadToDataBuf = HI_TRUE; pJpegHandle->stHDecDataBuf.pSaveStreamVirBuf = pStreamStartVirAddr + u32ResumeSize; pJpegHandle->stHDecDataBuf.u32ReadDataSize = pJpegHandle->stHDecDataBuf.u32ReadDataSize - u32ResumeSize; bRetVal = (*cinfo->src->fill_input_buffer)(cinfo); /*lint !e64 ignore by y00181162, because return value is ok */ if(HI_FALSE == bRetVal) { goto FAIL; } u32NeedDecCnt = u32ResumeSize + cinfo->src->bytes_in_buffer; pJpegHandle->stHDecDataBuf.pSaveStreamVirBuf = pStreamStartVirAddr; pJpegHandle->stHDecDataBuf.u32ReadDataSize = u32ReadDataSize; } if(HI_TRUE == bStartDec && u32NeedDecCnt < pJpegHandle->stHDecDataBuf.u32ReadDataSize) { bReachEOF = HI_TRUE; } if( (0xFF == (HI_UCHAR)pJpegHandle->stHDecDataBuf.pSaveStreamVirBuf[0]) \ && (0xD9 == (HI_UCHAR)pJpegHandle->stHDecDataBuf.pSaveStreamVirBuf[1]) \ && (2 == cinfo->src->bytes_in_buffer)) { /** ** strengthen the condition check ** CNcomment:加强条件判断 CNend\n **/ bReachEOF = HI_TRUE; } /** ** dinit the para ** CNcomment:去初始化相关变量 CNend\n **/ u32ResumeSize = 0; cinfo->src->bytes_in_buffer = 0; /** 刷码流数据 **/ #ifdef CONFIG_JPEG_USE_PRIVATE_MMZ s32Ret = HI_GFX_Flush(pJpegHandle->s32MMZDev,(HI_U32)pJpegHandle->stHDecDataBuf.pSaveStreamPhyBuf); #else s32Ret = HI_GFX_Flush((HI_U32)pJpegHandle->stHDecDataBuf.pSaveStreamPhyBuf); #endif if(HI_SUCCESS != s32Ret) { goto FAIL; } pStreamStartPhyAddr = pJpegHandle->stHDecDataBuf.pSaveStreamPhyBuf; pStreamEndPhyAddr = pStreamStartPhyAddr + u32NeedDecCnt; #ifdef CONFIG_JPEG_FPGA_TEST_SAVE_SCEN_ENABLE if(HI_TRUE == pJpegHandle->bSaveScen) {/** ** should save scen before start decode ** CNcomment:要在解码启动前保存现场,否则解码会失败 CNend\n **/ HI_JPEG_OutScenData(cinfo,pStreamStartPhyAddr,pStreamEndPhyAddr,pJpegHandle->stHDecDataBuf.pSaveStreamVirBuf,(HI_U64)u32NeedDecCnt,bStartFirst); bStartFirst = HI_FALSE; } #endif JPEG_HDEC_WriteReg(pJpegHandle->pJpegRegVirAddr,JPGD_REG_STADD, (HI_S32)pStreamStartPhyAddr); JPEG_HDEC_WriteReg(pJpegHandle->pJpegRegVirAddr,JPGD_REG_ENDADD,(HI_S32)pStreamEndPhyAddr); #ifdef CONFIG_JPEG_SUSPEND if(HI_FALSE == bStartDec || HI_TRUE == bResumeOk) #else if(HI_FALSE == bStartDec) #endif { /** ** strengthen the condition check ** CNcomment:是否为当前帧的最后一段续码。0:不是;1:是 CNend\n **/ JPEG_HDEC_WriteReg(pJpegHandle->pJpegRegVirAddr,JPGD_REG_RESUME,(bReachEOF ? JPG_EOF_VALUE : 0x0)); JPEG_HDEC_WriteReg(pJpegHandle->pJpegRegVirAddr,JPGD_REG_START, 0x1); bStartDec = HI_TRUE; } else { JPEG_HDEC_WriteReg(pJpegHandle->pJpegRegVirAddr,JPGD_REG_RESUME,(bReachEOF ? (JPG_EOF_VALUE|JPG_RESUME_VALUE) : JPG_RESUME_VALUE)); } eIntStatus = JPG_INTTYPE_ERROR; #ifdef CONFIG_JPEG_TEST_CHIP_RANDOM_RESET /** 软复位测试超时不能太长 **/ JPEG_TRACE("the waite up time is 1000ms\n"); s32Ret = JPEG_HDEC_GetIntStatus(pJpegHandle, &eIntStatus, 1000); JPEG_TRACE("waite up now\n"); #else s32Ret = JPEG_HDEC_GetIntStatus(pJpegHandle, &eIntStatus, 10000); #endif if(JPG_INTTYPE_ERROR == eIntStatus) { goto FAIL; } else if(JPG_INTTYPE_FINISH == eIntStatus) { break; } else if(JPG_INTTYPE_CONTINUE == eIntStatus) { #ifdef CONFIG_JPEG_SUSPEND bResumeOk = HI_FALSE; bSuspendSingal = HI_FALSE; bResumeSingal = HI_FALSE; JPEG_HDEC_GetSuspendSignal(pJpegHandle,&bSuspendSingal); JPEG_HDEC_GetResumeSignal(pJpegHandle,&bResumeSingal); if(HI_TRUE == bSuspendSingal || HI_TRUE == bResumeSingal) { JPEG_HDEC_Resume(cinfo); bResumeOk = HI_TRUE; } #endif continue; } else { goto FAIL; } } while (JPG_INTTYPE_FINISH != eIntStatus); cinfo->output_scanline = 0; cinfo->global_state = DSTATE_STOPPING; cinfo->inputctl->eoi_reached = HI_TRUE; cinfo->rec_outbuf_height = 1; cinfo->MCUs_per_row = JPEG_HDEC_ReadReg(pJpegHandle->pJpegRegVirAddr,JPGD_REG_PICSIZE)&0xffff; cinfo->MCU_rows_in_scan = ((HI_U32)JPEG_HDEC_ReadReg(pJpegHandle->pJpegRegVirAddr,JPGD_REG_PICSIZE)>>16)&0xffff; cinfo->blocks_in_MCU = cinfo->num_components; for(s32Cnt=0; s32Cnt<cinfo->num_components; s32Cnt++) { cinfo->MCU_membership[s32Cnt] = s32Cnt; } #if defined(CONFIG_JPEG_TEST_SAVE_BMP_PIC) && defined(CONFIG_JPEG_HARDDEC2ARGB) if(HI_TRUE == pJpegHandle->bDecARGB) { HI_JPEG_SaveBmp((HI_U32)pJpegHandle->stMiddleSurface.pMiddlePhy[0], \ (HI_U32)pJpegHandle->stOutDesc.stCropRect.w, \ (HI_U32)pJpegHandle->stOutDesc.stCropRect.h, \ pJpegHandle->stOutDesc.stOutSurface.u32OutStride[0], \ cinfo); } #endif #ifdef CONFIG_JPEG_HARDDEC2ARGB if( (HI_TRUE == pJpegHandle->stOutDesc.stOutSurface.bUserPhyMem) &&((HI_TRUE == pJpegHandle->bOutYCbCrSP) ||(HI_TRUE == pJpegHandle->bDecARGB))) #else if( (HI_TRUE == pJpegHandle->stOutDesc.stOutSurface.bUserPhyMem) &&(HI_TRUE == pJpegHandle->bOutYCbCrSP)) #endif { #ifdef CONFIG_JPEG_FPGA_TEST_SAVE_SCEN_ENABLE HI_JPEG_CloseScenFile(cinfo); #endif return HI_SUCCESS; } #ifdef CONFIG_JPEG_HARDDEC2ARGB if((HI_TRUE != pJpegHandle->bOutYCbCrSP) && (HI_TRUE != pJpegHandle->bDecARGB)) #else if(HI_TRUE != pJpegHandle->bOutYCbCrSP) #endif { #ifdef CONFIG_JPEG_FPGA_TEST_SAVE_SCEN_ENABLE HI_JPEG_CloseScenFile(cinfo); #endif return HI_SUCCESS; } if(0 != pJpegHandle->stJpegSofInfo.u32YSize) { memcpy(pJpegHandle->stOutDesc.stOutSurface.pOutVir[0],pJpegHandle->stMiddleSurface.pMiddleVir[0],pJpegHandle->stJpegSofInfo.u32YSize); } if(0 != pJpegHandle->stJpegSofInfo.u32CSize) { memcpy(pJpegHandle->stOutDesc.stOutSurface.pOutVir[1],pJpegHandle->stMiddleSurface.pMiddleVir[1],pJpegHandle->stJpegSofInfo.u32CSize); } #ifdef CONFIG_JPEG_FPGA_TEST_SAVE_SCEN_ENABLE HI_JPEG_CloseScenFile(cinfo); #endif return HI_SUCCESS; /** if decode failure jump here **/ FAIL: cinfo->src->bytes_in_buffer = 0; /** ** change the read stream dispose ** CNcomment:硬件解码失败之后读码流还是走原先软解的路了 CNend\n **/ pJpegHandle->stHDecDataBuf.bReadToDataBuf = HI_FALSE; #ifdef CONFIG_JPEG_FPGA_TEST_SAVE_SCEN_ENABLE HI_JPEG_CloseScenFile(cinfo); #endif return HI_FAILURE; }
jpeg_build_huffman_index_progressive(j_decompress_ptr cinfo, huffman_index *index) { if (cinfo->global_state == DSTATE_READY) { JPEG_TRACE("Progressive Mode\n"); /* First call: initialize active modules */ transdecode_master_selection(cinfo); cinfo->global_state = DSTATE_RDCOEFS; } if (cinfo->global_state == DSTATE_RDCOEFS) { int mcu, i; cinfo->marker->get_sos_marker_position(cinfo, index); /* Absorb whole file into the coef buffer */ for (mcu = 0; (unsigned int)mcu < cinfo->total_iMCU_rows; mcu++) { int retcode = 0; /* Call progress monitor hook if present */ if (cinfo->progress != NULL) (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); /* Absorb some more input */ jinit_phuff_decoder(cinfo); for (i = 0; i < index->scan_count; i++) { (*cinfo->inputctl->finish_input_pass) (cinfo); jset_input_stream_position(cinfo, index->scan[i].bitstream_offset); cinfo->unread_marker = 0; retcode = (*cinfo->inputctl->consume_input_build_huffman_index) (cinfo, index, i); if (retcode == JPEG_REACHED_EOI) break; cinfo->input_iMCU_row = mcu; if (mcu != 0) (*cinfo->entropy->configure_huffman_decoder) (cinfo, index->scan[i].prev_MCU_offset); cinfo->input_scan_number = i; retcode = (*cinfo->inputctl->consume_input_build_huffman_index) (cinfo, index, i); } if (retcode == JPEG_SUSPENDED) return FALSE; if (retcode == JPEG_REACHED_EOI) break; /* Advance progress counter if appropriate */ if (cinfo->progress != NULL && (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) { if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) { /* startup underestimated number of scans; ratchet up one scan */ cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows; } } } cinfo->global_state = DSTATE_STOPPING; } /* At this point we should be in state DSTATE_STOPPING if being used * standalone, or in state DSTATE_BUFIMAGE if being invoked to get access * to the coefficients during a full buffered-image-mode decompression. */ if ((cinfo->global_state == DSTATE_STOPPING || cinfo->global_state == DSTATE_BUFIMAGE) && cinfo->buffered_image) { return TRUE; } /* Oops, improper usage */ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); return FALSE; /* keep compiler happy */ }
/****************************************************************************** // Purpose: get information of res jpeg // Author: shan.he // Input: None // Output: None // Return: // Note: ******************************************************************************/ PUBLIC JPEG_RET_E ParseHead_Res(JPEG_DEC_INPUT_PARA_T *jpeg_dec_input) { JPEG_RET_E eRet = JPEG_SUCCESS; JPEG_CODEC_T *jpeg_fw_codec = Get_JPEGDecCodec(); uint16 w = 0; uint16 h = 0; uint16 format = 0; uint16 quant_level = 0; /*skip the res ID*/ if (!skip_n_byte(4)) { JPEG_TRACE("[ParseHead_Res] skip ID error"); return JPEG_FAILED; } if (!get_short_word(&h) || !get_short_word(&w) ) { JPEG_TRACE("[ParseHead_Res] get size error"); return JPEG_FAILED; } jpeg_dec_input->input_height = h; jpeg_dec_input->input_width = w; jpeg_fw_codec->num_components = 3; if (!get_short_word(&format)) { JPEG_TRACE("[ParseHead_Res] get format error"); return JPEG_FAILED; } switch (format) { case 0: jpeg_dec_input->input_mcu_info = JPEG_FW_YUV420; break; case 1: jpeg_dec_input->input_mcu_info = JPEG_FW_YUV411; break; case 2: jpeg_dec_input->input_mcu_info = JPEG_FW_YUV444; break; case 3: jpeg_dec_input->input_mcu_info = JPEG_FW_YUV422; break; case 4: jpeg_dec_input->input_mcu_info = JPEG_FW_YUV400; jpeg_fw_codec->num_components = 1; break; default: //SCI_PASSERT(0, ("unsupported sample")); return JPEG_FAILED; } if (!get_short_word(&quant_level)) { JPEG_TRACE("[ParseHead_Res] get format error"); return JPEG_FAILED; } switch (quant_level) { case 0: jpeg_dec_input->quant_level = JPEG_QUALITY_LOW; break; case 1: jpeg_dec_input->quant_level = JPEG_QUALITY_MIDDLE_LOW; break; case 2: jpeg_dec_input->quant_level = JPEG_QUALITY_MIDDLE; break; case 3: jpeg_dec_input->quant_level = JPEG_QUALITY_MIDDLE_HIGH; break; case 4: jpeg_dec_input->quant_level = JPEG_QUALITY_HIGH; break; default: //SCI_PASSERT(0, ("unsupported quality")); return JPEG_FAILED; } return eRet; }
PUBLIC JPEG_RET_E JpegEnc_InitParam(JPEG_ENC_INPUT_PARA_T *input_para_ptr) { int32 h_ratio_max, v_ratio_max; JPEG_CODEC_T *jpeg_fw_codec = Get_JPEGEncCodec(); SCI_ASSERT(jpeg_fw_codec != PNULL); SCI_ASSERT(input_para_ptr != PNULL); //check the input parameter! if((input_para_ptr->yuv_0_info.input_mcu_info != JPEG_FW_YUV422) &&(input_para_ptr->yuv_0_info.input_mcu_info != JPEG_FW_YUV420) && (input_para_ptr->yuv_1_info.input_mcu_info != JPEG_FW_YUV422) &&(input_para_ptr->yuv_1_info.input_mcu_info != JPEG_FW_YUV420) ) { JPEG_TRACE("mcu information is not valid, only supported yuv422 or yuv420\n"); return JPEG_FAILED; } if(jpeg_fw_codec->compress_level > JPEG_QUALITY_MAX) { JPEG_TRACE("Quant level is not valid, please set right value from [0,4]\n"); return JPEG_FAILED; } if((input_para_ptr->width < 1)||(input_para_ptr->height < 1)) { JPEG_TRACE("Too small image size!\n"); return JPEG_FAILED; } SCI_MEMSET(jpeg_fw_codec, 0, (sizeof(JPEG_CODEC_T))); jpeg_fw_codec->RST_Count = M_RST0; jpeg_fw_codec->mbio_bfr0_valid = TRUE; jpeg_fw_codec->mbio_bfr1_valid = FALSE; //Load parameter into JPEG Codec jpeg_fw_codec->work_mode = (uint8)input_para_ptr->work_mode; jpeg_fw_codec->is_first_slice = input_para_ptr->is_first_slice; jpeg_fw_codec->is_last_slice = input_para_ptr->is_last_slice; jpeg_fw_codec->input_mcu_info = (uint8)(input_para_ptr->yuv_0_info.input_mcu_info); jpeg_fw_codec->width = (uint16)input_para_ptr->width; jpeg_fw_codec->height = (uint16)input_para_ptr->height; jpeg_fw_codec->compress_level = input_para_ptr->quant_level; SCI_MEMCPY(&(jpeg_fw_codec->YUV_Info_0), &(input_para_ptr->yuv_0_info), (sizeof(YUV_FORMAT_T))); SCI_MEMCPY(&(jpeg_fw_codec->YUV_Info_1), &(input_para_ptr->yuv_1_info), (sizeof(YUV_FORMAT_T))); jpeg_fw_codec->stream_0 = input_para_ptr->stream_buf0; jpeg_fw_codec->stream_1 = input_para_ptr->stream_buf1; jpeg_fw_codec->pingpang_buf_len = input_para_ptr->bitstream_buf_len; //..... jpeg_fw_codec->dc_huff_tbl[JPEG_FW_LUM_ID].bits = &jpeg_fw_lum_dc_bits_default[0]; jpeg_fw_codec->dc_huff_tbl[JPEG_FW_LUM_ID].huffval = &jpeg_fw_lum_dc_huffvalue_default[0]; jpeg_fw_codec->ac_huff_tbl[JPEG_FW_LUM_ID].bits = &jpeg_fw_lum_ac_bits_default[0]; jpeg_fw_codec->ac_huff_tbl[JPEG_FW_LUM_ID].huffval = &jpeg_fw_lum_ac_huffvalue_default[0]; jpeg_fw_codec->dc_huff_tbl[JPEG_FW_CHR_ID].bits = &jpeg_fw_chr_dc_bits_default[0]; jpeg_fw_codec->dc_huff_tbl[JPEG_FW_CHR_ID].huffval = &jpeg_fw_chr_dc_huffvalue_default[0]; jpeg_fw_codec->ac_huff_tbl[JPEG_FW_CHR_ID].bits = &jpeg_fw_chr_ac_bits_default[0]; jpeg_fw_codec->ac_huff_tbl[JPEG_FW_CHR_ID].huffval = &jpeg_fw_chr_ac_huffvalue_default[0]; jpeg_fw_codec->restart_interval = input_para_ptr->restart_interval; jpeg_fw_codec->restart_to_go = 0; jpeg_fw_codec->next_restart_num = 0; /*init sample ratio*/ switch(jpeg_fw_codec->input_mcu_info) { case JPEG_FW_YUV420: jpeg_fw_codec->ratio[JPEG_FW_Y_ID].h_ratio = 2; jpeg_fw_codec->ratio[JPEG_FW_Y_ID].v_ratio = 2; jpeg_fw_codec->ratio[JPEG_FW_U_ID].h_ratio = 1; jpeg_fw_codec->ratio[JPEG_FW_U_ID].v_ratio = 1; jpeg_fw_codec->ratio[JPEG_FW_V_ID].h_ratio = 1; jpeg_fw_codec->ratio[JPEG_FW_V_ID].v_ratio = 1; break; case JPEG_FW_YUV422: jpeg_fw_codec->ratio[JPEG_FW_Y_ID].h_ratio = 2; jpeg_fw_codec->ratio[JPEG_FW_Y_ID].v_ratio = 1; jpeg_fw_codec->ratio[JPEG_FW_U_ID].h_ratio = 1; jpeg_fw_codec->ratio[JPEG_FW_U_ID].v_ratio = 1; jpeg_fw_codec->ratio[JPEG_FW_V_ID].h_ratio = 1; jpeg_fw_codec->ratio[JPEG_FW_V_ID].v_ratio = 1; break; default: return JPEG_FAILED; } /*get the mcu size*/ v_ratio_max = JPEG_FW_MAX3(jpeg_fw_codec->ratio[JPEG_FW_Y_ID].v_ratio, jpeg_fw_codec->ratio[JPEG_FW_U_ID].v_ratio, jpeg_fw_codec->ratio[JPEG_FW_V_ID].v_ratio); h_ratio_max = JPEG_FW_MAX3(jpeg_fw_codec->ratio[JPEG_FW_Y_ID].h_ratio, jpeg_fw_codec->ratio[JPEG_FW_U_ID].h_ratio, jpeg_fw_codec->ratio[JPEG_FW_V_ID].h_ratio); jpeg_fw_codec->mcu_height = 8 * v_ratio_max; jpeg_fw_codec->mcu_width = 8 * h_ratio_max; jpeg_fw_codec->mcu_num_x = (jpeg_fw_codec->width + jpeg_fw_codec->mcu_width -1)/jpeg_fw_codec->mcu_width; jpeg_fw_codec->mcu_num_y = (jpeg_fw_codec->height + jpeg_fw_codec->mcu_height -1)/jpeg_fw_codec->mcu_height; //Adjusted image width and height jpeg_fw_codec->c_width = jpeg_fw_codec->mcu_num_x * jpeg_fw_codec->mcu_width; jpeg_fw_codec->c_height = jpeg_fw_codec->mcu_num_y * jpeg_fw_codec->mcu_height; return JPEG_SUCCESS; }