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*/
24 #include "mm_file_debug.h"
25 #include "mm_file_utils.h"
27 /* Description of return value
32 /***********************************************************************/
33 /* Internal functions */
34 /***********************************************************************/
35 static int _MMFileSearchID3Tag(MMFileIOHandle *fp, unsigned int *offset);
36 static int _MMFileIsMP3Header(void *header);
37 static int _MMFileIsOGGHeader(void *header);
38 static int _MMFileIsREALHeader(void *header);
39 static int _MMFileIsMP4Header(void *header);
40 static int _MMFileIsWAVHeader(void *header);
41 static int _MMFileIsAVIHeader(void *header);
42 static int _MMFileIsMIDHeader(void *header);
43 static int _MMFileIsMMFHeader(void *header);
44 static int _MMFileIsIMYHeader(void *header);
45 static int _MMFileIsASFHeader(void *header);
46 static int _MMFileIsAMRHeader(void *header);
47 static int _MMFileIsFLACHeader(void *header);
48 static int _MMFileIsFLVHeader(void *header);
49 static int _MMFileIsMPEGTSHeader(MMFileIOHandle *fp);
50 static int _MMFileIsMPEGPSHeader(void *header);
51 static int _MMFileIsMPEGAUDIOHeader(void *header);
52 static int _MMFileIsMPEGVIDEOHeader(void *header);
53 static int _MMFileIsAIFFHeader(void *header);
54 static int _MMFileIsAPEHeader(void *header);
56 /***********************************************************************/
57 /* MP3 Header Check API */
58 /***********************************************************************/
60 int MMFileFormatIsValidMP3(MMFileIOHandle *pFileIO, const char *mmfileuri, int frameCnt)
62 #define _MMFILE_MP3_HEADER_LENGTH 4
63 #define _MMFILE_MP3_BUFFER_LENGTH 8200
65 MMFileIOHandle *fp = pFileIO;
66 unsigned char buffer[_MMFILE_MP3_BUFFER_LENGTH] = {0, };
67 long long filesize = 0;
68 unsigned int sizeID3 = 0;
69 int readed = 0, i = 0, j = 0;;
70 unsigned int startoffset = 0;
73 int ret = 0, count = 0, offset = 0;
76 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
77 if (ret == MMFILE_IO_FAILED) {
78 debug_error(DEBUG, "error: mmfile_open\n");
83 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
85 mmfile_seek(fp, 0L, MMFILE_SEEK_END);
86 filesize = mmfile_tell(fp);
87 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
89 if (filesize < _MMFILE_MP3_HEADER_LENGTH) {
90 debug_error(DEBUG, "header is too small.\n");
95 /* Search the existance of ID3 tag */
96 ret = _MMFileSearchID3Tag(fp, &sizeID3);
98 debug_error(RELEASE, "Error in searching the ID3 tag\n");
104 /* set begin and end point at the file */
105 startoffset += sizeID3;
106 endoffset = startoffset + 102400;
107 if (endoffset > filesize - _MMFILE_MP3_HEADER_LENGTH)
108 endoffset = filesize - _MMFILE_MP3_HEADER_LENGTH;
114 while (i < endoffset) {
115 mmfile_seek(fp, i, MMFILE_SEEK_SET);
116 readed = mmfile_read(fp, buffer, _MMFILE_MP3_BUFFER_LENGTH);
117 if (readed < _MMFILE_MP3_HEADER_LENGTH) {
118 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
124 for (j = 0; (j <= readed - _MMFILE_MP3_HEADER_LENGTH); j = j + offset) {
125 frameSize = _MMFileIsMP3Header(buffer + j);
131 if ((j + frameSize) >= (endoffset - (i + _MMFILE_MP3_HEADER_LENGTH))) {
135 if ((j + frameSize) >= (readed - _MMFILE_MP3_HEADER_LENGTH)) {
136 debug_msg(RELEASE, "MP3 coner hit %d %d\n", j, frameSize);
140 frameSize = _MMFileIsMP3Header(buffer + j + frameSize);
145 if (count == frameCnt) {
147 debug_msg(RELEASE, "Header Detected at %d\n", i + j);
156 /*If j is zero, this loop is infinite */
163 debug_msg(RELEASE, "Header Not Detected at: %d\n", i + j);
165 if (pFileIO == NULL && fp != NULL)
173 /***********************************************************************/
174 /* AAC Header Check API */
175 /***********************************************************************/
177 int MMFileFormatIsValidAAC(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
179 #define _MMFILE_AAC_HEADER_LENGTH 4
180 #define _MMFILE_AAC_BUFFER_LENGTH 8200
182 MMFileIOHandle *fp = pFileIO;
183 unsigned char buffer[_MMFILE_AAC_BUFFER_LENGTH] = {0, };
184 unsigned int sizeID3 = 0;
185 long long filesize = 0;
186 int readed = 0, i = 0, j = 0;
190 unsigned int sync = 0;
194 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
195 if (ret == MMFILE_IO_FAILED) {
196 debug_error(DEBUG, "error: mmfile_open\n");
201 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
203 /* Initialize the members of handle */
204 mmfile_seek(fp, 0, MMFILE_SEEK_END);
205 filesize = mmfile_tell(fp);
206 mmfile_seek(fp, 0, MMFILE_SEEK_SET);
208 if (filesize < _MMFILE_AAC_HEADER_LENGTH) {
209 debug_error(DEBUG, "header is too small.\n");
214 /* Search the existance of ID3 tag */
215 ret = _MMFileSearchID3Tag(fp, &sizeID3);
217 debug_error(RELEASE, "Error in searching the ID3 tag\n");
223 /* set begin and end point at the file */
224 startoffset += sizeID3;
225 endoffset = startoffset + 10240;
226 if (endoffset > filesize - _MMFILE_AAC_HEADER_LENGTH)
227 endoffset = filesize - _MMFILE_AAC_HEADER_LENGTH;
231 while (i < endoffset) {
232 mmfile_seek(fp, i, MMFILE_SEEK_SET);
234 readed = mmfile_read(fp, buffer, _MMFILE_AAC_BUFFER_LENGTH);
236 if (readed < _MMFILE_AAC_HEADER_LENGTH) {
237 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
242 debug_msg(RELEASE, "read error. size = %d. i = %d\n", readed, i);
244 for (j = 0; (j < readed - _MMFILE_AAC_HEADER_LENGTH); j++) {
246 sync = ((buffer[j] << 8) | (buffer[j + 1]));
248 if ((sync & 0xFFF6) == 0xFFF0) {
249 frameSize = (((buffer[j + 3] & 0x03) << 11) | (buffer[j + 4] << 3) | ((buffer[j + 5] & 0xE0) >> 5));
251 if (frameSize == 0) {
255 if ((j + frameSize) >= (endoffset - (i + 2))) {
258 if ((j + frameSize) >= (readed - 2)) {
259 debug_msg(RELEASE, "AAC coner hit %d %d\n", j, frameSize);
263 sync = ((buffer[j + frameSize] << 8) | (buffer[j + frameSize + 1]));
265 if ((sync & 0xFFF6) == 0xFFF0) {
267 debug_msg(RELEASE, "AAC ADTS Header Detected at %d\n", i + j);
270 } else if (!memcmp((buffer + j), "ADIF", 4)) {
272 debug_msg(RELEASE, "AAC ADIF Header Detected at %d\n", i + j);
276 /*If j is zero, this loop is infinite */
284 debug_msg(RELEASE, "Header Detected Failed\n");
286 if (pFileIO == NULL && fp != NULL)
294 /***********************************************************************/
295 /* OGG Header Check API */
296 /***********************************************************************/
298 int MMFileFormatIsValidOGG(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
300 #define _MMFILE_OGG_HEADER_LENGTH 4
301 #define _MMFILE_OGG_BUFFER_LENGTH 512
302 #define _MMFILE_OGG_CHECK_LIMIT (_MMFILE_OGG_HEADER_LENGTH * 1000)
304 MMFileIOHandle *fp = pFileIO;
305 unsigned char buffer[_MMFILE_OGG_BUFFER_LENGTH] = {0, };
306 unsigned int sizeID3 = 0;
307 long long filesize = 0;
308 int readed = 0, i = 0, j = 0;
315 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
316 if (ret == MMFILE_IO_FAILED) {
317 debug_error(DEBUG, "error: mmfile_open\n");
323 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
325 /* Initialize the members of handle */
326 mmfile_seek(fp, 0, MMFILE_SEEK_END);
327 filesize = mmfile_tell(fp);
328 mmfile_seek(fp, 0, MMFILE_SEEK_SET);
330 if (filesize < _MMFILE_OGG_HEADER_LENGTH) {
331 debug_error(DEBUG, "header is too small.\n");
336 /* Search the existance of ID3 tag */
337 ret = _MMFileSearchID3Tag(fp, &sizeID3);
339 debug_error(RELEASE, "Error in searching the ID3 tag\n");
345 /* set begin and end point at the file */
346 startoffset += sizeID3;
347 endoffset = filesize - _MMFILE_OGG_HEADER_LENGTH;
349 check_limit = (endoffset > _MMFILE_OGG_CHECK_LIMIT) ? _MMFILE_OGG_CHECK_LIMIT : endoffset;
352 while (i <= check_limit) {
353 mmfile_seek(fp, i, MMFILE_SEEK_SET);
354 readed = mmfile_read(fp, buffer, _MMFILE_OGG_BUFFER_LENGTH);
355 if (readed < _MMFILE_OGG_HEADER_LENGTH) {
356 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
361 for (j = 0; (j <= readed - _MMFILE_OGG_HEADER_LENGTH); j++) {
362 if (1 == _MMFileIsOGGHeader(buffer + j)) {
364 debug_msg(RELEASE, "Header Detected at %d\n", i + j);
369 memset(buffer, 0x00, _MMFILE_OGG_BUFFER_LENGTH);
375 if (pFileIO == NULL && fp != NULL)
383 /***********************************************************************/
384 /* MIDI Header Check API */
385 /***********************************************************************/
387 int MMFileFormatIsValidMID(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
389 #define _MMFILE_MIDI_HEADER_LENGTH 4
390 #define _MMFILE_MIDI_BUFFER_LENGTH 512
391 #define _MMFILE_MIDI_CHECK_LIMIT (_MMFILE_MIDI_HEADER_LENGTH * 1024)
393 MMFileIOHandle *fp = pFileIO;
394 unsigned char buffer[_MMFILE_MIDI_BUFFER_LENGTH] = {0, };
395 long long filesize = 0;
396 int readed = 0, i = 0, j = 0;
403 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
404 if (ret == MMFILE_IO_FAILED) {
405 debug_error(DEBUG, "error: mmfile_open\n");
410 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
412 /* Initialize the members of handle */
413 mmfile_seek(fp, 0, MMFILE_SEEK_END);
414 filesize = mmfile_tell(fp);
415 mmfile_seek(fp, 0, MMFILE_SEEK_SET);
417 if (filesize < _MMFILE_MIDI_HEADER_LENGTH) {
418 debug_error(DEBUG, "header is too small.\n");
425 /* set begin and end point at the file */
427 endoffset = filesize - _MMFILE_MIDI_HEADER_LENGTH;
429 check_limit = (endoffset > _MMFILE_MIDI_CHECK_LIMIT) ? _MMFILE_MIDI_CHECK_LIMIT : endoffset;
432 while (i <= check_limit) {
433 mmfile_seek(fp, i, MMFILE_SEEK_SET);
434 readed = mmfile_read(fp, buffer, _MMFILE_MIDI_BUFFER_LENGTH);
435 if (readed < _MMFILE_MIDI_HEADER_LENGTH) {
436 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
441 for (j = 0; (j <= readed - _MMFILE_MIDI_HEADER_LENGTH); j++) {
442 if (1 == _MMFileIsMIDHeader(buffer + j)) {
444 debug_msg(RELEASE, "Header Detected at %d\n", i + j);
449 memset(buffer, 0x00, _MMFILE_MIDI_BUFFER_LENGTH);
455 if (pFileIO == NULL && fp != NULL)
462 /***********************************************************************/
463 /* WAV Header Check API */
464 /***********************************************************************/
466 int MMFileFormatIsValidWAV(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
468 #define _MMFILE_WAV_HEADER_LENGTH 15
470 MMFileIOHandle *fp = pFileIO;
471 unsigned char buffer[_MMFILE_WAV_HEADER_LENGTH] = {0, };
476 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
477 if (ret == MMFILE_IO_FAILED) {
478 debug_error(DEBUG, "error: mmfile_open\n");
483 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
485 readed = mmfile_read(fp, buffer, _MMFILE_WAV_HEADER_LENGTH);
487 if (_MMFILE_WAV_HEADER_LENGTH != readed) {
488 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
493 if (1 == _MMFileIsWAVHeader(buffer)) {
494 debug_msg(RELEASE, "Header Detected\n");
500 if (pFileIO == NULL && fp != NULL)
508 /***********************************************************************/
509 /* MP4 Header Check API */
510 /***********************************************************************/
512 int MMFileFormatIsValidMP4(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
514 #define _MMFILE_MP4_HEADER_LENGTH 4
515 #define _MMFILE_MP4_CHECK_LIMIT (1024*10) /*10Kbyte*/
516 MMFileIOHandle *fp = pFileIO;
517 unsigned char buffer[_MMFILE_MP4_HEADER_LENGTH] = {0, };
518 long long filesize = 0;
520 unsigned int startoffset = 0;
522 unsigned int check_limit = 0;
525 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
526 if (ret == MMFILE_IO_FAILED) {
527 debug_error(DEBUG, "error: mmfile_open\n");
532 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
534 /* Initialize the members of handle */
535 mmfile_seek(fp, 0, MMFILE_SEEK_END);
536 filesize = mmfile_tell(fp);
537 mmfile_seek(fp, 0, MMFILE_SEEK_SET);
539 if (filesize < _MMFILE_MP4_HEADER_LENGTH) {
540 debug_error(DEBUG, "header is too small.\n");
547 /**@note weak check*/
548 check_limit = (filesize > _MMFILE_MP4_CHECK_LIMIT) ? _MMFILE_MP4_CHECK_LIMIT : filesize;
549 for (startoffset = 0; check_limit - (startoffset + _MMFILE_MP4_HEADER_LENGTH) > 0; startoffset++) {
550 mmfile_seek(fp, startoffset, MMFILE_SEEK_SET);
552 readed = mmfile_read(fp, buffer, _MMFILE_MP4_HEADER_LENGTH);
553 if (readed != _MMFILE_MP4_HEADER_LENGTH) {
554 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
560 if (1 == _MMFileIsMP4Header(buffer)) {
561 debug_msg(RELEASE, "MP4 Header Detected\n");
568 if (pFileIO == NULL && fp != NULL)
575 /***********************************************************************/
576 /* AVI Header Check API */
577 /***********************************************************************/
579 int MMFileFormatIsValidAVI(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
581 #define _MMFILE_AVI_HEADER_LENGTH 12
583 MMFileIOHandle *fp = pFileIO;
584 unsigned char buffer[_MMFILE_AVI_HEADER_LENGTH] = {0, };
589 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
590 if (ret == MMFILE_IO_FAILED) {
591 debug_error(DEBUG, "error: mmfile_open\n");
596 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
598 readed = mmfile_read(fp, buffer, _MMFILE_AVI_HEADER_LENGTH);
600 if (_MMFILE_AVI_HEADER_LENGTH != readed) {
601 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
606 if (1 == _MMFileIsAVIHeader(buffer)) {
607 debug_msg(RELEASE, "Header Detected \n");
613 if (pFileIO == NULL && fp != NULL)
621 /***********************************************************************/
622 /* ASF Header Check API */
623 /***********************************************************************/
625 int MMFileFormatIsValidASF(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
627 #define _MMFILE_ASF_HEADER_LENGTH 16
628 MMFileIOHandle *fp = pFileIO;
629 unsigned char buffer[_MMFILE_ASF_HEADER_LENGTH] = {0, };
634 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
635 if (ret == MMFILE_IO_FAILED) {
636 debug_error(DEBUG, "error: mmfile_open\n");
641 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
643 readed = mmfile_read(fp, buffer, _MMFILE_ASF_HEADER_LENGTH);
645 if (_MMFILE_ASF_HEADER_LENGTH != readed) {
646 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
651 if (1 == _MMFileIsASFHeader(buffer)) {
652 debug_msg(RELEASE, "Header Detected\n");
658 if (pFileIO == NULL && fp != NULL)
664 /***********************************************************************/
665 /* WMA Header Check API */
666 /***********************************************************************/
668 int MMFileFormatIsValidWMA(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
670 #define _MMFILE_ASF_HEADER_LENGTH 16
671 MMFileIOHandle *fp = pFileIO;
672 unsigned char buffer[_MMFILE_ASF_HEADER_LENGTH] = {0, };
677 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
678 if (ret == MMFILE_IO_FAILED) {
679 debug_error(DEBUG, "error: mmfile_open\n");
684 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
686 readed = mmfile_read(fp, buffer, _MMFILE_ASF_HEADER_LENGTH);
688 if (_MMFILE_ASF_HEADER_LENGTH != readed) {
689 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
695 if (1 == _MMFileIsASFHeader(buffer)) {
696 debug_msg(RELEASE, "Header Detected\n");
702 if (pFileIO == NULL && fp != NULL)
710 /***********************************************************************/
711 /* WMV Header Check API */
712 /***********************************************************************/
714 int MMFileFormatIsValidWMV(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
716 #define _MMFILE_ASF_HEADER_LENGTH 16
717 MMFileIOHandle *fp = pFileIO;
718 unsigned char buffer[_MMFILE_ASF_HEADER_LENGTH] = {0, };
723 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
724 if (ret == MMFILE_IO_FAILED) {
725 debug_error(DEBUG, "error: mmfile_open\n");
730 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
732 readed = mmfile_read(fp, buffer, _MMFILE_ASF_HEADER_LENGTH);
734 if (_MMFILE_ASF_HEADER_LENGTH != readed) {
735 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
740 if (1 == _MMFileIsASFHeader(buffer)) {
741 debug_msg(RELEASE, "Header Detected\n");
747 if (pFileIO == NULL && fp != NULL)
754 /***********************************************************************/
755 /* MMF Header Check API */
756 /***********************************************************************/
758 int MMFileFormatIsValidMMF(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
760 #define _MMFILE_MMF_HEADER_LENGTH 18
762 MMFileIOHandle *fp = pFileIO;
763 unsigned char buffer[_MMFILE_MMF_HEADER_LENGTH] = {0, };
768 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
769 if (ret == MMFILE_IO_FAILED) {
770 debug_error(DEBUG, "error: mmfile_open\n");
775 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
777 readed = mmfile_read(fp, buffer, _MMFILE_MMF_HEADER_LENGTH);
779 if (_MMFILE_MMF_HEADER_LENGTH != readed) {
780 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
785 if (1 == _MMFileIsMMFHeader(buffer)) {
786 debug_msg(RELEASE, "Header Detected\n");
792 if (pFileIO == NULL && fp != NULL)
800 /***********************************************************************/
801 /* MMF Header Check API */
802 /***********************************************************************/
804 int MMFileFormatIsValidIMY(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
806 #define _MMFILE_IMY_HEADER_LENGTH 13
808 MMFileIOHandle *fp = pFileIO;
809 unsigned char buffer[_MMFILE_IMY_HEADER_LENGTH] = {0, };
814 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
815 if (ret == MMFILE_IO_FAILED) {
816 debug_error(DEBUG, "error: mmfile_open\n");
821 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
823 readed = mmfile_read(fp, buffer, _MMFILE_IMY_HEADER_LENGTH);
825 if (_MMFILE_IMY_HEADER_LENGTH != readed) {
826 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
831 if (1 == _MMFileIsIMYHeader(buffer)) {
832 debug_msg(RELEASE, "Header Detected\n");
838 if (pFileIO == NULL && fp != NULL)
846 /***********************************************************************/
847 /* AMR Header Check API */
848 /***********************************************************************/
850 int MMFileFormatIsValidAMR(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
852 #define _MMFILE_AMR_MAX_HEADER_SIZE 15
853 #define _MMFILE_AMR_MIN_HEADER_SIZE 6
855 MMFileIOHandle *fp = pFileIO;
856 unsigned char buffer[_MMFILE_AMR_MAX_HEADER_SIZE] = {0, };
861 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
862 if (ret == MMFILE_IO_FAILED) {
863 debug_error(DEBUG, "error: mmfile_open\n");
868 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
870 readed = mmfile_read(fp, buffer, _MMFILE_AMR_MAX_HEADER_SIZE);
872 if (_MMFILE_AMR_MAX_HEADER_SIZE != readed) {
873 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
878 if (1 == _MMFileIsAMRHeader(buffer)) {
879 debug_msg(RELEASE, "Header Detected\n");
885 if (pFileIO == NULL && fp != NULL)
891 /***********************************************************************/
892 /* Matroska Header Check API */
893 /***********************************************************************/
895 int MMFileFormatIsValidMatroska(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
897 #define _MMFILE_EBML_MARKER_LENGTH 4
898 #define _MMFILE_MKV_READ_BUFFER_LENGTH 2048
900 MMFileIOHandle *fp = pFileIO;
901 unsigned char buffer[_MMFILE_MKV_READ_BUFFER_LENGTH] = {0, };
905 unsigned int size = 1, n = 1, total = 0;
906 //char probe_data[] = { 'm', 'a', 't', 'r', 'o', 's', 'k', 'a' };
907 /*support webm, add probe data*/
908 const char * probe_data[2] = { "matroska", "webm" };
910 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
911 if (ret == MMFILE_IO_FAILED) {
912 debug_error(DEBUG, "error: mmfile_open\n");
917 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
919 readed = mmfile_read(fp, buffer, _MMFILE_MKV_READ_BUFFER_LENGTH);
921 if (_MMFILE_MKV_READ_BUFFER_LENGTH != readed) {
922 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
928 if (buffer[0] != 0x1A || buffer[1] != 0x45 || buffer[2] != 0xDF || buffer[3] != 0xA3) {
929 debug_msg(RELEASE, "This is not a EBML format\n");
934 /* length of header */
937 debug_msg(RELEASE, "Initial total header size = [0x%x]\n", total);
939 while (size <= 8 && !(total & len_mask)) {
940 debug_msg(DEBUG, "This case can not be handled yet....");
945 debug_msg(RELEASE, "Final total header size = [%d]\n", total);
948 debug_msg(DEBUG, "This case can not be handled yet....");
953 total &= (len_mask - 1);
956 total = (total << 8) | buffer[4 + n++];
957 debug_msg(DEBUG, "This case can not be handled yet....");
960 /* Does the probe data contain the whole header? */
961 if (_MMFILE_MKV_READ_BUFFER_LENGTH < 4 + size + total)
964 /*compare two kinds of probe data*/
965 for (int i = 0; i < 2; i++) {
966 unsigned int probelen = strlen(probe_data[i]);
967 if (total < probelen)
969 for (n = 4 + size ; n <= 4 + size + total - probelen; n++) {
970 if (!memcmp(&buffer[n], probe_data[i], probelen)) {
971 debug_msg(RELEASE, "String %s found!!!\n", probe_data[i]);
979 if (pFileIO == NULL && fp != NULL)
985 /***********************************************************************/
986 /* QT Header Check API */
987 /***********************************************************************/
989 int MMFileFormatIsValidQT(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
994 /***********************************************************************/
995 /* Flac Header Check API */
996 /***********************************************************************/
998 int MMFileFormatIsValidFLAC(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
1000 #define _MMFILE_FLAC_HEADER_LENGTH 5 /*fLaC*/
1002 MMFileIOHandle *fp = pFileIO;
1003 unsigned char buffer[_MMFILE_FLAC_HEADER_LENGTH] = {0, };
1008 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
1009 if (ret == MMFILE_IO_FAILED) {
1010 debug_error(DEBUG, "error: mmfile_open\n");
1015 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
1017 readed = mmfile_read(fp, buffer, _MMFILE_FLAC_HEADER_LENGTH);
1019 if (_MMFILE_FLAC_HEADER_LENGTH != readed) {
1020 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
1025 if (1 == _MMFileIsFLACHeader(buffer)) {
1026 debug_msg(RELEASE, "Header Detected\n");
1032 if (pFileIO == NULL && fp != NULL)
1038 /***********************************************************************/
1039 /* FLV(flash video) Header Check API */
1040 /***********************************************************************/
1042 int MMFileFormatIsValidFLV(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
1044 #define _MMFILE_FLV_HEADER_LENGTH 4 /*FLV*/
1046 MMFileIOHandle *fp = pFileIO;
1047 unsigned char buffer[_MMFILE_FLV_HEADER_LENGTH] = {0, };
1052 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
1053 if (ret == MMFILE_IO_FAILED) {
1054 debug_error(DEBUG, "error: mmfile_open\n");
1059 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
1061 readed = mmfile_read(fp, buffer, _MMFILE_FLV_HEADER_LENGTH);
1063 if (_MMFILE_FLV_HEADER_LENGTH != readed) {
1064 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
1069 if (1 == _MMFileIsFLVHeader(buffer)) {
1070 debug_msg(RELEASE, "Header Detected\n");
1076 if (pFileIO == NULL && fp != NULL)
1083 /***********************************************************************/
1084 /* REAL Header Check API */
1085 /***********************************************************************/
1087 int MMFileFormatIsValidREAL(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
1089 #define _MMFILE_RMVB_HEADER_LENGTH 4 /*RMF*/
1091 MMFileIOHandle *fp = pFileIO;
1092 unsigned char buffer[_MMFILE_RMVB_HEADER_LENGTH] = {0, };
1097 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
1098 if (ret == MMFILE_IO_FAILED) {
1099 debug_error(DEBUG, "error: mmfile_open\n");
1104 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
1106 readed = mmfile_read(fp, buffer, _MMFILE_RMVB_HEADER_LENGTH);
1108 if (_MMFILE_RMVB_HEADER_LENGTH != readed) {
1109 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
1114 if (1 == _MMFileIsREALHeader(buffer)) {
1115 debug_msg(RELEASE, "Header Detected\n");
1122 if (pFileIO == NULL && fp != NULL)
1128 /***********************************************************************/
1129 /* MPEGTS Header Check API */
1130 /***********************************************************************/
1131 #define MPEGTS_NONE 0x00
1132 #define MPEGTS_FECE 0x10
1133 #define MPEGTS_DVHS 0x20
1134 #define MPEGTS_PACKET 0x40
1136 #define TS_PACKET_SIZE 188
1137 #define TS_DVHS_PACKET_SIZE 192
1138 #define TS_FEC_PACKET_SIZE 204
1139 #define TS_MAX_PACKET_SIZE 204
1142 int MMFileFormatIsValidMPEGTS(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
1144 MMFileIOHandle *fp = pFileIO;
1145 unsigned char buffer[TS_MAX_PACKET_SIZE] = {0, };
1150 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
1151 if (ret == MMFILE_IO_FAILED) {
1152 debug_error(DEBUG, "error: mmfile_open\n");
1157 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
1159 readed = mmfile_read(fp, buffer, TS_MAX_PACKET_SIZE);
1161 if (TS_MAX_PACKET_SIZE != readed) {
1162 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
1167 if (_MMFileIsMPEGTSHeader(fp) != MPEGTS_NONE) {
1168 debug_msg(RELEASE, "Header Detected\n");
1174 if (pFileIO == NULL && fp != NULL)
1180 /***********************************************************************/
1181 /* MPEG-PS Header Check API */
1182 /***********************************************************************/
1184 int MMFileFormatIsValidMPEGPS(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
1186 #define _MMFILE_MPEGPS_HEADER_LENGTH 4
1188 MMFileIOHandle *fp = pFileIO;
1189 unsigned char buffer[_MMFILE_MPEGPS_HEADER_LENGTH] = {0, };
1194 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
1195 if (ret == MMFILE_IO_FAILED) {
1196 debug_error(DEBUG, "error: mmfile_open\n");
1201 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
1203 readed = mmfile_read(fp, buffer, _MMFILE_MPEGPS_HEADER_LENGTH);
1205 if (_MMFILE_MPEGPS_HEADER_LENGTH != readed) {
1206 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
1211 if (1 == _MMFileIsMPEGPSHeader(buffer)) {
1212 debug_msg(RELEASE, "Header Detected\n");
1218 if (pFileIO == NULL && fp != NULL)
1224 /***********************************************************************/
1225 /* MPEG AUDIO Header Check API */
1226 /***********************************************************************/
1228 int MMFileFormatIsValidMPEGAUDIO(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
1230 #define _MMFILE_MPEGAUDIO_HEADER_LENGTH 4
1232 MMFileIOHandle *fp = pFileIO;
1233 unsigned char buffer[_MMFILE_MPEGAUDIO_HEADER_LENGTH] = {0, };
1238 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
1239 if (ret == MMFILE_IO_FAILED) {
1240 debug_error(DEBUG, "error: mmfile_open\n");
1245 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
1247 readed = mmfile_read(fp, buffer, _MMFILE_MPEGAUDIO_HEADER_LENGTH);
1249 if (_MMFILE_MPEGAUDIO_HEADER_LENGTH != readed) {
1250 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
1255 if (1 == _MMFileIsMPEGAUDIOHeader(buffer)) {
1256 debug_msg(RELEASE, "Header Detected\n");
1262 if (pFileIO == NULL && fp != NULL)
1268 /***********************************************************************/
1269 /* MPEG VIDEO Header Check API */
1270 /***********************************************************************/
1272 int MMFileFormatIsValidMPEGVIDEO(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
1274 #define _MMFILE_MPEGVIDEO_HEADER_LENGTH 4
1276 MMFileIOHandle *fp = pFileIO;
1277 unsigned char buffer[_MMFILE_MPEGVIDEO_HEADER_LENGTH] = {0, };
1282 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
1283 if (ret == MMFILE_IO_FAILED) {
1284 debug_error(DEBUG, "error: mmfile_open\n");
1289 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
1291 readed = mmfile_read(fp, buffer, _MMFILE_MPEGVIDEO_HEADER_LENGTH);
1293 if (_MMFILE_MPEGVIDEO_HEADER_LENGTH != readed) {
1294 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
1299 if (1 == _MMFileIsMPEGVIDEOHeader(buffer)) {
1300 debug_msg(RELEASE, "Header Detected\n");
1306 if (pFileIO == NULL && fp != NULL)
1312 /***********************************************************************/
1313 /* AIFF Header Check API */
1314 /***********************************************************************/
1316 int MMFileFormatIsValidAIFF(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
1318 #define _MMFILE_AIFF_HEADER_LENGTH 13
1320 MMFileIOHandle *fp = pFileIO;
1321 unsigned char buffer[_MMFILE_AIFF_HEADER_LENGTH] = {0, };
1326 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
1327 if (ret == MMFILE_IO_FAILED) {
1328 debug_error(DEBUG, "error: mmfile_open\n");
1333 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
1335 readed = mmfile_read(fp, buffer, _MMFILE_AIFF_HEADER_LENGTH);
1337 if (_MMFILE_AIFF_HEADER_LENGTH != readed) {
1338 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
1343 if (1 == _MMFileIsAIFFHeader(buffer)) {
1344 debug_msg(RELEASE, "Header Detected\n");
1350 if (pFileIO == NULL && fp != NULL)
1357 int MMFileFormatIsValidAPE(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
1359 #define _MMFILE_APE_HEADER_LENGTH 4 /*APE*/
1361 MMFileIOHandle *fp = pFileIO;
1362 unsigned char buffer[_MMFILE_APE_HEADER_LENGTH] = {0, };
1367 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
1368 if (ret == MMFILE_IO_FAILED) {
1369 debug_error(DEBUG, "error: mmfile_open\n");
1374 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
1376 readed = mmfile_read(fp, buffer, _MMFILE_APE_HEADER_LENGTH);
1378 if (_MMFILE_APE_HEADER_LENGTH != readed) {
1379 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
1384 if (1 == _MMFileIsAPEHeader(buffer)) {
1385 debug_msg(RELEASE, "Header Detected\n");
1391 if (pFileIO == NULL && fp != NULL)
1397 /***********************************************************************/
1398 /* Implementation of Internal Functions */
1399 /***********************************************************************/
1400 static int _MMFileIsASFHeader(void *header)
1402 /* ID: 30 26 B2 75 8E 66 CF 11 A6 D9 00 AA 00 62 CE 6C */
1403 unsigned char *s = header;
1405 if ((*(s + 0) == 0x30) &&
1406 (*(s + 1) == 0x26) &&
1407 (*(s + 2) == 0xB2) &&
1408 (*(s + 3) == 0x75) &&
1409 (*(s + 4) == 0x8E) &&
1410 (*(s + 5) == 0x66) &&
1411 (*(s + 6) == 0xCF) &&
1412 (*(s + 7) == 0x11) &&
1413 (*(s + 8) == 0xA6) &&
1414 (*(s + 9) == 0xD9) &&
1415 (*(s + 10) == 0x00) &&
1416 (*(s + 11) == 0xAA) &&
1417 (*(s + 12) == 0x00) &&
1418 (*(s + 13) == 0x62) &&
1419 (*(s + 14) == 0xCE) &&
1420 (*(s + 15) == 0x6C)) {
1428 static int _MMFileIsAMRHeader(void *header)
1430 #define _MMFILE_AMR_SINGLE_CH_HEADER_SIZE 6
1431 #define _MMFILE_AMR_SINGLE_CH_HEADER "#!AMR\n"
1433 #define _MMFILE_AMR_WB_SINGLE_CH_HEADER_SIZE 9
1434 #define _MMFILE_AMR_WB_SINGLE_CH_HEADER "#!AMR-WB\n"
1436 #define _MMFILE_AMR_MULTI_CH_HEADER_SIZE 12
1437 #define _MMFILE_AMR_MULTI_CH_HEADER "#!AMR_MC1.0\n"
1439 #define _MMFILE_AMR_WB_MULTI_CH_HEADER_SIZE 15
1440 #define _MMFILE_AMR_WB_MULTI_CH_HEADER "#!AMR-WB_MC1.0\n"
1442 unsigned char *s = header;
1444 if (!memcmp(s, _MMFILE_AMR_SINGLE_CH_HEADER, _MMFILE_AMR_SINGLE_CH_HEADER_SIZE) ||
1445 !memcmp(s, _MMFILE_AMR_WB_SINGLE_CH_HEADER, _MMFILE_AMR_WB_SINGLE_CH_HEADER_SIZE) ||
1446 !memcmp(s, _MMFILE_AMR_MULTI_CH_HEADER, _MMFILE_AMR_MULTI_CH_HEADER_SIZE) ||
1447 !memcmp(s, _MMFILE_AMR_WB_MULTI_CH_HEADER, _MMFILE_AMR_WB_MULTI_CH_HEADER_SIZE)) {
1455 static int _MMFileIsIMYHeader(void *header)
1457 unsigned char *s = header;
1459 if (!memcmp(s, "BEGIN:IMELODY", 13)) {
1466 static int _MMFileIsMIDHeader(void *header)
1468 unsigned char *s = header;
1470 if (!memcmp(s, "MThd", 4)) { /*general MIDI*/
1472 } else if (!memcmp(s, "XMF_", 4)) { /*XMF*/
1474 } else if (!memcmp(s, "IREZ", 4)) {
1475 return 1; /*RMF format*/
1481 static int _MMFileIsMMFHeader(void *header)
1483 #define _MMFILE_MMF_TYPE_POSITION ((char)0x11)
1484 unsigned char *s = header;
1486 if (!memcmp(s, "MMMD", 4)) {
1487 /* warning: comparison is always true due to limited range of data type */
1488 if (*(s + _MMFILE_MMF_TYPE_POSITION) <= 0x2F) {
1490 } else if (((*(s + _MMFILE_MMF_TYPE_POSITION) >= 0x30) && (*(s + _MMFILE_MMF_TYPE_POSITION) <= 0x38)) /* MA3, MA5 type */
1491 || ((*(s + _MMFILE_MMF_TYPE_POSITION) >= 0x40) && (*(s + _MMFILE_MMF_TYPE_POSITION) <= 0x48))
1492 || ((*(s + _MMFILE_MMF_TYPE_POSITION) >= 0x50) && (*(s + _MMFILE_MMF_TYPE_POSITION) <= 0x58))
1493 || ((*(s + _MMFILE_MMF_TYPE_POSITION) == 0xF0))) {
1503 static int _MMFileIsAVIHeader(void *header)
1505 unsigned char *s = header;
1507 if (!memcmp(s, "RIFF", 4) && !memcmp(s + 8, "AVI", 3)) {
1515 static int _MMFileIsWAVHeader(void *header)
1517 unsigned char *s = header;
1519 if (!memcmp(s, "RIFF", 4) && !memcmp(s + 8, "WAVE", 4)) {
1528 static int _MMFileIsMP4Header(void *header)
1530 unsigned char *s = header;
1532 if (!memcmp(s, "moov", 4) ||
1533 !memcmp(s, "mdat", 4) ||
1534 !memcmp(s, "ftyp", 4) ||
1535 !memcmp(s, "free", 4) ||
1536 !memcmp(s, "uuid", 4) ||
1537 !memcmp(s, "skip", 4) ||
1539 !memcmp(s, "PICT", 4) ||
1540 !memcmp(s, "wide", 4) ||
1541 !memcmp(s, "prfl", 4)) {
1548 static int _MMFileIsOGGHeader(void *header)
1550 unsigned char *s = header;
1552 if (!memcmp(s, "OggS", 4)) {
1559 static int _MMFileIsREALHeader(void *header)
1561 unsigned char *s = header;
1563 if (!memcmp(s, ".RMF", 4)) {
1570 static int _MMFileIsMPEGTSHeader(MMFileIOHandle *fp)
1572 unsigned char header[TS_MAX_PACKET_SIZE] = {0, };
1573 unsigned char *s = NULL;
1575 mmfile_seek(fp, 0, MMFILE_SEEK_SET);
1576 mmfile_read(fp, header, sizeof(header));
1578 s = (unsigned char *)memchr(header, 0x47, sizeof(header));
1581 unsigned char buffer[TS_PACKET_SIZE] = {0, };
1582 unsigned int startoffset = s - header + 1;
1584 mmfile_seek(fp, startoffset, MMFILE_SEEK_SET);
1585 mmfile_read(fp, buffer, sizeof(buffer));
1587 if (buffer[sizeof(buffer) - 1] & 0x47) {
1588 return MPEGTS_PACKET;
1590 unsigned char dvhs_buf[TS_DVHS_PACKET_SIZE] = {0, };
1592 mmfile_seek(fp, startoffset, MMFILE_SEEK_SET);
1593 mmfile_read(fp, dvhs_buf, sizeof(dvhs_buf));
1595 if (dvhs_buf[sizeof(dvhs_buf) - 1] & 0x47) {
1598 unsigned char fec_buf[TS_FEC_PACKET_SIZE] = {0, };
1600 mmfile_seek(fp, startoffset, MMFILE_SEEK_SET);
1601 mmfile_read(fp, fec_buf, sizeof(fec_buf));
1603 if (fec_buf[sizeof(fec_buf) - 1] & 0x47) {
1613 static int _MMFileIsMPEGPSHeader(void *header)
1615 unsigned char *s = header;
1617 if ((*(s + 0) == 0x00) &&
1618 (*(s + 1) == 0x00) &&
1619 (*(s + 2) == 0x01) &&
1620 (*(s + 3) == 0xba)) { /* mpeg-ps header */
1627 static int _MMFileIsMPEGAUDIOHeader(void *header)
1629 unsigned char *s = header;
1631 if ((*(s + 0) == 0xFF) &&
1632 ((*(s + 1) == 0xFE) || (*(s + 1) == 0xFF))) { /* mpeg audio layer 1 header ,FE: protected by CRC ,FF: not protected */
1639 static int _MMFileIsMPEGVIDEOHeader(void *header)
1641 unsigned char *s = header;
1643 if ((*(s + 0) == 0x00) &&
1644 (*(s + 1) == 0x00) &&
1645 (*(s + 2) == 0x01) &&
1646 (*(s + 3) == 0xb3)) { /* mpeg1 video header */
1653 static int _MMFileIsMP3Header(void *header)
1655 unsigned long head = 0;
1656 unsigned char *headc = header;
1657 unsigned int bitrate, layer, length/*, mode*/;
1658 unsigned int coef, samplerate, version/*, channels*/;
1659 static const unsigned int mp3types_bitrates[2][3][16] = {
1660 { {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448,},
1661 {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384,},
1662 {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320,}
1664 { {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256,},
1665 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,},
1666 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,}
1670 static const unsigned int mp3types_freqs[3][3] = {
1671 {11025, 12000, 8000},
1672 {22050, 24000, 16000},
1673 {44100, 48000, 32000}
1676 static const unsigned int mp3FrameCoef[4][4] = {
1684 head = (*(headc + 0) << 24 | *(headc + 1) << 16 | *(headc + 2) << 8 | *(headc + 3));
1686 if ((head & 0xffe00000) != 0xffe00000) {
1690 /* we don't need extension, copyright, original or
1691 * emphasis for the frame length */
1695 /*mode = head & 0x3;*/
1699 length = head & 0x1;
1702 /* sampling frequency */
1703 samplerate = head & 0x3;
1704 if (samplerate == 3) {
1710 bitrate = head & 0xF;
1712 if (bitrate == 15) {
1716 /* ignore error correction, too */
1720 layer = 4 - (head & 0x3);
1726 /* version 0=MPEG2.5; 2=MPEG2; 3=MPEG1 */
1727 version = head & 0x3;
1733 /*channels = (mode == 3) ? 1 : 2;*/
1734 samplerate = mp3types_freqs[version > 0 ? version - 1 : 0][samplerate];
1737 bitrate = mp3types_bitrates[version == 3 ? 0 : 1][layer - 1][bitrate];
1738 coef = mp3FrameCoef[version][layer];
1740 length = length * 4;
1742 length = length + ((coef * bitrate * 1000) / samplerate);
1748 static int _MMFileSearchID3Tag(MMFileIOHandle *fp, unsigned int *offset)
1750 #define _MMFILE_MP3_TAGV2_HEADER_LEN 10
1751 #define _MMFILE_GET_INT_NUMBER(buff) (int)((((int)(buff)[0]) << 24) | (((int)(buff)[1]) << 16) | (((int)(buff)[2]) << 8) | (((int)(buff)[3])))
1753 unsigned char tagHeader[_MMFILE_MP3_TAGV2_HEADER_LEN] = {0, };
1754 unsigned int tagInfoSize = 0;
1755 unsigned int acc_tagsize = 0;
1764 mmfile_seek(fp, 0, MMFILE_SEEK_SET);
1768 readed = mmfile_read(fp, tagHeader, _MMFILE_MP3_TAGV2_HEADER_LEN);
1769 if (readed != _MMFILE_MP3_TAGV2_HEADER_LEN) {
1770 debug_error(RELEASE, "read error occured.\n");
1774 if (memcmp(tagHeader, "ID3", 3) == 0) {
1775 debug_msg(RELEASE, "'ID3' found.\n");
1777 debug_msg(RELEASE, "'ID3' not found.\n");
1781 /**@note weak id3v2 tag checking*/
1782 if (tagHeader[3] != 0xFF && tagHeader[4] != 0xFF &&
1783 (tagHeader[6] & 0x80) == 0 && (tagHeader[7] & 0x80) == 0 &&
1784 (tagHeader[8] & 0x80) == 0 && (tagHeader[9] & 0x80) == 0) {
1785 debug_msg(RELEASE, "good ID3V2 tag.\n");
1787 debug_warning(DEBUG, "It's bad ID3V2 tag.\n");
1791 tagVersion = tagHeader[3];
1793 if (tagVersion > 4) {
1794 debug_msg(RELEASE, "Tag version not supported\n");
1798 encSize = _MMFILE_GET_INT_NUMBER(&tagHeader[6]);
1799 tagInfoSize = _MMFILE_MP3_TAGV2_HEADER_LEN;
1800 tagInfoSize += (((encSize & 0x0000007F) >> 0) | ((encSize & 0x00007F00) >> 1) | ((encSize & 0x007F0000) >> 2) | ((encSize & 0x7F000000) >> 3));
1802 /**@note unfortunately, some contents has many id3 tag.*/
1803 acc_tagsize += tagInfoSize;
1804 debug_msg(RELEASE, "tag size: %u, offset: %u\n", tagInfoSize, acc_tagsize);
1806 mmfile_seek(fp, acc_tagsize, MMFILE_SEEK_SET);
1807 *offset = acc_tagsize;
1811 goto _START_TAG_SEARCH;
1817 static int _MMFileIsFLACHeader(void *header)
1819 unsigned char *s = header;
1821 if (!memcmp(s, "fLaC", 4)) {
1828 static int _MMFileIsFLVHeader(void *header)
1830 unsigned char *s = header;
1832 if (!memcmp(s, "FLV", 3)) {
1839 static int _MMFileIsAIFFHeader(void *header)
1841 unsigned char *s = header;
1843 if (!memcmp(s, "FORM", 4) && !memcmp(s + 8, "AIFF", 4)) {
1849 static int _MMFileIsAPEHeader(void *header)
1851 unsigned char *s = header;
1853 if (!memcmp(s, "MAC ", 4)) {