76af91fa5a2f2940d81f12795aee3d1ae0739109
[platform/core/multimedia/libmm-fileinfo.git] / formats / ffmpeg / mm_file_format_aac.c
1 /*
2  * libmm-fileinfo
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Haejeong Kim <backto.kim@samsung.com>
7  *
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
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
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.
19  *
20  */
21
22 #include <stdio.h>
23 #include <string.h>     /*memcmp*/
24 #include <stdlib.h>     /*malloc*/
25
26 #include <mm_error.h>
27
28 #include "mm_file_debug.h"
29 #include "mm_file_utils.h"
30 #include "mm_file_format_private.h"
31 #include "mm_file_format_aac.h"
32
33
34 /* Internal Error Type */
35 #define MMFILE_AAC_PARSER_FILE_END 2
36
37 /* Media specific definations */
38 #define MMFILE_AAC_ADIF_HEADER_MAX_SIZE 30
39 #define MMFILE_AAC_ADTS_HEADER_MAX_SIZE 7
40 #define AAC_ADTS_FRAME_LEN_OFFSET 30
41 #define AAC_ADTS_SAMPLES_PER_FRAME 1024
42
43 #define IS_AAC_ADIF_HEADER(buff) (!(memcmp((buff), "ADIF", 4)))
44 #define IS_AAC_ADTS_HEADER(buff) (((buff)[0] == 0xff) && (((buff)[1] & 0xf0) == 0xf0))
45
46
47 /* Array to Number conversions */
48 #define GET_INT_NUMBER(buff) (int)((((int)(buff)[0]) << 24) | \
49                                     (((int)(buff)[1]) << 16) | \
50                                     (((int)(buff)[2]) << 8) | \
51                                     (((int)(buff)[3])))
52
53 #define GET_SHORT_NUMBER(buff) (short)(((short)(buff)[0] << 8) | \
54                                         ((short)(buff)[1]))
55
56
57
58 typedef enum _mmfile_aac_format_type {
59         AAC_FORMAT_ADIF,
60         AAC_FORMAT_ADTS,
61         AAC_FORMAT_UNKNOWN
62 } TAacFormatType;
63
64 typedef enum _mmfile_aac_bitstream_type {
65         AAC_STREAM_CONSTANT,
66         AAC_STREAM_VARIABLE
67 } TAacStreamType;
68
69 typedef enum _mmfile_aac_mpeg_type {
70         AAC_MPEG_4,
71         AAC_MPEG_2
72 } TAacMpegType;
73
74 typedef struct _mmfile_aac_handle {
75         MMFileIOHandle         *hFile;
76         AvFileContentInfo       id3Handle;
77         unsigned int            streamOffset;
78         unsigned int            tagOffset;
79         char                    isTagPresent;
80         unsigned int            tagInfoSize;
81         unsigned char           tagVersion;
82         TAacFormatType          formatType;
83         TAacStreamType          streamType;
84         TAacMpegType            mpegType;
85         tMMFILE_AAC_STREAM_INFO streamInfo;
86         tMMFILE_AAC_TAG_INFO    tagInfo;
87 } tMMFILE_AAC_HANDLE;
88
89
90 /*Index table for Sampling frequency */
91 const int Sampling_freq_table[16] = { 96000, 88200,  64000, 48000,
92                                       44100, 32000,  24000, 22050,
93                                       16000, 12000,  11025, 8000,
94                                       0,     0,      0,     0
95                                     };
96
97 /* internal APIs */
98 void _aac_init_handle(tMMFILE_AAC_HANDLE *privateData);
99 int _search_id3tag(tMMFILE_AAC_HANDLE *pData);
100 int _parse_id3_tag(tMMFILE_AAC_HANDLE *pData);
101 int _get_range_bits_value(unsigned char *buff, int fieldOffset, int fieldSize);
102 int _parse_aac_adif_header(tMMFILE_AAC_HANDLE *pData);
103 int _get_next_adts_frame_length(tMMFILE_AAC_HANDLE *pData, int *frameLen);
104 int _parse_aac_adts_header(tMMFILE_AAC_HANDLE *pData);
105
106
107 void _aac_init_handle(tMMFILE_AAC_HANDLE *privateData)
108 {
109         /* Default Initializations */
110         privateData->streamOffset = 0;
111         privateData->isTagPresent = FALSE;
112         privateData->streamOffset = 0;
113         privateData->tagOffset = 0;
114
115         privateData->streamInfo.fileSize = 0;
116         privateData->streamInfo.duration = 0;
117         privateData->streamInfo.bitRate = 0;
118         privateData->streamInfo.samplingRate = 0;
119         privateData->streamInfo.frameRate = 0;
120         privateData->streamInfo.numAudioChannels = 0;
121         privateData->streamInfo.numTracks = 1;
122         privateData->streamInfo.profileType = 0;
123
124         privateData->tagInfo.title = NULL;
125         privateData->tagInfo.author = NULL;
126         privateData->tagInfo.artist = NULL;
127         privateData->tagInfo.album = NULL;
128         privateData->tagInfo.album_artist = NULL;
129         privateData->tagInfo.year = NULL;
130         privateData->tagInfo.copyright = NULL;
131         privateData->tagInfo.comment = NULL;
132         privateData->tagInfo.genre = NULL;
133         privateData->tagInfo.composer = NULL;
134         privateData->tagInfo.classification = NULL;
135         privateData->tagInfo.rating = NULL;
136         privateData->tagInfo.recordDate = NULL;
137         privateData->tagInfo.conductor = NULL;
138         privateData->tagInfo.artwork = NULL;
139         privateData->tagInfo.artworkSize = 0;
140         privateData->tagInfo.artworkMime = NULL;
141 }
142
143
144 int _search_id3tag(tMMFILE_AAC_HANDLE *pData)
145 {
146         unsigned char tagHeader[MP3_TAGv2_HEADER_LEN] = {0, };
147         int encSize = 0;
148         int readed = 0;
149
150         mmfile_seek(pData->hFile, 0, MMFILE_SEEK_SET);
151         readed = mmfile_read(pData->hFile, tagHeader, MP3_TAGv2_HEADER_LEN);
152         if (MP3_TAGv2_HEADER_LEN != readed) {
153 #ifdef __MMFILE_TEST_MODE__
154                 debug_msg("Read Fail");
155 #endif
156                 return MMFILE_AAC_PARSER_FAIL;
157         }
158
159         if (!IS_ID3V2_TAG(tagHeader)) {
160 #ifdef __MMFILE_TEST_MODE__
161                 debug_msg("No ID3 Tag");
162 #endif
163                 goto search_end;
164         }
165
166         if (tagHeader[3] == 0xFF ||  tagHeader[4] == 0xFF ||
167             tagHeader[6] >= 0x80 ||  tagHeader[7] >= 0x80 ||
168             tagHeader[8] >= 0x80 ||  tagHeader[9] >= 0x80) {
169 #ifdef __MMFILE_TEST_MODE__
170                 debug_msg("Read Fail");
171 #endif
172                 return MMFILE_AAC_PARSER_FAIL;
173         }
174
175         pData->tagVersion = tagHeader[3];
176
177         if (pData->tagVersion > 4) {
178 #ifdef __MMFILE_TEST_MODE__
179                 debug_msg("\nTag version not supported");
180 #endif
181                 return MMFILE_AAC_PARSER_FAIL;
182         }
183
184         encSize = GET_INT_NUMBER(&tagHeader[6]);
185         pData->tagInfoSize = MP3_TAGv2_HEADER_LEN;
186
187         pData->tagInfoSize += (((encSize & 0x0000007F) >> 0) | ((encSize & 0x00007F00) >> 1) |  \
188                                ((encSize & 0x007F0000) >> 2) | ((encSize & 0x7F000000) >> 3));
189
190         if (pData->tagInfoSize > pData->streamInfo.fileSize) {
191 #ifdef __MMFILE_TEST_MODE__
192                 debug_msg("Invalid size");
193 #endif
194                 return MMFILE_AAC_PARSER_FAIL;
195         }
196
197         pData->isTagPresent = TRUE;
198         pData->tagOffset = 0;
199         pData->streamOffset = pData->tagInfoSize;
200
201         /* Filling the information in id3Handle for tag parsing */
202         pData->id3Handle.fileLen = pData->streamInfo.fileSize;
203         pData->id3Handle.tagV2Info.tagLen = pData->tagInfoSize;
204         pData->id3Handle.tagV2Info.tagVersion = pData->tagVersion;
205         pData->id3Handle.tagV2Info.tagLen = pData->tagInfoSize;
206
207 search_end:
208         return MMFILE_AAC_PARSER_SUCCESS;
209 }
210
211
212 int _parse_id3_tag(tMMFILE_AAC_HANDLE *pData)
213 {
214         unsigned char *tagBuff = NULL;
215         AvFileContentInfo *hTag = &pData->id3Handle;
216         int ret = FALSE;
217         int readed = 0;
218
219         mmfile_seek(pData->hFile, pData->tagOffset, MMFILE_SEEK_SET);
220         tagBuff = (unsigned char *) mmfile_malloc(hTag->fileLen);
221         if (tagBuff == NULL) {
222                 ret = MMFILE_AAC_PARSER_FAIL;
223                 debug_error("failed to memory allocation. %d\n", hTag->fileLen);
224                 goto failure;
225         }
226
227         readed = mmfile_read(pData->hFile, tagBuff, hTag->fileLen);
228         if (readed != hTag->fileLen) {
229                 debug_error("failed to read. %d, %lld\n", readed, hTag->fileLen);
230                 goto failure;
231         }
232
233         switch (hTag->tagV2Info.tagVersion) {
234                 case 1:
235                         ret = mm_file_id3tag_parse_v110(hTag, tagBuff);
236                         break;
237                 case 2:
238                         ret = mm_file_id3tag_parse_v222(hTag, tagBuff);
239                         break;
240                 case 3:
241                         ret = mm_file_id3tag_parse_v223(hTag, tagBuff);
242                         break;
243                 case 4:
244                         ret = mm_file_id3tag_parse_v224(hTag, tagBuff);
245                         break;
246                 default:
247                         debug_error("Invalid Tag version [%d]\n", hTag->tagV2Info.tagVersion);
248                         break;
249         }
250
251         if (ret == FALSE) {
252                 ret = MMFILE_AAC_PARSER_FAIL;
253                 debug_warning("failed to parse\n");
254                 goto failure;
255         }
256
257         mm_file_id3tag_restore_content_info(hTag);
258
259         pData->tagInfo.title = hTag->pTitle;
260         pData->tagInfo.author = hTag->pAuthor;
261         pData->tagInfo.artist = hTag->pArtist;
262         pData->tagInfo.album = hTag->pAlbum;
263         pData->tagInfo.album_artist = hTag->pAlbum_Artist;
264         pData->tagInfo.year = hTag->pYear;
265         pData->tagInfo.copyright = hTag->pCopyright;
266         pData->tagInfo.comment = hTag->pComment;
267         pData->tagInfo.genre = hTag->pGenre;
268         pData->tagInfo.tracknum = hTag->pTrackNum;
269         pData->tagInfo.composer = hTag->pComposer;
270         pData->tagInfo.classification = hTag->pContentGroup;
271         pData->tagInfo.rating = hTag->pRating;
272         pData->tagInfo.recordDate = hTag->pRecDate;
273         pData->tagInfo.conductor = hTag->pConductor;
274         pData->tagInfo.artworkMime = hTag->imageInfo.imageMIMEType;
275         pData->tagInfo.artworkSize = hTag->imageInfo.imageLen;
276         pData->tagInfo.artwork = hTag->imageInfo.pImageBuf;
277
278         ret = MMFILE_AAC_PARSER_SUCCESS;
279
280
281 failure:
282         if (tagBuff) {
283                 mmfile_free(tagBuff);
284                 tagBuff = NULL;
285         }
286
287         return ret;
288
289 }
290
291
292 int _get_range_bits_value(unsigned char *buff, int fieldOffset, int fieldSize)
293 {
294         int pos = 0;
295         unsigned int srcByteStartOff = 0;
296         unsigned int srcByteEndOff = 0;
297         unsigned int srcBitStartOff = 0;
298         unsigned int srcBitEndOff = 0;
299         unsigned char dest[4] = {0, };
300         unsigned int res = 0;
301         unsigned int i, j, temp;
302         unsigned char extraByteFlag = 0;
303         unsigned int occupiedBytes = 0;
304         unsigned char mask = 0, maskBit = 0x01;
305
306
307         srcByteStartOff = (fieldOffset / 8);
308         srcBitStartOff = (fieldOffset % 8);
309
310         srcByteEndOff = ((fieldOffset + fieldSize - 1) / 8);
311         srcBitEndOff = ((fieldOffset + fieldSize - 1) % 8);
312
313         occupiedBytes = srcByteEndOff - srcByteStartOff + 1;
314
315         for (i = srcByteStartOff, j = 0; i <= srcByteEndOff && j <= 3; i++, j++) {
316                 dest[j] = buff[i];
317         }
318
319         for (pos = 7; pos >= (char)srcBitStartOff; pos--) {
320                 mask = mask | maskBit;
321                 maskBit <<= 1;
322         }
323
324         dest[0] = dest[0] & mask;
325
326         if (i <= srcByteEndOff) {
327                 extraByteFlag = 1;
328         }
329
330         res = GET_INT_NUMBER(dest);
331
332         if (!extraByteFlag) {
333                 temp = (4 - occupiedBytes) * 8 + (7 - srcBitEndOff);
334                 res >>= temp;
335         }
336
337         if (extraByteFlag) {
338                 res <<= srcBitStartOff;
339                 temp = buff[srcByteEndOff] >> (7 - srcBitEndOff);
340                 res = res | (unsigned int)temp;
341         }
342
343         return res;
344 }
345
346
347 int _parse_aac_adif_header(tMMFILE_AAC_HANDLE *pData)
348 {
349         unsigned char adifHeader[MMFILE_AAC_ADIF_HEADER_MAX_SIZE] = {0, };
350         int currentBitOffset = 0;
351         unsigned int fieldValue = 0;
352         int copyRightStatus = 0;
353         int readed = 0;
354
355         mmfile_seek(pData->hFile, pData->streamOffset, MMFILE_SEEK_SET);
356         readed = mmfile_read(pData->hFile, adifHeader, MMFILE_AAC_ADIF_HEADER_MAX_SIZE);
357         if (readed < 0) {
358                 return MMFILE_AAC_PARSER_FAIL;
359         }
360
361         if (memcmp(adifHeader, "ADIF", 4) != 0) {
362                 return MMFILE_AAC_PARSER_FAIL;
363         }
364         currentBitOffset += 32;
365
366         copyRightStatus = _get_range_bits_value(adifHeader, currentBitOffset, 1);
367         currentBitOffset += 1;
368
369         if (copyRightStatus) {
370                 /*skipping Copyright info */
371                 currentBitOffset += 72;
372         }
373
374         /*Original/copy */
375         fieldValue = _get_range_bits_value(adifHeader, currentBitOffset, 1);
376         currentBitOffset += 1;
377
378         /*skipping Home status */
379         currentBitOffset += 1;
380
381         /*Bit stream type */
382         fieldValue = _get_range_bits_value(adifHeader, currentBitOffset, 1);
383         currentBitOffset += 1;
384         if (!fieldValue) {
385                 pData->streamType = AAC_STREAM_CONSTANT;
386         } else {
387                 pData->streamType = AAC_STREAM_VARIABLE;
388         }
389
390         /*Bit-rate */
391         pData->streamInfo.bitRate = _get_range_bits_value(adifHeader, currentBitOffset, 23);
392         currentBitOffset += 23;
393
394         /*Num of program config elements */
395         fieldValue = _get_range_bits_value(adifHeader, currentBitOffset, 4);
396         currentBitOffset += 4;
397
398         /*skipping adif buffer fullness */
399         currentBitOffset += 20;
400
401         /*skipping element instance tag */
402         currentBitOffset += 4;
403
404         /*Profile */
405         pData->streamInfo.profileType = _get_range_bits_value(adifHeader, currentBitOffset, 2);
406         currentBitOffset += 2;
407
408         /*sampling freq index */
409         fieldValue = _get_range_bits_value(adifHeader, currentBitOffset, 4);
410         currentBitOffset += 4;
411         pData->streamInfo.samplingRate = Sampling_freq_table[fieldValue];
412
413         /*num_front_channel_elements */
414         pData->streamInfo.numAudioChannels = _get_range_bits_value(adifHeader, currentBitOffset, 4);
415         currentBitOffset += 4;
416
417         /*num_side_channel_elements */
418         pData->streamInfo.numAudioChannels += _get_range_bits_value(adifHeader, currentBitOffset, 4);
419         currentBitOffset += 4;
420
421         /*num_back_channel_elements */
422         pData->streamInfo.numAudioChannels += _get_range_bits_value(adifHeader, currentBitOffset, 4);
423         currentBitOffset += 4;
424
425         /*num_lfe_channel_elements */
426         pData->streamInfo.numAudioChannels += _get_range_bits_value(adifHeader, currentBitOffset, 2);
427         currentBitOffset += 2;
428
429         return MMFILE_AAC_PARSER_SUCCESS;
430
431 }
432
433
434 int _parse_aac_adts_header(tMMFILE_AAC_HANDLE *pData)
435 {
436         unsigned char adtsHeader[MMFILE_AAC_ADTS_HEADER_MAX_SIZE] = {0, };
437         int currentBitOffset = 0;
438         unsigned int fieldValue = 0;
439         int readed = 0;
440
441         mmfile_seek(pData->hFile, pData->streamOffset, MMFILE_SEEK_SET);
442         readed = mmfile_read(pData->hFile, adtsHeader, MMFILE_AAC_ADTS_HEADER_MAX_SIZE);
443         if (readed < 0) {
444                 return MMFILE_AAC_PARSER_FAIL;
445         }
446
447         if (!IS_AAC_ADTS_HEADER(adtsHeader)) {
448                 return MMFILE_AAC_PARSER_FAIL;
449         }
450         currentBitOffset += 12;
451
452         /*adtsId */
453         fieldValue = _get_range_bits_value(adtsHeader, currentBitOffset, 1);
454         currentBitOffset += 1;
455         pData->mpegType = (fieldValue != 0);
456
457         /*LayerType */
458         fieldValue = _get_range_bits_value(adtsHeader, currentBitOffset, 2);
459         currentBitOffset += 2;
460
461         /*skipping Protection Absent */
462         currentBitOffset += 1;
463
464         /*ProfileType */
465         fieldValue = _get_range_bits_value(adtsHeader, currentBitOffset, 2);
466         currentBitOffset += 2;
467         pData->streamInfo.profileType = fieldValue;
468
469         /*SamplingrateIndex */
470         fieldValue = _get_range_bits_value(adtsHeader, currentBitOffset, 4);
471         currentBitOffset += 4;
472         pData->streamInfo.samplingRate = Sampling_freq_table[fieldValue];
473
474         /*skipping PrivateBit */
475         currentBitOffset += 1;
476
477         /*ChannelConfig */
478         pData->streamInfo.numAudioChannels = _get_range_bits_value(adtsHeader, currentBitOffset, 3);
479         currentBitOffset += 3;
480
481         /*Original/copy status */
482         fieldValue = _get_range_bits_value(adtsHeader, currentBitOffset, 1);
483         currentBitOffset += 1;
484
485         /*skipping Home status */
486         fieldValue = _get_range_bits_value(adtsHeader, currentBitOffset, 1);
487         currentBitOffset += 1;
488
489         /*copy right Id status bit */
490         currentBitOffset += 1;
491
492         return MMFILE_AAC_PARSER_SUCCESS;
493 }
494
495
496 int _get_next_adts_frame_length(tMMFILE_AAC_HANDLE *pData, int *frameLen)
497 {
498         unsigned char adtsHeader[MMFILE_AAC_ADTS_HEADER_MAX_SIZE] = {0, };
499         int ret = MMFILE_AAC_PARSER_SUCCESS;
500         long long filePosBefore = mmfile_tell(pData->hFile);
501         int readed = 0;
502
503         readed = mmfile_read(pData->hFile, adtsHeader, MMFILE_AAC_ADTS_HEADER_MAX_SIZE);
504         if (readed < 0)
505                 return MMFILE_AAC_PARSER_FAIL;
506
507 #ifdef __MMFILE_TEST_MODE__
508         debug_msg("\nFILE POS: %lld\n", filePosBefore);
509         debug_msg("\nADTS HEADER: [%2x] [%2x] [%2x] [%2x] [%2x] [%2x]\n",
510                   adtsHeader[0], adtsHeader[1], adtsHeader[2], adtsHeader[3], adtsHeader[4], adtsHeader[5]);
511 #endif
512
513         if (mmfile_tell(pData->hFile) >= pData->streamInfo.fileSize) {
514                 *frameLen = 0;
515                 ret = MMFILE_AAC_PARSER_FILE_END;
516                 goto function_end;
517         }
518
519         if (!IS_AAC_ADTS_HEADER(adtsHeader)) {
520                 *frameLen = 0;
521                 ret = MMFILE_AAC_PARSER_FAIL;
522                 goto function_end;
523         }
524
525         *frameLen = _get_range_bits_value(adtsHeader, AAC_ADTS_FRAME_LEN_OFFSET, 13);
526
527         if (*frameLen == 0 || *frameLen > (pData->streamInfo.fileSize - filePosBefore)) {
528                 *frameLen = 0;
529                 ret = MMFILE_AAC_PARSER_FAIL;
530                 goto function_end;
531         }
532
533 function_end:
534
535         mmfile_seek(pData->hFile, filePosBefore + *frameLen, MMFILE_SEEK_SET);
536
537         return ret;
538 }
539
540
541 int mmfile_aacparser_open(MMFileAACHandle *handle, const char *filenamec)
542 {
543         tMMFILE_AAC_HANDLE *privateData = NULL;
544         int ret = 0;
545         unsigned char header[4] = {0, };
546         int firstFrameLen = 0;
547         int readed = 0;
548
549         if (NULL == filenamec) {
550                 debug_error("file source is NULL\n");
551                 return MMFILE_AAC_PARSER_FAIL;
552         }
553
554         privateData = mmfile_malloc(sizeof(tMMFILE_AAC_HANDLE));
555         if (NULL == privateData) {
556                 debug_error("file source is NULL\n");
557                 return MMFILE_AAC_PARSER_FAIL;
558         }
559
560         ret = mmfile_open(&privateData->hFile, filenamec, MMFILE_RDONLY);
561         if (ret == MMFILE_UTIL_FAIL) {
562                 debug_error("error: mmfile_open\n");
563                 goto exception;
564         }
565
566         /* Initialize the members of handle */
567         _aac_init_handle(privateData);
568
569         mmfile_seek(privateData->hFile, 0, MMFILE_SEEK_END);
570         privateData->streamInfo.fileSize = mmfile_tell(privateData->hFile);
571
572         mmfile_seek(privateData->hFile, 0, MMFILE_SEEK_SET);
573
574         /* Search the existance of ID3 tag */
575         ret = _search_id3tag(privateData);
576         if (ret == MMFILE_AAC_PARSER_FAIL) {
577                 debug_error("Error in searching the ID3 tag\n");
578                 goto exception;
579         }
580
581         mmfile_seek(privateData->hFile, privateData->streamOffset, MMFILE_SEEK_SET);
582         readed = mmfile_read(privateData->hFile, header, 4);
583         if (readed != 4)
584                 goto exception;
585
586         if (IS_AAC_ADIF_HEADER(header)) {
587                 privateData->formatType = AAC_FORMAT_ADIF;
588
589 #ifdef __MMFILE_TEST_MODE__
590                 debug_msg("AAC Format: ADIF\n");
591 #endif
592
593         } else if (IS_AAC_ADTS_HEADER(header)) {
594                 privateData->formatType = AAC_FORMAT_ADTS;
595
596 #ifdef __MMFILE_TEST_MODE__
597                 debug_msg("AAC Format: ADTS\n");
598 #endif
599
600                 /* Verify whether the first frame size is proper */
601                 mmfile_seek(privateData->hFile, privateData->streamOffset, MMFILE_SEEK_SET);
602                 ret = _get_next_adts_frame_length(privateData, &firstFrameLen);
603                 if (ret == MMFILE_AAC_PARSER_FAIL) {
604                         debug_error("Invalid Frame length in ADTS header\n");
605                         goto exception;
606                 }
607         } else {
608                 privateData->formatType = AAC_FORMAT_UNKNOWN;
609                 debug_error("AAC Format: UNKNOWN\n");
610                 goto exception;
611         }
612
613         *handle = privateData;
614
615         return MMFILE_AAC_PARSER_SUCCESS;
616
617 exception:
618         if (privateData) {
619                 mmfile_close(privateData->hFile);
620                 mmfile_free(privateData);
621                 *handle = NULL;
622         }
623         return MMFILE_AAC_PARSER_FAIL;
624
625 }
626
627
628 int mmfile_aacparser_get_stream_info(MMFileAACHandle handle, tMMFILE_AAC_STREAM_INFO *aacinfo)
629 {
630         tMMFILE_AAC_HANDLE *privateData = NULL;
631         int frameLen = 0;
632         long long totalFrames = 0, totalFrameLength = 0;
633         unsigned long long streamDataSize = 0;
634         int ret = MMFILE_AAC_PARSER_SUCCESS;
635
636         if (NULL == handle || NULL == aacinfo) {
637                 debug_error("handle is NULL\n");
638                 return MMFILE_AAC_PARSER_FAIL;
639         }
640
641         privateData = (tMMFILE_AAC_HANDLE *) handle;
642
643         if (privateData->formatType == AAC_FORMAT_ADIF) {
644                 ret = _parse_aac_adif_header(privateData);
645                 aacinfo->iseekable = 0;
646         } else {
647                 ret = _parse_aac_adts_header(privateData);
648                 aacinfo->iseekable = 1;
649         }
650
651         if (ret == MMFILE_AAC_PARSER_FAIL) {
652                 debug_error("Error in parsing the stream header\n");
653                 return ret;
654         }
655
656         mmfile_seek(privateData->hFile, privateData->streamOffset, MMFILE_SEEK_SET);
657
658         if (privateData->formatType == AAC_FORMAT_ADTS) {
659
660                 while (TRUE) {
661                         ret = _get_next_adts_frame_length(privateData, &frameLen);
662                         if (ret != MMFILE_AAC_PARSER_SUCCESS) {
663                                 break;
664                         }
665                         totalFrameLength += frameLen - MMFILE_AAC_ADTS_HEADER_MAX_SIZE;
666                         totalFrames++;
667                 }
668
669                 if (ret == MMFILE_AAC_PARSER_FAIL) {
670                         debug_error("Found corrupted frames!!! Ignoring\n");
671                 }
672
673 #ifdef __MMFILE_TEST_MODE__
674                 debug_msg("No of ADTS frames: %d\n", totalFrames);
675 #endif
676                 privateData->streamInfo.frameRate = privateData->streamInfo.samplingRate / AAC_ADTS_SAMPLES_PER_FRAME;
677
678                 if (privateData->streamInfo.frameRate)
679                         privateData->streamInfo.duration = (totalFrames * 1000) / privateData->streamInfo.frameRate;
680                 else privateData->streamInfo.duration = 0;
681
682                 if (privateData->streamInfo.duration)
683                         privateData->streamInfo.bitRate = (totalFrameLength * 8 * 1000) / (privateData->streamInfo.duration);
684                 else privateData->streamInfo.bitRate = 0;
685
686         } else {
687                 streamDataSize = (unsigned long long)privateData->streamInfo.fileSize - privateData->tagInfoSize;
688                 privateData->streamInfo.duration = streamDataSize * 8 * 1000 / privateData->streamInfo.bitRate;
689         }
690
691         /* Return the stream info structure */
692         memcpy(aacinfo, &(privateData->streamInfo), sizeof(tMMFILE_AAC_STREAM_INFO));
693
694         return MMFILE_AAC_PARSER_SUCCESS;
695 }
696
697
698 int mmfile_aacparser_get_tag_info(MMFileAACHandle handle, tMMFILE_AAC_TAG_INFO *tagInfo)
699 {
700         tMMFILE_AAC_HANDLE *privateData = NULL;
701         int ret = 0;
702
703         if (NULL == handle || NULL == tagInfo) {
704                 debug_error("handle is NULL\n");
705                 return MMFILE_AAC_PARSER_FAIL;
706         }
707
708         privateData = (tMMFILE_AAC_HANDLE *) handle;
709         if (privateData->id3Handle.tagV2Info.tagVersion == 0) {
710                 debug_warning("There is no Tag info\n");
711                 return MMFILE_AAC_PARSER_SUCCESS;
712         }
713
714         ret = _parse_id3_tag(privateData);
715         if (ret == MMFILE_AAC_PARSER_FAIL) {
716                 debug_warning("Error in parsing the Tag info\n");
717                 return ret;
718         }
719
720         /* Return the tag info structure */
721         memcpy(tagInfo, &(privateData->tagInfo), sizeof(tMMFILE_AAC_TAG_INFO));
722
723         return MMFILE_AAC_PARSER_SUCCESS;
724 }
725
726
727 int mmfile_aacparser_close(MMFileAACHandle handle)
728 {
729         tMMFILE_AAC_HANDLE *privateData = NULL;
730
731         if (NULL == handle) {
732                 debug_error("handle is NULL\n");
733                 return MMFILE_AAC_PARSER_FAIL;
734         }
735
736         privateData = (tMMFILE_AAC_HANDLE *) handle;
737         mm_file_free_AvFileContentInfo(&privateData->id3Handle);
738
739         mmfile_close(privateData->hFile);
740
741         return MMFILE_AAC_PARSER_SUCCESS;
742 }
743
744
745 /* mm plugin interface */
746 int mmfile_format_read_stream_aac(MMFileFormatContext *formatContext);
747 int mmfile_format_read_frame_aac(MMFileFormatContext *formatContext, unsigned int timestamp, MMFileFormatFrame *frame);
748 int mmfile_format_read_tag_aac(MMFileFormatContext *formatContext);
749 int mmfile_format_close_aac(MMFileFormatContext *formatContext);
750
751
752 EXPORT_API
753 int mmfile_format_open_aac(MMFileFormatContext *formatContext)
754 {
755         MMFileAACHandle handle = NULL;
756         int res = MMFILE_FORMAT_FAIL;
757
758         if (NULL == formatContext || NULL == formatContext->uriFileName) {
759                 debug_error("error: mmfile_format_open_aac\n");
760                 return MMFILE_FORMAT_FAIL;
761         }
762
763         if (formatContext->pre_checked == 0) {
764                 res = MMFileFormatIsValidAAC(NULL, formatContext->uriFileName);
765                 if (res == 0) {
766                         debug_error("It is not AAC file\n");
767                         return MMFILE_FORMAT_FAIL;
768                 }
769         }
770
771         formatContext->ReadStream   = mmfile_format_read_stream_aac;
772         formatContext->ReadFrame    = mmfile_format_read_frame_aac;
773         formatContext->ReadTag      = mmfile_format_read_tag_aac;
774         formatContext->Close        = mmfile_format_close_aac;
775
776         formatContext->videoTotalTrackNum = 0;
777         formatContext->audioTotalTrackNum = 1;
778
779         res = mmfile_aacparser_open(&handle, formatContext->uriFileName);
780         if (MMFILE_AAC_PARSER_FAIL == res) {
781                 debug_error("mmfile_aacparser_open\n");
782                 return MMFILE_FORMAT_FAIL;
783         }
784
785         formatContext->privateFormatData = handle;
786
787         return MMFILE_FORMAT_SUCCESS;
788 }
789
790 EXPORT_API
791 int mmfile_format_read_stream_aac(MMFileFormatContext *formatContext)
792 {
793         MMFileAACHandle     handle = NULL;
794         tMMFILE_AAC_STREAM_INFO  aacinfo = {0, };
795         MMFileFormatStream  *audioStream = NULL;
796
797         int ret = MMFILE_FORMAT_FAIL;
798
799         if (NULL == formatContext) {
800                 debug_error("error: invalid params\n");
801                 ret = MMFILE_FORMAT_FAIL;
802                 goto exception;
803         }
804
805         handle = formatContext->privateFormatData;
806
807         ret = mmfile_aacparser_get_stream_info(handle, &aacinfo);
808         if (MMFILE_FORMAT_SUCCESS != ret) {
809                 debug_error("error: mmfile_aacparser_get_stream_info\n");
810                 ret = MMFILE_FORMAT_FAIL;
811                 goto exception;
812         }
813
814         formatContext->isseekable = aacinfo.iseekable;
815         formatContext->duration = aacinfo.duration;
816         formatContext->videoStreamId = -1;
817         formatContext->videoTotalTrackNum = 0;
818         formatContext->audioTotalTrackNum = aacinfo.numTracks;
819         formatContext->nbStreams = 1;
820
821         audioStream = mmfile_malloc(sizeof(MMFileFormatStream));
822         if (NULL == audioStream) {
823                 debug_error("error: calloc_audiostream\n");
824                 ret = MMFILE_FORMAT_FAIL;
825                 goto exception;
826         }
827
828         audioStream->streamType = MMFILE_AUDIO_STREAM;
829         audioStream->codecId = MM_AUDIO_CODEC_AAC;
830         audioStream->bitRate = aacinfo.bitRate;
831         audioStream->framePerSec = aacinfo.frameRate;
832         audioStream->width = 0;
833         audioStream->height = 0;
834         audioStream->nbChannel = aacinfo.numAudioChannels;
835         audioStream->samplePerSec = aacinfo.samplingRate;
836         formatContext->streams[MMFILE_AUDIO_STREAM] = audioStream;
837
838 #ifdef  __MMFILE_TEST_MODE__
839         mmfile_format_print_contents(formatContext);
840 #endif
841
842         return MMFILE_FORMAT_SUCCESS;
843
844 exception:
845         return ret;
846 }
847
848 EXPORT_API
849 int mmfile_format_read_tag_aac(MMFileFormatContext *formatContext)
850 {
851         MMFileAACHandle     handle = NULL;
852         tMMFILE_AAC_TAG_INFO  aacinfo = {0, };
853         int ret = MMFILE_FORMAT_FAIL;
854
855         if (NULL == formatContext) {
856                 debug_error("error: invalid params\n");
857                 ret = MMFILE_FORMAT_FAIL;
858                 goto exception;
859         }
860
861         handle = formatContext->privateFormatData;
862
863         ret = mmfile_aacparser_get_tag_info(handle, &aacinfo);
864         if (MMFILE_FORMAT_SUCCESS != ret) {
865                 debug_warning("error: mmfile_aacparser_get_tag_info\n");
866                 ret = MMFILE_FORMAT_FAIL;
867                 goto exception;
868         }
869
870         if (aacinfo.title)
871                 formatContext->title = mmfile_strdup(aacinfo.title);
872         if (aacinfo.author)
873                 formatContext->author = mmfile_strdup(aacinfo.author);
874         if (aacinfo.artist)
875                 formatContext->artist = mmfile_strdup(aacinfo.artist);
876         if (aacinfo.album)
877                 formatContext->album = mmfile_strdup(aacinfo.album);
878         if (aacinfo.album_artist)
879                 formatContext->album_artist = mmfile_strdup(aacinfo.album_artist);
880         if (aacinfo.year)
881                 formatContext->year = mmfile_strdup(aacinfo.year);
882         if (aacinfo.copyright)
883                 formatContext->copyright = mmfile_strdup(aacinfo.copyright);
884         if (aacinfo.comment)
885                 formatContext->comment = mmfile_strdup(aacinfo.comment);
886         if (aacinfo.genre)
887                 formatContext->genre = mmfile_strdup(aacinfo.genre);
888         if (aacinfo.tracknum)
889                 formatContext->tagTrackNum = mmfile_strdup(aacinfo.tracknum);
890         if (aacinfo.composer)
891                 formatContext->composer = mmfile_strdup(aacinfo.composer);
892         if (aacinfo.classification)
893                 formatContext->classification = mmfile_strdup(aacinfo.classification);
894         if (aacinfo.rating)
895                 formatContext->rating = mmfile_strdup(aacinfo.rating);  /*not exist rating tag in id3*/
896         if (aacinfo.conductor)
897                 formatContext->conductor = mmfile_strdup(aacinfo.conductor);
898         if (aacinfo.artworkMime)
899                 formatContext->artworkMime = mmfile_strdup(aacinfo.artworkMime);
900         if (aacinfo.artwork) {
901                 formatContext->artworkSize = aacinfo.artworkSize;
902                 formatContext->artwork = mmfile_malloc(aacinfo.artworkSize);
903                 if (formatContext->artwork == NULL) {
904                         ret = MMFILE_FORMAT_FAIL;
905                         goto exception;
906                 }
907                 memcpy(formatContext->artwork, aacinfo.artwork, aacinfo.artworkSize);
908         }
909
910 #ifdef  __MMFILE_TEST_MODE__
911         mmfile_format_print_contents(formatContext);
912 #endif
913
914         return MMFILE_FORMAT_SUCCESS;
915
916 exception:
917         return ret;
918 }
919
920
921 EXPORT_API
922 int mmfile_format_read_frame_aac(MMFileFormatContext *formatContext,
923                                  unsigned int timestamp, MMFileFormatFrame *frame)
924 {
925         debug_error("error: mmfile_format_read_frame_aac, no handling\n");
926
927         return MMFILE_FORMAT_FAIL;
928 }
929
930
931 EXPORT_API
932 int mmfile_format_close_aac(MMFileFormatContext *formatContext)
933 {
934         MMFileAACHandle  handle = NULL;
935         int ret = MMFILE_FORMAT_FAIL;
936
937         if (NULL == formatContext) {
938                 debug_error("error: invalid params\n");
939                 return MMFILE_FORMAT_FAIL;
940         }
941
942         handle = formatContext->privateFormatData;
943
944         if (NULL != handle) {
945                 ret = mmfile_aacparser_close(handle);
946                 if (ret == MMFILE_AAC_PARSER_FAIL) {
947                         debug_error("error: mmfile_format_close_aac\n");
948                 }
949         }
950
951         if (formatContext->streams[MMFILE_AUDIO_STREAM]) {
952                 mmfile_free(formatContext->streams[MMFILE_AUDIO_STREAM]);
953                 formatContext->streams[MMFILE_AUDIO_STREAM] = NULL;
954         }
955
956         formatContext->ReadStream   = NULL;
957         formatContext->ReadFrame    = NULL;
958         formatContext->ReadTag      = NULL;
959         formatContext->Close        = NULL;
960
961         return MMFILE_FORMAT_SUCCESS;
962 }
963
964