blob: ff74e6ab3da8cfefb822c7aa228051ad00a52675 [file] [log] [blame]
/*
* Copyright@ Samsung Electronics Co. LTD
*
* 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.
*/
/*#define LOG_NDEBUG 0 */
#define LOG_TAG "ExynosCmaeraPlugInUtils"
#include <log/log.h>
#include <binder/MemoryHeapBase.h>
#include <ion/ion.h>
#include "ExynosCameraPlugInUtils.h"
namespace android {
/*
* ION memory helper Class
*/
ExynosCameraPlugInUtilsIonAllocator::ExynosCameraPlugInUtilsIonAllocator(bool isCached)
{
status_t ret = NO_ERROR;
m_ionClient = ion_open();
if (m_ionClient < 0) {
PLUGIN_LOGE("ion_open failed");
}
m_ionAlign = 0;
m_ionHeapMask = ION_HEAP_SYSTEM_MASK;
m_ionFlags = (isCached == true ?
(ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC ) : 0);
}
ExynosCameraPlugInUtilsIonAllocator::~ExynosCameraPlugInUtilsIonAllocator()
{
if (m_ionClient >= 0)
ion_close(m_ionClient);
}
status_t ExynosCameraPlugInUtilsIonAllocator::alloc(int size, int *fd, char **addr, bool mapNeeded)
{
status_t ret = NO_ERROR;
int ionFd = 0;
char *ionAddr = NULL;
if (m_ionClient == 0) {
PLUGIN_LOGE("allocator is not yet created");
ret = INVALID_OPERATION;
goto func_exit;
}
if (size == 0) {
PLUGIN_LOGE("size equals zero");
ret = BAD_VALUE;
goto func_exit;
}
ret = ion_alloc_fd(m_ionClient, size, m_ionAlign, m_ionHeapMask, m_ionFlags, &ionFd);
if (ret < 0) {
PLUGIN_LOGE("ion_alloc_fd(fd=%d) failed(%s)", ionFd, strerror(errno));
ionFd = -1;
ret = INVALID_OPERATION;
goto func_exit;
}
if (mapNeeded == true) {
ionAddr = (char *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, ionFd, 0);
if (ionAddr == (char *)MAP_FAILED || ionAddr == NULL) {
PLUGIN_LOGE("ion_map(size=%d) failed, (fd=%d), (%s)", size, ionFd, strerror(errno));
close(ionFd);
ionFd = -1;
ionAddr = NULL;
ret = INVALID_OPERATION;
goto func_exit;
}
}
func_exit:
*fd = ionFd;
*addr = ionAddr;
return ret;
}
status_t ExynosCameraPlugInUtilsIonAllocator::free(int *fd, __unused int size, char **addr, bool mapNeeded)
{
status_t ret = NO_ERROR;
int ionFd = *fd;
char *ionAddr = *addr;
if (ionFd < 0) {
PLUGIN_LOGE("ion_fd is lower than zero");
ret = BAD_VALUE;
goto func_exit;
}
if (mapNeeded == true) {
if (ionAddr == NULL) {
PLUGIN_LOGE("ion_addr equals NULLi(%d)", ionFd);
ret = BAD_VALUE;
goto func_close_exit;
}
if (munmap(ionAddr, size) < 0) {
PLUGIN_LOGE("munmap failed");
ret = INVALID_OPERATION;
goto func_close_exit;
}
}
func_close_exit:
ion_close(ionFd);
ionFd = -1;
ionAddr = NULL;
func_exit:
*fd = ionFd;
*addr = ionAddr;
return ret;
}
status_t dumpToFile(char *filename, PlugInBuffer *planes, int planeCount, int index)
{
int i;
time_t rawtime;
struct tm* timeinfo;
int totalSize = 0;
FILE *fd = NULL;
char *buffer = NULL;
char finalFilePath[512];
time(&rawtime);
timeinfo = localtime(&rawtime);
snprintf(finalFilePath, sizeof(finalFilePath),
PLUGIN_FILE_DUMP_PATH "%s_%d_%02d%02d%02d_%02d%02d%02d.dump",
filename, index, timeinfo->tm_year+1900, timeinfo->tm_mon+1, timeinfo->tm_mday,
timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
fd = fopen(finalFilePath, "w+");
if (fd == NULL) {
PLUGIN_LOGE("ERR(%s):open(%s) fail", filename);
return INVALID_OPERATION;
}
fflush(stdout);
for (i = 0; i < planeCount; i++) {
fwrite(planes[i].addr, 1, planes[i].size, fd);
totalSize += planes[i].size;
}
fflush(fd);
if (fd)
fclose(fd);
PLUGIN_LOGD("filedump(%s, planes(%d) totalSize(%d)) is successed!!",
finalFilePath, i, totalSize);
return NO_ERROR;
}
}