xref: /utopia/UTPA2-700.0.x/modules/mfe/drv/mfe_ex/cModel/bufmng.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_reg.h"
84 #include "mfe_common.h"
85 #include "ms_dprintf.h"
86 #include <stdio.h>
87 #include <string.h>
88 
89 #define CEILING_ALIGN(value, align) (((MS_U32)(value)+((align)-1UL)) & ~((align)-1UL))
90 //static MS_S32 mfe_alloc_addr(MS_S32 Buf[2], MS_S32 mem_start, MS_S32 sizeY, MS_S32 sizeC)
mfe_alloc_addr(MS_PHY * ppBufStart,MS_PHY pBufEnd,MEMMAP_t Buf[2],MS_S32 sizeY,MS_S32 sizeC)91 static void mfe_alloc_addr(MS_PHY* ppBufStart, MS_PHY pBufEnd, MEMMAP_t Buf[2], MS_S32 sizeY, MS_S32 sizeC)
92 {
93 
94 	MMAPMalloc(ppBufStart, pBufEnd, sizeY, &Buf[0], 256UL, (const MS_S8*)("Y"));
95 	MMAPMalloc(ppBufStart, pBufEnd, sizeC, &Buf[1], 256UL, (const MS_S8*)("C"));
96 }
97 
98 
99 //////////////////////////////////////////////////////////////////////////
100 // JPEG
101 //////////////////////////////////////////////////////////////////////////
102 
103 
jpeAllocDRAM(MFE_CONFIG * pConfig)104 MS_U32 jpeAllocDRAM(MFE_CONFIG* pConfig)
105 {
106     BufInfo* pBufInfo = &pConfig->ctxBufInfo;
107     //JpgInfo *pInfo = &pConfig->ctxJpgInfo;
108     MS_S32  i;
109     MS_PHY pBufEnd = (MS_PHY)(pConfig->dram_base + pConfig->dram_size);
110 
111     for (i=0; i<pBufInfo->m_nOutBuffer; i++)
112     MMAPMalloc(&pConfig->dram_ptr, pBufEnd, pBufInfo->m_OutBufferSize, &pBufInfo->m_nOutBufAddr[i], 256UL, (const MS_S8*)("out buf"));
113 
114     ms_dprintk(DRV_L2, "[jpeAllocDRAM] Start = 0x%x, End = 0x%x\n", (unsigned int)pConfig->dram_base, (unsigned int)pConfig->dram_ptr);
115     return pConfig->dram_ptr;
116 
117 }
118 
119 
120 //////////////////////////////////////////////////////////////////////////
121 // MPEG-4
122 //////////////////////////////////////////////////////////////////////////
123 
124 // Total memory usage:
125 //   (Width*Height/256)*16 + (Width/16)*64 + (Width*Height*3/2)*3 + OBUF_SIZE*OBUF_NUM
m4veAllocDRAM(MFE_CONFIG * pConfig)126 MS_U32 m4veAllocDRAM(MFE_CONFIG* pConfig)
127 {
128 	BufInfo* pBufInfo = &pConfig->ctxBufInfo;
129 	M4VEINFO *pInfo = &pConfig->ctxM4veInfo;
130 	MS_S32 nMbCount;
131 	MS_S32 sizeY, sizeC, i;
132 	MS_PHY pBufEnd = (MS_PHY)(pConfig->dram_base + pConfig->dram_size);
133 
134 	nMbCount = (pConfig->nBufWidth * pConfig->nBufHeight)>>8;
135 
136 // 	pBufInfo->m_nMvStoreAddr = dram_base;
137 // 	MS_ASSERT((pBufInfo->m_nMvStoreAddr&0x7)==0);
138 // 	dram_base += nMbCount*16;
139 // 	dram_base = (dram_base+7) & ~7;
140 	MMAPMalloc(&pConfig->dram_ptr, pBufEnd, nMbCount*16, &pBufInfo->m_nMvStoreAddr, 8UL, (const MS_S8*)("nMbCount*16"));
141 	MS_ASSERT((pBufInfo->m_nMvStoreAddr.miuAddress&0x7)==0);
142 
143 	// For simplicity, fix GN address
144 // 	pBufInfo->m_nGNAddr = dram_base;
145 // 	MS_ASSERT((pBufInfo->m_nGNAddr&0x7)==0);
146 // 	dram_base += (pConfig->nBufWidth>>4)*64;
147 // 	dram_base = (dram_base+7) & ~7;
148 	MMAPMalloc(&pConfig->dram_ptr, pBufEnd, (pConfig->nBufWidth>>4)*64, &pBufInfo->m_nGNAddr, 8UL, (const MS_S8*)("(pConfig->nBufWidth>>4)*64"));
149 	MS_ASSERT((pBufInfo->m_nGNAddr.miuAddress&0x7)==0);
150 
151 	sizeY = pConfig->nBufWidth * pConfig->nBufHeight;
152 	sizeC = sizeY >> 1;
153 // 	mfe_alloc_addr(&pConfig->dram_ptr, pBufEnd, pInfo->m_FrameBuf[M4VE_FRM_CUR_ORI], sizeY, sizeC);	// m_pvopcOrig
154 // 	mfe_alloc_addr(&pConfig->dram_ptr, pBufEnd, pInfo->m_FrameBuf[M4VE_FRM_REF0_ORI], sizeY, sizeC);	// m_pvopcRefOrig0
155 // 	mfe_alloc_addr(&pConfig->dram_ptr, pBufEnd, pInfo->m_FrameBuf[M4VE_FRM_REF1_ORI], sizeY, sizeC);	// m_pvopcRefOrig1
156 	mfe_alloc_addr(&pConfig->dram_ptr, pBufEnd, pInfo->m_FrameBuf[M4VE_FRM_CUR_REC], sizeY, sizeC);	// m_pvopcCurrQ
157 	mfe_alloc_addr(&pConfig->dram_ptr, pBufEnd, pInfo->m_FrameBuf[M4VE_FRM_REF0_REC], sizeY, sizeC);	// m_pvopcRefQ0
158 #ifndef _MFE_M1_
159 	mfe_alloc_addr(&pConfig->dram_ptr, pBufEnd, pInfo->m_FrameBuf[M4VE_FRM_REF1_REC], sizeY, sizeC);	// m_pvopcRefQ1
160 #endif
161 // 	dram_base = (dram_base+255)&~255;
162 // 	pBufInfo->m_nOutBufAddr = dram_base;
163 // 	dram_base += OBUF_SIZE*OBUF_NUM;
164 // 	MS_ASSERT(dram_base<MAX_TOPSIM_ADDR);
165     if(pConfig->SecurityMode)
166         return pConfig->dram_ptr;
167 
168 	for (i=0; i<pBufInfo->m_nOutBuffer; i++)
169 		MMAPMalloc(&pConfig->dram_ptr, pBufEnd, pBufInfo->m_OutBufferSize, &pBufInfo->m_nOutBufAddr[i], 256UL, (const MS_S8*)("out buf"));
170 
171 	ms_dprintk(DRV_L2, "[m4veAllocDRAM] Start=0x%x, End=0x%x\n", (unsigned int)pConfig->dram_base, (unsigned int)pConfig->dram_ptr);
172 	return pConfig->dram_ptr;
173 }
174 
m4veUpdateAllRefVOPs(MFE_CONFIG * pConfig)175 void m4veUpdateAllRefVOPs(MFE_CONFIG* pConfig)
176 // perform this after VOP prediction type decided and before encoding
177 {
178 	M4VEINFO* pInfo = &pConfig->ctxM4veInfo;
179 	MEMMAP_t tmp;
180 	MS_S32 i;
181 
182 	if (pConfig->vopPredType != B_VOP) {
183 		//swapVOPU8Pointers (m_pvopcRefQ0, m_pvopcRefQ1);
184 #ifndef _MFE_M1_
185 		for (i=0; i<2; i++) {
186 			tmp = pInfo->m_FrameBuf[M4VE_FRM_REF0_REC][i];
187 			pInfo->m_FrameBuf[M4VE_FRM_REF0_REC][i] = pInfo->m_FrameBuf[M4VE_FRM_REF1_REC][i];
188 			pInfo->m_FrameBuf[M4VE_FRM_REF1_REC][i] = tmp;
189 		}
190 #else
191 		for (i=0; i<2; i++) {
192 			tmp = pInfo->m_FrameBuf[M4VE_FRM_CUR_REC][i];
193 			pInfo->m_FrameBuf[M4VE_FRM_CUR_REC][i] = pInfo->m_FrameBuf[M4VE_FRM_REF0_REC][i];
194 			pInfo->m_FrameBuf[M4VE_FRM_REF0_REC][i] = tmp;
195 		}
196 #endif
197 	}
198 }
199 
200 // Input: pConfig->nCodingOrder
201 // Output: pGOP->nDispOrder
202 // NOTE: Every nCodingOrder can only call this once!
203 // NOTE: nCodingOrder is determined outside this function.
204 
205 #define bIsOpenGOP 1UL
206 
mfeSetVopType(MFE_CONFIG * pConfig,GOPINFO * pGOP)207 void mfeSetVopType(MFE_CONFIG* pConfig, GOPINFO* pGOP)
208 {
209 //	M4VEINFO* pInfo = &pConfig->ctxM4veInfo;
210 
211         //remove for fix coverity deadcode.
212 //	const MS_U8 bIsOpenGOP = 1;
213 
214     if (pConfig->nCodecType==REG_ENC_MODE_H264 && (pConfig->bInterlace!=PROGRESSIVE)) {
215         // Always assume top-field first
216         if (pConfig->ctxH264Info.structure==BOTTOM_FIELD) {
217             if (pConfig->ctxH264Info.vopPredType_FirstField==I_VOP)
218                 pConfig->vopPredType = P_VOP;   // A trick here to match cModel for better compression gain.
219             pConfig->nCodingOrder = pGOP->nCodingOrder;
220             return;
221         }
222     }
223 
224 	if (pGOP->nCodingOrder==0) {
225 		// Initial
226 		pConfig->vopPredType = I_VOP;
227 		pGOP->nDispOrder = 0;
228 #if 0	// The very leading B-frames when open-GOP
229 		if (bIsOpenGOP && pConfig->nBbetweenP>0)
230 			pGOP->nDispOrder = pConfig->nBbetweenP;
231 #endif
232 		pGOP->nPCount = 0;
233 		pGOP->nBCount = 0;
234 	}
235 	else {
236 		if (pConfig->nPbetweenI==0&&pConfig->nBbetweenP==0) {
237 			// I-only
238 			pConfig->vopPredType = I_VOP;
239 			pGOP->nDispOrder++;
240 		}
241 #ifdef _GenSkipHeader_
242              else if(pConfig->VTMode && rc_CheckSkippedFrame(&pConfig->VTRateCtrl)){
243                 pConfig->vopPredType = P_VOP;
244                 pGOP->nDispOrder++;
245                 pGOP->nPCount ++;
246                 pGOP->nBCount = 0;
247              }
248 #endif
249              else if(pConfig->bForceIframe) {
250                 pConfig->vopPredType = I_VOP;
251                 pGOP->nDispOrder++;
252                 pGOP->nPCount = 0;
253                 pGOP->nBCount = 0;
254              }
255 		else {
256 			switch (pConfig->vopPredType) {
257 			case I_VOP:
258 				if (bIsOpenGOP && pConfig->nBbetweenP>0 && pGOP->nDispOrder>0) {
259 					pConfig->vopPredType = B_VOP;
260 					pGOP->nDispOrder = pGOP->nDispOrder - pConfig->nBbetweenP;
261 					pGOP->nPCount = 0;
262 					pGOP->nBCount = 1;
263 				}
264 				else {
265 					pConfig->vopPredType = P_VOP;
266 					pGOP->nDispOrder += pConfig->nBbetweenP+1;
267 					pGOP->nPCount = 1;
268 					pGOP->nBCount = 0;
269 				}
270 				break;
271 			case P_VOP:
272 				if (pGOP->nBCount<pConfig->nBbetweenP) {
273 					pConfig->vopPredType = B_VOP;
274 					pGOP->nDispOrder = pGOP->nDispOrder - pConfig->nBbetweenP;
275 					pGOP->nBCount = 1;
276 				}                                                                   //nPbetweenI<0 means infinite. Use For Skype project.
277 				else if (pGOP->nPCount<pConfig->nPbetweenI || pConfig->nP_is_infinite) {
278 					MS_ASSERT(pConfig->nBbetweenP==0);
279 					pConfig->vopPredType = P_VOP;
280 					pGOP->nDispOrder++;
281 					pGOP->nPCount++;
282 					pGOP->nBCount = 0;
283 				}
284 				else {
285 					MS_ASSERT(pConfig->nBbetweenP==0);
286 					pConfig->vopPredType = I_VOP;
287 					pGOP->nDispOrder++;
288 					pGOP->nPCount = 0;
289 					pGOP->nBCount = 0;
290 				}
291 				break;
292 			case B_VOP:
293 				if (pGOP->nBCount<pConfig->nBbetweenP) {
294 					pConfig->vopPredType = B_VOP;
295 					pGOP->nDispOrder++;
296 					pGOP->nBCount++;
297 				}
298 				else if (pGOP->nPCount<pConfig->nPbetweenI) {
299 					pConfig->vopPredType = P_VOP;
300 					pGOP->nDispOrder += 2+pConfig->nBbetweenP;
301 					pGOP->nPCount++;
302 					pGOP->nBCount = 0;
303 				}
304 				else {
305 					pConfig->vopPredType = I_VOP;
306 					if (bIsOpenGOP)
307 						pGOP->nDispOrder += 2+pConfig->nBbetweenP;
308 					else
309 						pGOP->nDispOrder += 2;
310 					pGOP->nPCount = 0;
311 					pGOP->nBCount = 0;
312 				}
313 				break;
314 			}
315 		}
316 	}
317 
318 	pConfig->nCodingOrder = pGOP->nCodingOrder;
319 
320     // If PAFF, always assume top-field first
321     if (pConfig->nCodecType==REG_ENC_MODE_H264 && (pConfig->bInterlace!=PROGRESSIVE))
322         pConfig->ctxH264Info.vopPredType_FirstField = pConfig->vopPredType;
323 
324 }
325 
m4veGetBufferAddr(MFE_CONFIG * pConfig)326 void m4veGetBufferAddr(MFE_CONFIG* pConfig)
327 {
328 	M4VEINFO* pInfo = &pConfig->ctxM4veInfo;
329 	BufInfo* pBufInfo = &pConfig->ctxBufInfo;
330 
331     if(!pConfig->nDropFlag)
332 	m4veUpdateAllRefVOPs(pConfig);
333 
334 #ifndef _MFE_M1_
335 	if (pConfig->vopPredType==B_VOP) {
336 		pBufInfo->m_nRecYAddr = pInfo->m_FrameBuf[M4VE_FRM_CUR_REC][0];
337 		pBufInfo->m_nRecCAddr = pInfo->m_FrameBuf[M4VE_FRM_CUR_REC][1];
338 	}
339 	else {
340 		pBufInfo->m_nRecYAddr = pInfo->m_FrameBuf[M4VE_FRM_REF1_REC][0];
341 		pBufInfo->m_nRecCAddr = pInfo->m_FrameBuf[M4VE_FRM_REF1_REC][1];
342 	}
343 
344     if(pConfig->m_bFrameMode) {
345         pBufInfo->m_nRefYAddr[0] = pInfo->m_FrameBuf[M4VE_FRM_REF0_REC][0];
346         pBufInfo->m_nRefCAddr[0] = pInfo->m_FrameBuf[M4VE_FRM_REF0_REC][1];
347 
348         pBufInfo->m_nRefYAddr[1] = pInfo->m_FrameBuf[M4VE_FRM_REF1_REC][0];
349         pBufInfo->m_nRefCAddr[1] = pInfo->m_FrameBuf[M4VE_FRM_REF1_REC][1];
350 
351     }
352 #else
353     pBufInfo->m_nRecYAddr = pInfo->m_FrameBuf[M4VE_FRM_CUR_REC][0];
354     pBufInfo->m_nRecCAddr = pInfo->m_FrameBuf[M4VE_FRM_CUR_REC][1];
355 
356     pBufInfo->m_nRefYAddr[0] = pInfo->m_FrameBuf[M4VE_FRM_REF0_REC][0];
357     pBufInfo->m_nRefCAddr[0] = pInfo->m_FrameBuf[M4VE_FRM_REF0_REC][1];
358 
359 #endif
360 	pBufInfo->m_bEnableMvStore = pInfo->bMvStore ? 1 : 0;
361 }
362 
363 
364 //////////////////////////////////////////////////////////////////////////
365 // H264
366 //////////////////////////////////////////////////////////////////////////
367 
368 // Total memory usage:
369 //   (Width/16)*64 + (Width*Height*3/2)*(MAX_BUFPOOL_COUNT) + OBUF_SIZE*OBUF_NUM
h264AllocDRAM(MFE_CONFIG * pConfig)370 MS_U32 h264AllocDRAM(MFE_CONFIG* pConfig)
371 {
372 	H264INFO *pInfo = &pConfig->ctxH264Info;
373 	BufInfo* pBufInfo = &pConfig->ctxBufInfo;
374 //	MS_S32 nMbCount;
375 	MS_S32 sizeY, sizeC, i, total;
376 	MS_U32 pBufEnd = (MS_U32)(pConfig->dram_base + pConfig->dram_size);
377 
378 //	nMbCount = (pConfig->nBufWidth * pConfig->nBufHeight)>>8;
379 
380 	// For simplicity, fix GN address
381 // 	g_gnstore_addr = g_dram_base;
382 // 	MS_ASSERT((g_gnstore_addr&0x7)==0);
383 // 	g_dram_base += (img->width / 16)*64;
384 // 	g_dram_base = (g_dram_base+7) & ~7;
385 #if defined(_MFE_MUJI_) || defined(_MFE_MONET_) || defined(_MFE_MESSI_) || defined(_MFE_MANHATTAN_) || defined(_MFE_MASERATI_) || defined(_MFE_MAXIM_) || defined(_MFE_KANO_) || defined(_MFE_K6_)
386 	MMAPMalloc(&pConfig->dram_ptr, pBufEnd, (pConfig->nBufWidth/16)*128, &pBufInfo->m_nGNAddr, 8UL, (const MS_S8*)("(pConfig->nBufWidth>>4)*128"));
387 #else
388     MMAPMalloc(&pConfig->dram_ptr, pBufEnd, (pConfig->nBufWidth/16)*64, &pBufInfo->m_nGNAddr, 8UL, (const MS_S8*)("(pConfig->nBufWidth>>4)*64"));
389 #endif
390 	MS_ASSERT((pBufInfo->m_nGNAddr.miuAddress&0x7)==0);
391 
392     if(pConfig->bColorFormat == YUVTILE) {
393     	sizeY = pConfig->nBufWidth * pConfig->nBufHeight;
394 	    sizeC = sizeY >> 1;
395 	    if (pConfig->bInterlace != PROGRESSIVE) {
396 		    sizeY >>= 1;
397 		    sizeC >>= 1;
398 	    }
399     } else {
400         MS_S32 interlace_h = pConfig->nBufHeight;
401         if (pConfig->bInterlace != PROGRESSIVE){
402             interlace_h = interlace_h/2;
403         }
404         sizeY = CEILING_ALIGN(interlace_h,32)*pConfig->nBufWidth;
405         sizeC = CEILING_ALIGN(interlace_h,64)*pConfig->nBufWidth/2;
406     }
407 
408 	// Frame buffer
409 	//total = pConfig->bInterlace ? MAX_BUFPOOL_COUNT : (MAX_BUFPOOL_COUNT>>1);
410     total = pInfo->BufPool.FrameBufPoolSize;
411 
412 
413 	for (i=0; i<total; i++) {
414 		mfe_alloc_addr(&pConfig->dram_ptr, pBufEnd, pInfo->BufPool.addr[i], sizeY, sizeC);
415 		pInfo->BufPool.available[i] = 1;
416 	}
417 
418 	for (; i<pInfo->BufPool.FrameBufPoolSize; i++)
419 		pInfo->BufPool.available[i] = 0;
420 
421 	// Out buffer
422 // 	g_dram_base = (g_dram_base+255)&~255;
423 // 	g_outbuf_addr = g_dram_base;
424 // 	g_dram_base += OBUF_SIZE*OBUF_NUM;
425 // 	MS_ASSERT(g_dram_base<MAX_TOPSIM_ADDR);
426 // 	g_dram_base = (g_dram_base+255)&~255;
427     if(pConfig->SecurityMode)
428         return pConfig->dram_ptr;
429 
430     for (i=0; i<pBufInfo->m_nOutBuffer; i++)
431     	MMAPMalloc(&pConfig->dram_ptr, pBufEnd, pBufInfo->m_OutBufferSize, &pBufInfo->m_nOutBufAddr[i], 256UL, (const MS_S8*)("OUT BUF"));
432     ms_dprintk(DRV_L2, "[h264AllocDRAM] Start = 0x%x, End = 0x%x\n", (unsigned int)pConfig->dram_base, (unsigned int)pConfig->dram_ptr);
433 
434     return pConfig->dram_ptr;
435 }
436 
bufpool_get(FrameBufPool * pPool,MEMMAP_t Buf[2])437 static void bufpool_get(FrameBufPool* pPool, MEMMAP_t Buf[2])
438 {
439 	MS_S32 i;
440 
441     for (i=0; i<pPool->FrameBufPoolSize; i++) {
442     	if (pPool->available[i]) {
443     		Buf[0] = pPool->addr[i][0];
444     		Buf[1] = pPool->addr[i][1];
445     		pPool->available[i] = 0;
446             ms_dprintk(DRV_L3, "[bufpool_get] %d\n", (int)i);
447     		break;
448     	}
449     }
450     if (i==pPool->FrameBufPoolSize)
451     {
452         ms_dprintk(DRV_L3, "[bufpool_get] Buffer pool empty!!\n");
453         MS_ASSERT(0);
454     }
455 }
456 
bufpool_return(FrameBufPool * pPool,MEMMAP_t Buf[2])457 static void bufpool_return(FrameBufPool* pPool, MEMMAP_t Buf[2])
458 {
459 	MS_S32 i;
460 	for (i=0; i<pPool->FrameBufPoolSize; i++) {
461 		if (pPool->addr[i][0].miuAddress==Buf[0].miuAddress &&
462                    pPool->addr[i][1].miuAddress==Buf[1].miuAddress) {
463 			pPool->available[i] = 1;
464 			break;
465 		}
466 	}
467     if (i==pPool->FrameBufPoolSize) {
468         ms_dprintk(DRV_L2, "[bufpool_return] Specific buffer not found!!\n");
469         MS_ASSERT(0);
470     }
471 }
472 
h264DpbHandling(MFE_CONFIG * pConfig)473 void h264DpbHandling(MFE_CONFIG* pConfig)
474 {
475     MS_S32 i, empty_idx;
476     H264INFO *pInfo = &pConfig->ctxH264Info;
477     BufInfo *pBufInfo = &pConfig->ctxBufInfo;
478 
479     // When IDR, clear all ref-frames in dpb
480     if (pInfo->idr_flag) {
481         // DPB initialization
482         for (i=0; i<pInfo->dpb_size; i++) {
483             pInfo->dpb[i].is_used = 0;
484         }
485     }
486 
487     // Leave dpb[0] for current rec frame
488     empty_idx = -1;
489     for (i=pInfo->dpb_size-1; i>=0; i--) {
490         if (pInfo->dpb[i].is_used==0)
491             empty_idx = i;
492     }
493 
494     if (empty_idx==-1) {
495         bufpool_return(&pInfo->BufPool, pInfo->dpb[pInfo->dpb_size-1].addr);
496         pInfo->dpb[pInfo->dpb_size-1].is_used = 0;
497         empty_idx = pInfo->dpb_size-1;	// Kick-off the least recent frame
498     }
499 
500     ms_dprintk(DRV_L3, "empty_idx = %d\n", (int)empty_idx);
501 
502     if(pInfo->PicInterlace!=FIELD_CODING) {
503 
504         if(empty_idx != 0) {
505             for (i=empty_idx; i>=1; i--) {
506                 pInfo->dpb[i].addr[0] = pInfo->dpb[i-1].addr[0];
507                 pInfo->dpb[i].addr[1] = pInfo->dpb[i-1].addr[1];
508                 pInfo->dpb[i].structure = pInfo->dpb[i-1].structure;    // For H264 PAFF
509                 pInfo->dpb[i].is_used = 1;
510             }
511         }
512         // Insert rec frame to dpb[0]
513         pInfo->dpb[0].is_used = 1;
514         pInfo->dpb[0].addr[0] = pBufInfo->m_nRecYAddr;
515         pInfo->dpb[0].addr[1] = pBufInfo->m_nRecCAddr;
516         pInfo->dpb[0].structure = pInfo->structure;
517     }
518     else if(pInfo->PicInterlace==FIELD_CODING && pInfo->structure==TOP_FIELD){
519         // Insert rec frame to dpb[0]
520         if(pInfo->dpb[0].is_used == 1)
521             bufpool_return(&pInfo->BufPool, pInfo->dpb[0].addr);
522         pInfo->dpb[0].addr[0] = pBufInfo->m_nRecYAddr;
523         pInfo->dpb[0].addr[1] = pBufInfo->m_nRecCAddr;
524         pInfo->dpb[0].structure = pInfo->structure;
525         pInfo->dpb[0].is_used = 1;
526         if(pInfo->dpb[1].is_used == 1) {
527             pInfo->dpb[1].is_used = 0;
528             bufpool_return(&pInfo->BufPool, pInfo->dpb[1].addr);
529         }
530 
531     }
532     else { //bottom field
533         // Insert rec frame to dpb[1]
534         pInfo->dpb[empty_idx].addr[0] = pBufInfo->m_nRecYAddr;
535         pInfo->dpb[empty_idx].addr[1] = pBufInfo->m_nRecCAddr;
536         pInfo->dpb[empty_idx].structure = pInfo->structure;
537         pInfo->dpb[empty_idx].is_used = 1;
538     }
539 
540     {
541         MS_S32 i;
542         for(i=0;i<pInfo->dpb_size;i++)
543             ms_dprintk(DRV_L3, "pInfo->dpb[%d].is_used = %d, structure = %d, addr = 0x%x\n",
544                 (int)i, (int)pInfo->dpb[i].is_used,
545                 pInfo->dpb[i].structure, (unsigned int)pInfo->dpb[i].addr[0].miuAddress);
546     }
547 
548 }
549 
h264GetBufferAddr(MFE_CONFIG * pConfig)550 void h264GetBufferAddr(MFE_CONFIG* pConfig)
551 {
552 	H264INFO* pInfo = &pConfig->ctxH264Info;
553 	BufInfo* pBufInfo = &pConfig->ctxBufInfo;
554     MS_S32 i;
555 	// When IDR, clean all buffer status
556 	if (pInfo->idr_flag) {
557 		MS_S32 total;
558 
559         total = pInfo->BufPool.FrameBufPoolSize;
560 
561 		for (i=0; i<total; i++)
562 			pInfo->BufPool.available[i] = 1;
563 
564         for(i=0;i<pInfo->dpb_size;i++) {
565             pBufInfo->m_nRefYAddr[i].miuAddress = 0;
566             pBufInfo->m_nRefYAddr[i].miuPointer = 0;
567             pBufInfo->m_nRefYAddr[i].size = 0;
568         }
569 	}
570 
571 	{
572 		MEMMAP_t MemTemp[2];
573              memset(MemTemp,0,2*sizeof(MEMMAP_t));
574 		bufpool_get(&pInfo->BufPool, MemTemp);
575 		pBufInfo->m_nRecYAddr = MemTemp[0];
576 		pBufInfo->m_nRecCAddr = MemTemp[1];
577 	}
578 
579     for(i=0;i<pInfo->dpb_size;i++) {
580         if (pInfo->dpb[i].is_used) {
581             pBufInfo->m_nRefYAddr[i] = pInfo->dpb[i].addr[0];
582             pBufInfo->m_nRefCAddr[i] = pInfo->dpb[i].addr[1];
583         }
584     }
585 
586     if (pInfo->PicInterlace==FIELD_CODING) {
587         MS_S32 i;
588         for (i=0; i<2; i++) {
589             if (pInfo->dpb[i].is_used) {
590                 if (pInfo->structure==TOP_FIELD && pInfo->structure != pInfo->dpb[i].structure)
591                     pInfo->h264_mcc_offset[i] = -2;
592                 if (pInfo->structure==BOTTOM_FIELD && pInfo->structure != pInfo->dpb[i].structure)
593                     pInfo->h264_mcc_offset[i] = 2;
594             }
595         }
596 
597     }
598 
599     pBufInfo->m_bEnableMvStore = 0;
600 }
601 
602