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);
54 /***********************************************************************/
55 /* MP3 Header Check API */
56 /***********************************************************************/
58 int MMFileFormatIsValidMP3(MMFileIOHandle *pFileIO, const char *mmfileuri, int frameCnt)
60 #define _MMFILE_MP3_HEADER_LENGTH 4
61 #define _MMFILE_MP3_BUFFER_LENGTH 8200
63 MMFileIOHandle *fp = pFileIO;
64 unsigned char buffer[_MMFILE_MP3_BUFFER_LENGTH] = {0, };
65 long long filesize = 0;
66 unsigned int sizeID3 = 0;
67 int readed = 0, i = 0, j = 0;;
68 unsigned int startoffset = 0;
71 int ret = 0, count = 0, offset = 0;
74 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
75 if (ret == MMFILE_IO_FAILED) {
76 debug_error(DEBUG, "error: mmfile_open\n");
81 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
83 mmfile_seek(fp, 0L, MMFILE_SEEK_END);
84 filesize = mmfile_tell(fp);
85 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
87 if (filesize < _MMFILE_MP3_HEADER_LENGTH) {
88 debug_error(DEBUG, "header is too small.\n");
93 /* Search the existance of ID3 tag */
94 ret = _MMFileSearchID3Tag(fp, &sizeID3);
96 debug_error(RELEASE, "Error in searching the ID3 tag\n");
102 /* set begin and end point at the file */
103 startoffset += sizeID3;
104 endoffset = startoffset + 102400;
105 if (endoffset > filesize - _MMFILE_MP3_HEADER_LENGTH)
106 endoffset = filesize - _MMFILE_MP3_HEADER_LENGTH;
112 while (i < endoffset) {
113 mmfile_seek(fp, i, MMFILE_SEEK_SET);
114 readed = mmfile_read(fp, buffer, _MMFILE_MP3_BUFFER_LENGTH);
115 if (readed < _MMFILE_MP3_HEADER_LENGTH) {
116 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
122 for (j = 0; (j <= readed - _MMFILE_MP3_HEADER_LENGTH); j = j + offset) {
123 frameSize = _MMFileIsMP3Header(buffer + j);
129 if ((j + frameSize) >= (endoffset - (i + _MMFILE_MP3_HEADER_LENGTH))) {
133 if ((j + frameSize) >= (readed - _MMFILE_MP3_HEADER_LENGTH)) {
134 debug_msg(RELEASE, "MP3 coner hit %d %d\n", j, frameSize);
138 frameSize = _MMFileIsMP3Header(buffer + j + frameSize);
143 if (count == frameCnt) {
145 debug_msg(RELEASE, "Header Detected at %d\n", i + j);
154 /*If j is zero, this loop is infinite */
161 debug_msg(RELEASE, "Header Not Detected at: %d\n", i + j);
163 if (pFileIO == NULL && fp != NULL)
171 /***********************************************************************/
172 /* AAC Header Check API */
173 /***********************************************************************/
175 int MMFileFormatIsValidAAC(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
177 #define _MMFILE_AAC_HEADER_LENGTH 4
178 #define _MMFILE_AAC_BUFFER_LENGTH 8200
180 MMFileIOHandle *fp = pFileIO;
181 unsigned char buffer[_MMFILE_AAC_BUFFER_LENGTH] = {0, };
182 unsigned int sizeID3 = 0;
183 long long filesize = 0;
184 int readed = 0, i = 0, j = 0;
188 unsigned int sync = 0;
192 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
193 if (ret == MMFILE_IO_FAILED) {
194 debug_error(DEBUG, "error: mmfile_open\n");
199 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
201 /* Initialize the members of handle */
202 mmfile_seek(fp, 0, MMFILE_SEEK_END);
203 filesize = mmfile_tell(fp);
204 mmfile_seek(fp, 0, MMFILE_SEEK_SET);
206 if (filesize < _MMFILE_AAC_HEADER_LENGTH) {
207 debug_error(DEBUG, "header is too small.\n");
212 /* Search the existance of ID3 tag */
213 ret = _MMFileSearchID3Tag(fp, &sizeID3);
215 debug_error(RELEASE, "Error in searching the ID3 tag\n");
221 /* set begin and end point at the file */
222 startoffset += sizeID3;
223 endoffset = startoffset + 10240;
224 if (endoffset > filesize - _MMFILE_AAC_HEADER_LENGTH)
225 endoffset = filesize - _MMFILE_AAC_HEADER_LENGTH;
229 while (i < endoffset) {
230 mmfile_seek(fp, i, MMFILE_SEEK_SET);
232 readed = mmfile_read(fp, buffer, _MMFILE_AAC_BUFFER_LENGTH);
234 if (readed < _MMFILE_AAC_HEADER_LENGTH) {
235 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
240 debug_msg(RELEASE, "read error. size = %d. i = %d\n", readed, i);
242 for (j = 0; (j < readed - _MMFILE_AAC_HEADER_LENGTH); j++) {
244 sync = ((buffer[j] << 8) | (buffer[j + 1]));
246 if ((sync & 0xFFF6) == 0xFFF0) {
247 frameSize = (((buffer[j + 3] & 0x03) << 11) | (buffer[j + 4] << 3) | ((buffer[j + 5] & 0xE0) >> 5));
249 if (frameSize == 0) {
253 if ((j + frameSize) >= (endoffset - (i + 2))) {
256 if ((j + frameSize) >= (readed - 2)) {
257 debug_msg(RELEASE, "AAC coner hit %d %d\n", j, frameSize);
261 sync = ((buffer[j + frameSize] << 8) | (buffer[j + frameSize + 1]));
263 if ((sync & 0xFFF6) == 0xFFF0) {
265 debug_msg(RELEASE, "AAC ADTS Header Detected at %d\n", i + j);
268 } else if (!memcmp((buffer + j), "ADIF", 4)) {
270 debug_msg(RELEASE, "AAC ADIF Header Detected at %d\n", i + j);
274 /*If j is zero, this loop is infinite */
282 debug_msg(RELEASE, "Header Detected Failed\n");
284 if (pFileIO == NULL && fp != NULL)
292 /***********************************************************************/
293 /* OGG Header Check API */
294 /***********************************************************************/
296 int MMFileFormatIsValidOGG(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
298 #define _MMFILE_OGG_HEADER_LENGTH 4
299 #define _MMFILE_OGG_BUFFER_LENGTH 512
300 #define _MMFILE_OGG_CHECK_LIMIT (_MMFILE_OGG_HEADER_LENGTH * 1000)
302 MMFileIOHandle *fp = pFileIO;
303 unsigned char buffer[_MMFILE_OGG_BUFFER_LENGTH] = {0, };
304 unsigned int sizeID3 = 0;
305 long long filesize = 0;
306 int readed = 0, i = 0, j = 0;
313 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
314 if (ret == MMFILE_IO_FAILED) {
315 debug_error(DEBUG, "error: mmfile_open\n");
321 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
323 /* Initialize the members of handle */
324 mmfile_seek(fp, 0, MMFILE_SEEK_END);
325 filesize = mmfile_tell(fp);
326 mmfile_seek(fp, 0, MMFILE_SEEK_SET);
328 if (filesize < _MMFILE_OGG_HEADER_LENGTH) {
329 debug_error(DEBUG, "header is too small.\n");
334 /* Search the existance of ID3 tag */
335 ret = _MMFileSearchID3Tag(fp, &sizeID3);
337 debug_error(RELEASE, "Error in searching the ID3 tag\n");
343 /* set begin and end point at the file */
344 startoffset += sizeID3;
345 endoffset = filesize - _MMFILE_OGG_HEADER_LENGTH;
347 check_limit = (endoffset > _MMFILE_OGG_CHECK_LIMIT) ? _MMFILE_OGG_CHECK_LIMIT : endoffset;
350 while (i <= check_limit) {
351 mmfile_seek(fp, i, MMFILE_SEEK_SET);
352 readed = mmfile_read(fp, buffer, _MMFILE_OGG_BUFFER_LENGTH);
353 if (readed < _MMFILE_OGG_HEADER_LENGTH) {
354 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
359 for (j = 0; (j <= readed - _MMFILE_OGG_HEADER_LENGTH); j++) {
360 if (1 == _MMFileIsOGGHeader(buffer + j)) {
362 debug_msg(RELEASE, "Header Detected at %d\n", i + j);
367 memset(buffer, 0x00, _MMFILE_OGG_BUFFER_LENGTH);
373 if (pFileIO == NULL && fp != NULL)
381 /***********************************************************************/
382 /* MIDI Header Check API */
383 /***********************************************************************/
385 int MMFileFormatIsValidMID(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
387 #define _MMFILE_MIDI_HEADER_LENGTH 4
388 #define _MMFILE_MIDI_BUFFER_LENGTH 512
389 #define _MMFILE_MIDI_CHECK_LIMIT (_MMFILE_MIDI_HEADER_LENGTH * 1024)
391 MMFileIOHandle *fp = pFileIO;
392 unsigned char buffer[_MMFILE_MIDI_BUFFER_LENGTH] = {0, };
393 long long filesize = 0;
394 int readed = 0, i = 0, j = 0;
401 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
402 if (ret == MMFILE_IO_FAILED) {
403 debug_error(DEBUG, "error: mmfile_open\n");
408 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
410 /* Initialize the members of handle */
411 mmfile_seek(fp, 0, MMFILE_SEEK_END);
412 filesize = mmfile_tell(fp);
413 mmfile_seek(fp, 0, MMFILE_SEEK_SET);
415 if (filesize < _MMFILE_MIDI_HEADER_LENGTH) {
416 debug_error(DEBUG, "header is too small.\n");
423 /* set begin and end point at the file */
425 endoffset = filesize - _MMFILE_MIDI_HEADER_LENGTH;
427 check_limit = (endoffset > _MMFILE_MIDI_CHECK_LIMIT) ? _MMFILE_MIDI_CHECK_LIMIT : endoffset;
430 while (i <= check_limit) {
431 mmfile_seek(fp, i, MMFILE_SEEK_SET);
432 readed = mmfile_read(fp, buffer, _MMFILE_MIDI_BUFFER_LENGTH);
433 if (readed < _MMFILE_MIDI_HEADER_LENGTH) {
434 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
439 for (j = 0; (j <= readed - _MMFILE_MIDI_HEADER_LENGTH); j++) {
440 if (1 == _MMFileIsMIDHeader(buffer + j)) {
442 debug_msg(RELEASE, "Header Detected at %d\n", i + j);
447 memset(buffer, 0x00, _MMFILE_MIDI_BUFFER_LENGTH);
453 if (pFileIO == NULL && fp != NULL)
460 /***********************************************************************/
461 /* WAV Header Check API */
462 /***********************************************************************/
464 int MMFileFormatIsValidWAV(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
466 #define _MMFILE_WAV_HEADER_LENGTH 15
468 MMFileIOHandle *fp = pFileIO;
469 unsigned char buffer[_MMFILE_WAV_HEADER_LENGTH] = {0, };
474 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
475 if (ret == MMFILE_IO_FAILED) {
476 debug_error(DEBUG, "error: mmfile_open\n");
481 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
483 readed = mmfile_read(fp, buffer, _MMFILE_WAV_HEADER_LENGTH);
485 if (_MMFILE_WAV_HEADER_LENGTH != readed) {
486 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
491 if (1 == _MMFileIsWAVHeader(buffer)) {
492 debug_msg(RELEASE, "Header Detected\n");
498 if (pFileIO == NULL && fp != NULL)
506 /***********************************************************************/
507 /* MP4 Header Check API */
508 /***********************************************************************/
510 int MMFileFormatIsValidMP4(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
512 #define _MMFILE_MP4_HEADER_LENGTH 4
513 #define _MMFILE_MP4_CHECK_LIMIT (1024*10) /*10Kbyte*/
514 MMFileIOHandle *fp = pFileIO;
515 unsigned char buffer[_MMFILE_MP4_HEADER_LENGTH] = {0, };
516 long long filesize = 0;
518 unsigned int startoffset = 0;
520 unsigned int check_limit = 0;
523 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
524 if (ret == MMFILE_IO_FAILED) {
525 debug_error(DEBUG, "error: mmfile_open\n");
530 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
532 /* Initialize the members of handle */
533 mmfile_seek(fp, 0, MMFILE_SEEK_END);
534 filesize = mmfile_tell(fp);
535 mmfile_seek(fp, 0, MMFILE_SEEK_SET);
537 if (filesize < _MMFILE_MP4_HEADER_LENGTH) {
538 debug_error(DEBUG, "header is too small.\n");
545 /**@note weak check*/
546 check_limit = (filesize > _MMFILE_MP4_CHECK_LIMIT) ? _MMFILE_MP4_CHECK_LIMIT : filesize;
547 for (startoffset = 0; check_limit - (startoffset + _MMFILE_MP4_HEADER_LENGTH) > 0; startoffset++) {
548 mmfile_seek(fp, startoffset, MMFILE_SEEK_SET);
550 readed = mmfile_read(fp, buffer, _MMFILE_MP4_HEADER_LENGTH);
551 if (readed != _MMFILE_MP4_HEADER_LENGTH) {
552 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
558 if (1 == _MMFileIsMP4Header(buffer)) {
559 debug_msg(RELEASE, "MP4 Header Detected\n");
566 if (pFileIO == NULL && fp != NULL)
573 /***********************************************************************/
574 /* AVI Header Check API */
575 /***********************************************************************/
577 int MMFileFormatIsValidAVI(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
579 #define _MMFILE_AVI_HEADER_LENGTH 12
581 MMFileIOHandle *fp = pFileIO;
582 unsigned char buffer[_MMFILE_AVI_HEADER_LENGTH] = {0, };
587 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
588 if (ret == MMFILE_IO_FAILED) {
589 debug_error(DEBUG, "error: mmfile_open\n");
594 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
596 readed = mmfile_read(fp, buffer, _MMFILE_AVI_HEADER_LENGTH);
598 if (_MMFILE_AVI_HEADER_LENGTH != readed) {
599 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
604 if (1 == _MMFileIsAVIHeader(buffer)) {
605 debug_msg(RELEASE, "Header Detected \n");
611 if (pFileIO == NULL && fp != NULL)
619 /***********************************************************************/
620 /* ASF Header Check API */
621 /***********************************************************************/
623 int MMFileFormatIsValidASF(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
625 #define _MMFILE_ASF_HEADER_LENGTH 16
626 MMFileIOHandle *fp = pFileIO;
627 unsigned char buffer[_MMFILE_ASF_HEADER_LENGTH] = {0, };
632 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
633 if (ret == MMFILE_IO_FAILED) {
634 debug_error(DEBUG, "error: mmfile_open\n");
639 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
641 readed = mmfile_read(fp, buffer, _MMFILE_ASF_HEADER_LENGTH);
643 if (_MMFILE_ASF_HEADER_LENGTH != readed) {
644 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
649 if (1 == _MMFileIsASFHeader(buffer)) {
650 debug_msg(RELEASE, "Header Detected\n");
656 if (pFileIO == NULL && fp != NULL)
662 /***********************************************************************/
663 /* WMA Header Check API */
664 /***********************************************************************/
666 int MMFileFormatIsValidWMA(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
668 #define _MMFILE_ASF_HEADER_LENGTH 16
669 MMFileIOHandle *fp = pFileIO;
670 unsigned char buffer[_MMFILE_ASF_HEADER_LENGTH] = {0, };
675 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
676 if (ret == MMFILE_IO_FAILED) {
677 debug_error(DEBUG, "error: mmfile_open\n");
682 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
684 readed = mmfile_read(fp, buffer, _MMFILE_ASF_HEADER_LENGTH);
686 if (_MMFILE_ASF_HEADER_LENGTH != readed) {
687 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
693 if (1 == _MMFileIsASFHeader(buffer)) {
694 debug_msg(RELEASE, "Header Detected\n");
700 if (pFileIO == NULL && fp != NULL)
708 /***********************************************************************/
709 /* WMV Header Check API */
710 /***********************************************************************/
712 int MMFileFormatIsValidWMV(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
714 #define _MMFILE_ASF_HEADER_LENGTH 16
715 MMFileIOHandle *fp = pFileIO;
716 unsigned char buffer[_MMFILE_ASF_HEADER_LENGTH] = {0, };
721 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
722 if (ret == MMFILE_IO_FAILED) {
723 debug_error(DEBUG, "error: mmfile_open\n");
728 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
730 readed = mmfile_read(fp, buffer, _MMFILE_ASF_HEADER_LENGTH);
732 if (_MMFILE_ASF_HEADER_LENGTH != readed) {
733 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
738 if (1 == _MMFileIsASFHeader(buffer)) {
739 debug_msg(RELEASE, "Header Detected\n");
745 if (pFileIO == NULL && fp != NULL)
752 /***********************************************************************/
753 /* MMF Header Check API */
754 /***********************************************************************/
756 int MMFileFormatIsValidMMF(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
758 #define _MMFILE_MMF_HEADER_LENGTH 18
760 MMFileIOHandle *fp = pFileIO;
761 unsigned char buffer[_MMFILE_MMF_HEADER_LENGTH] = {0, };
766 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
767 if (ret == MMFILE_IO_FAILED) {
768 debug_error(DEBUG, "error: mmfile_open\n");
773 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
775 readed = mmfile_read(fp, buffer, _MMFILE_MMF_HEADER_LENGTH);
777 if (_MMFILE_MMF_HEADER_LENGTH != readed) {
778 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
783 if (1 == _MMFileIsMMFHeader(buffer)) {
784 debug_msg(RELEASE, "Header Detected\n");
790 if (pFileIO == NULL && fp != NULL)
798 /***********************************************************************/
799 /* MMF Header Check API */
800 /***********************************************************************/
802 int MMFileFormatIsValidIMY(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
804 #define _MMFILE_IMY_HEADER_LENGTH 13
806 MMFileIOHandle *fp = pFileIO;
807 unsigned char buffer[_MMFILE_IMY_HEADER_LENGTH] = {0, };
812 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
813 if (ret == MMFILE_IO_FAILED) {
814 debug_error(DEBUG, "error: mmfile_open\n");
819 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
821 readed = mmfile_read(fp, buffer, _MMFILE_IMY_HEADER_LENGTH);
823 if (_MMFILE_IMY_HEADER_LENGTH != readed) {
824 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
829 if (1 == _MMFileIsIMYHeader(buffer)) {
830 debug_msg(RELEASE, "Header Detected\n");
836 if (pFileIO == NULL && fp != NULL)
844 /***********************************************************************/
845 /* AMR Header Check API */
846 /***********************************************************************/
848 int MMFileFormatIsValidAMR(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
850 #define _MMFILE_AMR_MAX_HEADER_SIZE 15
851 #define _MMFILE_AMR_MIN_HEADER_SIZE 6
853 MMFileIOHandle *fp = pFileIO;
854 unsigned char buffer[_MMFILE_AMR_MAX_HEADER_SIZE] = {0, };
859 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
860 if (ret == MMFILE_IO_FAILED) {
861 debug_error(DEBUG, "error: mmfile_open\n");
866 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
868 readed = mmfile_read(fp, buffer, _MMFILE_AMR_MAX_HEADER_SIZE);
870 if (_MMFILE_AMR_MAX_HEADER_SIZE != readed) {
871 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
876 if (1 == _MMFileIsAMRHeader(buffer)) {
877 debug_msg(RELEASE, "Header Detected\n");
883 if (pFileIO == NULL && fp != NULL)
889 /***********************************************************************/
890 /* Matroska Header Check API */
891 /***********************************************************************/
893 int MMFileFormatIsValidMatroska(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
895 #define _MMFILE_EBML_MARKER_LENGTH 4
896 #define _MMFILE_MKV_READ_BUFFER_LENGTH 2048
898 MMFileIOHandle *fp = pFileIO;
899 unsigned char buffer[_MMFILE_MKV_READ_BUFFER_LENGTH] = {0, };
903 unsigned int size = 1, n = 1, total = 0;
904 char probe_data[] = { 'm', 'a', 't', 'r', 'o', 's', 'k', 'a' };
907 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
908 if (ret == MMFILE_IO_FAILED) {
909 debug_error(DEBUG, "error: mmfile_open\n");
914 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
916 readed = mmfile_read(fp, buffer, _MMFILE_MKV_READ_BUFFER_LENGTH);
918 if (_MMFILE_MKV_READ_BUFFER_LENGTH != readed) {
919 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
925 if (buffer[0] != 0x1A || buffer[1] != 0x45 || buffer[2] != 0xDF || buffer[3] != 0xA3) {
926 debug_msg(RELEASE, "This is not a EBML format\n");
931 /* length of header */
934 debug_msg(RELEASE, "Initial total header size = [0x%x]\n", total);
936 while (size <= 8 && !(total & len_mask)) {
937 debug_msg(DEBUG, "This case can not be handled yet....");
942 debug_msg(RELEASE, "Final total header size = [%d]\n", total);
945 debug_msg(DEBUG, "This case can not be handled yet....");
950 total &= (len_mask - 1);
953 total = (total << 8) | buffer[4 + n++];
954 debug_msg(DEBUG, "This case can not be handled yet....");
957 /* Does the probe data contain the whole header? */
958 if (_MMFILE_MKV_READ_BUFFER_LENGTH < 4 + size + total)
961 for (n = 4 + size ; n <= 4 + size + total - sizeof(probe_data); n++) {
962 if (!memcmp(&buffer[n], probe_data, sizeof(probe_data))) {
963 debug_msg(RELEASE, "String matroska found!!!\n");
970 if (pFileIO == NULL && fp != NULL)
976 /***********************************************************************/
977 /* QT Header Check API */
978 /***********************************************************************/
980 int MMFileFormatIsValidQT(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
985 /***********************************************************************/
986 /* Flac Header Check API */
987 /***********************************************************************/
989 int MMFileFormatIsValidFLAC(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
991 #define _MMFILE_FLAC_HEADER_LENGTH 5 /*fLaC*/
993 MMFileIOHandle *fp = pFileIO;
994 unsigned char buffer[_MMFILE_FLAC_HEADER_LENGTH] = {0, };
999 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
1000 if (ret == MMFILE_IO_FAILED) {
1001 debug_error(DEBUG, "error: mmfile_open\n");
1006 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
1008 readed = mmfile_read(fp, buffer, _MMFILE_FLAC_HEADER_LENGTH);
1010 if (_MMFILE_FLAC_HEADER_LENGTH != readed) {
1011 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
1016 if (1 == _MMFileIsFLACHeader(buffer)) {
1017 debug_msg(RELEASE, "Header Detected\n");
1023 if (pFileIO == NULL && fp != NULL)
1029 /***********************************************************************/
1030 /* FLV(flash video) Header Check API */
1031 /***********************************************************************/
1033 int MMFileFormatIsValidFLV(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
1035 #define _MMFILE_FLV_HEADER_LENGTH 4 /*FLV*/
1037 MMFileIOHandle *fp = pFileIO;
1038 unsigned char buffer[_MMFILE_FLV_HEADER_LENGTH] = {0, };
1043 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
1044 if (ret == MMFILE_IO_FAILED) {
1045 debug_error(DEBUG, "error: mmfile_open\n");
1050 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
1052 readed = mmfile_read(fp, buffer, _MMFILE_FLV_HEADER_LENGTH);
1054 if (_MMFILE_FLV_HEADER_LENGTH != readed) {
1055 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
1060 if (1 == _MMFileIsFLVHeader(buffer)) {
1061 debug_msg(RELEASE, "Header Detected\n");
1067 if (pFileIO == NULL && fp != NULL)
1074 /***********************************************************************/
1075 /* REAL Header Check API */
1076 /***********************************************************************/
1078 int MMFileFormatIsValidREAL(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
1080 #define _MMFILE_RMVB_HEADER_LENGTH 4 /*RMF*/
1082 MMFileIOHandle *fp = pFileIO;
1083 unsigned char buffer[_MMFILE_RMVB_HEADER_LENGTH] = {0, };
1088 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
1089 if (ret == MMFILE_IO_FAILED) {
1090 debug_error(DEBUG, "error: mmfile_open\n");
1095 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
1097 readed = mmfile_read(fp, buffer, _MMFILE_RMVB_HEADER_LENGTH);
1099 if (_MMFILE_RMVB_HEADER_LENGTH != readed) {
1100 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
1105 if (1 == _MMFileIsREALHeader(buffer)) {
1106 debug_msg(RELEASE, "Header Detected\n");
1113 if (pFileIO == NULL && fp != NULL)
1119 /***********************************************************************/
1120 /* MPEGTS Header Check API */
1121 /***********************************************************************/
1122 #define MPEGTS_NONE 0x00
1123 #define MPEGTS_FECE 0x10
1124 #define MPEGTS_DVHS 0x20
1125 #define MPEGTS_PACKET 0x40
1127 #define TS_PACKET_SIZE 188
1128 #define TS_DVHS_PACKET_SIZE 192
1129 #define TS_FEC_PACKET_SIZE 204
1130 #define TS_MAX_PACKET_SIZE 204
1133 int MMFileFormatIsValidMPEGTS(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
1135 MMFileIOHandle *fp = pFileIO;
1136 unsigned char buffer[TS_MAX_PACKET_SIZE] = {0, };
1141 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
1142 if (ret == MMFILE_IO_FAILED) {
1143 debug_error(DEBUG, "error: mmfile_open\n");
1148 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
1150 readed = mmfile_read(fp, buffer, TS_MAX_PACKET_SIZE);
1152 if (TS_MAX_PACKET_SIZE != readed) {
1153 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
1158 if (_MMFileIsMPEGTSHeader(fp) != MPEGTS_NONE) {
1159 debug_msg(RELEASE, "Header Detected\n");
1165 if (pFileIO == NULL && fp != NULL)
1171 /***********************************************************************/
1172 /* MPEG-PS Header Check API */
1173 /***********************************************************************/
1175 int MMFileFormatIsValidMPEGPS(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
1177 #define _MMFILE_MPEGPS_HEADER_LENGTH 4
1179 MMFileIOHandle *fp = pFileIO;
1180 unsigned char buffer[_MMFILE_MPEGPS_HEADER_LENGTH] = {0, };
1185 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
1186 if (ret == MMFILE_IO_FAILED) {
1187 debug_error(DEBUG, "error: mmfile_open\n");
1192 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
1194 readed = mmfile_read(fp, buffer, _MMFILE_MPEGPS_HEADER_LENGTH);
1196 if (_MMFILE_MPEGPS_HEADER_LENGTH != readed) {
1197 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
1202 if (1 == _MMFileIsMPEGPSHeader(buffer)) {
1203 debug_msg(RELEASE, "Header Detected\n");
1209 if (pFileIO == NULL && fp != NULL)
1215 /***********************************************************************/
1216 /* MPEG AUDIO Header Check API */
1217 /***********************************************************************/
1219 int MMFileFormatIsValidMPEGAUDIO(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
1221 #define _MMFILE_MPEGAUDIO_HEADER_LENGTH 4
1223 MMFileIOHandle *fp = pFileIO;
1224 unsigned char buffer[_MMFILE_MPEGAUDIO_HEADER_LENGTH] = {0, };
1229 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
1230 if (ret == MMFILE_IO_FAILED) {
1231 debug_error(DEBUG, "error: mmfile_open\n");
1236 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
1238 readed = mmfile_read(fp, buffer, _MMFILE_MPEGAUDIO_HEADER_LENGTH);
1240 if (_MMFILE_MPEGAUDIO_HEADER_LENGTH != readed) {
1241 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
1246 if (1 == _MMFileIsMPEGAUDIOHeader(buffer)) {
1247 debug_msg(RELEASE, "Header Detected\n");
1253 if (pFileIO == NULL && fp != NULL)
1259 /***********************************************************************/
1260 /* MPEG VIDEO Header Check API */
1261 /***********************************************************************/
1263 int MMFileFormatIsValidMPEGVIDEO(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
1265 #define _MMFILE_MPEGVIDEO_HEADER_LENGTH 4
1267 MMFileIOHandle *fp = pFileIO;
1268 unsigned char buffer[_MMFILE_MPEGVIDEO_HEADER_LENGTH] = {0, };
1273 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
1274 if (ret == MMFILE_IO_FAILED) {
1275 debug_error(DEBUG, "error: mmfile_open\n");
1280 mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
1282 readed = mmfile_read(fp, buffer, _MMFILE_MPEGVIDEO_HEADER_LENGTH);
1284 if (_MMFILE_MPEGVIDEO_HEADER_LENGTH != readed) {
1285 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
1290 if (1 == _MMFileIsMPEGVIDEOHeader(buffer)) {
1291 debug_msg(RELEASE, "Header Detected\n");
1297 if (pFileIO == NULL && fp != NULL)
1306 /***********************************************************************/
1307 /* Implementation of Internal Functions */
1308 /***********************************************************************/
1309 static int _MMFileIsASFHeader(void *header)
1311 /* ID: 30 26 B2 75 8E 66 CF 11 A6 D9 00 AA 00 62 CE 6C */
1312 unsigned char *s = header;
1314 if ((*(s + 0) == 0x30) &&
1315 (*(s + 1) == 0x26) &&
1316 (*(s + 2) == 0xB2) &&
1317 (*(s + 3) == 0x75) &&
1318 (*(s + 4) == 0x8E) &&
1319 (*(s + 5) == 0x66) &&
1320 (*(s + 6) == 0xCF) &&
1321 (*(s + 7) == 0x11) &&
1322 (*(s + 8) == 0xA6) &&
1323 (*(s + 9) == 0xD9) &&
1324 (*(s + 10) == 0x00) &&
1325 (*(s + 11) == 0xAA) &&
1326 (*(s + 12) == 0x00) &&
1327 (*(s + 13) == 0x62) &&
1328 (*(s + 14) == 0xCE) &&
1329 (*(s + 15) == 0x6C)) {
1337 static int _MMFileIsAMRHeader(void *header)
1339 #define _MMFILE_AMR_SINGLE_CH_HEADER_SIZE 6
1340 #define _MMFILE_AMR_SINGLE_CH_HEADER "#!AMR\n"
1342 #define _MMFILE_AMR_WB_SINGLE_CH_HEADER_SIZE 9
1343 #define _MMFILE_AMR_WB_SINGLE_CH_HEADER "#!AMR-WB\n"
1345 #define _MMFILE_AMR_MULTI_CH_HEADER_SIZE 12
1346 #define _MMFILE_AMR_MULTI_CH_HEADER "#!AMR_MC1.0\n"
1348 #define _MMFILE_AMR_WB_MULTI_CH_HEADER_SIZE 15
1349 #define _MMFILE_AMR_WB_MULTI_CH_HEADER "#!AMR-WB_MC1.0\n"
1351 unsigned char *s = header;
1353 if (!memcmp(s, _MMFILE_AMR_SINGLE_CH_HEADER, _MMFILE_AMR_SINGLE_CH_HEADER_SIZE) ||
1354 !memcmp(s, _MMFILE_AMR_WB_SINGLE_CH_HEADER, _MMFILE_AMR_WB_SINGLE_CH_HEADER_SIZE) ||
1355 !memcmp(s, _MMFILE_AMR_MULTI_CH_HEADER, _MMFILE_AMR_MULTI_CH_HEADER_SIZE) ||
1356 !memcmp(s, _MMFILE_AMR_WB_MULTI_CH_HEADER, _MMFILE_AMR_WB_MULTI_CH_HEADER_SIZE)) {
1364 static int _MMFileIsIMYHeader(void *header)
1366 unsigned char *s = header;
1368 if (!memcmp(s, "BEGIN:IMELODY", 13)) {
1375 static int _MMFileIsMIDHeader(void *header)
1377 unsigned char *s = header;
1379 if (!memcmp(s, "MThd", 4)) { /*general MIDI*/
1381 } else if (!memcmp(s, "XMF_", 4)) { /*XMF*/
1383 } else if (!memcmp(s, "IREZ", 4)) {
1384 return 1; /*RMF format*/
1390 static int _MMFileIsMMFHeader(void *header)
1392 #define _MMFILE_MMF_TYPE_POSITION ((char)0x11)
1393 unsigned char *s = header;
1395 if (!memcmp(s, "MMMD", 4)) {
1396 /* warning: comparison is always true due to limited range of data type */
1397 if (*(s + _MMFILE_MMF_TYPE_POSITION) <= 0x2F) {
1399 } else if (((*(s + _MMFILE_MMF_TYPE_POSITION) >= 0x30) && (*(s + _MMFILE_MMF_TYPE_POSITION) <= 0x38)) /* MA3, MA5 type */
1400 || ((*(s + _MMFILE_MMF_TYPE_POSITION) >= 0x40) && (*(s + _MMFILE_MMF_TYPE_POSITION) <= 0x48))
1401 || ((*(s + _MMFILE_MMF_TYPE_POSITION) >= 0x50) && (*(s + _MMFILE_MMF_TYPE_POSITION) <= 0x58))
1402 || ((*(s + _MMFILE_MMF_TYPE_POSITION) == 0xF0))) {
1412 static int _MMFileIsAVIHeader(void *header)
1414 unsigned char *s = header;
1416 if (!memcmp(s, "RIFF", 4) && !memcmp(s + 8, "AVI", 3)) {
1424 static int _MMFileIsWAVHeader(void *header)
1426 unsigned char *s = header;
1428 if (!memcmp(s, "RIFF", 4) && !memcmp(s + 8, "WAVE", 4)) {
1437 static int _MMFileIsMP4Header(void *header)
1439 unsigned char *s = header;
1441 if (!memcmp(s, "moov", 4) ||
1442 !memcmp(s, "mdat", 4) ||
1443 !memcmp(s, "ftyp", 4) ||
1444 !memcmp(s, "free", 4) ||
1445 !memcmp(s, "uuid", 4) ||
1446 !memcmp(s, "skip", 4) ||
1448 !memcmp(s, "PICT", 4) ||
1449 !memcmp(s, "wide", 4) ||
1450 !memcmp(s, "prfl", 4)) {
1457 static int _MMFileIsOGGHeader(void *header)
1459 unsigned char *s = header;
1461 if (!memcmp(s, "OggS", 4)) {
1468 static int _MMFileIsREALHeader(void *header)
1470 unsigned char *s = header;
1472 if (!memcmp(s, ".RMF", 4)) {
1479 static int _MMFileIsMPEGTSHeader(MMFileIOHandle *fp)
1481 unsigned char header[TS_MAX_PACKET_SIZE] = {0, };
1482 unsigned char *s = NULL;
1484 mmfile_seek(fp, 0, MMFILE_SEEK_SET);
1485 mmfile_read(fp, header, sizeof(header));
1487 s = (unsigned char *)memchr(header, 0x47, sizeof(header));
1490 unsigned char buffer[TS_PACKET_SIZE] = {0, };
1491 unsigned int startoffset = s - header + 1;
1493 mmfile_seek(fp, startoffset, MMFILE_SEEK_SET);
1494 mmfile_read(fp, buffer, sizeof(buffer));
1496 if (buffer[sizeof(buffer) - 1] & 0x47) {
1497 return MPEGTS_PACKET;
1499 unsigned char dvhs_buf[TS_DVHS_PACKET_SIZE] = {0, };
1501 mmfile_seek(fp, startoffset, MMFILE_SEEK_SET);
1502 mmfile_read(fp, dvhs_buf, sizeof(dvhs_buf));
1504 if (dvhs_buf[sizeof(dvhs_buf) - 1] & 0x47) {
1507 unsigned char fec_buf[TS_FEC_PACKET_SIZE] = {0, };
1509 mmfile_seek(fp, startoffset, MMFILE_SEEK_SET);
1510 mmfile_read(fp, fec_buf, sizeof(fec_buf));
1512 if (fec_buf[sizeof(fec_buf) - 1] & 0x47) {
1522 static int _MMFileIsMPEGPSHeader(void *header)
1524 unsigned char *s = header;
1526 if ((*(s + 0) == 0x00) &&
1527 (*(s + 1) == 0x00) &&
1528 (*(s + 2) == 0x01) &&
1529 (*(s + 3) == 0xba)) { /* mpeg-ps header */
1536 static int _MMFileIsMPEGAUDIOHeader(void *header)
1538 unsigned char *s = header;
1540 if ((*(s + 0) == 0xFF) &&
1541 ((*(s + 1) == 0xFE) || (*(s + 1) == 0xFF))) { /* mpeg audio layer 1 header ,FE: protected by CRC ,FF: not protected */
1548 static int _MMFileIsMPEGVIDEOHeader(void *header)
1550 unsigned char *s = header;
1552 if ((*(s + 0) == 0x00) &&
1553 (*(s + 1) == 0x00) &&
1554 (*(s + 2) == 0x01) &&
1555 (*(s + 3) == 0xb3)) { /* mpeg1 video header */
1562 static int _MMFileIsMP3Header(void *header)
1564 unsigned long head = 0;
1565 unsigned char *headc = header;
1566 unsigned int bitrate, layer, length/*, mode*/;
1567 unsigned int coef, samplerate, version/*, channels*/;
1568 static const unsigned int mp3types_bitrates[2][3][16] = {
1569 { {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448,},
1570 {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384,},
1571 {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320,}
1573 { {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256,},
1574 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,},
1575 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,}
1579 static const unsigned int mp3types_freqs[3][3] = {
1580 {11025, 12000, 8000},
1581 {22050, 24000, 16000},
1582 {44100, 48000, 32000}
1585 static const unsigned int mp3FrameCoef[4][4] = {
1593 head = (*(headc + 0) << 24 | *(headc + 1) << 16 | *(headc + 2) << 8 | *(headc + 3));
1595 if ((head & 0xffe00000) != 0xffe00000) {
1599 /* we don't need extension, copyright, original or
1600 * emphasis for the frame length */
1604 /*mode = head & 0x3;*/
1608 length = head & 0x1;
1611 /* sampling frequency */
1612 samplerate = head & 0x3;
1613 if (samplerate == 3) {
1619 bitrate = head & 0xF;
1621 if (bitrate == 15) {
1625 /* ignore error correction, too */
1629 layer = 4 - (head & 0x3);
1635 /* version 0=MPEG2.5; 2=MPEG2; 3=MPEG1 */
1636 version = head & 0x3;
1642 /*channels = (mode == 3) ? 1 : 2;*/
1643 samplerate = mp3types_freqs[version > 0 ? version - 1 : 0][samplerate];
1646 bitrate = mp3types_bitrates[version == 3 ? 0 : 1][layer - 1][bitrate];
1647 coef = mp3FrameCoef[version][layer];
1649 length = length * 4;
1651 length = length + ((coef * bitrate * 1000) / samplerate);
1657 static int _MMFileSearchID3Tag(MMFileIOHandle *fp, unsigned int *offset)
1659 #define _MMFILE_MP3_TAGV2_HEADER_LEN 10
1660 #define _MMFILE_GET_INT_NUMBER(buff) (int)((((int)(buff)[0]) << 24) | (((int)(buff)[1]) << 16) | (((int)(buff)[2]) << 8) | (((int)(buff)[3])))
1662 unsigned char tagHeader[_MMFILE_MP3_TAGV2_HEADER_LEN] = {0, };
1663 unsigned int tagInfoSize = 0;
1664 unsigned int acc_tagsize = 0;
1673 mmfile_seek(fp, 0, MMFILE_SEEK_SET);
1677 readed = mmfile_read(fp, tagHeader, _MMFILE_MP3_TAGV2_HEADER_LEN);
1678 if (readed != _MMFILE_MP3_TAGV2_HEADER_LEN) {
1679 debug_error(RELEASE, "read error occured.\n");
1683 if (memcmp(tagHeader, "ID3", 3) == 0) {
1684 debug_msg(RELEASE, "'ID3' found.\n");
1686 debug_msg(RELEASE, "'ID3' not found.\n");
1690 /**@note weak id3v2 tag checking*/
1691 if (tagHeader[3] != 0xFF && tagHeader[4] != 0xFF &&
1692 (tagHeader[6] & 0x80) == 0 && (tagHeader[7] & 0x80) == 0 &&
1693 (tagHeader[8] & 0x80) == 0 && (tagHeader[9] & 0x80) == 0) {
1694 debug_msg(RELEASE, "good ID3V2 tag.\n");
1696 debug_warning(DEBUG, "It's bad ID3V2 tag.\n");
1700 tagVersion = tagHeader[3];
1702 if (tagVersion > 4) {
1703 debug_msg(RELEASE, "Tag version not supported\n");
1707 encSize = _MMFILE_GET_INT_NUMBER(&tagHeader[6]);
1708 tagInfoSize = _MMFILE_MP3_TAGV2_HEADER_LEN;
1709 tagInfoSize += (((encSize & 0x0000007F) >> 0) | ((encSize & 0x00007F00) >> 1) | ((encSize & 0x007F0000) >> 2) | ((encSize & 0x7F000000) >> 3));
1711 /**@note unfortunately, some contents has many id3 tag.*/
1712 acc_tagsize += tagInfoSize;
1713 debug_msg(RELEASE, "tag size: %u, offset: %u\n", tagInfoSize, acc_tagsize);
1715 mmfile_seek(fp, acc_tagsize, MMFILE_SEEK_SET);
1716 *offset = acc_tagsize;
1720 goto _START_TAG_SEARCH;
1726 static int _MMFileIsFLACHeader(void *header)
1728 unsigned char *s = header;
1730 if (!memcmp(s, "fLaC", 4)) {
1737 static int _MMFileIsFLVHeader(void *header)
1739 unsigned char *s = header;
1741 if (!memcmp(s, "FLV", 3)) {