blob: a5479d1e051477239bee1ed219789a6f92659c00 [file] [log] [blame]
/**
* @copyright
*
* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* @file
*
* omx_swvdec_utils.cpp
*
* @brief
*
* OMX software video decoder utility functions source.
*/
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <pthread.h>
#include <time.h>
#include <errno.h>
#include <cutils/properties.h>
#include "omx_swvdec_utils.h"
#define OMX_SWVDEC_LOGLEVEL_DEFAULT 2 ///< default OMX SwVdec loglevel
unsigned int g_omx_swvdec_logmask = (1 << OMX_SWVDEC_LOGLEVEL_DEFAULT) - 1;
///< global OMX SwVdec logmask variable definition
/**
* @brief Initialize OMX SwVdec log level & mask.
*/
void omx_swvdec_log_init()
{
int omx_swvdec_loglevel = OMX_SWVDEC_LOGLEVEL_DEFAULT;
char property_value[PROPERTY_VALUE_MAX] = {0};
if (property_get("omx_swvdec.log.level", property_value, NULL))
{
omx_swvdec_loglevel = atoi(property_value);
if (omx_swvdec_loglevel > 3)
{
omx_swvdec_loglevel = 3;
}
if (omx_swvdec_loglevel < 0)
{
omx_swvdec_loglevel = 0;
}
OMX_SWVDEC_LOG_HIGH(
"omx_swvdec.log.level: %d; %s",
omx_swvdec_loglevel,
(omx_swvdec_loglevel == 3) ? "error, high, & low logs" :
((omx_swvdec_loglevel == 2) ? "error & high logs" :
((omx_swvdec_loglevel == 1) ? "error logs" :
"no logs")));
}
g_omx_swvdec_logmask = (unsigned int) ((1 << omx_swvdec_loglevel) - 1);
}
/**
* @brief OMX SwVdec queue constructor.
*/
omx_swvdec_queue::omx_swvdec_queue()
{
pthread_mutex_init(&m_mutex, NULL);
}
/**
* @brief OMX SwVdec queue destructor.
*/
omx_swvdec_queue::~omx_swvdec_queue()
{
pthread_mutex_destroy(&m_mutex);
}
/**
* @brief Push event to queue.
*
* @param[in] p_event_info: Pointer to event information structure.
*/
void omx_swvdec_queue::push(OMX_SWVDEC_EVENT_INFO *p_event_info)
{
pthread_mutex_lock(&m_mutex);
m_queue.push(*p_event_info);
pthread_mutex_unlock(&m_mutex);
}
/**
* @brief Pop event from queue.
*
* @param[in,out] p_event_info: Pointer to event information structure.
*
* @retval true if pop successful
* @retval false if pop unsuccessful
*/
bool omx_swvdec_queue::pop(OMX_SWVDEC_EVENT_INFO *p_event_info)
{
bool retval = true;
pthread_mutex_lock(&m_mutex);
if (m_queue.empty())
{
retval = false;
}
else
{
*p_event_info = m_queue.front();
m_queue.pop();
}
pthread_mutex_unlock(&m_mutex);
return retval;
}
/**
* @brief OMX SwVdec diagnostics class constructor.
*/
omx_swvdec_diag::omx_swvdec_diag():
m_dump_ip(0),
m_dump_op(0),
m_filename_ip(NULL),
m_filename_op(NULL),
m_file_ip(NULL),
m_file_op(NULL)
{
time_t time_raw;
struct tm *time_info;
char time_string[16];
char filename_ip[PROPERTY_VALUE_MAX];
char filename_op[PROPERTY_VALUE_MAX];
char property_value[PROPERTY_VALUE_MAX] = {0};
time_raw = time(NULL);
time_info = localtime(&time_raw);
if (time_info != NULL)
{
// time string: "YYYYmmddTHHMMSS"
strftime(time_string, sizeof(time_string), "%Y%m%dT%H%M%S", time_info);
}
else
{
// time string: "19700101T000000"
snprintf(time_string, sizeof(time_string), "19700101T000000");
}
// default ip filename: "/data/misc/media/omx_swvdec_YYYYmmddTHHMMSS_ip.bin"
snprintf(filename_ip,
sizeof(filename_ip),
"%s/omx_swvdec_%s_ip.bin",
DIAG_FILE_PATH,
time_string);
// default op filename: "/data/misc/media/omx_swvdec_YYYYmmddTHHMMSS_op.yuv"
snprintf(filename_op,
sizeof(filename_op),
"%s/omx_swvdec_%s_op.yuv",
DIAG_FILE_PATH,
time_string);
if (property_get("omx_swvdec.dump.ip", property_value, NULL))
{
m_dump_ip = atoi(property_value);
OMX_SWVDEC_LOG_HIGH("omx_swvdec.dump.ip: %d", m_dump_ip);
}
if (property_get("omx_swvdec.dump.op", property_value, NULL))
{
m_dump_op = atoi(property_value);
OMX_SWVDEC_LOG_HIGH("omx_swvdec.dump.op: %d", m_dump_op);
}
if (m_dump_ip && property_get("omx_swvdec.filename.ip",
property_value,
filename_ip) && (strlen(property_value) > 0 ) )
{
size_t m_filename_ip_size = (strlen(property_value) + 1)*sizeof(char);
m_filename_ip =
(char *) malloc(m_filename_ip_size);
if (m_filename_ip == NULL)
{
OMX_SWVDEC_LOG_ERROR("failed to allocate %zu bytes for "
"input filename string",
m_filename_ip_size);
}
else
{
strlcpy(m_filename_ip, property_value,m_filename_ip_size);
OMX_SWVDEC_LOG_HIGH("omx_swvdec.filename.ip: %s", m_filename_ip);
if ((m_file_ip = fopen(m_filename_ip, "wb")) == NULL)
{
OMX_SWVDEC_LOG_ERROR("cannot open input file '%s' logging erro is : %d",
m_filename_ip,errno);
}
}
}
if (m_dump_op && property_get("omx_swvdec.filename.op",
property_value,
filename_op) && (strlen(property_value) > 0 ))
{
size_t m_filename_op_size = (strlen(property_value) + 1)*sizeof(char);
m_filename_op =
(char *) malloc(m_filename_op_size);
if (m_filename_op == NULL)
{
OMX_SWVDEC_LOG_ERROR("failed to allocate %zu bytes for "
"output filename string",
m_filename_op_size);
}
else
{
strlcpy(m_filename_op, property_value,m_filename_op_size);
OMX_SWVDEC_LOG_HIGH("omx_swvdec.filename.op: %s", m_filename_op);
if ((m_file_op = fopen(m_filename_op, "wb")) == NULL)
{
OMX_SWVDEC_LOG_ERROR("cannot open output file '%s' logging error : %d",
m_filename_op,errno);
}
}
}
}
/**
* @brief OMX SwVdec diagnostics class destructor.
*/
omx_swvdec_diag::~omx_swvdec_diag()
{
if (m_file_op)
{
fclose(m_file_op);
m_file_op = NULL;
}
if (m_file_ip)
{
fclose(m_file_ip);
m_file_ip = NULL;
}
if (m_filename_op)
{
free(m_filename_op);
m_filename_op = NULL;
}
if (m_filename_ip)
{
free(m_filename_ip);
m_filename_ip = NULL;
}
}
/**
* @brief Dump input bitstream to file.
*
* @param[in] p_buffer: Pointer to input bitstream buffer.
* @param[in] filled_length: Bitstream buffer's filled length.
*/
void omx_swvdec_diag::dump_ip(unsigned char *p_buffer,
unsigned int filled_length)
{
if (m_dump_ip && (m_file_ip != NULL))
{
fwrite(p_buffer, sizeof(unsigned char), filled_length, m_file_ip);
}
}
/**
* @brief Dump output YUV to file.
*
* @param[in] p_buffer: Pointer to output YUV buffer.
* @param[in] width: Frame width.
* @param[in] height: Frame height.
* @param[in] stride: Frame stride.
* @param[in] scanlines: Frame scanlines.
*/
void omx_swvdec_diag::dump_op(unsigned char *p_buffer,
unsigned int width,
unsigned int height,
unsigned int stride,
unsigned int scanlines)
{
if (m_dump_op && (m_file_op != NULL))
{
unsigned char *p_buffer_y;
unsigned char *p_buffer_uv;
unsigned int ii;
p_buffer_y = p_buffer;
p_buffer_uv = p_buffer + (stride * scanlines);
for (ii = 0; ii < height; ii++)
{
fwrite(p_buffer_y, sizeof(unsigned char), width, m_file_op);
p_buffer_y += stride;
}
for (ii = 0; ii < (height / 2); ii++)
{
fwrite(p_buffer_uv, sizeof(unsigned char), width, m_file_op);
p_buffer_uv += stride;
}
}
}