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 331700744ae0ce2fcf722816453ae0af2cd5646458James Dong#include "SoftMPEG4Encoder.h" 341700744ae0ce2fcf722816453ae0af2cd5646458James Dong 35b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross#include <inttypes.h> 36b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross 3787f8cbb223ee516803dbb99699320c2484cbf3baWei Jia#ifndef INT32_MAX 3887f8cbb223ee516803dbb99699320c2484cbf3baWei Jia#define INT32_MAX 2147483647 3987f8cbb223ee516803dbb99699320c2484cbf3baWei Jia#endif 4087f8cbb223ee516803dbb99699320c2484cbf3baWei Jia 411700744ae0ce2fcf722816453ae0af2cd5646458James Dongnamespace android { 421700744ae0ce2fcf722816453ae0af2cd5646458James Dong 431700744ae0ce2fcf722816453ae0af2cd5646458James Dongtemplate<class T> 441700744ae0ce2fcf722816453ae0af2cd5646458James Dongstatic void InitOMXParams(T *params) { 451700744ae0ce2fcf722816453ae0af2cd5646458James Dong params->nSize = sizeof(T); 461700744ae0ce2fcf722816453ae0af2cd5646458James Dong params->nVersion.s.nVersionMajor = 1; 471700744ae0ce2fcf722816453ae0af2cd5646458James Dong params->nVersion.s.nVersionMinor = 0; 481700744ae0ce2fcf722816453ae0af2cd5646458James Dong params->nVersion.s.nRevision = 0; 491700744ae0ce2fcf722816453ae0af2cd5646458James Dong params->nVersion.s.nStep = 0; 501700744ae0ce2fcf722816453ae0af2cd5646458James Dong} 511700744ae0ce2fcf722816453ae0af2cd5646458James Dong 52a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnarstatic const CodecProfileLevel kMPEG4ProfileLevels[] = { 53a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar { OMX_VIDEO_MPEG4ProfileCore, OMX_VIDEO_MPEG4Level2 }, 54a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar}; 55a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar 56a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnarstatic const CodecProfileLevel kH263ProfileLevels[] = { 57a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar { OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level45 }, 58a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar}; 59a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar 601700744ae0ce2fcf722816453ae0af2cd5646458James DongSoftMPEG4Encoder::SoftMPEG4Encoder( 611700744ae0ce2fcf722816453ae0af2cd5646458James Dong const char *name, 62a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar const char *componentRole, 63a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar OMX_VIDEO_CODINGTYPE codingType, 64a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar const char *mime, 65a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar const CodecProfileLevel *profileLevels, 66a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar size_t numProfileLevels, 671700744ae0ce2fcf722816453ae0af2cd5646458James Dong const OMX_CALLBACKTYPE *callbacks, 681700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_PTR appData, 691700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_COMPONENTTYPE **component) 70a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar : SoftVideoEncoderOMXComponent( 71a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar name, componentRole, codingType, 72a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar profileLevels, numProfileLevels, 73a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar 176 /* width */, 144 /* height */, 74a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar callbacks, appData, component), 751700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncodeMode(COMBINE_MODE_WITH_ERR_RES), 76d72e751fa185f053773603222fd220ab77c92b2fLajos Molnar mKeyFrameInterval(30), 771700744ae0ce2fcf722816453ae0af2cd5646458James Dong mNumInputFrames(-1), 781700744ae0ce2fcf722816453ae0af2cd5646458James Dong mStarted(false), 791700744ae0ce2fcf722816453ae0af2cd5646458James Dong mSawInputEOS(false), 801700744ae0ce2fcf722816453ae0af2cd5646458James Dong mSignalledError(false), 811700744ae0ce2fcf722816453ae0af2cd5646458James Dong mHandle(new tagvideoEncControls), 821700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams(new tagvideoEncOptions), 831700744ae0ce2fcf722816453ae0af2cd5646458James Dong mInputFrameData(NULL) { 841700744ae0ce2fcf722816453ae0af2cd5646458James Dong 85a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar if (codingType == OMX_VIDEO_CodingH263) { 861700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncodeMode = H263_MODE; 871700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 881700744ae0ce2fcf722816453ae0af2cd5646458James Dong 89a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar // 256 * 1024 is a magic number for PV's encoder, not sure why 90a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar const size_t kOutputBufferSize = 256 * 1024; 91a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar 92a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar initPorts(kNumBuffers, kNumBuffers, kOutputBufferSize, mime); 93a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar 941700744ae0ce2fcf722816453ae0af2cd5646458James Dong ALOGI("Construct SoftMPEG4Encoder"); 951700744ae0ce2fcf722816453ae0af2cd5646458James Dong} 961700744ae0ce2fcf722816453ae0af2cd5646458James Dong 971700744ae0ce2fcf722816453ae0af2cd5646458James DongSoftMPEG4Encoder::~SoftMPEG4Encoder() { 981700744ae0ce2fcf722816453ae0af2cd5646458James Dong ALOGV("Destruct SoftMPEG4Encoder"); 995443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim onReset(); 1001700744ae0ce2fcf722816453ae0af2cd5646458James Dong releaseEncoder(); 1011700744ae0ce2fcf722816453ae0af2cd5646458James Dong List<BufferInfo *> &outQueue = getPortQueue(1); 1021700744ae0ce2fcf722816453ae0af2cd5646458James Dong List<BufferInfo *> &inQueue = getPortQueue(0); 1031700744ae0ce2fcf722816453ae0af2cd5646458James Dong CHECK(outQueue.empty()); 1041700744ae0ce2fcf722816453ae0af2cd5646458James Dong CHECK(inQueue.empty()); 1051700744ae0ce2fcf722816453ae0af2cd5646458James Dong} 1061700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1071700744ae0ce2fcf722816453ae0af2cd5646458James DongOMX_ERRORTYPE SoftMPEG4Encoder::initEncParams() { 1081700744ae0ce2fcf722816453ae0af2cd5646458James Dong CHECK(mHandle != NULL); 1091700744ae0ce2fcf722816453ae0af2cd5646458James Dong memset(mHandle, 0, sizeof(tagvideoEncControls)); 1101700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1111700744ae0ce2fcf722816453ae0af2cd5646458James Dong CHECK(mEncParams != NULL); 1121700744ae0ce2fcf722816453ae0af2cd5646458James Dong memset(mEncParams, 0, sizeof(tagvideoEncOptions)); 1131700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (!PVGetDefaultEncOption(mEncParams, 0)) { 1141700744ae0ce2fcf722816453ae0af2cd5646458James Dong ALOGE("Failed to get default encoding parameters"); 1151700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 1161700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 117695123195034402ca76169b195069c28c30342d3Pawin Vongmasa if (mFramerate == 0) { 118695123195034402ca76169b195069c28c30342d3Pawin Vongmasa ALOGE("Framerate should not be 0"); 119695123195034402ca76169b195069c28c30342d3Pawin Vongmasa return OMX_ErrorUndefined; 120695123195034402ca76169b195069c28c30342d3Pawin Vongmasa } 1211700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->encMode = mEncodeMode; 122a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mEncParams->encWidth[0] = mWidth; 123a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mEncParams->encHeight[0] = mHeight; 124a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mEncParams->encFrameRate[0] = mFramerate >> 16; // mFramerate is in Q16 format 1251700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->rcType = VBR_1; 1261700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->vbvDelay = 5.0f; 1271700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1281700744ae0ce2fcf722816453ae0af2cd5646458James Dong // FIXME: 1291700744ae0ce2fcf722816453ae0af2cd5646458James Dong // Add more profile and level support for MPEG4 encoder 1301700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->profile_level = CORE_PROFILE_LEVEL2; 1311700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->packetSize = 32; 1321700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->rvlcEnable = PV_OFF; 1331700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->numLayers = 1; 1341700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->timeIncRes = 1000; 135a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mEncParams->tickPerSrc = ((int64_t)mEncParams->timeIncRes << 16) / mFramerate; 1361700744ae0ce2fcf722816453ae0af2cd5646458James Dong 137a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mEncParams->bitRate[0] = mBitrate; 1381700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->iQuant[0] = 15; 1391700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->pQuant[0] = 12; 1401700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->quantType[0] = 0; 1411700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->noFrameSkipped = PV_OFF; 1421700744ae0ce2fcf722816453ae0af2cd5646458James Dong 143a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar if (mColorFormat != OMX_COLOR_FormatYUV420Planar || mInputDataIsMeta) { 1441700744ae0ce2fcf722816453ae0af2cd5646458James Dong // Color conversion is needed. 1452edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar free(mInputFrameData); 14687f8cbb223ee516803dbb99699320c2484cbf3baWei Jia mInputFrameData = NULL; 14787f8cbb223ee516803dbb99699320c2484cbf3baWei Jia if (((uint64_t)mWidth * mHeight) > ((uint64_t)INT32_MAX / 3)) { 14887f8cbb223ee516803dbb99699320c2484cbf3baWei Jia ALOGE("b/25812794, Buffer size is too big."); 14987f8cbb223ee516803dbb99699320c2484cbf3baWei Jia return OMX_ErrorBadParameter; 15087f8cbb223ee516803dbb99699320c2484cbf3baWei Jia } 1511700744ae0ce2fcf722816453ae0af2cd5646458James Dong mInputFrameData = 152a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar (uint8_t *) malloc((mWidth * mHeight * 3 ) >> 1); 1531700744ae0ce2fcf722816453ae0af2cd5646458James Dong CHECK(mInputFrameData != NULL); 1541700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 1551700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1561700744ae0ce2fcf722816453ae0af2cd5646458James Dong // PV's MPEG4 encoder requires the video dimension of multiple 157a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar if (mWidth % 16 != 0 || mHeight % 16 != 0) { 1581700744ae0ce2fcf722816453ae0af2cd5646458James Dong ALOGE("Video frame size %dx%d must be a multiple of 16", 159a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mWidth, mHeight); 1601700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorBadParameter; 1611700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 1621700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1631700744ae0ce2fcf722816453ae0af2cd5646458James Dong // Set IDR frame refresh interval 164d72e751fa185f053773603222fd220ab77c92b2fLajos Molnar mEncParams->intraPeriod = mKeyFrameInterval; 1651700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1661700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->numIntraMB = 0; 1671700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->sceneDetect = PV_ON; 1681700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->searchRange = 16; 1691700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->mv8x8Enable = PV_OFF; 1701700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->gobHeaderInterval = 0; 1711700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->useACPred = PV_ON; 1721700744ae0ce2fcf722816453ae0af2cd5646458James Dong mEncParams->intraDCVlcTh = 0; 1731700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1741700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorNone; 1751700744ae0ce2fcf722816453ae0af2cd5646458James Dong} 1761700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1771700744ae0ce2fcf722816453ae0af2cd5646458James DongOMX_ERRORTYPE SoftMPEG4Encoder::initEncoder() { 1781700744ae0ce2fcf722816453ae0af2cd5646458James Dong CHECK(!mStarted); 1791700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1801700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_ERRORTYPE errType = OMX_ErrorNone; 1811700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (OMX_ErrorNone != (errType = initEncParams())) { 1821700744ae0ce2fcf722816453ae0af2cd5646458James Dong ALOGE("Failed to initialized encoder params"); 1831700744ae0ce2fcf722816453ae0af2cd5646458James Dong mSignalledError = true; 1841700744ae0ce2fcf722816453ae0af2cd5646458James Dong notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 1851700744ae0ce2fcf722816453ae0af2cd5646458James Dong return errType; 1861700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 1871700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1881700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (!PVInitVideoEncoder(mHandle, mEncParams)) { 1891700744ae0ce2fcf722816453ae0af2cd5646458James Dong ALOGE("Failed to initialize the encoder"); 1901700744ae0ce2fcf722816453ae0af2cd5646458James Dong mSignalledError = true; 1911700744ae0ce2fcf722816453ae0af2cd5646458James Dong notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 1921700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 1931700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 1941700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1951700744ae0ce2fcf722816453ae0af2cd5646458James Dong mNumInputFrames = -1; // 1st buffer for codec specific data 1961700744ae0ce2fcf722816453ae0af2cd5646458James Dong mStarted = true; 1971700744ae0ce2fcf722816453ae0af2cd5646458James Dong 1981700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorNone; 1991700744ae0ce2fcf722816453ae0af2cd5646458James Dong} 2001700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2011700744ae0ce2fcf722816453ae0af2cd5646458James DongOMX_ERRORTYPE SoftMPEG4Encoder::releaseEncoder() { 2025443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim if (mEncParams) { 2035443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim delete mEncParams; 2045443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim mEncParams = NULL; 2051700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 2061700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2075443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim if (mHandle) { 2085443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim delete mHandle; 2095443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim mHandle = NULL; 2105443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim } 2111700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2121700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorNone; 2131700744ae0ce2fcf722816453ae0af2cd5646458James Dong} 2141700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2151700744ae0ce2fcf722816453ae0af2cd5646458James DongOMX_ERRORTYPE SoftMPEG4Encoder::internalGetParameter( 2161700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_INDEXTYPE index, OMX_PTR params) { 2171700744ae0ce2fcf722816453ae0af2cd5646458James Dong switch (index) { 2181700744ae0ce2fcf722816453ae0af2cd5646458James Dong case OMX_IndexParamVideoBitrate: 2191700744ae0ce2fcf722816453ae0af2cd5646458James Dong { 2201700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_VIDEO_PARAM_BITRATETYPE *bitRate = 2211700744ae0ce2fcf722816453ae0af2cd5646458James Dong (OMX_VIDEO_PARAM_BITRATETYPE *) params; 2221700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2232720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen if (!isValidOMXParam(bitRate)) { 2242720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen return OMX_ErrorBadParameter; 2252720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen } 2262720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen 2271700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (bitRate->nPortIndex != 1) { 2281700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 2291700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 2301700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2311700744ae0ce2fcf722816453ae0af2cd5646458James Dong bitRate->eControlRate = OMX_Video_ControlRateVariable; 232a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar bitRate->nTargetBitrate = mBitrate; 2331700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorNone; 2341700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 2351700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2361700744ae0ce2fcf722816453ae0af2cd5646458James Dong case OMX_IndexParamVideoH263: 2371700744ae0ce2fcf722816453ae0af2cd5646458James Dong { 2381700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_VIDEO_PARAM_H263TYPE *h263type = 2391700744ae0ce2fcf722816453ae0af2cd5646458James Dong (OMX_VIDEO_PARAM_H263TYPE *)params; 2401700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2412720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen if (!isValidOMXParam(h263type)) { 2422720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen return OMX_ErrorBadParameter; 2432720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen } 2442720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen 2451700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (h263type->nPortIndex != 1) { 2461700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 2471700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 2481700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2491700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->nAllowedPictureTypes = 2501700744ae0ce2fcf722816453ae0af2cd5646458James Dong (OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP); 2511700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->eProfile = OMX_VIDEO_H263ProfileBaseline; 2521700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->eLevel = OMX_VIDEO_H263Level45; 2531700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->bPLUSPTYPEAllowed = OMX_FALSE; 2541700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->bForceRoundingTypeToZero = OMX_FALSE; 2551700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->nPictureHeaderRepetition = 0; 2561700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->nGOBHeaderInterval = 0; 2571700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2581700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorNone; 2591700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 2601700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2611700744ae0ce2fcf722816453ae0af2cd5646458James Dong case OMX_IndexParamVideoMpeg4: 2621700744ae0ce2fcf722816453ae0af2cd5646458James Dong { 2631700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_VIDEO_PARAM_MPEG4TYPE *mpeg4type = 2641700744ae0ce2fcf722816453ae0af2cd5646458James Dong (OMX_VIDEO_PARAM_MPEG4TYPE *)params; 2651700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2662720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen if (!isValidOMXParam(mpeg4type)) { 2672720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen return OMX_ErrorBadParameter; 2682720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen } 2692720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen 2701700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (mpeg4type->nPortIndex != 1) { 2711700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 2721700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 2731700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2741700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->eProfile = OMX_VIDEO_MPEG4ProfileCore; 2751700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->eLevel = OMX_VIDEO_MPEG4Level2; 2761700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nAllowedPictureTypes = 2771700744ae0ce2fcf722816453ae0af2cd5646458James Dong (OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP); 2781700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nBFrames = 0; 2791700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nIDCVLCThreshold = 0; 2801700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->bACPred = OMX_TRUE; 2811700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nMaxPacketSize = 256; 2821700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nTimeIncRes = 1000; 2831700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nHeaderExtension = 0; 2841700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->bReversibleVLC = OMX_FALSE; 2851700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2861700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorNone; 2871700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 2881700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2891700744ae0ce2fcf722816453ae0af2cd5646458James Dong default: 290a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar return SoftVideoEncoderOMXComponent::internalGetParameter(index, params); 2911700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 2921700744ae0ce2fcf722816453ae0af2cd5646458James Dong} 2931700744ae0ce2fcf722816453ae0af2cd5646458James Dong 2941700744ae0ce2fcf722816453ae0af2cd5646458James DongOMX_ERRORTYPE SoftMPEG4Encoder::internalSetParameter( 2951700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_INDEXTYPE index, const OMX_PTR params) { 296bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala int32_t indexFull = index; 297bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala 298bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala switch (indexFull) { 2991700744ae0ce2fcf722816453ae0af2cd5646458James Dong case OMX_IndexParamVideoBitrate: 3001700744ae0ce2fcf722816453ae0af2cd5646458James Dong { 3011700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_VIDEO_PARAM_BITRATETYPE *bitRate = 3021700744ae0ce2fcf722816453ae0af2cd5646458James Dong (OMX_VIDEO_PARAM_BITRATETYPE *) params; 3031700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3042720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen if (!isValidOMXParam(bitRate)) { 3052720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen return OMX_ErrorBadParameter; 3062720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen } 3072720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen 3081700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (bitRate->nPortIndex != 1 || 3091700744ae0ce2fcf722816453ae0af2cd5646458James Dong bitRate->eControlRate != OMX_Video_ControlRateVariable) { 3101700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 3111700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3121700744ae0ce2fcf722816453ae0af2cd5646458James Dong 313a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mBitrate = bitRate->nTargetBitrate; 3141700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorNone; 3151700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3161700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3171700744ae0ce2fcf722816453ae0af2cd5646458James Dong case OMX_IndexParamVideoH263: 3181700744ae0ce2fcf722816453ae0af2cd5646458James Dong { 3191700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_VIDEO_PARAM_H263TYPE *h263type = 3201700744ae0ce2fcf722816453ae0af2cd5646458James Dong (OMX_VIDEO_PARAM_H263TYPE *)params; 3211700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3222720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen if (!isValidOMXParam(h263type)) { 3232720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen return OMX_ErrorBadParameter; 3242720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen } 3252720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen 3261700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (h263type->nPortIndex != 1) { 3271700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 3281700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3291700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3301700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (h263type->eProfile != OMX_VIDEO_H263ProfileBaseline || 3311700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->eLevel != OMX_VIDEO_H263Level45 || 3321700744ae0ce2fcf722816453ae0af2cd5646458James Dong (h263type->nAllowedPictureTypes & OMX_VIDEO_PictureTypeB) || 3331700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->bPLUSPTYPEAllowed != OMX_FALSE || 3341700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->bForceRoundingTypeToZero != OMX_FALSE || 3351700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->nPictureHeaderRepetition != 0 || 3361700744ae0ce2fcf722816453ae0af2cd5646458James Dong h263type->nGOBHeaderInterval != 0) { 3371700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 3381700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3391700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3401700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorNone; 3411700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3421700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3431700744ae0ce2fcf722816453ae0af2cd5646458James Dong case OMX_IndexParamVideoMpeg4: 3441700744ae0ce2fcf722816453ae0af2cd5646458James Dong { 3451700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_VIDEO_PARAM_MPEG4TYPE *mpeg4type = 3461700744ae0ce2fcf722816453ae0af2cd5646458James Dong (OMX_VIDEO_PARAM_MPEG4TYPE *)params; 3471700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3482720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen if (!isValidOMXParam(mpeg4type)) { 3492720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen return OMX_ErrorBadParameter; 3502720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen } 3512720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen 3521700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (mpeg4type->nPortIndex != 1) { 3531700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 3541700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3551700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3561700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (mpeg4type->eProfile != OMX_VIDEO_MPEG4ProfileCore || 3571700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->eLevel != OMX_VIDEO_MPEG4Level2 || 3581700744ae0ce2fcf722816453ae0af2cd5646458James Dong (mpeg4type->nAllowedPictureTypes & OMX_VIDEO_PictureTypeB) || 3591700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nBFrames != 0 || 3601700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nIDCVLCThreshold != 0 || 3611700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->bACPred != OMX_TRUE || 3621700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nMaxPacketSize != 256 || 3631700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nTimeIncRes != 1000 || 3641700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->nHeaderExtension != 0 || 3651700744ae0ce2fcf722816453ae0af2cd5646458James Dong mpeg4type->bReversibleVLC != OMX_FALSE) { 3661700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorUndefined; 3671700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3681700744ae0ce2fcf722816453ae0af2cd5646458James Dong 369d72e751fa185f053773603222fd220ab77c92b2fLajos Molnar mKeyFrameInterval = int32_t(mpeg4type->nPFrames + 1); 370d72e751fa185f053773603222fd220ab77c92b2fLajos Molnar 3711700744ae0ce2fcf722816453ae0af2cd5646458James Dong return OMX_ErrorNone; 3721700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3731700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3741700744ae0ce2fcf722816453ae0af2cd5646458James Dong default: 375a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar return SoftVideoEncoderOMXComponent::internalSetParameter(index, params); 3761700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3771700744ae0ce2fcf722816453ae0af2cd5646458James Dong} 3781700744ae0ce2fcf722816453ae0af2cd5646458James Dong 37984333e0475bc911adc16417f4ca327c975cf6c36Andreas Hubervoid SoftMPEG4Encoder::onQueueFilled(OMX_U32 /* portIndex */) { 3801700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (mSignalledError || mSawInputEOS) { 3811700744ae0ce2fcf722816453ae0af2cd5646458James Dong return; 3821700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3831700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3841700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (!mStarted) { 3851700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (OMX_ErrorNone != initEncoder()) { 3861700744ae0ce2fcf722816453ae0af2cd5646458James Dong return; 3871700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3881700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 3891700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3901700744ae0ce2fcf722816453ae0af2cd5646458James Dong List<BufferInfo *> &inQueue = getPortQueue(0); 3911700744ae0ce2fcf722816453ae0af2cd5646458James Dong List<BufferInfo *> &outQueue = getPortQueue(1); 3921700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3931700744ae0ce2fcf722816453ae0af2cd5646458James Dong while (!mSawInputEOS && !inQueue.empty() && !outQueue.empty()) { 3941700744ae0ce2fcf722816453ae0af2cd5646458James Dong BufferInfo *inInfo = *inQueue.begin(); 3951700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader; 3961700744ae0ce2fcf722816453ae0af2cd5646458James Dong BufferInfo *outInfo = *outQueue.begin(); 3971700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; 3981700744ae0ce2fcf722816453ae0af2cd5646458James Dong 3991700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nTimeStamp = 0; 4001700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nFlags = 0; 4011700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nOffset = 0; 4021700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nFilledLen = 0; 4031700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nOffset = 0; 4041700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4051700744ae0ce2fcf722816453ae0af2cd5646458James Dong uint8_t *outPtr = (uint8_t *) outHeader->pBuffer; 4061700744ae0ce2fcf722816453ae0af2cd5646458James Dong int32_t dataLength = outHeader->nAllocLen; 4071700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4081700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (mNumInputFrames < 0) { 4091700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (!PVGetVolHeader(mHandle, outPtr, &dataLength, 0)) { 4101700744ae0ce2fcf722816453ae0af2cd5646458James Dong ALOGE("Failed to get VOL header"); 4111700744ae0ce2fcf722816453ae0af2cd5646458James Dong mSignalledError = true; 4121700744ae0ce2fcf722816453ae0af2cd5646458James Dong notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 4131700744ae0ce2fcf722816453ae0af2cd5646458James Dong return; 4141700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 4151700744ae0ce2fcf722816453ae0af2cd5646458James Dong ALOGV("Output VOL header: %d bytes", dataLength); 4161700744ae0ce2fcf722816453ae0af2cd5646458James Dong ++mNumInputFrames; 4171700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nFlags |= OMX_BUFFERFLAG_CODECCONFIG; 4181700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nFilledLen = dataLength; 4191700744ae0ce2fcf722816453ae0af2cd5646458James Dong outQueue.erase(outQueue.begin()); 4201700744ae0ce2fcf722816453ae0af2cd5646458James Dong outInfo->mOwnedByUs = false; 4211700744ae0ce2fcf722816453ae0af2cd5646458James Dong notifyFillBufferDone(outHeader); 4221700744ae0ce2fcf722816453ae0af2cd5646458James Dong return; 4231700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 4241700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4251700744ae0ce2fcf722816453ae0af2cd5646458James Dong // Save the input buffer info so that it can be 4261700744ae0ce2fcf722816453ae0af2cd5646458James Dong // passed to an output buffer 4271700744ae0ce2fcf722816453ae0af2cd5646458James Dong InputBufferInfo info; 4281700744ae0ce2fcf722816453ae0af2cd5646458James Dong info.mTimeUs = inHeader->nTimeStamp; 4291700744ae0ce2fcf722816453ae0af2cd5646458James Dong info.mFlags = inHeader->nFlags; 4301700744ae0ce2fcf722816453ae0af2cd5646458James Dong mInputBufferInfoVec.push(info); 4311700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4321700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) { 4331700744ae0ce2fcf722816453ae0af2cd5646458James Dong mSawInputEOS = true; 4341700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 4351700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4361700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (inHeader->nFilledLen > 0) { 4374e091c66df549e51944f64f67200682f6b786a24Dongwon Kang OMX_ERRORTYPE error = validateInputBuffer(inHeader); 4384e091c66df549e51944f64f67200682f6b786a24Dongwon Kang if (error != OMX_ErrorNone) { 4394e091c66df549e51944f64f67200682f6b786a24Dongwon Kang ALOGE("b/69065651"); 4404e091c66df549e51944f64f67200682f6b786a24Dongwon Kang android_errorWriteLog(0x534e4554, "69065651"); 4414e091c66df549e51944f64f67200682f6b786a24Dongwon Kang mSignalledError = true; 4424e091c66df549e51944f64f67200682f6b786a24Dongwon Kang notify(OMX_EventError, error, 0, 0); 4434e091c66df549e51944f64f67200682f6b786a24Dongwon Kang return; 4444e091c66df549e51944f64f67200682f6b786a24Dongwon Kang } 4452edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar const uint8_t *inputData = NULL; 446a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar if (mInputDataIsMeta) { 447bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala inputData = 4482edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar extractGraphicBuffer( 449a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mInputFrameData, (mWidth * mHeight * 3) >> 1, 4502edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar inHeader->pBuffer + inHeader->nOffset, inHeader->nFilledLen, 451a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mWidth, mHeight); 452bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala if (inputData == NULL) { 453bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala ALOGE("Unable to extract gralloc buffer in metadata mode"); 454bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala mSignalledError = true; 455bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 456bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala return; 457bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala } 458bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala } else { 4592edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar inputData = (const uint8_t *)inHeader->pBuffer + inHeader->nOffset; 460a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar if (mColorFormat != OMX_COLOR_FormatYUV420Planar) { 4612edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar ConvertYUV420SemiPlanarToYUV420Planar( 462a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar inputData, mInputFrameData, mWidth, mHeight); 4632edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar inputData = mInputFrameData; 4642edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar } 465bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala } 466bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala 4671700744ae0ce2fcf722816453ae0af2cd5646458James Dong CHECK(inputData != NULL); 4681700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4691700744ae0ce2fcf722816453ae0af2cd5646458James Dong VideoEncFrameIO vin, vout; 4701700744ae0ce2fcf722816453ae0af2cd5646458James Dong memset(&vin, 0, sizeof(vin)); 4711700744ae0ce2fcf722816453ae0af2cd5646458James Dong memset(&vout, 0, sizeof(vout)); 472a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar vin.height = align(mHeight, 16); 473a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar vin.pitch = align(mWidth, 16); 4741700744ae0ce2fcf722816453ae0af2cd5646458James Dong vin.timestamp = (inHeader->nTimeStamp + 500) / 1000; // in ms 4752edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar vin.yChan = (uint8_t *)inputData; 4761700744ae0ce2fcf722816453ae0af2cd5646458James Dong vin.uChan = vin.yChan + vin.height * vin.pitch; 4771700744ae0ce2fcf722816453ae0af2cd5646458James Dong vin.vChan = vin.uChan + ((vin.height * vin.pitch) >> 2); 4781700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4792426d11f795a99de85999b3ff0a26cc070a99a59Ashok Bhat ULong modTimeMs = 0; 4801700744ae0ce2fcf722816453ae0af2cd5646458James Dong int32_t nLayer = 0; 4811700744ae0ce2fcf722816453ae0af2cd5646458James Dong MP4HintTrack hintTrack; 4821700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (!PVEncodeVideoFrame(mHandle, &vin, &vout, 4831700744ae0ce2fcf722816453ae0af2cd5646458James Dong &modTimeMs, outPtr, &dataLength, &nLayer) || 4841700744ae0ce2fcf722816453ae0af2cd5646458James Dong !PVGetHintTrack(mHandle, &hintTrack)) { 485b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross ALOGE("Failed to encode frame or get hink track at frame %" PRId64, 4861700744ae0ce2fcf722816453ae0af2cd5646458James Dong mNumInputFrames); 4871700744ae0ce2fcf722816453ae0af2cd5646458James Dong mSignalledError = true; 4881700744ae0ce2fcf722816453ae0af2cd5646458James Dong notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 4891700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 4901700744ae0ce2fcf722816453ae0af2cd5646458James Dong CHECK(NULL == PVGetOverrunBuffer(mHandle)); 4911700744ae0ce2fcf722816453ae0af2cd5646458James Dong if (hintTrack.CodeType == 0) { // I-frame serves as sync frame 4921700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; 4931700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 4941700744ae0ce2fcf722816453ae0af2cd5646458James Dong 4951700744ae0ce2fcf722816453ae0af2cd5646458James Dong ++mNumInputFrames; 4961700744ae0ce2fcf722816453ae0af2cd5646458James Dong } else { 4971700744ae0ce2fcf722816453ae0af2cd5646458James Dong dataLength = 0; 4981700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 4991700744ae0ce2fcf722816453ae0af2cd5646458James Dong 5001700744ae0ce2fcf722816453ae0af2cd5646458James Dong inQueue.erase(inQueue.begin()); 5011700744ae0ce2fcf722816453ae0af2cd5646458James Dong inInfo->mOwnedByUs = false; 5021700744ae0ce2fcf722816453ae0af2cd5646458James Dong notifyEmptyBufferDone(inHeader); 5031700744ae0ce2fcf722816453ae0af2cd5646458James Dong 5041700744ae0ce2fcf722816453ae0af2cd5646458James Dong outQueue.erase(outQueue.begin()); 5051700744ae0ce2fcf722816453ae0af2cd5646458James Dong CHECK(!mInputBufferInfoVec.empty()); 5061700744ae0ce2fcf722816453ae0af2cd5646458James Dong InputBufferInfo *inputBufInfo = mInputBufferInfoVec.begin(); 5071700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nTimeStamp = inputBufInfo->mTimeUs; 5081700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nFlags |= (inputBufInfo->mFlags | OMX_BUFFERFLAG_ENDOFFRAME); 5091700744ae0ce2fcf722816453ae0af2cd5646458James Dong outHeader->nFilledLen = dataLength; 5106e5b6ef15bb39cc0aa3d8fb7d4f75d44e5aadd92Jun Tian mInputBufferInfoVec.erase(mInputBufferInfoVec.begin()); 5111700744ae0ce2fcf722816453ae0af2cd5646458James Dong outInfo->mOwnedByUs = false; 5121700744ae0ce2fcf722816453ae0af2cd5646458James Dong notifyFillBufferDone(outHeader); 5131700744ae0ce2fcf722816453ae0af2cd5646458James Dong } 5141700744ae0ce2fcf722816453ae0af2cd5646458James Dong} 5151700744ae0ce2fcf722816453ae0af2cd5646458James Dong 5165443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kimvoid SoftMPEG4Encoder::onReset() { 5175443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim if (!mStarted) { 5185443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim return; 5195443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim } 5205443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim 5215443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim PVCleanUpVideoEncoder(mHandle); 5225443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim 5235443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim free(mInputFrameData); 5245443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim mInputFrameData = NULL; 5255443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim 5265443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim mStarted = false; 5275443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim} 5285443b57cc54f2e46b35246637be26a69e9f493e1Wonsik Kim 5291700744ae0ce2fcf722816453ae0af2cd5646458James Dong} // namespace android 5301700744ae0ce2fcf722816453ae0af2cd5646458James Dong 5311700744ae0ce2fcf722816453ae0af2cd5646458James Dongandroid::SoftOMXComponent *createSoftOMXComponent( 5321700744ae0ce2fcf722816453ae0af2cd5646458James Dong const char *name, const OMX_CALLBACKTYPE *callbacks, 5331700744ae0ce2fcf722816453ae0af2cd5646458James Dong OMX_PTR appData, OMX_COMPONENTTYPE **component) { 534a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar using namespace android; 535a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar if (!strcmp(name, "OMX.google.h263.encoder")) { 536a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar return new android::SoftMPEG4Encoder( 537a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar name, "video_encoder.h263", OMX_VIDEO_CodingH263, MEDIA_MIMETYPE_VIDEO_H263, 538a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar kH263ProfileLevels, NELEM(kH263ProfileLevels), 539a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar callbacks, appData, component); 540a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar } else if (!strcmp(name, "OMX.google.mpeg4.encoder")) { 541a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar return new android::SoftMPEG4Encoder( 542a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar name, "video_encoder.mpeg4", OMX_VIDEO_CodingMPEG4, MEDIA_MIMETYPE_VIDEO_MPEG4, 543a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar kMPEG4ProfileLevels, NELEM(kMPEG4ProfileLevels), 544a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar callbacks, appData, component); 545a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar } else { 546a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar CHECK(!"Unknown component"); 547a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar } 548a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar return NULL; 5491700744ae0ce2fcf722816453ae0af2cd5646458James Dong} 550