61
|
1 /*
|
|
2 *
|
|
3 * utils for AAC informations
|
|
4 */
|
|
5 #include <glib.h>
|
|
6 #include <stdio.h>
|
|
7 #include <stdlib.h>
|
|
8
|
|
9
|
|
10 #define ADTS_HEADER_SIZE 8
|
|
11 #define SEEK_TABLE_CHUNK 60
|
|
12 #define MPEG4_TYPE 0
|
|
13 #define MPEG2_TYPE 1
|
|
14
|
|
15 // Read ADTS header, the file descriptor must be at
|
|
16 // the begining of the aac frame not at the id3tag
|
|
17
|
|
18 int getAacInfo(FILE *fd)
|
|
19 {
|
|
20 unsigned char header[ADTS_HEADER_SIZE];
|
|
21 unsigned int id;
|
|
22 unsigned long originPosition;
|
|
23
|
|
24 originPosition = ftell(fd);
|
|
25 if(fread(header, 1, ADTS_HEADER_SIZE, fd) != ADTS_HEADER_SIZE){
|
|
26 fseek(fd, originPosition, SEEK_SET);
|
|
27 return(-1);
|
|
28 }
|
|
29 if(!((header[0]==0xFF)&&((header[1]& 0xF6)==0xF0))){
|
|
30 printf("Bad header\n");
|
|
31 return(-1);
|
|
32 }
|
|
33 id = header[1]&0x08;
|
|
34 if(id==0){//MPEG-4 AAC
|
|
35 fseek(fd, originPosition, SEEK_SET);
|
|
36 return(MPEG4_TYPE);
|
|
37 }else{
|
|
38 fseek(fd, originPosition, SEEK_SET);
|
|
39 return(MPEG2_TYPE);
|
|
40 }
|
|
41 fseek(fd, originPosition, SEEK_SET);
|
|
42 return(-1);
|
|
43 }
|
|
44
|
|
45 // as AAC is VBR we need to check all ADTS header
|
|
46 // to enable seeking...
|
|
47 // there is no other solution
|
|
48 void checkADTSForSeeking(FILE *fd,
|
|
49 unsigned long **seekTable,
|
|
50 unsigned long *seekTableLength)
|
|
51 {
|
|
52 unsigned long originPosition;
|
|
53 unsigned long position;
|
|
54 unsigned char header[ADTS_HEADER_SIZE];
|
|
55 unsigned int frameCount, frameLength, frameInsec;
|
|
56 unsigned int id=0, seconds=0;
|
|
57
|
|
58 originPosition = ftell(fd);
|
|
59
|
|
60 for(frameCount=0,frameInsec=0;; frameCount++,frameInsec++){
|
|
61 position = ftell(fd);
|
|
62 if(fread(header, 1, ADTS_HEADER_SIZE, fd)!=ADTS_HEADER_SIZE){
|
|
63 break;
|
|
64 }
|
|
65 if(!strncmp(header, "ID3", 3)){
|
|
66 break;
|
|
67 }
|
|
68 if(!((header[0]==0xFF)&&((header[1]& 0xF6)==0xF0))){
|
|
69 printf("error : Bad 1st header, file may be corrupt !\n");
|
|
70 break;
|
|
71 }
|
|
72 if(!frameCount){
|
|
73 id=header[1]&0x08;
|
|
74 if(((*seekTable) = malloc(SEEK_TABLE_CHUNK * sizeof(unsigned long)))==0){
|
|
75 printf("malloc error\n");
|
|
76 return;
|
|
77 }
|
|
78 (*seekTableLength) = SEEK_TABLE_CHUNK;
|
|
79 }
|
|
80
|
|
81 //if(id==0){//MPEG-4
|
|
82 //frameLength = ((unsigned int)header[4]<<5)|((unsigned int)header[5]>>3);
|
|
83 //}else{//MPEG-2
|
|
84 frameLength = (((unsigned int)header[3]&0x3)<<11)|((unsigned int)header[4]<<3)|(header[5]>>5);
|
|
85 //}
|
|
86 if(frameInsec==43){//???
|
|
87 frameInsec=0;
|
|
88 }
|
|
89 if(frameInsec==0){
|
|
90 if(seconds == (*seekTableLength)){
|
|
91 (*seekTable) = realloc((*seekTable), (seconds+SEEK_TABLE_CHUNK)*sizeof(unsigned long));
|
|
92 (*seekTableLength) = seconds+SEEK_TABLE_CHUNK;
|
|
93 }
|
|
94 (*seekTable)[seconds] = position;
|
|
95 seconds++;
|
|
96 }
|
|
97 if(fseek(fd, frameLength-ADTS_HEADER_SIZE, SEEK_CUR)==-1){
|
|
98 break;
|
|
99 }
|
|
100 }
|
|
101 (*seekTableLength) = seconds;
|
|
102 fseek(fd, originPosition, SEEK_SET);
|
|
103 }
|