xref: /utopia/UTPA2-700.0.x/modules/mfe/api/mfe/FramerMp4V.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 // Copyright (c) 2006-2009 MStar Semiconductor, Inc.
81 // All rights reserved.
82 //
83 // Unless otherwise stipulated in writing, any and all information contained
84 // herein regardless in any format shall remain the sole proprietary of
85 // MStar Semiconductor Inc. and be kept in strict confidence
86 // (�uMStar Confidential Information�v) by the recipient.
87 // Any unauthorized act including without limitation unauthorized disclosure,
88 // copying, use, reproduction, sale, distribution, modification, disassembling,
89 // reverse engineering and compiling of the contents of MStar Confidential
90 // Information is unlawful and strictly prohibited. MStar hereby reserves the
91 // rights to any and all damages, losses, costs and expenses resulting therefrom.
92 //
93 ////////////////////////////////////////////////////////////////////////////////
94 
95 
96 #ifdef _WIN32
97 #include <windows.h>
98 #endif
99 #include <stdio.h>
100 
101 #include "MFE_chip.h"
102 #include "mfe_common.h"
103 #include "mfe_type.h"
104 #include "madp_ms_dprintf.h"
105 
106 #include "Framer.h"
107 
108 #define DBG_FRAMER_MSG(format, ...)
109 //#define DBG_FRAMER_MSG printf//(x)
110 
111 #define VIDEO_STARTCODE(x) ((x)==0x1000000)
112 #define MP2_SYNCWORD(x) (((x)&0xFCFF)==0xFCFF)
113 #define SAMPLES_IN_AUDIO_FRAME 1152
114 
115 #ifdef _WIN32
116 typedef struct Mp2aFrameHeader {
117 	unsigned int layer;
118 	unsigned int bitrate_index;
119 	unsigned int sampling_frequency;
120 } Mp2aFrameHeader;
121 
122 //////////////////////////////////////////////////////////////////////////
123 // Internal functions
124 //////////////////////////////////////////////////////////////////////////
125 
DoFileMapping(LPCTSTR lpFileName,BitstreamInfo * pBsInfo)126 static void DoFileMapping(LPCTSTR lpFileName, BitstreamInfo* pBsInfo)
127 {
128   HANDLE hMapFile, hFile;
129 
130   pBsInfo->nFileSize = 0;
131   pBsInfo->pBits = NULL;
132   hFile = CreateFile(lpFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
133 
134   if(hFile && hFile != INVALID_HANDLE_VALUE)
135   {
136     pBsInfo->nFileSize = GetFileSize(hFile, NULL);
137     hMapFile = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
138 
139     if(hMapFile && hMapFile != INVALID_HANDLE_VALUE)
140     {
141       pBsInfo->pBits =  (U8*)MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0);
142 
143       CloseHandle(hMapFile);
144     }
145 
146     CloseHandle(hFile);
147   }
148 }
149 
UndoFileMapping(MFE_U8 * pVideoMemory)150 static MFE_BOOL UndoFileMapping(MFE_U8* pVideoMemory)
151 {
152 	MFE_BOOL bRtn = 0;
153 	if (UnmapViewOfFile(pVideoMemory))
154 		bRtn = 1;
155 	return bRtn;
156 }
157 
158 //////////////////////////////////////////////////////////////////////////
159 //   APIs
160 //////////////////////////////////////////////////////////////////////////
161 
OpenMappedFile(const char * strFileName,BitstreamInfo * pBsInfo)162 MFE_BOOL OpenMappedFile(const char* strFileName, BitstreamInfo* pBsInfo)
163 {
164 	// For audio
165 	Mp2aFrameHeader mp2aHeader;
166 	unsigned int nAudBitrate, nSampleFreq;
167 
168 	pBsInfo->pBits = NULL;
169 	DoFileMapping(/*LPCTSTR*/(strFileName), pBsInfo);
170 	if (pBsInfo->pBits == NULL)
171 		return 0;
172 
173 	pBsInfo->pCur = pBsInfo->pLast = pBsInfo->pBits;
174 	pBsInfo->pEnd = pBsInfo->pBits + pBsInfo->nFileSize;
175 	pBsInfo->nFrameIndex = 0;
176 	pBsInfo->bPrevVOP = 0;
177 	if (pBsInfo->bIsAudio) {
178 		mp2aHeader.layer = (pBsInfo->pBits[1] & 0x6) >> 1;
179 		mp2aHeader.bitrate_index = (pBsInfo->pBits[2] & 0xF0) >> 4;
180 		mp2aHeader.sampling_frequency = (pBsInfo->pBits[2] & 0xC) >> 2;
181 		switch (mp2aHeader.bitrate_index)
182 		{
183 		case 1:
184 			nAudBitrate = 32000;
185 			break;
186 		case 2:
187 			nAudBitrate = (mp2aHeader.layer==2 ? 48000 : 40000);
188 			break;
189 		case 3:
190 			nAudBitrate = (mp2aHeader.layer==2 ? 56000 : 48000);
191 			break;
192 		case 4:
193 			nAudBitrate = (mp2aHeader.layer==2 ? 64000 : 56000);
194 			break;
195 		case 5:
196 			nAudBitrate = (mp2aHeader.layer==2 ? 80000 : 64000);
197 			break;
198 		case 6:
199 			nAudBitrate = (mp2aHeader.layer==2 ? 96000 : 80000);
200 			break;
201 		case 7:
202 			nAudBitrate = (mp2aHeader.layer==2 ? 112000 : 96000);
203 			break;
204 		case 8:
205 			nAudBitrate = (mp2aHeader.layer==2 ? 128000 : 112000);
206 			break;
207 		case 9:
208 			nAudBitrate = (mp2aHeader.layer==2 ? 160000 : 128000);
209 			break;
210 		case 10:
211 			nAudBitrate = (mp2aHeader.layer==2 ? 192000 : 160000);
212 			break;
213 		case 11:
214 			nAudBitrate = (mp2aHeader.layer==2 ? 224000 : 192000);
215 			break;
216 		case 12:
217 			nAudBitrate = (mp2aHeader.layer==2 ? 256000 : 224000);
218 			break;
219 		case 13:
220 			nAudBitrate = (mp2aHeader.layer==2 ? 320000 : 256000);
221 			break;
222 		case 14:
223 			nAudBitrate = (mp2aHeader.layer==2 ? 384000 : 320000);
224 			break;
225 		default:
226 			nAudBitrate = 0;	// free format
227 			break;
228 		}
229 		switch (mp2aHeader.sampling_frequency) {
230 		case 0:
231 			nSampleFreq = 44100; break;
232 		case 1:
233 			nSampleFreq = 48000; break;
234 		case 2:
235 			nSampleFreq = 32000; break;
236 		}
237 		pBsInfo->nAudFrameSize = (nAudBitrate>>3) * SAMPLES_IN_AUDIO_FRAME / nSampleFreq;
238 	}
239 
240 	return 1;
241 }
242 
CloseMappedFile(BitstreamInfo * pBsInfo)243 MFE_BOOL CloseMappedFile(BitstreamInfo* pBsInfo)
244 {
245 	MFE_BOOL rtn;
246 	if (pBsInfo->pBits==NULL)
247 		return 1;
248 	rtn = UndoFileMapping(pBsInfo->pBits);
249 	return rtn;
250 }
251 
252 enum {
253 	MPEG2_SC_SEQSTART,
254 	MPEG2_SC_SEQEND,
255 	MPEG2_SC_EXT,
256 	MPEG2_SC_GOP,
257 	MPEG2_SC_PIC,
258 	MPEG2_SC_SLICE,
259 	MPEG4_SC_VO_OR_VOL,
260 	MPEG4_SC_VOS_START,
261 	MPEG4_SC_VOS_END,
262 	MPEG4_SC_GOVOP,
263 	MPEG4_SC_VOP,
264 	SC_UNKNOWN,
265 } SC_TYPE;
266 
267 // MPEG4 video
GetOneFrameBitsMP4V(BitstreamInfo * pBsInfo,unsigned int nFrameCount)268 MFE_BOOL GetOneFrameBitsMP4V(BitstreamInfo* pBsInfo, unsigned int nFrameCount/*DontCare*/)
269 {
270 	unsigned int n3Byte;
271 	MFE_BOOL bFound = 0;
272 	MFE_U8 StartCode, SCType;
273 
274 	//assert(nFrameCount==1);
275 	pBsInfo->nFrameCount = 1;
276 	while (pBsInfo->pCur<pBsInfo->pEnd) {
277 		n3Byte = (*(unsigned int*)pBsInfo->pCur)<<8;
278 		if (VIDEO_STARTCODE(n3Byte)) {
279 			StartCode = *(pBsInfo->pCur+3);
280 			if (StartCode>=0x0 && StartCode<=0x2F)
281 				SCType = MPEG4_SC_VO_OR_VOL;	// Video Object start code, or VOL start code
282 			else if (StartCode==0xB0)
283 				SCType = MPEG4_SC_VOS_START;	// Visual Object Sequence
284 			else if (StartCode==0xB1)
285 				SCType = MPEG4_SC_VOS_END;		// Visual Object Sequence End
286 			else if (StartCode==0xB3)
287 				SCType = MPEG4_SC_GOVOP;		// Group Of Video Object Plane
288 			else if (StartCode==0xB6)
289 				SCType = MPEG4_SC_VOP;			// Video Object Plane
290 			else
291 				SCType = SC_UNKNOWN;
292 
293 			if (pBsInfo->bPrevVOP==0) {
294 				if (SCType==MPEG4_SC_VOP)
295 					pBsInfo->bPrevVOP = 1;
296 				pBsInfo->pCur+=4;
297 			}
298 			else {
299 				if (SCType==MPEG4_SC_VOP||SCType==MPEG4_SC_GOVOP||SCType==MPEG4_SC_VOS_END) {
300 					bFound = 1;
301 					pBsInfo->pFrameBits = pBsInfo->pLast;
302 					if (SCType==MPEG4_SC_VOS_END)
303 						pBsInfo->nFrameSize = (int)(pBsInfo->pCur+4-pBsInfo->pLast);
304 					else
305 						pBsInfo->nFrameSize = (int)(pBsInfo->pCur-pBsInfo->pLast);
306 					DBG_FRAMER_MSG("Found frame #%d, offset %d, size %d\n",
307 						pBsInfo->nFrameIndex, pBsInfo->pFrameBits-pBsInfo->pBits, pBsInfo->nFrameSize);
308 					// Prepare for next round
309 					pBsInfo->pLast = pBsInfo->pCur;
310 					pBsInfo->pCur+=4;
311 					pBsInfo->nFrameIndex++;
312 					if (SCType==MPEG4_SC_GOVOP||SCType==MPEG4_SC_VOS_END)
313 						pBsInfo->bPrevVOP = 0;
314 				}
315 				else
316 					pBsInfo->pCur+=4;
317 				if (bFound)
318 					break;
319 			}
320 		}
321 		else
322 			pBsInfo->pCur++;
323 	}
324 
325 	if (!bFound && pBsInfo->pCur>=pBsInfo->pEnd) {
326 		pBsInfo->nFrameCount = 0;
327 		return 0;
328 	}
329 	return 1;
330 }
331 
332 // MPEG-2 video
GetOneFrameBitsMP2V(BitstreamInfo * pBsInfo,unsigned int nFrameCount)333 MFE_BOOL GetOneFrameBitsMP2V(BitstreamInfo* pBsInfo, unsigned int nFrameCount/*DontCare*/)
334 {
335 	unsigned int n3Byte;
336 	MFE_BOOL bFound = 0;
337 	MFE_U8 StartCode, SCType;
338 
339 	//assert(nFrameCount==1);
340 	pBsInfo->nFrameCount = 1;
341 	while (pBsInfo->pCur<pBsInfo->pEnd) {
342 		n3Byte = (*(unsigned int*)pBsInfo->pCur)<<8;
343 		if (VIDEO_STARTCODE(n3Byte)) {
344 			StartCode = *(pBsInfo->pCur+3);
345 			if (StartCode==0x0)
346 				SCType = MPEG2_SC_PIC;
347 			else if (StartCode>=0x1 && StartCode<=0xAF)
348 				SCType = MPEG2_SC_SLICE;
349 			else if (StartCode==0xB3)
350 				SCType = MPEG2_SC_SEQSTART;
351 			else if (StartCode==0xB5)
352 				SCType = MPEG2_SC_EXT;
353 			else if (StartCode==0xB7)
354 				SCType = MPEG2_SC_SEQEND;
355 			else if (StartCode==0xB8)
356 				SCType = MPEG2_SC_GOP;
357 			else
358 				SCType = SC_UNKNOWN;
359 
360 			if (pBsInfo->bPrevVOP==0) {
361 				if (SCType==MPEG2_SC_PIC)
362 					pBsInfo->bPrevVOP = 1;
363 				pBsInfo->pCur+=4;
364 			}
365 			else {
366 				if (SCType==MPEG2_SC_SEQSTART||SCType==MPEG2_SC_PIC||SCType==MPEG2_SC_GOP||SCType==MPEG2_SC_SEQEND) {
367 					bFound = 1;
368 					pBsInfo->pFrameBits = pBsInfo->pLast;
369 					if (SCType==MPEG2_SC_SEQEND)
370 						pBsInfo->nFrameSize = (int)(pBsInfo->pCur+4-pBsInfo->pLast);
371 					else
372 						pBsInfo->nFrameSize = (int)(pBsInfo->pCur-pBsInfo->pLast);
373 					DBG_FRAMER_MSG("Found frame #%d, offset %d, size %d\n",
374 						pBsInfo->nFrameIndex, pBsInfo->pFrameBits-pBsInfo->pBits, pBsInfo->nFrameSize);
375 					// Prepare for next round
376 					pBsInfo->pLast = pBsInfo->pCur;
377 					pBsInfo->pCur+=4;
378 					pBsInfo->nFrameIndex++;
379 					if (SCType==MPEG2_SC_SEQSTART||SCType==MPEG2_SC_GOP||SCType==MPEG2_SC_SEQEND)
380 						pBsInfo->bPrevVOP = 0;
381 				}
382 				else
383 					pBsInfo->pCur+=4;
384 				if (bFound)
385 					break;
386 			}
387 		}
388 		else
389 			pBsInfo->pCur++;
390 	}
391 
392 	if (pBsInfo->pCur==pBsInfo->pEnd) {
393 		pBsInfo->nFrameCount = 0;
394 		return 0;
395 	}
396 	return 1;
397 }
398 #endif //_WIN32
399 // MPEG-1 audio
GetOneFrameBitsMP1A(BitstreamInfo_ptr pBsInfo,unsigned int nFrameCount)400 MFE_BOOL GetOneFrameBitsMP1A(BitstreamInfo_ptr pBsInfo, unsigned int nFrameCount)
401 {
402 	unsigned short n2Byte;
403 	MFE_BOOL bSync = 0;
404 //	MFE_BOOL bFound = 0;
405 //    DBG_FRAMER_MSG("in GetOneFrameBitsMP1A 0x%x 0x%x 0x%x 0x%x\n", (U32)pBsInfo, nFrameCount, (U32)pBsInfo->pCur, (U32)pBsInfo->pEnd);
406 	pBsInfo->nFrameCount = 1;
407 	while (pBsInfo->pCur<pBsInfo->pEnd) {
408 		n2Byte = (*(unsigned short*)pBsInfo->pCur);//(((U16)pBsInfo->pCur[1])<<8)|(pBsInfo->pCur[0]);
409 		bSync = MP2_SYNCWORD(n2Byte);
410 //        DBG_FRAMER_MSG("nFrameIndex: %d %d 0x%x %d %d\n", pBsInfo->nFrameIndex
411 //            , bSync, n2Byte, pBsInfo->pCur[0], pBsInfo->pCur[1]);
412 		if (bSync) {
413 			if (pBsInfo->pEnd - pBsInfo->pCur >= pBsInfo->nAudFrameSize) {
414 				// NOTE: This mechanism does not handle un-fixed frame size! say, 44.1Khz.
415                           pBsInfo->pFrameBits = pBsInfo->pLast = pBsInfo->pCur;
416                           pBsInfo->nFrameSize = pBsInfo->nAudFrameSize;
417                           pBsInfo->pCur += pBsInfo->nAudFrameSize;
418 				pBsInfo->nFrameIndex++;
419 				break;
420 			}
421 /*
422 			if (pBsInfo->bPrevVOP==0) {
423 				pBsInfo->bPrevVOP = 1;
424 				//pBsInfo->pCur+=2;
425                 pBsInfo->pFrameBits = pBsInfo->pLast = pBsInfo->pCur;
426                 pBsInfo->pCur += pBsInfo->nAudFrameSize;    //consider this input only contain one audio frame
427                 pBsInfo->nFrameSize = pBsInfo->nAudFrameSize; //consider this input only contain one audio frame
428 		     } else {
429 				pBsInfo->pFrameBits = pBsInfo->pLast;
430 				pBsInfo->nFrameSize = (int)(pBsInfo->pCur-pBsInfo->pLast);
431 				if (pBsInfo->nFrameSize==pBsInfo->nAudFrameSize || pBsInfo->nFrameSize==pBsInfo->nAudFrameSize+1) {
432 					bFound = 1;
433 //			     DBG_FRAMER_MSG("Found frame #%d, offset %d, size %d\n",
434 //    				 pBsInfo->nFrameIndex, pBsInfo->pFrameBits-pBsInfo->pBits, pBsInfo->nFrameSize);
435 					// Prepare for next round
436 					pBsInfo->pLast = pBsInfo->pCur;
437 					pBsInfo->pCur+=pBsInfo->nAudFrameSize;
438 					pBsInfo->nFrameIndex++;
439 					if (bFound)
440 						break;
441 				}
442 				else
443 					pBsInfo->pCur+=2;
444 			}
445 */
446 		}
447 		else
448 			pBsInfo->pCur++;
449 	}
450 //    DBG_FRAMER_MSG("leave GetOneFrameBitsMP1A pCur 0x%x 0x%x\n"
451 //        , (U32)pBsInfo->pCur, (U32)pBsInfo->pEnd);
452     if (pBsInfo->pCur > pBsInfo->pEnd) { //consider this input only contain one audio frame
453         DBG_FRAMER_MSG("!!!Audio read the end of buffer!!!\n");
454 		pBsInfo->nFrameCount = 0;
455 		return 0;
456     }
457     else if (bSync==0) {
458 	    DBG_FRAMER_MSG("Audio data not correct!!!\n");
459     }
460 	return 1;
461 }
462