1 //<MStar Software>
2 //******************************************************************************
3 // MStar Software
4 // Copyright (c) 2010 - 2012 MStar Semiconductor, Inc. All rights reserved.
5 // All software, firmware and related documentation herein ("MStar Software") are
6 // intellectual property of MStar Semiconductor, Inc. ("MStar") and protected by
7 // law, including, but not limited to, copyright law and international treaties.
8 // Any use, modification, reproduction, retransmission, or republication of all
9 // or part of MStar Software is expressly prohibited, unless prior written
10 // permission has been granted by MStar.
11 //
12 // By accessing, browsing and/or using MStar Software, you acknowledge that you
13 // have read, understood, and agree, to be bound by below terms ("Terms") and to
14 // comply with all applicable laws and regulations:
15 //
16 // 1. MStar shall retain any and all right, ownership and interest to MStar
17 // Software and any modification/derivatives thereof.
18 // No right, ownership, or interest to MStar Software and any
19 // modification/derivatives thereof is transferred to you under Terms.
20 //
21 // 2. You understand that MStar Software might include, incorporate or be
22 // supplied together with third party`s software and the use of MStar
23 // Software may require additional licenses from third parties.
24 // Therefore, you hereby agree it is your sole responsibility to separately
25 // obtain any and all third party right and license necessary for your use of
26 // such third party`s software.
27 //
28 // 3. MStar Software and any modification/derivatives thereof shall be deemed as
29 // MStar`s confidential information and you agree to keep MStar`s
30 // confidential information in strictest confidence and not disclose to any
31 // third party.
32 //
33 // 4. MStar Software is provided on an "AS IS" basis without warranties of any
34 // kind. Any warranties are hereby expressly disclaimed by MStar, including
35 // without limitation, any warranties of merchantability, non-infringement of
36 // intellectual property rights, fitness for a particular purpose, error free
37 // and in conformity with any international standard. You agree to waive any
38 // claim against MStar for any loss, damage, cost or expense that you may
39 // incur related to your use of MStar Software.
40 // In no event shall MStar be liable for any direct, indirect, incidental or
41 // consequential damages, including without limitation, lost of profit or
42 // revenues, lost or damage of data, and unauthorized system use.
43 // You agree that this Section 4 shall still apply without being affected
44 // even if MStar Software has been modified by MStar in accordance with your
45 // request or instruction for your use, except otherwise agreed by both
46 // parties in writing.
47 //
48 // 5. If requested, MStar may from time to time provide technical supports or
49 // services in relation with MStar Software to you for your use of
50 // MStar Software in conjunction with your or your customer`s product
51 // ("Services").
52 // You understand and agree that, except otherwise agreed by both parties in
53 // writing, Services are provided on an "AS IS" basis and the warranty
54 // disclaimer set forth in Section 4 above shall apply.
55 //
56 // 6. Nothing contained herein shall be construed as by implication, estoppels
57 // or otherwise:
58 // (a) conferring any license or right to use MStar name, trademark, service
59 // mark, symbol or any other identification;
60 // (b) obligating MStar or any of its affiliates to furnish any person,
61 // including without limitation, you and your customers, any assistance
62 // of any kind whatsoever, or any information; or
63 // (c) conferring any license or right under any intellectual property right.
64 //
65 // 7. These terms shall be governed by and construed in accordance with the laws
66 // of Taiwan, R.O.C., excluding its conflict of law rules.
67 // Any and all dispute arising out hereof or related hereto shall be finally
68 // settled by arbitration referred to the Chinese Arbitration Association,
69 // Taipei in accordance with the ROC Arbitration Law and the Arbitration
70 // Rules of the Association by three (3) arbitrators appointed in accordance
71 // with the said Rules.
72 // The place of arbitration shall be in Taipei, Taiwan and the language shall
73 // be English.
74 // The arbitration award shall be final and binding to both parties.
75 //
76 //******************************************************************************
77 //<MStar Software>
78
79
80
81 #include "MFE_chip.h"
82 #include "mfe_type.h"
83 #include "mfe_common.h"
84 #include "ms_dprintf.h"
85 #include "mhal_mfe.h"
86 #ifdef __MOBILE_CASE__
87 #include <stdio.h>
88 #include <string.h>
89 #endif
90
91 #include "msRateCtrl.h"
92 #include "OutStrm.h"
93 #include "m4v_header.h"
94 #include "BufMng.h"
95 #include "mfe_reg.h"
96 #if defined(WIN32)
97 #include "mdrv_mfe.h"
98 #elif defined(_MFE_T8_) && defined(_MIPS_PLATFORM_) &&!defined(_KERNEL_MODE_)
99 #include "mdrv_mfe.h"
100 #endif
101 #include "msRateCtrl.h"
102 #if defined(_MFE_T8_)
103 #define MAX_REF_FRAME 2UL
104 #define SEARCH_RANGE_X 32UL
105 #elif defined(_MFE_M1_)
106 #define MAX_REF_FRAME 1UL
107 #define SEARCH_RANGE_X 16UL
108 #endif
109
110 // Sync with cModel QExp.h
111 #define CLOCK_GATING // Enable clock gating
112 #define FME_PIPELINE_OPEN // Enable David's FME speedup version
113
114
115
116 #define FIELD_DCT_DIFF_THR (350UL>>2) // Subsampled by 4
117
118
119
120 static const MS_S32 rgiDefaultIntraQMatrix [64] = {
121 8, 17, 18, 19, 21, 23, 25, 27,
122 17, 18, 19, 21, 23, 25, 27, 28,
123 20, 21, 22, 23, 24, 26, 28, 30,
124 21, 22, 23, 24, 26, 28, 30, 32,
125 22, 23, 24, 26, 28, 30, 32, 35,
126 23, 24, 26, 28, 30, 32, 35, 38,
127 25, 26, 28, 30, 32, 35, 38, 41,
128 27, 28, 30, 32, 35, 38, 41, 45
129 };
130
131 static const MS_S32 rgiDefaultInterQMatrix [64] = {
132 16, 17, 18, 19, 20, 21, 22, 23,
133 17, 18, 19, 20, 21, 22, 23, 24,
134 18, 19, 20, 21, 22, 23, 24, 25,
135 19, 20, 21, 22, 23, 24, 26, 27,
136 20, 21, 22, 23, 25, 26, 27, 28,
137 21, 22, 23, 24, 26, 27, 28, 30,
138 22, 23, 24, 26, 27, 28, 30, 31,
139 23, 24, 25, 27, 28, 30, 31, 33
140 };
141 #ifdef MFE_MIU_PROTECT
142 extern void MHal_MFE_Enable_MIU_Protection(MS_S32 MIU_TEST_MODE,MFE_CONFIG* pConfig);
143 #endif
144 void OutputSwCfg1_Mp4(MS_S32 nFrmNum, MFE_CONFIG* pConfig);
145
CeilLog2(MS_U32 uiVal)146 static MS_U32 CeilLog2( MS_U32 uiVal)
147 {
148 MS_U32 uiTmp = uiVal-1;
149 MS_U32 uiRet = 0;
150
151 while( uiTmp != 0 )
152 {
153 uiTmp >>= 1;
154 uiRet++;
155 }
156 return uiRet;
157 }
158
mfeM4VE_DeInit(MFE_CONFIG * pConfig)159 void mfeM4VE_DeInit(MFE_CONFIG *pConfig)
160 {
161 IntraUpdateClose(pConfig);
162 }
163
mfeM4VE_Init(MFE_CONFIG * pConfig)164 void mfeM4VE_Init(MFE_CONFIG *pConfig)
165 {
166 MS_S32 i;
167 M4VEINFO* pInfo = &pConfig->ctxM4veInfo;
168
169 memset(pInfo, 0, sizeof(M4VEINFO));
170
171 switch (pConfig->nCodecType)
172 {
173 case REG_ENC_MODE_MPG4:
174 pInfo->bShortHeader = 0;
175 pConfig->bQuantType = 1;
176 break;
177 case REG_ENC_MODE_H263:
178 pInfo->bShortHeader = 1;
179 pConfig->bQuantType = 0;
180 break;
181 default:
182 MS_ASSERT(0);
183 pInfo->bShortHeader = 0;
184 }
185
186 switch (pConfig->FrameRatex100) {
187 case 3000:
188 pInfo->nTimeResolution = 30;
189 pInfo->nFixedIncrement = 1;
190 pInfo->iClockRate = 30;
191 break;
192 case 1500:
193 pInfo->nTimeResolution = 15;
194 pInfo->nFixedIncrement = 1;
195 pInfo->iClockRate = 15;
196 break;
197 case 2500:
198 pInfo->nTimeResolution = 25;
199 pInfo->nFixedIncrement = 1;
200 pInfo->iClockRate = 25;
201 break;
202 case 2997:
203 pInfo->nTimeResolution = 30000;
204 pInfo->nFixedIncrement = 1001;
205 pInfo->iClockRate = 2997;
206 break;
207 default:
208 if(pConfig->nCodecType == REG_ENC_MODE_MPG4) {
209 pInfo->nTimeResolution = pConfig->TimeIncreamentRes;
210 pInfo->nFixedIncrement = pConfig->VopTimeIncreament;
211 ms_dprintk(DRV_L2,"Setting from API: pInfo->nTimeResolution = %d, pInfo->nFixedIncrement = %d\n",
212 (int)pInfo->nTimeResolution, (int)pInfo->nFixedIncrement);
213 pInfo->iClockRate = pInfo->nTimeResolution;
214 }
215 else {
216 pInfo->nTimeResolution = pConfig->FrameRatex100 / 100;
217 pInfo->nFixedIncrement = 1;
218 pInfo->iClockRate = pInfo->nTimeResolution;
219 }
220 MS_ASSERT(pInfo->nTimeResolution>0);
221 MS_ASSERT(pInfo->nFixedIncrement>0);
222 }
223 {
224 MS_S32 iClockRate = pInfo->iClockRate-1;
225 MS_ASSERT (iClockRate < 65536);
226 //printf("mfeM4VE_Init: iClockRate=%d\n"), iClockRate);
227 if(iClockRate>0)
228 {
229 for (pInfo->nNumBitsTimeIncr = 1; pInfo->nNumBitsTimeIncr < 16; pInfo->nNumBitsTimeIncr++) {
230 if (iClockRate == 1)
231 break;
232 iClockRate = (iClockRate >> 1);
233 }
234 }
235 else
236 pInfo->nNumBitsTimeIncr = 1;
237 //printf("mfeM4VE_Init: nNumBitsTimeIncr=%d\n"), pInfo->nNumBitsTimeIncr);
238 }
239
240 if (pConfig->nCodecType==REG_ENC_MODE_MPG4) {
241 pInfo->bInterlacedCoding = (pConfig->bInterlace != PROGRESSIVE);
242 pInfo->bInterlace = pInfo->bInterlacedCoding;
243 pInfo->iSearchRangeForward = SEARCH_RANGE_X;
244 pInfo->bQuantizerType = pConfig->bQuantType;
245
246 for (i=0; i<64; i++) {
247 pInfo->rgiIntraQuantizerMatrix[i] = rgiDefaultIntraQMatrix[i];
248 pInfo->rgiInterQuantizerMatrix[i] = rgiDefaultInterQMatrix[i];
249 }
250
251 pInfo->iRoundingControlSwitch = 1;
252 }
253 else {
254 pInfo->iSearchRangeForward = 16;
255 pInfo->bQuantizerType = 0;
256
257 pInfo->iRoundingControlSwitch = 0;
258 }
259
260 pInfo->SEARCH_RANGE_Y = 16;
261 pInfo->IME_ADAPTIVE_WINDOW = 1;
262 if (pInfo->SEARCH_RANGE_Y<=16 && pInfo->iSearchRangeForward<=16)
263 pInfo->iFCode = 1;
264 else
265 pInfo->iFCode = 2;
266
267 pInfo->iRoundingControl = pInfo->iRoundingControlSwitch;
268 pConfig->vopPredType = I_VOP;
269 pInfo->g_rec_en = 1;
270 pInfo->g_ref_en = 0;
271 pInfo->m_nLastZZ = 63;
272 pInfo->m_nFmePrec = 1; // Default: Half-pixel
273
274 pInfo->m_nBitsResyncMarker = 0;
275 pInfo->nNumBitsVPMBnum = CeilLog2((pConfig->nBufWidth*pConfig->nBufHeight)>>8); // number of bits for macroblock_number
276
277 pInfo->m_tModuloBaseDecd = 0;
278 pInfo->m_tModuloBaseDisp = 0;
279 pInfo->m_tFutureRef = 0;
280 pInfo->m_tPastRef = 0;
281 pInfo->m_t = 0;
282 pInfo->m_nBitsModuloBase = 0;
283 pInfo->m_iVopTimeIncr = 0;
284
285 pInfo->intQP = 0;
286
287 MS_ASSERT((pConfig->nBufWidth&0xF)==0);
288 MS_ASSERT((pConfig->nBufHeight&0xF)==0);
289
290 pInfo->bAllowSkippedPMBs = !(pConfig->nBbetweenP>0);
291 pInfo->nAllowDirectBMBs = 1;
292
293 pInfo->bHECEnabled = 1;
294 pInfo->nHECPeriod = 3;
295
296 // H263
297 if (pConfig->nCodecType==REG_ENC_MODE_H263) {
298 if (pConfig->nBufHeight<=400)
299 pInfo->nGobUnit = 0;
300 else if (pConfig->nBufHeight<=800)
301 pInfo->nGobUnit = 1;
302 else if (pConfig->nBufHeight<=1152)
303 pInfo->nGobUnit = 2;
304 else
305 MS_ASSERT(0);
306 pInfo->m_iGobFrameId = 0;
307 }
308
309 // Rate control
310 MfeDrvRateControlInit(pConfig);
311
312 // FDC header initialization
313 osCreate(&pConfig->m_OutStream);
314 osSetWriteBuffer(&pConfig->m_OutStream, pConfig->m_FdcBuffer);
315
316 // Intra-update initialization
317 IntraUpdateInit(pConfig);
318 }
319
320
mfeM4VE_EncodeFrame(MFE_CONFIG * pConfig,GOPINFO * pGopInfo)321 void mfeM4VE_EncodeFrame(MFE_CONFIG *pConfig, GOPINFO* pGopInfo)
322 {
323 M4VEINFO* pInfo = &pConfig->ctxM4veInfo;
324 BitsInfo* pBitsInfo = &pConfig->ctxBitsInfo;
325 OutStream* pStream = &pConfig->m_OutStream;
326 const MS_U8 gBITMASK[8] = { 0x0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe };
327 // This is done in msAPI_MFE_EnOneFrm()
328 //mfeSetVopType(pConfig, pGopInfo); // Will set pConfig->vopPredType
329
330 // Config
331 // Frame type
332 pInfo->bInterlace = pInfo->bInterlacedCoding;
333 if (!pInfo->bShortHeader) {
334 if (pConfig->vopPredType==P_VOP) {
335 pInfo->iRoundingControlSwitch ^= 1;
336 pInfo->iRoundingControl = pInfo->iRoundingControlSwitch;
337 }
338 else if (pConfig->vopPredType==B_VOP)
339 pInfo->iRoundingControl = 0;
340 }
341 pInfo->g_rec_en = (MS_U8)((pConfig->nPbetweenI==0 || pConfig->vopPredType==B_VOP) ? /*0*/(pGopInfo->nCodingOrder&1) : 1); // nCodingOrder&1 is for testing.
342 pInfo->g_ref_en = pConfig->vopPredType==I_VOP ? 0 : (pConfig->vopPredType==P_VOP?1:3);
343 pInfo->bMvStore = (pConfig->nBbetweenP>0) & ((pConfig->vopPredType==P_VOP) | (/*IVOP_MVSTORE*/1 & (pConfig->vopPredType==I_VOP) & (pGopInfo->nCodingOrder!=0)));
344
345 #ifdef _GenSkipHeader_
346 if(pConfig->VTMode && rc_CheckSkippedFrame(&pConfig->VTRateCtrl)){
347 codeNonCodedVOPShortHead(pConfig, pStream);
348 // Finalize
349 osFlushAll(&pConfig->m_OutStream);
350 return;
351 }
352 #endif
353 if(pConfig->VTMode) {
354 MS_S8 chFrameType;
355 if(pConfig->vopPredType==I_VOP)
356 chFrameType = 'I';
357 else
358 chFrameType = 'P';
359 {
360 //update original ratecontrol struct for set reg.
361 CVBRRateControl* rcCtx = &pConfig->ctxRateControl;
362 RateCtrl_t* rcVTCtx = &pConfig->VTRateCtrl;
363 rcCtx->m_rcGranularity=MBLEVELRC;
364 rcCtx->m_nFrameQStep = rcQP2Qstep(rcCtx,rc_InitFrame(&pConfig->VTRateCtrl, chFrameType));
365 rcCtx->m_nTargetMbBits = rcVTCtx->m_nTargetBits / rcVTCtx->m_nNFrame;
366 rcCtx->m_nMinQP = SPEC_MIN_QP;
367 rcCtx->m_nMaxQP = SPEC_MAX_QP;
368 rcCtx->m_nMinQStep = SPEC_MIN_QP<<QS_SHIFT_FACTOR;
369 rcCtx->m_nMaxQStep = SPEC_MAX_QP<<QS_SHIFT_FACTOR;
370 rcCtx->m_nCodecType = pConfig->nCodecType;
371 pInfo->intQP = rcQstep2QP(rcCtx, rcCtx->m_nFrameQStep);
372 ms_dprintf(DRV_L3, "m_rcGranularity = %d, rcCtx->m_nTargetMbBits = %d",
373 rcCtx->m_rcGranularity, (int)rcCtx->m_nTargetMbBits);
374 }
375 }
376 else
377 pInfo->intQP = cvbr_InitFrame(&pConfig->ctxRateControl, pConfig->vopPredType, 0);
378
379 // Frame time
380 pInfo->m_t = pGopInfo->nDispOrder;
381 if (pConfig->vopPredType != B_VOP) {
382 pInfo->m_tPastRef = pInfo->m_tFutureRef;
383 pInfo->m_tFutureRef = pInfo->m_t;
384 }
385 // Handled in codeVOPHeadInitial()
386 //m_tModuloBaseDecd
387 //m_tModuloBaseDisp
388 //m_nBitsModuloBase
389 //m_iVopTimeIncr
390
391 // VideoPacket, GOB parameters
392 pInfo->m_nBitsResyncMarker = 17/*NUMBITS_VP_RESYNC_MARKER*/;
393 if(pConfig->vopPredType == P_VOP)
394 pInfo->m_nBitsResyncMarker += (pInfo->iFCode - 1);
395 else if(pConfig->vopPredType == B_VOP) {
396 // tung : VP 4.21
397 pInfo->m_nBitsResyncMarker += (pInfo->iFCode - 1);
398 if (pInfo->m_nBitsResyncMarker<18)
399 pInfo->m_nBitsResyncMarker = 18;
400 // ~tung
401 }
402
403 // H263
404 pInfo->m_iGobFrameId = (pConfig->vopPredType==P_VOP ? 1 : 0);
405
406 // Buffer management
407 m4veGetBufferAddr(pConfig);
408
409 //MODE 0: (Checking range > real range ) reg_mfe_s_marb_miu_bound_err = 0
410 //MODE 1: (Checking range < real range ) reg_mfe_s_marb_miu_bound_err = 1
411 //#define TEST_MIU_PROTECTION_MODE 0UL
412 #ifdef MFE_MIU_PROTECT
413 MHal_MFE_Enable_MIU_Protection(TEST_MIU_PROTECTION_MODE,pConfig);
414 #endif
415
416
417 // Prepare header
418 osReset(&pConfig->m_OutStream);
419 if (!pInfo->bShortHeader)
420 {
421 // VOS and VO header
422 if (pGopInfo->nCodingOrder==0)
423 {
424 codeSequenceHead(pConfig, pStream);
425 codeVOHead(pConfig, pStream);
426 }
427 // VOL header
428 #if defined(_MFE_T8_)
429 if (pGopInfo->nCodingOrder==0||pConfig->vopPredType==I_VOP)
430 #else
431 if (pGopInfo->nCodingOrder==0)
432 #endif
433 {
434 codeVOLHead(pConfig, pStream);
435 }
436 }
437
438 // VOP header
439 if (pConfig->m_cvbrFrameSkip>0 && pConfig->vopPredType==P_VOP) {
440 if (pConfig->m_bGenSkipVopHeader) {
441 if (pInfo->bShortHeader)
442 codeNonCodedVOPShortHead(pConfig, pStream);
443 else
444 codeNonCodedVOPHead(pConfig, pStream);
445 }
446 }
447 else {
448 if (pInfo->bShortHeader)
449 codeVOPShortHead(pConfig, pStream);
450 else
451 codeVOPHead(pConfig, pStream);
452 }
453 // Finalize
454 osFlushAll(&pConfig->m_OutStream);
455 pBitsInfo->ptr = pStream->m_pbFrameBuffer;
456 pBitsInfo->len = pStream->m_nByteCount;
457 if ((pStream->BC_nCumulativeBits&7)==0) {
458 pBitsInfo->bit_len = 0;
459 pBitsInfo->bits = 0;
460 }
461 else {
462 pBitsInfo->len--;
463 pBitsInfo->bit_len = pStream->BC_nCumulativeBits&7;
464 pBitsInfo->bits = pStream->m_pbFrameBuffer[pStream->BC_nCumulativeBits>>3] & gBITMASK[pBitsInfo->bit_len];
465 }
466 /*
467 #if DEBUG_LEVEL
468 { // DEBUG codes
469 MS_S32 i;
470 ms_dprintk(DRV_L3,"FDC bitcount %d ==> "), pBitsInfo->len*8+pBitsInfo->bit_len);
471 for (i=0; i<pBitsInfo->len; i++) {
472 ms_dprintk(DRV_L3,"%02x "), pBitsInfo->ptr[i]);
473 }
474 ms_dprintk(DRV_L3,"%02x(msb %d bits)\n"), pBitsInfo->bits, pBitsInfo->bit_len);
475 }
476 #endif
477 */
478 // Set reg and start encoding
479 OutputSwCfg1_Mp4(pGopInfo->nCodingOrder, pConfig);
480 ms_dprintk(DRV_L3,"In mfeM4VE_EncodeFrame() After OutputSwCfg1_Mp4\n");
481 }
482
483
484
mfeM4VE_UpdateFrame(MFE_CONFIG * pConfig)485 void mfeM4VE_UpdateFrame(MFE_CONFIG *pConfig)
486 {
487 if (pConfig->vopPredType==I_VOP)
488 IntraUpdateInit(pConfig);
489 IntraUpdateFrame(pConfig);
490
491 // Rate control
492 MfeDrvRateControlUpdate(pConfig, 0);
493
494 }
495
496 // Trd must >= Trb, no checking here.
TrbTrdReduction(MS_S32 * Trb,MS_S32 * Trd)497 static void TrbTrdReduction(MS_S32* Trb, MS_S32* Trd)
498 {
499 MS_S32 r;
500 MS_S32 d = *Trd;
501 MS_S32 b = *Trb;
502
503 if (b==d) {
504 *Trb = *Trd = 1;
505 return;
506 }
507
508 // b < d
509 while(1) {
510 r = d%b;
511 if(r==0) {
512 *Trb /= b;
513 *Trd /= b;
514 return;
515 }
516 d = b;
517 b = r;
518 }
519 }
520
OutputSwCfg1_Mp4(MS_S32 nFrmNum,MFE_CONFIG * pConfig)521 void OutputSwCfg1_Mp4(MS_S32 nFrmNum, MFE_CONFIG* pConfig)
522 {
523
524 MS_S32 nTarWriteCount;
525 MS_S32 nRegWriteCount;
526 MS_S32 nTarFDCCount;
527 MS_S32 nRegFDCCount;
528
529 M4VEINFO* pM4veInfo = &pConfig->ctxM4veInfo;
530 BufInfo* pBufInfo = &pConfig->ctxBufInfo;
531 BitsInfo* pBitsInfo = &pConfig->ctxBitsInfo;
532 CVBRRateControl* rcCtx = &pConfig->ctxRateControl;
533 MFE_REG* mfe_reg = &pConfig->mfe_reg;
534
535 //////////////////////////////////////////////////////////////////////////
536 // Sequence-wide settings
537
538 if (nFrmNum==0) {
539 memset(mfe_reg, 0, sizeof(MFE_REG)); // Initial
540 mfe_reg->reg_mfe_g_enc_mode = pM4veInfo->bShortHeader ? REG_ENC_MODE_H263 : REG_ENC_MODE_MPG4;
541 mfe_reg->reg_mfe_g_pic_width = pConfig->nBufWidth;
542 mfe_reg->reg_mfe_g_pic_height = pConfig->nBufHeight;
543 #ifdef _MFE_M1_
544 mfe_reg->reg_mfe_g_jpe_buffer_mode=0;
545 #endif
546 if (mfe_reg->reg_mfe_g_enc_mode==REG_ENC_MODE_MPG4) { // MPEG-4
547 // Qtable
548 mfe_reg->reg_mfe_g_qmode = pM4veInfo->bQuantizerType;
549
550 mfe_reg->reg_mfe_g_mp4_itlc = pM4veInfo->bInterlacedCoding;
551 mfe_reg->reg_mfe_g_mp4_pskip_off = (pM4veInfo->bAllowSkippedPMBs==0);
552 mfe_reg->reg_mfe_g_mp4_acp = (0<<1) | 1; // disabled
553 mfe_reg->reg_mfe_g_er_hec = pM4veInfo->bHECEnabled;
554 mfe_reg->reg_mfe_g_er_hec_t = pM4veInfo->nHECPeriod;
555 mfe_reg->reg_mfe_g_mp4_direct_en = pM4veInfo->nAllowDirectBMBs==0 ? 0 : 1;
556 mfe_reg->reg_mfe_g_inter_pref = 512; // inter-intra selection
557
558 // ME partition type
559 mfe_reg->reg_mfe_s_me_16x16_disable = 0;
560 mfe_reg->reg_mfe_s_me_8x8_disable = 0;
561 mfe_reg->reg_mfe_s_me_16x8_disable = 1;
562 mfe_reg->reg_mfe_s_me_8x16_disable = 1;
563 mfe_reg->reg_mfe_s_me_8x4_disable = 1;
564 mfe_reg->reg_mfe_s_me_4x8_disable = 1;
565 mfe_reg->reg_mfe_s_me_4x4_disable = 1;
566
567 // MDC
568 mfe_reg->reg_mfe_s_mdc_total_mb_bw = pM4veInfo->nNumBitsVPMBnum;
569 mfe_reg->reg_mfe_s_mdc_m4vop_tinc_bw = pM4veInfo->nNumBitsTimeIncr;
570
571 // Field DCT
572 mfe_reg->reg_mfe_g_mp4_flddct_en = pM4veInfo->bInterlace ? 1 : 0;
573 mfe_reg->reg_mfe_g_mp4_flddct_diff_thr = FIELD_DCT_DIFF_THR;
574 }
575 if (mfe_reg->reg_mfe_g_enc_mode==REG_ENC_MODE_H263) { // H263
576 // Qtable
577 mfe_reg->reg_mfe_g_qmode = 0;
578
579 mfe_reg->reg_mfe_g_er_h263_unit = pM4veInfo->nGobUnit;
580 mfe_reg->reg_mfe_g_inter_pref = 512; // inter-intra selection
581
582 // ME partition type
583 mfe_reg->reg_mfe_s_me_16x16_disable = 0;
584 mfe_reg->reg_mfe_s_ime_sr16 = 1;
585 mfe_reg->reg_mfe_s_ime_umv_disable = 1;
586 mfe_reg->reg_mfe_s_me_8x8_disable = 1;
587 mfe_reg->reg_mfe_s_me_16x8_disable = 1;
588 mfe_reg->reg_mfe_s_me_8x16_disable = 1;
589 mfe_reg->reg_mfe_s_me_8x4_disable = 1;
590 mfe_reg->reg_mfe_s_me_4x8_disable = 1;
591 mfe_reg->reg_mfe_s_me_4x4_disable = 1;
592 }
593 #ifdef _MFE_M1_
594 // pre-fetch
595 mfe_reg->reg_mfe_s_prfh_cryc_en = 1;
596 mfe_reg->reg_mfe_s_prfh_refy_en = 1;
597 mfe_reg->reg_mfe_s_prfh_cryc_idle_cnt = 0;
598 mfe_reg->reg_mfe_s_prfh_refy_idle_cnt = 0;
599
600 if (pConfig->m_bFrameMode) {
601 mfe_reg->reg_mfe_g_jpe_buffer_mode = 1; // frame-mode
602 mfe_reg->reg_mfe_g_jpe_fsvs_mode = 0;
603 }
604 else {
605 mfe_reg->reg_mfe_g_jpe_buffer_mode = 0; // row-mode
606 mfe_reg->reg_mfe_g_jpe_multibuf_mode = 0;
607 mfe_reg->reg_mfe_g_jpe_enc_mode = 0; // 420
608 mfe_reg->reg_mfe_g_jpe_qfactor = 3;
609 #if defined(TEST_INPUT_ROW_MODE_HWAUTO_OK) || defined(TEST_INPUT_ROW_MODE_HWAUTO_FAIL1) || defined(TEST_INPUT_ROW_MODE_HWAUTO_FAIL2) || defined(TEST_INPUT_ROW_MODE_HWAUTO_FAIL3)
610 mfe_reg->reg_mfe_g_jpe_fsvs_mode=3;
611 #elif defined(TEST_INPUT_ROW_MODE_HW_OK) || defined(TEST_INPUT_ROW_MODE_HW_FAIL)
612 mfe_reg->reg_mfe_g_jpe_fsvs_mode=2;
613 #elif defined(TEST_INPUT_ROW_MODE_SWHW_OK) || defined(TEST_INPUT_ROW_MODE_SWHW_FAIL)
614 mfe_reg->reg_mfe_g_jpe_fsvs_mode=1;
615 #else
616 mfe_reg->reg_mfe_g_jpe_fsvs_mode=2;
617 #endif
618 }
619
620 #ifdef SW_BUF_MODE
621 mfe_reg->reg_mfe_g_sw_buffer_mode = 1;
622 #else
623 mfe_reg->reg_mfe_g_sw_buffer_mode = 0;
624 #endif
625 #endif //_MFE_M1_
626 }
627 else {
628 mfe_reg->reg_mfe_g_frame_start_sw = 0;
629 }
630
631
632 //////////////////////////////////////////////////////////////////////////
633 // Frame-wide settings
634 #ifdef CLOCK_GATING
635 mfe_reg->reg16 = 0xffff; // clock gating
636 #endif
637
638 // Input buffer address: Must be 256-byte aligned.
639 MS_ASSERT((pBufInfo->m_nCurYAddr.miuAddress&0xFF)==0);
640 MS_ASSERT((pBufInfo->m_nCurCAddr.miuAddress&0xFF)==0);
641 MS_ASSERT((pBufInfo->m_nRefYAddr[0].miuAddress&0xFF)==0);
642 MS_ASSERT((pBufInfo->m_nRefCAddr[0].miuAddress&0xFF)==0);
643 if(pConfig->m_bFrameMode==0) {
644 MS_ASSERT((pBufInfo->m_nRefYAddr[1].miuAddress&0xFF)==0);
645 MS_ASSERT((pBufInfo->m_nRefCAddr[1].miuAddress&0xFF)==0);
646 }
647 MS_ASSERT((pBufInfo->m_nOutBufAddr[pConfig->nOBufIndex].miuAddress&0x7)==0);
648 mfe_reg->reg_mfe_g_cur_y_adr_low = (MS_U16)((pBufInfo->m_nCurYAddr.miuAddress>>8)&0xFFFF);
649 mfe_reg->reg_mfe_g_cur_y_adr_high = (MS_U16)(pBufInfo->m_nCurYAddr.miuAddress>>(8+16));
650 mfe_reg->reg_mfe_g_cur_c_adr_low = (MS_U16)((pBufInfo->m_nCurCAddr.miuAddress>>8)&0xFFFF);
651 mfe_reg->reg_mfe_g_cur_c_adr_high = (MS_U16)(pBufInfo->m_nCurCAddr.miuAddress>>(8+16));
652
653 mfe_reg->reg_mfe_g_ref_y_adr0_low = (MS_U16)((pBufInfo->m_nRefYAddr[0].miuAddress>>8)&0xFFFF);
654 mfe_reg->reg_mfe_g_ref_y_adr0_high = (MS_U16)(pBufInfo->m_nRefYAddr[0].miuAddress>>(8+16));
655 mfe_reg->reg_mfe_g_ref_c_adr0_low = (MS_U16)((pBufInfo->m_nRefCAddr[0].miuAddress>>8)&0xFFFF);
656 mfe_reg->reg_mfe_g_ref_c_adr0_high = (MS_U16)(pBufInfo->m_nRefCAddr[0].miuAddress>>(8+16));
657 if(pConfig->m_bFrameMode==0) {
658 mfe_reg->reg_mfe_g_ref_y_adr1_low = (MS_U16)((pBufInfo->m_nRefYAddr[1].miuAddress>>8)&0xFFFF);
659 mfe_reg->reg_mfe_g_ref_y_adr1_high = (MS_U16)(pBufInfo->m_nRefYAddr[1].miuAddress>>(8+16));
660 mfe_reg->reg_mfe_g_ref_c_adr1_low = (MS_U16)((pBufInfo->m_nRefCAddr[1].miuAddress>>8)&0xFFFF);
661 mfe_reg->reg_mfe_g_ref_c_adr1_high = (MS_U16)(pBufInfo->m_nRefCAddr[1].miuAddress>>(8+16));
662 }
663 #ifdef USE_CUR_AS_REC
664 MS_ASSERT(pBufInfo->m_nRecYAddr.miuAddress==pBufInfo->m_nCurYAddr.miuAddress);
665 MS_ASSERT(pBufInfo->m_nRecCAddr.miuAddress==pBufInfo->m_nCurCAddr.miuAddress);
666 #endif
667 mfe_reg->reg_mfe_g_rec_y_adr_low = (MS_U16)((pBufInfo->m_nRecYAddr.miuAddress>>8)&0xFFFF);
668 mfe_reg->reg_mfe_g_rec_y_adr_high = (MS_U16)(pBufInfo->m_nRecYAddr.miuAddress>>(8+16));
669 mfe_reg->reg_mfe_g_rec_c_adr_low = (MS_U16)((pBufInfo->m_nRecCAddr.miuAddress>>8)&0xFFFF);
670 mfe_reg->reg_mfe_g_rec_c_adr_high = (MS_U16)(pBufInfo->m_nRecCAddr.miuAddress>>(8+16));
671
672 // Output buffers: Must be 8-byte aligned.
673 #if defined(_MFE_M1_)||defined(_MFE_AGATE_)
674 mfe_reg->reg_mfe_s_bspobuf_hw_en = 0;
675 #if defined(USE_HW_DBL_OBUF)
676 mfe_reg->reg_mfe_s_bspobuf_hw_en = 1;
677 #endif
678 #else
679 mfe_reg->reg_mfe_s_bspobuf_sadr_low = (MS_U16)((pBufInfo->m_nOutBufAddr[pConfig->nOBufIndex].miuAddress>>3)&0xFFFF);
680 mfe_reg->reg_mfe_s_bspobuf_sadr_high = (MS_U16)(pBufInfo->m_nOutBufAddr[pConfig->nOBufIndex].miuAddress>>(3+16));
681 mfe_reg->reg_mfe_s_bspobuf_eadr_low = (MS_U16)(((pBufInfo->m_nOutBufAddr[pConfig->nOBufIndex].miuAddress+pBufInfo->m_OutBufferSize-8)>>3)&0xFFFF);
682 mfe_reg->reg_mfe_s_bspobuf_eadr_high = (MS_U16)((pBufInfo->m_nOutBufAddr[pConfig->nOBufIndex].miuAddress+pBufInfo->m_OutBufferSize-8)>>(3+16));
683 #endif
684 // GN
685 mfe_reg->reg_mfe_s_gn_sadr_low = (MS_U16)((pBufInfo->m_nGNAddr.miuAddress>>3)&0xFFFF);
686 mfe_reg->reg_mfe_s_gn_sadr_high = (MS_U16)(pBufInfo->m_nGNAddr.miuAddress>>(3+16));
687 #ifdef _MFE_M1_
688 mfe_reg->reg_mfe_s_gn_sadr_mode =
689 #if defined(GN_WHOLE_FRAME)
690 1;
691 #else
692 0;
693 #endif
694 #endif
695
696 // MV store
697 if (mfe_reg->reg_mfe_g_enc_mode==REG_ENC_MODE_MPG4) {
698 mfe_reg->reg_mfe_g_mp4_direct_mvstore = pBufInfo->m_bEnableMvStore;
699 if (mfe_reg->reg_mfe_g_mp4_direct_mvstore) {
700 mfe_reg->reg_mfe_s_mvobuf_sadr_low = (MS_U16)((pBufInfo->m_nMvStoreAddr.miuAddress>>3)&0xFFFF);
701 mfe_reg->reg_mfe_s_mvobuf_sadr_high = (MS_U16)(pBufInfo->m_nMvStoreAddr.miuAddress>>(3+16));
702 }
703 if (mfe_reg->reg_mfe_g_mp4_direct_en) {
704 mfe_reg->reg_mfe_s_gn_mvibuf_sadr_low = (MS_U16)((pBufInfo->m_nMvStoreAddr.miuAddress>>3)&0xFFFF);
705 mfe_reg->reg_mfe_s_gn_mvibuf_sadr_high = (MS_U16)(pBufInfo->m_nMvStoreAddr.miuAddress>>(3+16));
706 }
707 }
708 #ifdef _MFE_M1_
709 // IMI buffer
710 if(pConfig->MfeAdvInfo.input_imi_en) {
711 mfe_reg->reg_mfe_s_marb_eimi_block = 0x1;
712 WriteRegMFE(0x68, mfe_reg->reg68, (MS_S8*)("[%d] reg68"), nRegWriteCount, (MS_S8*)("IMI enable"));
713 }
714 else
715 mfe_reg->reg_mfe_s_marb_eimi_block = 0x0;
716
717 mfe_reg->reg_mfe_s_marb_lbwd_mode = 0;
718 mfe_reg->reg_mfe_s_marb_imi_sadr_low = 0;
719 mfe_reg->reg_mfe_s_marb_imi_sadr_high = 0;
720
721 if (pConfig->vopPredType!=I_VOP && pConfig->MfeAdvInfo.low_bandwidth_en && pConfig->imi_size>0) {
722 mfe_reg->reg_mfe_s_marb_eimi_block = 1;
723 mfe_reg->reg_mfe_s_marb_lbwd_mode = 1;
724 mfe_reg->reg_mfe_s_marb_imi_sadr_low = (pConfig->imi_addr>>3)&0xFFFF;
725 mfe_reg->reg_mfe_s_marb_imi_sadr_high = pConfig->imi_addr>>(3+16);
726 switch (pConfig->imi_size) {
727 // 0: 64kB, 1:32kB, 2:16kB, 3:8kB
728 case 0x10000:
729 mfe_reg->reg_mfe_s_marb_imi_cache_size = 0;
730 break;
731 case 0x8000:
732 mfe_reg->reg_mfe_s_marb_imi_cache_size = 1;
733 break;
734 case 0x4000:
735 mfe_reg->reg_mfe_s_marb_imi_cache_size = 2;
736 break;
737 case 0x2000:
738 mfe_reg->reg_mfe_s_marb_imi_cache_size = 3;
739 break;
740 default:
741 mfe_reg->reg_mfe_s_marb_imi_cache_size = 0;
742 MS_ASSERT(0);
743 }
744 }
745 #endif
746 mfe_reg->reg_mfe_g_frame_type = pConfig->vopPredType==I_VOP ? 0 : (pConfig->vopPredType==P_VOP?1:2);
747 mfe_reg->reg_mfe_g_ref_no = pConfig->vopPredType==P_VOP ? 0 : (pConfig->vopPredType==B_VOP&&(!pM4veInfo->nAllowDirectBMBs)&&pM4veInfo->g_ref_en!=3 ? 0 : 1);
748
749 // ME setting
750 mfe_reg->reg_mfe_s_ime_mesr_max_addr = (pM4veInfo->SEARCH_RANGE_Y==16 ? 95 : 83);//0x5f;
751 mfe_reg->reg_mfe_s_ime_mesr_min_addr = (pM4veInfo->SEARCH_RANGE_Y==16 ? 0 : 16);//0;
752 mfe_reg->reg_mfe_s_ime_mvx_min = -(pConfig->vopPredType==I_VOP?0:pM4veInfo->iSearchRangeForward) + 32; // Min X is -pVopMd->iSearchRangeForward
753 mfe_reg->reg_mfe_s_ime_mvx_max = ((pConfig->vopPredType==I_VOP?0:pM4veInfo->iSearchRangeForward)-2) + 32; // Max X is pVopMd->iSearchRangeForward-1
754 mfe_reg->reg_mfe_s_ime_mvy_min = -pM4veInfo->SEARCH_RANGE_Y + 16; // Min Y
755 mfe_reg->reg_mfe_s_ime_mvy_max = (pM4veInfo->SEARCH_RANGE_Y==16 ? 15 : 8) + 16; // Max Y
756 mfe_reg->reg_mfe_s_ime_sr16 = (mfe_reg->reg_mfe_s_ime_mvx_min>=16 ? 1 : 0);
757 mfe_reg->reg_mfe_s_mesr_adapt = pM4veInfo->IME_ADAPTIVE_WINDOW?1:0;
758 mfe_reg->reg_mfe_s_me_ref_en_mode = pM4veInfo->g_ref_en;
759 mfe_reg->reg_mfe_s_ime_ime_wait_fme = 1;
760 #ifdef FME_PIPELINE_OPEN
761 mfe_reg->reg_mfe_s_fme_pipeline_on = mfe_reg->reg_mfe_s_ime_ime_wait_fme ? 1 : 0;
762 #else
763 mfe_reg->reg_mfe_s_fme_pipeline_on = 0x0;
764 #endif
765
766 // Intra update
767 mfe_reg->reg_mfe_s_txip_irfsh_en = 0;
768
769 if(mfe_reg->reg_mfe_s_txip_irfsh_en)
770 {
771 MS_S32 i;
772 MS_S32 count, prv_intra;
773 MS_S32 start[2], end[2];
774 IntraUpdateContext* ctx = &pConfig->m_IUContext;
775
776 count = 0;
777 prv_intra = 0;
778 for (i=0; i<ctx->nTotalMb; i++) {
779 if (ctx->pHwMbMap[i].intra) {
780 if (prv_intra==0) {
781 count++;
782 if (count>2) {
783 MS_ASSERT(0);
784 }
785 start[count-1] = end[count-1] = i;
786 }
787 else
788 end[count-1] = i;
789 }
790 prv_intra = ctx->pHwMbMap[i].intra;
791 }
792 if (count>0) {
793 mfe_reg->reg_mfe_s_txip_irfsh_en |= 1;
794 mfe_reg->reg_mfe_s_txip_irfsh_mb_s0 = start[0];
795 mfe_reg->reg_mfe_s_txip_irfsh_mb_e0 = end[0];
796 }
797 if (count>1) {
798 mfe_reg->reg_mfe_s_txip_irfsh_en |= 2;
799 mfe_reg->reg_mfe_s_txip_irfsh_mb_s1 = start[1];
800 mfe_reg->reg_mfe_s_txip_irfsh_mb_e1 = end[1];
801 }
802 }
803
804
805
806 // LastZZ
807 mfe_reg->reg_mfe_s_quan_idx_last = pM4veInfo->m_nLastZZ;
808 if (mfe_reg->reg_mfe_s_quan_idx_last<63)
809 mfe_reg->reg_mfe_s_quan_idx_swlast = 1;
810 else
811 mfe_reg->reg_mfe_s_quan_idx_swlast = 0;
812
813 if (mfe_reg->reg_mfe_g_enc_mode==REG_ENC_MODE_MPG4) { // MPEG-4
814 mfe_reg->reg_mfe_s_fme_quarter_disable = 1;
815 mfe_reg->reg_mfe_s_fme_half_disable = (pM4veInfo->m_nFmePrec==0);
816 //mfe_reg->reg_mfe_s_fme_one_mode = 0;
817 mfe_reg->reg_mfe_s_fme_pmv_enable = 0;
818 mfe_reg->reg_mfe_s_fme_mode_no = pConfig->vopPredType==P_VOP ? 1 : 0;
819 mfe_reg->reg_mfe_s_fme_mode0_refno = pConfig->vopPredType==P_VOP ? 0 : ((pConfig->vopPredType==B_VOP&&pM4veInfo->g_ref_en!=3)?0:1);
820 mfe_reg->reg_mfe_s_fme_mode1_refno = 0;
821 mfe_reg->reg_mfe_s_fme_mode2_refno = 0;
822
823 mfe_reg->reg_mfe_g_mp4_rounding_ctrl = pM4veInfo->iRoundingControl;
824 // codeVideoPacketHeader
825 MS_ASSERT(pM4veInfo->m_nBitsResyncMarker==17||pM4veInfo->m_nBitsResyncMarker==18);
826 mfe_reg->reg_mfe_s_mdc_m4vpktpzero = (pM4veInfo->m_nBitsResyncMarker-1==17) ? 1 : 0;
827 mfe_reg->reg_mfe_s_mdc_m4time = pM4veInfo->m_nBitsModuloBase;
828 mfe_reg->reg_mfe_s_mdc_m4vop_tinc = pM4veInfo->m_iVopTimeIncr;
829
830 // B-direct mode
831 mfe_reg->reg_mfe_g_mp4_direct_pref = 129;
832 {
833 MS_S32 trd = pM4veInfo->m_tFutureRef - pM4veInfo->m_tPastRef;
834 MS_S32 trb = pM4veInfo->m_t - pM4veInfo->m_tPastRef;
835 if (trb&trb)
836 TrbTrdReduction(&trb, &trd);
837 mfe_reg->reg_mfe_g_mp4_direct_trb = trb;
838 mfe_reg->reg_mfe_g_mp4_direct_trd = trd;
839 }
840 }
841
842
843 if (mfe_reg->reg_mfe_g_enc_mode==REG_ENC_MODE_H263) { // H263
844 mfe_reg->reg_mfe_s_fme_quarter_disable = 1;
845 mfe_reg->reg_mfe_s_fme_half_disable = (pM4veInfo->m_nFmePrec==0);
846 //mfe_reg->reg_mfe_s_fme_one_mode = 1;
847 mfe_reg->reg_mfe_s_fme_pmv_enable = 0;
848 mfe_reg->reg_mfe_s_fme_mode_no = 0;
849 mfe_reg->reg_mfe_s_fme_mode0_refno = 0;
850 mfe_reg->reg_mfe_s_fme_mode1_refno = 0;
851 mfe_reg->reg_mfe_s_fme_mode2_refno = 0;
852
853 mfe_reg->reg_mfe_s_mdc_gob_frame_id = pM4veInfo->m_iGobFrameId;
854 }
855 ms_dprintf(DRV_L3,"m_rcGranularity = %d",rcCtx->m_rcGranularity);
856 // MBR
857 mfe_reg->reg_mfe_g_mbr_en = rcCtx->m_rcGranularity==MBLEVELRC ? 1 : 0;
858 mfe_reg->reg_mfe_s_mbr_pqp_dlimit = LEFT_QP_DIFF_LIMIT;
859 mfe_reg->reg_mfe_s_mbr_uqp_dlimit = TOP_QP_DIFF_LIMIT;
860 // er_en
861 if (rcCtx->m_nVPMbRow>0 && rcCtx->m_nVPSize<=0)
862 mfe_reg->reg_mfe_g_er_mode = 0;
863 else if (rcCtx->m_nVPMbRow<=0 && rcCtx->m_nVPSize>0)
864 mfe_reg->reg_mfe_g_er_mode = 1;
865 else if (rcCtx->m_nVPMbRow>0 && rcCtx->m_nVPSize>0)
866 mfe_reg->reg_mfe_g_er_mode = 2;
867 else
868 mfe_reg->reg_mfe_g_er_mode = 3;
869
870 if (rcCtx->m_nVPMbRow==0 || rcCtx->m_nVPMbRow==1)
871 mfe_reg->reg_mfe_g_er_mby = 0;
872 else if (rcCtx->m_nVPMbRow==2)
873 mfe_reg->reg_mfe_g_er_mby = 1;
874 else if (rcCtx->m_nVPMbRow==4)
875 mfe_reg->reg_mfe_g_er_mby = 2;
876 else if (rcCtx->m_nVPMbRow==8)
877 mfe_reg->reg_mfe_g_er_mby = 3;
878 else if (rcCtx->m_nVPMbRow>0)
879 MS_ASSERT(0);
880 if (mfe_reg->reg_mfe_g_er_mode==1 || mfe_reg->reg_mfe_g_er_mode==2)
881 mfe_reg->reg_mfe_g_er_bs_th = rcCtx->m_nVPSize;
882 mfe_reg->reg_mfe_g_qscale = pM4veInfo->intQP;
883 mfe_reg->reg_mfe_s_mbr_frame_qstep = rcCtx->m_nFrameQStep;
884 mfe_reg->reg_mfe_s_mbr_tmb_bits = rcCtx->m_nTargetMbBits;
885 // QP/QStep: Min, max
886 mfe_reg->reg_mfe_s_mbr_qp_min = rcCtx->m_nMinQP;
887 mfe_reg->reg_mfe_s_mbr_qp_max = rcCtx->m_nMaxQP;
888 MS_ASSERT(rcCtx->m_nMinQStep<(2<<7));
889 mfe_reg->reg_mfe_s_mbr_qstep_min = rcCtx->m_nMinQStep;
890 mfe_reg->reg_mfe_s_mbr_qstep_max = rcCtx->m_nMaxQStep;
891
892 mfe_reg->reg_mfe_g_rec_en = pM4veInfo->g_rec_en;
893
894 #ifdef HW_ECO_STARTCODE_PREVENTION
895 mfe_reg->reg_eco_bsp_rdy_fix = 1;
896 #if defined(_MFE_EDISON_)
897 //agate U02 cannot set this.
898 mfe_reg->reg_eco_bsp_multi_slice_fix = 1;
899 #endif
900 #endif
901 //////////////////////////////////////////////////////////////////////////
902 // swcfg1 output
903 nTarWriteCount = 0;
904 nRegWriteCount = 0;
905 nTarFDCCount = 0;
906 nRegFDCCount = 0;
907 if (nFrmNum==0)
908 WriteQTable(mfe_reg, pM4veInfo->rgiIntraQuantizerMatrix, pM4veInfo->rgiInterQuantizerMatrix);
909
910 nRegWriteCount = 0;
911 #ifdef _MFE_M1_
912 //FDC
913 mfe_reg->reg_mfe_s_bsp_fdc_skip = 0;
914 mfe_reg->reg_mfe_s_bsp_fdc_offset = 0;
915 nTarFDCCount = PutFDC(mfe_reg, pBitsInfo, 1);
916 #endif
917
918 if (mfe_reg->reg_mfe_g_enc_mode==REG_ENC_MODE_MPG4) {
919 nTarWriteCount = (pBufInfo->m_bEnableMvStore?62:59) + (nTarFDCCount*3);
920 }
921 else if (mfe_reg->reg_mfe_g_enc_mode==REG_ENC_MODE_H263) {
922 nTarWriteCount = 53 + (nTarFDCCount*3);
923 }
924 nTarWriteCount++; // reg to set fdc round
925
926 #ifdef CLOCK_GATING
927 nTarWriteCount++;
928 #endif
929
930 nTarFDCCount *= 3;
931 nTarFDCCount++; // reg to set fdc round
932
933 // SW reset
934 mfe_reg->reg_mfe_g_soft_rstz = 0;
935 WriteRegMFE(0x0, mfe_reg->reg00, (MS_S8*)("[%d] reg00"), nRegWriteCount++, (MS_S8*)("SW reset 0"));
936 mfe_reg->reg_mfe_g_soft_rstz = 1;
937 WriteRegMFE(0x0, mfe_reg->reg00, (MS_S8*)("[%d] reg00"), nRegWriteCount++, (MS_S8*)("SW reset 1"));
938 WriteRegMFE(0x1, mfe_reg->reg01, (MS_S8*)("[%d] reg01"), nRegWriteCount++, (MS_S8*)("picture width"));
939 WriteRegMFE(0x2, mfe_reg->reg02, (MS_S8*)("[%d] reg02"), nRegWriteCount++, (MS_S8*)("picture height"));
940 WriteRegMFE(0x3, mfe_reg->reg03, (MS_S8*)("[%d] reg03"), nRegWriteCount++, (MS_S8*)("value"));
941 WriteRegMFE(0x4, mfe_reg->reg04, (MS_S8*)("[%d] reg04"), nRegWriteCount++, (MS_S8*)("er_bs mode threshold"));
942 WriteRegMFE(0x5, mfe_reg->reg05, (MS_S8*)("[%d] reg05"), nRegWriteCount++, (MS_S8*)("inter prediction preference"));
943
944 WriteRegMFE(0x20, mfe_reg->reg20, (MS_S8*)("[%d] reg20"), nRegWriteCount++, (MS_S8*)("ME partition setting"));
945 WriteRegMFE(0x21, mfe_reg->reg21, (MS_S8*)("[%d] reg21"), nRegWriteCount++, (MS_S8*)("value"));
946 WriteRegMFE(0x22, mfe_reg->reg22, (MS_S8*)("[%d] reg22"), nRegWriteCount++, (MS_S8*)("me search range max depth"));
947 WriteRegMFE(0x23, mfe_reg->reg23, (MS_S8*)("[%d] reg23"), nRegWriteCount++, (MS_S8*)("me mvx"));
948 WriteRegMFE(0x24, mfe_reg->reg24, (MS_S8*)("[%d] reg24"), nRegWriteCount++, (MS_S8*)("me mvy"));
949 WriteRegMFE(0x25, mfe_reg->reg25, (MS_S8*)("[%d] reg25"), nRegWriteCount++, (MS_S8*)("FME"));
950
951 #ifdef CLOCK_GATING
952 WriteRegMFE(0x16, mfe_reg->reg16, (MS_S8*)("[%d] reg16"), nRegWriteCount++, (MS_S8*)("Clock gating"));
953 #endif
954
955 // Input buffers
956 //
957 WriteRegMFE(0x06, mfe_reg->reg06, (MS_S8*)("[%d] reg06"), nRegWriteCount++, (MS_S8*)("current luma base address"));
958 WriteRegMFE(0x07, mfe_reg->reg07, (MS_S8*)("[%d] reg07"), nRegWriteCount++, (MS_S8*)("current luma base address high"));
959 WriteRegMFE(0x08, mfe_reg->reg08, (MS_S8*)("[%d] reg08"), nRegWriteCount++, (MS_S8*)("current chroma base address"));
960 WriteRegMFE(0x09, mfe_reg->reg09, (MS_S8*)("[%d] reg09"), nRegWriteCount++, (MS_S8*)("current chroma base address high"));
961 WriteRegMFE(0x0a, mfe_reg->reg0a, (MS_S8*)("[%d] reg0a"), nRegWriteCount++, (MS_S8*)("reference luma base address0"));
962 WriteRegMFE(0x0b, mfe_reg->reg0b, (MS_S8*)("[%d] reg0b"), nRegWriteCount++, (MS_S8*)("reference luma base address0 high"));
963 WriteRegMFE(0x0c, mfe_reg->reg0c, (MS_S8*)("[%d] reg0c"), nRegWriteCount++, (MS_S8*)("reference luma base address1"));
964 WriteRegMFE(0x0d, mfe_reg->reg0d, (MS_S8*)("[%d] reg0d"), nRegWriteCount++, (MS_S8*)("reference luma base address1 high"));
965 WriteRegMFE(0x0e, mfe_reg->reg0e, (MS_S8*)("[%d] reg0e"), nRegWriteCount++, (MS_S8*)("reference chroma base address0"));
966 WriteRegMFE(0x0f, mfe_reg->reg0f, (MS_S8*)("[%d] reg0f"), nRegWriteCount++, (MS_S8*)("reference chroma base address0 high"));
967 WriteRegMFE(0x10, mfe_reg->reg10, (MS_S8*)("[%d] reg10"), nRegWriteCount++, (MS_S8*)("reference chroma base address1"));
968 WriteRegMFE(0x11, mfe_reg->reg11, (MS_S8*)("[%d] reg11"), nRegWriteCount++, (MS_S8*)("reference chroma base address1 high"));
969 WriteRegMFE(0x12, mfe_reg->reg12, (MS_S8*)("[%d] reg12"), nRegWriteCount++, (MS_S8*)("reconstructed luma base address:"));
970 WriteRegMFE(0x13, mfe_reg->reg13, (MS_S8*)("[%d] reg13"), nRegWriteCount++, (MS_S8*)("reconstructed luma base address high"));
971 WriteRegMFE(0x14, mfe_reg->reg14, (MS_S8*)("[%d] reg14"), nRegWriteCount++, (MS_S8*)("reconstructed chroma base address:"));
972 WriteRegMFE(0x15, mfe_reg->reg15, (MS_S8*)("[%d] reg15"), nRegWriteCount++, (MS_S8*)("reconstructed chroma base address: high"));
973
974 #if defined(_MFE_T8_)&&!defined(_MFE_AGATE_)
975 // Output buffer
976 WriteRegMFE(0x3c, mfe_reg->reg3c, (MS_S8*)("[%d] reg3c"), nRegWriteCount++, (MS_S8*)("bsp obuf start address: "));
977 WriteRegMFE(0x3d, mfe_reg->reg3d, (MS_S8*)("[%d] reg3d"), nRegWriteCount++, (MS_S8*)("bsp obuf start address high"));
978 WriteRegMFE(0x3e, mfe_reg->reg3e, (MS_S8*)("[%d] reg3e"), nRegWriteCount++, (MS_S8*)("bsp obuf end address: "));
979 WriteRegMFE(0x3f, mfe_reg->reg3f, (MS_S8*)("[%d] reg3f"), nRegWriteCount++, (MS_S8*)("bsp obuf end address high"));
980 mfe_reg->reg_mfe_s_bspobuf_set_adr = 1;
981 #endif
982 //
983 mfe_reg->reg_mfe_s_bspobuf_fifo_th = 1;
984 mfe_reg->reg_mfe_s_mvobuf_set_adr = 0;
985 mfe_reg->reg_mfe_s_mvobuf_fifo_th = 0;
986
987 #if defined(_MFE_T8_)&&!defined(_MFE_AGATE_)
988 WriteRegMFE(0x3b, mfe_reg->reg3b, (MS_S8*)("[%d] reg3b"), nRegWriteCount++, (MS_S8*)("set bsp obuf"));
989 mfe_reg->reg_mfe_s_bspobuf_set_adr = 0; // HW is write-one-clear
990 #elif defined(_MFE_M1_)||defined(_MFE_AGATE_)
991 // Enable set-obuf
992 mfe_reg->reg_mfe_s_bspobuf_update_adr = 1;
993 WriteRegMFE(0x3f, mfe_reg->reg3f, (MS_S8*)("[%d] reg3f"), nRegWriteCount++, (MS_S8*)("reg_mfe_s_bspobuf_update_adr"));
994 mfe_reg->reg_mfe_s_bspobuf_update_adr = 0; // write-one-clear
995 #if defined(WIN32)
996 mfe_reg->enable_obufadr_update = 0;
997 UDMA_RIURead16(REG_BANK_MFE+0x6a, (MS_U16*)&mfe_reg->reg6a);
998 while (mfe_reg->enable_obufadr_update!=1) {
999 UDMA_RIURead16(REG_BANK_MFE+0x6a, (MS_U16*)&mfe_reg->reg6a);
1000 printf("Wait for enable_obufadr_update=1!\n"));
1001 }
1002 #endif
1003 #if defined(USE_HW_DBL_OBUF)
1004 nRegWriteCount += SetObufAddr(mfe_reg, (MS_U32)pBufInfo->m_nOutBufAddr, pBufInfo->m_OutBufferSize, 0, 0);
1005 nRegWriteCount += SetObufAddr(mfe_reg, (MS_U32)pBufInfo->m_nOutBufAddr+pBufInfo->m_OutBufferSize, pBufInfo->m_OutBufferSize, 1, 1);
1006 #else
1007 nRegWriteCount += SetObufAddr(mfe_reg, (MS_U32)pBufInfo->m_nOutBufAddr[pConfig->nOBufIndex].miuAddress, pBufInfo->m_OutBufferSize, 0, 1);
1008 #endif
1009 #endif
1010
1011 // MV-store
1012 if (mfe_reg->reg_mfe_g_enc_mode==REG_ENC_MODE_MPG4) {
1013 WriteRegMFE(0x19, mfe_reg->reg19, (MS_S8*)("[%d] reg19"), nRegWriteCount++, (MS_S8*)("enable mv-store"));
1014 if (mfe_reg->reg_mfe_g_mp4_direct_mvstore) {
1015 WriteRegMFE(0x40, mfe_reg->reg40, (MS_S8*)("[%d] reg40"), nRegWriteCount++, (MS_S8*)("reg_mfe_s_mvobuf_sadr_low"));
1016 WriteRegMFE(0x41, mfe_reg->reg41, (MS_S8*)("[%d] reg41"), nRegWriteCount++, (MS_S8*)("reg_mfe_s_mvobuf_sadr_high"));
1017 //
1018 mfe_reg->reg_mfe_s_bspobuf_set_adr = 0;
1019 mfe_reg->reg_mfe_s_bspobuf_fifo_th = 0;
1020 mfe_reg->reg_mfe_s_mvobuf_set_adr = 1;
1021 mfe_reg->reg_mfe_s_mvobuf_fifo_th = 1;
1022 WriteRegMFE(0x3b, mfe_reg->reg3b, (MS_S8*)("[%d] reg3b"), nRegWriteCount++, (MS_S8*)("set mv-sotre addr"));
1023 mfe_reg->reg_mfe_s_mvobuf_set_adr = 0; // HW is write-one-clear
1024 }
1025 // mvibuf
1026 WriteRegMFE(0x4e, mfe_reg->reg4e, (MS_S8*)("[%d] reg4e"), nRegWriteCount++, (MS_S8*)("reg_mfe_s_gn_mvibuf_sadr_low"));
1027 WriteRegMFE(0x4f, mfe_reg->reg4f, (MS_S8*)("[%d] reg4f"), nRegWriteCount++, (MS_S8*)("reg_mfe_s_gn_mvibuf_sadr_high"));
1028 }
1029
1030
1031 // GN
1032 WriteRegMFE(0x4c, mfe_reg->reg4c, (MS_S8*)("[%d] reg1c"), nRegWriteCount++, (MS_S8*)("reg_mfe_s_gn_sadr_low"));
1033 WriteRegMFE(0x4d, mfe_reg->reg4d, (MS_S8*)("[%d] reg4d"), nRegWriteCount++, (MS_S8*)("reg_mfe_s_gn_sadr_high"));
1034
1035 WriteRegMFE(0x19, mfe_reg->reg19, (MS_S8*)("[%d] reg19"), nRegWriteCount++, (MS_S8*)("value"));
1036 // MBR
1037 WriteRegMFE(0x26, mfe_reg->reg26, (MS_S8*)("[%d] reg26"), nRegWriteCount++, (MS_S8*)("MBR: mbbits"));
1038 WriteRegMFE(0x27, mfe_reg->reg27, (MS_S8*)("[%d] reg27"), nRegWriteCount++, (MS_S8*)("MBR: frame qstep"));
1039 WriteRegMFE(0x29, mfe_reg->reg29, (MS_S8*)("[%d] reg29"), nRegWriteCount++, (MS_S8*)("264 qp-offset"));
1040 WriteRegMFE(0x2a, mfe_reg->reg2a, (MS_S8*)("[%d] reg2a"), nRegWriteCount++, (MS_S8*)("QP min/max"));
1041 WriteRegMFE(0x6e, mfe_reg->reg6e, (MS_S8*)("[%d] reg6e"), nRegWriteCount++, (MS_S8*)("QStep min"));
1042 WriteRegMFE(0x6f, mfe_reg->reg6f, (MS_S8*)("[%d] reg6f"), nRegWriteCount++, (MS_S8*)("QStep max"));
1043
1044 // MDC
1045 WriteRegMFE(0x39, mfe_reg->reg39, (MS_S8*)("[%d] reg39"), nRegWriteCount++, (MS_S8*)("value"));
1046
1047 // Intra Update
1048 WriteRegMFE(0x2f, mfe_reg->reg2f, (MS_S8*)("[%d] reg2f"), nRegWriteCount++, (MS_S8*)("value"));
1049 WriteRegMFE(0x30, mfe_reg->reg30, (MS_S8*)("[%d] reg30"), nRegWriteCount++, (MS_S8*)("value"));
1050 WriteRegMFE(0x31, mfe_reg->reg31, (MS_S8*)("[%d] reg31"), nRegWriteCount++, (MS_S8*)("value"));
1051 WriteRegMFE(0x32, mfe_reg->reg32, (MS_S8*)("[%d] reg32"), nRegWriteCount++, (MS_S8*)("value"));
1052
1053 if (mfe_reg->reg_mfe_g_enc_mode==REG_ENC_MODE_MPG4) { // MPEG-4
1054 WriteRegMFE(0x37, mfe_reg->reg37, (MS_S8*)("[%d] reg37"), nRegWriteCount++, (MS_S8*)("MPEG4 MDC"));
1055 WriteRegMFE(0x38, mfe_reg->reg38, (MS_S8*)("[%d] reg38"), nRegWriteCount++, (MS_S8*)("MPEG4: vop_time_increment"));
1056 // B-direct
1057 WriteRegMFE(0x1a, mfe_reg->reg1a, (MS_S8*)("[%d] reg1a"), nRegWriteCount++, (MS_S8*)("MPEG4 BDirect"));
1058 }
1059
1060
1061 mfe_reg->reg_mfe_g_crc_mode = 0xC;
1062 mfe_reg->reg_mfe_g_debug_tcycle_chk_en = 0x1;
1063 mfe_reg->reg_mfe_g_debug_tcycle_chk_sel = 0x0;
1064 mfe_reg->reg_mfe_g_debug_en = 0; // TEST
1065 WriteRegMFE(0x73, mfe_reg->reg73, (MS_S8*)("[%d] reg73"), nRegWriteCount++, (MS_S8*)("crc mode"));
1066
1067
1068
1069 WriteRegMFE(0x2c, mfe_reg->reg2c, (MS_S8*)("[%d] reg2c"), nRegWriteCount++, (MS_S8*)("Last zigzag"));
1070
1071 // Cross-format wrong reg setting prevention
1072 WriteRegMFE(0x18, mfe_reg->reg18, (MS_S8*)("[%d] reg18"), nRegWriteCount++, (MS_S8*)("JPE encode mode"));
1073 WriteRegMFE(0x1b, mfe_reg->reg1b, (MS_S8*)("[%d] reg1b"), nRegWriteCount++, (MS_S8*)("MPEG4 FieldDCT"));
1074
1075 #ifdef _MFE_M1_
1076 // Prefetch & Low bandwidth mode
1077 WriteRegMFE(0x68,mfe_reg->reg68,"[%d] reg68"), nRegWriteCount++, (MS_S8*)("Prefetch enable/disable"));
1078 // Prefetch
1079 WriteRegMFE(0x6d,mfe_reg->reg6d,"[%d] reg6d"), nRegWriteCount++, (MS_S8*)("Prefetch MB idle count"));
1080 //Low bandwidth
1081 WriteRegMFE(0x6b, mfe_reg->reg6b, (MS_S8*)("[%d] reg6b"), nRegWriteCount++, (MS_S8*)("Low Bandwidth: IMI addr low"));
1082 WriteRegMFE(0x6c, mfe_reg->reg6c, (MS_S8*)("[%d] reg6c"), nRegWriteCount++, (MS_S8*)("Low Bandwidth: IMI addr high"));
1083
1084 // Reset any StopAndGo or StopAndDrop setting.
1085 mfe_reg->reg_mfe_s_txip_sng_mb = 0;
1086 WriteRegMFE(0x2d, mfe_reg->reg2d, (MS_S8*)("[%d] reg2d"), nRegWriteCount++, (MS_S8*)("reg_mfe_s_txip_sng_mb=0"));
1087
1088 #endif
1089
1090 //enable eco item
1091 WriteRegMFE(0x7d, mfe_reg->reg7d, (MS_S8*)("[%d] reg7d"), nRegWriteCount++, (MS_S8*)("reg_mfe_s_txip_eco0=1"));
1092
1093 ms_dprintk(DRV_L3, "In mfe_reg_m4ve.c Before En HW..\n");
1094 // DumpAllReg(mfe_reg);
1095
1096 // Enable HW
1097 mfe_reg->reg_mfe_g_frame_start_sw = 1;
1098
1099 WriteRegMFE(0x00, mfe_reg->reg00, (MS_S8*)("[%d] reg00"), nRegWriteCount++, (MS_S8*)("frame start"));
1100 mfe_reg->reg_mfe_g_frame_start_sw = 0; // HW is write-one-clear
1101
1102 ms_dprintk(DRV_L3,"After RESET\n");
1103 // FDC
1104 nRegFDCCount = PutFDC(mfe_reg, pBitsInfo, 0);
1105 nRegWriteCount += nRegFDCCount;
1106
1107 if(nRegFDCCount != nTarFDCCount) {
1108 ms_dprintk(DRV_L3, "nRegFDCCount = %d, nTarFDCCount = %d\n", (int)nRegFDCCount, (int)nTarFDCCount);
1109 }
1110 if(nRegWriteCount != nTarWriteCount) {
1111 ms_dprintk(DRV_L3, "nRegWriteCount = %d, nTarWriteCount = %d\n", (int)nRegWriteCount, (int)nTarWriteCount);
1112 }
1113 // Only for debug
1114 // MS_ASSERT(nRegFDCCount==nTarFDCCount);
1115 // MS_ASSERT(nRegWriteCount==nTarWriteCount);
1116
1117 }
1118
codeM4vConfigHeaders(MFE_CONFIG * pConfig,MS_BOOL IsSkipHeader)1119 MS_S32 codeM4vConfigHeaders(MFE_CONFIG *pConfig,MS_BOOL IsSkipHeader)
1120 {
1121 OutStream* pStream = &pConfig->m_OutStream;
1122 // BitsInfo* pBitsInfo = &pConfig->ctxBitsInfo;
1123
1124 if(IsSkipHeader) {
1125 osReset(pStream);
1126 codeNonCodedVOPShortHead(pConfig, pStream);
1127 osFlushAll(&pConfig->m_OutStream);
1128 } else {
1129 osReset(pStream);
1130 codeSequenceHead(pConfig, pStream);
1131 codeVOHead(pConfig, pStream);
1132 codeVOLHead(pConfig, pStream);
1133 // Finalize
1134 osFlushAll(&pConfig->m_OutStream);
1135 }
1136 // The generated bytes start from pStream->m_pbFrameBuffer and with pStream->m_nByteCount bytes.
1137 return pStream->m_nByteCount;
1138 }
1139
1140
1141
1142