1 2 3 4#include "MFE_chip.h" 5#include "mfe_common.h" 6#include "mfe_type.h" 7#include "ms_dprintf.h" 8#ifdef __MOBILE_CASE__ 9#include <stdio.h> 10#include <string.h> 11#endif 12#if defined(WIN32) 13 #include "sigdump/sigdump_api.h" 14#endif 15#include "Exif.h" 16#include "jcmarker.h" 17#if (DEBUG_LEVEL & DRV_L6) 18extern int mfe_starttime; 19//int endtime=0; 20#endif 21/* 22typedef struct _JpgInfo 23{ 24 int nFrameMode; 25 int nUseMST422; 26 int nUseYVYU; 27 int nWidth, nHeight; 28 int nLastZZ; 29 int QTable[2][64]; 30 int nQFactor; 31} JpgInfo; 32*/ 33 34static void OutputSwCfg1_Jpg(MFE_U32 nFrmNum, MFE_CONFIG* pConfig); 35 36 37static void jpeg_add_quant_table (JpgInfo* cinfo, int which_tbl, 38 const unsigned int *basic_table, 39 int scale_factor, MFE_BOOL force_baseline) 40{ 41 42 long temp; 43 int i; 44 for (i = 0; i < DCTSIZE2; i++) { 45 temp = ((long) basic_table[i] * scale_factor + 50L) / 100L; 46 /* limit the values to the valid range */ 47 if (temp <= 0L) temp = 1L; 48 if (temp > 32767L) temp = 32767L; /* max quantizer needed for 12 bits */ 49 if (force_baseline && temp > 255L) 50 temp = 255L; /* limit to baseline range if requested */ 51 cinfo->QTable[which_tbl][i] = (MFE_U16) temp; 52 } 53 54} 55 56static void jpeg_set_linear_quality (JpgInfo* cinfo, int scale_factor, MFE_BOOL force_baseline) 57{ 58 jpeg_add_quant_table(cinfo, 0, QTable_default_0, 59 scale_factor, force_baseline); 60 jpeg_add_quant_table(cinfo, 1, QTable_default_1, 61 scale_factor, force_baseline); 62} 63 64static int jpeg_quality_scaling (int quality) 65{ 66 if (quality <= 0) quality = 1; 67 if (quality > 100) quality = 100; 68 69 if (quality < 50) 70 quality = 5000 / quality; 71 else 72 quality = 200 - quality*2; 73 74 return quality; 75} 76 77void mfeJPE_Set_QTABLE(MFE_CONFIG *pConfig) 78{ 79 int quality; 80 JpgInfo* pInfo = &pConfig->ctxJpgInfo; 81 quality = jpeg_quality_scaling(pConfig->m_quality); 82 jpeg_set_linear_quality(pInfo, quality, TRUE); 83} 84 85void mfeJPE_Init(MFE_CONFIG *pConfig) 86{ 87 int i; 88 JpgInfo* pInfo = &pConfig->ctxJpgInfo; 89 int quality; 90 memset(pInfo, 0, sizeof(JpgInfo)); 91 92 pInfo->nFrameMode = pConfig->m_bFrameMode; 93 pInfo->nUseMST422 = 1; 94 pInfo->nUseYVYU = 0; 95 pInfo->nQFactor = 3; 96 pInfo->nLastZZ = 63; 97 pInfo->nWidth = pConfig->nBufWidth; 98 pInfo->nHeight = pConfig->nBufHeight; 99 pInfo->fdc_mode = pConfig->m_bFDC_mode; 100 101 quality = jpeg_quality_scaling(pConfig->m_quality); 102 jpeg_set_linear_quality(pInfo, quality, TRUE); 103 104 //print Q table 105 ms_dprintk(DRV_L1, "table 0"); 106 for(i=0;i<64;i+=8){ 107 ms_dprintk(DRV_L1, "%d,%d,%d,%d,%d,%d,%d,%d",pInfo->QTable[0][i+0],pInfo->QTable[0][i+1], 108 pInfo->QTable[0][i+2],pInfo->QTable[0][i+3], 109 pInfo->QTable[0][i+4],pInfo->QTable[0][i+5], 110 pInfo->QTable[0][i+6],pInfo->QTable[0][i+7]); 111 } 112 113 ms_dprintk(DRV_L1, "table 1"); 114 for(i=0;i<64;i+=8){ 115 ms_dprintk(DRV_L1, "%d,%d,%d,%d,%d,%d,%d,%d\n",pInfo->QTable[1][i+0],pInfo->QTable[1][i+1], 116 pInfo->QTable[1][i+2],pInfo->QTable[1][i+3], 117 pInfo->QTable[1][i+4],pInfo->QTable[1][i+5], 118 pInfo->QTable[1][i+6],pInfo->QTable[1][i+7]); 119 } 120 121} 122 123void mfeJPE_EncodeFrame(MFE_CONFIG *pConfig, GOPINFO* pGopInfo) 124{ 125 126#if (DEBUG_LEVEL & DRV_L6) 127 mfe_starttime = MsOS_GetSystemTime(); 128#endif 129 OutputSwCfg1_Jpg(0 , pConfig); 130 131} 132 133void OutputSwCfg1_Jpg(MFE_U32 nFrmNum, MFE_CONFIG* pConfig) 134{ 135 136 int nTarWriteCount; 137 int nRegWriteCount; 138 int nTarFDCCount; 139 int nRegFDCCount; 140 141 void* pContext; 142 JpgInfo* pJpgInfo = &pConfig->ctxJpgInfo; 143 BitsInfo* pBitsInfo = &pConfig->ctxBitsInfo; 144 BufInfo* pBufInfo = &pConfig->ctxBufInfo; 145 146 pContext = (void*)pBitsInfo; 147 148 ////////////////////////////////////////////////////////////////////////// 149 // Sequence-wide settings 150 151 if (nFrmNum==0) { 152 memset(mfe_reg, 0, sizeof(MFE_REG)); // Initial 153 mfe_reg->reg_mfe_g_enc_mode = REG_ENC_MODE_JPEG; 154 mfe_reg->reg_mfe_g_pic_width = (pJpgInfo->nWidth+15)&~15; 155 mfe_reg->reg_mfe_g_pic_height = (pJpgInfo->nHeight+7)&~7; 156 157 mfe_reg->reg_mfe_g_qmode = 1; // Always with quant-tables 158 mfe_reg->reg_mfe_g_jpe_enc_mode = 1; // current version supports 422 only 159 mfe_reg->reg_mfe_g_jpe_buffer_mode = pJpgInfo->nFrameMode; 160 if (pJpgInfo->nFrameMode==0) 161 mfe_reg->reg_mfe_g_jpe_multibuf_mode = 0; 162 163 mfe_reg->reg_mfe_g_jpe_qfactor = pJpgInfo->nQFactor; // 3 means no altering qtable 164 mfe_reg->reg_mfe_g_packed_mode = pJpgInfo->nUseYVYU ? 0 : 1; 165#ifdef _MFE_M1_ 166 mfe_reg->reg_mfe_g_jpe_mst422_mode = pJpgInfo->nUseMST422 ? 1 : 0; 167 168#ifdef _SW_BUF_MODE_ 169 mfe_reg->reg_mfe_g_sw_buffer_mode = 1; 170#else 171 mfe_reg->reg_mfe_g_sw_buffer_mode = 0; 172 if (pJpgInfo->nFrameMode==0) { //hw row mode 173 // disable fs fail irq for hw handshake 174 mfe_reg->reg_mfe_g_irq_mask = IRQ_FS_FAIL; 175 } 176#endif 177#endif 178 } 179 else { 180 mfe_reg->reg_mfe_g_frame_start_sw = 0; 181 } 182 183 ////////////////////////////////////////////////////////////////////////// 184 // Frame-wide settings 185#ifdef CLOCK_GATING 186 mfe_reg->reg16 = 0xffff; // clock gating 187#endif 188 // Input buffer address: Must be 256-byte aligned. 189 MFE_ASSERT((pBufInfo->m_nCurYAddr.miuAddress&0xFF)==0); 190 MFE_ASSERT((pBufInfo->m_nCurCAddr.miuAddress&0xFF)==0); 191 192 if(pConfig->m_bFrameMode==0) { 193// MFE_ASSERT((pBufInfo->m_nRefYAddr[0].miuAddress&0xFF)==0); 194 MFE_ASSERT((pBufInfo->m_nRefYAddr[1].miuAddress&0xFF)==0); 195// MFE_ASSERT((pBufInfo->m_nRefCAddr[0].miuAddress&0xFF)==0); 196 MFE_ASSERT((pBufInfo->m_nRefCAddr[1].miuAddress&0xFF)==0); 197 } 198 MFE_ASSERT((pBufInfo->m_nOutBufAddr[pConfig->nOBufIndex].miuAddress&0x7)==0); 199 200 mfe_reg->reg_mfe_g_cur_y_adr_low = (MFE_U16)((pBufInfo->m_nCurYAddr.miuAddress>>8)&0xFFFF); 201 mfe_reg->reg_mfe_g_cur_y_adr_high = (MFE_U16)(pBufInfo->m_nCurYAddr.miuAddress>>(8+16)); 202 mfe_reg->reg_mfe_g_cur_c_adr_low = (MFE_U16)((pBufInfo->m_nCurCAddr.miuAddress>>8)&0xFFFF); 203 mfe_reg->reg_mfe_g_cur_c_adr_high = (MFE_U16)(pBufInfo->m_nCurCAddr.miuAddress>>(8+16)); 204 205 //if (mfe_reg->reg_mfe_g_enc_mode!=REG_ENC_MODE_JPEG) 206 { 207 // mfe_reg->reg_mfe_g_ref_y_adr0_low = (MFE_U16)((pBufInfo->m_nRefYAddr[0].miuAddress>>8)&0xFFFF); 208 // mfe_reg->reg_mfe_g_ref_y_adr0_high = (MFE_U16)(pBufInfo->m_nRefYAddr[0].miuAddress>>(8+16)); 209 if(pConfig->m_bFrameMode==0) { 210 mfe_reg->reg_mfe_g_ref_y_adr1_low = (MFE_U16)((pBufInfo->m_nRefYAddr[1].miuAddress>>8)&0xFFFF); 211 mfe_reg->reg_mfe_g_ref_y_adr1_high = (MFE_U16)(pBufInfo->m_nRefYAddr[1].miuAddress>>(8+16)); 212 213 // mfe_reg->reg_mfe_g_ref_c_adr0_low = (MFE_U16)((pBufInfo->m_nRefCAddr[0].miuAddress>>8)&0xFFFF); 214 // mfe_reg->reg_mfe_g_ref_c_adr0_high = (MFE_U16)(pBufInfo->m_nRefCAddr[0].miuAddress>>(8+16)); 215 mfe_reg->reg_mfe_g_ref_c_adr1_low = (MFE_U16)((pBufInfo->m_nRefCAddr[1].miuAddress>>8)&0xFFFF); 216 mfe_reg->reg_mfe_g_ref_c_adr1_high = (MFE_U16)(pBufInfo->m_nRefCAddr[1].miuAddress>>(8+16)); 217 } 218 // mfe_reg->reg_mfe_g_rec_y_adr_low = (MFE_U16)((pBufInfo->m_nRecYAddr.miuAddress>>8)&0xFFFF); 219 // mfe_reg->reg_mfe_g_rec_y_adr_high = (MFE_U16)(pBufInfo->m_nRecYAddr.miuAddress>>(8+16)); 220 // mfe_reg->reg_mfe_g_rec_c_adr_low = (MFE_U16)((pBufInfo->m_nRecCAddr.miuAddress>>8)&0xFFFF); 221 // mfe_reg->reg_mfe_g_rec_c_adr_high = (MFE_U16)(pBufInfo->m_nRecCAddr.miuAddress>>(8+16)); 222 } 223 224 // Output buffers: Must be 8-byte aligned. 225#ifdef _MFE_T8_ 226 mfe_reg->reg_mfe_s_bspobuf_sadr_low = (MFE_U16)((pBufInfo->m_nOutBufAddr[pConfig->nOBufIndex].miuAddress>>3)&0xFFFF); 227 mfe_reg->reg_mfe_s_bspobuf_sadr_high = (MFE_U16)(pBufInfo->m_nOutBufAddr[pConfig->nOBufIndex].miuAddress>>(3+16)); 228 mfe_reg->reg_mfe_s_bspobuf_eadr_low = (MFE_U16)(((pBufInfo->m_nOutBufAddr[pConfig->nOBufIndex].miuAddress+pBufInfo->m_OutBufferSize-8)>>3)&0xFFFF); 229 mfe_reg->reg_mfe_s_bspobuf_eadr_high = (MFE_U16)((pBufInfo->m_nOutBufAddr[pConfig->nOBufIndex].miuAddress+pBufInfo->m_OutBufferSize-8)>>(3+16)); 230#elif defined(_MFE_M1_) 231 mfe_reg->reg_mfe_s_bspobuf_hw_en = 0; 232#if defined(USE_HW_DBL_OBUF) 233 mfe_reg->reg_mfe_s_bspobuf_hw_en = 1; 234#endif 235#endif 236 237 mfe_reg->reg_mfe_s_txip_irfsh_en = 0; 238 239 mfe_reg->reg_mfe_g_frame_type = 0; // JPEG: always I-frame 240 mfe_reg->reg_mfe_s_quan_idx_last = pJpgInfo->nLastZZ; 241 if (mfe_reg->reg_mfe_s_quan_idx_last<63) 242 mfe_reg->reg_mfe_s_quan_idx_swlast = 1; 243 else 244 mfe_reg->reg_mfe_s_quan_idx_swlast = 0; 245#if defined(_MFE_M1_) 246 //enable eco item. 247 mfe_reg->reg_mfe_s_txip_eco0 = 1; 248#endif 249 ////////////////////////////////////////////////////////////////////////// 250 // swcfg1 output 251 nTarWriteCount = 0; 252 nRegWriteCount = 0; 253 nTarFDCCount = 0; 254 nRegFDCCount = 0; 255 if (nFrmNum==0) { 256 MFE_ASSERT(mfe_reg->reg_mfe_g_qmode==1); 257 WriteQTable(pJpgInfo->QTable[0], pJpgInfo->QTable[1]); 258 } 259 260 nTarWriteCount = 40 +1; //add eco item. 261 262 if(pJpgInfo->fdc_mode) { 263 nTarFDCCount = PutFDC(pContext, 1); 264 nTarWriteCount += nTarFDCCount*3+1; 265 } 266#ifdef TEST_IMGBUF_FULL 267 nTarWriteCount += 2; 268#endif 269 if(pJpgInfo->fdc_mode) { 270 nTarFDCCount *= 3; 271 nTarFDCCount++; // reg to set fdc round 272 } 273 // SW reset 274 mfe_reg->reg_mfe_g_viu_soft_rstz=1; 275 276 mfe_reg->reg_mfe_g_soft_rstz = 0; 277 WriteRegMFE(0x0, mfe_reg->reg00, "[%d] reg00", nRegWriteCount++, "SW reset 0"); 278 mfe_reg->reg_mfe_g_soft_rstz = 1; 279 WriteRegMFE(0x0, mfe_reg->reg00, "[%d] reg00", nRegWriteCount++, "SW reset 1"); 280 281 WriteRegMFE(0x1, mfe_reg->reg01, "[%d] reg01", nRegWriteCount++, "picture width"); 282 WriteRegMFE(0x2, mfe_reg->reg02, "[%d] reg02", nRegWriteCount++, "picture height"); 283 WriteRegMFE(0x3, mfe_reg->reg03, "[%d] reg03", nRegWriteCount++, "value"); 284 285 WriteRegMFE(0x16, mfe_reg->reg16, "[%d] reg16", nRegWriteCount++, "Clock gating"); 286 287 // Input buffers 288 WriteRegMFE(0x06, mfe_reg->reg06, "[%d] reg06", nRegWriteCount++, "current luma base address"); 289 WriteRegMFE(0x07, mfe_reg->reg07, "[%d] reg07", nRegWriteCount++, "current luma base address high"); 290 WriteRegMFE(0x08, mfe_reg->reg08, "[%d] reg08", nRegWriteCount++, "current chroma base address"); 291 WriteRegMFE(0x09, mfe_reg->reg09, "[%d] reg09", nRegWriteCount++, "current chroma base address high"); 292 WriteRegMFE(0x0a, mfe_reg->reg0a, "[%d] reg0a", nRegWriteCount++, "reference luma base address0"); 293 WriteRegMFE(0x0b, mfe_reg->reg0b, "[%d] reg0b", nRegWriteCount++, "reference luma base address0 high"); 294 WriteRegMFE(0x0c, mfe_reg->reg0c, "[%d] reg0c", nRegWriteCount++, "reference luma base address1"); 295 WriteRegMFE(0x0d, mfe_reg->reg0d, "[%d] reg0d", nRegWriteCount++, "reference luma base address1 high"); 296 WriteRegMFE(0x0e, mfe_reg->reg0e, "[%d] reg0e", nRegWriteCount++, "reference chroma base address0"); 297 WriteRegMFE(0x0f, mfe_reg->reg0f, "[%d] reg0f", nRegWriteCount++, "reference chroma base address0 high"); 298 WriteRegMFE(0x10, mfe_reg->reg10, "[%d] reg10", nRegWriteCount++, "reference chroma base address1"); 299 WriteRegMFE(0x11, mfe_reg->reg11, "[%d] reg11", nRegWriteCount++, "reference chroma base address1 high"); 300 WriteRegMFE(0x12, mfe_reg->reg12, "[%d] reg12", nRegWriteCount++, "reconstructed luma base address:"); 301 WriteRegMFE(0x13, mfe_reg->reg13, "[%d] reg13", nRegWriteCount++, "reconstructed luma base address high"); 302 WriteRegMFE(0x14, mfe_reg->reg14, "[%d] reg14", nRegWriteCount++, "reconstructed chroma base address:"); 303 WriteRegMFE(0x15, mfe_reg->reg15, "[%d] reg15", nRegWriteCount++, "reconstructed chroma base address: high"); 304 305 // Output buffer 306#ifdef _MFE_M1_ 307 mfe_reg->reg_mfe_s_bspobuf_fifo_th = 1; 308 mfe_reg->reg_mfe_s_mvobuf_set_adr = 0; 309 mfe_reg->reg_mfe_s_mvobuf_fifo_th = 0; 310 mfe_reg->reg_mfe_s_bsp_fdc_skip = !pJpgInfo->fdc_mode; 311#else 312 WriteRegMFE(0x3c, mfe_reg->reg3c, "[%d] reg3c", nRegWriteCount++, "bsp obuf start address: "); 313 WriteRegMFE(0x3d, mfe_reg->reg3d, "[%d] reg3d", nRegWriteCount++, "bsp obuf start address high"); 314 WriteRegMFE(0x3e, mfe_reg->reg3e, "[%d] reg3e", nRegWriteCount++, "bsp obuf end address: "); 315 WriteRegMFE(0x3f, mfe_reg->reg3f, "[%d] reg3f", nRegWriteCount++, "bsp obuf end address high"); 316 // 317 mfe_reg->reg_mfe_s_bspobuf_set_adr = 1; 318 mfe_reg->reg_mfe_s_bspobuf_fifo_th = 1; 319 mfe_reg->reg_mfe_s_mvobuf_set_adr = 0; 320 mfe_reg->reg_mfe_s_mvobuf_fifo_th = 0; 321 mfe_reg->reg_mfe_s_bsp_fdc_skip = 1; 322#endif 323 324#ifdef _MFE_M1_ 325 // Enable set-obuf 326 mfe_reg->reg_mfe_s_bspobuf_update_adr = 1; 327 WriteRegMFE(0x3f, mfe_reg->reg3f, "[%d] reg3f", nRegWriteCount++, "reg_mfe_s_bspobuf_update_adr"); 328 mfe_reg->reg_mfe_s_bspobuf_update_adr = 0; // write-one-clear 329#if defined(USE_HW_DBL_OBUF) 330 nRegWriteCount += SetObufAddr((MFE_U32)pBufInfo->m_nOutBufAddr, pBufInfo->m_OutBufferSize, 0, 0); 331 nRegWriteCount += SetObufAddr((MFE_U32)pBufInfo->m_nOutBufAddr+pBufInfo->m_OutBufferSize, pBufInfo->m_OutBufferSize, 1, 1); 332#else 333 nRegWriteCount += SetObufAddr((MFE_U32)pBufInfo->m_nOutBufAddr[pConfig->nOBufIndex].miuAddress, pBufInfo->m_OutBufferSize, 0, 1); 334#endif 335 336#else 337 WriteRegMFE(0x3b, mfe_reg->reg3b, "[%d] reg3b", nRegWriteCount++, "set bsp obuf"); 338 mfe_reg->reg_mfe_s_bspobuf_set_adr = 0; // HW is write-one-clear 339#endif 340 341 // Cannot use mode 3. 342 if (pJpgInfo->nFrameMode==0) { 343 mfe_reg->reg_mfe_g_jpe_fsvs_mode=2; 344 } 345 else 346 mfe_reg->reg_mfe_g_jpe_fsvs_mode=0; // When frame mode: Don't care 347 348 WriteRegMFE(0x18, mfe_reg->reg18, "[%d] reg18", nRegWriteCount++, "JPE encode mode"); 349 350 // Cross-format wrong reg setting prevention 351 WriteRegMFE(0x1b, mfe_reg->reg1b, "[%d] reg1b", nRegWriteCount++, "MPEG4 FieldDCT"); 352 353#ifdef _MFE_M1_ 354 if(pConfig->MfeAdvInfo.input_imi_en) { 355 mfe_reg->reg_mfe_s_marb_eimi_block = 0x1; 356 WriteRegMFE(0x68, mfe_reg->reg68, "[%d] reg68", nRegWriteCount, "IMI enable"); 357 } 358 else 359 mfe_reg->reg_mfe_s_marb_eimi_block = 0x0; 360#endif 361 mfe_reg->reg_mfe_g_crc_mode = 0xC; 362 mfe_reg->reg_mfe_g_debug_tcycle_chk_en = 0x1; 363 mfe_reg->reg_mfe_g_debug_tcycle_chk_sel = 0x0; 364 mfe_reg->reg_mfe_g_debug_en = 0; // TEST 365 WriteRegMFE(0x73, mfe_reg->reg73, "[%d] reg73", nRegWriteCount++, "crc mode"); 366 367 WriteRegMFE(0x2c, mfe_reg->reg2c, "[%d] reg2c", nRegWriteCount++, "Last zigzag"); 368 369 // Reset any StopAndGo or StopAndDrop setting. 370 mfe_reg->reg_mfe_s_txip_sng_mb = 0; 371 WriteRegMFE(0x2d, mfe_reg->reg2d, "[%d] reg2d", nRegWriteCount++, "reg_mfe_s_txip_sng_mb=0"); 372 373#ifdef _MFE_M1_ 374 //enable eco item 375 WriteRegMFE(0x7d, mfe_reg->reg7d, "[%d] reg7d", nRegWriteCount++, "reg_mfe_s_txip_eco0=1"); 376#endif 377 378 DumpAllReg(); 379 380 // Enable HW 381 mfe_reg->reg_mfe_g_frame_start_sw = 1; 382 WriteRegMFE(0x00, mfe_reg->reg00, "[%d] reg00", nRegWriteCount++, "frame start"); 383 mfe_reg->reg_mfe_g_frame_start_sw = 0; // HW is write-one-clear 384 385 // FDC 386 if(pJpgInfo->fdc_mode) { 387 nRegFDCCount = PutFDC(pContext, 0); 388 nRegWriteCount += nRegFDCCount; 389 } 390 391 if(nRegFDCCount != nTarFDCCount) { 392 ms_dprintk(DRV_L4,"nRegFDCCount = %d,nTarFDCCount = %d \n",nRegFDCCount,nTarFDCCount); 393 } 394 if(nRegWriteCount != nTarWriteCount) { 395 ms_dprintk(DRV_L4,"nRegWriteCount = %d,nTarWriteCount = %d \n",nRegWriteCount,nTarWriteCount); 396 } 397 // Only for debug 398 //MFE_ASSERT(nRegWriteCount==nTarWriteCount); 399 //MFE_ASSERT(nRegFDCCount==nTarFDCCount); 400 401} 402 403