SoftAVCDec.cpp revision c7e892937448915a89d3aaef369ecfe3999bd4eb
12c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*
22c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * Copyright 2015 The Android Open Source Project
3135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent *
489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * you may not use this file except in compliance with the License.
689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * You may obtain a copy of the License at
789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *
889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *
1089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
1189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
1289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * See the License for the specific language governing permissions and
1489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * limitations under the License.
1589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project */
1689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
1789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//#define LOG_NDEBUG 0
182c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#define LOG_TAG "SoftAVCDec"
192c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#include <utils/Log.h>
202c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
212c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#include "ih264_typedefs.h"
222c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#include "iv.h"
232c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#include "ivd.h"
242c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#include "ih264d.h"
252c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#include "SoftAVCDec.h"
262c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
272c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#include <media/stagefright/foundation/ADebug.h>
282c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#include <media/stagefright/MediaDefs.h>
292c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#include <OMX_VideoExt.h>
302c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
312c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurentnamespace android {
322c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
332c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#define PRINT_TIME  ALOGV
342c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
352c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#define componentName                   "video_decoder.avc"
362c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#define codingType                      OMX_VIDEO_CodingAVC
372c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#define CODEC_MIME_TYPE                 MEDIA_MIMETYPE_VIDEO_AVC
382c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
392c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/** Function and structure definitions to keep code similar for each codec */
402c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#define ivdec_api_function              ih264d_api_function
412c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#define ivdext_create_ip_t              ih264d_create_ip_t
422c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#define ivdext_create_op_t              ih264d_create_op_t
432c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#define ivdext_delete_ip_t              ih264d_delete_ip_t
442c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#define ivdext_delete_op_t              ih264d_delete_op_t
452c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#define ivdext_ctl_set_num_cores_ip_t   ih264d_ctl_set_num_cores_ip_t
462c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#define ivdext_ctl_set_num_cores_op_t   ih264d_ctl_set_num_cores_op_t
472c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
482c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#define IVDEXT_CMD_CTL_SET_NUM_CORES    \
492c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        (IVD_CONTROL_API_COMMAND_TYPE_T)IH264D_CMD_CTL_SET_NUM_CORES
502c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
512c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurentstatic const CodecProfileLevel kProfileLevels[] = {
522c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1  },
532c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1b },
542c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel11 },
552c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel12 },
562c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel13 },
572c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel2  },
582c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel21 },
592c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel22 },
602c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel3  },
612c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel31 },
622c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel32 },
632c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel4  },
642c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel41 },
652c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel42 },
662c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel5  },
672c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel51 },
682c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel52 },
692c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
702c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel1  },
712c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel1b },
722c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel11 },
732c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel12 },
742c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel13 },
752c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel2  },
762c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel21 },
772c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel22 },
782c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel3  },
792c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel31 },
802c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel32 },
812c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel4  },
822c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel41 },
832c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel42 },
842c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel5  },
852c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel51 },
862c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel52 },
872c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
882c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel1  },
892c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel1b },
902c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel11 },
912c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel12 },
922c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel13 },
932c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel2  },
942c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel21 },
952c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel22 },
962c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel3  },
972c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel31 },
982c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel32 },
992c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel4  },
1002c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel41 },
1012c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel42 },
1022c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel5  },
1032c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel51 },
1042c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel52 },
1052c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent};
1062c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1072c8e5cab3faa6d360e222b7a6c40a80083d021acEric LaurentSoftAVC::SoftAVC(
1082c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        const char *name,
1092c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        const OMX_CALLBACKTYPE *callbacks,
1102c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        OMX_PTR appData,
1112c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        OMX_COMPONENTTYPE **component)
1122c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    : SoftVideoDecoderOMXComponent(
1132c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            name, componentName, codingType,
1142c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            kProfileLevels, ARRAY_SIZE(kProfileLevels),
1152c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            320 /* width */, 240 /* height */, callbacks,
1162c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            appData, component),
1172c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent      mCodecCtx(NULL),
1182c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent      mFlushOutBuffer(NULL),
1192c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent      mOmxColorFormat(OMX_COLOR_FormatYUV420Planar),
1202c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent      mIvColorFormat(IV_YUV_420P),
1212c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent      mChangingResolution(false),
1222c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent      mSignalledError(false),
1232c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent      mStride(mWidth){
1242c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    initPorts(
1252c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            kNumBuffers, INPUT_BUF_SIZE, kNumBuffers, CODEC_MIME_TYPE);
1262c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1272c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    GETTIME(&mTimeStart, NULL);
1282c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1292c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    // If input dump is enabled, then open create an empty file
1302c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    GENERATE_FILE_NAMES();
1312c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    CREATE_DUMP_FILE(mInFile);
1322c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent}
1332c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1342c8e5cab3faa6d360e222b7a6c40a80083d021acEric LaurentSoftAVC::~SoftAVC() {
1352c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    CHECK_EQ(deInitDecoder(), (status_t)OK);
1362c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent}
1372c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1382c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurentstatic void *ivd_aligned_malloc(void *ctxt, WORD32 alignment, WORD32 size) {
1392c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    UNUSED(ctxt);
1402c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    return memalign(alignment, size);
1412c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent}
1422c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1432c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurentstatic void ivd_aligned_free(void *ctxt, void *buf) {
1442c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    UNUSED(ctxt);
1452c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    free(buf);
1462c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    return;
1472c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent}
1482c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1492c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurentstatic size_t GetCPUCoreCount() {
1502c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    long cpuCoreCount = 1;
1512c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#if defined(_SC_NPROCESSORS_ONLN)
1522c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    cpuCoreCount = sysconf(_SC_NPROCESSORS_ONLN);
1532c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#else
1542c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    // _SC_NPROC_ONLN must be defined...
1552c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    cpuCoreCount = sysconf(_SC_NPROC_ONLN);
1562c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#endif
1572c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    CHECK(cpuCoreCount >= 1);
1582c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    ALOGV("Number of CPU cores: %ld", cpuCoreCount);
1592c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    return (size_t)cpuCoreCount;
1602c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent}
1612c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1622c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurentvoid SoftAVC::logVersion() {
1632c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    ivd_ctl_getversioninfo_ip_t s_ctl_ip;
1642c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    ivd_ctl_getversioninfo_op_t s_ctl_op;
1652c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    UWORD8 au1_buf[512];
1662c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    IV_API_CALL_STATUS_T status;
1672c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1682c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
1692c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_GETVERSION;
1702c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    s_ctl_ip.u4_size = sizeof(ivd_ctl_getversioninfo_ip_t);
1712c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    s_ctl_op.u4_size = sizeof(ivd_ctl_getversioninfo_op_t);
1722c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    s_ctl_ip.pv_version_buffer = au1_buf;
1732c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    s_ctl_ip.u4_version_buffer_size = sizeof(au1_buf);
1742c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1752c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    status =
1762c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        ivdec_api_function(mCodecCtx, (void *)&s_ctl_ip, (void *)&s_ctl_op);
1772c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1782c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if (status != IV_SUCCESS) {
1792c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        ALOGE("Error in getting version number: 0x%x",
1802c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                s_ctl_op.u4_error_code);
1812c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    } else {
1822c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        ALOGV("Ittiam decoder version number: %s",
1832c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                (char *)s_ctl_ip.pv_version_buffer);
1842c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
1852c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    return;
1862c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent}
1872c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1882c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurentstatus_t SoftAVC::setParams(size_t stride) {
1892c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    ivd_ctl_set_config_ip_t s_ctl_ip;
1902c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    ivd_ctl_set_config_op_t s_ctl_op;
1912c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    IV_API_CALL_STATUS_T status;
1922c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    s_ctl_ip.u4_disp_wd = (UWORD32)stride;
1932c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    s_ctl_ip.e_frm_skip_mode = IVD_SKIP_NONE;
1942c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1952c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    s_ctl_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
1962c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    s_ctl_ip.e_vid_dec_mode = IVD_DECODE_FRAME;
1972c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
1982c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
1992c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    s_ctl_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t);
2002c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_op_t);
2012c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2022c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    ALOGV("Set the run-time (dynamic) parameters stride = %zu", stride);
2032c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    status = ivdec_api_function(mCodecCtx, (void *)&s_ctl_ip, (void *)&s_ctl_op);
2042c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2052c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if (status != IV_SUCCESS) {
2062c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        ALOGE("Error in setting the run-time parameters: 0x%x",
2072c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                s_ctl_op.u4_error_code);
2082c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2092c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        return UNKNOWN_ERROR;
2102c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
2112c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    return OK;
2122c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent}
2132c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2142c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurentstatus_t SoftAVC::resetPlugin() {
2152c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    mIsInFlush = false;
2162c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    mReceivedEOS = false;
2172c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    memset(mTimeStamps, 0, sizeof(mTimeStamps));
2182c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    memset(mTimeStampsValid, 0, sizeof(mTimeStampsValid));
2192c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2202c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /* Initialize both start and end times */
2212c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    gettimeofday(&mTimeStart, NULL);
2222c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    gettimeofday(&mTimeEnd, NULL);
2232c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2242c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    return OK;
2252c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent}
2262c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2272c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurentstatus_t SoftAVC::resetDecoder() {
2282c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    ivd_ctl_reset_ip_t s_ctl_ip;
2292c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    ivd_ctl_reset_op_t s_ctl_op;
2302c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    IV_API_CALL_STATUS_T status;
2312c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2322c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
2332c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_RESET;
2342c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    s_ctl_ip.u4_size = sizeof(ivd_ctl_reset_ip_t);
2352c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    s_ctl_op.u4_size = sizeof(ivd_ctl_reset_op_t);
2362c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2372c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    status = ivdec_api_function(mCodecCtx, (void *)&s_ctl_ip, (void *)&s_ctl_op);
2382c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if (IV_SUCCESS != status) {
2392c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        ALOGE("Error in reset: 0x%x", s_ctl_op.u4_error_code);
2402c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        return UNKNOWN_ERROR;
2412c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
2422c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    mSignalledError = false;
2432c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2442c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /* Set number of cores/threads to be used by the codec */
2452c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    setNumCores();
2462c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2472c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    mStride = 0;
2482c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    return OK;
2492c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent}
2502c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2512c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurentstatus_t SoftAVC::setNumCores() {
2522c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    ivdext_ctl_set_num_cores_ip_t s_set_cores_ip;
2532c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    ivdext_ctl_set_num_cores_op_t s_set_cores_op;
2542c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    IV_API_CALL_STATUS_T status;
2552c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    s_set_cores_ip.e_cmd = IVD_CMD_VIDEO_CTL;
2562c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    s_set_cores_ip.e_sub_cmd = IVDEXT_CMD_CTL_SET_NUM_CORES;
2572c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    s_set_cores_ip.u4_num_cores = MIN(mNumCores, CODEC_MAX_NUM_CORES);
2582c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    s_set_cores_ip.u4_size = sizeof(ivdext_ctl_set_num_cores_ip_t);
2592c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    s_set_cores_op.u4_size = sizeof(ivdext_ctl_set_num_cores_op_t);
2602c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    status = ivdec_api_function(
2612c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            mCodecCtx, (void *)&s_set_cores_ip, (void *)&s_set_cores_op);
2622c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if (IV_SUCCESS != status) {
2632c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        ALOGE("Error in setting number of cores: 0x%x",
2642c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                s_set_cores_op.u4_error_code);
2652c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        return UNKNOWN_ERROR;
2662c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
2672c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    return OK;
2682c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent}
2692c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2702c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurentstatus_t SoftAVC::setFlushMode() {
2712c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    IV_API_CALL_STATUS_T status;
2722c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    ivd_ctl_flush_ip_t s_video_flush_ip;
2732c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    ivd_ctl_flush_op_t s_video_flush_op;
2742c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2752c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    s_video_flush_ip.e_cmd = IVD_CMD_VIDEO_CTL;
2762c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    s_video_flush_ip.e_sub_cmd = IVD_CMD_CTL_FLUSH;
2772c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    s_video_flush_ip.u4_size = sizeof(ivd_ctl_flush_ip_t);
2782c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    s_video_flush_op.u4_size = sizeof(ivd_ctl_flush_op_t);
2792c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2802c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /* Set the decoder in Flush mode, subsequent decode() calls will flush */
2812c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    status = ivdec_api_function(
2822c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            mCodecCtx, (void *)&s_video_flush_ip, (void *)&s_video_flush_op);
2832c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2842c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if (status != IV_SUCCESS) {
2852c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        ALOGE("Error in setting the decoder in flush mode: (%d) 0x%x", status,
2862c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                s_video_flush_op.u4_error_code);
2872c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        return UNKNOWN_ERROR;
2882c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
2892c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2902c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    mIsInFlush = true;
2912c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    return OK;
2922c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent}
2932c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2942c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurentstatus_t SoftAVC::initDecoder() {
2952c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    IV_API_CALL_STATUS_T status;
2962c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2972c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    mNumCores = GetCPUCoreCount();
2982c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    mCodecCtx = NULL;
2992c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3002c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    mStride = outputBufferWidth();
3012c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3022c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /* Initialize the decoder */
3032c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
3042c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        ivdext_create_ip_t s_create_ip;
3052c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        ivdext_create_op_t s_create_op;
3062c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3072c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        void *dec_fxns = (void *)ivdec_api_function;
3082c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3092c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        s_create_ip.s_ivd_create_ip_t.u4_size = sizeof(ivdext_create_ip_t);
3102c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        s_create_ip.s_ivd_create_ip_t.e_cmd = IVD_CMD_CREATE;
3112c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        s_create_ip.s_ivd_create_ip_t.u4_share_disp_buf = 0;
3122c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        s_create_op.s_ivd_create_op_t.u4_size = sizeof(ivdext_create_op_t);
3132c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        s_create_ip.s_ivd_create_ip_t.e_output_format = mIvColorFormat;
3142c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        s_create_ip.s_ivd_create_ip_t.pf_aligned_alloc = ivd_aligned_malloc;
3152c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        s_create_ip.s_ivd_create_ip_t.pf_aligned_free = ivd_aligned_free;
3162c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        s_create_ip.s_ivd_create_ip_t.pv_mem_ctxt = NULL;
3172c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3182c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        status = ivdec_api_function(mCodecCtx, (void *)&s_create_ip, (void *)&s_create_op);
3192c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3202c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        mCodecCtx = (iv_obj_t*)s_create_op.s_ivd_create_op_t.pv_handle;
3212c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        mCodecCtx->pv_fxns = dec_fxns;
3222c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        mCodecCtx->u4_size = sizeof(iv_obj_t);
3232c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3242c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        if (status != IV_SUCCESS) {
3252c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            ALOGE("Error in create: 0x%x",
3262c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                    s_create_op.s_ivd_create_op_t.u4_error_code);
3272c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            deInitDecoder();
3282c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            mCodecCtx = NULL;
3292c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            return UNKNOWN_ERROR;
3302c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        }
3312c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
3322c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3332c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /* Reset the plugin state */
3342c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    resetPlugin();
3352c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3362c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /* Set the run time (dynamic) parameters */
3372c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    setParams(mStride);
3382c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3392c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /* Set number of cores/threads to be used by the codec */
3402c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    setNumCores();
3412c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3422c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /* Get codec version */
3432c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    logVersion();
3442c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3452c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    mFlushNeeded = false;
3462c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    return OK;
3472c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent}
3482c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3492c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurentstatus_t SoftAVC::deInitDecoder() {
3502c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    size_t i;
3512c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    IV_API_CALL_STATUS_T status;
3522c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3532c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if (mCodecCtx) {
3542c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        ivdext_delete_ip_t s_delete_ip;
3552c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        ivdext_delete_op_t s_delete_op;
3562c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3572c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        s_delete_ip.s_ivd_delete_ip_t.u4_size = sizeof(ivdext_delete_ip_t);
3582c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        s_delete_ip.s_ivd_delete_ip_t.e_cmd = IVD_CMD_DELETE;
3592c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3602c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        s_delete_op.s_ivd_delete_op_t.u4_size = sizeof(ivdext_delete_op_t);
3612c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3622c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        status = ivdec_api_function(mCodecCtx, (void *)&s_delete_ip, (void *)&s_delete_op);
3632c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        if (status != IV_SUCCESS) {
3642c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            ALOGE("Error in delete: 0x%x",
3652c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                    s_delete_op.s_ivd_delete_op_t.u4_error_code);
3662c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            return UNKNOWN_ERROR;
3672c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        }
3682c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
3692c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3702c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3712c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    mChangingResolution = false;
3722c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3732c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    return OK;
3742c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent}
3752c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3762c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurentvoid SoftAVC::onReset() {
3772c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    SoftVideoDecoderOMXComponent::onReset();
3782c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3792c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    mSignalledError = false;
3802c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    resetDecoder();
3812c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    resetPlugin();
3822c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent}
3832c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3842c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurentvoid SoftAVC::setDecodeArgs(
3852c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        ivd_video_decode_ip_t *ps_dec_ip,
3862c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        ivd_video_decode_op_t *ps_dec_op,
3872c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        OMX_BUFFERHEADERTYPE *inHeader,
3882c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        OMX_BUFFERHEADERTYPE *outHeader,
389        size_t timeStampIx) {
390    size_t sizeY = outputBufferWidth() * outputBufferHeight();
391    size_t sizeUV;
392    uint8_t *pBuf;
393
394    ps_dec_ip->u4_size = sizeof(ivd_video_decode_ip_t);
395    ps_dec_op->u4_size = sizeof(ivd_video_decode_op_t);
396
397    ps_dec_ip->e_cmd = IVD_CMD_VIDEO_DECODE;
398
399    /* When in flush and after EOS with zero byte input,
400     * inHeader is set to zero. Hence check for non-null */
401    if (inHeader) {
402        ps_dec_ip->u4_ts = timeStampIx;
403        ps_dec_ip->pv_stream_buffer =
404            inHeader->pBuffer + inHeader->nOffset;
405        ps_dec_ip->u4_num_Bytes = inHeader->nFilledLen;
406    } else {
407        ps_dec_ip->u4_ts = 0;
408        ps_dec_ip->pv_stream_buffer = NULL;
409        ps_dec_ip->u4_num_Bytes = 0;
410    }
411
412    if (outHeader) {
413        pBuf = outHeader->pBuffer;
414    } else {
415        pBuf = mFlushOutBuffer;
416    }
417
418    sizeUV = sizeY / 4;
419    ps_dec_ip->s_out_buffer.u4_min_out_buf_size[0] = sizeY;
420    ps_dec_ip->s_out_buffer.u4_min_out_buf_size[1] = sizeUV;
421    ps_dec_ip->s_out_buffer.u4_min_out_buf_size[2] = sizeUV;
422
423    ps_dec_ip->s_out_buffer.pu1_bufs[0] = pBuf;
424    ps_dec_ip->s_out_buffer.pu1_bufs[1] = pBuf + sizeY;
425    ps_dec_ip->s_out_buffer.pu1_bufs[2] = pBuf + sizeY + sizeUV;
426    ps_dec_ip->s_out_buffer.u4_num_bufs = 3;
427    return;
428}
429void SoftAVC::onPortFlushCompleted(OMX_U32 portIndex) {
430    /* Once the output buffers are flushed, ignore any buffers that are held in decoder */
431    if (kOutputPortIndex == portIndex) {
432        setFlushMode();
433
434        /* Allocate a picture buffer to flushed data */
435        uint32_t displayStride = outputBufferWidth();
436        uint32_t displayHeight = outputBufferHeight();
437
438        uint32_t bufferSize = displayStride * displayHeight * 3 / 2;
439        mFlushOutBuffer = (uint8_t *)memalign(128, bufferSize);
440        if (NULL == mFlushOutBuffer) {
441            ALOGE("Could not allocate flushOutputBuffer of size %zu", bufferSize);
442            return;
443        }
444
445        while (true) {
446            ivd_video_decode_ip_t s_dec_ip;
447            ivd_video_decode_op_t s_dec_op;
448            IV_API_CALL_STATUS_T status;
449            size_t sizeY, sizeUV;
450
451            setDecodeArgs(&s_dec_ip, &s_dec_op, NULL, NULL, 0);
452
453            status = ivdec_api_function(mCodecCtx, (void *)&s_dec_ip, (void *)&s_dec_op);
454            if (0 == s_dec_op.u4_output_present) {
455                resetPlugin();
456                break;
457            }
458        }
459
460        if (mFlushOutBuffer) {
461            free(mFlushOutBuffer);
462            mFlushOutBuffer = NULL;
463        }
464
465    }
466}
467
468void SoftAVC::onQueueFilled(OMX_U32 portIndex) {
469    UNUSED(portIndex);
470
471    if (mSignalledError) {
472        return;
473    }
474    if (mOutputPortSettingsChange != NONE) {
475        return;
476    }
477
478    if (NULL == mCodecCtx) {
479        if (OK != initDecoder()) {
480            ALOGE("Failed to initialize decoder");
481            notify(OMX_EventError, OMX_ErrorUnsupportedSetting, 0, NULL);
482            mSignalledError = true;
483            return;
484        }
485    }
486    if (outputBufferWidth() != mStride) {
487        /* Set the run-time (dynamic) parameters */
488        mStride = outputBufferWidth();
489        setParams(mStride);
490    }
491
492    List<BufferInfo *> &inQueue = getPortQueue(kInputPortIndex);
493    List<BufferInfo *> &outQueue = getPortQueue(kOutputPortIndex);
494
495    /* If input EOS is seen and decoder is not in flush mode,
496     * set the decoder in flush mode.
497     * There can be a case where EOS is sent along with last picture data
498     * In that case, only after decoding that input data, decoder has to be
499     * put in flush. This case is handled here  */
500
501    if (mReceivedEOS && !mIsInFlush) {
502        setFlushMode();
503    }
504
505    while (!outQueue.empty()) {
506        BufferInfo *inInfo;
507        OMX_BUFFERHEADERTYPE *inHeader;
508
509        BufferInfo *outInfo;
510        OMX_BUFFERHEADERTYPE *outHeader;
511        size_t timeStampIx;
512
513        inInfo = NULL;
514        inHeader = NULL;
515
516        if (!mIsInFlush) {
517            if (!inQueue.empty()) {
518                inInfo = *inQueue.begin();
519                inHeader = inInfo->mHeader;
520                if (inHeader == NULL) {
521                    inQueue.erase(inQueue.begin());
522                    inInfo->mOwnedByUs = false;
523                    continue;
524                }
525            } else {
526                break;
527            }
528        }
529
530        outInfo = *outQueue.begin();
531        outHeader = outInfo->mHeader;
532        outHeader->nFlags = 0;
533        outHeader->nTimeStamp = 0;
534        outHeader->nOffset = 0;
535
536        if (inHeader != NULL) {
537            if (inHeader->nFilledLen == 0) {
538                inQueue.erase(inQueue.begin());
539                inInfo->mOwnedByUs = false;
540                notifyEmptyBufferDone(inHeader);
541
542                if (!(inHeader->nFlags & OMX_BUFFERFLAG_EOS)) {
543                    continue;
544                }
545
546                mReceivedEOS = true;
547                inHeader = NULL;
548                setFlushMode();
549            } else if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
550                mReceivedEOS = true;
551            }
552        }
553
554        /* Get a free slot in timestamp array to hold input timestamp */
555        {
556            size_t i;
557            timeStampIx = 0;
558            for (i = 0; i < MAX_TIME_STAMPS; i++) {
559                if (!mTimeStampsValid[i]) {
560                    timeStampIx = i;
561                    break;
562                }
563            }
564            if (inHeader != NULL) {
565                mTimeStampsValid[timeStampIx] = true;
566                mTimeStamps[timeStampIx] = inHeader->nTimeStamp;
567            }
568        }
569
570        {
571            ivd_video_decode_ip_t s_dec_ip;
572            ivd_video_decode_op_t s_dec_op;
573            WORD32 timeDelay, timeTaken;
574            size_t sizeY, sizeUV;
575
576            setDecodeArgs(&s_dec_ip, &s_dec_op, inHeader, outHeader, timeStampIx);
577            // If input dump is enabled, then write to file
578            DUMP_TO_FILE(mInFile, s_dec_ip.pv_stream_buffer, s_dec_ip.u4_num_Bytes);
579
580            GETTIME(&mTimeStart, NULL);
581            /* Compute time elapsed between end of previous decode()
582             * to start of current decode() */
583            TIME_DIFF(mTimeEnd, mTimeStart, timeDelay);
584
585            IV_API_CALL_STATUS_T status;
586            status = ivdec_api_function(mCodecCtx, (void *)&s_dec_ip, (void *)&s_dec_op);
587
588            bool unsupportedResolution =
589                (IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED == (s_dec_op.u4_error_code & 0xFF));
590
591            /* Check for unsupported dimensions */
592            if (unsupportedResolution) {
593                ALOGE("Unsupported resolution : %dx%d", mWidth, mHeight);
594                notify(OMX_EventError, OMX_ErrorUnsupportedSetting, 0, NULL);
595                mSignalledError = true;
596                return;
597            }
598
599            bool allocationFailed = (IVD_MEM_ALLOC_FAILED == (s_dec_op.u4_error_code & 0xFF));
600            if (allocationFailed) {
601                ALOGE("Allocation failure in decoder");
602                notify(OMX_EventError, OMX_ErrorUnsupportedSetting, 0, NULL);
603                mSignalledError = true;
604                return;
605            }
606
607            bool resChanged = (IVD_RES_CHANGED == (s_dec_op.u4_error_code & 0xFF));
608
609            GETTIME(&mTimeEnd, NULL);
610            /* Compute time taken for decode() */
611            TIME_DIFF(mTimeStart, mTimeEnd, timeTaken);
612
613            PRINT_TIME("timeTaken=%6d delay=%6d numBytes=%6d", timeTaken, timeDelay,
614                   s_dec_op.u4_num_bytes_consumed);
615            if (s_dec_op.u4_frame_decoded_flag && !mFlushNeeded) {
616                mFlushNeeded = true;
617            }
618
619            if ((inHeader != NULL) && (1 != s_dec_op.u4_frame_decoded_flag)) {
620                /* If the input did not contain picture data, then ignore
621                 * the associated timestamp */
622                mTimeStampsValid[timeStampIx] = false;
623            }
624
625            // If the decoder is in the changing resolution mode and there is no output present,
626            // that means the switching is done and it's ready to reset the decoder and the plugin.
627            if (mChangingResolution && !s_dec_op.u4_output_present) {
628                mChangingResolution = false;
629                resetDecoder();
630                resetPlugin();
631                continue;
632            }
633
634            if (resChanged) {
635                mChangingResolution = true;
636                if (mFlushNeeded) {
637                    setFlushMode();
638                }
639                continue;
640            }
641
642            if ((0 < s_dec_op.u4_pic_wd) && (0 < s_dec_op.u4_pic_ht)) {
643                uint32_t width = s_dec_op.u4_pic_wd;
644                uint32_t height = s_dec_op.u4_pic_ht;
645                bool portWillReset = false;
646                handlePortSettingsChange(&portWillReset, width, height);
647
648                if (portWillReset) {
649                    resetDecoder();
650                    return;
651                }
652            }
653
654            if (s_dec_op.u4_output_present) {
655                outHeader->nFilledLen = (outputBufferWidth() * outputBufferHeight() * 3) / 2;
656
657                outHeader->nTimeStamp = mTimeStamps[s_dec_op.u4_ts];
658                mTimeStampsValid[s_dec_op.u4_ts] = false;
659
660                outInfo->mOwnedByUs = false;
661                outQueue.erase(outQueue.begin());
662                outInfo = NULL;
663                notifyFillBufferDone(outHeader);
664                outHeader = NULL;
665            } else {
666                /* If in flush mode and no output is returned by the codec,
667                 * then come out of flush mode */
668                mIsInFlush = false;
669
670                /* If EOS was recieved on input port and there is no output
671                 * from the codec, then signal EOS on output port */
672                if (mReceivedEOS) {
673                    outHeader->nFilledLen = 0;
674                    outHeader->nFlags |= OMX_BUFFERFLAG_EOS;
675
676                    outInfo->mOwnedByUs = false;
677                    outQueue.erase(outQueue.begin());
678                    outInfo = NULL;
679                    notifyFillBufferDone(outHeader);
680                    outHeader = NULL;
681                    resetPlugin();
682                }
683            }
684        }
685
686        if (inHeader != NULL) {
687            inInfo->mOwnedByUs = false;
688            inQueue.erase(inQueue.begin());
689            inInfo = NULL;
690            notifyEmptyBufferDone(inHeader);
691            inHeader = NULL;
692        }
693    }
694}
695
696}  // namespace android
697
698android::SoftOMXComponent *createSoftOMXComponent(
699        const char *name, const OMX_CALLBACKTYPE *callbacks, OMX_PTR appData,
700        OMX_COMPONENTTYPE **component) {
701    return new android::SoftAVC(name, callbacks, appData, component);
702}
703