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