4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Haejeong Kim <backto.kim@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
22 #include <string.h> /*memcmp*/
23 #include <stdlib.h> /*malloc*/
25 #include "mm_file_debug.h"
27 #include "mm_file_utils.h"
28 #include "mm_file_format_mmf.h"
29 #include "mm_file_format_private.h"
35 #define AV_MMF_CONTENTS_CLASS_0 0x00
36 #define AV_MMF_CONTENTS_CLASS_1 0x20
37 #define AV_MMF_CONTENTS_CLASS_2 0x10
39 #define AV_MMF_CONTENTS_TYPE_0 0x00
40 #define AV_MMF_CONTENTS_TYPE_1 0x10
41 #define AV_MMF_CONTENTS_TYPE_2 0x20
42 #define AV_MMF_CONTENTS_TYPE_3 0x30
43 #define AV_MMF_CONTENTS_TYPE_4 0x40
44 #define AV_MMF_CONTENTS_TYPE_5 0x50
46 #define AVMALIB_MAKEDWORD(a, b, c, d) (unsigned int)(((unsigned int)(a) << 24) | \
47 ((unsigned int)(b) << 16) | ((unsigned int)(c) << 8) | (unsigned int)(d))
49 /****************************************************************************
51 ****************************************************************************/
52 #define AVMALIB_SIZE_OF_CHUNKHEADER (8)
55 #define AVMALIB_CHUNKID_MMMD 0x4D4D4D44
56 #define AVMALIB_CHUNKID_CNTI 0x434E5449
57 #define AVMALIB_CHUNKID_OPDA 0x4F504441
58 #define AVMALIB_CHUNKID_DCH 0x44636800
59 #define AVMALIB_CHUNKID_M5P 0x50726F00
60 #define AVMALIB_CHUNKID_MTR 0x4D545200
61 #define AVMALIB_CHUNKID_MSPI 0x4D737049
62 #define AVMALIB_CHUNKID_MTSU 0x4D747375
63 #define AVMALIB_CHUNKID_MTSQ 0x4D747371
64 #define AVMALIB_CHUNKID_MTSP 0x4D747370
65 #define AVMALIB_CHUNKID_MWA 0x4D776100
66 #define AVMALIB_CHUNKID_ATR 0x41545200
67 #define AVMALIB_CHUNKID_ASPI 0x41737049
68 #define AVMALIB_CHUNKID_ATSU 0x41747375
69 #define AVMALIB_CHUNKID_ATSQ 0x41747371
70 #define AVMALIB_CHUNKID_AWA 0x41776100
71 #define AVMALIB_CHUNKID_MTHV 0x4D746876
72 #define AVMALIB_CHUNKID_MHVS 0x4D687673
73 #define AVMALIB_CHUNKID_HVP 0x48565000
74 #define AVMALIB_CHUNKID_MHSC 0x4D687363
76 /****************************************************************************
78 ****************************************************************************/
79 static const unsigned short g_crc_tbl[256] = {
80 0x0000U, 0x1021U, 0x2042U, 0x3063U, 0x4084U, 0x50A5U, 0x60C6U, 0x70E7U,
81 0x8108U, 0x9129U, 0xA14AU, 0xB16BU, 0xC18CU, 0xD1ADU, 0xE1CEU, 0xF1EFU,
82 0x1231U, 0x0210U, 0x3273U, 0x2252U, 0x52B5U, 0x4294U, 0x72F7U, 0x62D6U,
83 0x9339U, 0x8318U, 0xB37BU, 0xA35AU, 0xD3BDU, 0xC39CU, 0xF3FFU, 0xE3DEU,
84 0x2462U, 0x3443U, 0x0420U, 0x1401U, 0x64E6U, 0x74C7U, 0x44A4U, 0x5485U,
85 0xA56AU, 0xB54BU, 0x8528U, 0x9509U, 0xE5EEU, 0xF5CFU, 0xC5ACU, 0xD58DU,
86 0x3653U, 0x2672U, 0x1611U, 0x0630U, 0x76D7U, 0x66F6U, 0x5695U, 0x46B4U,
87 0xB75BU, 0xA77AU, 0x9719U, 0x8738U, 0xF7DFU, 0xE7FEU, 0xD79DU, 0xC7BCU,
88 0x48C4U, 0x58E5U, 0x6886U, 0x78A7U, 0x0840U, 0x1861U, 0x2802U, 0x3823U,
89 0xC9CCU, 0xD9EDU, 0xE98EU, 0xF9AFU, 0x8948U, 0x9969U, 0xA90AU, 0xB92BU,
90 0x5AF5U, 0x4AD4U, 0x7AB7U, 0x6A96U, 0x1A71U, 0x0A50U, 0x3A33U, 0x2A12U,
91 0xDBFDU, 0xCBDCU, 0xFBBFU, 0xEB9EU, 0x9B79U, 0x8B58U, 0xBB3BU, 0xAB1AU,
92 0x6CA6U, 0x7C87U, 0x4CE4U, 0x5CC5U, 0x2C22U, 0x3C03U, 0x0C60U, 0x1C41U,
93 0xEDAEU, 0xFD8FU, 0xCDECU, 0xDDCDU, 0xAD2AU, 0xBD0BU, 0x8D68U, 0x9D49U,
94 0x7E97U, 0x6EB6U, 0x5ED5U, 0x4EF4U, 0x3E13U, 0x2E32U, 0x1E51U, 0x0E70U,
95 0xFF9FU, 0xEFBEU, 0xDFDDU, 0xCFFCU, 0xBF1BU, 0xAF3AU, 0x9F59U, 0x8F78U,
96 0x9188U, 0x81A9U, 0xB1CAU, 0xA1EBU, 0xD10CU, 0xC12DU, 0xF14EU, 0xE16FU,
97 0x1080U, 0x00A1U, 0x30C2U, 0x20E3U, 0x5004U, 0x4025U, 0x7046U, 0x6067U,
98 0x83B9U, 0x9398U, 0xA3FBU, 0xB3DAU, 0xC33DU, 0xD31CU, 0xE37FU, 0xF35EU,
99 0x02B1U, 0x1290U, 0x22F3U, 0x32D2U, 0x4235U, 0x5214U, 0x6277U, 0x7256U,
100 0xB5EAU, 0xA5CBU, 0x95A8U, 0x8589U, 0xF56EU, 0xE54FU, 0xD52CU, 0xC50DU,
101 0x34E2U, 0x24C3U, 0x14A0U, 0x0481U, 0x7466U, 0x6447U, 0x5424U, 0x4405U,
102 0xA7DBU, 0xB7FAU, 0x8799U, 0x97B8U, 0xE75FU, 0xF77EU, 0xC71DU, 0xD73CU,
103 0x26D3U, 0x36F2U, 0x0691U, 0x16B0U, 0x6657U, 0x7676U, 0x4615U, 0x5634U,
104 0xD94CU, 0xC96DU, 0xF90EU, 0xE92FU, 0x99C8U, 0x89E9U, 0xB98AU, 0xA9ABU,
105 0x5844U, 0x4865U, 0x7806U, 0x6827U, 0x18C0U, 0x08E1U, 0x3882U, 0x28A3U,
106 0xCB7DU, 0xDB5CU, 0xEB3FU, 0xFB1EU, 0x8BF9U, 0x9BD8U, 0xABBBU, 0xBB9AU,
107 0x4A75U, 0x5A54U, 0x6A37U, 0x7A16U, 0x0AF1U, 0x1AD0U, 0x2AB3U, 0x3A92U,
108 0xFD2EU, 0xED0FU, 0xDD6CU, 0xCD4DU, 0xBDAAU, 0xAD8BU, 0x9DE8U, 0x8DC9U,
109 0x7C26U, 0x6C07U, 0x5C64U, 0x4C45U, 0x3CA2U, 0x2C83U, 0x1CE0U, 0x0CC1U,
110 0xEF1FU, 0xFF3EU, 0xCF5DU, 0xDF7CU, 0xAF9BU, 0xBFBAU, 0x8FD9U, 0x9FF8U,
111 0x6E17U, 0x7E36U, 0x4E55U, 0x5E74U, 0x2E93U, 0x3EB2U, 0x0ED1U, 0x1EF0U
115 #define AVMALIB_CHUNK_PHASE_MMMD 0
116 #define AVMALIB_CHUNK_PHASE_CNTI 1
117 #define AVMALIB_CHUNK_PHASE_MMMDSUB 2
118 #define AVMALIB_CHUNK_PHASE_MTRSUB 3
119 #define AVMALIB_CHUNK_PHASE_ATRSUB 4
120 #define AVMALIB_CHUNK_PHASE_OPDASUB 5
121 #define AVMALIB_CHUNK_PHASE_MTSPSUB 6
122 #define AVMALIB_CHUNK_PHASE_MTHVSUB 7
125 #define AVMALIB_CHUNKCODE_MMMD 0x00
126 #define AVMALIB_CHUNKCODE_CNTI 0x01
127 #define AVMALIB_CHUNKCODE_OPDA 0x02
128 #define AVMALIB_CHUNKCODE_DCH 0x20
129 #define AVMALIB_CHUNKCODE_M5P 0x21
130 #define AVMALIB_CHUNKCODE_MTR 0x03
131 #define AVMALIB_CHUNKCODE_MSPI 0x30
132 #define AVMALIB_CHUNKCODE_MTSU 0x31
133 #define AVMALIB_CHUNKCODE_MTSQ 0x32
134 #define AVMALIB_CHUNKCODE_MTSP 0x33
135 #define AVMALIB_CHUNKCODE_MWA 0x3F
136 #define AVMALIB_CHUNKCODE_ATR 0x04
137 #define AVMALIB_CHUNKCODE_ASPI 0x40
138 #define AVMALIB_CHUNKCODE_ATSU 0x41
139 #define AVMALIB_CHUNKCODE_ATSQ 0x42
140 #define AVMALIB_CHUNKCODE_AWA 0x43
142 #define AVMALIB_CHUNKCODE_MTHV 0x35
143 #define AVMALIB_CHUNKCODE_MHVS 0x36
144 #define AVMALIB_CHUNKCODE_HVP 0x37
145 #define AVMALIB_CHUNKCODE_MHSC 0x38
147 #define AV_MMF_MAX_TRACK_NUM 8
148 #define AV_MMF_MAX_PHRASE_INFO 7
150 #define AV_MMF_STATUS_IDLE 0
151 #define AV_MMF_STATUS_SAT_PROFILE 1
152 #define AV_MMF_STATUS_LOADED 2
154 #define AV_MMF_CRC_NULL 0xFFFF0000
155 #define AV_MMF_POSITION_OF_CCLASS 16
156 #define AV_MMF_POSITION_OF_CTYPE 17
157 #define AV_MMF_STSP_OFFSET_NULL 0xFFFFFFFF
158 #define AV_MMF_STSP_TIME_NULL 0xFFFFFFFF
159 #define AV_MMF_CHUNK_HEADER_SIZE 8
160 #define AV_MMF_FILE_CRC_SIZE 2
161 #define AV_MMF_ATR_TRACK_NO AV_MMF_MAX_TRACK_NUM - 1
162 #define AV_MMF_MINIMUM_TRACKSIZE2 6
163 #define AV_MMF_MINIMUM_TRACKSIZE3 20
164 #define AV_MMF_PLAY_TIME_MIN 20
165 #define AV_MMF_PLAY_TIME_MAX 0x00200000
166 #define AV_MMF_MA2_VOICE_NOTFOUND 0
167 #define AV_MMF_MA2_VOICE_FOUND 1
169 #define AV_MMF_MA2_VOICE_NULL 0xFF
171 #define AV_MMF_PHRAZE_SIZE_A 8
172 #define AV_MMF_PHRAZE_SIZE_B 12
174 #define AV_MMF_TAG_STARTPOINT 0x7374
175 #define AV_MMF_TAG_STOPPOINT 0x7370
176 #define AV_MMF_TAG_PHRASE_A 0x5041
177 #define AV_MMF_TAG_PHRASE_B 0x5042
178 #define AV_MMF_TAG_PHRASE_E 0x5045
179 #define AV_MMF_TAG_PHRASE_I 0x5049
180 #define AV_MMF_TAG_PHRASE_K 0x504B
181 #define AV_MMF_TAG_PHRASE_R 0x5052
182 #define AV_MMF_TAG_PHRASE_S 0x5053
184 #define AV_MMF_SMAF_TYPE_NULL 0
185 #define AV_MMF_SMAF_TYPE_MA1 1
186 #define AV_MMF_SMAF_TYPE_MA2 2
187 #define AV_MMF_SMAF_TYPE_MA3 3
188 #define AV_MMF_SMAF_TYPE_MA5 5
190 #define AV_MMF_HV_CHANNEL_NULL 16
192 /****************************************************************************
194 ****************************************************************************/
196 /* OPDA infomation structure */
197 typedef struct AvTagOptionInfo {
198 unsigned char *pbCnti; /* pointer to CNTI Body */
199 unsigned int dCntiSize; /* size of CNTI Body */
200 unsigned char *pbOpda; /* pointer to OPDA Body */
201 unsigned int dOpdaSize; /* size of OPDA Body */
202 } OPTIONINFO, *POPTIONINFO;
204 /* Track information structure */
205 typedef struct AvTagTrackInfo {
206 unsigned char *pbMtr; /* pointer to MTR(ATR) Body */
207 unsigned int dMtrSize; /* size of MTR(ATR) Body */
208 unsigned char *pbMspi; /* pointer to MspI(AspI) Body */
209 unsigned int dMspiSize; /* size of MspI(AspI) Body */
210 unsigned char *pbMtsu; /* pointer to Mtsu Body */
211 unsigned int dMtsuSize; /* size of Mtsu Body */
212 unsigned char *pbMtsq; /* pointer to Mtsq(Atsq) Body */
213 unsigned int dMtsqSize; /* size of Mtsq(Atsq) Body */
214 unsigned char *pbMtsp; /* pointer to Mtsp Body */
215 unsigned int dMtspSize; /* size of Mtsp Body */
216 unsigned char *pbMthv; /* pointer to Mthv Body */
217 unsigned int dMthvSize; /* size of Mthv Body */
218 unsigned int dPlayTime; /* play time (tick) */
219 unsigned int dTimeBase; /* time base (msec/tick) */
220 unsigned int dStartPoint; /* start point(offset) */
221 unsigned int dStopPoint; /* stop point(offset) */
222 unsigned int dStartTick; /* start point(tick) */
223 unsigned int dStopTick; /* stop point(tick) */
224 } TRACKINFO, *PTRACKINFO;
226 /* Phrase information structure */
227 typedef struct AvTagPhraseInfo {
228 unsigned int dStartPoint; /* start point of phrase(offset) */
229 unsigned int dStopPoint; /* stop point of phrase(offset) */
230 unsigned int dStartTick; /* start point of phrase(tick) */
231 unsigned int dStopTick; /* stop point of phrase(tick) */
232 } PHRASEINFO, *PPHRASEINFO;
234 /* Huffman information structure */
235 typedef struct AvTagHuffmanInfo {
236 unsigned int dMtsqSize; /* size of Mtsq(Atsq) Body */
237 unsigned int dSeqSize; /* size of sequence data */
238 unsigned int dReadSize; /* read data size */
239 short swLeft[512]; /* Huffman Tree (Left) */
240 short swRight[512]; /* Huffman Tree (Right) */
241 unsigned char *psBuffer; /* pointer to reference area */
242 char sbBitC; /* counter of reference bit */
243 unsigned char bByte; /* value of reference byte */
244 unsigned char *psFBuf; /* pointer to sequence data top */
245 char sbFBit; /* counter of sequence data top bit */
246 unsigned char bFByte ; /* value of sequence data top byte */
247 } HUFFMANINFO, *PHUFFMANINFO;
249 /* HV information structure */
250 typedef struct AvTagHvInfo {
251 unsigned char *pbVoice; /* pointer to HVP0 chunk header */
252 unsigned int dVoiceSize; /* size of HV voice parameter */
253 unsigned char *pbScript; /* pointer to Mhsc body */
254 unsigned int dScriptSize; /* size of Mhsc body */
255 unsigned char bHvChannel; /* HV channel # */
259 /* Load information structure */
260 typedef struct AvTagLoadInfo {
261 unsigned char *pbMmmd; /* pointer to MMMD top */
262 unsigned int dMmmdSize; /* size of MMMD (whole) */
263 unsigned int dCrc; /* file CRC */
264 unsigned int dSmafType; /* SMAF Type */
265 unsigned int dPlayTime; /* play time (tick) */
266 unsigned int dStartTime; /* start time (start point tick) */
267 unsigned int dTimeBase; /* time base (msec/tick) */
268 unsigned char(*pfnGetByte)(PHUFFMANINFO psHuf);
269 OPTIONINFO sOption_Info;
270 TRACKINFO sTrack_Info[AV_MMF_MAX_TRACK_NUM];
271 PHRASEINFO sPhrase_Info[AV_MMF_MAX_PHRASE_INFO];
272 HUFFMANINFO sHuffman_Info;
274 } LOADINFO, *PLOADINFO;
276 /* SMAF information structure */
277 typedef struct AvTagSmafInfo {
278 unsigned int dStatus; /* converter status */
279 LOADINFO sLoad_Info[2];
280 } SMAFINFO, *PSMAFINFO;
282 static SMAFINFO g_sSmaf_Info;
283 static const unsigned char g_abBitMaskTable1[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
284 static const unsigned short g_awBitMaskTable2[8] = {0x00FF, 0x01FE, 0x03FC, 0x07F8, 0x0FF0, 0x1FE0, 0x3FC0, 0x7F80};
287 static int __mmf_file_mmf_get_duration(char *src, int is_xmf);
289 /* mm plugin porting */
290 /* plugin manadatory API */
291 int mmfile_format_read_stream_mmf(MMFileFormatContext *formatContext);
292 int mmfile_format_read_frame_mmf(MMFileFormatContext *formatContext, unsigned int timestamp, MMFileFormatFrame *frame);
293 int mmfile_format_read_tag_mmf(MMFileFormatContext *formatContext);
294 int mmfile_format_close_mmf(MMFileFormatContext *formatContext);
296 int mmfile_format_open_mmf(MMFileFormatContext *formatContext)
298 mm_file_retvm_if_fails(DEBUG, formatContext, MMFILE_FORMAT_FAIL);
299 mm_file_retvm_if_fails(DEBUG, MMFileFormatIsValidMMF(NULL, formatContext->uriFileName, 0), MMFILE_FORMAT_FAIL);
301 formatContext->ReadStream = mmfile_format_read_stream_mmf;
302 formatContext->ReadFrame = mmfile_format_read_frame_mmf;
303 formatContext->ReadTag = mmfile_format_read_tag_mmf;
304 formatContext->Close = mmfile_format_close_mmf;
306 formatContext->videoTotalTrackNum = 0;
307 formatContext->audioTotalTrackNum = 1;
309 return MMFILE_FORMAT_SUCCESS;
313 int mmfile_format_read_stream_mmf(MMFileFormatContext *formatContext)
317 total = __mmf_file_mmf_get_duration(formatContext->uriFileName, 0 /*not XMF*/);
318 mm_file_retvm_if_fails(DEBUG, total > 0, MMFILE_FORMAT_FAIL);
320 formatContext->duration = total;
321 formatContext->audioTotalTrackNum = 1;
322 formatContext->nbStreams = 1;
323 formatContext->streams[MMFILE_AUDIO_STREAM] = g_new0(MMFileFormatStream, 1);
324 formatContext->streams[MMFILE_AUDIO_STREAM]->codecId = MM_AUDIO_CODEC_MMF;
325 formatContext->streams[MMFILE_AUDIO_STREAM]->nbChannel = 1;
327 return MMFILE_FORMAT_SUCCESS;
331 int mmfile_format_read_frame_mmf(MMFileFormatContext *formatContext, unsigned int timestamp, MMFileFormatFrame *frame)
333 return MMFILE_FORMAT_SUCCESS;
337 int mmfile_format_read_tag_mmf(MMFileFormatContext *formatContext)
339 return MMFILE_FORMAT_SUCCESS;
343 int mmfile_format_close_mmf(MMFileFormatContext *formatContext)
345 return MMFILE_FORMAT_SUCCESS;
349 static unsigned int _mmf_Get4Byte(unsigned char *pbBuf)
351 return (unsigned int)((((unsigned int)pbBuf[0]) << 24) +
352 (((unsigned int)pbBuf[1]) << 16) +
353 (((unsigned int)pbBuf[2]) << 8) +
354 ((unsigned int)pbBuf[3]));
357 static void _mmf_CheckInitial(PLOADINFO psLoad)
361 /* Initialize Load information structure */
362 psLoad->pbMmmd = NULL;
363 psLoad->dMmmdSize = 0;
364 psLoad->dCrc = AV_MMF_CRC_NULL;
365 psLoad->dSmafType = AV_MMF_SMAF_TYPE_NULL;
366 psLoad->dPlayTime = 0;
367 psLoad->dStartTime = 0;
368 psLoad->dTimeBase = 0;
369 psLoad->pfnGetByte = NULL;
371 psLoad->sOption_Info.pbCnti = NULL;
372 psLoad->sOption_Info.dCntiSize = 0;
373 psLoad->sOption_Info.pbOpda = NULL;
374 psLoad->sOption_Info.dOpdaSize = 0;
376 for (i = 0; i < AV_MMF_MAX_TRACK_NUM; i++) {
377 psLoad->sTrack_Info[i].pbMtr = NULL;
378 psLoad->sTrack_Info[i].dMtrSize = 0;
379 psLoad->sTrack_Info[i].pbMspi = NULL;
380 psLoad->sTrack_Info[i].dMspiSize = 0;
381 psLoad->sTrack_Info[i].pbMtsu = NULL;
382 psLoad->sTrack_Info[i].dMtsuSize = 0;
383 psLoad->sTrack_Info[i].pbMtsq = NULL;
384 psLoad->sTrack_Info[i].dMtsqSize = 0;
385 psLoad->sTrack_Info[i].pbMtsp = NULL;
386 psLoad->sTrack_Info[i].dMtspSize = 0;
387 psLoad->sTrack_Info[i].pbMthv = NULL;
388 psLoad->sTrack_Info[i].dMthvSize = 0;
389 psLoad->sTrack_Info[i].dPlayTime = 0;
390 psLoad->sTrack_Info[i].dTimeBase = 0;
391 psLoad->sTrack_Info[i].dStartPoint = AV_MMF_STSP_OFFSET_NULL;
392 psLoad->sTrack_Info[i].dStopPoint = AV_MMF_STSP_OFFSET_NULL;
393 psLoad->sTrack_Info[i].dStartTick = AV_MMF_STSP_TIME_NULL;
394 psLoad->sTrack_Info[i].dStopTick = AV_MMF_STSP_TIME_NULL;
397 for (i = 0; i < AV_MMF_MAX_PHRASE_INFO; i++) {
398 psLoad->sPhrase_Info[i].dStartPoint = AV_MMF_STSP_OFFSET_NULL;
399 psLoad->sPhrase_Info[i].dStopPoint = AV_MMF_STSP_OFFSET_NULL;
400 psLoad->sPhrase_Info[i].dStartTick = AV_MMF_STSP_TIME_NULL;
401 psLoad->sPhrase_Info[i].dStopTick = AV_MMF_STSP_TIME_NULL;
404 psLoad->sHV_Info.pbVoice = NULL;
405 psLoad->sHV_Info.dVoiceSize = 0;
406 psLoad->sHV_Info.pbScript = NULL;
407 psLoad->sHV_Info.dScriptSize = 0;
408 psLoad->sHV_Info.bHvChannel = AV_MMF_HV_CHANNEL_NULL;
411 static unsigned int _mmf_GetTimebase(unsigned char bData)
415 return 4; /* 4[msec/tick] */
417 return 5; /* 5[msec/tick] */
419 return 10; /* 10[msec/tick] */
421 return 20; /* 20[msec/tick] */
423 return 40; /* 40[msec/tick] */
425 return 50; /* 50[msec/tick] */
427 return MMFILE_FORMAT_FAIL; /* Time Base Error */
432 unsigned int dChunkID;
433 unsigned int dChunkCode;
435 } _mmf_malib_chunk_s;
437 static const _mmf_malib_chunk_s _mmf_malib_chunk_table[] = {
438 { AVMALIB_CHUNKID_MMMD, AVMALIB_CHUNKCODE_MMMD, AVMALIB_CHUNK_PHASE_MMMD },
439 { AVMALIB_CHUNKID_CNTI, AVMALIB_CHUNKCODE_CNTI, AVMALIB_CHUNK_PHASE_CNTI },
440 { AVMALIB_CHUNKID_OPDA, AVMALIB_CHUNKCODE_OPDA, AVMALIB_CHUNK_PHASE_MMMDSUB },
441 { AVMALIB_CHUNKID_MSPI, AVMALIB_CHUNKCODE_MSPI, AVMALIB_CHUNK_PHASE_MTRSUB },
442 { AVMALIB_CHUNKID_MTSU, AVMALIB_CHUNKCODE_MTSU, AVMALIB_CHUNK_PHASE_MTRSUB },
443 { AVMALIB_CHUNKID_MTSQ, AVMALIB_CHUNKCODE_MTSQ, AVMALIB_CHUNK_PHASE_MTRSUB },
444 { AVMALIB_CHUNKID_MTSP, AVMALIB_CHUNKCODE_MTSP, AVMALIB_CHUNK_PHASE_MTRSUB },
445 { AVMALIB_CHUNKID_ASPI, AVMALIB_CHUNKCODE_ASPI, AVMALIB_CHUNK_PHASE_ATRSUB },
446 { AVMALIB_CHUNKID_ATSU, AVMALIB_CHUNKCODE_ATSU, AVMALIB_CHUNK_PHASE_ATRSUB },
447 { AVMALIB_CHUNKID_ATSQ, AVMALIB_CHUNKCODE_ATSQ, AVMALIB_CHUNK_PHASE_ATRSUB },
448 { AVMALIB_CHUNKID_MTHV, AVMALIB_CHUNKCODE_MTHV, AVMALIB_CHUNK_PHASE_MTRSUB },
449 { AVMALIB_CHUNKID_MHVS, AVMALIB_CHUNKCODE_MHVS, AVMALIB_CHUNK_PHASE_MTHVSUB },
450 { AVMALIB_CHUNKID_MHSC, AVMALIB_CHUNKCODE_MHSC, AVMALIB_CHUNK_PHASE_MTHVSUB },
453 static const _mmf_malib_chunk_s _mmf_malib_chunk_sub_table[] = {
454 { AVMALIB_CHUNKID_MTR, AVMALIB_CHUNKCODE_MTR, AVMALIB_CHUNK_PHASE_MMMDSUB },
455 { AVMALIB_CHUNKID_ATR, AVMALIB_CHUNKCODE_ATR, AVMALIB_CHUNK_PHASE_MMMDSUB },
456 { AVMALIB_CHUNKID_DCH, AVMALIB_CHUNKCODE_DCH, AVMALIB_CHUNK_PHASE_OPDASUB },
457 { AVMALIB_CHUNKID_M5P, AVMALIB_CHUNKCODE_M5P, AVMALIB_CHUNK_PHASE_OPDASUB },
458 { AVMALIB_CHUNKID_MWA, AVMALIB_CHUNKCODE_MWA, AVMALIB_CHUNK_PHASE_MTSPSUB },
459 { AVMALIB_CHUNKID_AWA, AVMALIB_CHUNKCODE_AWA, AVMALIB_CHUNK_PHASE_ATRSUB },
460 { AVMALIB_CHUNKID_HVP, AVMALIB_CHUNKCODE_HVP, AVMALIB_CHUNK_PHASE_MTHVSUB },
463 static bool __mmf_MalibNextChunk(unsigned char *pbFile,
466 unsigned int *pdChunkID,
467 unsigned int *pdChunkNo,
468 unsigned int *pdChunkSize)
470 unsigned int dChunkID;
471 unsigned int dIdx = 0;
472 unsigned int dTableSize = sizeof(_mmf_malib_chunk_table) / sizeof(_mmf_malib_chunk_s);
473 unsigned int dSubTableSize = sizeof(_mmf_malib_chunk_sub_table) / sizeof(_mmf_malib_chunk_s);
475 if (dSize < AVMALIB_SIZE_OF_CHUNKHEADER)
478 dChunkID = AVMALIB_MAKEDWORD(pbFile[0], pbFile[1], pbFile[2], pbFile[3]);
479 *pdChunkSize = AVMALIB_MAKEDWORD(pbFile[4], pbFile[5], pbFile[6], pbFile[7]);
481 if (*pdChunkSize > (dSize - AVMALIB_SIZE_OF_CHUNKHEADER))
484 for (dIdx = 0; dIdx < dTableSize; dIdx++) {
485 if (dChunkID == _mmf_malib_chunk_table[dIdx].dChunkID) {
486 *pdChunkID = _mmf_malib_chunk_table[dIdx].dChunkCode;
487 if (dState != _mmf_malib_chunk_table[dIdx].dState)
493 if (dIdx == dTableSize) {
494 *pdChunkNo = (unsigned char)(dChunkID & 0x000000FF);
495 for (dIdx = 0; dIdx < dSubTableSize; dIdx++) {
496 if ((dChunkID & 0xFFFFFF00) == _mmf_malib_chunk_sub_table[dIdx].dChunkID) {
497 *pdChunkID = _mmf_malib_chunk_sub_table[dIdx].dChunkCode;
498 if (dState != _mmf_malib_chunk_sub_table[dIdx].dState)
508 static bool __mmf_MTRCheck(PTRACKINFO psTrack, unsigned char bSmafType)
510 unsigned int dSize, dIndex, dResult, dChunkSize;
511 unsigned char *pbBuf;
512 unsigned int dChunkID, dChunkNo;
514 /* Check Format Type */
516 case AV_MMF_SMAF_TYPE_MA1:
517 case AV_MMF_SMAF_TYPE_MA2:
518 if (psTrack->pbMtr[0] != 0x00)
521 case AV_MMF_SMAF_TYPE_MA3:
522 if ((psTrack->pbMtr[0] != 0x01) && (psTrack->pbMtr[0] != 0x02))
525 case AV_MMF_SMAF_TYPE_MA5:
526 if (psTrack->pbMtr[0] != 0x02)
533 /* Check Sequence Type */
534 mm_file_retv_if_fails(psTrack->pbMtr[1] == 0x00, false);
536 /* Check Time Base */
537 mm_file_retv_if_fails(psTrack->pbMtr[2] == psTrack->pbMtr[3], false);
539 dResult = _mmf_GetTimebase(psTrack->pbMtr[2]);
540 mm_file_retv_if_fails(dResult != MMFILE_FORMAT_FAIL, false);
542 psTrack->dTimeBase = dResult;
544 /* Check sub chunk disposition */
545 if ((bSmafType == AV_MMF_SMAF_TYPE_MA1) || (bSmafType == AV_MMF_SMAF_TYPE_MA2))
546 dIndex = AV_MMF_MINIMUM_TRACKSIZE2;
548 dIndex = AV_MMF_MINIMUM_TRACKSIZE3;
550 pbBuf = psTrack->pbMtr;
551 dSize = psTrack->dMtrSize;
553 while (dSize > (dIndex + AV_MMF_CHUNK_HEADER_SIZE)) {
554 if (!__mmf_MalibNextChunk(&pbBuf[dIndex], (dSize - dIndex), AVMALIB_CHUNK_PHASE_MTRSUB, &dChunkID, &dChunkNo, &dChunkSize))
557 dIndex += AV_MMF_CHUNK_HEADER_SIZE;
559 case AVMALIB_CHUNKCODE_MSPI:
560 psTrack->pbMspi = &(pbBuf[dIndex]);
561 psTrack->dMspiSize = dChunkSize;
563 case AVMALIB_CHUNKCODE_MTSU:
564 psTrack->pbMtsu = &(pbBuf[dIndex]);
565 psTrack->dMtsuSize = dChunkSize;
567 case AVMALIB_CHUNKCODE_MTSQ:
568 psTrack->pbMtsq = &(pbBuf[dIndex]);
569 psTrack->dMtsqSize = dChunkSize;
571 case AVMALIB_CHUNKCODE_MTSP:
572 psTrack->pbMtsp = &(pbBuf[dIndex]);
573 psTrack->dMtspSize = dChunkSize;
575 case AVMALIB_CHUNKCODE_MTHV:
576 psTrack->pbMthv = &(pbBuf[dIndex]);
577 psTrack->dMthvSize = dChunkSize;
582 dIndex += dChunkSize;
585 if ((psTrack->pbMtsq == NULL) || (psTrack->dMtsqSize == 0))
591 static bool __mmf_ATRCheck(PTRACKINFO psTrack)
593 unsigned int dSize, dIndex, dResult, dChunkSize;
594 unsigned char *pbBuf;
595 unsigned int dChunkID, dChunkNo;
596 unsigned char fbWave = AV_MMF_MA2_VOICE_NULL;
598 /* Check Format Type */
599 mm_file_retv_if_fails(psTrack->pbMtr[0] == 0x00, false);
601 /* Check Sequence Type */
602 mm_file_retv_if_fails(psTrack->pbMtr[1] == 0x00, false);
604 /* Check Wave Type */
605 mm_file_retv_if_fails(psTrack->pbMtr[2] == 0x10 || psTrack->pbMtr[2] == 0x11, false);
606 mm_file_retv_if_fails((psTrack->pbMtr[3] & 0xF0) == 0x00, false);
608 /* Check Time Base */
609 mm_file_retv_if_fails(psTrack->pbMtr[4] == psTrack->pbMtr[5], false);
611 dResult = _mmf_GetTimebase(psTrack->pbMtr[4]);
612 mm_file_retv_if_fails(dResult != MMFILE_FORMAT_FAIL, false);
614 psTrack->dTimeBase = dResult;
616 pbBuf = psTrack->pbMtr;
617 dSize = psTrack->dMtrSize;
620 /* Check sub chunk disposition */
621 while (dSize > (dIndex + AV_MMF_CHUNK_HEADER_SIZE)) {
622 if (!__mmf_MalibNextChunk(&pbBuf[dIndex], (dSize - dIndex), AVMALIB_CHUNK_PHASE_ATRSUB, &dChunkID, &dChunkNo, &dChunkSize))
625 dIndex += AV_MMF_CHUNK_HEADER_SIZE;
627 case AVMALIB_CHUNKCODE_ASPI:
628 psTrack->pbMspi = &(pbBuf[dIndex]);
629 psTrack->dMspiSize = dChunkSize;
631 case AVMALIB_CHUNKCODE_ATSQ:
632 psTrack->pbMtsq = &(pbBuf[dIndex]);
633 psTrack->dMtsqSize = dChunkSize;
635 case AVMALIB_CHUNKCODE_AWA:
636 if ((0x01 <= dChunkNo) && (dChunkNo <= 0x3E))
637 fbWave = AV_MMF_MA2_VOICE_FOUND;
642 dIndex += dChunkSize;
645 if ((psTrack->pbMtsq == NULL) || (psTrack->dMtsqSize == 0) || (fbWave == AV_MMF_MA2_VOICE_NULL))
651 static void __mmf_MspICheck(PTRACKINFO psTrack, PPHRASEINFO psPhrase)
653 unsigned char *pbBuf;
654 unsigned int dSize, dIndex;
657 if (psTrack->pbMspi == NULL)
660 pbBuf = psTrack->pbMspi;
661 dSize = psTrack->dMspiSize;
664 while (dSize >= dIndex + AV_MMF_PHRAZE_SIZE_A) {
665 wTag = (unsigned short)((((unsigned short)pbBuf[dIndex]) << 8) + (unsigned short)pbBuf[dIndex + 1]);
667 case AV_MMF_TAG_STARTPOINT: /* start point */
668 psTrack->dStartPoint = _mmf_Get4Byte(&(pbBuf[dIndex + 3]));
669 dIndex += AV_MMF_PHRAZE_SIZE_A;
671 case AV_MMF_TAG_STOPPOINT: /* stop point */
672 psTrack->dStopPoint = _mmf_Get4Byte(&(pbBuf[dIndex + 3]));
673 dIndex += AV_MMF_PHRAZE_SIZE_A;
675 case AV_MMF_TAG_PHRASE_A: /* A melody */
676 if (dSize < dIndex + AV_MMF_PHRAZE_SIZE_B)
678 psPhrase[0].dStartPoint = _mmf_Get4Byte(&(pbBuf[dIndex + 3]));
679 psPhrase[0].dStopPoint = _mmf_Get4Byte(&(pbBuf[dIndex + 7]));
680 dIndex += AV_MMF_PHRAZE_SIZE_B;
682 case AV_MMF_TAG_PHRASE_B: /* B melody */
683 if (dSize < dIndex + AV_MMF_PHRAZE_SIZE_B)
685 psPhrase[1].dStartPoint = _mmf_Get4Byte(&(pbBuf[dIndex + 3]));
686 psPhrase[1].dStopPoint = _mmf_Get4Byte(&(pbBuf[dIndex + 7]));
687 dIndex += AV_MMF_PHRAZE_SIZE_B;
689 case AV_MMF_TAG_PHRASE_E: /* Ending */
690 if (dSize < dIndex + AV_MMF_PHRAZE_SIZE_B)
692 psPhrase[2].dStartPoint = _mmf_Get4Byte(&(pbBuf[dIndex + 3]));
693 psPhrase[2].dStopPoint = _mmf_Get4Byte(&(pbBuf[dIndex + 7]));
694 dIndex += AV_MMF_PHRAZE_SIZE_B;
696 case AV_MMF_TAG_PHRASE_I: /* Intro */
697 if (dSize < dIndex + AV_MMF_PHRAZE_SIZE_B)
699 psPhrase[3].dStartPoint = _mmf_Get4Byte(&(pbBuf[dIndex + 3]));
700 psPhrase[3].dStopPoint = _mmf_Get4Byte(&(pbBuf[dIndex + 7]));
701 dIndex += AV_MMF_PHRAZE_SIZE_B;
703 case AV_MMF_TAG_PHRASE_K: /* Interlude */
704 if (dSize < dIndex + AV_MMF_PHRAZE_SIZE_B)
706 psPhrase[4].dStartPoint = _mmf_Get4Byte(&(pbBuf[dIndex + 3]));
707 psPhrase[4].dStopPoint = _mmf_Get4Byte(&(pbBuf[dIndex + 7]));
708 dIndex += AV_MMF_PHRAZE_SIZE_B;
710 case AV_MMF_TAG_PHRASE_R: /* Refrain */
711 if (dSize < dIndex + AV_MMF_PHRAZE_SIZE_B)
713 psPhrase[5].dStartPoint = _mmf_Get4Byte(&(pbBuf[dIndex + 3]));
714 psPhrase[5].dStopPoint = _mmf_Get4Byte(&(pbBuf[dIndex + 7]));
715 dIndex += AV_MMF_PHRAZE_SIZE_B;
717 case AV_MMF_TAG_PHRASE_S: /* Bridge */
718 if (dSize < dIndex + AV_MMF_PHRAZE_SIZE_B)
720 psPhrase[6].dStartPoint = _mmf_Get4Byte(&(pbBuf[dIndex + 3]));
721 psPhrase[6].dStopPoint = _mmf_Get4Byte(&(pbBuf[dIndex + 7]));
722 dIndex += AV_MMF_PHRAZE_SIZE_B;
730 static bool __mmf_STSPCheck(PTRACKINFO psTrack)
732 unsigned int dStart, dStop, dSize;
734 dSize = psTrack->dMtsqSize;
736 if (psTrack->dStartPoint == AV_MMF_STSP_OFFSET_NULL)
739 dStart = psTrack->dStartPoint;
741 if (psTrack->dStopPoint == AV_MMF_STSP_OFFSET_NULL)
744 dStop = psTrack->dStopPoint;
746 if ((dStart >= dStop) || (dStart > dSize) || (dStop > dSize))
752 static bool __mmf_MtsuCheck2(PTRACKINFO psTrack, unsigned char bSmafType)
754 unsigned char *pbBuf;
755 unsigned int dSize, dIndex;
757 mm_file_retv_if_fails(psTrack->pbMtsu, false);
759 pbBuf = psTrack->pbMtsu;
760 dSize = psTrack->dMtsuSize;
763 while (dSize > dIndex + 20) {
764 if ((pbBuf[dIndex] != 0xFF) || (pbBuf[dIndex + 1] != 0xF0))
767 if (pbBuf[dIndex + 3] == 0x43) {
768 if ((bSmafType == AV_MMF_SMAF_TYPE_MA1) && (pbBuf[dIndex + 4] == 0x02))
770 if ((bSmafType == AV_MMF_SMAF_TYPE_MA2) && (pbBuf[dIndex + 4] == 0x03))
773 dIndex += (pbBuf[dIndex + 2] + 3);
779 static bool __mmf_GetFlex2L(unsigned char *pbBuf, unsigned int dSize, unsigned int *pbRead, unsigned int *pdFlex)
781 unsigned int dTemp = 0;
783 if ((dSize < 1) || ((dSize < 2) && (pbBuf[0] >= 0x80)))
786 dTemp = pbBuf[0] + pbBuf[1] + pbBuf[2] + pbBuf[3];
791 if (pbBuf[0] >= 0x80) {
792 *pdFlex = (((unsigned int)(pbBuf[0] & 0x7F)) << 7) + ((unsigned int)(pbBuf[1] & 0x7F)) + 128;
795 *pdFlex = (unsigned int)(pbBuf[0] & 0x7F);
802 static bool __mmf_SeqDataCheck2(PTRACKINFO psTrack, unsigned char bSmafType)
804 unsigned char *pbBuf;
805 unsigned int dSize, dIndex;
806 unsigned int dPast, dGate, dFlexSize, dTemp;
808 mm_file_retv_if_fails(psTrack->pbMtsq, false);
812 pbBuf = psTrack->pbMtsq;
813 dSize = psTrack->dMtsqSize;
816 /* scanning to EOS or stop point */
817 while (dSize > dIndex) {
818 if (psTrack->dStartPoint == dIndex) /* start point */
819 psTrack->dStartTick = dPast;
820 if (psTrack->dStopPoint == dIndex) {
822 psTrack->dStopTick = dPast;
826 if (dSize >= dIndex + 4) {
827 dTemp = pbBuf[dIndex] + pbBuf[dIndex + 1] + pbBuf[dIndex + 2] + pbBuf[dIndex + 3];
830 if (bSmafType == AV_MMF_SMAF_TYPE_MA1)
831 psTrack->dStopTick = dPast + dGate;
833 psTrack->dStopTick = dPast;
838 if (!__mmf_GetFlex2L(&pbBuf[dIndex], (dSize - dIndex), &dFlexSize, &dTemp))
842 if (dPast >= AV_MMF_PLAY_TIME_MAX)
845 if (dTemp >= dGate) /* calculate remain of GT */
851 if (dSize < dIndex + 2)
854 switch (pbBuf[dIndex]) {
856 if ((pbBuf[dIndex + 1] & 0x30) != 0x30)
862 switch (pbBuf[dIndex + 1]) {
867 if (dSize < dIndex + 3)
870 dIndex += (pbBuf[dIndex + 2] + 3);
874 if (pbBuf[dIndex - 1] != 0xF7)
882 if (!__mmf_GetFlex2L(&pbBuf[dIndex + 1], (dSize - dIndex - 1), &dFlexSize, &dTemp))
888 dIndex += (1 + dFlexSize);
896 if (psTrack->dStartTick == AV_MMF_STSP_TIME_NULL) {
897 if (psTrack->dStartPoint != AV_MMF_STSP_OFFSET_NULL)
900 psTrack->dStartTick = 0;
903 /* check start/stop point potision */
904 if (psTrack->dStopTick == AV_MMF_STSP_TIME_NULL) {
905 if ((psTrack->dStopPoint != AV_MMF_STSP_OFFSET_NULL) && (psTrack->dStopPoint != dIndex))
908 if (bSmafType == AV_MMF_SMAF_TYPE_MA1)
909 psTrack->dStopTick = dPast + dGate;
911 psTrack->dStopTick = dPast;
914 /* calculate playback time of this track */
915 psTrack->dPlayTime = psTrack->dStopTick - psTrack->dStartTick;
917 debug_msg(RELEASE, "Play time: %u\n", psTrack->dPlayTime);
922 static bool __mmf_TrackChunkCheck2(PLOADINFO psLoad)
928 /* delete track information of MA-3/5 */
929 psLoad->sTrack_Info[5].pbMtr = NULL;
930 psLoad->sTrack_Info[5].dMtrSize = 0;
931 psLoad->sTrack_Info[6].pbMtr = NULL;
932 psLoad->sTrack_Info[6].dMtrSize = 0;
935 psLoad->dSmafType = AV_MMF_SMAF_TYPE_MA1;
936 for (i = 1; i < 5; i++) {
937 if (psLoad->sTrack_Info[i].pbMtr != NULL) {
938 psLoad->dSmafType = AV_MMF_SMAF_TYPE_MA2;
942 if (psLoad->sTrack_Info[AV_MMF_ATR_TRACK_NO].pbMtr != NULL)
943 psLoad->dSmafType = AV_MMF_SMAF_TYPE_MA2;
945 if (psLoad->dSmafType == AV_MMF_SMAF_TYPE_MA1) {
947 mm_file_retv_if_fails(psLoad->sTrack_Info[0].pbMtr, false);
949 psTrack = &(psLoad->sTrack_Info[0]);
950 mm_file_retv_if_fails(psTrack->dMtrSize > AV_MMF_MINIMUM_TRACKSIZE2, false);
951 mm_file_retv_if_fails(__mmf_MTRCheck(psTrack, AV_MMF_SMAF_TYPE_MA1), false);
953 __mmf_MspICheck(psTrack, &(psLoad->sPhrase_Info[0]));
954 mm_file_retv_if_fails(__mmf_STSPCheck(psTrack), false);
955 mm_file_retv_if_fails(__mmf_MtsuCheck2(psTrack, AV_MMF_SMAF_TYPE_MA1), false);
956 mm_file_retv_if_fails(__mmf_SeqDataCheck2(psTrack, AV_MMF_SMAF_TYPE_MA1), false);
958 psLoad->dPlayTime = psTrack->dPlayTime;
959 psLoad->dStartTime = psTrack->dStartTick;
960 psLoad->dTimeBase = psTrack->dTimeBase;
964 psLoad->sTrack_Info[0].pbMtr = NULL;
965 psLoad->sTrack_Info[0].dMtrSize = 0;
967 for (i = 1; i < 5; i++) {
968 psTrack = &(psLoad->sTrack_Info[i]);
969 if (psTrack->pbMtr == NULL)
972 mm_file_retv_if_fails(psTrack->dMtrSize > AV_MMF_MINIMUM_TRACKSIZE2, false);
973 mm_file_retv_if_fails(__mmf_MTRCheck(psTrack, AV_MMF_SMAF_TYPE_MA2), false);
975 __mmf_MspICheck(psTrack, &(psLoad->sPhrase_Info[0]));
976 mm_file_retv_if_fails(__mmf_STSPCheck(psTrack), false);
977 mm_file_retv_if_fails(__mmf_SeqDataCheck2(psTrack, AV_MMF_SMAF_TYPE_MA2), false);
979 psLoad->dPlayTime = psTrack->dPlayTime;
980 psLoad->dStartTime = psTrack->dStartTick;
981 psLoad->dTimeBase = psTrack->dTimeBase;
983 if (psLoad->sTrack_Info[AV_MMF_ATR_TRACK_NO].pbMtr != NULL) {
984 psTrack = &(psLoad->sTrack_Info[AV_MMF_ATR_TRACK_NO]);
986 mm_file_retv_if_fails(psTrack->dMtrSize > AV_MMF_MINIMUM_TRACKSIZE2, false);
987 mm_file_retv_if_fails(__mmf_ATRCheck(psTrack), false);
989 __mmf_MspICheck(psTrack, &(psLoad->sPhrase_Info[0]));
990 mm_file_retv_if_fails(__mmf_STSPCheck(psTrack), false);
991 mm_file_retv_if_fails(__mmf_SeqDataCheck2(psTrack, AV_MMF_SMAF_TYPE_MA2), false);
993 psLoad->dPlayTime = psTrack->dPlayTime;
994 psLoad->dStartTime = psTrack->dStartTick;
995 psLoad->dTimeBase = psTrack->dTimeBase;
998 /* totaling of track information */
999 for (i = 1; i < AV_MMF_MAX_TRACK_NUM; i++) {
1000 psTrack = &(psLoad->sTrack_Info[i]);
1001 if (psTrack->pbMtr == NULL)
1004 if (psLoad->dPlayTime < psTrack->dPlayTime)
1005 psLoad->dPlayTime = psTrack->dPlayTime;
1007 mm_file_retv_if_fails(psLoad->dTimeBase == psTrack->dTimeBase, false);
1008 mm_file_retv_if_fails(psLoad->dStartTime == psTrack->dStartTick, false);
1011 for (i = 1; i < 5; i++) {
1012 psTrack = &(psLoad->sTrack_Info[i]);
1013 if (psTrack->pbMtr == NULL)
1016 if (__mmf_MtsuCheck2(psTrack, AV_MMF_SMAF_TYPE_MA2)) {
1026 debug_msg(RELEASE, "Play time: %u\n", psLoad->dPlayTime);
1031 static unsigned char __mmf_GetByte3L(PHUFFMANINFO psHuf)
1034 if (psHuf->dReadSize > psHuf->dMtsqSize)
1037 return *(psHuf->psBuffer++);
1040 static bool __mmf_GetFlex3L(PLOADINFO psLoad, unsigned int *pdRead, unsigned int *pdFlex)
1042 unsigned int dTemp, dRead;
1043 unsigned char bTemp;
1046 bTemp = psLoad->pfnGetByte(&(psLoad->sHuffman_Info));
1047 dTemp = (unsigned int)(bTemp & 0x7F);
1048 while (bTemp & 0x80) {
1052 bTemp = psLoad->pfnGetByte(&(psLoad->sHuffman_Info));
1053 dTemp = (dTemp << 7) + (unsigned int)(bTemp & 0x7F);
1055 if (dTemp >= AV_MMF_PLAY_TIME_MAX)
1064 static bool __mmf_SeqDataCheck3(PLOADINFO psLoad, unsigned char bSmafType)
1069 unsigned int dIndex, fdPhrase, dSize, dPast, dGate, dReadSize, i;
1070 unsigned int dStartTick, dStopTick, dTemp;
1071 unsigned char bTemp;
1073 if (bSmafType == AV_MMF_SMAF_TYPE_MA3) {
1075 psTrk = &(psLoad->sTrack_Info[5]);
1076 dStartTick = AV_MMF_STSP_TIME_NULL;
1077 dStopTick = AV_MMF_STSP_TIME_NULL;
1080 psTrk = &(psLoad->sTrack_Info[6]);
1081 dStartTick = psTrk->dStartTick;
1082 dStopTick = psTrk->dStopTick;
1083 psTrk->dStartTick = AV_MMF_STSP_TIME_NULL;
1084 psTrk->dStopTick = AV_MMF_STSP_TIME_NULL;
1087 psPhr = &(psLoad->sPhrase_Info[0]);
1088 psHuf = &(psLoad->sHuffman_Info);
1093 dSize = psHuf->dSeqSize;
1095 mm_file_retv_if_fails(psHuf->dSeqSize > 0, false);
1097 for (i = 0; i < AV_MMF_MAX_PHRASE_INFO; i++) {
1098 if (psPhr[i].dStartPoint != AV_MMF_STSP_OFFSET_NULL)
1102 /* scanning sequence data to EOS or stop point */
1103 while (dSize >= dIndex) {
1104 if (psTrk->dStartPoint == dIndex)
1105 psTrk->dStartTick = dPast;
1106 if (psTrk->dStopPoint == dIndex) /* stop point */
1107 psTrk->dStopTick = dPast;
1109 for (i = 0; i < AV_MMF_MAX_PHRASE_INFO; i++) {
1110 if (psPhr[i].dStartPoint == dIndex)
1111 psPhr[i].dStartTick = dPast;
1112 if (psPhr[i].dStopPoint == dIndex)
1113 psPhr[i].dStopTick = dPast;
1117 if ((psTrk->dStopTick != AV_MMF_STSP_TIME_NULL) || (dSize == dIndex))
1121 mm_file_retv_if_fails(__mmf_GetFlex3L(psLoad, &dReadSize, &dTemp), false);
1124 mm_file_retv_if_fails(dPast < AV_MMF_PLAY_TIME_MAX, false);
1130 dIndex += dReadSize;
1132 bTemp = psLoad->pfnGetByte(psHuf);
1135 switch (bTemp & 0xF0) {
1137 psLoad->pfnGetByte(psHuf); /*Note number*/
1139 psLoad->pfnGetByte(psHuf); /*Key Velocity*/
1141 mm_file_retv_if_fails(__mmf_GetFlex3L(psLoad, &dReadSize, &dTemp), false);
1143 dIndex += dReadSize;
1148 psLoad->pfnGetByte(psHuf); /*Note number*/
1150 mm_file_retv_if_fails(__mmf_GetFlex3L(psLoad, &dReadSize, &dTemp), false);
1152 dIndex += dReadSize;
1159 bTemp = psLoad->pfnGetByte(psHuf); /*B0: Conrol number, E0:Pitch Bend Change LSB*/
1161 bTemp = psLoad->pfnGetByte(psHuf); /*B0: Conrol value, E0:Pitch Bend Change MSB*/
1166 bTemp = psLoad->pfnGetByte(psHuf);
1172 mm_file_retv_if_fails(__mmf_GetFlex3L(psLoad, &dReadSize, &dTemp), false);
1174 for (i = 0; i < dTemp; i++)
1175 bTemp = psLoad->pfnGetByte(psHuf);
1176 mm_file_retv_if_fails(bTemp == 0xF7, false);
1178 dIndex += dTemp + dReadSize;
1181 bTemp = psLoad->pfnGetByte(psHuf);
1187 bTemp = psLoad->pfnGetByte(psHuf);
1193 psTrk->dStopTick = dPast;
1205 if ((dSize < dIndex) || (psHuf->dReadSize > psHuf->dMtsqSize))
1210 if (bSmafType == AV_MMF_SMAF_TYPE_MA3) {
1212 /* check start point */
1213 if (psTrk->dStartTick == AV_MMF_STSP_TIME_NULL) {
1214 if (psTrk->dStartPoint != AV_MMF_STSP_OFFSET_NULL)
1217 psTrk->dStartPoint = 0;
1218 psTrk->dStartTick = 0;
1220 /* check stop point */
1221 if (psTrk->dStopTick == AV_MMF_STSP_TIME_NULL) {
1222 if (psTrk->dStopPoint != AV_MMF_STSP_OFFSET_NULL)
1225 psTrk->dStopPoint = dSize;
1226 psTrk->dStopTick = dPast + dGate;
1228 /* adjust phrase information */
1229 for (i = 0; i < AV_MMF_MAX_PHRASE_INFO; i++) {
1230 if (psPhr[i].dStartPoint <= psTrk->dStartPoint)
1231 psPhr[i].dStartTick = psTrk->dStartTick;
1232 if (psPhr[i].dStopPoint >= psTrk->dStopPoint)
1233 psPhr[i].dStopTick = psTrk->dStopTick;
1234 if (psPhr[i].dStopPoint <= psTrk->dStartPoint)
1235 psPhr[i].dStopTick = AV_MMF_STSP_TIME_NULL;
1239 /* check stop point */
1240 if (dStopTick > dPast)
1243 psTrk->dStartTick = dStartTick;
1244 psTrk->dStopTick = dStopTick;
1247 /* calculate playback time of this track */
1248 psTrk->dPlayTime = psTrk->dStopTick - psTrk->dStartTick;
1250 debug_msg(RELEASE, "Play time: %u\n", psTrk->dPlayTime);
1255 static unsigned char __mmf_DecodeGetbitL(PHUFFMANINFO psHuf)
1259 if (--psHuf->sbBitC < czero) {
1260 if (psHuf->dReadSize >= psHuf->dMtsqSize)
1263 psHuf->bByte = *(psHuf->psBuffer++);
1266 return (psHuf->bByte & g_abBitMaskTable1[(int)(psHuf->sbBitC)]);
1269 static unsigned char __mmf_DecodeGetbits(PHUFFMANINFO psHuf)
1271 unsigned short wTemp;
1272 unsigned char bData1, bData2;
1274 if (psHuf->dReadSize >= psHuf->dMtsqSize)
1277 bData1 = psHuf->bByte;
1278 bData2 = *(psHuf->psBuffer++);
1279 psHuf->bByte = bData2;
1281 wTemp = (unsigned short)((((unsigned short)bData1) << 8) + ((unsigned short)bData2));
1282 return (unsigned char)((wTemp & g_awBitMaskTable2[(int)(psHuf->sbBitC)]) >> psHuf->sbBitC);
1285 static bool __mmf_DecodeTree(PHUFFMANINFO psHuf)
1287 unsigned int dNode, dEmpty, dIndex, i;
1288 short *pswLeft, *pswRight, *pswPNode;
1289 unsigned char bTemp;
1291 if (__mmf_DecodeGetbitL(psHuf)) {
1292 if (psHuf->dReadSize >= psHuf->dMtsqSize)
1295 pswLeft = &(psHuf->swLeft[256]);
1296 pswRight = &(psHuf->swRight[256]);
1297 pswPNode = &(psHuf->swRight[0]);
1298 for (i = 0; i < 256; i++) {
1309 while (dNode != 0) {
1310 if ((dEmpty >= 256) || (dNode >= 257))
1313 bTemp = __mmf_DecodeGetbitL(psHuf);
1314 if (psHuf->dReadSize >= psHuf->dMtsqSize)
1319 if (pswLeft[dIndex] == -1)
1320 pswLeft[dIndex] = (short)(dEmpty + 256);
1322 pswRight[dIndex] = (short)(dEmpty + 256);
1323 pswPNode[dEmpty] = (short)dIndex;
1328 bTemp = __mmf_DecodeGetbits(psHuf);
1329 if (psHuf->dReadSize >= psHuf->dMtsqSize)
1332 if (pswLeft[dIndex] == -1)
1333 pswLeft[dIndex] = (short)bTemp;
1335 pswRight[dIndex] = (short)bTemp;
1336 while ((pswRight[dIndex] != -1) && (dIndex != 0))
1337 dIndex = (unsigned int)pswPNode[dIndex];
1342 for (i = 0; i < 256; i++) {
1343 if (pswLeft[i] == -1)
1345 if (pswRight[i] == -1)
1351 static unsigned int __mmf_DecodeInit(PHUFFMANINFO psHuf)
1353 unsigned int dSeqSize;
1355 if (psHuf->dMtsqSize <= 5)
1358 dSeqSize = _mmf_Get4Byte(psHuf->psBuffer);
1359 psHuf->psBuffer += 4;
1360 psHuf->dReadSize = 4;
1363 if (!__mmf_DecodeTree(psHuf))
1369 static unsigned char __mmf_DecodeByte3L(PHUFFMANINFO psHuf)
1371 unsigned int bData, bIndex;
1374 while (bIndex >= 256) {
1375 if (--psHuf->sbBitC < czero) {
1377 if (psHuf->dReadSize > psHuf->dMtsqSize)
1380 psHuf->bByte = *(psHuf->psBuffer++);
1382 bData = (unsigned char)(psHuf->bByte & g_abBitMaskTable1[(int)(psHuf->sbBitC)]);
1384 bIndex = psHuf->swRight[bIndex];
1386 bIndex = psHuf->swLeft[bIndex];
1388 return (unsigned char)bIndex;
1391 static bool __mmf_TrackChunkCheck3(PLOADINFO psLoad)
1395 mm_file_retv_if_fails(psLoad->sTrack_Info[5].pbMtr, false);
1397 psTrack = &(psLoad->sTrack_Info[5]);
1398 mm_file_retv_if_fails(psTrack->dMtrSize > AV_MMF_MINIMUM_TRACKSIZE3, false);
1399 mm_file_retv_if_fails(__mmf_MTRCheck(psTrack, AV_MMF_SMAF_TYPE_MA3), false);
1401 __mmf_MspICheck(psTrack, &(psLoad->sPhrase_Info[0]));
1403 psLoad->sHuffman_Info.psBuffer = psTrack->pbMtsq;
1404 psLoad->sHuffman_Info.dMtsqSize = psTrack->dMtsqSize;
1406 /* Initialize Huffman information structure */
1407 if (psTrack->pbMtr[0] == 0x01) {
1408 /* Compressed Foramt */
1409 psLoad->sHuffman_Info.dSeqSize = __mmf_DecodeInit(&(psLoad->sHuffman_Info));
1410 mm_file_retv_if_fails(psLoad->sHuffman_Info.dSeqSize > 0, false);
1412 psLoad->pfnGetByte = __mmf_DecodeByte3L;
1413 psLoad->sHuffman_Info.psFBuf = psLoad->sHuffman_Info.psBuffer;
1414 psLoad->sHuffman_Info.sbFBit = psLoad->sHuffman_Info.sbBitC;
1415 psLoad->sHuffman_Info.bFByte = psLoad->sHuffman_Info.bByte;
1417 /* No Compressed Foramt */
1418 psLoad->pfnGetByte = __mmf_GetByte3L;
1419 psLoad->sHuffman_Info.dSeqSize = psTrack->dMtsqSize;
1420 psLoad->sHuffman_Info.dReadSize = 0;
1421 psLoad->sHuffman_Info.psFBuf = psTrack->pbMtsq;
1422 psLoad->sHuffman_Info.sbFBit = 0;
1423 psLoad->sHuffman_Info.bFByte = 0;
1426 psTrack->dMtsqSize = psLoad->sHuffman_Info.dSeqSize;
1427 psTrack->dMtsqSize = psLoad->sHuffman_Info.dMtsqSize;
1428 mm_file_retv_if_fails(__mmf_STSPCheck(psTrack), false);
1429 mm_file_retv_if_fails(__mmf_SeqDataCheck3(psLoad, AV_MMF_SMAF_TYPE_MA3), false);
1431 psLoad->dPlayTime = psTrack->dPlayTime;
1432 psLoad->dStartTime = psTrack->dStartTick;
1433 psLoad->dTimeBase = psTrack->dTimeBase;
1435 debug_msg(RELEASE, "Play time: %u\n", psLoad->dPlayTime);
1440 static bool __mmf_CheckM5P(PLOADINFO psLoad)
1445 unsigned char *pbOpda, *pbM5p;
1446 unsigned int dOSize, dMSize, dIndex, dPhraseFlag, i;
1447 unsigned int dChunkID, dChunkNo, dChunkSize;
1449 psOptn = &(psLoad->sOption_Info);
1450 psTrk = &(psLoad->sTrack_Info[6]);
1451 psPhr = &(psLoad->sPhrase_Info[0]);
1452 pbOpda = psOptn->pbOpda;
1453 dOSize = psOptn->dOpdaSize;
1458 /* search Pro5 Chunk */
1459 while (dOSize > (dIndex + AV_MMF_CHUNK_HEADER_SIZE)) {
1460 if (!__mmf_MalibNextChunk(&pbOpda[dIndex], (dOSize - dIndex), AVMALIB_CHUNK_PHASE_OPDASUB, &dChunkID, &dChunkNo, &dChunkSize))
1463 dIndex += AV_MMF_CHUNK_HEADER_SIZE;
1464 if ((dChunkID == AVMALIB_CHUNKCODE_M5P) && (dChunkNo == 0x05)) {
1465 pbM5p = &pbOpda[dIndex];
1466 dMSize = dChunkSize;
1469 dIndex += dChunkSize;
1472 if ((pbM5p == NULL) || (dMSize < 12))
1475 dPhraseFlag = _mmf_Get4Byte(&pbM5p[0]);
1476 psTrk->dStartTick = _mmf_Get4Byte(&pbM5p[4]); /* start point */
1477 psTrk->dStopTick = _mmf_Get4Byte(&pbM5p[8]); /* stop point */
1480 if (psTrk->dStartTick >= psTrk->dStopTick)
1483 for (i = 0; i < AV_MMF_MAX_PHRASE_INFO; i++) {
1484 if (dMSize < (dIndex + 8)) break;
1485 if (dPhraseFlag & (0x80000000 >> i)) {
1486 psPhr[i].dStartTick = _mmf_Get4Byte(&pbM5p[dIndex]);
1487 psPhr[i].dStopTick = _mmf_Get4Byte(&pbM5p[dIndex + 4]);
1488 if (psPhr[i].dStartTick >= psPhr[i].dStopTick) {
1489 psPhr[i].dStartTick = AV_MMF_STSP_TIME_NULL;
1490 psPhr[i].dStopTick = AV_MMF_STSP_TIME_NULL;
1492 if (psPhr[i].dStartTick < psTrk->dStartTick)
1493 psPhr[i].dStartTick = psTrk->dStartTick;
1494 if (psPhr[i].dStopTick > psTrk->dStopTick)
1495 psPhr[i].dStopTick = psTrk->dStopTick;
1502 static bool __mmf_TrackChunkCheck5(PLOADINFO psLoad)
1506 mm_file_retv_if_fails(psLoad->sTrack_Info[6].pbMtr, false);
1508 psTrack = &(psLoad->sTrack_Info[6]);
1509 mm_file_retv_if_fails(psTrack->dMtrSize > AV_MMF_MINIMUM_TRACKSIZE3, false);
1510 mm_file_retv_if_fails(__mmf_MTRCheck(psTrack, AV_MMF_SMAF_TYPE_MA5), false);
1512 psLoad->sHuffman_Info.psBuffer = psTrack->pbMtsq;
1513 psLoad->sHuffman_Info.dMtsqSize = psTrack->dMtsqSize;
1514 psLoad->sHuffman_Info.dSeqSize = psTrack->dMtsqSize;
1515 psLoad->sHuffman_Info.dReadSize = 0;
1516 psLoad->pfnGetByte = __mmf_GetByte3L;
1518 mm_file_retv_if_fails(__mmf_SeqDataCheck3(psLoad, AV_MMF_SMAF_TYPE_MA5), false);
1520 psLoad->dPlayTime = psTrack->dPlayTime;
1521 psLoad->dStartTime = psTrack->dStartTick;
1522 psLoad->dTimeBase = psTrack->dTimeBase;
1524 debug_msg(RELEASE, "Play time: %u\n", psLoad->dPlayTime);
1530 static void __mmf_GetHvData(PLOADINFO psLoad, unsigned char bCType)
1532 unsigned char *pbHvData;
1533 unsigned int dHvDataSize;
1535 unsigned char *pbVoice;
1536 unsigned char *pbScript;
1537 unsigned char *pbSetup;
1538 unsigned int dVoiceSize, dScriptSize, dSetupSize, dIndex;
1539 unsigned char bHvCh;
1540 unsigned short wTag, wSize;
1542 unsigned int dChunkID, dChunkNo, dChunkSize;
1544 if ((psLoad->dSmafType == AV_MMF_SMAF_TYPE_MA1) || (psLoad->dSmafType == AV_MMF_SMAF_TYPE_MA2))
1547 if ((bCType & 0x0F) == 0x08)
1550 if (psLoad->dSmafType == AV_MMF_SMAF_TYPE_MA3) {
1551 pbHvData = psLoad->sTrack_Info[5].pbMthv;
1552 dHvDataSize = psLoad->sTrack_Info[5].dMthvSize;
1554 pbHvData = psLoad->sTrack_Info[6].pbMthv;
1555 dHvDataSize = psLoad->sTrack_Info[6].dMthvSize;
1558 if ((pbHvData == NULL) || (dHvDataSize < AV_MMF_CHUNK_HEADER_SIZE))
1567 bHvCh = AV_MMF_HV_CHANNEL_NULL;
1570 while (dHvDataSize > (dIndex + AV_MMF_CHUNK_HEADER_SIZE)) {
1571 if (!__mmf_MalibNextChunk(&(pbHvData[dIndex]), (dHvDataSize - dIndex), AVMALIB_CHUNK_PHASE_MTHVSUB, &dChunkID, &dChunkNo, &dChunkSize))
1574 dIndex += AV_MMF_CHUNK_HEADER_SIZE;
1576 case AVMALIB_CHUNKCODE_MHVS:
1577 pbSetup = &(pbHvData[dIndex]);
1578 dSetupSize = dChunkSize;
1580 case AVMALIB_CHUNKCODE_HVP:
1583 pbVoice = &(pbHvData[dIndex - AV_MMF_CHUNK_HEADER_SIZE]);
1584 dVoiceSize = dChunkSize + AV_MMF_CHUNK_HEADER_SIZE;
1586 case AVMALIB_CHUNKCODE_MHSC:
1587 pbScript = &(pbHvData[dIndex]);
1588 dScriptSize = dChunkSize;
1593 dIndex += dChunkSize;
1596 if (pbSetup == NULL) {
1597 debug_error(DEBUG, "pbSetup is NULL.\n");
1602 while (dSetupSize >= dIndex + 4) {
1603 wTag = (unsigned short)(((unsigned short)(pbSetup[dIndex]) << 8) + pbSetup[dIndex + 1]);
1604 wSize = (unsigned short)(((unsigned short)(pbSetup[dIndex + 2]) << 8) + pbSetup[dIndex + 3]);
1606 if (dSetupSize < (dIndex + wSize))
1608 if ((wTag == 0x4348) && (wSize == 1))
1609 bHvCh = pbSetup[dIndex];
1613 if ((pbScript == NULL) || (bHvCh >= AV_MMF_HV_CHANNEL_NULL))
1616 psLoad->sHV_Info.pbVoice = pbVoice;
1617 psLoad->sHV_Info.dVoiceSize = dVoiceSize;
1618 psLoad->sHV_Info.pbScript = pbScript;
1619 psLoad->sHV_Info.dScriptSize = dScriptSize;
1620 psLoad->sHV_Info.bHvChannel = bHvCh;
1624 static unsigned short __mmf_MalibMakeCRC(unsigned int dSize, unsigned char *pbData)
1626 unsigned short wRes = 0xFFFFU;
1627 unsigned char bData;
1629 while (--dSize >= 2) {
1631 wRes = (unsigned short)((wRes << 8) ^ g_crc_tbl[(unsigned char)(wRes >> 8) ^ bData]);
1634 return (unsigned short)(~wRes & 0xFFFFU);
1637 static int __mmf_MALoad(unsigned char *pbFile, unsigned int dFSize)
1639 PLOADINFO psLoad_Info;
1640 unsigned int bNo = 0;
1641 unsigned int dChunkID = 0, dChunkNo = 0, dChunkSize = 0;
1642 unsigned char *pbBuf = NULL;
1643 unsigned int dSize = 0, dIndex = 0;
1644 unsigned int dCalcCrc = 0, dFileCrc = 0;
1649 psLoad_Info = &(g_sSmaf_Info.sLoad_Info[bNo]);
1650 _mmf_CheckInitial(psLoad_Info);
1652 /* check File Chunk(ID/Size) */
1653 if (!__mmf_MalibNextChunk(pbBuf, dSize, AVMALIB_CHUNK_PHASE_MMMD, &dChunkID, &dChunkNo, &dChunkSize)
1654 || dChunkID != AVMALIB_CHUNKCODE_MMMD)
1657 dSize = dChunkSize + AV_MMF_CHUNK_HEADER_SIZE;
1658 dCalcCrc = AV_MMF_CRC_NULL;
1660 dCalcCrc = __mmf_MalibMakeCRC(dSize, pbBuf);
1661 dFileCrc = (unsigned int)((((unsigned int)pbBuf[dSize - 2]) << 8) + pbBuf[dSize - 1]);
1662 if (dCalcCrc != dFileCrc) {
1667 /* check Contents Info Chunk */
1668 dIndex = AV_MMF_CHUNK_HEADER_SIZE;
1669 if (!__mmf_MalibNextChunk(&pbBuf[dIndex], (dSize - dIndex), AVMALIB_CHUNK_PHASE_CNTI, &dChunkID, &dChunkNo, &dChunkSize)
1671 || dChunkID != AVMALIB_CHUNKCODE_CNTI)
1674 /* check Contents Class */
1675 if ((pbBuf[AV_MMF_POSITION_OF_CCLASS] != AV_MMF_CONTENTS_CLASS_0) &&
1676 (pbBuf[AV_MMF_POSITION_OF_CCLASS] != AV_MMF_CONTENTS_CLASS_1) &&
1677 (pbBuf[AV_MMF_POSITION_OF_CCLASS] != AV_MMF_CONTENTS_CLASS_2)) {
1681 /* check Contents Type */
1682 dIndex += AV_MMF_CHUNK_HEADER_SIZE;
1683 if (((pbBuf[AV_MMF_POSITION_OF_CTYPE] & 0xF0) == AV_MMF_CONTENTS_TYPE_0) ||
1684 ((pbBuf[AV_MMF_POSITION_OF_CTYPE] & 0xF0) == AV_MMF_CONTENTS_TYPE_1) ||
1685 ((pbBuf[AV_MMF_POSITION_OF_CTYPE] & 0xF0) == AV_MMF_CONTENTS_TYPE_2)) {
1686 psLoad_Info->dSmafType = AV_MMF_SMAF_TYPE_MA2;
1687 } else if (((pbBuf[AV_MMF_POSITION_OF_CTYPE] & 0xF0) == AV_MMF_CONTENTS_TYPE_3) ||
1688 ((pbBuf[AV_MMF_POSITION_OF_CTYPE] & 0xF0) == AV_MMF_CONTENTS_TYPE_4) ||
1689 ((pbBuf[AV_MMF_POSITION_OF_CTYPE] & 0xF0) == AV_MMF_CONTENTS_TYPE_5)) {
1690 switch (pbBuf[AV_MMF_POSITION_OF_CTYPE] & 0x0F) {
1693 psLoad_Info->dSmafType = AV_MMF_SMAF_TYPE_MA2;
1697 psLoad_Info->dSmafType = AV_MMF_SMAF_TYPE_MA3;
1704 psLoad_Info->dSmafType = AV_MMF_SMAF_TYPE_MA5;
1713 /* get pointer & size of option information */
1714 psLoad_Info->sOption_Info.pbCnti = &pbBuf[dIndex];
1715 psLoad_Info->sOption_Info.dCntiSize = dChunkSize;
1716 dIndex += dChunkSize;
1718 if (pbBuf[AV_MMF_POSITION_OF_CTYPE] >= 0x30) {
1719 if (__mmf_MalibNextChunk(&pbBuf[dIndex], (dSize - dIndex), AVMALIB_CHUNK_PHASE_MMMDSUB, &dChunkID, &dChunkNo, &dChunkSize)
1721 && dChunkID == AVMALIB_CHUNKCODE_OPDA) {
1722 dIndex += AV_MMF_CHUNK_HEADER_SIZE;
1723 psLoad_Info->sOption_Info.pbOpda = &pbBuf[dIndex];
1724 psLoad_Info->sOption_Info.dOpdaSize = dChunkSize;
1725 dIndex += dChunkSize;
1729 /* get Track Chunk information */
1730 while (dSize > (dIndex + AV_MMF_CHUNK_HEADER_SIZE + AV_MMF_FILE_CRC_SIZE)) {
1731 if (!__mmf_MalibNextChunk(&pbBuf[dIndex], (dSize - dIndex), AVMALIB_CHUNK_PHASE_MMMDSUB, &dChunkID, &dChunkNo, &dChunkSize))
1734 dIndex += AV_MMF_CHUNK_HEADER_SIZE;
1736 case AVMALIB_CHUNKCODE_MTR:
1739 psLoad_Info->sTrack_Info[dChunkNo].pbMtr = &(pbBuf[dIndex]);
1740 psLoad_Info->sTrack_Info[dChunkNo].dMtrSize = dChunkSize;
1742 case AVMALIB_CHUNKCODE_ATR:
1745 psLoad_Info->sTrack_Info[AV_MMF_ATR_TRACK_NO].pbMtr = &(pbBuf[dIndex]);
1746 psLoad_Info->sTrack_Info[AV_MMF_ATR_TRACK_NO].dMtrSize = dChunkSize;
1751 dIndex += dChunkSize;
1754 /* Error Check of Track Chunk */
1755 switch (psLoad_Info->dSmafType) {
1756 case AV_MMF_SMAF_TYPE_MA2:
1757 mm_file_retvm_if_fails(DEBUG, __mmf_TrackChunkCheck2(psLoad_Info), -1);
1759 case AV_MMF_SMAF_TYPE_MA3:
1760 mm_file_retvm_if_fails(DEBUG, __mmf_TrackChunkCheck3(psLoad_Info), -1);
1763 mm_file_retvm_if_fails(DEBUG, __mmf_CheckM5P(psLoad_Info), -1);
1764 mm_file_retvm_if_fails(DEBUG, __mmf_TrackChunkCheck5(psLoad_Info), -1);
1768 debug_msg(RELEASE, "SUM %u\n", psLoad_Info->dPlayTime * psLoad_Info->dTimeBase);
1770 rVal = psLoad_Info->dPlayTime * psLoad_Info->dTimeBase;
1771 mm_file_retvm_if_fails(DEBUG, rVal > AV_MMF_PLAY_TIME_MIN && rVal < AV_MMF_PLAY_TIME_MAX, -1);
1773 __mmf_GetHvData(psLoad_Info, pbBuf[AV_MMF_POSITION_OF_CTYPE]);
1775 psLoad_Info->pbMmmd = pbBuf;
1776 psLoad_Info->dMmmdSize = dSize;
1777 psLoad_Info->dCrc = dCalcCrc;
1782 static bool __mmf_RenewalProfile(unsigned char *pbFile)
1789 psLoad = &(g_sSmaf_Info.sLoad_Info[1]);
1790 psOptn = &(psLoad->sOption_Info);
1791 psTrk = &(psLoad->sTrack_Info[5]);
1792 psHuf = &(psLoad->sHuffman_Info);
1794 /* renew pointer offset to pointer */
1795 psLoad->pbMmmd = pbFile;
1796 psLoad->dCrc = AV_MMF_CRC_NULL;
1798 psOptn->pbCnti = &(pbFile[(unsigned int)psOptn->pbCnti]);
1799 psOptn->pbOpda = &(pbFile[(unsigned int)psOptn->pbOpda]);
1801 psTrk->pbMtr = &(pbFile[(unsigned int)psTrk->pbMtr]);
1802 psTrk->pbMspi = &(pbFile[(unsigned int)psTrk->pbMspi]);
1803 psTrk->pbMtsu = &(pbFile[(unsigned int)psTrk->pbMtsu]);
1804 psTrk->pbMtsq = &(pbFile[(unsigned int)psTrk->pbMtsq]);
1805 psTrk->pbMtsp = &(pbFile[(unsigned int)psTrk->pbMtsp]);
1807 /* Initialize Huffman information structure */
1808 psHuf->psBuffer = psTrk->pbMtsq;
1809 psHuf->dMtsqSize = psTrk->dMtsqSize;
1811 if (psTrk->pbMtr[0] == 0x01) {
1812 psHuf->dSeqSize = __mmf_DecodeInit(psHuf);
1813 if (psHuf->dSeqSize == 0)
1817 psHuf->psFBuf = psHuf->psBuffer;
1818 psHuf->sbFBit = psHuf->sbBitC;
1819 psHuf->bFByte = psHuf->bByte;
1824 static bool __mmf_ParseSkipXmf2Mmf(unsigned char *pbFile, unsigned int dFSize, unsigned int *pdSkipOffSet)
1826 unsigned int skipVal = 0, sizeOfpbFile = dFSize;
1830 memcpy(cmpXmfCMMD, pbFile, 4);
1832 debug_error(DEBUG, "NULL pointer!\n");
1838 if (strncmp(cmpXmfCMMD, "CMMD", 4) == 0) {
1840 if (pbFile[skipVal] == 'M' && pbFile[skipVal + 1] == 'M' && pbFile[skipVal + 2] == 'M' && pbFile[skipVal + 3] == 'D') {
1841 debug_msg(RELEASE, "MMMD Header found!\n");
1845 if (skipVal >= sizeOfpbFile) {
1846 debug_msg(RELEASE, "MMMD Header is not found!\n");
1853 debug_msg(RELEASE, "File header is not started CMMD\n");
1856 debug_msg(RELEASE, "skip value: %d\n", skipVal);
1857 *pdSkipOffSet = skipVal;
1862 static int __mmf_file_mmf_get_duration(char *src, int is_xmf)
1865 unsigned int xmf_skip_offset = 0;
1866 MMFileIOHandle *fp = NULL;
1867 unsigned char *buf = 0;
1868 long long src_size = 0L;
1870 PLOADINFO load_info;
1871 unsigned char *p_crc = NULL;
1872 unsigned int dCrc = 0;
1875 /*total time (millisecond)*/
1878 debug_fenter(RELEASE);
1881 ret = mmfile_open(&fp, src, MMFILE_RDONLY);
1882 if (ret == MMFILE_UTIL_FAIL) {
1883 debug_error(DEBUG, "open failed.\n");
1888 src_size = mmfile_get_size(fp);
1889 if (src_size <= 0) {
1890 debug_error(DEBUG, "failed to get file size.\n");
1892 goto _RELEASE_RESOURCE;
1895 /*alloc work buffer*/
1896 buf = g_malloc0(src_size + 1);
1899 if ((readed = mmfile_read(fp, buf, src_size)) <= 0) {
1900 debug_error(DEBUG, "read error. size = %d\n", readed);
1903 goto _RELEASE_RESOURCE;
1906 /*if XMF, get skip offset.*/
1908 if (!__mmf_ParseSkipXmf2Mmf(buf, src_size, &xmf_skip_offset)) {
1910 goto _RELEASE_RESOURCE;
1914 if (g_sSmaf_Info.dStatus == AV_MMF_STATUS_SAT_PROFILE) {
1915 load_info = &(g_sSmaf_Info.sLoad_Info[1]);
1916 if (load_info->dMmmdSize <= src_size) {
1917 p_crc = &(buf[load_info->dMmmdSize - 2 + xmf_skip_offset]);
1918 dCrc = (unsigned int)((((unsigned int)p_crc[0]) << 8) + (unsigned int)p_crc[1]);
1920 dCrc = AV_MMF_CRC_NULL;
1923 if (dCrc == load_info->dCrc) {
1924 if (__mmf_RenewalProfile(buf + xmf_skip_offset)) {
1925 g_sSmaf_Info.dStatus = AV_MMF_STATUS_LOADED;
1927 goto _RELEASE_RESOURCE;
1932 ret_msec = __mmf_MALoad(buf + xmf_skip_offset, src_size);