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); 2475c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mInputFrameData = 248a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar (uint8_t *) malloc((mWidth * mHeight * 3 ) >> 1); 2495c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(mInputFrameData != NULL); 2505c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 2515c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 2525c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // PV's AVC encoder requires the video dimension of multiple 253a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar if (mWidth % 16 != 0 || mHeight % 16 != 0) { 2545c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ALOGE("Video frame size %dx%d must be a multiple of 16", 255a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mWidth, mHeight); 2565c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorBadParameter; 2575c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 2585c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 259a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mEncParams->width = mWidth; 260a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mEncParams->height = mHeight; 261a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mEncParams->bitrate = mBitrate; 262a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mEncParams->frame_rate = (1000 * mFramerate) >> 16; // In frames/ms!, mFramerate is in Q16 263a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mEncParams->CPB_size = (uint32_t) (mBitrate >> 1); 2645c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 265a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar int32_t nMacroBlocks = divUp(mWidth, 16) * divUp(mHeight, 16); 2665c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(mSliceGroup == NULL); 2675c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mSliceGroup = (uint32_t *) malloc(sizeof(uint32_t) * nMacroBlocks); 2685c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(mSliceGroup != NULL); 2695c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong for (int ii = 0, idx = 0; ii < nMacroBlocks; ++ii) { 2705c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mSliceGroup[ii] = idx++; 2715c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (idx >= mEncParams->num_slice_group) { 2725c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong idx = 0; 2735c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 2745c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 2755c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->slice_group = mSliceGroup; 2765c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 2775c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // Set IDR frame refresh interval 2785c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (mIDRFrameRefreshIntervalInSec < 0) { 2795c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->idr_period = -1; 2805c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } else if (mIDRFrameRefreshIntervalInSec == 0) { 2815c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->idr_period = 1; // All I frames 2825c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } else { 2835c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->idr_period = 284a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar (mIDRFrameRefreshIntervalInSec * mFramerate) >> 16; // mFramerate is in Q16 2855c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 2865c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 2875c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // Set profile and level 2885c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->profile = mAVCEncProfile; 2895c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->level = mAVCEncLevel; 2905c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 2915c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorNone; 2925c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 2935c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 2945c61b361d1c55a93a215cfb2c325b4987f57f1c5James DongOMX_ERRORTYPE SoftAVCEncoder::initEncoder() { 2955c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(!mStarted); 2965c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 2975c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_ERRORTYPE errType = OMX_ErrorNone; 2985c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (OMX_ErrorNone != (errType = initEncParams())) { 2995c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ALOGE("Failed to initialized encoder params"); 3005c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mSignalledError = true; 3015c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 3025c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return errType; 3035c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 3045c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3055c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong AVCEnc_Status err; 3065c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong err = PVAVCEncInitialize(mHandle, mEncParams, NULL, NULL); 3075c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (err != AVCENC_SUCCESS) { 3085c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ALOGE("Failed to initialize the encoder: %d", err); 3095c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mSignalledError = true; 3105c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 3115c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorUndefined; 3125c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 3135c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3145c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mNumInputFrames = -2; // 1st two buffers contain SPS and PPS 3155c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mSpsPpsHeaderReceived = false; 3165c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mReadyForNextFrame = true; 3175c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mIsIDRFrame = false; 3185c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mStarted = true; 3195c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3205c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorNone; 3215c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 3225c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3235c61b361d1c55a93a215cfb2c325b4987f57f1c5James DongOMX_ERRORTYPE SoftAVCEncoder::releaseEncoder() { 3245c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (!mStarted) { 3255c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorNone; 3265c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 3275c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3285c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong PVAVCCleanUpEncoder(mHandle); 3295c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong releaseOutputBuffers(); 3305c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3312edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar free(mInputFrameData); 3325c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mInputFrameData = NULL; 3335c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3342edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar free(mSliceGroup); 3355c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mSliceGroup = NULL; 3365c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3375c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong delete mEncParams; 3385c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams = NULL; 3395c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3405c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong delete mHandle; 3415c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mHandle = NULL; 3425c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3435c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mStarted = false; 3445c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3455c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorNone; 3465c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 3475c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3485c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongvoid SoftAVCEncoder::releaseOutputBuffers() { 3495c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong for (size_t i = 0; i < mOutputBuffers.size(); ++i) { 3505c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong MediaBuffer *buffer = mOutputBuffers.editItemAt(i); 3515c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong buffer->setObserver(NULL); 3525c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong buffer->release(); 3535c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 3545c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mOutputBuffers.clear(); 3555c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 3565c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3575c61b361d1c55a93a215cfb2c325b4987f57f1c5James DongOMX_ERRORTYPE SoftAVCEncoder::internalGetParameter( 3585c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_INDEXTYPE index, OMX_PTR params) { 3595c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong switch (index) { 3605c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong case OMX_IndexParamVideoBitrate: 3615c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong { 3625c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_VIDEO_PARAM_BITRATETYPE *bitRate = 3635c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong (OMX_VIDEO_PARAM_BITRATETYPE *) params; 3645c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3655c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (bitRate->nPortIndex != 1) { 3665c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorUndefined; 3675c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 3685c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3695c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong bitRate->eControlRate = OMX_Video_ControlRateVariable; 370a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar bitRate->nTargetBitrate = mBitrate; 3715c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorNone; 3725c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 3735c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3745c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong case OMX_IndexParamVideoAvc: 3755c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong { 3765c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_VIDEO_PARAM_AVCTYPE *avcParams = 3775c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong (OMX_VIDEO_PARAM_AVCTYPE *)params; 3785c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3795c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (avcParams->nPortIndex != 1) { 3805c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorUndefined; 3815c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 3825c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3835c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->eProfile = OMX_VIDEO_AVCProfileBaseline; 3845c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_U32 omxLevel = AVC_LEVEL2; 3855c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (OMX_ErrorNone != 3865c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ConvertAvcSpecLevelToOmxAvcLevel(mAVCEncLevel, &omxLevel)) { 3875c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorUndefined; 3885c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 3895c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3905c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->eLevel = (OMX_VIDEO_AVCLEVELTYPE) omxLevel; 3915c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->nRefFrames = 1; 3925c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->nBFrames = 0; 3935c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->bUseHadamard = OMX_TRUE; 3945c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->nAllowedPictureTypes = 3955c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong (OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP); 3965c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->nRefIdx10ActiveMinus1 = 0; 3975c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->nRefIdx11ActiveMinus1 = 0; 3985c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->bWeightedPPrediction = OMX_FALSE; 3995c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->bEntropyCodingCABAC = OMX_FALSE; 4005c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->bconstIpred = OMX_FALSE; 4015c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->bDirect8x8Inference = OMX_FALSE; 4025c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->bDirectSpatialTemporal = OMX_FALSE; 4035c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->nCabacInitIdc = 0; 4045c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorNone; 4055c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 4065c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4075c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong default: 408a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar return SoftVideoEncoderOMXComponent::internalGetParameter(index, params); 4095c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 4105c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 4115c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4125c61b361d1c55a93a215cfb2c325b4987f57f1c5James DongOMX_ERRORTYPE SoftAVCEncoder::internalSetParameter( 4135c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_INDEXTYPE index, const OMX_PTR params) { 414bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala int32_t indexFull = index; 415bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala 416bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala switch (indexFull) { 4175c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong case OMX_IndexParamVideoBitrate: 4185c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong { 4195c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_VIDEO_PARAM_BITRATETYPE *bitRate = 4205c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong (OMX_VIDEO_PARAM_BITRATETYPE *) params; 4215c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4225c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (bitRate->nPortIndex != 1 || 4235c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong bitRate->eControlRate != OMX_Video_ControlRateVariable) { 4245c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorUndefined; 4255c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 4265c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 427a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mBitrate = bitRate->nTargetBitrate; 4285c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorNone; 4295c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 4305c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4315c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong case OMX_IndexParamVideoAvc: 4325c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong { 4335c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_VIDEO_PARAM_AVCTYPE *avcType = 4345c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong (OMX_VIDEO_PARAM_AVCTYPE *)params; 4355c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4365c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (avcType->nPortIndex != 1) { 4375c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorUndefined; 4385c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 4395c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4405c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // PV's AVC encoder only supports baseline profile 4415c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (avcType->eProfile != OMX_VIDEO_AVCProfileBaseline || 4425c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcType->nRefFrames != 1 || 4435c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcType->nBFrames != 0 || 4445c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcType->bUseHadamard != OMX_TRUE || 4455c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong (avcType->nAllowedPictureTypes & OMX_VIDEO_PictureTypeB) != 0 || 4465c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcType->nRefIdx10ActiveMinus1 != 0 || 4475c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcType->nRefIdx11ActiveMinus1 != 0 || 4485c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcType->bWeightedPPrediction != OMX_FALSE || 4495c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcType->bEntropyCodingCABAC != OMX_FALSE || 4505c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcType->bconstIpred != OMX_FALSE || 4515c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcType->bDirect8x8Inference != OMX_FALSE || 4525c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcType->bDirectSpatialTemporal != OMX_FALSE || 4535c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcType->nCabacInitIdc != 0) { 4545c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorUndefined; 4555c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 4565c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4575c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (OK != ConvertOmxAvcLevelToAvcSpecLevel(avcType->eLevel, &mAVCEncLevel)) { 4585c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorUndefined; 4595c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 4605c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4615c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorNone; 4625c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 4635c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4645c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong default: 465a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar return SoftVideoEncoderOMXComponent::internalSetParameter(index, params); 4665c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 4675c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 4685c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 46984333e0475bc911adc16417f4ca327c975cf6c36Andreas Hubervoid SoftAVCEncoder::onQueueFilled(OMX_U32 /* portIndex */) { 4705c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (mSignalledError || mSawInputEOS) { 4715c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return; 4725c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 4735c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4745c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (!mStarted) { 4755c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (OMX_ErrorNone != initEncoder()) { 4765c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return; 4775c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 4785c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 4795c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4805c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong List<BufferInfo *> &inQueue = getPortQueue(0); 4815c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong List<BufferInfo *> &outQueue = getPortQueue(1); 4825c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4835c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong while (!mSawInputEOS && !inQueue.empty() && !outQueue.empty()) { 4845c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong BufferInfo *inInfo = *inQueue.begin(); 4855c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader; 4865c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong BufferInfo *outInfo = *outQueue.begin(); 4875c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; 4885c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4895c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outHeader->nTimeStamp = 0; 4905c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outHeader->nFlags = 0; 4915c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outHeader->nOffset = 0; 4925c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outHeader->nFilledLen = 0; 4935c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outHeader->nOffset = 0; 4945c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4955c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong uint8_t *outPtr = (uint8_t *) outHeader->pBuffer; 4965c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong uint32_t dataLength = outHeader->nAllocLen; 4975c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4985c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (!mSpsPpsHeaderReceived && mNumInputFrames < 0) { 4995c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // 4 bytes are reserved for holding the start code 0x00000001 5005c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // of the sequence parameter set at the beginning. 5015c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outPtr += 4; 5025c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong dataLength -= 4; 5035c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 5045c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 5055c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong int32_t type; 5065c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong AVCEnc_Status encoderStatus = AVCENC_SUCCESS; 5075c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 5085c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // Combine SPS and PPS and place them in the very first output buffer 5095c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // SPS and PPS are separated by start code 0x00000001 5105c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // Assume that we have exactly one SPS and exactly one PPS. 5115c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong while (!mSpsPpsHeaderReceived && mNumInputFrames <= 0) { 5125c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong encoderStatus = PVAVCEncodeNAL(mHandle, outPtr, &dataLength, &type); 5135c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (encoderStatus == AVCENC_WRONG_STATE) { 5145c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mSpsPpsHeaderReceived = true; 5155c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK_EQ(0, mNumInputFrames); // 1st video frame is 0 5165c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outHeader->nFlags = OMX_BUFFERFLAG_CODECCONFIG; 5175c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outQueue.erase(outQueue.begin()); 5185c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outInfo->mOwnedByUs = false; 5195c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong notifyFillBufferDone(outHeader); 5205c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return; 5215c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } else { 5225c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong switch (type) { 5235c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong case AVC_NALTYPE_SPS: 5245c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ++mNumInputFrames; 5255c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong memcpy((uint8_t *)outHeader->pBuffer, "\x00\x00\x00\x01", 4); 5265c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outHeader->nFilledLen = 4 + dataLength; 5275c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outPtr += (dataLength + 4); // 4 bytes for next start code 5285c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong dataLength = outHeader->nAllocLen - outHeader->nFilledLen; 5295c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong break; 5305c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong default: 5315c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK_EQ(AVC_NALTYPE_PPS, type); 5325c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ++mNumInputFrames; 5335c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong memcpy((uint8_t *) outHeader->pBuffer + outHeader->nFilledLen, 5345c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong "\x00\x00\x00\x01", 4); 5355c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outHeader->nFilledLen += (dataLength + 4); 5365c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outPtr += (dataLength + 4); 5375c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong break; 5385c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 5395c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 5405c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 5415c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 5425c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // Get next input video frame 5435c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (mReadyForNextFrame) { 5445c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // Save the input buffer info so that it can be 5455c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // passed to an output buffer 5465c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong InputBufferInfo info; 5475c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong info.mTimeUs = inHeader->nTimeStamp; 5485c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong info.mFlags = inHeader->nFlags; 5495c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mInputBufferInfoVec.push(info); 5505c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mPrevTimestampUs = inHeader->nTimeStamp; 5515c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 5525c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) { 5535c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mSawInputEOS = true; 5545c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 5555c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 5565c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (inHeader->nFilledLen > 0) { 5575c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong AVCFrameIO videoInput; 5585c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong memset(&videoInput, 0, sizeof(videoInput)); 559a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar videoInput.height = align(mHeight, 16); 560a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar videoInput.pitch = align(mWidth, 16); 5615c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong videoInput.coding_timestamp = (inHeader->nTimeStamp + 500) / 1000; // in ms 5622edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar const uint8_t *inputData = NULL; 563a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar if (mInputDataIsMeta) { 564bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala if (inHeader->nFilledLen != 8) { 565bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala ALOGE("MetaData buffer is wrong size! " 56666fe2e9ee30bcb4161bc487ec63d2ae4a05f4051Glenn Kasten "(got %u bytes, expected 8)", inHeader->nFilledLen); 567bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala mSignalledError = true; 568bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 569bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala return; 570bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala } 571bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala inputData = 5722edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar extractGraphicBuffer( 573a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mInputFrameData, (mWidth * mHeight * 3) >> 1, 5742edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar inHeader->pBuffer + inHeader->nOffset, inHeader->nFilledLen, 575a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar mWidth, mHeight); 576bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala if (inputData == NULL) { 577bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala ALOGE("Unable to extract gralloc buffer in metadata mode"); 578bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala mSignalledError = true; 579bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 580bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala return; 581bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala } 582bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala // TODO: Verify/convert pixel format enum 583bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala } else { 5842edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar inputData = (const uint8_t *)inHeader->pBuffer + inHeader->nOffset; 585a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar if (mColorFormat != OMX_COLOR_FormatYUV420Planar) { 5862edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar ConvertYUV420SemiPlanarToYUV420Planar( 587a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar inputData, mInputFrameData, mWidth, mHeight); 5882edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar inputData = mInputFrameData; 5892edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar } 590bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala } 5915c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 5925c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(inputData != NULL); 5932edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar videoInput.YCbCr[0] = (uint8_t *)inputData; 5945c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong videoInput.YCbCr[1] = videoInput.YCbCr[0] + videoInput.height * videoInput.pitch; 5955c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong videoInput.YCbCr[2] = videoInput.YCbCr[1] + 5965c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ((videoInput.height * videoInput.pitch) >> 2); 5975c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong videoInput.disp_order = mNumInputFrames; 5985c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 5995c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong encoderStatus = PVAVCEncSetInput(mHandle, &videoInput); 6005c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (encoderStatus == AVCENC_SUCCESS || encoderStatus == AVCENC_NEW_IDR) { 6015c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mReadyForNextFrame = false; 6025c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ++mNumInputFrames; 6035c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (encoderStatus == AVCENC_NEW_IDR) { 6045c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mIsIDRFrame = 1; 6055c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 6065c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } else { 6075c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (encoderStatus < AVCENC_SUCCESS) { 6085c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ALOGE("encoderStatus = %d at line %d", encoderStatus, __LINE__); 6095c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mSignalledError = true; 6105c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 6115c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return; 6125c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } else { 6135c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ALOGV("encoderStatus = %d at line %d", encoderStatus, __LINE__); 6145c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong inQueue.erase(inQueue.begin()); 6155c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong inInfo->mOwnedByUs = false; 6165c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong notifyEmptyBufferDone(inHeader); 6175c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return; 6185c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 6195c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 6205c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 6215c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 6225c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 6235c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // Encode an input video frame 6245c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(encoderStatus == AVCENC_SUCCESS || encoderStatus == AVCENC_NEW_IDR); 6255c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong dataLength = outHeader->nAllocLen; // Reset the output buffer length 6265c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (inHeader->nFilledLen > 0) { 62767606c31f41959589d46fbd9e845a2974a48e505Martin Storsjo if (outHeader->nAllocLen >= 4) { 62867606c31f41959589d46fbd9e845a2974a48e505Martin Storsjo memcpy(outPtr, "\x00\x00\x00\x01", 4); 62967606c31f41959589d46fbd9e845a2974a48e505Martin Storsjo outPtr += 4; 63067606c31f41959589d46fbd9e845a2974a48e505Martin Storsjo dataLength -= 4; 63167606c31f41959589d46fbd9e845a2974a48e505Martin Storsjo } 6325c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong encoderStatus = PVAVCEncodeNAL(mHandle, outPtr, &dataLength, &type); 63367606c31f41959589d46fbd9e845a2974a48e505Martin Storsjo dataLength = outPtr + dataLength - outHeader->pBuffer; 6345c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (encoderStatus == AVCENC_SUCCESS) { 6355c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(NULL == PVAVCEncGetOverrunBuffer(mHandle)); 6365c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } else if (encoderStatus == AVCENC_PICTURE_READY) { 6375c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(NULL == PVAVCEncGetOverrunBuffer(mHandle)); 6385c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (mIsIDRFrame) { 6395c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outHeader->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; 6405c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mIsIDRFrame = false; 6415c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 6425c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mReadyForNextFrame = true; 6435c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong AVCFrameIO recon; 6445c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (PVAVCEncGetRecon(mHandle, &recon) == AVCENC_SUCCESS) { 6455c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong PVAVCEncReleaseRecon(mHandle, &recon); 6465c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 6475c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } else { 6485c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong dataLength = 0; 6495c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mReadyForNextFrame = true; 6505c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 6515c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 6525c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (encoderStatus < AVCENC_SUCCESS) { 6535c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ALOGE("encoderStatus = %d at line %d", encoderStatus, __LINE__); 6545c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mSignalledError = true; 6555c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 6565c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return; 6575c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 6585c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } else { 6595c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong dataLength = 0; 6605c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 6615c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 6625c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong inQueue.erase(inQueue.begin()); 6635c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong inInfo->mOwnedByUs = false; 6645c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong notifyEmptyBufferDone(inHeader); 6655c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 6665c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outQueue.erase(outQueue.begin()); 6675c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(!mInputBufferInfoVec.empty()); 6685c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong InputBufferInfo *inputBufInfo = mInputBufferInfoVec.begin(); 6695c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outHeader->nTimeStamp = inputBufInfo->mTimeUs; 6705c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outHeader->nFlags |= (inputBufInfo->mFlags | OMX_BUFFERFLAG_ENDOFFRAME); 671f547a36c8f0fe11c4c425168037e3ce1d1a697dfMartin Storsjo if (mSawInputEOS) { 672f547a36c8f0fe11c4c425168037e3ce1d1a697dfMartin Storsjo outHeader->nFlags |= OMX_BUFFERFLAG_EOS; 673f547a36c8f0fe11c4c425168037e3ce1d1a697dfMartin Storsjo } 6745c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outHeader->nFilledLen = dataLength; 6755c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outInfo->mOwnedByUs = false; 6765c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong notifyFillBufferDone(outHeader); 677e61f13d2c710918f5267b3c835fcc20447b4e4d6Martin Storsjo mInputBufferInfoVec.erase(mInputBufferInfoVec.begin()); 6785c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 6795c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 6805c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 6815c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongint32_t SoftAVCEncoder::allocOutputBuffers( 6825c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong unsigned int sizeInMbs, unsigned int numBuffers) { 6835c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(mOutputBuffers.isEmpty()); 6845c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong size_t frameSize = (sizeInMbs << 7) * 3; 6855c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong for (unsigned int i = 0; i < numBuffers; ++i) { 6865c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong MediaBuffer *buffer = new MediaBuffer(frameSize); 6875c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong buffer->setObserver(this); 6885c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mOutputBuffers.push(buffer); 6895c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 6905c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 6915c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return 1; 6925c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 6935c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 6945c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongvoid SoftAVCEncoder::unbindOutputBuffer(int32_t index) { 6955c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(index >= 0); 6965c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 6975c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 6985c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongint32_t SoftAVCEncoder::bindOutputBuffer(int32_t index, uint8_t **yuv) { 6995c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(index >= 0); 7005c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(index < (int32_t) mOutputBuffers.size()); 7015c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong *yuv = (uint8_t *) mOutputBuffers[index]->data(); 7025c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 7035c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return 1; 7045c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 7055c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 7065c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongvoid SoftAVCEncoder::signalBufferReturned(MediaBuffer *buffer) { 70784333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber UNUSED_UNLESS_VERBOSE(buffer); 7085c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ALOGV("signalBufferReturned: %p", buffer); 7095c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 7105c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 7115c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} // namespace android 7125c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 7135c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongandroid::SoftOMXComponent *createSoftOMXComponent( 7145c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong const char *name, const OMX_CALLBACKTYPE *callbacks, 7155c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_PTR appData, OMX_COMPONENTTYPE **component) { 7165c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return new android::SoftAVCEncoder(name, callbacks, appData, component); 7175c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 718