xref: /utopia/UTPA2-700.0.x/modules/mfe/drv/mfe_ex/cModel/mfe_reg_m4ve.c (revision 53ee8cc121a030b8d368113ac3e966b4705770ef)
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