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