182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON/*
282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* Copyright (c) 2009-2011 Intel Corporation.  All rights reserved.
382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON*
482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* Licensed under the Apache License, Version 2.0 (the "License");
582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* you may not use this file except in compliance with the License.
682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* You may obtain a copy of the License at
782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON*
882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* http://www.apache.org/licenses/LICENSE-2.0
982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON*
1082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* Unless required by applicable law or agreed to in writing, software
1182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* distributed under the License is distributed on an "AS IS" BASIS,
1282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* See the License for the specific language governing permissions and
1482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* limitations under the License.
1582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON*/
1682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
1782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON//#define LOG_NDEBUG 0
1882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#define LOG_TAG "PVSoftMPEG4Encoder"
1982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include <wrs_omxil_core/log.h>
2082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
2182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include "mp4enc_api.h"
2282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include "OMX_Video.h"
2382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
2482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include <media/stagefright/foundation/ADebug.h>
2582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include <media/stagefright/MediaDefs.h>
2682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include <media/stagefright/MediaErrors.h>
2782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include <media/stagefright/MetaData.h>
2882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include <media/stagefright/Utils.h>
2982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
3082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include <ui/GraphicBufferMapper.h>
3182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include <ui/Rect.h>
3282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
3382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include "PVSoftMPEG4Encoder.h"
3482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include "VideoEncoderLog.h"
3582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
3682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#define ALIGN(x, align)                  (((x) + (align) - 1) & (~((align) - 1)))
3782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
3882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONinline static void ConvertYUV420SemiPlanarToYUV420Planar(
3982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        uint8_t *inyuv, uint8_t* outyuv,
4082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        int32_t width, int32_t height) {
4182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
4282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int32_t outYsize = width * height;
4382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint32_t *outy =  (uint32_t *) outyuv;
4482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint16_t *outcb = (uint16_t *) (outyuv + outYsize);
4582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint16_t *outcr = (uint16_t *) (outyuv + outYsize + (outYsize >> 2));
4682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
4782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    /* Y copying */
4882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    memcpy(outy, inyuv, outYsize);
4982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
5082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    /* U & V copying */
5182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint32_t *inyuv_4 = (uint32_t *) (inyuv + outYsize);
5282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    for (int32_t i = height >> 1; i > 0; --i) {
5382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        for (int32_t j = width >> 2; j > 0; --j) {
5482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            uint32_t temp = *inyuv_4++;
5582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            uint32_t tempU = temp & 0xFF;
5682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            tempU = tempU | ((temp >> 8) & 0xFF00);
5782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
5882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            uint32_t tempV = (temp >> 8) & 0xFF;
5982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            tempV = tempV | ((temp >> 16) & 0xFF00);
6082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
6182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // Flip U and V
6282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            *outcb++ = tempU;
6382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            *outcr++ = tempV;
6482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
6582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
6682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
6782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
6882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONinline static void trimBuffer(uint8_t *dataIn, uint8_t *dataOut,
6982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        int32_t width, int32_t height,
7082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        int32_t alignedHeight, int32_t stride) {
7182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int32_t h;
7282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint8_t *y_start, *uv_start, *_y_start, *_uv_start;
7382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    y_start = dataOut;
7482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uv_start = dataOut + width * height;
7582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    _y_start = dataIn;
7682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    _uv_start = dataIn + stride * alignedHeight;
7782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
7882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    for (h = 0; h < height; h++)
7982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        memcpy(y_start + h * width, _y_start + h * stride, width);
8082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    for (h = 0; h < height / 2; h++)
8182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        memcpy(uv_start + h * width,
8282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                _uv_start + h * stride, width);
8382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
8482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
8582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONPVSoftMPEG4Encoder::PVSoftMPEG4Encoder(const char *name)
8682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    :  mEncodeMode(COMBINE_MODE_WITH_ERR_RES),
8782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mVideoWidth(176),
8882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mVideoHeight(144),
8982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mVideoFrameRate(30),
9082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mVideoBitRate(192000),
9182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mVideoColorFormat(OMX_COLOR_FormatYUV420SemiPlanar),
9282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mStoreMetaDataInBuffers(false),
9382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mIDRFrameRefreshIntervalInSec(1),
9482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mNumInputFrames(-1),
9582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mStarted(false),
9682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mSawInputEOS(false),
9782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mSignalledError(false),
9882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mHandle(new tagvideoEncControls),
9982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mEncParams(new tagvideoEncOptions),
10082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mInputFrameData(NULL)
10182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON{
10282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
10382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (!strcmp(name, "OMX.google.h263.encoder")) {
10482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mEncodeMode = H263_MODE;
10582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        LOG_I("construct h263 encoder");
10682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else {
10782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK(!strcmp(name, "OMX.google.mpeg4.encoder"));
10882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        LOG_I("construct mpeg4 encoder");
10982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
11082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
11182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    setDefaultParams();
11282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#if NO_BUFFER_SHARE
11382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVASurfaceMappingAction |= MAPACT_COPY;
11482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#endif
11582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
11682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    LOG_I("Construct PVSoftMPEG4Encoder");
11782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
11882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
11982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
12082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONPVSoftMPEG4Encoder::~PVSoftMPEG4Encoder() {
12182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    LOG_I("Destruct PVSoftMPEG4Encoder");
12282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    releaseEncoder();
12382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
12482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
12582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
12682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONvoid PVSoftMPEG4Encoder::setDefaultParams() {
12782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
12882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // Set default value for input parameters
12982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mComParams.profile = VAProfileH264Baseline;
13082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mComParams.level = 41;
13182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mComParams.rawFormat = RAW_FORMAT_NV12;
13282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mComParams.frameRate.frameRateNum = 30;
13382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mComParams.frameRate.frameRateDenom = 1;
13482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mComParams.resolution.width = 0;
13582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mComParams.resolution.height = 0;
13682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mComParams.intraPeriod = 30;
13782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mComParams.rcMode = RATE_CONTROL_NONE;
13882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mComParams.rcParams.initQP = 15;
13982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mComParams.rcParams.minQP = 0;
14082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mComParams.rcParams.bitRate = 640000;
14182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mComParams.rcParams.targetPercentage= 0;
14282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mComParams.rcParams.windowSize = 0;
14382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mComParams.rcParams.disableFrameSkip = 0;
14482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mComParams.rcParams.disableBitsStuffing = 1;
14582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mComParams.cyclicFrameInterval = 30;
14682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mComParams.refreshType = VIDEO_ENC_NONIR;
14782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mComParams.airParams.airMBs = 0;
14882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mComParams.airParams.airThreshold = 0;
14982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mComParams.airParams.airAuto = 1;
15082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mComParams.disableDeblocking = 2;
15182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mComParams.syncEncMode = false;
15282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mComParams.codedBufNum = 2;
15382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
15482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
15582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
15682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONEncode_Status PVSoftMPEG4Encoder::initEncParams() {
15782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK(mHandle != NULL);
15882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    memset(mHandle, 0, sizeof(tagvideoEncControls));
15982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
16082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK(mEncParams != NULL);
16182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    memset(mEncParams, 0, sizeof(tagvideoEncOptions));
16282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (!PVGetDefaultEncOption(mEncParams, 0)) {
16382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        LOG_E("Failed to get default encoding parameters");
16482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return ENCODE_FAIL;
16582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
16682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mEncParams->encMode = mEncodeMode;
16782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mEncParams->encWidth[0] = mVideoWidth;
16882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mEncParams->encHeight[0] = mVideoHeight;
16982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mEncParams->encFrameRate[0] = mVideoFrameRate;
17082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mEncParams->rcType = VBR_1;
17182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mEncParams->vbvDelay = 5.0f;
17282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
17382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // FIXME:
17482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // Add more profile and level support for MPEG4 encoder
17582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mEncParams->profile_level = CORE_PROFILE_LEVEL2;
17682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mEncParams->packetSize = 32;
17782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mEncParams->rvlcEnable = PV_OFF;
17882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mEncParams->numLayers = 1;
17982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mEncParams->timeIncRes = 1000;
18082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mEncParams->tickPerSrc = mEncParams->timeIncRes / mVideoFrameRate;
18182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
18282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mEncParams->bitRate[0] = mVideoBitRate <= 2000000 ? mVideoBitRate : 2000000;
18382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mEncParams->iQuant[0] = 15;
18482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mEncParams->pQuant[0] = 12;
18582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mEncParams->quantType[0] = 0;
18682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mEncParams->noFrameSkipped = PV_OFF;
18782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
18882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mTrimedInputData =
18982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        (uint8_t *) malloc((mVideoWidth * mVideoHeight * 3 ) >> 1);
19082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK(mTrimedInputData != NULL);
19182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
19282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mVideoColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
19382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // Color conversion is needed.
19482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK(mInputFrameData == NULL);
19582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mInputFrameData =
19682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            (uint8_t *) malloc((mVideoWidth * mVideoHeight * 3 ) >> 1);
19782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK(mInputFrameData != NULL);
19882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
19982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
20082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // PV's MPEG4 encoder requires the video dimension of multiple
20182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mVideoWidth % 16 != 0 || mVideoHeight % 16 != 0) {
20282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        LOG_E("Video frame size %dx%d must be a multiple of 16",
20382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVideoWidth, mVideoHeight);
20482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return ENCODE_INVALID_PARAMS;
20582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
20682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
20782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // Set IDR frame refresh interval
20882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mIDRFrameRefreshIntervalInSec < 0) {
20982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mEncParams->intraPeriod = -1;
21082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else if (mIDRFrameRefreshIntervalInSec == 0) {
21182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mEncParams->intraPeriod = 1;  // All I frames
21282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else {
21382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mEncParams->intraPeriod =
21482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            (mIDRFrameRefreshIntervalInSec * mVideoFrameRate);
21582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
21682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
21782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mEncParams->numIntraMB = 0;
21882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mEncParams->sceneDetect = PV_ON;
21982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mEncParams->searchRange = 16;
22082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mEncParams->mv8x8Enable = PV_OFF;
22182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mEncParams->gobHeaderInterval = 0;
22282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mEncParams->useACPred = PV_ON;
22382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mEncParams->intraDCVlcTh = 0;
22482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
22582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return ENCODE_SUCCESS;
22682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
22782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
22882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONEncode_Status PVSoftMPEG4Encoder::initEncoder() {
22982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    LOG_V("Begin\n");
23082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
23182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK(!mStarted);
23282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
23382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Encode_Status ret = ENCODE_SUCCESS;
23482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (ENCODE_SUCCESS != (ret = initEncParams())) {
23582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        LOG_E("Failed to initialized encoder params");
23682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSignalledError = true;
23782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return ret;
23882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
23982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
24082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (!PVInitVideoEncoder(mHandle, mEncParams)) {
24182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        LOG_E("Failed to initialize the encoder");
24282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSignalledError = true;
24382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return ENCODE_FAIL;
24482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
24582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
24682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mNumInputFrames = -1;  // 1st buffer for codec specific data
24782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mStarted = true;
24882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mCurTimestampUs = 0;
24982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mLastTimestampUs = 0;
25082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVolHeaderLength = 256;
25182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
25282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    LOG_V("End\n");
25382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
25482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return ENCODE_SUCCESS;
25582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
25682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
25782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONEncode_Status PVSoftMPEG4Encoder::releaseEncoder() {
25882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    LOG_V("Begin\n");
25982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
26082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (!mStarted) {
26182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return ENCODE_SUCCESS;
26282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
26382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
26482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    PVCleanUpVideoEncoder(mHandle);
26582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
26682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    delete mTrimedInputData;
26782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mTrimedInputData = NULL;
26882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
26982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    delete mInputFrameData;
27082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mInputFrameData = NULL;
27182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
27282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    delete mEncParams;
27382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mEncParams = NULL;
27482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
27582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    delete mHandle;
27682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mHandle = NULL;
27782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
27882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mStarted = false;
27982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
28082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    LOG_V("End\n");
28182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
28282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return ENCODE_SUCCESS;
28382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
28482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
28582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONEncode_Status PVSoftMPEG4Encoder::setParameters(
28682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        VideoParamConfigSet *videoEncParams)
28782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON{
28882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
28982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Encode_Status ret = ENCODE_SUCCESS;
29082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_NULL_RETURN_IFFAIL(videoEncParams);
29182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    LOG_I("Config type = %d\n", (int)videoEncParams->type);
29282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
29382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mStarted) {
29482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        LOG_E("Encoder has been initialized, should use setConfig to change configurations\n");
29582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return ENCODE_ALREADY_INIT;
29682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
29782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
29882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    switch (videoEncParams->type) {
29982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        case VideoParamsTypeCommon: {
30082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
30182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            VideoParamsCommon *paramsCommon =
30282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    reinterpret_cast <VideoParamsCommon *> (videoEncParams);
30382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (paramsCommon->size != sizeof (VideoParamsCommon)) {
30482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                return ENCODE_INVALID_PARAMS;
30582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
30682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if(paramsCommon->codedBufNum < 2)
30782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                paramsCommon->codedBufNum =2;
30882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mComParams = *paramsCommon;
30982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
31082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVideoWidth = mComParams.resolution.width;
31182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVideoHeight = mComParams.resolution.height;
31282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVideoFrameRate =  mComParams.frameRate.frameRateNum / \
31382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                               mComParams.frameRate.frameRateDenom;
31482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVideoBitRate = mComParams.rcParams.bitRate;
31582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVideoColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
31682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            break;
31782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
31882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
31982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        case VideoParamsTypeStoreMetaDataInBuffers: {
32082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            VideoParamsStoreMetaDataInBuffers *metadata =
32182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    reinterpret_cast <VideoParamsStoreMetaDataInBuffers *> (videoEncParams);
32282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
32382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (metadata->size != sizeof (VideoParamsStoreMetaDataInBuffers)) {
32482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                return ENCODE_INVALID_PARAMS;
32582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
32682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
32782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mStoreMetaDataInBuffers = metadata->isEnabled;
32882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
32982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            break;
33082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
33182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
33282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        default: {
33382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            LOG_I ("Wrong ParamType here\n");
33482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            break;
33582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
33682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
33782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
33882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return ret;
33982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
34082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
34182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONEncode_Status PVSoftMPEG4Encoder::getParameters(
34282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        VideoParamConfigSet *videoEncParams) {
34382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
34482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Encode_Status ret = ENCODE_SUCCESS;
34582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_NULL_RETURN_IFFAIL(videoEncParams);
34682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    LOG_I("Config type = %d\n", (int)videoEncParams->type);
34782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
34882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    switch (videoEncParams->type) {
34982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        case VideoParamsTypeCommon: {
35082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
35182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            VideoParamsCommon *paramsCommon =
35282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    reinterpret_cast <VideoParamsCommon *> (videoEncParams);
35382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
35482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (paramsCommon->size != sizeof (VideoParamsCommon)) {
35582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                return ENCODE_INVALID_PARAMS;
35682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
35782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            *paramsCommon = mComParams;
35882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            break;
35982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
36082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
36182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        case VideoParamsTypeStoreMetaDataInBuffers: {
36282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            VideoParamsStoreMetaDataInBuffers *metadata =
36382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    reinterpret_cast <VideoParamsStoreMetaDataInBuffers *> (videoEncParams);
36482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
36582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (metadata->size != sizeof (VideoParamsStoreMetaDataInBuffers)) {
36682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                return ENCODE_INVALID_PARAMS;
36782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
36882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
36982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            metadata->isEnabled = mStoreMetaDataInBuffers;
37082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
37182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            break;
37282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
37382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
37482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        default: {
37582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            LOG_I ("Wrong ParamType here\n");
37682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            break;
37782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
37882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
37982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
38082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return ret;
38182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
38282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
38382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONEncode_Status PVSoftMPEG4Encoder::encode(VideoEncRawBuffer *inBuffer, uint32_t timeout)
38482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON{
38582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    LOG_V("Begin\n");
38682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
38782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Encode_Status ret = ENCODE_SUCCESS;
38882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
38982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mCurTimestampUs <= inBuffer->timeStamp) {
39082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mLastTimestampUs = mCurTimestampUs;
39182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mCurTimestampUs = inBuffer->timeStamp;
39282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
39382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
39482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mNumInputFrames < 0) {
39582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (!PVGetVolHeader(mHandle, mVolHeader, &mVolHeaderLength, 0)) {
39682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            LOG_E("Failed to get VOL header");
39782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mSignalledError = true;
39882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return ENCODE_FAIL;
39982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
40082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        LOG_I("Output VOL header: %d bytes", mVolHeaderLength);
40182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mNumInputFrames++;
40282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        //return ENCODE_SUCCESS;
40382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
40482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
40582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mStoreMetaDataInBuffers) {
40682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        IntelMetadataBuffer imb;
40782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        int32_t type;
40882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        int32_t value;
40982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        uint8_t *img;
41082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        const android::Rect rect(mVideoWidth, mVideoHeight);
41182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        android::status_t res;
41282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ValueInfo vinfo;
41382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ValueInfo *pvinfo = &vinfo;
41482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK(IMB_SUCCESS == imb.UnSerialize(inBuffer->data, inBuffer->size));
41582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        imb.GetType((::IntelMetadataBufferType&)type);
41682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        imb.GetValue(value);
41782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        imb.GetValueInfo(pvinfo);
41882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if(pvinfo == NULL) {
41982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            res = android::GraphicBufferMapper::get().lock((buffer_handle_t)value,
42082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    GRALLOC_USAGE_SW_READ_MASK,
42182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    rect, (void**)&img);
42282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        } else {
42382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            img = (uint8_t*)value;
42482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
42582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (pvinfo != NULL)
42682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            trimBuffer(img, mTrimedInputData, pvinfo->width, pvinfo->height,
42782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                   pvinfo->height, pvinfo->lumaStride);
42882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        else {
42982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            //NV12 Y-TILED
43082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            trimBuffer(img, mTrimedInputData, mVideoWidth, mVideoHeight,
43182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    ALIGN(mVideoHeight, 32), ALIGN(mVideoWidth, 128));
43282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            android::GraphicBufferMapper::get().unlock((buffer_handle_t)value);
43382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
43482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else {
43582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        memcpy(mTrimedInputData, inBuffer->data,
43682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                (mVideoWidth * mVideoHeight * 3 ) >> 1);
43782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
43882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
43982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mVideoColorFormat != OMX_COLOR_FormatYUV420Planar) {
44082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ConvertYUV420SemiPlanarToYUV420Planar(
44182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mTrimedInputData, mInputFrameData, mVideoWidth, mVideoHeight);
44282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else {
44382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        memcpy(mTrimedInputData, mInputFrameData,
44482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                (mVideoWidth * mVideoHeight * 3 ) >> 1);
44582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
44682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
44782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    LOG_V("End\n");
44882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
44982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return ret;
45082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
45182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
45282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONEncode_Status PVSoftMPEG4Encoder::getOutput(VideoEncOutputBuffer *outBuffer, uint32_t timeout)
45382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON{
45482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    LOG_V("Begin\n");
45582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
45682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Encode_Status ret = ENCODE_SUCCESS;
45782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint8_t *outPtr = outBuffer->data;
45882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int32_t dataLength = outBuffer->bufferSize;
45982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    outBuffer->flag = 0;
46082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
46182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if ((mEncodeMode == COMBINE_MODE_WITH_ERR_RES) &&
46282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            (outBuffer->format == OUTPUT_CODEC_DATA)) {
46382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        memcpy(outPtr, mVolHeader, mVolHeaderLength);
46482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ++mNumInputFrames;
46582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        outBuffer->flag |= ENCODE_BUFFERFLAG_CODECCONFIG;
46682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        outBuffer->flag |= ENCODE_BUFFERFLAG_ENDOFFRAME;
46782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        outBuffer->flag |= ENCODE_BUFFERFLAG_SYNCFRAME;
46882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        outBuffer->dataSize = mVolHeaderLength;
46982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        outBuffer->remainingSize = 0;
47082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return ENCODE_SUCCESS;
47182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
47282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
47382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    outBuffer->timeStamp = mCurTimestampUs;
47482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    LOG_I("info.mTimeUs %lld\n", outBuffer->timeStamp);
47582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
47682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoEncFrameIO vin, vout;
47782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    memset(&vin, 0, sizeof(vin));
47882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    memset(&vout, 0, sizeof(vout));
47982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vin.height = ((mVideoHeight  + 15) >> 4) << 4;
48082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vin.pitch = ((mVideoWidth + 15) >> 4) << 4;
48182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vin.timestamp = (outBuffer->timeStamp + 500) / 1000;  // in ms
48282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vin.yChan = mInputFrameData;
48382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vin.uChan = vin.yChan + vin.height * vin.pitch;
48482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vin.vChan = vin.uChan + ((vin.height * vin.pitch) >> 2);
48582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
48682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    unsigned long modTimeMs = 0;
48782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int32_t nLayer = 0;
48882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    MP4HintTrack hintTrack;
48982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (!PVEncodeVideoFrame(mHandle, &vin, &vout,
49082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                &modTimeMs, outPtr, &dataLength, &nLayer) ||
49182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            !PVGetHintTrack(mHandle, &hintTrack)) {
49282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        LOG_E("Failed to encode frame or get hink track at frame %lld",
49382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mNumInputFrames);
49482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSignalledError = true;
49582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        hintTrack.CodeType = 0;
49682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ret = ENCODE_FAIL;
49782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
49882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    LOG_I("dataLength %d\n", dataLength);
49982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK(NULL == PVGetOverrunBuffer(mHandle));
50082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (hintTrack.CodeType == 0) {  // I-frame serves as sync frame
50182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        outBuffer->flag |= ENCODE_BUFFERFLAG_SYNCFRAME;
50282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
50382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
50482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ++mNumInputFrames;
50582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
50682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    outBuffer->flag |= ENCODE_BUFFERFLAG_ENDOFFRAME;
50782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    outBuffer->dataSize = dataLength;
50882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
50982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    LOG_V("End\n");
51082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
51182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return ret;
51282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
51382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
514