15c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong/* 25c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong * Copyright (C) 2012 The Android Open Source Project 35c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong * 45c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong * Licensed under the Apache License, Version 2.0 (the "License"); 55c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong * you may not use this file except in compliance with the License. 65c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong * You may obtain a copy of the License at 75c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong * 85c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong * http://www.apache.org/licenses/LICENSE-2.0 95c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong * 105c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong * Unless required by applicable law or agreed to in writing, software 115c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong * distributed under the License is distributed on an "AS IS" BASIS, 125c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong * See the License for the specific language governing permissions and 145c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong * limitations under the License. 155c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong */ 165c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 175c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong//#define LOG_NDEBUG 0 185c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong#define LOG_TAG "SoftAVCEncoder" 195c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong#include <utils/Log.h> 20a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar#include <utils/misc.h> 215c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 225c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong#include "avcenc_api.h" 235c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong#include "avcenc_int.h" 245c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong#include "OMX_Video.h" 255c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 26bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala#include <HardwareAPI.h> 27bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala#include <MetadataBufferType.h> 285c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong#include <media/stagefright/foundation/ADebug.h> 29a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar#include <media/stagefright/foundation/AUtils.h> 305c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong#include <media/stagefright/MediaDefs.h> 315c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong#include <media/stagefright/MediaErrors.h> 325c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong#include <media/stagefright/MetaData.h> 335c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong#include <media/stagefright/Utils.h> 34bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala#include <ui/Rect.h> 35bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala#include <ui/GraphicBufferMapper.h> 365c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 375c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong#include "SoftAVCEncoder.h" 385c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3984333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#if LOG_NDEBUG 4084333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#define UNUSED_UNLESS_VERBOSE(x) (void)(x) 4184333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#else 4284333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#define UNUSED_UNLESS_VERBOSE(x) 4384333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#endif 4484333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber 455c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongnamespace android { 465c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 475c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongtemplate<class T> 485c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongstatic void InitOMXParams(T *params) { 495c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong params->nSize = sizeof(T); 505c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong params->nVersion.s.nVersionMajor = 1; 515c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong params->nVersion.s.nVersionMinor = 0; 525c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong params->nVersion.s.nRevision = 0; 535c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong params->nVersion.s.nStep = 0; 545c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 555c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 56a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnarstatic const CodecProfileLevel kProfileLevels[] = { 57a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel2 }, 58a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar}; 59a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar 605c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongtypedef struct LevelConversion { 615c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_U32 omxLevel; 625c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong AVCLevel avcLevel; 63a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar uint32_t maxMacroBlocks; 645c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} LevelConcersion; 655c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 665c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongstatic LevelConversion ConversionTable[] = { 67a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar { OMX_VIDEO_AVCLevel1, AVC_LEVEL1_B, 99 }, 68a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar { OMX_VIDEO_AVCLevel1b, AVC_LEVEL1, 99 }, 69a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar { OMX_VIDEO_AVCLevel11, AVC_LEVEL1_1, 396 }, 70a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar { OMX_VIDEO_AVCLevel12, AVC_LEVEL1_2, 396 }, 71a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar { OMX_VIDEO_AVCLevel13, AVC_LEVEL1_3, 396 }, 72a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar { OMX_VIDEO_AVCLevel2, AVC_LEVEL2, 396 }, 735c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong#if 0 74a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar // encoding speed is very poor if video resolution 75a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar // is higher than CIF or if level is higher than 2 76a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar { OMX_VIDEO_AVCLevel21, AVC_LEVEL2_1, 792 }, 77a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar { OMX_VIDEO_AVCLevel22, AVC_LEVEL2_2, 1620 }, 78a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar { OMX_VIDEO_AVCLevel3, AVC_LEVEL3, 1620 }, 79a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar { OMX_VIDEO_AVCLevel31, AVC_LEVEL3_1, 3600 }, 80a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar { OMX_VIDEO_AVCLevel32, AVC_LEVEL3_2, 5120 }, 81a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar { OMX_VIDEO_AVCLevel4, AVC_LEVEL4, 8192 }, 82a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar { OMX_VIDEO_AVCLevel41, AVC_LEVEL4_1, 8192 }, 83a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar { OMX_VIDEO_AVCLevel42, AVC_LEVEL4_2, 8704 }, 84a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar { OMX_VIDEO_AVCLevel5, AVC_LEVEL5, 22080 }, 85a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar { OMX_VIDEO_AVCLevel51, AVC_LEVEL5_1, 36864 }, 865c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong#endif 875c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong}; 885c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 895c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongstatic status_t ConvertOmxAvcLevelToAvcSpecLevel( 905c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_U32 omxLevel, AVCLevel *avcLevel) { 915c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong for (size_t i = 0, n = sizeof(ConversionTable)/sizeof(ConversionTable[0]); 925c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong i < n; ++i) { 935c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (omxLevel == ConversionTable[i].omxLevel) { 945c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong *avcLevel = ConversionTable[i].avcLevel; 955c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OK; 965c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 975c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 985c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 995c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ALOGE("ConvertOmxAvcLevelToAvcSpecLevel: %d level not supported", 1005c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong (int32_t)omxLevel); 1015c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 1025c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return BAD_VALUE; 1035c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 1045c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 1055c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongstatic status_t ConvertAvcSpecLevelToOmxAvcLevel( 1065c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong AVCLevel avcLevel, OMX_U32 *omxLevel) { 1075c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong for (size_t i = 0, n = sizeof(ConversionTable)/sizeof(ConversionTable[0]); 1085c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong i < n; ++i) { 1095c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (avcLevel == ConversionTable[i].avcLevel) { 1105c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong *omxLevel = ConversionTable[i].omxLevel; 1115c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OK; 1125c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 1135c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 1145c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 1155c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ALOGE("ConvertAvcSpecLevelToOmxAvcLevel: %d level not supported", 1165c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong (int32_t) avcLevel); 1175c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 1185c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return BAD_VALUE; 1195c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 1205c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 12123da4cf305b9bfff07954711a8a2d9ec040865afMartin Storsjostatic void* MallocWrapper( 12284333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber void * /* userData */, int32_t size, int32_t /* attrs */) { 123359d8fcd30ff0a8390e4c5560d53ec55a4cc5bcdMartin Storsjo void *ptr = malloc(size); 124359d8fcd30ff0a8390e4c5560d53ec55a4cc5bcdMartin Storsjo if (ptr) 125359d8fcd30ff0a8390e4c5560d53ec55a4cc5bcdMartin Storsjo memset(ptr, 0, size); 126359d8fcd30ff0a8390e4c5560d53ec55a4cc5bcdMartin Storsjo return ptr; 1275c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 1285c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 12984333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatic void FreeWrapper(void * /* userData */, void* ptr) { 13023da4cf305b9bfff07954711a8a2d9ec040865afMartin Storsjo free(ptr); 1315c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 1325c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 1335c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongstatic int32_t DpbAllocWrapper(void *userData, 1345c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong unsigned int sizeInMbs, unsigned int numBuffers) { 1355c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong SoftAVCEncoder *encoder = static_cast<SoftAVCEncoder *>(userData); 1365c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(encoder != NULL); 1375c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return encoder->allocOutputBuffers(sizeInMbs, numBuffers); 1385c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 1395c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 1405c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongstatic int32_t BindFrameWrapper( 1415c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong void *userData, int32_t index, uint8_t **yuv) { 1425c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong SoftAVCEncoder *encoder = static_cast<SoftAVCEncoder *>(userData); 1435c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(encoder != NULL); 1445c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return encoder->bindOutputBuffer(index, yuv); 1455c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 1465c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 1475c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongstatic void UnbindFrameWrapper(void *userData, int32_t index) { 1485c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong SoftAVCEncoder *encoder = static_cast<SoftAVCEncoder *>(userData); 1495c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(encoder != NULL); 1505c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return encoder->unbindOutputBuffer(index); 1515c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 1525c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 1535c61b361d1c55a93a215cfb2c325b4987f57f1c5James DongSoftAVCEncoder::SoftAVCEncoder( 1545c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong const char *name, 1555c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong const OMX_CALLBACKTYPE *callbacks, 1565c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_PTR appData, 1575c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_COMPONENTTYPE **component) 158a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar : SoftVideoEncoderOMXComponent( 159a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar name, "video_encoder.avc", OMX_VIDEO_CodingAVC, 160a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar kProfileLevels, NELEM(kProfileLevels), 161a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar 176 /* width */, 144 /* height */, 162a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar callbacks, appData, component), 1635c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mIDRFrameRefreshIntervalInSec(1), 1645c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mAVCEncProfile(AVC_BASELINE), 1655c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mAVCEncLevel(AVC_LEVEL2), 1665c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mNumInputFrames(-1), 1675c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mPrevTimestampUs(-1), 1685c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mStarted(false), 1695c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mSawInputEOS(false), 1705c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mSignalledError(false), 1715c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mHandle(new tagAVCHandle), 1725c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams(new tagAVCEncParam), 1735c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mInputFrameData(NULL), 1745c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mSliceGroup(NULL) { 1755c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 176a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar const size_t kOutputBufferSize = 177a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar 320 * ConversionTable[NELEM(ConversionTable) - 1].maxMacroBlocks; 178a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar 179a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar initPorts( 180a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar kNumBuffers, kNumBuffers, kOutputBufferSize, 181a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar MEDIA_MIMETYPE_VIDEO_AVC, 2 /* minCompressionRatio */); 182a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar 1835c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ALOGI("Construct SoftAVCEncoder"); 1845c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 1855c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 1865c61b361d1c55a93a215cfb2c325b4987f57f1c5James DongSoftAVCEncoder::~SoftAVCEncoder() { 1875c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ALOGV("Destruct SoftAVCEncoder"); 1885c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong releaseEncoder(); 1895c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong List<BufferInfo *> &outQueue = getPortQueue(1); 1905c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong List<BufferInfo *> &inQueue = getPortQueue(0); 1915c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(outQueue.empty()); 1925c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(inQueue.empty()); 1935c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 1945c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 1955c61b361d1c55a93a215cfb2c325b4987f57f1c5James DongOMX_ERRORTYPE SoftAVCEncoder::initEncParams() { 1965c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(mHandle != NULL); 1975c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong memset(mHandle, 0, sizeof(tagAVCHandle)); 1985c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mHandle->AVCObject = NULL; 1995c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mHandle->userData = this; 2005c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mHandle->CBAVC_DPBAlloc = DpbAllocWrapper; 2015c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mHandle->CBAVC_FrameBind = BindFrameWrapper; 2025c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mHandle->CBAVC_FrameUnbind = UnbindFrameWrapper; 2035c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mHandle->CBAVC_Malloc = MallocWrapper; 2045c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mHandle->CBAVC_Free = FreeWrapper; 2055c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 2065c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(mEncParams != NULL); 20784333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber memset(mEncParams, 0, sizeof(*mEncParams)); 2085c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->rate_control = AVC_ON; 2095c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->initQP = 0; 2105c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->init_CBP_removal_delay = 1600; 2115c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 2125c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->intramb_refresh = 0; 2135c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->auto_scd = AVC_ON; 2145c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->out_of_band_param_set = AVC_ON; 2155c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->poc_type = 2; 2165c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->log2_max_poc_lsb_minus_4 = 12; 2175c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->delta_poc_zero_flag = 0; 2185c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->offset_poc_non_ref = 0; 2195c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->offset_top_bottom = 0; 2205c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->num_ref_in_cycle = 0; 2215c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->offset_poc_ref = NULL; 2225c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 2235c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->num_ref_frame = 1; 2245c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->num_slice_group = 1; 2255c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->fmo_type = 0; 2265c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 2275c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->db_filter = AVC_ON; 2285c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->disable_db_idc = 0; 2295c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 2305c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->alpha_offset = 0; 2315c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->beta_offset = 0; 2325c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->constrained_intra_pred = AVC_OFF; 2335c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 2345c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->data_par = AVC_OFF; 2355c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->fullsearch = AVC_OFF; 2365c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->search_range = 16; 2375c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->sub_pel = AVC_OFF; 2385c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->submb_pred = AVC_OFF; 2395c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->rdopt_mode = AVC_OFF; 2405c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->bidir_pred = AVC_OFF; 2415c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 2425c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->use_overrun_buffer = AVC_OFF; 2435c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 244a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar if (mColorFormat != OMX_COLOR_FormatYUV420Planar || mInputDataIsMeta) { 2455c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // Color conversion is needed. 2462edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar free(mInputFrameData); 24791860b89488b3ee4644c539e89e657fbb79fb6adWei Jia if (((uint64_t)mWidth * mHeight) > ((uint64_t)INT32_MAX / 3)) { 248479b4de0d267eb7d4c419f4da0069186a952ad17Wei Jia ALOGE("Buffer size is too big."); 249479b4de0d267eb7d4c419f4da0069186a952ad17Wei Jia return OMX_ErrorUndefined; 250479b4de0d267eb7d4c419f4da0069186a952ad17Wei Jia } 2515c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mInputFrameData = 252a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar (uint8_t *) malloc((mWidth * mHeight * 3 ) >> 1); 2535c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(mInputFrameData != NULL); 2545c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 2555c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 2565c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // PV's AVC encoder requires the video dimension of multiple 257a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar if (mWidth % 16 != 0 || mHeight % 16 != 0) { 2585c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ALOGE("Video frame size %dx%d must be a multiple of 16", 259a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mWidth, mHeight); 2605c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorBadParameter; 2615c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 2625c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 263a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mEncParams->width = mWidth; 264a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mEncParams->height = mHeight; 265a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mEncParams->bitrate = mBitrate; 266a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mEncParams->frame_rate = (1000 * mFramerate) >> 16; // In frames/ms!, mFramerate is in Q16 267a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mEncParams->CPB_size = (uint32_t) (mBitrate >> 1); 2685c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 269a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar int32_t nMacroBlocks = divUp(mWidth, 16) * divUp(mHeight, 16); 2705c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(mSliceGroup == NULL); 27138eff9af5c032bf12f89d6e94df05f65eef51afcWei Jia if ((size_t)nMacroBlocks > SIZE_MAX / sizeof(uint32_t)) { 272479b4de0d267eb7d4c419f4da0069186a952ad17Wei Jia ALOGE("requested memory size is too big."); 273479b4de0d267eb7d4c419f4da0069186a952ad17Wei Jia return OMX_ErrorUndefined; 274479b4de0d267eb7d4c419f4da0069186a952ad17Wei Jia } 2755c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mSliceGroup = (uint32_t *) malloc(sizeof(uint32_t) * nMacroBlocks); 2765c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(mSliceGroup != NULL); 2775c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong for (int ii = 0, idx = 0; ii < nMacroBlocks; ++ii) { 2785c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mSliceGroup[ii] = idx++; 2795c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (idx >= mEncParams->num_slice_group) { 2805c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong idx = 0; 2815c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 2825c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 2835c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->slice_group = mSliceGroup; 2845c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 2855c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // Set IDR frame refresh interval 2865c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (mIDRFrameRefreshIntervalInSec < 0) { 2875c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->idr_period = -1; 2885c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } else if (mIDRFrameRefreshIntervalInSec == 0) { 2895c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->idr_period = 1; // All I frames 2905c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } else { 2915c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->idr_period = 292a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar (mIDRFrameRefreshIntervalInSec * mFramerate) >> 16; // mFramerate is in Q16 2935c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 2945c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 2955c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // Set profile and level 2965c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->profile = mAVCEncProfile; 2975c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->level = mAVCEncLevel; 2985c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 2995c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorNone; 3005c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 3015c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3025c61b361d1c55a93a215cfb2c325b4987f57f1c5James DongOMX_ERRORTYPE SoftAVCEncoder::initEncoder() { 3035c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(!mStarted); 3045c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3055c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_ERRORTYPE errType = OMX_ErrorNone; 3065c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (OMX_ErrorNone != (errType = initEncParams())) { 3075c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ALOGE("Failed to initialized encoder params"); 3085c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mSignalledError = true; 3095c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 3105c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return errType; 3115c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 3125c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3135c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong AVCEnc_Status err; 3145c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong err = PVAVCEncInitialize(mHandle, mEncParams, NULL, NULL); 3155c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (err != AVCENC_SUCCESS) { 3165c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ALOGE("Failed to initialize the encoder: %d", err); 3175c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mSignalledError = true; 3185c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 3195c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorUndefined; 3205c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 3215c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3225c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mNumInputFrames = -2; // 1st two buffers contain SPS and PPS 3235c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mSpsPpsHeaderReceived = false; 3245c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mReadyForNextFrame = true; 3255c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mIsIDRFrame = false; 3265c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mStarted = true; 3275c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3285c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorNone; 3295c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 3305c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3315c61b361d1c55a93a215cfb2c325b4987f57f1c5James DongOMX_ERRORTYPE SoftAVCEncoder::releaseEncoder() { 3325c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (!mStarted) { 3335c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorNone; 3345c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 3355c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3365c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong PVAVCCleanUpEncoder(mHandle); 3375c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong releaseOutputBuffers(); 3385c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 339a0c5812dfbb34c168129baa300942db18bed9f5eAshok Bhat free(mInputFrameData); 3405c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mInputFrameData = NULL; 3415c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 342a0c5812dfbb34c168129baa300942db18bed9f5eAshok Bhat free(mSliceGroup); 3435c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mSliceGroup = NULL; 3445c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3455c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong delete mEncParams; 3465c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams = NULL; 3475c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3485c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong delete mHandle; 3495c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mHandle = NULL; 3505c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3515c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mStarted = false; 3525c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3535c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorNone; 3545c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 3555c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3565c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongvoid SoftAVCEncoder::releaseOutputBuffers() { 3575c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong for (size_t i = 0; i < mOutputBuffers.size(); ++i) { 3585c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong MediaBuffer *buffer = mOutputBuffers.editItemAt(i); 3595c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong buffer->setObserver(NULL); 3605c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong buffer->release(); 3615c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 3625c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mOutputBuffers.clear(); 3635c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 3645c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3655c61b361d1c55a93a215cfb2c325b4987f57f1c5James DongOMX_ERRORTYPE SoftAVCEncoder::internalGetParameter( 3665c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_INDEXTYPE index, OMX_PTR params) { 3675c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong switch (index) { 3685c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong case OMX_IndexParamVideoBitrate: 3695c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong { 3705c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_VIDEO_PARAM_BITRATETYPE *bitRate = 3715c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong (OMX_VIDEO_PARAM_BITRATETYPE *) params; 3725c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3732720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen if (!isValidOMXParam(bitRate)) { 3742720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen return OMX_ErrorBadParameter; 3752720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen } 3762720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen 3775c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (bitRate->nPortIndex != 1) { 3785c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorUndefined; 3795c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 3805c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3815c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong bitRate->eControlRate = OMX_Video_ControlRateVariable; 382a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar bitRate->nTargetBitrate = mBitrate; 3835c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorNone; 3845c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 3855c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3865c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong case OMX_IndexParamVideoAvc: 3875c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong { 3885c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_VIDEO_PARAM_AVCTYPE *avcParams = 3895c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong (OMX_VIDEO_PARAM_AVCTYPE *)params; 3905c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3912720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen if (!isValidOMXParam(avcParams)) { 3922720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen return OMX_ErrorBadParameter; 3932720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen } 3942720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen 3955c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (avcParams->nPortIndex != 1) { 3965c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorUndefined; 3975c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 3985c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3995c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->eProfile = OMX_VIDEO_AVCProfileBaseline; 4005c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_U32 omxLevel = AVC_LEVEL2; 4015c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (OMX_ErrorNone != 4025c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ConvertAvcSpecLevelToOmxAvcLevel(mAVCEncLevel, &omxLevel)) { 4035c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorUndefined; 4045c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 4055c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4065c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->eLevel = (OMX_VIDEO_AVCLEVELTYPE) omxLevel; 4075c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->nRefFrames = 1; 4085c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->nBFrames = 0; 4095c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->bUseHadamard = OMX_TRUE; 4105c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->nAllowedPictureTypes = 4115c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong (OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP); 4125c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->nRefIdx10ActiveMinus1 = 0; 4135c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->nRefIdx11ActiveMinus1 = 0; 4145c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->bWeightedPPrediction = OMX_FALSE; 4155c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->bEntropyCodingCABAC = OMX_FALSE; 4165c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->bconstIpred = OMX_FALSE; 4175c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->bDirect8x8Inference = OMX_FALSE; 4185c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->bDirectSpatialTemporal = OMX_FALSE; 4195c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->nCabacInitIdc = 0; 4205c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorNone; 4215c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 4225c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4235c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong default: 424a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar return SoftVideoEncoderOMXComponent::internalGetParameter(index, params); 4255c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 4265c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 4275c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4285c61b361d1c55a93a215cfb2c325b4987f57f1c5James DongOMX_ERRORTYPE SoftAVCEncoder::internalSetParameter( 4295c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_INDEXTYPE index, const OMX_PTR params) { 430bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala int32_t indexFull = index; 431bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala 432bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala switch (indexFull) { 4335c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong case OMX_IndexParamVideoBitrate: 4345c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong { 4355c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_VIDEO_PARAM_BITRATETYPE *bitRate = 4365c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong (OMX_VIDEO_PARAM_BITRATETYPE *) params; 4375c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4382720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen if (!isValidOMXParam(bitRate)) { 4392720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen return OMX_ErrorBadParameter; 4402720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen } 4412720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen 4425c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (bitRate->nPortIndex != 1 || 4435c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong bitRate->eControlRate != OMX_Video_ControlRateVariable) { 4445c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorUndefined; 4455c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 4465c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 447a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mBitrate = bitRate->nTargetBitrate; 4485c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorNone; 4495c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 4505c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4515c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong case OMX_IndexParamVideoAvc: 4525c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong { 4535c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_VIDEO_PARAM_AVCTYPE *avcType = 4545c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong (OMX_VIDEO_PARAM_AVCTYPE *)params; 4555c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4562720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen if (!isValidOMXParam(avcType)) { 4572720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen return OMX_ErrorBadParameter; 4582720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen } 4592720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen 4605c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (avcType->nPortIndex != 1) { 4615c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorUndefined; 4625c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 4635c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4645c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // PV's AVC encoder only supports baseline profile 4655c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (avcType->eProfile != OMX_VIDEO_AVCProfileBaseline || 4665c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcType->nRefFrames != 1 || 4675c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcType->nBFrames != 0 || 4685c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcType->bUseHadamard != OMX_TRUE || 4695c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong (avcType->nAllowedPictureTypes & OMX_VIDEO_PictureTypeB) != 0 || 4705c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcType->nRefIdx10ActiveMinus1 != 0 || 4715c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcType->nRefIdx11ActiveMinus1 != 0 || 4725c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcType->bWeightedPPrediction != OMX_FALSE || 4735c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcType->bEntropyCodingCABAC != OMX_FALSE || 4745c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcType->bconstIpred != OMX_FALSE || 4755c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcType->bDirect8x8Inference != OMX_FALSE || 4765c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcType->bDirectSpatialTemporal != OMX_FALSE || 4775c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcType->nCabacInitIdc != 0) { 4785c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorUndefined; 4795c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 4805c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4815c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (OK != ConvertOmxAvcLevelToAvcSpecLevel(avcType->eLevel, &mAVCEncLevel)) { 4825c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorUndefined; 4835c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 4845c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4855c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorNone; 4865c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 4875c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4885c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong default: 489a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar return SoftVideoEncoderOMXComponent::internalSetParameter(index, params); 4905c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 4915c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 4925c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 49384333e0475bc911adc16417f4ca327c975cf6c36Andreas Hubervoid SoftAVCEncoder::onQueueFilled(OMX_U32 /* portIndex */) { 4945c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (mSignalledError || mSawInputEOS) { 4955c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return; 4965c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 4975c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4985c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (!mStarted) { 4995c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (OMX_ErrorNone != initEncoder()) { 5005c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return; 5015c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 5025c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 5035c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 5045c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong List<BufferInfo *> &inQueue = getPortQueue(0); 5055c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong List<BufferInfo *> &outQueue = getPortQueue(1); 5065c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 5075c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong while (!mSawInputEOS && !inQueue.empty() && !outQueue.empty()) { 5085c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong BufferInfo *inInfo = *inQueue.begin(); 5095c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader; 5105c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong BufferInfo *outInfo = *outQueue.begin(); 5115c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; 5125c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 5135c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outHeader->nTimeStamp = 0; 5145c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outHeader->nFlags = 0; 5155c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outHeader->nOffset = 0; 5165c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outHeader->nFilledLen = 0; 5175c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outHeader->nOffset = 0; 5185c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 5195c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong uint8_t *outPtr = (uint8_t *) outHeader->pBuffer; 5205c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong uint32_t dataLength = outHeader->nAllocLen; 5215c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 5225c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (!mSpsPpsHeaderReceived && mNumInputFrames < 0) { 5235c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // 4 bytes are reserved for holding the start code 0x00000001 5245c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // of the sequence parameter set at the beginning. 5255c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outPtr += 4; 5265c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong dataLength -= 4; 5275c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 5285c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 5295c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong int32_t type; 5305c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong AVCEnc_Status encoderStatus = AVCENC_SUCCESS; 5315c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 5325c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // Combine SPS and PPS and place them in the very first output buffer 5335c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // SPS and PPS are separated by start code 0x00000001 5345c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // Assume that we have exactly one SPS and exactly one PPS. 5355c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong while (!mSpsPpsHeaderReceived && mNumInputFrames <= 0) { 5365c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong encoderStatus = PVAVCEncodeNAL(mHandle, outPtr, &dataLength, &type); 5375c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (encoderStatus == AVCENC_WRONG_STATE) { 5385c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mSpsPpsHeaderReceived = true; 5395c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK_EQ(0, mNumInputFrames); // 1st video frame is 0 5405c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outHeader->nFlags = OMX_BUFFERFLAG_CODECCONFIG; 5415c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outQueue.erase(outQueue.begin()); 5425c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outInfo->mOwnedByUs = false; 5435c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong notifyFillBufferDone(outHeader); 5445c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return; 5455c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } else { 5465c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong switch (type) { 5475c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong case AVC_NALTYPE_SPS: 5485c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ++mNumInputFrames; 5495c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong memcpy((uint8_t *)outHeader->pBuffer, "\x00\x00\x00\x01", 4); 5505c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outHeader->nFilledLen = 4 + dataLength; 5515c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outPtr += (dataLength + 4); // 4 bytes for next start code 5525c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong dataLength = outHeader->nAllocLen - outHeader->nFilledLen; 5535c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong break; 5545c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong default: 5555c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK_EQ(AVC_NALTYPE_PPS, type); 5565c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ++mNumInputFrames; 5575c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong memcpy((uint8_t *) outHeader->pBuffer + outHeader->nFilledLen, 5585c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong "\x00\x00\x00\x01", 4); 5595c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outHeader->nFilledLen += (dataLength + 4); 5605c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outPtr += (dataLength + 4); 5615c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong break; 5625c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 5635c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 5645c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 5655c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 5665c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // Get next input video frame 5675c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (mReadyForNextFrame) { 5685c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // Save the input buffer info so that it can be 5695c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // passed to an output buffer 5705c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong InputBufferInfo info; 5715c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong info.mTimeUs = inHeader->nTimeStamp; 5725c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong info.mFlags = inHeader->nFlags; 5735c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mInputBufferInfoVec.push(info); 5745c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mPrevTimestampUs = inHeader->nTimeStamp; 5755c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 5765c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) { 5775c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mSawInputEOS = true; 5785c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 5795c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 5805c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (inHeader->nFilledLen > 0) { 5815c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong AVCFrameIO videoInput; 5825c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong memset(&videoInput, 0, sizeof(videoInput)); 583a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar videoInput.height = align(mHeight, 16); 584a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar videoInput.pitch = align(mWidth, 16); 5855c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong videoInput.coding_timestamp = (inHeader->nTimeStamp + 500) / 1000; // in ms 5862edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar const uint8_t *inputData = NULL; 587a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar if (mInputDataIsMeta) { 588bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala inputData = 5892edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar extractGraphicBuffer( 590a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mInputFrameData, (mWidth * mHeight * 3) >> 1, 5912edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar inHeader->pBuffer + inHeader->nOffset, inHeader->nFilledLen, 592a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mWidth, mHeight); 593bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala if (inputData == NULL) { 594bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala ALOGE("Unable to extract gralloc buffer in metadata mode"); 595bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala mSignalledError = true; 596bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 597bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala return; 598bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala } 599bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala // TODO: Verify/convert pixel format enum 600bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala } else { 6012edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar inputData = (const uint8_t *)inHeader->pBuffer + inHeader->nOffset; 602a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar if (mColorFormat != OMX_COLOR_FormatYUV420Planar) { 6032edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar ConvertYUV420SemiPlanarToYUV420Planar( 604a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar inputData, mInputFrameData, mWidth, mHeight); 6052edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar inputData = mInputFrameData; 6062edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar } 607bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala } 6085c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 6095c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(inputData != NULL); 6102edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar videoInput.YCbCr[0] = (uint8_t *)inputData; 6115c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong videoInput.YCbCr[1] = videoInput.YCbCr[0] + videoInput.height * videoInput.pitch; 6125c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong videoInput.YCbCr[2] = videoInput.YCbCr[1] + 6135c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ((videoInput.height * videoInput.pitch) >> 2); 6145c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong videoInput.disp_order = mNumInputFrames; 6155c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 6165c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong encoderStatus = PVAVCEncSetInput(mHandle, &videoInput); 6175c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (encoderStatus == AVCENC_SUCCESS || encoderStatus == AVCENC_NEW_IDR) { 6185c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mReadyForNextFrame = false; 6195c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ++mNumInputFrames; 6205c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (encoderStatus == AVCENC_NEW_IDR) { 6215c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mIsIDRFrame = 1; 6225c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 6235c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } else { 6245c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (encoderStatus < AVCENC_SUCCESS) { 6255c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ALOGE("encoderStatus = %d at line %d", encoderStatus, __LINE__); 6265c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mSignalledError = true; 6275c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 6285c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return; 6295c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } else { 6305c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ALOGV("encoderStatus = %d at line %d", encoderStatus, __LINE__); 6315c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong inQueue.erase(inQueue.begin()); 6325c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong inInfo->mOwnedByUs = false; 6335c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong notifyEmptyBufferDone(inHeader); 6345c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return; 6355c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 6365c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 6375c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 6385c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 6395c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 6405c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // Encode an input video frame 6415c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(encoderStatus == AVCENC_SUCCESS || encoderStatus == AVCENC_NEW_IDR); 6425c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong dataLength = outHeader->nAllocLen; // Reset the output buffer length 6435c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (inHeader->nFilledLen > 0) { 64467606c31f41959589d46fbd9e845a2974a48e505Martin Storsjo if (outHeader->nAllocLen >= 4) { 64567606c31f41959589d46fbd9e845a2974a48e505Martin Storsjo memcpy(outPtr, "\x00\x00\x00\x01", 4); 64667606c31f41959589d46fbd9e845a2974a48e505Martin Storsjo outPtr += 4; 64767606c31f41959589d46fbd9e845a2974a48e505Martin Storsjo dataLength -= 4; 64867606c31f41959589d46fbd9e845a2974a48e505Martin Storsjo } 6495c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong encoderStatus = PVAVCEncodeNAL(mHandle, outPtr, &dataLength, &type); 65067606c31f41959589d46fbd9e845a2974a48e505Martin Storsjo dataLength = outPtr + dataLength - outHeader->pBuffer; 6515c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (encoderStatus == AVCENC_SUCCESS) { 6525c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(NULL == PVAVCEncGetOverrunBuffer(mHandle)); 6535c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } else if (encoderStatus == AVCENC_PICTURE_READY) { 6545c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(NULL == PVAVCEncGetOverrunBuffer(mHandle)); 6555c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (mIsIDRFrame) { 6565c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outHeader->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; 6575c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mIsIDRFrame = false; 6585c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 6595c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mReadyForNextFrame = true; 6605c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong AVCFrameIO recon; 6615c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (PVAVCEncGetRecon(mHandle, &recon) == AVCENC_SUCCESS) { 6625c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong PVAVCEncReleaseRecon(mHandle, &recon); 6635c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 6645c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } else { 6655c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong dataLength = 0; 6665c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mReadyForNextFrame = true; 6675c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 6685c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 6695c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (encoderStatus < AVCENC_SUCCESS) { 6705c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ALOGE("encoderStatus = %d at line %d", encoderStatus, __LINE__); 6715c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mSignalledError = true; 6725c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 6735c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return; 6745c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 6755c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } else { 6765c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong dataLength = 0; 6775c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 6785c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 6795c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong inQueue.erase(inQueue.begin()); 6805c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong inInfo->mOwnedByUs = false; 6815c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong notifyEmptyBufferDone(inHeader); 6825c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 6835c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outQueue.erase(outQueue.begin()); 6845c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(!mInputBufferInfoVec.empty()); 6855c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong InputBufferInfo *inputBufInfo = mInputBufferInfoVec.begin(); 6865c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outHeader->nTimeStamp = inputBufInfo->mTimeUs; 6875c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outHeader->nFlags |= (inputBufInfo->mFlags | OMX_BUFFERFLAG_ENDOFFRAME); 688f547a36c8f0fe11c4c425168037e3ce1d1a697dfMartin Storsjo if (mSawInputEOS) { 689f547a36c8f0fe11c4c425168037e3ce1d1a697dfMartin Storsjo outHeader->nFlags |= OMX_BUFFERFLAG_EOS; 690f547a36c8f0fe11c4c425168037e3ce1d1a697dfMartin Storsjo } 6915c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outHeader->nFilledLen = dataLength; 6925c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outInfo->mOwnedByUs = false; 6935c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong notifyFillBufferDone(outHeader); 694e61f13d2c710918f5267b3c835fcc20447b4e4d6Martin Storsjo mInputBufferInfoVec.erase(mInputBufferInfoVec.begin()); 6955c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 6965c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 6975c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 6985c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongint32_t SoftAVCEncoder::allocOutputBuffers( 6995c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong unsigned int sizeInMbs, unsigned int numBuffers) { 7005c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(mOutputBuffers.isEmpty()); 7015c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong size_t frameSize = (sizeInMbs << 7) * 3; 7025c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong for (unsigned int i = 0; i < numBuffers; ++i) { 7035c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong MediaBuffer *buffer = new MediaBuffer(frameSize); 7045c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong buffer->setObserver(this); 7055c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mOutputBuffers.push(buffer); 7065c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 7075c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 7085c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return 1; 7095c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 7105c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 7115c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongvoid SoftAVCEncoder::unbindOutputBuffer(int32_t index) { 7125c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(index >= 0); 7135c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 7145c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 7155c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongint32_t SoftAVCEncoder::bindOutputBuffer(int32_t index, uint8_t **yuv) { 7165c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(index >= 0); 7175c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(index < (int32_t) mOutputBuffers.size()); 7185c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong *yuv = (uint8_t *) mOutputBuffers[index]->data(); 7195c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 7205c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return 1; 7215c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 7225c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 7235c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongvoid SoftAVCEncoder::signalBufferReturned(MediaBuffer *buffer) { 72484333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber UNUSED_UNLESS_VERBOSE(buffer); 7255c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ALOGV("signalBufferReturned: %p", buffer); 7265c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 7275c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 7285c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} // namespace android 7295c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 7305c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongandroid::SoftOMXComponent *createSoftOMXComponent( 7315c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong const char *name, const OMX_CALLBACKTYPE *callbacks, 7325c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_PTR appData, OMX_COMPONENTTYPE **component) { 7335c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return new android::SoftAVCEncoder(name, callbacks, appData, component); 7345c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 735