/******************************************************************************
* *
* 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;
}