13e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar/*
23e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar * Copyright (C) 2014 The Android Open Source Project
33e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar *
43e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar * Licensed under the Apache License, Version 2.0 (the "License");
53e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar * you may not use this file except in compliance with the License.
63e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar * You may obtain a copy of the License at
73e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar *
83e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar *      http://www.apache.org/licenses/LICENSE-2.0
93e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar *
103e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar * Unless required by applicable law or agreed to in writing, software
113e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar * distributed under the License is distributed on an "AS IS" BASIS,
123e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar * See the License for the specific language governing permissions and
143e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar * limitations under the License.
153e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar */
163e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
173e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar//#define LOG_NDEBUG 0
183e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar#define LOG_TAG "SoftHEVC"
193e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar#include <utils/Log.h>
203e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
213e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar#include "ihevc_typedefs.h"
223e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar#include "iv.h"
233e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar#include "ivd.h"
243e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar#include "ithread.h"
253e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar#include "ihevcd_cxa.h"
263e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar#include "SoftHEVC.h"
273e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
283e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar#include <media/stagefright/foundation/ADebug.h>
29a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar#include <media/stagefright/foundation/AUtils.h>
303e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar#include <media/stagefright/MediaDefs.h>
313e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar#include <OMX_VideoExt.h>
323e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
333e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnarnamespace android {
343e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
353e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar#define componentName                   "video_decoder.hevc"
363e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar#define codingType                      OMX_VIDEO_CodingHEVC
373e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar#define CODEC_MIME_TYPE                 MEDIA_MIMETYPE_VIDEO_HEVC
383e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
393e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar/** Function and structure definitions to keep code similar for each codec */
403e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar#define ivdec_api_function              ihevcd_cxa_api_function
413e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar#define ivdext_init_ip_t                ihevcd_cxa_init_ip_t
423e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar#define ivdext_init_op_t                ihevcd_cxa_init_op_t
433e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar#define ivdext_fill_mem_rec_ip_t        ihevcd_cxa_fill_mem_rec_ip_t
443e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar#define ivdext_fill_mem_rec_op_t        ihevcd_cxa_fill_mem_rec_op_t
453e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar#define ivdext_ctl_set_num_cores_ip_t   ihevcd_cxa_ctl_set_num_cores_ip_t
463e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar#define ivdext_ctl_set_num_cores_op_t   ihevcd_cxa_ctl_set_num_cores_op_t
473e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
483e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar#define IVDEXT_CMD_CTL_SET_NUM_CORES    \
493e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        (IVD_CONTROL_API_COMMAND_TYPE_T)IHEVCD_CXA_CMD_CTL_SET_NUM_CORES
503e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
513e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnarstatic const CodecProfileLevel kProfileLevels[] = {
523e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    { OMX_VIDEO_HEVCProfileMain, OMX_VIDEO_HEVCMainTierLevel1  },
533e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    { OMX_VIDEO_HEVCProfileMain, OMX_VIDEO_HEVCMainTierLevel2  },
543e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    { OMX_VIDEO_HEVCProfileMain, OMX_VIDEO_HEVCMainTierLevel21 },
553e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    { OMX_VIDEO_HEVCProfileMain, OMX_VIDEO_HEVCMainTierLevel3  },
563e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    { OMX_VIDEO_HEVCProfileMain, OMX_VIDEO_HEVCMainTierLevel31 },
573e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    { OMX_VIDEO_HEVCProfileMain, OMX_VIDEO_HEVCMainTierLevel4  },
583e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    { OMX_VIDEO_HEVCProfileMain, OMX_VIDEO_HEVCMainTierLevel41 },
593e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    { OMX_VIDEO_HEVCProfileMain, OMX_VIDEO_HEVCMainTierLevel5  },
603e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    { OMX_VIDEO_HEVCProfileMain, OMX_VIDEO_HEVCMainTierLevel51 },
613e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar};
623e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
633e648747e7e40752580ae7fd0ff2e803623680cdLajos MolnarSoftHEVC::SoftHEVC(
643e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        const char *name,
653e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        const OMX_CALLBACKTYPE *callbacks,
663e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        OMX_PTR appData,
673e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        OMX_COMPONENTTYPE **component)
683e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    : SoftVideoDecoderOMXComponent(name, componentName, codingType,
693e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            kProfileLevels, ARRAY_SIZE(kProfileLevels),
70f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy            320 /* width */, 240 /* height */, callbacks,
711aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu            appData, component),
721aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu      mMemRecords(NULL),
731aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu      mFlushOutBuffer(NULL),
741aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu      mOmxColorFormat(OMX_COLOR_FormatYUV420Planar),
751aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu      mIvColorFormat(IV_YUV_420P),
761aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu      mNewWidth(mWidth),
771aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu      mNewHeight(mHeight),
781aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu      mChangingResolution(false) {
79a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    const size_t kMinCompressionRatio = 4 /* compressionRatio (for Level 4+) */;
80a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    const size_t kMaxOutputBufferSize = 2048 * 2048 * 3 / 2;
81a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    // INPUT_BUF_SIZE is given by HEVC codec as minimum input size
82a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    initPorts(
83a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            kNumBuffers, max(kMaxOutputBufferSize / kMinCompressionRatio, (size_t)INPUT_BUF_SIZE),
84a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            kNumBuffers, CODEC_MIME_TYPE, kMinCompressionRatio);
853e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    CHECK_EQ(initDecoder(), (status_t)OK);
863e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar}
873e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
883e648747e7e40752580ae7fd0ff2e803623680cdLajos MolnarSoftHEVC::~SoftHEVC() {
893e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    ALOGD("In SoftHEVC::~SoftHEVC");
903e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    CHECK_EQ(deInitDecoder(), (status_t)OK);
913e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar}
923e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
933e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnarstatic size_t GetCPUCoreCount() {
943e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    long cpuCoreCount = 1;
953e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar#if defined(_SC_NPROCESSORS_ONLN)
963e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    cpuCoreCount = sysconf(_SC_NPROCESSORS_ONLN);
973e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar#else
983e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    // _SC_NPROC_ONLN must be defined...
993e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    cpuCoreCount = sysconf(_SC_NPROC_ONLN);
1003e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar#endif
1013e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    CHECK(cpuCoreCount >= 1);
1023e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    ALOGD("Number of CPU cores: %ld", cpuCoreCount);
1033e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    return (size_t)cpuCoreCount;
1043e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar}
1053e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
106f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamyvoid SoftHEVC::logVersion() {
1073e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    ivd_ctl_getversioninfo_ip_t s_ctl_ip;
1083e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    ivd_ctl_getversioninfo_op_t s_ctl_op;
1093e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    UWORD8 au1_buf[512];
1103e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    IV_API_CALL_STATUS_T status;
1113e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
1123e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
1133e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_GETVERSION;
1143e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    s_ctl_ip.u4_size = sizeof(ivd_ctl_getversioninfo_ip_t);
1153e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    s_ctl_op.u4_size = sizeof(ivd_ctl_getversioninfo_op_t);
1163e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    s_ctl_ip.pv_version_buffer = au1_buf;
1173e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    s_ctl_ip.u4_version_buffer_size = sizeof(au1_buf);
1183e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
1193e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    status = ivdec_api_function(mCodecCtx, (void *)&s_ctl_ip,
1203e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            (void *)&s_ctl_op);
1213e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
1223e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    if (status != IV_SUCCESS) {
1233e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        ALOGE("Error in getting version number: 0x%x",
1243e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                s_ctl_op.u4_error_code);
1253e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    } else {
1263e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        ALOGD("Ittiam decoder version number: %s",
1273e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                (char *)s_ctl_ip.pv_version_buffer);
1283e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    }
129f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy    return;
1303e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar}
1313e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
132f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamystatus_t SoftHEVC::setParams(size_t stride) {
1333e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    ivd_ctl_set_config_ip_t s_ctl_ip;
1343e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    ivd_ctl_set_config_op_t s_ctl_op;
1353e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    IV_API_CALL_STATUS_T status;
136f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy    s_ctl_ip.u4_disp_wd = (UWORD32)stride;
1373e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    s_ctl_ip.e_frm_skip_mode = IVD_SKIP_NONE;
1383e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
1393e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    s_ctl_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
140f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy    s_ctl_ip.e_vid_dec_mode = IVD_DECODE_FRAME;
1413e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
1423e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
1433e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    s_ctl_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t);
1443e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_op_t);
1453e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
1461aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu    ALOGV("Set the run-time (dynamic) parameters stride = %u", stride);
1473e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    status = ivdec_api_function(mCodecCtx, (void *)&s_ctl_ip,
1483e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            (void *)&s_ctl_op);
1493e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
1503e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    if (status != IV_SUCCESS) {
1513e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        ALOGE("Error in setting the run-time parameters: 0x%x",
1523e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                s_ctl_op.u4_error_code);
1533e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
1543e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        return UNKNOWN_ERROR;
1553e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    }
1563e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    return OK;
1573e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar}
1583e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
1593e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnarstatus_t SoftHEVC::resetPlugin() {
1603e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    mIsInFlush = false;
1613e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    mReceivedEOS = false;
1623e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    memset(mTimeStamps, 0, sizeof(mTimeStamps));
1633e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    memset(mTimeStampsValid, 0, sizeof(mTimeStampsValid));
1643e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
1653e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    /* Initialize both start and end times */
1663e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    gettimeofday(&mTimeStart, NULL);
1673e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    gettimeofday(&mTimeEnd, NULL);
1683e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
1693e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    return OK;
1703e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar}
1713e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
1723e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnarstatus_t SoftHEVC::resetDecoder() {
1733e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    ivd_ctl_reset_ip_t s_ctl_ip;
1743e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    ivd_ctl_reset_op_t s_ctl_op;
1753e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    IV_API_CALL_STATUS_T status;
1763e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
1773e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
1783e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_RESET;
1793e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    s_ctl_ip.u4_size = sizeof(ivd_ctl_reset_ip_t);
1803e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    s_ctl_op.u4_size = sizeof(ivd_ctl_reset_op_t);
1813e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
1823e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    status = ivdec_api_function(mCodecCtx, (void *)&s_ctl_ip,
1833e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            (void *)&s_ctl_op);
1843e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    if (IV_SUCCESS != status) {
1853e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        ALOGE("Error in reset: 0x%x", s_ctl_op.u4_error_code);
1863e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        return UNKNOWN_ERROR;
1873e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    }
1883e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
1893e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    /* Set the run-time (dynamic) parameters */
1901aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu    setParams(outputBufferWidth());
1913e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
1923e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    /* Set number of cores/threads to be used by the codec */
1933e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    setNumCores();
1943e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
1953e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    return OK;
1963e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar}
1973e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
1983e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnarstatus_t SoftHEVC::setNumCores() {
1993e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    ivdext_ctl_set_num_cores_ip_t s_set_cores_ip;
2003e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    ivdext_ctl_set_num_cores_op_t s_set_cores_op;
2013e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    IV_API_CALL_STATUS_T status;
2023e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    s_set_cores_ip.e_cmd = IVD_CMD_VIDEO_CTL;
2033e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    s_set_cores_ip.e_sub_cmd = IVDEXT_CMD_CTL_SET_NUM_CORES;
2043e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    s_set_cores_ip.u4_num_cores = MIN(mNumCores, CODEC_MAX_NUM_CORES);
2053e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    s_set_cores_ip.u4_size = sizeof(ivdext_ctl_set_num_cores_ip_t);
2063e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    s_set_cores_op.u4_size = sizeof(ivdext_ctl_set_num_cores_op_t);
2073e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    ALOGD("Set number of cores to %u", s_set_cores_ip.u4_num_cores);
2083e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    status = ivdec_api_function(mCodecCtx, (void *)&s_set_cores_ip,
2093e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            (void *)&s_set_cores_op);
2103e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    if (IV_SUCCESS != status) {
2113e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        ALOGE("Error in setting number of cores: 0x%x",
2123e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                s_set_cores_op.u4_error_code);
2133e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        return UNKNOWN_ERROR;
2143e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    }
2153e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    return OK;
2163e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar}
2173e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
2183e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnarstatus_t SoftHEVC::setFlushMode() {
2193e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    IV_API_CALL_STATUS_T status;
2203e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    ivd_ctl_flush_ip_t s_video_flush_ip;
2213e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    ivd_ctl_flush_op_t s_video_flush_op;
2223e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
2233e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    s_video_flush_ip.e_cmd = IVD_CMD_VIDEO_CTL;
2243e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    s_video_flush_ip.e_sub_cmd = IVD_CMD_CTL_FLUSH;
2253e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    s_video_flush_ip.u4_size = sizeof(ivd_ctl_flush_ip_t);
2263e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    s_video_flush_op.u4_size = sizeof(ivd_ctl_flush_op_t);
2273e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    ALOGD("Set the decoder in flush mode ");
2283e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
2293e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    /* Set the decoder in Flush mode, subsequent decode() calls will flush */
2303e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    status = ivdec_api_function(mCodecCtx, (void *)&s_video_flush_ip,
2313e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            (void *)&s_video_flush_op);
2323e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
2333e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    if (status != IV_SUCCESS) {
2343e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        ALOGE("Error in setting the decoder in flush mode: (%d) 0x%x", status,
2353e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                s_video_flush_op.u4_error_code);
2363e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        return UNKNOWN_ERROR;
2373e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    }
2383e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
2393e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    mIsInFlush = true;
2403e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    return OK;
2413e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar}
2423e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
2433e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnarstatus_t SoftHEVC::initDecoder() {
2443e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    IV_API_CALL_STATUS_T status;
2453e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
2463e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    UWORD32 u4_num_reorder_frames;
2473e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    UWORD32 u4_num_ref_frames;
2483e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    UWORD32 u4_share_disp_buf;
2493e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    WORD32 i4_level;
2503e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
2513e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    mNumCores = GetCPUCoreCount();
2523e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
2533e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    /* Initialize number of ref and reorder modes (for HEVC) */
2543e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    u4_num_reorder_frames = 16;
2553e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    u4_num_ref_frames = 16;
2563e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    u4_share_disp_buf = 0;
2573e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
2581aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu    uint32_t displayStride = outputBufferWidth();
2591aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu    uint32_t displayHeight = outputBufferHeight();
2601aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu    uint32_t displaySizeY = displayStride * displayHeight;
2611aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu
2621aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu    if (displaySizeY > (1920 * 1088)) {
2633e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        i4_level = 50;
2641aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu    } else if (displaySizeY > (1280 * 720)) {
265f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy        i4_level = 40;
2661aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu    } else if (displaySizeY > (960 * 540)) {
2673e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        i4_level = 31;
2681aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu    } else if (displaySizeY > (640 * 360)) {
269f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy        i4_level = 30;
2701aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu    } else if (displaySizeY > (352 * 288)) {
271f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy        i4_level = 21;
272f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy    } else {
273f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy        i4_level = 20;
2743e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    }
2753e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    {
2763e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        iv_num_mem_rec_ip_t s_num_mem_rec_ip;
2773e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        iv_num_mem_rec_op_t s_num_mem_rec_op;
2783e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
2793e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        s_num_mem_rec_ip.u4_size = sizeof(s_num_mem_rec_ip);
2803e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        s_num_mem_rec_op.u4_size = sizeof(s_num_mem_rec_op);
2813e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        s_num_mem_rec_ip.e_cmd = IV_CMD_GET_NUM_MEM_REC;
2823e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
2833e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        ALOGV("Get number of mem records");
2843e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        status = ivdec_api_function(mCodecCtx, (void*)&s_num_mem_rec_ip,
2853e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                (void*)&s_num_mem_rec_op);
2863e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        if (IV_SUCCESS != status) {
2873e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            ALOGE("Error in getting mem records: 0x%x",
2883e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                    s_num_mem_rec_op.u4_error_code);
2893e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            return UNKNOWN_ERROR;
2903e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        }
2913e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
2923e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        mNumMemRecords = s_num_mem_rec_op.u4_num_mem_rec;
2933e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    }
2943e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
2953e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    mMemRecords = (iv_mem_rec_t*)ivd_aligned_malloc(
2963e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            128, mNumMemRecords * sizeof(iv_mem_rec_t));
2973e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    if (mMemRecords == NULL) {
2983e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        ALOGE("Allocation failure");
2993e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        return NO_MEMORY;
3003e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    }
3013e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
302f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy    memset(mMemRecords, 0, mNumMemRecords * sizeof(iv_mem_rec_t));
303f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy
3043e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    {
3053e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        size_t i;
3063e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        ivdext_fill_mem_rec_ip_t s_fill_mem_ip;
3073e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        ivdext_fill_mem_rec_op_t s_fill_mem_op;
3083e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        iv_mem_rec_t *ps_mem_rec;
3093e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
3103e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.u4_size =
3113e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            sizeof(ivdext_fill_mem_rec_ip_t);
3123e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        s_fill_mem_ip.i4_level = i4_level;
3133e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        s_fill_mem_ip.u4_num_reorder_frames = u4_num_reorder_frames;
3143e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        s_fill_mem_ip.u4_num_ref_frames = u4_num_ref_frames;
3153e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        s_fill_mem_ip.u4_share_disp_buf = u4_share_disp_buf;
3163e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        s_fill_mem_ip.u4_num_extra_disp_buf = 0;
3173e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        s_fill_mem_ip.e_output_format = mIvColorFormat;
3183e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
3193e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.e_cmd = IV_CMD_FILL_NUM_MEM_REC;
3203e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location = mMemRecords;
3211aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu        s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_wd = displayStride;
3221aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu        s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_ht = displayHeight;
3233e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        s_fill_mem_op.s_ivd_fill_mem_rec_op_t.u4_size =
3243e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            sizeof(ivdext_fill_mem_rec_op_t);
3253e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
3263e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        ps_mem_rec = mMemRecords;
3273e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        for (i = 0; i < mNumMemRecords; i++)
3283e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            ps_mem_rec[i].u4_size = sizeof(iv_mem_rec_t);
3293e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
3303e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        status = ivdec_api_function(mCodecCtx, (void *)&s_fill_mem_ip,
3313e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                (void *)&s_fill_mem_op);
3323e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
3333e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        if (IV_SUCCESS != status) {
3343e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            ALOGE("Error in filling mem records: 0x%x",
3353e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                    s_fill_mem_op.s_ivd_fill_mem_rec_op_t.u4_error_code);
3363e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            return UNKNOWN_ERROR;
3373e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        }
3383e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        mNumMemRecords =
3393e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            s_fill_mem_op.s_ivd_fill_mem_rec_op_t.u4_num_mem_rec_filled;
3403e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
3413e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        ps_mem_rec = mMemRecords;
3423e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
3433e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        for (i = 0; i < mNumMemRecords; i++) {
3443e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            ps_mem_rec->pv_base = ivd_aligned_malloc(
3453e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                    ps_mem_rec->u4_mem_alignment, ps_mem_rec->u4_mem_size);
3463e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            if (ps_mem_rec->pv_base == NULL) {
3473e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                ALOGE("Allocation failure for memory record #%zu of size %u",
3483e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                        i, ps_mem_rec->u4_mem_size);
3493e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                status = IV_FAIL;
3503e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                return NO_MEMORY;
3513e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            }
3523e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
3533e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            ps_mem_rec++;
3543e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        }
3553e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    }
3563e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
3573e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    /* Initialize the decoder */
3583e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    {
3593e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        ivdext_init_ip_t s_init_ip;
3603e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        ivdext_init_op_t s_init_op;
3613e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
3623e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        void *dec_fxns = (void *)ivdec_api_function;
3633e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
3643e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        s_init_ip.s_ivd_init_ip_t.u4_size = sizeof(ivdext_init_ip_t);
3653e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        s_init_ip.s_ivd_init_ip_t.e_cmd = (IVD_API_COMMAND_TYPE_T)IV_CMD_INIT;
3663e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        s_init_ip.s_ivd_init_ip_t.pv_mem_rec_location = mMemRecords;
3671aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu        s_init_ip.s_ivd_init_ip_t.u4_frm_max_wd = displayStride;
3681aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu        s_init_ip.s_ivd_init_ip_t.u4_frm_max_ht = displayHeight;
3693e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
3703e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        s_init_ip.i4_level = i4_level;
3713e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        s_init_ip.u4_num_reorder_frames = u4_num_reorder_frames;
3723e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        s_init_ip.u4_num_ref_frames = u4_num_ref_frames;
3733e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        s_init_ip.u4_share_disp_buf = u4_share_disp_buf;
3743e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        s_init_ip.u4_num_extra_disp_buf = 0;
3753e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
3763e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        s_init_op.s_ivd_init_op_t.u4_size = sizeof(s_init_op);
3773e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
3783e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        s_init_ip.s_ivd_init_ip_t.u4_num_mem_rec = mNumMemRecords;
3793e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        s_init_ip.s_ivd_init_ip_t.e_output_format = mIvColorFormat;
3803e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
3813e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        mCodecCtx = (iv_obj_t*)mMemRecords[0].pv_base;
3823e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        mCodecCtx->pv_fxns = dec_fxns;
3833e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        mCodecCtx->u4_size = sizeof(iv_obj_t);
3843e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
3853e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        ALOGD("Initializing decoder");
3863e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        status = ivdec_api_function(mCodecCtx, (void *)&s_init_ip,
3873e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                (void *)&s_init_op);
3883e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        if (status != IV_SUCCESS) {
3893e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            ALOGE("Error in init: 0x%x",
3903e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                    s_init_op.s_ivd_init_op_t.u4_error_code);
3913e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            return UNKNOWN_ERROR;
3923e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        }
3933e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    }
3943e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
3953e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    /* Reset the plugin state */
3963e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    resetPlugin();
3973e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
3983e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    /* Set the run time (dynamic) parameters */
3991aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu    setParams(displayStride);
4003e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
4013e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    /* Set number of cores/threads to be used by the codec */
4023e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    setNumCores();
4033e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
4043e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    /* Get codec version */
405f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy    logVersion();
4063e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
4073e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    /* Allocate internal picture buffer */
4081aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu    uint32_t bufferSize = displaySizeY * 3 / 2;
4091aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu    mFlushOutBuffer = (uint8_t *)ivd_aligned_malloc(128, bufferSize);
4103e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    if (NULL == mFlushOutBuffer) {
4111aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu        ALOGE("Could not allocate flushOutputBuffer of size %zu", bufferSize);
4123e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        return NO_MEMORY;
4133e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    }
4143e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
4151aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu    mInitNeeded = false;
4161aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu    mFlushNeeded = false;
4173e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    return OK;
4183e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar}
4193e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
4203e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnarstatus_t SoftHEVC::deInitDecoder() {
4213e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    size_t i;
422f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy
423f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy    if (mMemRecords) {
424f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy        iv_mem_rec_t *ps_mem_rec;
425f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy
426f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy        ps_mem_rec = mMemRecords;
427f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy        ALOGD("Freeing codec memory");
428f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy        for (i = 0; i < mNumMemRecords; i++) {
429f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy            if(ps_mem_rec->pv_base) {
430f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy                ivd_aligned_free(ps_mem_rec->pv_base);
431f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy            }
432f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy            ps_mem_rec++;
433f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy        }
434f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy        ivd_aligned_free(mMemRecords);
4351aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu        mMemRecords = NULL;
4363e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    }
4373e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
438f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy    if(mFlushOutBuffer) {
439f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy        ivd_aligned_free(mFlushOutBuffer);
4401aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu        mFlushOutBuffer = NULL;
441f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy    }
4421aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu
4431aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu    mInitNeeded = true;
4441aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu    mChangingResolution = false;
4451aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu
4463e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    return OK;
4473e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar}
4483e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
449f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamystatus_t SoftHEVC::reInitDecoder() {
450f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy    status_t ret;
451f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy
452f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy    deInitDecoder();
453f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy
454f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy    ret = initDecoder();
455f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy    if (OK != ret) {
456f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy        ALOGE("Create failure");
457f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy        deInitDecoder();
458f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy        return NO_MEMORY;
459f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy    }
460f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy    return OK;
461f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy}
4621aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu
4633e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnarvoid SoftHEVC::onReset() {
4643e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    ALOGD("onReset called");
4653e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    SoftVideoDecoderOMXComponent::onReset();
4663e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
4673e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    resetDecoder();
4683e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    resetPlugin();
4693e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar}
4703e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
4711aa26f787afc525e0deae31d856dce74a4b28a0fRonghua WuOMX_ERRORTYPE SoftHEVC::internalSetParameter(OMX_INDEXTYPE index, const OMX_PTR params) {
4721aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu    const uint32_t oldWidth = mWidth;
4731aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu    const uint32_t oldHeight = mHeight;
4741aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu    OMX_ERRORTYPE ret = SoftVideoDecoderOMXComponent::internalSetParameter(index, params);
4751aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu    if (mWidth != oldWidth || mHeight != oldHeight) {
4761aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu        reInitDecoder();
4771aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu    }
4781aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu    return ret;
4791aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu}
4801aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu
481f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamyvoid SoftHEVC::setDecodeArgs(ivd_video_decode_ip_t *ps_dec_ip,
482f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy        ivd_video_decode_op_t *ps_dec_op,
483f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy        OMX_BUFFERHEADERTYPE *inHeader,
484f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy        OMX_BUFFERHEADERTYPE *outHeader,
485f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy        size_t timeStampIx) {
4861aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu    size_t sizeY = outputBufferWidth() * outputBufferHeight();
487f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy    size_t sizeUV;
488f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy    uint8_t *pBuf;
489f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy
490f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy    ps_dec_ip->u4_size = sizeof(ivd_video_decode_ip_t);
491f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy    ps_dec_op->u4_size = sizeof(ivd_video_decode_op_t);
492f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy
493f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy    ps_dec_ip->e_cmd = IVD_CMD_VIDEO_DECODE;
494f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy
495f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy    /* When in flush and after EOS with zero byte input,
496f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy     * inHeader is set to zero. Hence check for non-null */
497f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy    if (inHeader) {
498f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy        ps_dec_ip->u4_ts = timeStampIx;
499f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy        ps_dec_ip->pv_stream_buffer = inHeader->pBuffer
500f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy                + inHeader->nOffset;
501f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy        ps_dec_ip->u4_num_Bytes = inHeader->nFilledLen;
502f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy    } else {
503f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy        ps_dec_ip->u4_ts = 0;
504f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy        ps_dec_ip->pv_stream_buffer = NULL;
505f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy        ps_dec_ip->u4_num_Bytes = 0;
506f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy    }
507f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy
508f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy    if (outHeader) {
509f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy        pBuf = outHeader->pBuffer;
510f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy    } else {
511f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy        pBuf = mFlushOutBuffer;
512f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy    }
513f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy
514f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy    sizeUV = sizeY / 4;
515f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy    ps_dec_ip->s_out_buffer.u4_min_out_buf_size[0] = sizeY;
516f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy    ps_dec_ip->s_out_buffer.u4_min_out_buf_size[1] = sizeUV;
517f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy    ps_dec_ip->s_out_buffer.u4_min_out_buf_size[2] = sizeUV;
518f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy
519f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy    ps_dec_ip->s_out_buffer.pu1_bufs[0] = pBuf;
520f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy    ps_dec_ip->s_out_buffer.pu1_bufs[1] = pBuf + sizeY;
521f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy    ps_dec_ip->s_out_buffer.pu1_bufs[2] = pBuf + sizeY + sizeUV;
522f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy    ps_dec_ip->s_out_buffer.u4_num_bufs = 3;
523f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy    return;
524f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy}
5253e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnarvoid SoftHEVC::onPortFlushCompleted(OMX_U32 portIndex) {
5263e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    /* Once the output buffers are flushed, ignore any buffers that are held in decoder */
5273e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    if (kOutputPortIndex == portIndex) {
5283e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        setFlushMode();
5293e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
5303e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        while (true) {
5313e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            ivd_video_decode_ip_t s_dec_ip;
5323e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            ivd_video_decode_op_t s_dec_op;
5333e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            IV_API_CALL_STATUS_T status;
5343e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            size_t sizeY, sizeUV;
5353e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
5361aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu            setDecodeArgs(&s_dec_ip, &s_dec_op, NULL, NULL, 0);
5373e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
5383e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            status = ivdec_api_function(mCodecCtx, (void *)&s_dec_ip,
5393e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                    (void *)&s_dec_op);
5403e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            if (0 == s_dec_op.u4_output_present) {
5413e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                resetPlugin();
5423e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                break;
5433e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            }
5443e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        }
5453e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    }
5463e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar}
5473e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
5483e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnarvoid SoftHEVC::onQueueFilled(OMX_U32 portIndex) {
5493e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    UNUSED(portIndex);
5503e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
5513e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    if (mOutputPortSettingsChange != NONE) {
5523e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        return;
5533e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    }
5543e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
5553e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    List<BufferInfo *> &inQueue = getPortQueue(kInputPortIndex);
5563e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    List<BufferInfo *> &outQueue = getPortQueue(kOutputPortIndex);
5573e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
5583e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    /* If input EOS is seen and decoder is not in flush mode,
5593e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar     * set the decoder in flush mode.
5603e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar     * There can be a case where EOS is sent along with last picture data
5613e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar     * In that case, only after decoding that input data, decoder has to be
5623e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar     * put in flush. This case is handled here  */
5633e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
5643e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    if (mReceivedEOS && !mIsInFlush) {
5653e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        setFlushMode();
5663e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    }
5673e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
5681aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu    while (!outQueue.empty()) {
5693e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        BufferInfo *inInfo;
5703e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        OMX_BUFFERHEADERTYPE *inHeader;
5713e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
5723e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        BufferInfo *outInfo;
5733e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        OMX_BUFFERHEADERTYPE *outHeader;
5743e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        size_t timeStampIx;
5753e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
5763e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        inInfo = NULL;
5773e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        inHeader = NULL;
5783e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
5793e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        if (!mIsInFlush) {
5803e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            if (!inQueue.empty()) {
5813e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                inInfo = *inQueue.begin();
5823e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                inHeader = inInfo->mHeader;
5833e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            } else {
5843e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                break;
5853e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            }
5863e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        }
5873e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
5883e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        outInfo = *outQueue.begin();
5893e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        outHeader = outInfo->mHeader;
5903e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        outHeader->nFlags = 0;
5913e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        outHeader->nTimeStamp = 0;
5923e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        outHeader->nOffset = 0;
5933e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
5943e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        if (inHeader != NULL && (inHeader->nFlags & OMX_BUFFERFLAG_EOS)) {
5953e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            ALOGD("EOS seen on input");
5963e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            mReceivedEOS = true;
5973e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            if (inHeader->nFilledLen == 0) {
5983e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                inQueue.erase(inQueue.begin());
5993e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                inInfo->mOwnedByUs = false;
6003e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                notifyEmptyBufferDone(inHeader);
6013e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                inHeader = NULL;
6023e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                setFlushMode();
6033e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            }
6043e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        }
6053e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
6061aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu        // When there is an init required and the decoder is not in flush mode,
6071aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu        // update output port's definition and reinitialize decoder.
6081aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu        if (mInitNeeded && !mIsInFlush) {
6091aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu            bool portWillReset = false;
6101aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu            handlePortSettingsChange(&portWillReset, mNewWidth, mNewHeight);
6111aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu
6121aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu            CHECK_EQ(reInitDecoder(), (status_t)OK);
6131aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu            return;
6141aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu        }
6151aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu
6163e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        /* Get a free slot in timestamp array to hold input timestamp */
6173e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        {
6183e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            size_t i;
6193e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            timeStampIx = 0;
6203e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            for (i = 0; i < MAX_TIME_STAMPS; i++) {
6213e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                if (!mTimeStampsValid[i]) {
6223e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                    timeStampIx = i;
6233e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                    break;
6243e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                }
6253e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            }
6263e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            if (inHeader != NULL) {
6273e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                mTimeStampsValid[timeStampIx] = true;
6283e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                mTimeStamps[timeStampIx] = inHeader->nTimeStamp;
6293e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            }
6303e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        }
6313e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
6323e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        {
6333e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            ivd_video_decode_ip_t s_dec_ip;
6343e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            ivd_video_decode_op_t s_dec_op;
6353e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            WORD32 timeDelay, timeTaken;
6363e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            size_t sizeY, sizeUV;
6373e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
6381aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu            setDecodeArgs(&s_dec_ip, &s_dec_op, inHeader, outHeader, timeStampIx);
6393e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
6403e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            GETTIME(&mTimeStart, NULL);
6413e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            /* Compute time elapsed between end of previous decode()
6423e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar             * to start of current decode() */
6433e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            TIME_DIFF(mTimeEnd, mTimeStart, timeDelay);
6443e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
6451aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu            IV_API_CALL_STATUS_T status;
6461aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu            status = ivdec_api_function(mCodecCtx, (void *)&s_dec_ip, (void *)&s_dec_op);
6471aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu            // FIXME: Compare |status| to IHEVCD_UNSUPPORTED_DIMENSIONS, which is not one of the
6481aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu            // IV_API_CALL_STATUS_T, seems be wrong. But this is what the decoder returns right now.
6491aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu            // The decoder should be fixed so that |u4_error_code| instead of |status| returns
6501aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu            // IHEVCD_UNSUPPORTED_DIMENSIONS.
6511aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu            bool unsupportedDimensions =
652a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                ((IHEVCD_UNSUPPORTED_DIMENSIONS == (IHEVCD_CXA_ERROR_CODES_T)status)
6531aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu                    || (IHEVCD_UNSUPPORTED_DIMENSIONS == s_dec_op.u4_error_code));
6541aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu            bool resChanged = (IVD_RES_CHANGED == (s_dec_op.u4_error_code & 0xFF));
6553e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
6563e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            GETTIME(&mTimeEnd, NULL);
6573e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            /* Compute time taken for decode() */
6583e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            TIME_DIFF(mTimeStart, mTimeEnd, timeTaken);
6593e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
6601aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu            ALOGV("timeTaken=%6d delay=%6d numBytes=%6d", timeTaken, timeDelay,
6611aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu                   s_dec_op.u4_num_bytes_consumed);
6621aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu            if (s_dec_op.u4_frame_decoded_flag && !mFlushNeeded) {
6631aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu                mFlushNeeded = true;
6641aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu            }
6651aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu
6661aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu            if ((inHeader != NULL) && (1 != s_dec_op.u4_frame_decoded_flag)) {
6671aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu                /* If the input did not contain picture data, then ignore
6681aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu                 * the associated timestamp */
6691aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu                mTimeStampsValid[timeStampIx] = false;
6701aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu            }
6713e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
6721aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu            // This is needed to handle CTS DecoderTest testCodecResetsHEVCWithoutSurface,
6731aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu            // which is not sending SPS/PPS after port reconfiguration and flush to the codec.
6741aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu            if (unsupportedDimensions && !mFlushNeeded) {
6751aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu                bool portWillReset = false;
6761aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu                handlePortSettingsChange(&portWillReset, s_dec_op.u4_pic_wd, s_dec_op.u4_pic_ht);
677f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy
678f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy                CHECK_EQ(reInitDecoder(), (status_t)OK);
679f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy
6801aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu                setDecodeArgs(&s_dec_ip, &s_dec_op, inHeader, outHeader, timeStampIx);
681f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy
6821aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu                ivdec_api_function(mCodecCtx, (void *)&s_dec_ip, (void *)&s_dec_op);
6831aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu                return;
684f6ef963fecde3b63696028fadce4bcfb5b998db0Naveen Kumar Ponnusamy            }
6851aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu
6861aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu            // If the decoder is in the changing resolution mode and there is no output present,
6871aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu            // that means the switching is done and it's ready to reset the decoder and the plugin.
6881aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu            if (mChangingResolution && !s_dec_op.u4_output_present) {
6891aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu                mChangingResolution = false;
6901aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu                resetDecoder();
6911aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu                resetPlugin();
6921aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu                continue;
6931aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu            }
6941aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu
6951aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu            if (unsupportedDimensions || resChanged) {
6961aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu                mChangingResolution = true;
6971aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu                if (mFlushNeeded) {
6981aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu                    setFlushMode();
6991aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu                }
7001aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu
7011aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu                if (unsupportedDimensions) {
7021aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu                    mNewWidth = s_dec_op.u4_pic_wd;
7031aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu                    mNewHeight = s_dec_op.u4_pic_ht;
7041aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu                    mInitNeeded = true;
7051aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu                }
7061aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu                continue;
7073e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            }
7083e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
7093e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            if ((0 < s_dec_op.u4_pic_wd) && (0 < s_dec_op.u4_pic_ht)) {
7103e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                uint32_t width = s_dec_op.u4_pic_wd;
7113e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                uint32_t height = s_dec_op.u4_pic_ht;
7121aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu                bool portWillReset = false;
7131aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu                handlePortSettingsChange(&portWillReset, width, height);
7143e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
7151aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu                if (portWillReset) {
7161aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu                    resetDecoder();
7173e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                    return;
7183e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                }
7193e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            }
7203e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
7213e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            if (s_dec_op.u4_output_present) {
7221aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu                outHeader->nFilledLen = (mWidth * mHeight * 3) / 2;
7233e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
7243e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                outHeader->nTimeStamp = mTimeStamps[s_dec_op.u4_ts];
7253e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                mTimeStampsValid[s_dec_op.u4_ts] = false;
7263e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
7273e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                outInfo->mOwnedByUs = false;
7283e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                outQueue.erase(outQueue.begin());
7293e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                outInfo = NULL;
7303e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                notifyFillBufferDone(outHeader);
7313e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                outHeader = NULL;
7323e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            } else {
7333e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                /* If in flush mode and no output is returned by the codec,
7343e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                 * then come out of flush mode */
7353e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                mIsInFlush = false;
7363e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
7373e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                /* If EOS was recieved on input port and there is no output
7383e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                 * from the codec, then signal EOS on output port */
7393e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                if (mReceivedEOS) {
7403e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                    outHeader->nFilledLen = 0;
7413e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                    outHeader->nFlags |= OMX_BUFFERFLAG_EOS;
7423e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
7433e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                    outInfo->mOwnedByUs = false;
7443e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                    outQueue.erase(outQueue.begin());
7453e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                    outInfo = NULL;
7463e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                    notifyFillBufferDone(outHeader);
7473e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                    outHeader = NULL;
7483e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                    resetPlugin();
7493e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar                }
7503e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            }
7513e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        }
7523e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
7533e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        // TODO: Handle more than one picture data
7543e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        if (inHeader != NULL) {
7553e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            inInfo->mOwnedByUs = false;
7563e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            inQueue.erase(inQueue.begin());
7573e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            inInfo = NULL;
7583e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            notifyEmptyBufferDone(inHeader);
7593e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar            inHeader = NULL;
7603e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        }
7613e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    }
7623e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar}
7633e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
7641aa26f787afc525e0deae31d856dce74a4b28a0fRonghua Wu}  // namespace android
7653e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar
7663e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnarandroid::SoftOMXComponent *createSoftOMXComponent(const char *name,
7673e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        const OMX_CALLBACKTYPE *callbacks, OMX_PTR appData,
7683e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar        OMX_COMPONENTTYPE **component) {
7693e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar    return new android::SoftHEVC(name, callbacks, appData, component);
7703e648747e7e40752580ae7fd0ff2e803623680cdLajos Molnar}
771