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"); 1025443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim onReset(); 1031700744ae0ce2fcf722816453ae0af2cd5646458James Dong releaseEncoder(); 1041700744ae0ce2fcf722816453ae0af2cd5646458James Dong List<BufferInfo *> &outQueue = getPortQueue(1); 1051700744ae0ce2fcf722816453ae0af2cd5646458James Dong List<BufferInfo *> &inQueue = getPortQueue(0); 1061700744ae0ce2fcf722816453ae0af2cd5646458James Dong CHECK(outQueue.empty()); 1071700744ae0ce2fcf722816453ae0af2cd5646458James Dong CHECK(inQueue.empty()); 1081700744ae0ce2fcf722816453ae0af2cd5646458James Dong} 1091700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1101700744ae0ce2fcf722816453ae0af2cd5646458James DongOMX_ERRORTYPE SoftMPEG4Encoder::initEncParams() { 1111700744ae0ce2fcf722816453ae0af2cd5646458James Dong CHECK(mHandle != NULL); 1121700744ae0ce2fcf722816453ae0af2cd5646458James Dong memset(mHandle, 0, sizeof(tagvideoEncControls)); 1131700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1141700744ae0ce2fcf722816453ae0af2cd5646458James Dong CHECK(mEncParams != NULL); 1151700744ae0ce2fcf722816453ae0af2cd5646458James Dong memset(mEncParams, 0, sizeof(tagvideoEncOptions)); 1161700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (!PVGetDefaultEncOption(mEncParams, 0)) { 1171700744ae0ce2fcf722816453ae0af2cd5646458James Dong ALOGE("Failed to get default encoding parameters"); 1181700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 1191700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 120695123195034402ca76169b195069c28c30342d3Pawin Vongmasa if (mFramerate == 0) { 121695123195034402ca76169b195069c28c30342d3Pawin Vongmasa ALOGE("Framerate should not be 0"); 122695123195034402ca76169b195069c28c30342d3Pawin Vongmasa return OMX_ErrorUndefined; 123695123195034402ca76169b195069c28c30342d3Pawin Vongmasa } 1241700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->encMode = mEncodeMode; 125a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mEncParams->encWidth[0] = mWidth; 126a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mEncParams->encHeight[0] = mHeight; 127a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mEncParams->encFrameRate[0] = mFramerate >> 16; // mFramerate is in Q16 format 1281700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->rcType = VBR_1; 1291700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->vbvDelay = 5.0f; 1301700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1311700744ae0ce2fcf722816453ae0af2cd5646458James Dong // FIXME: 1321700744ae0ce2fcf722816453ae0af2cd5646458James Dong // Add more profile and level support for MPEG4 encoder 1331700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->profile_level = CORE_PROFILE_LEVEL2; 1341700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->packetSize = 32; 1351700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->rvlcEnable = PV_OFF; 1361700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->numLayers = 1; 1371700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->timeIncRes = 1000; 138a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mEncParams->tickPerSrc = ((int64_t)mEncParams->timeIncRes << 16) / mFramerate; 1391700744ae0ce2fcf722816453ae0af2cd5646458James Dong 140a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mEncParams->bitRate[0] = mBitrate; 1411700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->iQuant[0] = 15; 1421700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->pQuant[0] = 12; 1431700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->quantType[0] = 0; 1441700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->noFrameSkipped = PV_OFF; 1451700744ae0ce2fcf722816453ae0af2cd5646458James Dong 146a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar if (mColorFormat != OMX_COLOR_FormatYUV420Planar || mInputDataIsMeta) { 1471700744ae0ce2fcf722816453ae0af2cd5646458James Dong // Color conversion is needed. 1482edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar free(mInputFrameData); 14987f8cbb223ee516803dbb99699320c2484cbf3baWei Jia mInputFrameData = NULL; 15087f8cbb223ee516803dbb99699320c2484cbf3baWei Jia if (((uint64_t)mWidth * mHeight) > ((uint64_t)INT32_MAX / 3)) { 15187f8cbb223ee516803dbb99699320c2484cbf3baWei Jia ALOGE("b/25812794, Buffer size is too big."); 15287f8cbb223ee516803dbb99699320c2484cbf3baWei Jia return OMX_ErrorBadParameter; 15387f8cbb223ee516803dbb99699320c2484cbf3baWei Jia } 1541700744ae0ce2fcf722816453ae0af2cd5646458James Dong mInputFrameData = 155a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar (uint8_t *) malloc((mWidth * mHeight * 3 ) >> 1); 1561700744ae0ce2fcf722816453ae0af2cd5646458James Dong CHECK(mInputFrameData != NULL); 1571700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 1581700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1591700744ae0ce2fcf722816453ae0af2cd5646458James Dong // PV's MPEG4 encoder requires the video dimension of multiple 160a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar if (mWidth % 16 != 0 || mHeight % 16 != 0) { 1611700744ae0ce2fcf722816453ae0af2cd5646458James Dong ALOGE("Video frame size %dx%d must be a multiple of 16", 162a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mWidth, mHeight); 1631700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorBadParameter; 1641700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 1651700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1661700744ae0ce2fcf722816453ae0af2cd5646458James Dong // Set IDR frame refresh interval 167d72e751fa185f053773603222fd220ab77c92b2fLajos Molnar mEncParams->intraPeriod = mKeyFrameInterval; 1681700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1691700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->numIntraMB = 0; 1701700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->sceneDetect = PV_ON; 1711700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->searchRange = 16; 1721700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->mv8x8Enable = PV_OFF; 1731700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->gobHeaderInterval = 0; 1741700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->useACPred = PV_ON; 1751700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->intraDCVlcTh = 0; 1761700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1771700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorNone; 1781700744ae0ce2fcf722816453ae0af2cd5646458James Dong} 1791700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1801700744ae0ce2fcf722816453ae0af2cd5646458James DongOMX_ERRORTYPE SoftMPEG4Encoder::initEncoder() { 1811700744ae0ce2fcf722816453ae0af2cd5646458James Dong CHECK(!mStarted); 1821700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1831700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_ERRORTYPE errType = OMX_ErrorNone; 1841700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (OMX_ErrorNone != (errType = initEncParams())) { 1851700744ae0ce2fcf722816453ae0af2cd5646458James Dong ALOGE("Failed to initialized encoder params"); 1861700744ae0ce2fcf722816453ae0af2cd5646458James Dong mSignalledError = true; 1871700744ae0ce2fcf722816453ae0af2cd5646458James Dong notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 1881700744ae0ce2fcf722816453ae0af2cd5646458James Dong return errType; 1891700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 1901700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1911700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (!PVInitVideoEncoder(mHandle, mEncParams)) { 1921700744ae0ce2fcf722816453ae0af2cd5646458James Dong ALOGE("Failed to initialize the encoder"); 1931700744ae0ce2fcf722816453ae0af2cd5646458James Dong mSignalledError = true; 1941700744ae0ce2fcf722816453ae0af2cd5646458James Dong notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 1951700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 1961700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 1971700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1981700744ae0ce2fcf722816453ae0af2cd5646458James Dong mNumInputFrames = -1; // 1st buffer for codec specific data 1991700744ae0ce2fcf722816453ae0af2cd5646458James Dong mStarted = true; 2001700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2011700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorNone; 2021700744ae0ce2fcf722816453ae0af2cd5646458James Dong} 2031700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2041700744ae0ce2fcf722816453ae0af2cd5646458James DongOMX_ERRORTYPE SoftMPEG4Encoder::releaseEncoder() { 2055443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim if (mEncParams) { 2065443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim delete mEncParams; 2075443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim mEncParams = NULL; 2081700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 2091700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2105443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim if (mHandle) { 2115443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim delete mHandle; 2125443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim mHandle = NULL; 2135443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim } 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 2262720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen if (!isValidOMXParam(bitRate)) { 2272720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen return OMX_ErrorBadParameter; 2282720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen } 2292720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen 2301700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (bitRate->nPortIndex != 1) { 2311700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 2321700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 2331700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2341700744ae0ce2fcf722816453ae0af2cd5646458James Dong bitRate->eControlRate = OMX_Video_ControlRateVariable; 235a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar bitRate->nTargetBitrate = mBitrate; 2361700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorNone; 2371700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 2381700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2391700744ae0ce2fcf722816453ae0af2cd5646458James Dong case OMX_IndexParamVideoH263: 2401700744ae0ce2fcf722816453ae0af2cd5646458James Dong { 2411700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_VIDEO_PARAM_H263TYPE *h263type = 2421700744ae0ce2fcf722816453ae0af2cd5646458James Dong (OMX_VIDEO_PARAM_H263TYPE *)params; 2431700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2442720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen if (!isValidOMXParam(h263type)) { 2452720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen return OMX_ErrorBadParameter; 2462720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen } 2472720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen 2481700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (h263type->nPortIndex != 1) { 2491700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 2501700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 2511700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2521700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->nAllowedPictureTypes = 2531700744ae0ce2fcf722816453ae0af2cd5646458James Dong (OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP); 2541700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->eProfile = OMX_VIDEO_H263ProfileBaseline; 2551700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->eLevel = OMX_VIDEO_H263Level45; 2561700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->bPLUSPTYPEAllowed = OMX_FALSE; 2571700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->bForceRoundingTypeToZero = OMX_FALSE; 2581700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->nPictureHeaderRepetition = 0; 2591700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->nGOBHeaderInterval = 0; 2601700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2611700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorNone; 2621700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 2631700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2641700744ae0ce2fcf722816453ae0af2cd5646458James Dong case OMX_IndexParamVideoMpeg4: 2651700744ae0ce2fcf722816453ae0af2cd5646458James Dong { 2661700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_VIDEO_PARAM_MPEG4TYPE *mpeg4type = 2671700744ae0ce2fcf722816453ae0af2cd5646458James Dong (OMX_VIDEO_PARAM_MPEG4TYPE *)params; 2681700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2692720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen if (!isValidOMXParam(mpeg4type)) { 2702720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen return OMX_ErrorBadParameter; 2712720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen } 2722720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen 2731700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (mpeg4type->nPortIndex != 1) { 2741700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 2751700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 2761700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2771700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->eProfile = OMX_VIDEO_MPEG4ProfileCore; 2781700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->eLevel = OMX_VIDEO_MPEG4Level2; 2791700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nAllowedPictureTypes = 2801700744ae0ce2fcf722816453ae0af2cd5646458James Dong (OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP); 2811700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nBFrames = 0; 2821700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nIDCVLCThreshold = 0; 2831700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->bACPred = OMX_TRUE; 2841700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nMaxPacketSize = 256; 2851700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nTimeIncRes = 1000; 2861700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nHeaderExtension = 0; 2871700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->bReversibleVLC = OMX_FALSE; 2881700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2891700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorNone; 2901700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 2911700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2921700744ae0ce2fcf722816453ae0af2cd5646458James Dong default: 293a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar return SoftVideoEncoderOMXComponent::internalGetParameter(index, params); 2941700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 2951700744ae0ce2fcf722816453ae0af2cd5646458James Dong} 2961700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2971700744ae0ce2fcf722816453ae0af2cd5646458James DongOMX_ERRORTYPE SoftMPEG4Encoder::internalSetParameter( 2981700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_INDEXTYPE index, const OMX_PTR params) { 299bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala int32_t indexFull = index; 300bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala 301bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala switch (indexFull) { 3021700744ae0ce2fcf722816453ae0af2cd5646458James Dong case OMX_IndexParamVideoBitrate: 3031700744ae0ce2fcf722816453ae0af2cd5646458James Dong { 3041700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_VIDEO_PARAM_BITRATETYPE *bitRate = 3051700744ae0ce2fcf722816453ae0af2cd5646458James Dong (OMX_VIDEO_PARAM_BITRATETYPE *) params; 3061700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3072720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen if (!isValidOMXParam(bitRate)) { 3082720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen return OMX_ErrorBadParameter; 3092720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen } 3102720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen 3111700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (bitRate->nPortIndex != 1 || 3121700744ae0ce2fcf722816453ae0af2cd5646458James Dong bitRate->eControlRate != OMX_Video_ControlRateVariable) { 3131700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 3141700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3151700744ae0ce2fcf722816453ae0af2cd5646458James Dong 316a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mBitrate = bitRate->nTargetBitrate; 3171700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorNone; 3181700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3191700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3201700744ae0ce2fcf722816453ae0af2cd5646458James Dong case OMX_IndexParamVideoH263: 3211700744ae0ce2fcf722816453ae0af2cd5646458James Dong { 3221700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_VIDEO_PARAM_H263TYPE *h263type = 3231700744ae0ce2fcf722816453ae0af2cd5646458James Dong (OMX_VIDEO_PARAM_H263TYPE *)params; 3241700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3252720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen if (!isValidOMXParam(h263type)) { 3262720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen return OMX_ErrorBadParameter; 3272720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen } 3282720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen 3291700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (h263type->nPortIndex != 1) { 3301700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 3311700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3321700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3331700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (h263type->eProfile != OMX_VIDEO_H263ProfileBaseline || 3341700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->eLevel != OMX_VIDEO_H263Level45 || 3351700744ae0ce2fcf722816453ae0af2cd5646458James Dong (h263type->nAllowedPictureTypes & OMX_VIDEO_PictureTypeB) || 3361700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->bPLUSPTYPEAllowed != OMX_FALSE || 3371700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->bForceRoundingTypeToZero != OMX_FALSE || 3381700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->nPictureHeaderRepetition != 0 || 3391700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->nGOBHeaderInterval != 0) { 3401700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 3411700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3421700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3431700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorNone; 3441700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3451700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3461700744ae0ce2fcf722816453ae0af2cd5646458James Dong case OMX_IndexParamVideoMpeg4: 3471700744ae0ce2fcf722816453ae0af2cd5646458James Dong { 3481700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_VIDEO_PARAM_MPEG4TYPE *mpeg4type = 3491700744ae0ce2fcf722816453ae0af2cd5646458James Dong (OMX_VIDEO_PARAM_MPEG4TYPE *)params; 3501700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3512720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen if (!isValidOMXParam(mpeg4type)) { 3522720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen return OMX_ErrorBadParameter; 3532720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen } 3542720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen 3551700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (mpeg4type->nPortIndex != 1) { 3561700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 3571700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3581700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3591700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (mpeg4type->eProfile != OMX_VIDEO_MPEG4ProfileCore || 3601700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->eLevel != OMX_VIDEO_MPEG4Level2 || 3611700744ae0ce2fcf722816453ae0af2cd5646458James Dong (mpeg4type->nAllowedPictureTypes & OMX_VIDEO_PictureTypeB) || 3621700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nBFrames != 0 || 3631700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nIDCVLCThreshold != 0 || 3641700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->bACPred != OMX_TRUE || 3651700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nMaxPacketSize != 256 || 3661700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nTimeIncRes != 1000 || 3671700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nHeaderExtension != 0 || 3681700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->bReversibleVLC != OMX_FALSE) { 3691700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 3701700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3711700744ae0ce2fcf722816453ae0af2cd5646458James Dong 372d72e751fa185f053773603222fd220ab77c92b2fLajos Molnar mKeyFrameInterval = int32_t(mpeg4type->nPFrames + 1); 373d72e751fa185f053773603222fd220ab77c92b2fLajos Molnar 3741700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorNone; 3751700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3761700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3771700744ae0ce2fcf722816453ae0af2cd5646458James Dong default: 378a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar return SoftVideoEncoderOMXComponent::internalSetParameter(index, params); 3791700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3801700744ae0ce2fcf722816453ae0af2cd5646458James Dong} 3811700744ae0ce2fcf722816453ae0af2cd5646458James Dong 38284333e0475bc911adc16417f4ca327c975cf6c36Andreas Hubervoid SoftMPEG4Encoder::onQueueFilled(OMX_U32 /* portIndex */) { 3831700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (mSignalledError || mSawInputEOS) { 3841700744ae0ce2fcf722816453ae0af2cd5646458James Dong return; 3851700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3861700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3871700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (!mStarted) { 3881700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (OMX_ErrorNone != initEncoder()) { 3891700744ae0ce2fcf722816453ae0af2cd5646458James Dong return; 3901700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3911700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3921700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3931700744ae0ce2fcf722816453ae0af2cd5646458James Dong List<BufferInfo *> &inQueue = getPortQueue(0); 3941700744ae0ce2fcf722816453ae0af2cd5646458James Dong List<BufferInfo *> &outQueue = getPortQueue(1); 3951700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3961700744ae0ce2fcf722816453ae0af2cd5646458James Dong while (!mSawInputEOS && !inQueue.empty() && !outQueue.empty()) { 3971700744ae0ce2fcf722816453ae0af2cd5646458James Dong BufferInfo *inInfo = *inQueue.begin(); 3981700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader; 3991700744ae0ce2fcf722816453ae0af2cd5646458James Dong BufferInfo *outInfo = *outQueue.begin(); 4001700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; 4011700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4021700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nTimeStamp = 0; 4031700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nFlags = 0; 4041700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nOffset = 0; 4051700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nFilledLen = 0; 4061700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nOffset = 0; 4071700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4081700744ae0ce2fcf722816453ae0af2cd5646458James Dong uint8_t *outPtr = (uint8_t *) outHeader->pBuffer; 4091700744ae0ce2fcf722816453ae0af2cd5646458James Dong int32_t dataLength = outHeader->nAllocLen; 4101700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4111700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (mNumInputFrames < 0) { 4121700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (!PVGetVolHeader(mHandle, outPtr, &dataLength, 0)) { 4131700744ae0ce2fcf722816453ae0af2cd5646458James Dong ALOGE("Failed to get VOL header"); 4141700744ae0ce2fcf722816453ae0af2cd5646458James Dong mSignalledError = true; 4151700744ae0ce2fcf722816453ae0af2cd5646458James Dong notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 4161700744ae0ce2fcf722816453ae0af2cd5646458James Dong return; 4171700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 4181700744ae0ce2fcf722816453ae0af2cd5646458James Dong ALOGV("Output VOL header: %d bytes", dataLength); 4191700744ae0ce2fcf722816453ae0af2cd5646458James Dong ++mNumInputFrames; 4201700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nFlags |= OMX_BUFFERFLAG_CODECCONFIG; 4211700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nFilledLen = dataLength; 4221700744ae0ce2fcf722816453ae0af2cd5646458James Dong outQueue.erase(outQueue.begin()); 4231700744ae0ce2fcf722816453ae0af2cd5646458James Dong outInfo->mOwnedByUs = false; 4241700744ae0ce2fcf722816453ae0af2cd5646458James Dong notifyFillBufferDone(outHeader); 4251700744ae0ce2fcf722816453ae0af2cd5646458James Dong return; 4261700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 4271700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4281700744ae0ce2fcf722816453ae0af2cd5646458James Dong // Save the input buffer info so that it can be 4291700744ae0ce2fcf722816453ae0af2cd5646458James Dong // passed to an output buffer 4301700744ae0ce2fcf722816453ae0af2cd5646458James Dong InputBufferInfo info; 4311700744ae0ce2fcf722816453ae0af2cd5646458James Dong info.mTimeUs = inHeader->nTimeStamp; 4321700744ae0ce2fcf722816453ae0af2cd5646458James Dong info.mFlags = inHeader->nFlags; 4331700744ae0ce2fcf722816453ae0af2cd5646458James Dong mInputBufferInfoVec.push(info); 4341700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4351700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) { 4361700744ae0ce2fcf722816453ae0af2cd5646458James Dong mSawInputEOS = true; 4371700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 4381700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4391700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (inHeader->nFilledLen > 0) { 4402edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar const uint8_t *inputData = NULL; 441a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar if (mInputDataIsMeta) { 442bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala inputData = 4432edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar extractGraphicBuffer( 444a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mInputFrameData, (mWidth * mHeight * 3) >> 1, 4452edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar inHeader->pBuffer + inHeader->nOffset, inHeader->nFilledLen, 446a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mWidth, mHeight); 447bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala if (inputData == NULL) { 448bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala ALOGE("Unable to extract gralloc buffer in metadata mode"); 449bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala mSignalledError = true; 450bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 451bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala return; 452bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala } 453bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala } else { 4542edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar inputData = (const uint8_t *)inHeader->pBuffer + inHeader->nOffset; 455a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar if (mColorFormat != OMX_COLOR_FormatYUV420Planar) { 4562edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar ConvertYUV420SemiPlanarToYUV420Planar( 457a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar inputData, mInputFrameData, mWidth, mHeight); 4582edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar inputData = mInputFrameData; 4592edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar } 460bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala } 461bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala 4621700744ae0ce2fcf722816453ae0af2cd5646458James Dong CHECK(inputData != NULL); 4631700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4641700744ae0ce2fcf722816453ae0af2cd5646458James Dong VideoEncFrameIO vin, vout; 4651700744ae0ce2fcf722816453ae0af2cd5646458James Dong memset(&vin, 0, sizeof(vin)); 4661700744ae0ce2fcf722816453ae0af2cd5646458James Dong memset(&vout, 0, sizeof(vout)); 467a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar vin.height = align(mHeight, 16); 468a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar vin.pitch = align(mWidth, 16); 4691700744ae0ce2fcf722816453ae0af2cd5646458James Dong vin.timestamp = (inHeader->nTimeStamp + 500) / 1000; // in ms 4702edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar vin.yChan = (uint8_t *)inputData; 4711700744ae0ce2fcf722816453ae0af2cd5646458James Dong vin.uChan = vin.yChan + vin.height * vin.pitch; 4721700744ae0ce2fcf722816453ae0af2cd5646458James Dong vin.vChan = vin.uChan + ((vin.height * vin.pitch) >> 2); 4731700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4742426d11f795a99de85999b3ff0a26cc070a99a59Ashok Bhat ULong modTimeMs = 0; 4751700744ae0ce2fcf722816453ae0af2cd5646458James Dong int32_t nLayer = 0; 4761700744ae0ce2fcf722816453ae0af2cd5646458James Dong MP4HintTrack hintTrack; 4771700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (!PVEncodeVideoFrame(mHandle, &vin, &vout, 4781700744ae0ce2fcf722816453ae0af2cd5646458James Dong &modTimeMs, outPtr, &dataLength, &nLayer) || 4791700744ae0ce2fcf722816453ae0af2cd5646458James Dong !PVGetHintTrack(mHandle, &hintTrack)) { 480b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross ALOGE("Failed to encode frame or get hink track at frame %" PRId64, 4811700744ae0ce2fcf722816453ae0af2cd5646458James Dong mNumInputFrames); 4821700744ae0ce2fcf722816453ae0af2cd5646458James Dong mSignalledError = true; 4831700744ae0ce2fcf722816453ae0af2cd5646458James Dong notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 4841700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 4851700744ae0ce2fcf722816453ae0af2cd5646458James Dong CHECK(NULL == PVGetOverrunBuffer(mHandle)); 4861700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (hintTrack.CodeType == 0) { // I-frame serves as sync frame 4871700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; 4881700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 4891700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4901700744ae0ce2fcf722816453ae0af2cd5646458James Dong ++mNumInputFrames; 4911700744ae0ce2fcf722816453ae0af2cd5646458James Dong } else { 4921700744ae0ce2fcf722816453ae0af2cd5646458James Dong dataLength = 0; 4931700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 4941700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4951700744ae0ce2fcf722816453ae0af2cd5646458James Dong inQueue.erase(inQueue.begin()); 4961700744ae0ce2fcf722816453ae0af2cd5646458James Dong inInfo->mOwnedByUs = false; 4971700744ae0ce2fcf722816453ae0af2cd5646458James Dong notifyEmptyBufferDone(inHeader); 4981700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4991700744ae0ce2fcf722816453ae0af2cd5646458James Dong outQueue.erase(outQueue.begin()); 5001700744ae0ce2fcf722816453ae0af2cd5646458James Dong CHECK(!mInputBufferInfoVec.empty()); 5011700744ae0ce2fcf722816453ae0af2cd5646458James Dong InputBufferInfo *inputBufInfo = mInputBufferInfoVec.begin(); 5021700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nTimeStamp = inputBufInfo->mTimeUs; 5031700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nFlags |= (inputBufInfo->mFlags | OMX_BUFFERFLAG_ENDOFFRAME); 5041700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nFilledLen = dataLength; 5056e5b6ef15bb39cc0aa3d8fb7d4f75d44e5aadd92Jun Tian mInputBufferInfoVec.erase(mInputBufferInfoVec.begin()); 5061700744ae0ce2fcf722816453ae0af2cd5646458James Dong outInfo->mOwnedByUs = false; 5071700744ae0ce2fcf722816453ae0af2cd5646458James Dong notifyFillBufferDone(outHeader); 5081700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 5091700744ae0ce2fcf722816453ae0af2cd5646458James Dong} 5101700744ae0ce2fcf722816453ae0af2cd5646458James Dong 5115443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kimvoid SoftMPEG4Encoder::onReset() { 5125443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim if (!mStarted) { 5135443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim return; 5145443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim } 5155443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim 5165443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim PVCleanUpVideoEncoder(mHandle); 5175443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim 5185443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim free(mInputFrameData); 5195443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim mInputFrameData = NULL; 5205443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim 5215443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim mStarted = false; 5225443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim} 5235443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim 5241700744ae0ce2fcf722816453ae0af2cd5646458James Dong} // namespace android 5251700744ae0ce2fcf722816453ae0af2cd5646458James Dong 5261700744ae0ce2fcf722816453ae0af2cd5646458James Dongandroid::SoftOMXComponent *createSoftOMXComponent( 5271700744ae0ce2fcf722816453ae0af2cd5646458James Dong const char *name, const OMX_CALLBACKTYPE *callbacks, 5281700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_PTR appData, OMX_COMPONENTTYPE **component) { 529a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar using namespace android; 530a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar if (!strcmp(name, "OMX.google.h263.encoder")) { 531a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar return new android::SoftMPEG4Encoder( 532a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar name, "video_encoder.h263", OMX_VIDEO_CodingH263, MEDIA_MIMETYPE_VIDEO_H263, 533a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar kH263ProfileLevels, NELEM(kH263ProfileLevels), 534a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar callbacks, appData, component); 535a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar } else if (!strcmp(name, "OMX.google.mpeg4.encoder")) { 536a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar return new android::SoftMPEG4Encoder( 537a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar name, "video_encoder.mpeg4", OMX_VIDEO_CodingMPEG4, MEDIA_MIMETYPE_VIDEO_MPEG4, 538a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar kMPEG4ProfileLevels, NELEM(kMPEG4ProfileLevels), 539a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar callbacks, appData, component); 540a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar } else { 541a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar CHECK(!"Unknown component"); 542a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar } 543a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar return NULL; 5441700744ae0ce2fcf722816453ae0af2cd5646458James Dong} 545