/** * @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 #include #include #include #include #include #include #include "omx_swvdec_utils.h" #define OMX_SWVDEC_LOGLEVEL_DEFAULT 3 ///< default OMX SwVdec loglevel unsigned int g_omx_swvdec_logmask = OMX_SWVDEC_LOGLEVEL_DEFAULT; ///< 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("vendor.vidc.debug.level", property_value, NULL)) { omx_swvdec_loglevel = atoi(property_value); if (omx_swvdec_loglevel > 7) { omx_swvdec_loglevel = 7; } if (omx_swvdec_loglevel < 0) { omx_swvdec_loglevel = 0; } OMX_SWVDEC_LOG_HIGH( "vendor.vidc.debug.level: %d; %s", omx_swvdec_loglevel, (omx_swvdec_loglevel == 7) ? "error, high, & low logs" : ((omx_swvdec_loglevel == 3) ? "error & high logs" : ((omx_swvdec_loglevel == 1) ? "error logs" : "no logs"))); } g_omx_swvdec_logmask = omx_swvdec_loglevel; } /** * @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/vendor/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/vendor/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("vendor.vidc.dec.log.in", property_value, NULL)) { m_dump_ip = atoi(property_value); OMX_SWVDEC_LOG_HIGH("vendor.vidc.dec.log.in: %d", m_dump_ip); } if (property_get("vendor.vidc.dec.log.out", property_value, NULL)) { m_dump_op = atoi(property_value); OMX_SWVDEC_LOG_HIGH("vendor.vidc.dec.log.out: %d", m_dump_op); } if (m_dump_ip && property_get("vendor.vidc.dec.log.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("vendor.vidc.dec.log.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("vendor.vidc.dec.log.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("vendor.vidc.dec.log.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; } } }