11700744ae0ce2fcf722816453ae0af2cd5646458James Dong/* 21700744ae0ce2fcf722816453ae0af2cd5646458James Dong * Copyright (C) 2012 The Android Open Source Project 31700744ae0ce2fcf722816453ae0af2cd5646458James Dong * 41700744ae0ce2fcf722816453ae0af2cd5646458James Dong * Licensed under the Apache License, Version 2.0 (the "License"); 51700744ae0ce2fcf722816453ae0af2cd5646458James Dong * you may not use this file except in compliance with the License. 61700744ae0ce2fcf722816453ae0af2cd5646458James Dong * You may obtain a copy of the License at 71700744ae0ce2fcf722816453ae0af2cd5646458James Dong * 81700744ae0ce2fcf722816453ae0af2cd5646458James Dong * http://www.apache.org/licenses/LICENSE-2.0 91700744ae0ce2fcf722816453ae0af2cd5646458James Dong * 101700744ae0ce2fcf722816453ae0af2cd5646458James Dong * Unless required by applicable law or agreed to in writing, software 111700744ae0ce2fcf722816453ae0af2cd5646458James Dong * distributed under the License is distributed on an "AS IS" BASIS, 121700744ae0ce2fcf722816453ae0af2cd5646458James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131700744ae0ce2fcf722816453ae0af2cd5646458James Dong * See the License for the specific language governing permissions and 141700744ae0ce2fcf722816453ae0af2cd5646458James Dong * limitations under the License. 151700744ae0ce2fcf722816453ae0af2cd5646458James Dong */ 161700744ae0ce2fcf722816453ae0af2cd5646458James Dong 171700744ae0ce2fcf722816453ae0af2cd5646458James Dong//#define LOG_NDEBUG 0 181700744ae0ce2fcf722816453ae0af2cd5646458James Dong#define LOG_TAG "SoftMPEG4Encoder" 191700744ae0ce2fcf722816453ae0af2cd5646458James Dong#include <utils/Log.h> 20a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar#include <utils/misc.h> 211700744ae0ce2fcf722816453ae0af2cd5646458James Dong 221700744ae0ce2fcf722816453ae0af2cd5646458James Dong#include "mp4enc_api.h" 231700744ae0ce2fcf722816453ae0af2cd5646458James Dong#include "OMX_Video.h" 241700744ae0ce2fcf722816453ae0af2cd5646458James Dong 25bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala#include <HardwareAPI.h> 26bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala#include <MetadataBufferType.h> 271700744ae0ce2fcf722816453ae0af2cd5646458James Dong#include <media/stagefright/foundation/ADebug.h> 28a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar#include <media/stagefright/foundation/AUtils.h> 291700744ae0ce2fcf722816453ae0af2cd5646458James Dong#include <media/stagefright/MediaDefs.h> 301700744ae0ce2fcf722816453ae0af2cd5646458James Dong#include <media/stagefright/MediaErrors.h> 311700744ae0ce2fcf722816453ae0af2cd5646458James Dong#include <media/stagefright/MetaData.h> 321700744ae0ce2fcf722816453ae0af2cd5646458James Dong#include <media/stagefright/Utils.h> 33bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala#include <ui/Rect.h> 34bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala#include <ui/GraphicBufferMapper.h> 351700744ae0ce2fcf722816453ae0af2cd5646458James Dong 361700744ae0ce2fcf722816453ae0af2cd5646458James Dong#include "SoftMPEG4Encoder.h" 371700744ae0ce2fcf722816453ae0af2cd5646458James Dong 38b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross#include <inttypes.h> 39b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross 401700744ae0ce2fcf722816453ae0af2cd5646458James Dongnamespace android { 411700744ae0ce2fcf722816453ae0af2cd5646458James Dong 421700744ae0ce2fcf722816453ae0af2cd5646458James Dongtemplate<class T> 431700744ae0ce2fcf722816453ae0af2cd5646458James Dongstatic void InitOMXParams(T *params) { 441700744ae0ce2fcf722816453ae0af2cd5646458James Dong params->nSize = sizeof(T); 451700744ae0ce2fcf722816453ae0af2cd5646458James Dong params->nVersion.s.nVersionMajor = 1; 461700744ae0ce2fcf722816453ae0af2cd5646458James Dong params->nVersion.s.nVersionMinor = 0; 471700744ae0ce2fcf722816453ae0af2cd5646458James Dong params->nVersion.s.nRevision = 0; 481700744ae0ce2fcf722816453ae0af2cd5646458James Dong params->nVersion.s.nStep = 0; 491700744ae0ce2fcf722816453ae0af2cd5646458James Dong} 501700744ae0ce2fcf722816453ae0af2cd5646458James Dong 51a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnarstatic const CodecProfileLevel kMPEG4ProfileLevels[] = { 52a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar { OMX_VIDEO_MPEG4ProfileCore, OMX_VIDEO_MPEG4Level2 }, 53a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar}; 54a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar 55a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnarstatic const CodecProfileLevel kH263ProfileLevels[] = { 56a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar { OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level45 }, 57a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar}; 58a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar 591700744ae0ce2fcf722816453ae0af2cd5646458James DongSoftMPEG4Encoder::SoftMPEG4Encoder( 601700744ae0ce2fcf722816453ae0af2cd5646458James Dong const char *name, 61a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar const char *componentRole, 62a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar OMX_VIDEO_CODINGTYPE codingType, 63a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar const char *mime, 64a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar const CodecProfileLevel *profileLevels, 65a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar size_t numProfileLevels, 661700744ae0ce2fcf722816453ae0af2cd5646458James Dong const OMX_CALLBACKTYPE *callbacks, 671700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_PTR appData, 681700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_COMPONENTTYPE **component) 69a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar : SoftVideoEncoderOMXComponent( 70a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar name, componentRole, codingType, 71a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar profileLevels, numProfileLevels, 72a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar 176 /* width */, 144 /* height */, 73a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar callbacks, appData, component), 741700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncodeMode(COMBINE_MODE_WITH_ERR_RES), 751700744ae0ce2fcf722816453ae0af2cd5646458James Dong mIDRFrameRefreshIntervalInSec(1), 761700744ae0ce2fcf722816453ae0af2cd5646458James Dong mNumInputFrames(-1), 771700744ae0ce2fcf722816453ae0af2cd5646458James Dong mStarted(false), 781700744ae0ce2fcf722816453ae0af2cd5646458James Dong mSawInputEOS(false), 791700744ae0ce2fcf722816453ae0af2cd5646458James Dong mSignalledError(false), 801700744ae0ce2fcf722816453ae0af2cd5646458James Dong mHandle(new tagvideoEncControls), 811700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams(new tagvideoEncOptions), 821700744ae0ce2fcf722816453ae0af2cd5646458James Dong mInputFrameData(NULL) { 831700744ae0ce2fcf722816453ae0af2cd5646458James Dong 84a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar if (codingType == OMX_VIDEO_CodingH263) { 851700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncodeMode = H263_MODE; 861700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 871700744ae0ce2fcf722816453ae0af2cd5646458James Dong 88a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar // 256 * 1024 is a magic number for PV's encoder, not sure why 89a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar const size_t kOutputBufferSize = 256 * 1024; 90a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar 91a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar initPorts(kNumBuffers, kNumBuffers, kOutputBufferSize, mime); 92a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar 931700744ae0ce2fcf722816453ae0af2cd5646458James Dong ALOGI("Construct SoftMPEG4Encoder"); 941700744ae0ce2fcf722816453ae0af2cd5646458James Dong} 951700744ae0ce2fcf722816453ae0af2cd5646458James Dong 961700744ae0ce2fcf722816453ae0af2cd5646458James DongSoftMPEG4Encoder::~SoftMPEG4Encoder() { 971700744ae0ce2fcf722816453ae0af2cd5646458James Dong ALOGV("Destruct SoftMPEG4Encoder"); 981700744ae0ce2fcf722816453ae0af2cd5646458James Dong releaseEncoder(); 991700744ae0ce2fcf722816453ae0af2cd5646458James Dong List<BufferInfo *> &outQueue = getPortQueue(1); 1001700744ae0ce2fcf722816453ae0af2cd5646458James Dong List<BufferInfo *> &inQueue = getPortQueue(0); 1011700744ae0ce2fcf722816453ae0af2cd5646458James Dong CHECK(outQueue.empty()); 1021700744ae0ce2fcf722816453ae0af2cd5646458James Dong CHECK(inQueue.empty()); 1031700744ae0ce2fcf722816453ae0af2cd5646458James Dong} 1041700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1051700744ae0ce2fcf722816453ae0af2cd5646458James DongOMX_ERRORTYPE SoftMPEG4Encoder::initEncParams() { 1061700744ae0ce2fcf722816453ae0af2cd5646458James Dong CHECK(mHandle != NULL); 1071700744ae0ce2fcf722816453ae0af2cd5646458James Dong memset(mHandle, 0, sizeof(tagvideoEncControls)); 1081700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1091700744ae0ce2fcf722816453ae0af2cd5646458James Dong CHECK(mEncParams != NULL); 1101700744ae0ce2fcf722816453ae0af2cd5646458James Dong memset(mEncParams, 0, sizeof(tagvideoEncOptions)); 1111700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (!PVGetDefaultEncOption(mEncParams, 0)) { 1121700744ae0ce2fcf722816453ae0af2cd5646458James Dong ALOGE("Failed to get default encoding parameters"); 1131700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 1141700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 1151700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->encMode = mEncodeMode; 116a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mEncParams->encWidth[0] = mWidth; 117a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mEncParams->encHeight[0] = mHeight; 118a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mEncParams->encFrameRate[0] = mFramerate >> 16; // mFramerate is in Q16 format 1191700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->rcType = VBR_1; 1201700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->vbvDelay = 5.0f; 1211700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1221700744ae0ce2fcf722816453ae0af2cd5646458James Dong // FIXME: 1231700744ae0ce2fcf722816453ae0af2cd5646458James Dong // Add more profile and level support for MPEG4 encoder 1241700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->profile_level = CORE_PROFILE_LEVEL2; 1251700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->packetSize = 32; 1261700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->rvlcEnable = PV_OFF; 1271700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->numLayers = 1; 1281700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->timeIncRes = 1000; 129a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mEncParams->tickPerSrc = ((int64_t)mEncParams->timeIncRes << 16) / mFramerate; 1301700744ae0ce2fcf722816453ae0af2cd5646458James Dong 131a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mEncParams->bitRate[0] = mBitrate; 1321700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->iQuant[0] = 15; 1331700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->pQuant[0] = 12; 1341700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->quantType[0] = 0; 1351700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->noFrameSkipped = PV_OFF; 1361700744ae0ce2fcf722816453ae0af2cd5646458James Dong 137a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar if (mColorFormat != OMX_COLOR_FormatYUV420Planar || mInputDataIsMeta) { 1381700744ae0ce2fcf722816453ae0af2cd5646458James Dong // Color conversion is needed. 1392edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar free(mInputFrameData); 1401700744ae0ce2fcf722816453ae0af2cd5646458James Dong mInputFrameData = 141a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar (uint8_t *) malloc((mWidth * mHeight * 3 ) >> 1); 1421700744ae0ce2fcf722816453ae0af2cd5646458James Dong CHECK(mInputFrameData != NULL); 1431700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 1441700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1451700744ae0ce2fcf722816453ae0af2cd5646458James Dong // PV's MPEG4 encoder requires the video dimension of multiple 146a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar if (mWidth % 16 != 0 || mHeight % 16 != 0) { 1471700744ae0ce2fcf722816453ae0af2cd5646458James Dong ALOGE("Video frame size %dx%d must be a multiple of 16", 148a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mWidth, mHeight); 1491700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorBadParameter; 1501700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 1511700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1521700744ae0ce2fcf722816453ae0af2cd5646458James Dong // Set IDR frame refresh interval 1531700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (mIDRFrameRefreshIntervalInSec < 0) { 1541700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->intraPeriod = -1; 1551700744ae0ce2fcf722816453ae0af2cd5646458James Dong } else if (mIDRFrameRefreshIntervalInSec == 0) { 1561700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->intraPeriod = 1; // All I frames 1571700744ae0ce2fcf722816453ae0af2cd5646458James Dong } else { 1581700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->intraPeriod = 159a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar (mIDRFrameRefreshIntervalInSec * mFramerate) >> 16; 1601700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 1611700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1621700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->numIntraMB = 0; 1631700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->sceneDetect = PV_ON; 1641700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->searchRange = 16; 1651700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->mv8x8Enable = PV_OFF; 1661700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->gobHeaderInterval = 0; 1671700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->useACPred = PV_ON; 1681700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->intraDCVlcTh = 0; 1691700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1701700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorNone; 1711700744ae0ce2fcf722816453ae0af2cd5646458James Dong} 1721700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1731700744ae0ce2fcf722816453ae0af2cd5646458James DongOMX_ERRORTYPE SoftMPEG4Encoder::initEncoder() { 1741700744ae0ce2fcf722816453ae0af2cd5646458James Dong CHECK(!mStarted); 1751700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1761700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_ERRORTYPE errType = OMX_ErrorNone; 1771700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (OMX_ErrorNone != (errType = initEncParams())) { 1781700744ae0ce2fcf722816453ae0af2cd5646458James Dong ALOGE("Failed to initialized encoder params"); 1791700744ae0ce2fcf722816453ae0af2cd5646458James Dong mSignalledError = true; 1801700744ae0ce2fcf722816453ae0af2cd5646458James Dong notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 1811700744ae0ce2fcf722816453ae0af2cd5646458James Dong return errType; 1821700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 1831700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1841700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (!PVInitVideoEncoder(mHandle, mEncParams)) { 1851700744ae0ce2fcf722816453ae0af2cd5646458James Dong ALOGE("Failed to initialize the encoder"); 1861700744ae0ce2fcf722816453ae0af2cd5646458James Dong mSignalledError = true; 1871700744ae0ce2fcf722816453ae0af2cd5646458James Dong notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 1881700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 1891700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 1901700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1911700744ae0ce2fcf722816453ae0af2cd5646458James Dong mNumInputFrames = -1; // 1st buffer for codec specific data 1921700744ae0ce2fcf722816453ae0af2cd5646458James Dong mStarted = true; 1931700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1941700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorNone; 1951700744ae0ce2fcf722816453ae0af2cd5646458James Dong} 1961700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1971700744ae0ce2fcf722816453ae0af2cd5646458James DongOMX_ERRORTYPE SoftMPEG4Encoder::releaseEncoder() { 1981700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (!mStarted) { 1991700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorNone; 2001700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 2011700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2021700744ae0ce2fcf722816453ae0af2cd5646458James Dong PVCleanUpVideoEncoder(mHandle); 2031700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2042edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar free(mInputFrameData); 2051700744ae0ce2fcf722816453ae0af2cd5646458James Dong mInputFrameData = NULL; 2061700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2071700744ae0ce2fcf722816453ae0af2cd5646458James Dong delete mEncParams; 2081700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams = NULL; 2091700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2101700744ae0ce2fcf722816453ae0af2cd5646458James Dong delete mHandle; 2111700744ae0ce2fcf722816453ae0af2cd5646458James Dong mHandle = NULL; 2121700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2131700744ae0ce2fcf722816453ae0af2cd5646458James Dong mStarted = false; 2141700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2151700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorNone; 2161700744ae0ce2fcf722816453ae0af2cd5646458James Dong} 2171700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2181700744ae0ce2fcf722816453ae0af2cd5646458James DongOMX_ERRORTYPE SoftMPEG4Encoder::internalGetParameter( 2191700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_INDEXTYPE index, OMX_PTR params) { 2201700744ae0ce2fcf722816453ae0af2cd5646458James Dong switch (index) { 2211700744ae0ce2fcf722816453ae0af2cd5646458James Dong case OMX_IndexParamVideoBitrate: 2221700744ae0ce2fcf722816453ae0af2cd5646458James Dong { 2231700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_VIDEO_PARAM_BITRATETYPE *bitRate = 2241700744ae0ce2fcf722816453ae0af2cd5646458James Dong (OMX_VIDEO_PARAM_BITRATETYPE *) params; 2251700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2261700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (bitRate->nPortIndex != 1) { 2271700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 2281700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 2291700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2301700744ae0ce2fcf722816453ae0af2cd5646458James Dong bitRate->eControlRate = OMX_Video_ControlRateVariable; 231a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar bitRate->nTargetBitrate = mBitrate; 2321700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorNone; 2331700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 2341700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2351700744ae0ce2fcf722816453ae0af2cd5646458James Dong case OMX_IndexParamVideoH263: 2361700744ae0ce2fcf722816453ae0af2cd5646458James Dong { 2371700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_VIDEO_PARAM_H263TYPE *h263type = 2381700744ae0ce2fcf722816453ae0af2cd5646458James Dong (OMX_VIDEO_PARAM_H263TYPE *)params; 2391700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2401700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (h263type->nPortIndex != 1) { 2411700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 2421700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 2431700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2441700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->nAllowedPictureTypes = 2451700744ae0ce2fcf722816453ae0af2cd5646458James Dong (OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP); 2461700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->eProfile = OMX_VIDEO_H263ProfileBaseline; 2471700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->eLevel = OMX_VIDEO_H263Level45; 2481700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->bPLUSPTYPEAllowed = OMX_FALSE; 2491700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->bForceRoundingTypeToZero = OMX_FALSE; 2501700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->nPictureHeaderRepetition = 0; 2511700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->nGOBHeaderInterval = 0; 2521700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2531700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorNone; 2541700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 2551700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2561700744ae0ce2fcf722816453ae0af2cd5646458James Dong case OMX_IndexParamVideoMpeg4: 2571700744ae0ce2fcf722816453ae0af2cd5646458James Dong { 2581700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_VIDEO_PARAM_MPEG4TYPE *mpeg4type = 2591700744ae0ce2fcf722816453ae0af2cd5646458James Dong (OMX_VIDEO_PARAM_MPEG4TYPE *)params; 2601700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2611700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (mpeg4type->nPortIndex != 1) { 2621700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 2631700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 2641700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2651700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->eProfile = OMX_VIDEO_MPEG4ProfileCore; 2661700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->eLevel = OMX_VIDEO_MPEG4Level2; 2671700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nAllowedPictureTypes = 2681700744ae0ce2fcf722816453ae0af2cd5646458James Dong (OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP); 2691700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nBFrames = 0; 2701700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nIDCVLCThreshold = 0; 2711700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->bACPred = OMX_TRUE; 2721700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nMaxPacketSize = 256; 2731700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nTimeIncRes = 1000; 2741700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nHeaderExtension = 0; 2751700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->bReversibleVLC = OMX_FALSE; 2761700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2771700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorNone; 2781700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 2791700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2801700744ae0ce2fcf722816453ae0af2cd5646458James Dong default: 281a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar return SoftVideoEncoderOMXComponent::internalGetParameter(index, params); 2821700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 2831700744ae0ce2fcf722816453ae0af2cd5646458James Dong} 2841700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2851700744ae0ce2fcf722816453ae0af2cd5646458James DongOMX_ERRORTYPE SoftMPEG4Encoder::internalSetParameter( 2861700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_INDEXTYPE index, const OMX_PTR params) { 287bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala int32_t indexFull = index; 288bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala 289bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala switch (indexFull) { 2901700744ae0ce2fcf722816453ae0af2cd5646458James Dong case OMX_IndexParamVideoBitrate: 2911700744ae0ce2fcf722816453ae0af2cd5646458James Dong { 2921700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_VIDEO_PARAM_BITRATETYPE *bitRate = 2931700744ae0ce2fcf722816453ae0af2cd5646458James Dong (OMX_VIDEO_PARAM_BITRATETYPE *) params; 2941700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2951700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (bitRate->nPortIndex != 1 || 2961700744ae0ce2fcf722816453ae0af2cd5646458James Dong bitRate->eControlRate != OMX_Video_ControlRateVariable) { 2971700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 2981700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 2991700744ae0ce2fcf722816453ae0af2cd5646458James Dong 300a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mBitrate = bitRate->nTargetBitrate; 3011700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorNone; 3021700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3031700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3041700744ae0ce2fcf722816453ae0af2cd5646458James Dong case OMX_IndexParamVideoH263: 3051700744ae0ce2fcf722816453ae0af2cd5646458James Dong { 3061700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_VIDEO_PARAM_H263TYPE *h263type = 3071700744ae0ce2fcf722816453ae0af2cd5646458James Dong (OMX_VIDEO_PARAM_H263TYPE *)params; 3081700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3091700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (h263type->nPortIndex != 1) { 3101700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 3111700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3121700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3131700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (h263type->eProfile != OMX_VIDEO_H263ProfileBaseline || 3141700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->eLevel != OMX_VIDEO_H263Level45 || 3151700744ae0ce2fcf722816453ae0af2cd5646458James Dong (h263type->nAllowedPictureTypes & OMX_VIDEO_PictureTypeB) || 3161700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->bPLUSPTYPEAllowed != OMX_FALSE || 3171700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->bForceRoundingTypeToZero != OMX_FALSE || 3181700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->nPictureHeaderRepetition != 0 || 3191700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->nGOBHeaderInterval != 0) { 3201700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 3211700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3221700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3231700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorNone; 3241700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3251700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3261700744ae0ce2fcf722816453ae0af2cd5646458James Dong case OMX_IndexParamVideoMpeg4: 3271700744ae0ce2fcf722816453ae0af2cd5646458James Dong { 3281700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_VIDEO_PARAM_MPEG4TYPE *mpeg4type = 3291700744ae0ce2fcf722816453ae0af2cd5646458James Dong (OMX_VIDEO_PARAM_MPEG4TYPE *)params; 3301700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3311700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (mpeg4type->nPortIndex != 1) { 3321700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 3331700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3341700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3351700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (mpeg4type->eProfile != OMX_VIDEO_MPEG4ProfileCore || 3361700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->eLevel != OMX_VIDEO_MPEG4Level2 || 3371700744ae0ce2fcf722816453ae0af2cd5646458James Dong (mpeg4type->nAllowedPictureTypes & OMX_VIDEO_PictureTypeB) || 3381700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nBFrames != 0 || 3391700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nIDCVLCThreshold != 0 || 3401700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->bACPred != OMX_TRUE || 3411700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nMaxPacketSize != 256 || 3421700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nTimeIncRes != 1000 || 3431700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nHeaderExtension != 0 || 3441700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->bReversibleVLC != OMX_FALSE) { 3451700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 3461700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3471700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3481700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorNone; 3491700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3501700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3511700744ae0ce2fcf722816453ae0af2cd5646458James Dong default: 352a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar return SoftVideoEncoderOMXComponent::internalSetParameter(index, params); 3531700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3541700744ae0ce2fcf722816453ae0af2cd5646458James Dong} 3551700744ae0ce2fcf722816453ae0af2cd5646458James Dong 35684333e0475bc911adc16417f4ca327c975cf6c36Andreas Hubervoid SoftMPEG4Encoder::onQueueFilled(OMX_U32 /* portIndex */) { 3571700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (mSignalledError || mSawInputEOS) { 3581700744ae0ce2fcf722816453ae0af2cd5646458James Dong return; 3591700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3601700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3611700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (!mStarted) { 3621700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (OMX_ErrorNone != initEncoder()) { 3631700744ae0ce2fcf722816453ae0af2cd5646458James Dong return; 3641700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3651700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3661700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3671700744ae0ce2fcf722816453ae0af2cd5646458James Dong List<BufferInfo *> &inQueue = getPortQueue(0); 3681700744ae0ce2fcf722816453ae0af2cd5646458James Dong List<BufferInfo *> &outQueue = getPortQueue(1); 3691700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3701700744ae0ce2fcf722816453ae0af2cd5646458James Dong while (!mSawInputEOS && !inQueue.empty() && !outQueue.empty()) { 3711700744ae0ce2fcf722816453ae0af2cd5646458James Dong BufferInfo *inInfo = *inQueue.begin(); 3721700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader; 3731700744ae0ce2fcf722816453ae0af2cd5646458James Dong BufferInfo *outInfo = *outQueue.begin(); 3741700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; 3751700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3761700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nTimeStamp = 0; 3771700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nFlags = 0; 3781700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nOffset = 0; 3791700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nFilledLen = 0; 3801700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nOffset = 0; 3811700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3821700744ae0ce2fcf722816453ae0af2cd5646458James Dong uint8_t *outPtr = (uint8_t *) outHeader->pBuffer; 3831700744ae0ce2fcf722816453ae0af2cd5646458James Dong int32_t dataLength = outHeader->nAllocLen; 3841700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3851700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (mNumInputFrames < 0) { 3861700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (!PVGetVolHeader(mHandle, outPtr, &dataLength, 0)) { 3871700744ae0ce2fcf722816453ae0af2cd5646458James Dong ALOGE("Failed to get VOL header"); 3881700744ae0ce2fcf722816453ae0af2cd5646458James Dong mSignalledError = true; 3891700744ae0ce2fcf722816453ae0af2cd5646458James Dong notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 3901700744ae0ce2fcf722816453ae0af2cd5646458James Dong return; 3911700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3921700744ae0ce2fcf722816453ae0af2cd5646458James Dong ALOGV("Output VOL header: %d bytes", dataLength); 3931700744ae0ce2fcf722816453ae0af2cd5646458James Dong ++mNumInputFrames; 3941700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nFlags |= OMX_BUFFERFLAG_CODECCONFIG; 3951700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nFilledLen = dataLength; 3961700744ae0ce2fcf722816453ae0af2cd5646458James Dong outQueue.erase(outQueue.begin()); 3971700744ae0ce2fcf722816453ae0af2cd5646458James Dong outInfo->mOwnedByUs = false; 3981700744ae0ce2fcf722816453ae0af2cd5646458James Dong notifyFillBufferDone(outHeader); 3991700744ae0ce2fcf722816453ae0af2cd5646458James Dong return; 4001700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 4011700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4021700744ae0ce2fcf722816453ae0af2cd5646458James Dong // Save the input buffer info so that it can be 4031700744ae0ce2fcf722816453ae0af2cd5646458James Dong // passed to an output buffer 4041700744ae0ce2fcf722816453ae0af2cd5646458James Dong InputBufferInfo info; 4051700744ae0ce2fcf722816453ae0af2cd5646458James Dong info.mTimeUs = inHeader->nTimeStamp; 4061700744ae0ce2fcf722816453ae0af2cd5646458James Dong info.mFlags = inHeader->nFlags; 4071700744ae0ce2fcf722816453ae0af2cd5646458James Dong mInputBufferInfoVec.push(info); 4081700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4091700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) { 4101700744ae0ce2fcf722816453ae0af2cd5646458James Dong mSawInputEOS = true; 4111700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 4121700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4131700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (inHeader->nFilledLen > 0) { 4142edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar const uint8_t *inputData = NULL; 415a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar if (mInputDataIsMeta) { 416bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala if (inHeader->nFilledLen != 8) { 417bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala ALOGE("MetaData buffer is wrong size! " 41866fe2e9ee30bcb4161bc487ec63d2ae4a05f4051Glenn Kasten "(got %u bytes, expected 8)", inHeader->nFilledLen); 419bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala mSignalledError = true; 420bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 421bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala return; 422bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala } 423bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala inputData = 4242edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar extractGraphicBuffer( 425a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mInputFrameData, (mWidth * mHeight * 3) >> 1, 4262edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar inHeader->pBuffer + inHeader->nOffset, inHeader->nFilledLen, 427a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mWidth, mHeight); 428bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala if (inputData == NULL) { 429bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala ALOGE("Unable to extract gralloc buffer in metadata mode"); 430bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala mSignalledError = true; 431bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 432bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala return; 433bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala } 434bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala } else { 4352edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar inputData = (const uint8_t *)inHeader->pBuffer + inHeader->nOffset; 436a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar if (mColorFormat != OMX_COLOR_FormatYUV420Planar) { 4372edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar ConvertYUV420SemiPlanarToYUV420Planar( 438a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar inputData, mInputFrameData, mWidth, mHeight); 4392edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar inputData = mInputFrameData; 4402edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar } 441bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala } 442bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala 4431700744ae0ce2fcf722816453ae0af2cd5646458James Dong CHECK(inputData != NULL); 4441700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4451700744ae0ce2fcf722816453ae0af2cd5646458James Dong VideoEncFrameIO vin, vout; 4461700744ae0ce2fcf722816453ae0af2cd5646458James Dong memset(&vin, 0, sizeof(vin)); 4471700744ae0ce2fcf722816453ae0af2cd5646458James Dong memset(&vout, 0, sizeof(vout)); 448a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar vin.height = align(mHeight, 16); 449a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar vin.pitch = align(mWidth, 16); 4501700744ae0ce2fcf722816453ae0af2cd5646458James Dong vin.timestamp = (inHeader->nTimeStamp + 500) / 1000; // in ms 4512edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar vin.yChan = (uint8_t *)inputData; 4521700744ae0ce2fcf722816453ae0af2cd5646458James Dong vin.uChan = vin.yChan + vin.height * vin.pitch; 4531700744ae0ce2fcf722816453ae0af2cd5646458James Dong vin.vChan = vin.uChan + ((vin.height * vin.pitch) >> 2); 4541700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4552426d11f795a99de85999b3ff0a26cc070a99a59Ashok Bhat ULong modTimeMs = 0; 4561700744ae0ce2fcf722816453ae0af2cd5646458James Dong int32_t nLayer = 0; 4571700744ae0ce2fcf722816453ae0af2cd5646458James Dong MP4HintTrack hintTrack; 4581700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (!PVEncodeVideoFrame(mHandle, &vin, &vout, 4591700744ae0ce2fcf722816453ae0af2cd5646458James Dong &modTimeMs, outPtr, &dataLength, &nLayer) || 4601700744ae0ce2fcf722816453ae0af2cd5646458James Dong !PVGetHintTrack(mHandle, &hintTrack)) { 461b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross ALOGE("Failed to encode frame or get hink track at frame %" PRId64, 4621700744ae0ce2fcf722816453ae0af2cd5646458James Dong mNumInputFrames); 4631700744ae0ce2fcf722816453ae0af2cd5646458James Dong mSignalledError = true; 4641700744ae0ce2fcf722816453ae0af2cd5646458James Dong notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 4651700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 4661700744ae0ce2fcf722816453ae0af2cd5646458James Dong CHECK(NULL == PVGetOverrunBuffer(mHandle)); 4671700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (hintTrack.CodeType == 0) { // I-frame serves as sync frame 4681700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; 4691700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 4701700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4711700744ae0ce2fcf722816453ae0af2cd5646458James Dong ++mNumInputFrames; 4721700744ae0ce2fcf722816453ae0af2cd5646458James Dong } else { 4731700744ae0ce2fcf722816453ae0af2cd5646458James Dong dataLength = 0; 4741700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 4751700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4761700744ae0ce2fcf722816453ae0af2cd5646458James Dong inQueue.erase(inQueue.begin()); 4771700744ae0ce2fcf722816453ae0af2cd5646458James Dong inInfo->mOwnedByUs = false; 4781700744ae0ce2fcf722816453ae0af2cd5646458James Dong notifyEmptyBufferDone(inHeader); 4791700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4801700744ae0ce2fcf722816453ae0af2cd5646458James Dong outQueue.erase(outQueue.begin()); 4811700744ae0ce2fcf722816453ae0af2cd5646458James Dong CHECK(!mInputBufferInfoVec.empty()); 4821700744ae0ce2fcf722816453ae0af2cd5646458James Dong InputBufferInfo *inputBufInfo = mInputBufferInfoVec.begin(); 4831700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nTimeStamp = inputBufInfo->mTimeUs; 4841700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nFlags |= (inputBufInfo->mFlags | OMX_BUFFERFLAG_ENDOFFRAME); 4851700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nFilledLen = dataLength; 4866e5b6ef15bb39cc0aa3d8fb7d4f75d44e5aadd92Jun Tian mInputBufferInfoVec.erase(mInputBufferInfoVec.begin()); 4871700744ae0ce2fcf722816453ae0af2cd5646458James Dong outInfo->mOwnedByUs = false; 4881700744ae0ce2fcf722816453ae0af2cd5646458James Dong notifyFillBufferDone(outHeader); 4891700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 4901700744ae0ce2fcf722816453ae0af2cd5646458James Dong} 4911700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4921700744ae0ce2fcf722816453ae0af2cd5646458James Dong} // namespace android 4931700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4941700744ae0ce2fcf722816453ae0af2cd5646458James Dongandroid::SoftOMXComponent *createSoftOMXComponent( 4951700744ae0ce2fcf722816453ae0af2cd5646458James Dong const char *name, const OMX_CALLBACKTYPE *callbacks, 4961700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_PTR appData, OMX_COMPONENTTYPE **component) { 497a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar using namespace android; 498a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar if (!strcmp(name, "OMX.google.h263.encoder")) { 499a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar return new android::SoftMPEG4Encoder( 500a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar name, "video_encoder.h263", OMX_VIDEO_CodingH263, MEDIA_MIMETYPE_VIDEO_H263, 501a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar kH263ProfileLevels, NELEM(kH263ProfileLevels), 502a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar callbacks, appData, component); 503a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar } else if (!strcmp(name, "OMX.google.mpeg4.encoder")) { 504a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar return new android::SoftMPEG4Encoder( 505a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar name, "video_encoder.mpeg4", OMX_VIDEO_CodingMPEG4, MEDIA_MIMETYPE_VIDEO_MPEG4, 506a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar kMPEG4ProfileLevels, NELEM(kMPEG4ProfileLevels), 507a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar callbacks, appData, component); 508a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar } else { 509a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar CHECK(!"Unknown component"); 510a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar } 511a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar return NULL; 5121700744ae0ce2fcf722816453ae0af2cd5646458James Dong} 513