/****************************************************************************** * * * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ #include <stdlib.h> #include <string.h> #ifndef CORTEX_M4 #include <stdio.h> #else #include "cm4_file_operations.h" #endif #include <assert.h> #include "ixheaacd_fileifc.h" #ifndef min #define min(a, b) (((a) < (b)) ? (a) : (b)) #endif //#define INCLUDE_MP4_PARSER FileWrapperPtr FileWrapper_Open(char fileName[]) { FileWrapperPtr transport = (FileWrapper *)calloc(1, sizeof(FileWrapper)); transport->isMp4File = 0; transport->inputFile = NULL; #ifdef INCLUDE_MP4_PARSER transport->header_given = 0; transport->fileCtxt = 0; transport->mp4Ctxt = 0; transport->interim_buffer = 0; transport->avail_buffer = 0; if ((transport->fileCtxt = it_fopen((void *)fileName, 1, 0)) == NULL) { transport->inputFile = fopen(fileName, "rb"); if (!transport->inputFile) return 0; else return transport; } if ((transport->mp4Ctxt = it_mp4_parser_init(transport->fileCtxt, NULL)) == NULL) { transport->inputFile = fopen(fileName, "rb"); if (!transport->inputFile) return 0; else return transport; } transport->isMp4File = 1; /* 768 * max channels is the max audio block size for AAC */ /* As max channels is 8 and +2 for upto two Ind CoupCh */ transport->interim_buffer = malloc(10 * 768); if (transport->interim_buffer == NULL) { return 0; } return transport; #else transport->inputFile = fopen(fileName, "rb"); if (!transport->inputFile) return 0; else return transport; #endif } int FileWrapper_Read(FileWrapperPtr transport, unsigned char *buffer, int bufSize, unsigned int *length) { #ifdef INCLUDE_MP4_PARSER if (!transport->isMp4File) *length = fread(buffer, 1, bufSize, transport->inputFile); else { int errorCode; if (transport->header_given == 0) { transport->headerCtxt.header = (void *)buffer; /* MP4 Hook: Audio Header data to be put in buffer pointed by // headerCtxt.header and length to be put in headerCtxt.headerLength*/ errorCode = it_mp4_get_audio_header(transport->mp4Ctxt, &transport->headerCtxt); transport->header_given = 1; if (errorCode != 0) /* IT_OK = 0 */ { *length = 0; return 1; } *length = transport->headerCtxt.headerLength; } else { *length = 0; /* MP4 Hook: Audio Data to be put in buffer pointed by frameCtxt.header*/ #ifndef ENABLE_LD_DEC while ((int)*length < bufSize) #endif { if (transport->avail_buffer == 0) { transport->frameCtxt.frame = (void *)transport->interim_buffer; errorCode = it_mp4_get_audio(transport->mp4Ctxt, &transport->frameCtxt); if (errorCode != 0) /* IT_OK = 0 */ { if (*length == 0) return 1; else #ifndef ENABLE_LD_DEC break; #else return 1; #endif } transport->avail_buffer += transport->frameCtxt.frameLength; } #ifndef ENABLE_LD_DEC else #endif { int size_to_cpy = min((int)(bufSize - *length), transport->avail_buffer); memcpy(buffer + (*length), transport->interim_buffer, size_to_cpy); memmove(transport->interim_buffer, ((char *)transport->interim_buffer) + size_to_cpy, (transport->avail_buffer - size_to_cpy)); *length += size_to_cpy; transport->avail_buffer -= size_to_cpy; } } } #ifdef DEBUG_ASSERT assert(*length <= (unsigned)bufSize); #endif } #else *length = fread(buffer, 1, bufSize, transport->inputFile); #endif return 0; } unsigned int FileWrapper_Close(FileWrapperPtr transport) { if (transport == 0) return 0; #ifdef INCLUDE_MP4_PARSER if (transport->isMp4File) { it_mp4_parser_close(transport->mp4Ctxt); it_fclose(transport->fileCtxt); } else #endif if (transport->inputFile) fclose(transport->inputFile); free(transport); return 0; } unsigned int FileWrapper_IsMp4File(FileWrapperPtr transport) { return transport->isMp4File; }