SoftMPEG4Encoder.cpp revision d72e751fa185f053773603222fd220ab77c92b2f
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 4087f8cbb223ee516803dbb99699320c2484cbf3baWei Jia#ifndef INT32_MAX 4187f8cbb223ee516803dbb99699320c2484cbf3baWei Jia#define INT32_MAX 2147483647 4287f8cbb223ee516803dbb99699320c2484cbf3baWei Jia#endif 4387f8cbb223ee516803dbb99699320c2484cbf3baWei Jia 441700744ae0ce2fcf722816453ae0af2cd5646458James Dongnamespace android { 451700744ae0ce2fcf722816453ae0af2cd5646458James Dong 461700744ae0ce2fcf722816453ae0af2cd5646458James Dongtemplate<class T> 471700744ae0ce2fcf722816453ae0af2cd5646458James Dongstatic void InitOMXParams(T *params) { 481700744ae0ce2fcf722816453ae0af2cd5646458James Dong params->nSize = sizeof(T); 491700744ae0ce2fcf722816453ae0af2cd5646458James Dong params->nVersion.s.nVersionMajor = 1; 501700744ae0ce2fcf722816453ae0af2cd5646458James Dong params->nVersion.s.nVersionMinor = 0; 511700744ae0ce2fcf722816453ae0af2cd5646458James Dong params->nVersion.s.nRevision = 0; 521700744ae0ce2fcf722816453ae0af2cd5646458James Dong params->nVersion.s.nStep = 0; 531700744ae0ce2fcf722816453ae0af2cd5646458James Dong} 541700744ae0ce2fcf722816453ae0af2cd5646458James Dong 55a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnarstatic const CodecProfileLevel kMPEG4ProfileLevels[] = { 56a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar { OMX_VIDEO_MPEG4ProfileCore, OMX_VIDEO_MPEG4Level2 }, 57a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar}; 58a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar 59a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnarstatic const CodecProfileLevel kH263ProfileLevels[] = { 60a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar { OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level45 }, 61a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar}; 62a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar 631700744ae0ce2fcf722816453ae0af2cd5646458James DongSoftMPEG4Encoder::SoftMPEG4Encoder( 641700744ae0ce2fcf722816453ae0af2cd5646458James Dong const char *name, 65a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar const char *componentRole, 66a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar OMX_VIDEO_CODINGTYPE codingType, 67a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar const char *mime, 68a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar const CodecProfileLevel *profileLevels, 69a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar size_t numProfileLevels, 701700744ae0ce2fcf722816453ae0af2cd5646458James Dong const OMX_CALLBACKTYPE *callbacks, 711700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_PTR appData, 721700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_COMPONENTTYPE **component) 73a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar : SoftVideoEncoderOMXComponent( 74a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar name, componentRole, codingType, 75a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar profileLevels, numProfileLevels, 76a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar 176 /* width */, 144 /* height */, 77a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar callbacks, appData, component), 781700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncodeMode(COMBINE_MODE_WITH_ERR_RES), 79d72e751fa185f053773603222fd220ab77c92b2fLajos Molnar mKeyFrameInterval(30), 801700744ae0ce2fcf722816453ae0af2cd5646458James Dong mNumInputFrames(-1), 811700744ae0ce2fcf722816453ae0af2cd5646458James Dong mStarted(false), 821700744ae0ce2fcf722816453ae0af2cd5646458James Dong mSawInputEOS(false), 831700744ae0ce2fcf722816453ae0af2cd5646458James Dong mSignalledError(false), 841700744ae0ce2fcf722816453ae0af2cd5646458James Dong mHandle(new tagvideoEncControls), 851700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams(new tagvideoEncOptions), 861700744ae0ce2fcf722816453ae0af2cd5646458James Dong mInputFrameData(NULL) { 871700744ae0ce2fcf722816453ae0af2cd5646458James Dong 88a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar if (codingType == OMX_VIDEO_CodingH263) { 891700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncodeMode = H263_MODE; 901700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 911700744ae0ce2fcf722816453ae0af2cd5646458James Dong 92a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar // 256 * 1024 is a magic number for PV's encoder, not sure why 93a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar const size_t kOutputBufferSize = 256 * 1024; 94a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar 95a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar initPorts(kNumBuffers, kNumBuffers, kOutputBufferSize, mime); 96a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar 971700744ae0ce2fcf722816453ae0af2cd5646458James Dong ALOGI("Construct SoftMPEG4Encoder"); 981700744ae0ce2fcf722816453ae0af2cd5646458James Dong} 991700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1001700744ae0ce2fcf722816453ae0af2cd5646458James DongSoftMPEG4Encoder::~SoftMPEG4Encoder() { 1011700744ae0ce2fcf722816453ae0af2cd5646458James Dong ALOGV("Destruct SoftMPEG4Encoder"); 1021700744ae0ce2fcf722816453ae0af2cd5646458James Dong releaseEncoder(); 1031700744ae0ce2fcf722816453ae0af2cd5646458James Dong List<BufferInfo *> &outQueue = getPortQueue(1); 1041700744ae0ce2fcf722816453ae0af2cd5646458James Dong List<BufferInfo *> &inQueue = getPortQueue(0); 1051700744ae0ce2fcf722816453ae0af2cd5646458James Dong CHECK(outQueue.empty()); 1061700744ae0ce2fcf722816453ae0af2cd5646458James Dong CHECK(inQueue.empty()); 1071700744ae0ce2fcf722816453ae0af2cd5646458James Dong} 1081700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1091700744ae0ce2fcf722816453ae0af2cd5646458James DongOMX_ERRORTYPE SoftMPEG4Encoder::initEncParams() { 1101700744ae0ce2fcf722816453ae0af2cd5646458James Dong CHECK(mHandle != NULL); 1111700744ae0ce2fcf722816453ae0af2cd5646458James Dong memset(mHandle, 0, sizeof(tagvideoEncControls)); 1121700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1131700744ae0ce2fcf722816453ae0af2cd5646458James Dong CHECK(mEncParams != NULL); 1141700744ae0ce2fcf722816453ae0af2cd5646458James Dong memset(mEncParams, 0, sizeof(tagvideoEncOptions)); 1151700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (!PVGetDefaultEncOption(mEncParams, 0)) { 1161700744ae0ce2fcf722816453ae0af2cd5646458James Dong ALOGE("Failed to get default encoding parameters"); 1171700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 1181700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 1191700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->encMode = mEncodeMode; 120a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mEncParams->encWidth[0] = mWidth; 121a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mEncParams->encHeight[0] = mHeight; 122a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mEncParams->encFrameRate[0] = mFramerate >> 16; // mFramerate is in Q16 format 1231700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->rcType = VBR_1; 1241700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->vbvDelay = 5.0f; 1251700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1261700744ae0ce2fcf722816453ae0af2cd5646458James Dong // FIXME: 1271700744ae0ce2fcf722816453ae0af2cd5646458James Dong // Add more profile and level support for MPEG4 encoder 1281700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->profile_level = CORE_PROFILE_LEVEL2; 1291700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->packetSize = 32; 1301700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->rvlcEnable = PV_OFF; 1311700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->numLayers = 1; 1321700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->timeIncRes = 1000; 133a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mEncParams->tickPerSrc = ((int64_t)mEncParams->timeIncRes << 16) / mFramerate; 1341700744ae0ce2fcf722816453ae0af2cd5646458James Dong 135a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mEncParams->bitRate[0] = mBitrate; 1361700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->iQuant[0] = 15; 1371700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->pQuant[0] = 12; 1381700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->quantType[0] = 0; 1391700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->noFrameSkipped = PV_OFF; 1401700744ae0ce2fcf722816453ae0af2cd5646458James Dong 141a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar if (mColorFormat != OMX_COLOR_FormatYUV420Planar || mInputDataIsMeta) { 1421700744ae0ce2fcf722816453ae0af2cd5646458James Dong // Color conversion is needed. 1432edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar free(mInputFrameData); 14487f8cbb223ee516803dbb99699320c2484cbf3baWei Jia mInputFrameData = NULL; 14587f8cbb223ee516803dbb99699320c2484cbf3baWei Jia if (((uint64_t)mWidth * mHeight) > ((uint64_t)INT32_MAX / 3)) { 14687f8cbb223ee516803dbb99699320c2484cbf3baWei Jia ALOGE("b/25812794, Buffer size is too big."); 14787f8cbb223ee516803dbb99699320c2484cbf3baWei Jia return OMX_ErrorBadParameter; 14887f8cbb223ee516803dbb99699320c2484cbf3baWei Jia } 1491700744ae0ce2fcf722816453ae0af2cd5646458James Dong mInputFrameData = 150a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar (uint8_t *) malloc((mWidth * mHeight * 3 ) >> 1); 1511700744ae0ce2fcf722816453ae0af2cd5646458James Dong CHECK(mInputFrameData != NULL); 1521700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 1531700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1541700744ae0ce2fcf722816453ae0af2cd5646458James Dong // PV's MPEG4 encoder requires the video dimension of multiple 155a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar if (mWidth % 16 != 0 || mHeight % 16 != 0) { 1561700744ae0ce2fcf722816453ae0af2cd5646458James Dong ALOGE("Video frame size %dx%d must be a multiple of 16", 157a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mWidth, mHeight); 1581700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorBadParameter; 1591700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 1601700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1611700744ae0ce2fcf722816453ae0af2cd5646458James Dong // Set IDR frame refresh interval 162d72e751fa185f053773603222fd220ab77c92b2fLajos Molnar mEncParams->intraPeriod = mKeyFrameInterval; 1631700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1641700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->numIntraMB = 0; 1651700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->sceneDetect = PV_ON; 1661700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->searchRange = 16; 1671700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->mv8x8Enable = PV_OFF; 1681700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->gobHeaderInterval = 0; 1691700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->useACPred = PV_ON; 1701700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->intraDCVlcTh = 0; 1711700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1721700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorNone; 1731700744ae0ce2fcf722816453ae0af2cd5646458James Dong} 1741700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1751700744ae0ce2fcf722816453ae0af2cd5646458James DongOMX_ERRORTYPE SoftMPEG4Encoder::initEncoder() { 1761700744ae0ce2fcf722816453ae0af2cd5646458James Dong CHECK(!mStarted); 1771700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1781700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_ERRORTYPE errType = OMX_ErrorNone; 1791700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (OMX_ErrorNone != (errType = initEncParams())) { 1801700744ae0ce2fcf722816453ae0af2cd5646458James Dong ALOGE("Failed to initialized encoder params"); 1811700744ae0ce2fcf722816453ae0af2cd5646458James Dong mSignalledError = true; 1821700744ae0ce2fcf722816453ae0af2cd5646458James Dong notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 1831700744ae0ce2fcf722816453ae0af2cd5646458James Dong return errType; 1841700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 1851700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1861700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (!PVInitVideoEncoder(mHandle, mEncParams)) { 1871700744ae0ce2fcf722816453ae0af2cd5646458James Dong ALOGE("Failed to initialize the encoder"); 1881700744ae0ce2fcf722816453ae0af2cd5646458James Dong mSignalledError = true; 1891700744ae0ce2fcf722816453ae0af2cd5646458James Dong notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 1901700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 1911700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 1921700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1931700744ae0ce2fcf722816453ae0af2cd5646458James Dong mNumInputFrames = -1; // 1st buffer for codec specific data 1941700744ae0ce2fcf722816453ae0af2cd5646458James Dong mStarted = true; 1951700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1961700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorNone; 1971700744ae0ce2fcf722816453ae0af2cd5646458James Dong} 1981700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1991700744ae0ce2fcf722816453ae0af2cd5646458James DongOMX_ERRORTYPE SoftMPEG4Encoder::releaseEncoder() { 2001700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (!mStarted) { 2011700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorNone; 2021700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 2031700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2041700744ae0ce2fcf722816453ae0af2cd5646458James Dong PVCleanUpVideoEncoder(mHandle); 2051700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2062edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar free(mInputFrameData); 2071700744ae0ce2fcf722816453ae0af2cd5646458James Dong mInputFrameData = NULL; 2081700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2091700744ae0ce2fcf722816453ae0af2cd5646458James Dong delete mEncParams; 2101700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams = NULL; 2111700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2121700744ae0ce2fcf722816453ae0af2cd5646458James Dong delete mHandle; 2131700744ae0ce2fcf722816453ae0af2cd5646458James Dong mHandle = NULL; 2141700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2151700744ae0ce2fcf722816453ae0af2cd5646458James Dong mStarted = false; 2161700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2171700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorNone; 2181700744ae0ce2fcf722816453ae0af2cd5646458James Dong} 2191700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2201700744ae0ce2fcf722816453ae0af2cd5646458James DongOMX_ERRORTYPE SoftMPEG4Encoder::internalGetParameter( 2211700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_INDEXTYPE index, OMX_PTR params) { 2221700744ae0ce2fcf722816453ae0af2cd5646458James Dong switch (index) { 2231700744ae0ce2fcf722816453ae0af2cd5646458James Dong case OMX_IndexParamVideoBitrate: 2241700744ae0ce2fcf722816453ae0af2cd5646458James Dong { 2251700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_VIDEO_PARAM_BITRATETYPE *bitRate = 2261700744ae0ce2fcf722816453ae0af2cd5646458James Dong (OMX_VIDEO_PARAM_BITRATETYPE *) params; 2271700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2282720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen if (!isValidOMXParam(bitRate)) { 2292720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen return OMX_ErrorBadParameter; 2302720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen } 2312720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen 2321700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (bitRate->nPortIndex != 1) { 2331700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 2341700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 2351700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2361700744ae0ce2fcf722816453ae0af2cd5646458James Dong bitRate->eControlRate = OMX_Video_ControlRateVariable; 237a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar bitRate->nTargetBitrate = mBitrate; 2381700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorNone; 2391700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 2401700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2411700744ae0ce2fcf722816453ae0af2cd5646458James Dong case OMX_IndexParamVideoH263: 2421700744ae0ce2fcf722816453ae0af2cd5646458James Dong { 2431700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_VIDEO_PARAM_H263TYPE *h263type = 2441700744ae0ce2fcf722816453ae0af2cd5646458James Dong (OMX_VIDEO_PARAM_H263TYPE *)params; 2451700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2462720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen if (!isValidOMXParam(h263type)) { 2472720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen return OMX_ErrorBadParameter; 2482720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen } 2492720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen 2501700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (h263type->nPortIndex != 1) { 2511700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 2521700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 2531700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2541700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->nAllowedPictureTypes = 2551700744ae0ce2fcf722816453ae0af2cd5646458James Dong (OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP); 2561700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->eProfile = OMX_VIDEO_H263ProfileBaseline; 2571700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->eLevel = OMX_VIDEO_H263Level45; 2581700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->bPLUSPTYPEAllowed = OMX_FALSE; 2591700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->bForceRoundingTypeToZero = OMX_FALSE; 2601700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->nPictureHeaderRepetition = 0; 2611700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->nGOBHeaderInterval = 0; 2621700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2631700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorNone; 2641700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 2651700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2661700744ae0ce2fcf722816453ae0af2cd5646458James Dong case OMX_IndexParamVideoMpeg4: 2671700744ae0ce2fcf722816453ae0af2cd5646458James Dong { 2681700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_VIDEO_PARAM_MPEG4TYPE *mpeg4type = 2691700744ae0ce2fcf722816453ae0af2cd5646458James Dong (OMX_VIDEO_PARAM_MPEG4TYPE *)params; 2701700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2712720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen if (!isValidOMXParam(mpeg4type)) { 2722720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen return OMX_ErrorBadParameter; 2732720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen } 2742720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen 2751700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (mpeg4type->nPortIndex != 1) { 2761700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 2771700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 2781700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2791700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->eProfile = OMX_VIDEO_MPEG4ProfileCore; 2801700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->eLevel = OMX_VIDEO_MPEG4Level2; 2811700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nAllowedPictureTypes = 2821700744ae0ce2fcf722816453ae0af2cd5646458James Dong (OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP); 2831700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nBFrames = 0; 2841700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nIDCVLCThreshold = 0; 2851700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->bACPred = OMX_TRUE; 2861700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nMaxPacketSize = 256; 2871700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nTimeIncRes = 1000; 2881700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nHeaderExtension = 0; 2891700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->bReversibleVLC = OMX_FALSE; 2901700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2911700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorNone; 2921700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 2931700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2941700744ae0ce2fcf722816453ae0af2cd5646458James Dong default: 295a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar return SoftVideoEncoderOMXComponent::internalGetParameter(index, params); 2961700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 2971700744ae0ce2fcf722816453ae0af2cd5646458James Dong} 2981700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2991700744ae0ce2fcf722816453ae0af2cd5646458James DongOMX_ERRORTYPE SoftMPEG4Encoder::internalSetParameter( 3001700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_INDEXTYPE index, const OMX_PTR params) { 301bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala int32_t indexFull = index; 302bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala 303bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala switch (indexFull) { 3041700744ae0ce2fcf722816453ae0af2cd5646458James Dong case OMX_IndexParamVideoBitrate: 3051700744ae0ce2fcf722816453ae0af2cd5646458James Dong { 3061700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_VIDEO_PARAM_BITRATETYPE *bitRate = 3071700744ae0ce2fcf722816453ae0af2cd5646458James Dong (OMX_VIDEO_PARAM_BITRATETYPE *) params; 3081700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3092720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen if (!isValidOMXParam(bitRate)) { 3102720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen return OMX_ErrorBadParameter; 3112720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen } 3122720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen 3131700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (bitRate->nPortIndex != 1 || 3141700744ae0ce2fcf722816453ae0af2cd5646458James Dong bitRate->eControlRate != OMX_Video_ControlRateVariable) { 3151700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 3161700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3171700744ae0ce2fcf722816453ae0af2cd5646458James Dong 318a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mBitrate = bitRate->nTargetBitrate; 3191700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorNone; 3201700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3211700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3221700744ae0ce2fcf722816453ae0af2cd5646458James Dong case OMX_IndexParamVideoH263: 3231700744ae0ce2fcf722816453ae0af2cd5646458James Dong { 3241700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_VIDEO_PARAM_H263TYPE *h263type = 3251700744ae0ce2fcf722816453ae0af2cd5646458James Dong (OMX_VIDEO_PARAM_H263TYPE *)params; 3261700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3272720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen if (!isValidOMXParam(h263type)) { 3282720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen return OMX_ErrorBadParameter; 3292720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen } 3302720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen 3311700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (h263type->nPortIndex != 1) { 3321700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 3331700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3341700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3351700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (h263type->eProfile != OMX_VIDEO_H263ProfileBaseline || 3361700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->eLevel != OMX_VIDEO_H263Level45 || 3371700744ae0ce2fcf722816453ae0af2cd5646458James Dong (h263type->nAllowedPictureTypes & OMX_VIDEO_PictureTypeB) || 3381700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->bPLUSPTYPEAllowed != OMX_FALSE || 3391700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->bForceRoundingTypeToZero != OMX_FALSE || 3401700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->nPictureHeaderRepetition != 0 || 3411700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->nGOBHeaderInterval != 0) { 3421700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 3431700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3441700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3451700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorNone; 3461700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3471700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3481700744ae0ce2fcf722816453ae0af2cd5646458James Dong case OMX_IndexParamVideoMpeg4: 3491700744ae0ce2fcf722816453ae0af2cd5646458James Dong { 3501700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_VIDEO_PARAM_MPEG4TYPE *mpeg4type = 3511700744ae0ce2fcf722816453ae0af2cd5646458James Dong (OMX_VIDEO_PARAM_MPEG4TYPE *)params; 3521700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3532720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen if (!isValidOMXParam(mpeg4type)) { 3542720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen return OMX_ErrorBadParameter; 3552720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen } 3562720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen 3571700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (mpeg4type->nPortIndex != 1) { 3581700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 3591700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3601700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3611700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (mpeg4type->eProfile != OMX_VIDEO_MPEG4ProfileCore || 3621700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->eLevel != OMX_VIDEO_MPEG4Level2 || 3631700744ae0ce2fcf722816453ae0af2cd5646458James Dong (mpeg4type->nAllowedPictureTypes & OMX_VIDEO_PictureTypeB) || 3641700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nBFrames != 0 || 3651700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nIDCVLCThreshold != 0 || 3661700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->bACPred != OMX_TRUE || 3671700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nMaxPacketSize != 256 || 3681700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nTimeIncRes != 1000 || 3691700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nHeaderExtension != 0 || 3701700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->bReversibleVLC != OMX_FALSE) { 3711700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 3721700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3731700744ae0ce2fcf722816453ae0af2cd5646458James Dong 374d72e751fa185f053773603222fd220ab77c92b2fLajos Molnar mKeyFrameInterval = int32_t(mpeg4type->nPFrames + 1); 375d72e751fa185f053773603222fd220ab77c92b2fLajos Molnar 3761700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorNone; 3771700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3781700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3791700744ae0ce2fcf722816453ae0af2cd5646458James Dong default: 380a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar return SoftVideoEncoderOMXComponent::internalSetParameter(index, params); 3811700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3821700744ae0ce2fcf722816453ae0af2cd5646458James Dong} 3831700744ae0ce2fcf722816453ae0af2cd5646458James Dong 38484333e0475bc911adc16417f4ca327c975cf6c36Andreas Hubervoid SoftMPEG4Encoder::onQueueFilled(OMX_U32 /* portIndex */) { 3851700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (mSignalledError || mSawInputEOS) { 3861700744ae0ce2fcf722816453ae0af2cd5646458James Dong return; 3871700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3881700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3891700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (!mStarted) { 3901700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (OMX_ErrorNone != initEncoder()) { 3911700744ae0ce2fcf722816453ae0af2cd5646458James Dong return; 3921700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3931700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3941700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3951700744ae0ce2fcf722816453ae0af2cd5646458James Dong List<BufferInfo *> &inQueue = getPortQueue(0); 3961700744ae0ce2fcf722816453ae0af2cd5646458James Dong List<BufferInfo *> &outQueue = getPortQueue(1); 3971700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3981700744ae0ce2fcf722816453ae0af2cd5646458James Dong while (!mSawInputEOS && !inQueue.empty() && !outQueue.empty()) { 3991700744ae0ce2fcf722816453ae0af2cd5646458James Dong BufferInfo *inInfo = *inQueue.begin(); 4001700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader; 4011700744ae0ce2fcf722816453ae0af2cd5646458James Dong BufferInfo *outInfo = *outQueue.begin(); 4021700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; 4031700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4041700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nTimeStamp = 0; 4051700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nFlags = 0; 4061700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nOffset = 0; 4071700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nFilledLen = 0; 4081700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nOffset = 0; 4091700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4101700744ae0ce2fcf722816453ae0af2cd5646458James Dong uint8_t *outPtr = (uint8_t *) outHeader->pBuffer; 4111700744ae0ce2fcf722816453ae0af2cd5646458James Dong int32_t dataLength = outHeader->nAllocLen; 4121700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4131700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (mNumInputFrames < 0) { 4141700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (!PVGetVolHeader(mHandle, outPtr, &dataLength, 0)) { 4151700744ae0ce2fcf722816453ae0af2cd5646458James Dong ALOGE("Failed to get VOL header"); 4161700744ae0ce2fcf722816453ae0af2cd5646458James Dong mSignalledError = true; 4171700744ae0ce2fcf722816453ae0af2cd5646458James Dong notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 4181700744ae0ce2fcf722816453ae0af2cd5646458James Dong return; 4191700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 4201700744ae0ce2fcf722816453ae0af2cd5646458James Dong ALOGV("Output VOL header: %d bytes", dataLength); 4211700744ae0ce2fcf722816453ae0af2cd5646458James Dong ++mNumInputFrames; 4221700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nFlags |= OMX_BUFFERFLAG_CODECCONFIG; 4231700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nFilledLen = dataLength; 4241700744ae0ce2fcf722816453ae0af2cd5646458James Dong outQueue.erase(outQueue.begin()); 4251700744ae0ce2fcf722816453ae0af2cd5646458James Dong outInfo->mOwnedByUs = false; 4261700744ae0ce2fcf722816453ae0af2cd5646458James Dong notifyFillBufferDone(outHeader); 4271700744ae0ce2fcf722816453ae0af2cd5646458James Dong return; 4281700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 4291700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4301700744ae0ce2fcf722816453ae0af2cd5646458James Dong // Save the input buffer info so that it can be 4311700744ae0ce2fcf722816453ae0af2cd5646458James Dong // passed to an output buffer 4321700744ae0ce2fcf722816453ae0af2cd5646458James Dong InputBufferInfo info; 4331700744ae0ce2fcf722816453ae0af2cd5646458James Dong info.mTimeUs = inHeader->nTimeStamp; 4341700744ae0ce2fcf722816453ae0af2cd5646458James Dong info.mFlags = inHeader->nFlags; 4351700744ae0ce2fcf722816453ae0af2cd5646458James Dong mInputBufferInfoVec.push(info); 4361700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4371700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) { 4381700744ae0ce2fcf722816453ae0af2cd5646458James Dong mSawInputEOS = true; 4391700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 4401700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4411700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (inHeader->nFilledLen > 0) { 4422edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar const uint8_t *inputData = NULL; 443a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar if (mInputDataIsMeta) { 444bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala inputData = 4452edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar extractGraphicBuffer( 446a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mInputFrameData, (mWidth * mHeight * 3) >> 1, 4472edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar inHeader->pBuffer + inHeader->nOffset, inHeader->nFilledLen, 448a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mWidth, mHeight); 449bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala if (inputData == NULL) { 450bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala ALOGE("Unable to extract gralloc buffer in metadata mode"); 451bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala mSignalledError = true; 452bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 453bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala return; 454bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala } 455bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala } else { 4562edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar inputData = (const uint8_t *)inHeader->pBuffer + inHeader->nOffset; 457a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar if (mColorFormat != OMX_COLOR_FormatYUV420Planar) { 4582edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar ConvertYUV420SemiPlanarToYUV420Planar( 459a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar inputData, mInputFrameData, mWidth, mHeight); 4602edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar inputData = mInputFrameData; 4612edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar } 462bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala } 463bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala 4641700744ae0ce2fcf722816453ae0af2cd5646458James Dong CHECK(inputData != NULL); 4651700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4661700744ae0ce2fcf722816453ae0af2cd5646458James Dong VideoEncFrameIO vin, vout; 4671700744ae0ce2fcf722816453ae0af2cd5646458James Dong memset(&vin, 0, sizeof(vin)); 4681700744ae0ce2fcf722816453ae0af2cd5646458James Dong memset(&vout, 0, sizeof(vout)); 469a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar vin.height = align(mHeight, 16); 470a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar vin.pitch = align(mWidth, 16); 4711700744ae0ce2fcf722816453ae0af2cd5646458James Dong vin.timestamp = (inHeader->nTimeStamp + 500) / 1000; // in ms 4722edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar vin.yChan = (uint8_t *)inputData; 4731700744ae0ce2fcf722816453ae0af2cd5646458James Dong vin.uChan = vin.yChan + vin.height * vin.pitch; 4741700744ae0ce2fcf722816453ae0af2cd5646458James Dong vin.vChan = vin.uChan + ((vin.height * vin.pitch) >> 2); 4751700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4762426d11f795a99de85999b3ff0a26cc070a99a59Ashok Bhat ULong modTimeMs = 0; 4771700744ae0ce2fcf722816453ae0af2cd5646458James Dong int32_t nLayer = 0; 4781700744ae0ce2fcf722816453ae0af2cd5646458James Dong MP4HintTrack hintTrack; 4791700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (!PVEncodeVideoFrame(mHandle, &vin, &vout, 4801700744ae0ce2fcf722816453ae0af2cd5646458James Dong &modTimeMs, outPtr, &dataLength, &nLayer) || 4811700744ae0ce2fcf722816453ae0af2cd5646458James Dong !PVGetHintTrack(mHandle, &hintTrack)) { 482b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross ALOGE("Failed to encode frame or get hink track at frame %" PRId64, 4831700744ae0ce2fcf722816453ae0af2cd5646458James Dong mNumInputFrames); 4841700744ae0ce2fcf722816453ae0af2cd5646458James Dong mSignalledError = true; 4851700744ae0ce2fcf722816453ae0af2cd5646458James Dong notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 4861700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 4871700744ae0ce2fcf722816453ae0af2cd5646458James Dong CHECK(NULL == PVGetOverrunBuffer(mHandle)); 4881700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (hintTrack.CodeType == 0) { // I-frame serves as sync frame 4891700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; 4901700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 4911700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4921700744ae0ce2fcf722816453ae0af2cd5646458James Dong ++mNumInputFrames; 4931700744ae0ce2fcf722816453ae0af2cd5646458James Dong } else { 4941700744ae0ce2fcf722816453ae0af2cd5646458James Dong dataLength = 0; 4951700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 4961700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4971700744ae0ce2fcf722816453ae0af2cd5646458James Dong inQueue.erase(inQueue.begin()); 4981700744ae0ce2fcf722816453ae0af2cd5646458James Dong inInfo->mOwnedByUs = false; 4991700744ae0ce2fcf722816453ae0af2cd5646458James Dong notifyEmptyBufferDone(inHeader); 5001700744ae0ce2fcf722816453ae0af2cd5646458James Dong 5011700744ae0ce2fcf722816453ae0af2cd5646458James Dong outQueue.erase(outQueue.begin()); 5021700744ae0ce2fcf722816453ae0af2cd5646458James Dong CHECK(!mInputBufferInfoVec.empty()); 5031700744ae0ce2fcf722816453ae0af2cd5646458James Dong InputBufferInfo *inputBufInfo = mInputBufferInfoVec.begin(); 5041700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nTimeStamp = inputBufInfo->mTimeUs; 5051700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nFlags |= (inputBufInfo->mFlags | OMX_BUFFERFLAG_ENDOFFRAME); 5061700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nFilledLen = dataLength; 5076e5b6ef15bb39cc0aa3d8fb7d4f75d44e5aadd92Jun Tian mInputBufferInfoVec.erase(mInputBufferInfoVec.begin()); 5081700744ae0ce2fcf722816453ae0af2cd5646458James Dong outInfo->mOwnedByUs = false; 5091700744ae0ce2fcf722816453ae0af2cd5646458James Dong notifyFillBufferDone(outHeader); 5101700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 5111700744ae0ce2fcf722816453ae0af2cd5646458James Dong} 5121700744ae0ce2fcf722816453ae0af2cd5646458James Dong 5131700744ae0ce2fcf722816453ae0af2cd5646458James Dong} // namespace android 5141700744ae0ce2fcf722816453ae0af2cd5646458James Dong 5151700744ae0ce2fcf722816453ae0af2cd5646458James Dongandroid::SoftOMXComponent *createSoftOMXComponent( 5161700744ae0ce2fcf722816453ae0af2cd5646458James Dong const char *name, const OMX_CALLBACKTYPE *callbacks, 5171700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_PTR appData, OMX_COMPONENTTYPE **component) { 518a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar using namespace android; 519a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar if (!strcmp(name, "OMX.google.h263.encoder")) { 520a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar return new android::SoftMPEG4Encoder( 521a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar name, "video_encoder.h263", OMX_VIDEO_CodingH263, MEDIA_MIMETYPE_VIDEO_H263, 522a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar kH263ProfileLevels, NELEM(kH263ProfileLevels), 523a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar callbacks, appData, component); 524a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar } else if (!strcmp(name, "OMX.google.mpeg4.encoder")) { 525a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar return new android::SoftMPEG4Encoder( 526a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar name, "video_encoder.mpeg4", OMX_VIDEO_CodingMPEG4, MEDIA_MIMETYPE_VIDEO_MPEG4, 527a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar kMPEG4ProfileLevels, NELEM(kMPEG4ProfileLevels), 528a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar callbacks, appData, component); 529a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar } else { 530a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar CHECK(!"Unknown component"); 531a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar } 532a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar return NULL; 5331700744ae0ce2fcf722816453ae0af2cd5646458James Dong} 534