SoftMPEG2.cpp revision f5a92a768f8d2058d09c9b6d3d370b64723887bd
14b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines/* 24b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * Copyright 2015 The Android Open Source Project 34b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * 44b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * Licensed under the Apache License, Version 2.0 (the "License"); 54b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * you may not use this file except in compliance with the License. 64b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * You may obtain a copy of the License at 74b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * 84b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * http://www.apache.org/licenses/LICENSE-2.0 94b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * 104b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * Unless required by applicable law or agreed to in writing, software 114b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * distributed under the License is distributed on an "AS IS" BASIS, 124b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * See the License for the specific language governing permissions and 144b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * limitations under the License. 154b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines */ 164b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 174b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines//#define LOG_NDEBUG 0 184b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#define LOG_TAG "SoftMPEG2" 19e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <utils/Log.h> 20e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 214b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "iv_datatypedef.h" 224b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "iv.h" 23be27482cdeaf08576bc39b72a15d35d13014a636Logan#include "ivd.h" 244b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "impeg2d.h" 254b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "SoftMPEG2.h" 264b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 274b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include <media/stagefright/foundation/ADebug.h> 286e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include <media/stagefright/MediaDefs.h> 294b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include <OMX_VideoExt.h> 30292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 314b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesnamespace android { 324b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 33e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#define componentName "video_decoder.mpeg2" 344b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#define codingType OMX_VIDEO_CodingMPEG2 35f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines#define CODEC_MIME_TYPE MEDIA_MIMETYPE_VIDEO_MPEG2 361bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 371bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines/** Function and structure definitions to keep code similar for each codec */ 38f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines#define ivdec_api_function impeg2d_api_function 391bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines#define ivdext_init_ip_t impeg2d_init_ip_t 401bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines#define ivdext_init_op_t impeg2d_init_op_t 411bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines#define ivdext_fill_mem_rec_ip_t impeg2d_fill_mem_rec_ip_t 42f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines#define ivdext_fill_mem_rec_op_t impeg2d_fill_mem_rec_op_t 431bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines#define ivdext_ctl_set_num_cores_ip_t impeg2d_ctl_set_num_cores_ip_t 441bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines#define ivdext_ctl_set_num_cores_op_t impeg2d_ctl_set_num_cores_op_t 451bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 461bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines#define IVDEXT_CMD_CTL_SET_NUM_CORES \ 471bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines (IVD_CONTROL_API_COMMAND_TYPE_T)IMPEG2D_CMD_CTL_SET_NUM_CORES 481bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 491bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hinesstatic const CodecProfileLevel kProfileLevels[] = { 501bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines { OMX_VIDEO_MPEG2ProfileSimple, OMX_VIDEO_MPEG2LevelLL }, 511bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines { OMX_VIDEO_MPEG2ProfileSimple, OMX_VIDEO_MPEG2LevelML }, 521bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines { OMX_VIDEO_MPEG2ProfileSimple, OMX_VIDEO_MPEG2LevelH14 }, 531bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines { OMX_VIDEO_MPEG2ProfileSimple, OMX_VIDEO_MPEG2LevelHL }, 541bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 551bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines { OMX_VIDEO_MPEG2ProfileMain , OMX_VIDEO_MPEG2LevelLL }, 561bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines { OMX_VIDEO_MPEG2ProfileMain , OMX_VIDEO_MPEG2LevelML }, 571bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines { OMX_VIDEO_MPEG2ProfileMain , OMX_VIDEO_MPEG2LevelH14 }, 581bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines { OMX_VIDEO_MPEG2ProfileMain , OMX_VIDEO_MPEG2LevelHL }, 591bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines}; 601bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 611bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen HinesSoftMPEG2::SoftMPEG2( 626e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines const char *name, 636e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines const OMX_CALLBACKTYPE *callbacks, 641bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines OMX_PTR appData, 651bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines OMX_COMPONENTTYPE **component) 666e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines : SoftVideoDecoderOMXComponent( 676e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines name, componentName, codingType, 681bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines kProfileLevels, ARRAY_SIZE(kProfileLevels), 69e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 320 /* width */, 240 /* height */, callbacks, 701bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines appData, component), 711bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines mMemRecords(NULL), 721bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines mFlushOutBuffer(NULL), 731bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines mOmxColorFormat(OMX_COLOR_FormatYUV420Planar), 741bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines mIvColorFormat(IV_YUV_420P), 751bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines mNewWidth(mWidth), 766e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines mNewHeight(mHeight), 776e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines mChangingResolution(false) { 781bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines initPorts(kNumBuffers, INPUT_BUF_SIZE, kNumBuffers, CODEC_MIME_TYPE); 791bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 801bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // If input dump is enabled, then open create an empty file 811bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines GENERATE_FILE_NAMES(); 821bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines CREATE_DUMP_FILE(mInFile); 836e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines 841bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines CHECK_EQ(initDecoder(), (status_t)OK); 851bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 861bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 871bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen HinesSoftMPEG2::~SoftMPEG2() { 881bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines CHECK_EQ(deInitDecoder(), (status_t)OK); 891bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 901bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 914464d825c11349068f2917f9ebee86b721423f3cStephen Hines 924464d825c11349068f2917f9ebee86b721423f3cStephen Hinesstatic size_t getMinTimestampIdx(OMX_S64 *pNTimeStamp, bool *pIsTimeStampValid) { 93292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines OMX_S64 minTimeStamp = LLONG_MAX; 94292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines int idx = -1; 95292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines for (size_t i = 0; i < MAX_TIME_STAMPS; i++) { 96d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines if (pIsTimeStampValid[i]) { 97292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines if (pNTimeStamp[i] < minTimeStamp) { 981bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines minTimeStamp = pNTimeStamp[i]; 99292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines idx = i; 100292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 1011bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 102292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 103292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return idx; 104292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 105292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 1061bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hinesstatic size_t GetCPUCoreCount() { 107292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines long cpuCoreCount = 1; 1081bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines#if defined(_SC_NPROCESSORS_ONLN) 109292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines cpuCoreCount = sysconf(_SC_NPROCESSORS_ONLN); 110292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines#else 111292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // _SC_NPROC_ONLN must be defined... 112292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines cpuCoreCount = sysconf(_SC_NPROC_ONLN); 113292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines#endif 1141bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines CHECK(cpuCoreCount >= 1); 115292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines ALOGV("Number of CPU cores: %ld", cpuCoreCount); 1161bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines return (size_t)cpuCoreCount; 117292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 1181bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1191bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hinesvoid SoftMPEG2::logVersion() { 120292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines ivd_ctl_getversioninfo_ip_t s_ctl_ip; 121e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ivd_ctl_getversioninfo_op_t s_ctl_op; 122292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines UWORD8 au1_buf[512]; 123292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines IV_API_CALL_STATUS_T status; 124292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 125e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL; 126292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_GETVERSION; 127292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_ctl_ip.u4_size = sizeof(ivd_ctl_getversioninfo_ip_t); 128292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_ctl_op.u4_size = sizeof(ivd_ctl_getversioninfo_op_t); 129e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines s_ctl_ip.pv_version_buffer = au1_buf; 130e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines s_ctl_ip.u4_version_buffer_size = sizeof(au1_buf); 131e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 132292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines status = ivdec_api_function(mCodecCtx, (void *)&s_ctl_ip, (void *)&s_ctl_op); 133292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 134292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines if (status != IV_SUCCESS) { 135292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines ALOGE("Error in getting version number: 0x%x", 136292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_ctl_op.u4_error_code); 137292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } else { 138292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines ALOGV("Ittiam decoder version number: %s", 139292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines (char *)s_ctl_ip.pv_version_buffer); 140e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 141e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return; 142292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 143c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 144292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesstatus_t SoftMPEG2::setParams(size_t stride) { 145292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines ivd_ctl_set_config_ip_t s_ctl_ip; 146292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines ivd_ctl_set_config_op_t s_ctl_op; 147292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines IV_API_CALL_STATUS_T status; 148292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_ctl_ip.u4_disp_wd = (UWORD32)stride; 149292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_ctl_ip.e_frm_skip_mode = IVD_SKIP_NONE; 150292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 151292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_ctl_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT; 152c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines s_ctl_ip.e_vid_dec_mode = IVD_DECODE_FRAME; 153292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL; 154c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS; 155292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_ctl_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t); 156292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_op_t); 157292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 158292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines ALOGV("Set the run-time (dynamic) parameters stride = %zu", stride); 159292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines status = ivdec_api_function(mCodecCtx, (void *)&s_ctl_ip, (void *)&s_ctl_op); 160292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 161292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines if (status != IV_SUCCESS) { 162c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines ALOGE("Error in setting the run-time parameters: 0x%x", 163c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines s_ctl_op.u4_error_code); 164c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 165c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines return UNKNOWN_ERROR; 166c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 167c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines return OK; 168c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines} 169c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 170c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hinesstatus_t SoftMPEG2::resetPlugin() { 171c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines mIsInFlush = false; 172d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines mReceivedEOS = false; 1734464d825c11349068f2917f9ebee86b721423f3cStephen Hines memset(mTimeStamps, 0, sizeof(mTimeStamps)); 1744464d825c11349068f2917f9ebee86b721423f3cStephen Hines memset(mTimeStampsValid, 0, sizeof(mTimeStampsValid)); 1754464d825c11349068f2917f9ebee86b721423f3cStephen Hines 1764464d825c11349068f2917f9ebee86b721423f3cStephen Hines /* Initialize both start and end times */ 1774464d825c11349068f2917f9ebee86b721423f3cStephen Hines gettimeofday(&mTimeStart, NULL); 178292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines gettimeofday(&mTimeEnd, NULL); 179292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 180292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return OK; 181292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 182292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 183292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesstatus_t SoftMPEG2::resetDecoder() { 1844464d825c11349068f2917f9ebee86b721423f3cStephen Hines ivd_ctl_reset_ip_t s_ctl_ip; 1854464d825c11349068f2917f9ebee86b721423f3cStephen Hines ivd_ctl_reset_op_t s_ctl_op; 1864464d825c11349068f2917f9ebee86b721423f3cStephen Hines IV_API_CALL_STATUS_T status; 187292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 188292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL; 189292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_RESET; 190292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_ctl_ip.u4_size = sizeof(ivd_ctl_reset_ip_t); 191292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_ctl_op.u4_size = sizeof(ivd_ctl_reset_op_t); 192292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 193292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines status = ivdec_api_function(mCodecCtx, (void *)&s_ctl_ip, (void *)&s_ctl_op); 194292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines if (IV_SUCCESS != status) { 195292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines ALOGE("Error in reset: 0x%x", s_ctl_op.u4_error_code); 196292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return UNKNOWN_ERROR; 197292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 198292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 199292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines /* Set the run-time (dynamic) parameters */ 200292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines setParams(outputBufferWidth()); 201292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 202d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines /* Set number of cores/threads to be used by the codec */ 203292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines setNumCores(); 204292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 205292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return OK; 206292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 207292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 2084464d825c11349068f2917f9ebee86b721423f3cStephen Hinesstatus_t SoftMPEG2::setNumCores() { 209292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines ivdext_ctl_set_num_cores_ip_t s_set_cores_ip; 210292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines ivdext_ctl_set_num_cores_op_t s_set_cores_op; 211292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines IV_API_CALL_STATUS_T status; 212292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_set_cores_ip.e_cmd = IVD_CMD_VIDEO_CTL; 213292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_set_cores_ip.e_sub_cmd = IVDEXT_CMD_CTL_SET_NUM_CORES; 214292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_set_cores_ip.u4_num_cores = MIN(mNumCores, CODEC_MAX_NUM_CORES); 215292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_set_cores_ip.u4_size = sizeof(ivdext_ctl_set_num_cores_ip_t); 216292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_set_cores_op.u4_size = sizeof(ivdext_ctl_set_num_cores_op_t); 217292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 218292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines status = ivdec_api_function(mCodecCtx, (void *)&s_set_cores_ip, (void *)&s_set_cores_op); 219292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines if (IV_SUCCESS != status) { 220292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines ALOGE("Error in setting number of cores: 0x%x", 221292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_set_cores_op.u4_error_code); 222292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return UNKNOWN_ERROR; 223292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 224292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return OK; 225292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 226292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 227292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesstatus_t SoftMPEG2::setFlushMode() { 228292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines IV_API_CALL_STATUS_T status; 229292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines ivd_ctl_flush_ip_t s_video_flush_ip; 230292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines ivd_ctl_flush_op_t s_video_flush_op; 231292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 232292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_video_flush_ip.e_cmd = IVD_CMD_VIDEO_CTL; 233292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_video_flush_ip.e_sub_cmd = IVD_CMD_CTL_FLUSH; 234292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_video_flush_ip.u4_size = sizeof(ivd_ctl_flush_ip_t); 235292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_video_flush_op.u4_size = sizeof(ivd_ctl_flush_op_t); 236292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 2374464d825c11349068f2917f9ebee86b721423f3cStephen Hines /* Set the decoder in Flush mode, subsequent decode() calls will flush */ 2384464d825c11349068f2917f9ebee86b721423f3cStephen Hines status = ivdec_api_function( 239292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mCodecCtx, (void *)&s_video_flush_ip, (void *)&s_video_flush_op); 240292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 241292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines if (status != IV_SUCCESS) { 242292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines ALOGE("Error in setting the decoder in flush mode: (%d) 0x%x", status, 243292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_video_flush_op.u4_error_code); 244292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return UNKNOWN_ERROR; 245292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 246292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 247292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mWaitForI = true; 248292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mIsInFlush = true; 249292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return OK; 250292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 2514464d825c11349068f2917f9ebee86b721423f3cStephen Hines 2524464d825c11349068f2917f9ebee86b721423f3cStephen Hinesstatus_t SoftMPEG2::initDecoder() { 2534464d825c11349068f2917f9ebee86b721423f3cStephen Hines IV_API_CALL_STATUS_T status; 254292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 255292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines UWORD32 u4_num_reorder_frames; 2564464d825c11349068f2917f9ebee86b721423f3cStephen Hines UWORD32 u4_num_ref_frames; 257292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines UWORD32 u4_share_disp_buf; 258292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 259292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mNumCores = GetCPUCoreCount(); 260292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mWaitForI = true; 2614464d825c11349068f2917f9ebee86b721423f3cStephen Hines 2624464d825c11349068f2917f9ebee86b721423f3cStephen Hines /* Initialize number of ref and reorder modes (for MPEG2) */ 2634464d825c11349068f2917f9ebee86b721423f3cStephen Hines u4_num_reorder_frames = 16; 2644464d825c11349068f2917f9ebee86b721423f3cStephen Hines u4_num_ref_frames = 16; 2654464d825c11349068f2917f9ebee86b721423f3cStephen Hines u4_share_disp_buf = 0; 2664464d825c11349068f2917f9ebee86b721423f3cStephen Hines 2674464d825c11349068f2917f9ebee86b721423f3cStephen Hines uint32_t displayStride = outputBufferWidth(); 2684464d825c11349068f2917f9ebee86b721423f3cStephen Hines uint32_t displayHeight = outputBufferHeight(); 2694464d825c11349068f2917f9ebee86b721423f3cStephen Hines uint32_t displaySizeY = displayStride * displayHeight; 2704464d825c11349068f2917f9ebee86b721423f3cStephen Hines 2714464d825c11349068f2917f9ebee86b721423f3cStephen Hines { 2724464d825c11349068f2917f9ebee86b721423f3cStephen Hines iv_num_mem_rec_ip_t s_num_mem_rec_ip; 2734464d825c11349068f2917f9ebee86b721423f3cStephen Hines iv_num_mem_rec_op_t s_num_mem_rec_op; 2744464d825c11349068f2917f9ebee86b721423f3cStephen Hines 275292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_num_mem_rec_ip.u4_size = sizeof(s_num_mem_rec_ip); 276292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_num_mem_rec_op.u4_size = sizeof(s_num_mem_rec_op); 277292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_num_mem_rec_ip.e_cmd = IV_CMD_GET_NUM_MEM_REC; 278292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 279292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines status = ivdec_api_function( 280292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mCodecCtx, (void *)&s_num_mem_rec_ip, (void *)&s_num_mem_rec_op); 281292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines if (IV_SUCCESS != status) { 282292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines ALOGE("Error in getting mem records: 0x%x", 283292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_num_mem_rec_op.u4_error_code); 284292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return UNKNOWN_ERROR; 285292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 286292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 287292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mNumMemRecords = s_num_mem_rec_op.u4_num_mem_rec; 288292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 289292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 290292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mMemRecords = (iv_mem_rec_t *)ivd_aligned_malloc( 291292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 128, mNumMemRecords * sizeof(iv_mem_rec_t)); 292292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines if (mMemRecords == NULL) { 293292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines ALOGE("Allocation failure"); 294292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return NO_MEMORY; 295292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 296292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 297292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines memset(mMemRecords, 0, mNumMemRecords * sizeof(iv_mem_rec_t)); 298292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 299292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines { 300292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines size_t i; 301292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines ivdext_fill_mem_rec_ip_t s_fill_mem_ip; 302292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines ivdext_fill_mem_rec_op_t s_fill_mem_op; 303292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines iv_mem_rec_t *ps_mem_rec; 304292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 305292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.u4_size = 306292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines sizeof(ivdext_fill_mem_rec_ip_t); 307292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 308292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_fill_mem_ip.u4_share_disp_buf = u4_share_disp_buf; 309292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_fill_mem_ip.e_output_format = mIvColorFormat; 310292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 311292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.e_cmd = IV_CMD_FILL_NUM_MEM_REC; 312292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location = mMemRecords; 313292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_wd = displayStride; 314292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_ht = displayHeight; 315292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_fill_mem_op.s_ivd_fill_mem_rec_op_t.u4_size = 316292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines sizeof(ivdext_fill_mem_rec_op_t); 317292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 318292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines ps_mem_rec = mMemRecords; 319292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines for (i = 0; i < mNumMemRecords; i++) { 320292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines ps_mem_rec[i].u4_size = sizeof(iv_mem_rec_t); 321292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 322292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 323292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines status = ivdec_api_function( 324292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mCodecCtx, (void *)&s_fill_mem_ip, (void *)&s_fill_mem_op); 325292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 326292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines if (IV_SUCCESS != status) { 327292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines ALOGE("Error in filling mem records: 0x%x", 328292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_fill_mem_op.s_ivd_fill_mem_rec_op_t.u4_error_code); 329292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return UNKNOWN_ERROR; 330292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 331292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mNumMemRecords = 332292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines s_fill_mem_op.s_ivd_fill_mem_rec_op_t.u4_num_mem_rec_filled; 333292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 334292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines ps_mem_rec = mMemRecords; 335292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 336292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines for (i = 0; i < mNumMemRecords; i++) { 337292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines ps_mem_rec->pv_base = ivd_aligned_malloc( 338292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines ps_mem_rec->u4_mem_alignment, ps_mem_rec->u4_mem_size); 339292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines if (ps_mem_rec->pv_base == NULL) { 340292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines ALOGE("Allocation failure for memory record #%zu of size %u", 341292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines i, ps_mem_rec->u4_mem_size); 342292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines status = IV_FAIL; 343292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return NO_MEMORY; 344292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 345292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 346292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines ps_mem_rec++; 347292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 348292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 349292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 350292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines /* Initialize the decoder */ 351f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines { 352f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ivdext_init_ip_t s_init_ip; 353f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ivdext_init_op_t s_init_op; 354f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 355f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines void *dec_fxns = (void *)ivdec_api_function; 356f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 357f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines s_init_ip.s_ivd_init_ip_t.u4_size = sizeof(ivdext_init_ip_t); 358f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines s_init_ip.s_ivd_init_ip_t.e_cmd = (IVD_API_COMMAND_TYPE_T)IV_CMD_INIT; 359f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines s_init_ip.s_ivd_init_ip_t.pv_mem_rec_location = mMemRecords; 360f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines s_init_ip.s_ivd_init_ip_t.u4_frm_max_wd = displayStride; 361f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines s_init_ip.s_ivd_init_ip_t.u4_frm_max_ht = displayHeight; 362f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 363f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines s_init_ip.u4_share_disp_buf = u4_share_disp_buf; 364f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 365f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines s_init_op.s_ivd_init_op_t.u4_size = sizeof(s_init_op); 366f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 367f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines s_init_ip.s_ivd_init_ip_t.u4_num_mem_rec = mNumMemRecords; 368f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines s_init_ip.s_ivd_init_ip_t.e_output_format = mIvColorFormat; 369f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 370f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines mCodecCtx = (iv_obj_t *)mMemRecords[0].pv_base; 371f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines mCodecCtx->pv_fxns = dec_fxns; 372f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines mCodecCtx->u4_size = sizeof(iv_obj_t); 373f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 374f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines status = ivdec_api_function(mCodecCtx, (void *)&s_init_ip, (void *)&s_init_op); 375f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (status != IV_SUCCESS) { 376f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ALOGE("Error in init: 0x%x", 377f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines s_init_op.s_ivd_init_op_t.u4_error_code); 378f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return UNKNOWN_ERROR; 379f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 380be27482cdeaf08576bc39b72a15d35d13014a636Logan } 381be27482cdeaf08576bc39b72a15d35d13014a636Logan 382f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines /* Reset the plugin state */ 383f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines resetPlugin(); 384f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 385f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines /* Set the run time (dynamic) parameters */ 386be27482cdeaf08576bc39b72a15d35d13014a636Logan setParams(displayStride); 387f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 388f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines /* Set number of cores/threads to be used by the codec */ 389be27482cdeaf08576bc39b72a15d35d13014a636Logan setNumCores(); 390be27482cdeaf08576bc39b72a15d35d13014a636Logan 391be27482cdeaf08576bc39b72a15d35d13014a636Logan /* Get codec version */ 392f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines logVersion(); 393f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 394f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines /* Allocate internal picture buffer */ 395f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines uint32_t bufferSize = displaySizeY * 3 / 2; 396f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines mFlushOutBuffer = (uint8_t *)ivd_aligned_malloc(128, bufferSize); 397f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (NULL == mFlushOutBuffer) { 398f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ALOGE("Could not allocate flushOutputBuffer of size %u", bufferSize); 399f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return NO_MEMORY; 40003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 401f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 402f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines mInitNeeded = false; 403f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines mFlushNeeded = false; 404f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return OK; 405f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines} 406f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 407be27482cdeaf08576bc39b72a15d35d13014a636Loganstatus_t SoftMPEG2::deInitDecoder() { 408f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines size_t i; 409f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 410f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (mMemRecords) { 411f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines iv_mem_rec_t *ps_mem_rec; 412f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 413f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ps_mem_rec = mMemRecords; 41403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines for (i = 0; i < mNumMemRecords; i++) { 41503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines if (ps_mem_rec->pv_base) { 41603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ivd_aligned_free(ps_mem_rec->pv_base); 41703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 41803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ps_mem_rec++; 41903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 4209d2c0fa6490e09b3ff5603796bce42d97788e5c8Stephen Hines ivd_aligned_free(mMemRecords); 42103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines mMemRecords = NULL; 42203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 423f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 424f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (mFlushOutBuffer) { 425f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ivd_aligned_free(mFlushOutBuffer); 426f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines mFlushOutBuffer = NULL; 427f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 428f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 429f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines mInitNeeded = true; 430f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines mChangingResolution = false; 431f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 432f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return OK; 433f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines} 434f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 435f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesstatus_t SoftMPEG2::reInitDecoder() { 436f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines status_t ret; 437f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 438f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines deInitDecoder(); 439f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 44003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ret = initDecoder(); 44103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines if (OK != ret) { 44203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ALOGE("Create failure"); 44303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines deInitDecoder(); 44403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return NO_MEMORY; 44503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 44603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return OK; 44703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines} 44803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 44903981a308201b9123512297c8b9562a0f29bdf31Stephen Hinesvoid SoftMPEG2::onReset() { 45003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines SoftVideoDecoderOMXComponent::onReset(); 45103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 45203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines mWaitForI = true; 45303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 45403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines resetDecoder(); 45503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines resetPlugin(); 45603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines} 45703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 45803981a308201b9123512297c8b9562a0f29bdf31Stephen HinesOMX_ERRORTYPE SoftMPEG2::internalSetParameter(OMX_INDEXTYPE index, const OMX_PTR params) { 45903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines const uint32_t oldWidth = mWidth; 46003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines const uint32_t oldHeight = mHeight; 46103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines OMX_ERRORTYPE ret = SoftVideoDecoderOMXComponent::internalSetParameter(index, params); 46203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines if (mWidth != oldWidth || mHeight != oldHeight) { 46303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines reInitDecoder(); 46403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 46503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return ret; 46603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines} 46703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 46803981a308201b9123512297c8b9562a0f29bdf31Stephen Hinesbool SoftMPEG2::setDecodeArgs( 46903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ivd_video_decode_ip_t *ps_dec_ip, 47003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ivd_video_decode_op_t *ps_dec_op, 47103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines OMX_BUFFERHEADERTYPE *inHeader, 47203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines OMX_BUFFERHEADERTYPE *outHeader, 47303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines size_t timeStampIx) { 47403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines size_t sizeY = outputBufferWidth() * outputBufferHeight(); 475f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines size_t sizeUV; 47603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 47703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ps_dec_ip->u4_size = sizeof(ivd_video_decode_ip_t); 47803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ps_dec_op->u4_size = sizeof(ivd_video_decode_op_t); 47903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 48003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ps_dec_ip->e_cmd = IVD_CMD_VIDEO_DECODE; 48103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 48203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines /* When in flush and after EOS with zero byte input, 48303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines * inHeader is set to zero. Hence check for non-null */ 48403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines if (inHeader) { 48503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ps_dec_ip->u4_ts = timeStampIx; 48603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ps_dec_ip->pv_stream_buffer = inHeader->pBuffer 48703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines + inHeader->nOffset; 48803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ps_dec_ip->u4_num_Bytes = inHeader->nFilledLen; 48903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } else { 49003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ps_dec_ip->u4_ts = 0; 49103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ps_dec_ip->pv_stream_buffer = NULL; 49203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ps_dec_ip->u4_num_Bytes = 0; 49303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 494be27482cdeaf08576bc39b72a15d35d13014a636Logan 49503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines sizeUV = sizeY / 4; 49603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ps_dec_ip->s_out_buffer.u4_min_out_buf_size[0] = sizeY; 497be27482cdeaf08576bc39b72a15d35d13014a636Logan ps_dec_ip->s_out_buffer.u4_min_out_buf_size[1] = sizeUV; 498be27482cdeaf08576bc39b72a15d35d13014a636Logan ps_dec_ip->s_out_buffer.u4_min_out_buf_size[2] = sizeUV; 499be27482cdeaf08576bc39b72a15d35d13014a636Logan 50003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines uint8_t *pBuf; 50103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines if (outHeader) { 50203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines if (outHeader->nAllocLen < sizeY + (sizeUV * 2)) { 50303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines android_errorWriteLog(0x534e4554, "27833616"); 50403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return false; 50503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 50603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines pBuf = outHeader->pBuffer; 50703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } else { 50803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // mFlushOutBuffer always has the right size. 509be27482cdeaf08576bc39b72a15d35d13014a636Logan pBuf = mFlushOutBuffer; 510be27482cdeaf08576bc39b72a15d35d13014a636Logan } 51103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 51203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ps_dec_ip->s_out_buffer.pu1_bufs[0] = pBuf; 51303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ps_dec_ip->s_out_buffer.pu1_bufs[1] = pBuf + sizeY; 51403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ps_dec_ip->s_out_buffer.pu1_bufs[2] = pBuf + sizeY + sizeUV; 51503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ps_dec_ip->s_out_buffer.u4_num_bufs = 3; 51603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return true; 51703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines} 51803981a308201b9123512297c8b9562a0f29bdf31Stephen Hinesvoid SoftMPEG2::onPortFlushCompleted(OMX_U32 portIndex) { 51903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines /* Once the output buffers are flushed, ignore any buffers that are held in decoder */ 52003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines if (kOutputPortIndex == portIndex) { 52103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines setFlushMode(); 522be27482cdeaf08576bc39b72a15d35d13014a636Logan 523be27482cdeaf08576bc39b72a15d35d13014a636Logan while (true) { 52403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ivd_video_decode_ip_t s_dec_ip; 52503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ivd_video_decode_op_t s_dec_op; 52603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines IV_API_CALL_STATUS_T status; 52703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines size_t sizeY, sizeUV; 52803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 52903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines setDecodeArgs(&s_dec_ip, &s_dec_op, NULL, NULL, 0); 53003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 531be27482cdeaf08576bc39b72a15d35d13014a636Logan status = ivdec_api_function(mCodecCtx, (void *)&s_dec_ip, (void *)&s_dec_op); 532be27482cdeaf08576bc39b72a15d35d13014a636Logan if (0 == s_dec_op.u4_output_present) { 53303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines resetPlugin(); 53403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines break; 53503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 53603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 53703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 538f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines} 53903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 540f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesvoid SoftMPEG2::onQueueFilled(OMX_U32 portIndex) { 54103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines UNUSED(portIndex); 542f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 54303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines if (mOutputPortSettingsChange != NONE) { 54403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return; 54503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 546f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 547f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines List<BufferInfo *> &inQueue = getPortQueue(kInputPortIndex); 54803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines List<BufferInfo *> &outQueue = getPortQueue(kOutputPortIndex); 549f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 550be27482cdeaf08576bc39b72a15d35d13014a636Logan /* If input EOS is seen and decoder is not in flush mode, 551be27482cdeaf08576bc39b72a15d35d13014a636Logan * set the decoder in flush mode. 552f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines * There can be a case where EOS is sent along with last picture data 55303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines * In that case, only after decoding that input data, decoder has to be 554f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines * put in flush. This case is handled here */ 555f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 556f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (mReceivedEOS && !mIsInFlush) { 557f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines setFlushMode(); 558f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 559f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 560be27482cdeaf08576bc39b72a15d35d13014a636Logan while (!outQueue.empty()) { 561f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines BufferInfo *inInfo; 562f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines OMX_BUFFERHEADERTYPE *inHeader; 563be27482cdeaf08576bc39b72a15d35d13014a636Logan 564f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines BufferInfo *outInfo; 565f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines OMX_BUFFERHEADERTYPE *outHeader; 566f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines size_t timeStampIx; 56703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 56803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines inInfo = NULL; 56903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines inHeader = NULL; 57003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 57103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines if (!mIsInFlush) { 57203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines if (!inQueue.empty()) { 57303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines inInfo = *inQueue.begin(); 57403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines inHeader = inInfo->mHeader; 57503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } else { 57603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines break; 57703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 57803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 57903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 5806e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines outInfo = *outQueue.begin(); 58103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines outHeader = outInfo->mHeader; 58203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines outHeader->nFlags = 0; 58303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines outHeader->nTimeStamp = 0; 58403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines outHeader->nOffset = 0; 58503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 58603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines if (inHeader != NULL && (inHeader->nFlags & OMX_BUFFERFLAG_EOS)) { 58703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines mReceivedEOS = true; 5882bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (inHeader->nFilledLen == 0) { 589f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines inQueue.erase(inQueue.begin()); 590f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines inInfo->mOwnedByUs = false; 591f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines notifyEmptyBufferDone(inHeader); 592f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines inHeader = NULL; 5932bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines setFlushMode(); 594f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 595f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 596f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 597f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // When there is an init required and the decoder is not in flush mode, 598f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // update output port's definition and reinitialize decoder. 599f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (mInitNeeded && !mIsInFlush) { 600f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines bool portWillReset = false; 601f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines handlePortSettingsChange(&portWillReset, mNewWidth, mNewHeight); 602f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 603f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines CHECK_EQ(reInitDecoder(), (status_t)OK); 604f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return; 605f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 606f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 607f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines /* Get a free slot in timestamp array to hold input timestamp */ 608f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines { 609f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines size_t i; 610f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines timeStampIx = 0; 611f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines for (i = 0; i < MAX_TIME_STAMPS; i++) { 612f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (!mTimeStampsValid[i]) { 613f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines timeStampIx = i; 6142bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines break; 615f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 616f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 617f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (inHeader != NULL) { 618f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines mTimeStampsValid[timeStampIx] = true; 619f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines mTimeStamps[timeStampIx] = inHeader->nTimeStamp; 620f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 621f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 622f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 623f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines { 624f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ivd_video_decode_ip_t s_dec_ip; 625f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ivd_video_decode_op_t s_dec_op; 626f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines WORD32 timeDelay, timeTaken; 627f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines size_t sizeY, sizeUV; 628f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 629f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (!setDecodeArgs(&s_dec_ip, &s_dec_op, inHeader, outHeader, timeStampIx)) { 630f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ALOGE("Decoder arg setup failed"); 631f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); 632f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return; 6339be9360d8e02b52ed669afbd69f9becb575c3f0dAlex Sakhartchouk } 6349be9360d8e02b52ed669afbd69f9becb575c3f0dAlex Sakhartchouk // If input dump is enabled, then write to file 635f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DUMP_TO_FILE(mInFile, s_dec_ip.pv_stream_buffer, s_dec_ip.u4_num_Bytes); 6362bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 637f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (s_dec_ip.u4_num_Bytes > 0) { 638f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines char *ptr = (char *)s_dec_ip.pv_stream_buffer; 639f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 6402bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 6412bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines GETTIME(&mTimeStart, NULL); 6422bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines /* Compute time elapsed between end of previous decode() 643f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines * to start of current decode() */ 644f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines TIME_DIFF(mTimeEnd, mTimeStart, timeDelay); 645f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 646f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines IV_API_CALL_STATUS_T status; 647f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines status = ivdec_api_function(mCodecCtx, (void *)&s_dec_ip, (void *)&s_dec_op); 648f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 649f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines bool unsupportedDimensions = (IMPEG2D_UNSUPPORTED_DIMENSIONS == s_dec_op.u4_error_code); 650f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines bool resChanged = (IVD_RES_CHANGED == (s_dec_op.u4_error_code & 0xFF)); 651f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 652f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines GETTIME(&mTimeEnd, NULL); 653f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines /* Compute time taken for decode() */ 654f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines TIME_DIFF(mTimeStart, mTimeEnd, timeTaken); 655f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 656f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ALOGV("timeTaken=%6d delay=%6d numBytes=%6d", timeTaken, timeDelay, 657f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines s_dec_op.u4_num_bytes_consumed); 658f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (s_dec_op.u4_frame_decoded_flag && !mFlushNeeded) { 659f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines mFlushNeeded = true; 660f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 661f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 662f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if ((inHeader != NULL) && (1 != s_dec_op.u4_frame_decoded_flag)) { 663f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines /* If the input did not contain picture data, then ignore 664f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines * the associated timestamp */ 665f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines mTimeStampsValid[timeStampIx] = false; 666f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 667f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 668f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // This is needed to handle CTS DecoderTest testCodecResetsMPEG2WithoutSurface, 669be27482cdeaf08576bc39b72a15d35d13014a636Logan // which is not sending SPS/PPS after port reconfiguration and flush to the codec. 670f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (unsupportedDimensions && !mFlushNeeded) { 671f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines bool portWillReset = false; 672f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines handlePortSettingsChange(&portWillReset, s_dec_op.u4_pic_wd, s_dec_op.u4_pic_ht); 673f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 674be27482cdeaf08576bc39b72a15d35d13014a636Logan CHECK_EQ(reInitDecoder(), (status_t)OK); 675be27482cdeaf08576bc39b72a15d35d13014a636Logan 676be27482cdeaf08576bc39b72a15d35d13014a636Logan if (setDecodeArgs(&s_dec_ip, &s_dec_op, inHeader, outHeader, timeStampIx)) { 677f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ivdec_api_function(mCodecCtx, (void *)&s_dec_ip, (void *)&s_dec_op); 678f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 679f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return; 680f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 681f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 682f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // If the decoder is in the changing resolution mode and there is no output present, 683f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // that means the switching is done and it's ready to reset the decoder and the plugin. 684f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (mChangingResolution && !s_dec_op.u4_output_present) { 685f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines mChangingResolution = false; 686f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines resetDecoder(); 687f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines resetPlugin(); 688f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines continue; 689f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 6902bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 691f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (unsupportedDimensions || resChanged) { 692f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines mChangingResolution = true; 693f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (mFlushNeeded) { 694f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines setFlushMode(); 695f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 696f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 697f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (unsupportedDimensions) { 698f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines mNewWidth = s_dec_op.u4_pic_wd; 699f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines mNewHeight = s_dec_op.u4_pic_ht; 700be27482cdeaf08576bc39b72a15d35d13014a636Logan mInitNeeded = true; 701f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 702f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines continue; 703f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 704f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 705be27482cdeaf08576bc39b72a15d35d13014a636Logan if ((0 < s_dec_op.u4_pic_wd) && (0 < s_dec_op.u4_pic_ht)) { 706be27482cdeaf08576bc39b72a15d35d13014a636Logan uint32_t width = s_dec_op.u4_pic_wd; 707be27482cdeaf08576bc39b72a15d35d13014a636Logan uint32_t height = s_dec_op.u4_pic_ht; 708f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines bool portWillReset = false; 709f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines handlePortSettingsChange(&portWillReset, width, height); 710f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 711f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (portWillReset) { 712f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines resetDecoder(); 713f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return; 714f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 715f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 716f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 717f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (s_dec_op.u4_output_present) { 718f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines size_t timeStampIdx; 719f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines outHeader->nFilledLen = (mWidth * mHeight * 3) / 2; 720f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 721f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines timeStampIdx = getMinTimestampIdx(mTimeStamps, mTimeStampsValid); 722f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines outHeader->nTimeStamp = mTimeStamps[timeStampIdx]; 723f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines mTimeStampsValid[timeStampIdx] = false; 724f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 725f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines /* mWaitForI waits for the first I picture. Once made FALSE, it 726f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines has to remain false till explicitly set to TRUE. */ 727f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines mWaitForI = mWaitForI && !(IV_I_FRAME == s_dec_op.e_pic_type); 728f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 729f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (mWaitForI) { 730f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines s_dec_op.u4_output_present = false; 731f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else { 7322bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines ALOGV("Output timestamp: %lld, res: %ux%u", 7332bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines (long long)outHeader->nTimeStamp, mWidth, mHeight); 7342bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines DUMP_TO_FILE(mOutFile, outHeader->pBuffer, outHeader->nFilledLen); 7352bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines outInfo->mOwnedByUs = false; 7362bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines outQueue.erase(outQueue.begin()); 7372bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines outInfo = NULL; 7382bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines notifyFillBufferDone(outHeader); 7396e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines outHeader = NULL; 7406e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines } 741c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } else { 742c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines /* If in flush mode and no output is returned by the codec, 743c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines * then come out of flush mode */ 744c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines mIsInFlush = false; 745c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 746c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines /* If EOS was recieved on input port and there is no output 747c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines * from the codec, then signal EOS on output port */ 748c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines if (mReceivedEOS) { 749be27482cdeaf08576bc39b72a15d35d13014a636Logan outHeader->nFilledLen = 0; 750c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines outHeader->nFlags |= OMX_BUFFERFLAG_EOS; 751c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 752be27482cdeaf08576bc39b72a15d35d13014a636Logan outInfo->mOwnedByUs = false; 753be27482cdeaf08576bc39b72a15d35d13014a636Logan outQueue.erase(outQueue.begin()); 754be27482cdeaf08576bc39b72a15d35d13014a636Logan outInfo = NULL; 755c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines notifyFillBufferDone(outHeader); 756c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines outHeader = NULL; 757c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines resetPlugin(); 758c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 759c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 760c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 761c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 762c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines // TODO: Handle more than one picture data 763c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines if (inHeader != NULL) { 764c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines inInfo->mOwnedByUs = false; 7652bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines inQueue.erase(inQueue.begin()); 766c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines inInfo = NULL; 767c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines notifyEmptyBufferDone(inHeader); 768be27482cdeaf08576bc39b72a15d35d13014a636Logan inHeader = NULL; 769be27482cdeaf08576bc39b72a15d35d13014a636Logan } 770c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 7712bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines} 772c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 773c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines} // namespace android 774c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 775c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hinesandroid::SoftOMXComponent *createSoftOMXComponent( 776c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines const char *name, const OMX_CALLBACKTYPE *callbacks, OMX_PTR appData, 777c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines OMX_COMPONENTTYPE **component) { 778c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines return new android::SoftMPEG2(name, callbacks, appData, component); 779be27482cdeaf08576bc39b72a15d35d13014a636Logan} 780c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines