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 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 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 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 176 unsigned int FileWrapper_IsMp4File(FileWrapperPtr transport) { 177 return transport->isMp4File; 178 } 179