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