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 return 0; 54 else 55 return transport; 56 } 57 58 if ((transport->mp4Ctxt = it_mp4_parser_init(transport->fileCtxt, NULL)) == 59 NULL) { 60 transport->inputFile = fopen(fileName, "rb"); 61 if (!transport->inputFile) 62 return 0; 63 else 64 return transport; 65 } 66 transport->isMp4File = 1; 67 /* 768 * max channels is the max audio block size for AAC */ 68 /* As max channels is 8 and +2 for upto two Ind CoupCh */ 69 transport->interim_buffer = malloc(10 * 768); 70 if (transport->interim_buffer == NULL) { 71 return 0; 72 } 73 return transport; 74 #else 75 transport->inputFile = fopen(fileName, "rb"); 76 if (!transport->inputFile) 77 return 0; 78 else 79 return transport; 80 #endif 81 } 82 83 int FileWrapper_Read(FileWrapperPtr transport, unsigned char *buffer, 84 int bufSize, unsigned int *length) { 85 #ifdef INCLUDE_MP4_PARSER 86 if (!transport->isMp4File) 87 *length = fread(buffer, 1, bufSize, transport->inputFile); 88 else { 89 int errorCode; 90 if (transport->header_given == 0) { 91 transport->headerCtxt.header = (void *)buffer; 92 /* MP4 Hook: Audio Header data to be put in buffer pointed by 93 // headerCtxt.header and length to be put in headerCtxt.headerLength*/ 94 errorCode = 95 it_mp4_get_audio_header(transport->mp4Ctxt, &transport->headerCtxt); 96 transport->header_given = 1; 97 if (errorCode != 0) /* IT_OK = 0 */ 98 { 99 *length = 0; 100 return 1; 101 } 102 *length = transport->headerCtxt.headerLength; 103 } else { 104 *length = 0; 105 /* MP4 Hook: Audio Data to be put in buffer pointed by frameCtxt.header*/ 106 #ifndef ENABLE_LD_DEC 107 while ((int)*length < bufSize) 108 #endif 109 { 110 if (transport->avail_buffer == 0) { 111 transport->frameCtxt.frame = (void *)transport->interim_buffer; 112 errorCode = 113 it_mp4_get_audio(transport->mp4Ctxt, &transport->frameCtxt); 114 if (errorCode != 0) /* IT_OK = 0 */ 115 { 116 if (*length == 0) 117 return 1; 118 else 119 #ifndef ENABLE_LD_DEC 120 break; 121 #else 122 return 1; 123 #endif 124 } 125 transport->avail_buffer += transport->frameCtxt.frameLength; 126 } 127 #ifndef ENABLE_LD_DEC 128 else 129 #endif 130 { 131 int size_to_cpy = 132 min((int)(bufSize - *length), transport->avail_buffer); 133 memcpy(buffer + (*length), transport->interim_buffer, size_to_cpy); 134 memmove(transport->interim_buffer, 135 ((char *)transport->interim_buffer) + size_to_cpy, 136 (transport->avail_buffer - size_to_cpy)); 137 *length += size_to_cpy; 138 transport->avail_buffer -= size_to_cpy; 139 } 140 } 141 } 142 #ifdef DEBUG_ASSERT 143 assert(*length <= (unsigned)bufSize); 144 #endif 145 } 146 147 #else 148 *length = fread(buffer, 1, bufSize, transport->inputFile); 149 #endif 150 151 return 0; 152 } 153 154 unsigned int FileWrapper_Close(FileWrapperPtr transport) { 155 if (transport == 0) return 0; 156 157 #ifdef INCLUDE_MP4_PARSER 158 if (transport->isMp4File) { 159 it_mp4_parser_close(transport->mp4Ctxt); 160 it_fclose(transport->fileCtxt); 161 } else 162 #endif 163 if (transport->inputFile) 164 fclose(transport->inputFile); 165 166 free(transport); 167 return 0; 168 } 169 170 unsigned int FileWrapper_IsMp4File(FileWrapperPtr transport) { 171 return transport->isMp4File; 172 } 173