1 /******************************************************************************
2 * *
3 * Copyright (C) 2018 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *****************************************************************************
18 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20 #include <stdlib.h>
21 #include <string.h>
22 #ifndef CORTEX_M4
23 #include <stdio.h>
24 #else
25 #include "cm4_file_operations.h"
26 #endif
27 #include <assert.h>
28
29 #include "ixheaacd_fileifc.h"
30 #ifndef min
31 #define min(a, b) (((a) < (b)) ? (a) : (b))
32 #endif
33
34 //#define INCLUDE_MP4_PARSER
35
FileWrapper_Open(char fileName[])36 FileWrapperPtr FileWrapper_Open(char fileName[]) {
37 FileWrapperPtr transport = (FileWrapper *)calloc(1, sizeof(FileWrapper));
38
39 transport->isMp4File = 0;
40 transport->inputFile = NULL;
41
42 #ifdef INCLUDE_MP4_PARSER
43
44 transport->header_given = 0;
45 transport->fileCtxt = 0;
46 transport->mp4Ctxt = 0;
47 transport->interim_buffer = 0;
48 transport->avail_buffer = 0;
49
50 if ((transport->fileCtxt = it_fopen((void *)fileName, 1, 0)) == NULL) {
51 transport->inputFile = fopen(fileName, "rb");
52 if (!transport->inputFile) {
53 free(transport);
54 return 0;
55 }
56
57 else
58 return transport;
59 }
60
61 if ((transport->mp4Ctxt = it_mp4_parser_init(transport->fileCtxt, NULL)) ==
62 NULL) {
63 transport->inputFile = fopen(fileName, "rb");
64 if (!transport->inputFile) {
65 free(transport);
66 return 0;
67 } else
68 return transport;
69 }
70 transport->isMp4File = 1;
71 /* 768 * max channels is the max audio block size for AAC */
72 /* As max channels is 8 and +2 for upto two Ind CoupCh */
73 transport->interim_buffer = malloc(10 * 768);
74 if (transport->interim_buffer == NULL) {
75 free(transport);
76 return 0;
77 }
78 return transport;
79 #else
80 transport->inputFile = fopen(fileName, "rb");
81 if (!transport->inputFile) {
82 free(transport);
83 return 0;
84 } else
85 return transport;
86 #endif
87 }
88
FileWrapper_Read(FileWrapperPtr transport,unsigned char * buffer,int bufSize,unsigned int * length)89 int FileWrapper_Read(FileWrapperPtr transport, unsigned char *buffer,
90 int bufSize, unsigned int *length) {
91 #ifdef INCLUDE_MP4_PARSER
92 if (!transport->isMp4File)
93 *length = fread(buffer, 1, bufSize, transport->inputFile);
94 else {
95 int errorCode;
96 if (transport->header_given == 0) {
97 transport->headerCtxt.header = (void *)buffer;
98 /* MP4 Hook: Audio Header data to be put in buffer pointed by
99 // headerCtxt.header and length to be put in headerCtxt.headerLength*/
100 errorCode =
101 it_mp4_get_audio_header(transport->mp4Ctxt, &transport->headerCtxt);
102 transport->header_given = 1;
103 if (errorCode != 0) /* IT_OK = 0 */
104 {
105 *length = 0;
106 return 1;
107 }
108 *length = transport->headerCtxt.headerLength;
109 } else {
110 *length = 0;
111 /* MP4 Hook: Audio Data to be put in buffer pointed by frameCtxt.header*/
112 #ifndef ENABLE_LD_DEC
113 while ((int)*length < bufSize)
114 #endif
115 {
116 if (transport->avail_buffer == 0) {
117 transport->frameCtxt.frame = (void *)transport->interim_buffer;
118 errorCode =
119 it_mp4_get_audio(transport->mp4Ctxt, &transport->frameCtxt);
120 if (errorCode != 0) /* IT_OK = 0 */
121 {
122 if (*length == 0)
123 return 1;
124 else
125 #ifndef ENABLE_LD_DEC
126 break;
127 #else
128 return 1;
129 #endif
130 }
131 transport->avail_buffer += transport->frameCtxt.frameLength;
132 }
133 #ifndef ENABLE_LD_DEC
134 else
135 #endif
136 {
137 int size_to_cpy =
138 min((int)(bufSize - *length), transport->avail_buffer);
139 memcpy(buffer + (*length), transport->interim_buffer, size_to_cpy);
140 memmove(transport->interim_buffer,
141 ((char *)transport->interim_buffer) + size_to_cpy,
142 (transport->avail_buffer - size_to_cpy));
143 *length += size_to_cpy;
144 transport->avail_buffer -= size_to_cpy;
145 }
146 }
147 }
148 #ifdef DEBUG_ASSERT
149 assert(*length <= (unsigned)bufSize);
150 #endif
151 }
152
153 #else
154 *length = fread(buffer, 1, bufSize, transport->inputFile);
155 #endif
156
157 return 0;
158 }
159
FileWrapper_Close(FileWrapperPtr transport)160 unsigned int FileWrapper_Close(FileWrapperPtr transport) {
161 if (transport == 0) return 0;
162
163 #ifdef INCLUDE_MP4_PARSER
164 if (transport->isMp4File) {
165 it_mp4_parser_close(transport->mp4Ctxt);
166 it_fclose(transport->fileCtxt);
167 } else
168 #endif
169 if (transport->inputFile)
170 fclose(transport->inputFile);
171
172 free(transport);
173 return 0;
174 }
175
FileWrapper_IsMp4File(FileWrapperPtr transport)176 unsigned int FileWrapper_IsMp4File(FileWrapperPtr transport) {
177 return transport->isMp4File;
178 }
179