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> 205c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 215c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong#include "avcenc_api.h" 225c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong#include "avcenc_int.h" 235c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong#include "OMX_Video.h" 245c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 25bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala#include <HardwareAPI.h> 26bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala#include <MetadataBufferType.h> 275c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong#include <media/stagefright/foundation/ADebug.h> 285c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong#include <media/stagefright/MediaDefs.h> 295c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong#include <media/stagefright/MediaErrors.h> 305c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong#include <media/stagefright/MetaData.h> 315c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong#include <media/stagefright/Utils.h> 32bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala#include <ui/Rect.h> 33bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala#include <ui/GraphicBufferMapper.h> 345c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 355c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong#include "SoftAVCEncoder.h" 365c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 375c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongnamespace android { 385c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 395c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongtemplate<class T> 405c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongstatic void InitOMXParams(T *params) { 415c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong params->nSize = sizeof(T); 425c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong params->nVersion.s.nVersionMajor = 1; 435c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong params->nVersion.s.nVersionMinor = 0; 445c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong params->nVersion.s.nRevision = 0; 455c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong params->nVersion.s.nStep = 0; 465c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 475c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 485c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongtypedef struct LevelConversion { 495c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_U32 omxLevel; 505c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong AVCLevel avcLevel; 515c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} LevelConcersion; 525c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 535c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongstatic LevelConversion ConversionTable[] = { 545c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong { OMX_VIDEO_AVCLevel1, AVC_LEVEL1_B }, 555c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong { OMX_VIDEO_AVCLevel1b, AVC_LEVEL1 }, 565c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong { OMX_VIDEO_AVCLevel11, AVC_LEVEL1_1 }, 575c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong { OMX_VIDEO_AVCLevel12, AVC_LEVEL1_2 }, 585c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong { OMX_VIDEO_AVCLevel13, AVC_LEVEL1_3 }, 595c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong { OMX_VIDEO_AVCLevel2, AVC_LEVEL2 }, 605c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong#if 0 615c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // encoding speed is very poor if video 625c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // resolution is higher than CIF 635c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong { OMX_VIDEO_AVCLevel21, AVC_LEVEL2_1 }, 645c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong { OMX_VIDEO_AVCLevel22, AVC_LEVEL2_2 }, 655c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong { OMX_VIDEO_AVCLevel3, AVC_LEVEL3 }, 665c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong { OMX_VIDEO_AVCLevel31, AVC_LEVEL3_1 }, 675c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong { OMX_VIDEO_AVCLevel32, AVC_LEVEL3_2 }, 685c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong { OMX_VIDEO_AVCLevel4, AVC_LEVEL4 }, 695c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong { OMX_VIDEO_AVCLevel41, AVC_LEVEL4_1 }, 705c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong { OMX_VIDEO_AVCLevel42, AVC_LEVEL4_2 }, 715c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong { OMX_VIDEO_AVCLevel5, AVC_LEVEL5 }, 725c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong { OMX_VIDEO_AVCLevel51, AVC_LEVEL5_1 }, 735c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong#endif 745c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong}; 755c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 765c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongstatic status_t ConvertOmxAvcLevelToAvcSpecLevel( 775c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_U32 omxLevel, AVCLevel *avcLevel) { 785c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong for (size_t i = 0, n = sizeof(ConversionTable)/sizeof(ConversionTable[0]); 795c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong i < n; ++i) { 805c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (omxLevel == ConversionTable[i].omxLevel) { 815c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong *avcLevel = ConversionTable[i].avcLevel; 825c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OK; 835c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 845c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 855c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 865c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ALOGE("ConvertOmxAvcLevelToAvcSpecLevel: %d level not supported", 875c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong (int32_t)omxLevel); 885c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 895c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return BAD_VALUE; 905c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 915c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 925c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongstatic status_t ConvertAvcSpecLevelToOmxAvcLevel( 935c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong AVCLevel avcLevel, OMX_U32 *omxLevel) { 945c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong for (size_t i = 0, n = sizeof(ConversionTable)/sizeof(ConversionTable[0]); 955c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong i < n; ++i) { 965c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (avcLevel == ConversionTable[i].avcLevel) { 975c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong *omxLevel = ConversionTable[i].omxLevel; 985c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OK; 995c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 1005c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 1015c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 1025c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ALOGE("ConvertAvcSpecLevelToOmxAvcLevel: %d level not supported", 1035c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong (int32_t) avcLevel); 1045c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 1055c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return BAD_VALUE; 1065c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 1075c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 1085c61b361d1c55a93a215cfb2c325b4987f57f1c5James Donginline static void ConvertYUV420SemiPlanarToYUV420Planar( 1095c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong uint8_t *inyuv, uint8_t* outyuv, 1105c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong int32_t width, int32_t height) { 1115c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 1125c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong int32_t outYsize = width * height; 1135c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong uint32_t *outy = (uint32_t *) outyuv; 1145c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong uint16_t *outcb = (uint16_t *) (outyuv + outYsize); 1155c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong uint16_t *outcr = (uint16_t *) (outyuv + outYsize + (outYsize >> 2)); 1165c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 1175c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong /* Y copying */ 1185c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong memcpy(outy, inyuv, outYsize); 1195c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 1205c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong /* U & V copying */ 1215c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong uint32_t *inyuv_4 = (uint32_t *) (inyuv + outYsize); 1225c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong for (int32_t i = height >> 1; i > 0; --i) { 1235c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong for (int32_t j = width >> 2; j > 0; --j) { 1245c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong uint32_t temp = *inyuv_4++; 1255c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong uint32_t tempU = temp & 0xFF; 1265c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong tempU = tempU | ((temp >> 8) & 0xFF00); 1275c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 1285c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong uint32_t tempV = (temp >> 8) & 0xFF; 1295c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong tempV = tempV | ((temp >> 16) & 0xFF00); 1305c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 1315c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // Flip U and V 1325c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong *outcb++ = tempV; 1335c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong *outcr++ = tempU; 1345c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 1355c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 1365c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 1375c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 13823da4cf305b9bfff07954711a8a2d9ec040865afMartin Storsjostatic void* MallocWrapper( 1395c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong void *userData, int32_t size, int32_t attrs) { 140359d8fcd30ff0a8390e4c5560d53ec55a4cc5bcdMartin Storsjo void *ptr = malloc(size); 141359d8fcd30ff0a8390e4c5560d53ec55a4cc5bcdMartin Storsjo if (ptr) 142359d8fcd30ff0a8390e4c5560d53ec55a4cc5bcdMartin Storsjo memset(ptr, 0, size); 143359d8fcd30ff0a8390e4c5560d53ec55a4cc5bcdMartin Storsjo return ptr; 1445c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 1455c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 14623da4cf305b9bfff07954711a8a2d9ec040865afMartin Storsjostatic void FreeWrapper(void *userData, void* ptr) { 14723da4cf305b9bfff07954711a8a2d9ec040865afMartin Storsjo free(ptr); 1485c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 1495c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 1505c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongstatic int32_t DpbAllocWrapper(void *userData, 1515c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong unsigned int sizeInMbs, unsigned int numBuffers) { 1525c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong SoftAVCEncoder *encoder = static_cast<SoftAVCEncoder *>(userData); 1535c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(encoder != NULL); 1545c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return encoder->allocOutputBuffers(sizeInMbs, numBuffers); 1555c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 1565c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 1575c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongstatic int32_t BindFrameWrapper( 1585c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong void *userData, int32_t index, uint8_t **yuv) { 1595c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong SoftAVCEncoder *encoder = static_cast<SoftAVCEncoder *>(userData); 1605c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(encoder != NULL); 1615c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return encoder->bindOutputBuffer(index, yuv); 1625c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 1635c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 1645c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongstatic void UnbindFrameWrapper(void *userData, int32_t index) { 1655c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong SoftAVCEncoder *encoder = static_cast<SoftAVCEncoder *>(userData); 1665c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(encoder != NULL); 1675c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return encoder->unbindOutputBuffer(index); 1685c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 1695c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 1705c61b361d1c55a93a215cfb2c325b4987f57f1c5James DongSoftAVCEncoder::SoftAVCEncoder( 1715c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong const char *name, 1725c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong const OMX_CALLBACKTYPE *callbacks, 1735c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_PTR appData, 1745c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_COMPONENTTYPE **component) 1755c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong : SimpleSoftOMXComponent(name, callbacks, appData, component), 1765c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mVideoWidth(176), 1775c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mVideoHeight(144), 1785c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mVideoFrameRate(30), 1795c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mVideoBitRate(192000), 1805c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mVideoColorFormat(OMX_COLOR_FormatYUV420Planar), 181bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala mStoreMetaDataInBuffers(false), 1825c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mIDRFrameRefreshIntervalInSec(1), 1835c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mAVCEncProfile(AVC_BASELINE), 1845c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mAVCEncLevel(AVC_LEVEL2), 1855c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mNumInputFrames(-1), 1865c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mPrevTimestampUs(-1), 1875c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mStarted(false), 1885c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mSawInputEOS(false), 1895c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mSignalledError(false), 1905c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mHandle(new tagAVCHandle), 1915c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams(new tagAVCEncParam), 1925c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mInputFrameData(NULL), 1935c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mSliceGroup(NULL) { 1945c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 1955c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong initPorts(); 1965c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ALOGI("Construct SoftAVCEncoder"); 1975c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 1985c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 1995c61b361d1c55a93a215cfb2c325b4987f57f1c5James DongSoftAVCEncoder::~SoftAVCEncoder() { 2005c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ALOGV("Destruct SoftAVCEncoder"); 2015c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong releaseEncoder(); 2025c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong List<BufferInfo *> &outQueue = getPortQueue(1); 2035c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong List<BufferInfo *> &inQueue = getPortQueue(0); 2045c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(outQueue.empty()); 2055c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(inQueue.empty()); 2065c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 2075c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 2085c61b361d1c55a93a215cfb2c325b4987f57f1c5James DongOMX_ERRORTYPE SoftAVCEncoder::initEncParams() { 2095c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(mHandle != NULL); 2105c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong memset(mHandle, 0, sizeof(tagAVCHandle)); 2115c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mHandle->AVCObject = NULL; 2125c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mHandle->userData = this; 2135c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mHandle->CBAVC_DPBAlloc = DpbAllocWrapper; 2145c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mHandle->CBAVC_FrameBind = BindFrameWrapper; 2155c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mHandle->CBAVC_FrameUnbind = UnbindFrameWrapper; 2165c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mHandle->CBAVC_Malloc = MallocWrapper; 2175c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mHandle->CBAVC_Free = FreeWrapper; 2185c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 2195c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(mEncParams != NULL); 2205c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong memset(mEncParams, 0, sizeof(mEncParams)); 2215c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->rate_control = AVC_ON; 2225c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->initQP = 0; 2235c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->init_CBP_removal_delay = 1600; 2245c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 2255c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->intramb_refresh = 0; 2265c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->auto_scd = AVC_ON; 2275c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->out_of_band_param_set = AVC_ON; 2285c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->poc_type = 2; 2295c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->log2_max_poc_lsb_minus_4 = 12; 2305c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->delta_poc_zero_flag = 0; 2315c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->offset_poc_non_ref = 0; 2325c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->offset_top_bottom = 0; 2335c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->num_ref_in_cycle = 0; 2345c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->offset_poc_ref = NULL; 2355c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 2365c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->num_ref_frame = 1; 2375c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->num_slice_group = 1; 2385c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->fmo_type = 0; 2395c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 2405c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->db_filter = AVC_ON; 2415c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->disable_db_idc = 0; 2425c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 2435c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->alpha_offset = 0; 2445c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->beta_offset = 0; 2455c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->constrained_intra_pred = AVC_OFF; 2465c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 2475c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->data_par = AVC_OFF; 2485c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->fullsearch = AVC_OFF; 2495c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->search_range = 16; 2505c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->sub_pel = AVC_OFF; 2515c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->submb_pred = AVC_OFF; 2525c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->rdopt_mode = AVC_OFF; 2535c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->bidir_pred = AVC_OFF; 2545c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 2555c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->use_overrun_buffer = AVC_OFF; 2565c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 2575c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (mVideoColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) { 2585c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // Color conversion is needed. 2595c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(mInputFrameData == NULL); 2605c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mInputFrameData = 2615c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong (uint8_t *) malloc((mVideoWidth * mVideoHeight * 3 ) >> 1); 2625c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(mInputFrameData != NULL); 2635c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 2645c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 2655c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // PV's AVC encoder requires the video dimension of multiple 2665c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (mVideoWidth % 16 != 0 || mVideoHeight % 16 != 0) { 2675c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ALOGE("Video frame size %dx%d must be a multiple of 16", 2685c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mVideoWidth, mVideoHeight); 2695c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorBadParameter; 2705c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 2715c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 2725c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->width = mVideoWidth; 2735c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->height = mVideoHeight; 2745c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->bitrate = mVideoBitRate; 2755c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->frame_rate = 1000 * mVideoFrameRate; // In frames/ms! 2765c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->CPB_size = (uint32_t) (mVideoBitRate >> 1); 2775c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 2785c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong int32_t nMacroBlocks = ((((mVideoWidth + 15) >> 4) << 4) * 2795c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong (((mVideoHeight + 15) >> 4) << 4)) >> 8; 2805c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(mSliceGroup == NULL); 2815c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mSliceGroup = (uint32_t *) malloc(sizeof(uint32_t) * nMacroBlocks); 2825c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(mSliceGroup != NULL); 2835c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong for (int ii = 0, idx = 0; ii < nMacroBlocks; ++ii) { 2845c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mSliceGroup[ii] = idx++; 2855c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (idx >= mEncParams->num_slice_group) { 2865c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong idx = 0; 2875c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 2885c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 2895c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->slice_group = mSliceGroup; 2905c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 2915c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // Set IDR frame refresh interval 2925c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (mIDRFrameRefreshIntervalInSec < 0) { 2935c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->idr_period = -1; 2945c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } else if (mIDRFrameRefreshIntervalInSec == 0) { 2955c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->idr_period = 1; // All I frames 2965c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } else { 2975c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->idr_period = 2985c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong (mIDRFrameRefreshIntervalInSec * mVideoFrameRate); 2995c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 3005c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3015c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // Set profile and level 3025c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->profile = mAVCEncProfile; 3035c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams->level = mAVCEncLevel; 3045c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3055c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorNone; 3065c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 3075c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3085c61b361d1c55a93a215cfb2c325b4987f57f1c5James DongOMX_ERRORTYPE SoftAVCEncoder::initEncoder() { 3095c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(!mStarted); 3105c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3115c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_ERRORTYPE errType = OMX_ErrorNone; 3125c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (OMX_ErrorNone != (errType = initEncParams())) { 3135c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ALOGE("Failed to initialized encoder params"); 3145c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mSignalledError = true; 3155c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 3165c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return errType; 3175c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 3185c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3195c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong AVCEnc_Status err; 3205c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong err = PVAVCEncInitialize(mHandle, mEncParams, NULL, NULL); 3215c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (err != AVCENC_SUCCESS) { 3225c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ALOGE("Failed to initialize the encoder: %d", err); 3235c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mSignalledError = true; 3245c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 3255c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorUndefined; 3265c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 3275c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3285c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mNumInputFrames = -2; // 1st two buffers contain SPS and PPS 3295c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mSpsPpsHeaderReceived = false; 3305c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mReadyForNextFrame = true; 3315c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mIsIDRFrame = false; 3325c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mStarted = true; 3335c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3345c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorNone; 3355c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 3365c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3375c61b361d1c55a93a215cfb2c325b4987f57f1c5James DongOMX_ERRORTYPE SoftAVCEncoder::releaseEncoder() { 3385c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (!mStarted) { 3395c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorNone; 3405c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 3415c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3425c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong PVAVCCleanUpEncoder(mHandle); 3435c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong releaseOutputBuffers(); 3445c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3455c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong delete mInputFrameData; 3465c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mInputFrameData = NULL; 3475c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3485c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong delete mSliceGroup; 3495c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mSliceGroup = NULL; 3505c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3515c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong delete mEncParams; 3525c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mEncParams = NULL; 3535c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3545c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong delete mHandle; 3555c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mHandle = NULL; 3565c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3575c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mStarted = false; 3585c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3595c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorNone; 3605c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 3615c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3625c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongvoid SoftAVCEncoder::releaseOutputBuffers() { 3635c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong for (size_t i = 0; i < mOutputBuffers.size(); ++i) { 3645c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong MediaBuffer *buffer = mOutputBuffers.editItemAt(i); 3655c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong buffer->setObserver(NULL); 3665c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong buffer->release(); 3675c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 3685c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mOutputBuffers.clear(); 3695c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 3705c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3715c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongvoid SoftAVCEncoder::initPorts() { 3725c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_PARAM_PORTDEFINITIONTYPE def; 3735c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong InitOMXParams(&def); 3745c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3755c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong const size_t kInputBufferSize = (mVideoWidth * mVideoHeight * 3) >> 1; 3765c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3775c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // 31584 is PV's magic number. Not sure why. 3785c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong const size_t kOutputBufferSize = 3795c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong (kInputBufferSize > 31584) ? kInputBufferSize: 31584; 3805c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3815c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong def.nPortIndex = 0; 3825c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong def.eDir = OMX_DirInput; 3835c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong def.nBufferCountMin = kNumBuffers; 3845c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong def.nBufferCountActual = def.nBufferCountMin; 3855c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong def.nBufferSize = kInputBufferSize; 3865c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong def.bEnabled = OMX_TRUE; 3875c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong def.bPopulated = OMX_FALSE; 3885c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong def.eDomain = OMX_PortDomainVideo; 3895c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong def.bBuffersContiguous = OMX_FALSE; 3905c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong def.nBufferAlignment = 1; 3915c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 3925c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong def.format.video.cMIMEType = const_cast<char *>("video/raw"); 3935c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong def.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; 3945c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong def.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar; 3955c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong def.format.video.xFramerate = (mVideoFrameRate << 16); // Q16 format 3965c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong def.format.video.nBitrate = mVideoBitRate; 3975c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong def.format.video.nFrameWidth = mVideoWidth; 3985c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong def.format.video.nFrameHeight = mVideoHeight; 3995c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong def.format.video.nStride = mVideoWidth; 4005c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong def.format.video.nSliceHeight = mVideoHeight; 4015c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4025c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong addPort(def); 4035c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4045c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong def.nPortIndex = 1; 4055c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong def.eDir = OMX_DirOutput; 4065c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong def.nBufferCountMin = kNumBuffers; 4075c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong def.nBufferCountActual = def.nBufferCountMin; 4085c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong def.nBufferSize = kOutputBufferSize; 4095c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong def.bEnabled = OMX_TRUE; 4105c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong def.bPopulated = OMX_FALSE; 4115c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong def.eDomain = OMX_PortDomainVideo; 4125c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong def.bBuffersContiguous = OMX_FALSE; 4135c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong def.nBufferAlignment = 2; 4145c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4155c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong def.format.video.cMIMEType = const_cast<char *>("video/avc"); 4165c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong def.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; 4175c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong def.format.video.eColorFormat = OMX_COLOR_FormatUnused; 4185c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong def.format.video.xFramerate = (0 << 16); // Q16 format 4195c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong def.format.video.nBitrate = mVideoBitRate; 4205c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong def.format.video.nFrameWidth = mVideoWidth; 4215c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong def.format.video.nFrameHeight = mVideoHeight; 4225c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong def.format.video.nStride = mVideoWidth; 4235c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong def.format.video.nSliceHeight = mVideoHeight; 4245c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4255c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong addPort(def); 4265c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 4275c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4285c61b361d1c55a93a215cfb2c325b4987f57f1c5James DongOMX_ERRORTYPE SoftAVCEncoder::internalGetParameter( 4295c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_INDEXTYPE index, OMX_PTR params) { 4305c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong switch (index) { 4315c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong case OMX_IndexParamVideoErrorCorrection: 4325c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong { 4335c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorNotImplemented; 4345c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 4355c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4365c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong case OMX_IndexParamVideoBitrate: 4375c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong { 4385c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_VIDEO_PARAM_BITRATETYPE *bitRate = 4395c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong (OMX_VIDEO_PARAM_BITRATETYPE *) params; 4405c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4415c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (bitRate->nPortIndex != 1) { 4425c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorUndefined; 4435c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 4445c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4455c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong bitRate->eControlRate = OMX_Video_ControlRateVariable; 4465c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong bitRate->nTargetBitrate = mVideoBitRate; 4475c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorNone; 4485c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 4495c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4505c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong case OMX_IndexParamVideoPortFormat: 4515c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong { 4525c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams = 4535c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong (OMX_VIDEO_PARAM_PORTFORMATTYPE *)params; 4545c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4555c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (formatParams->nPortIndex > 1) { 4565c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorUndefined; 4575c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 4585c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 459bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala if (formatParams->nIndex > 2) { 4605c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorNoMore; 4615c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 4625c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4635c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (formatParams->nPortIndex == 0) { 4645c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong formatParams->eCompressionFormat = OMX_VIDEO_CodingUnused; 4655c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (formatParams->nIndex == 0) { 4665c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong formatParams->eColorFormat = OMX_COLOR_FormatYUV420Planar; 467bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala } else if (formatParams->nIndex == 1) { 4685c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong formatParams->eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; 469bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala } else { 470bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala formatParams->eColorFormat = OMX_COLOR_FormatAndroidOpaque; 4715c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 4725c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } else { 4735c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong formatParams->eCompressionFormat = OMX_VIDEO_CodingAVC; 4745c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong formatParams->eColorFormat = OMX_COLOR_FormatUnused; 4755c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 4765c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4775c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorNone; 4785c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 4795c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4805c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong case OMX_IndexParamVideoAvc: 4815c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong { 4825c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_VIDEO_PARAM_AVCTYPE *avcParams = 4835c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong (OMX_VIDEO_PARAM_AVCTYPE *)params; 4845c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4855c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (avcParams->nPortIndex != 1) { 4865c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorUndefined; 4875c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 4885c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4895c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->eProfile = OMX_VIDEO_AVCProfileBaseline; 4905c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_U32 omxLevel = AVC_LEVEL2; 4915c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (OMX_ErrorNone != 4925c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ConvertAvcSpecLevelToOmxAvcLevel(mAVCEncLevel, &omxLevel)) { 4935c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorUndefined; 4945c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 4955c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 4965c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->eLevel = (OMX_VIDEO_AVCLEVELTYPE) omxLevel; 4975c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->nRefFrames = 1; 4985c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->nBFrames = 0; 4995c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->bUseHadamard = OMX_TRUE; 5005c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->nAllowedPictureTypes = 5015c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong (OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP); 5025c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->nRefIdx10ActiveMinus1 = 0; 5035c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->nRefIdx11ActiveMinus1 = 0; 5045c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->bWeightedPPrediction = OMX_FALSE; 5055c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->bEntropyCodingCABAC = OMX_FALSE; 5065c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->bconstIpred = OMX_FALSE; 5075c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->bDirect8x8Inference = OMX_FALSE; 5085c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->bDirectSpatialTemporal = OMX_FALSE; 5095c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcParams->nCabacInitIdc = 0; 5105c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorNone; 5115c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 5125c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 5135c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong case OMX_IndexParamVideoProfileLevelQuerySupported: 5145c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong { 5155c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevel = 5165c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)params; 5175c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 5185c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (profileLevel->nPortIndex != 1) { 5195c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorUndefined; 5205c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 5215c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 5225c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong const size_t size = 5235c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong sizeof(ConversionTable) / sizeof(ConversionTable[0]); 5245c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 5255c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (profileLevel->nProfileIndex >= size) { 5265c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorNoMore; 5275c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 5285c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 5295c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong profileLevel->eProfile = OMX_VIDEO_AVCProfileBaseline; 5305c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong profileLevel->eLevel = ConversionTable[profileLevel->nProfileIndex].omxLevel; 5315c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 5325c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorNone; 5335c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 5345c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 5355c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong default: 5365c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return SimpleSoftOMXComponent::internalGetParameter(index, params); 5375c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 5385c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 5395c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 5405c61b361d1c55a93a215cfb2c325b4987f57f1c5James DongOMX_ERRORTYPE SoftAVCEncoder::internalSetParameter( 5415c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_INDEXTYPE index, const OMX_PTR params) { 542bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala int32_t indexFull = index; 543bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala 544bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala switch (indexFull) { 5455c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong case OMX_IndexParamVideoErrorCorrection: 5465c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong { 5475c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorNotImplemented; 5485c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 5495c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 5505c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong case OMX_IndexParamVideoBitrate: 5515c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong { 5525c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_VIDEO_PARAM_BITRATETYPE *bitRate = 5535c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong (OMX_VIDEO_PARAM_BITRATETYPE *) params; 5545c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 5555c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (bitRate->nPortIndex != 1 || 5565c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong bitRate->eControlRate != OMX_Video_ControlRateVariable) { 5575c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorUndefined; 5585c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 5595c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 5605c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mVideoBitRate = bitRate->nTargetBitrate; 5615c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorNone; 5625c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 5635c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 5645c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong case OMX_IndexParamPortDefinition: 5655c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong { 5665c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_PARAM_PORTDEFINITIONTYPE *def = 5675c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong (OMX_PARAM_PORTDEFINITIONTYPE *)params; 5685c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (def->nPortIndex > 1) { 5695c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorUndefined; 5705c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 5715c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 5725c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (def->nPortIndex == 0) { 5735c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (def->format.video.eCompressionFormat != OMX_VIDEO_CodingUnused || 5745c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong (def->format.video.eColorFormat != OMX_COLOR_FormatYUV420Planar && 575bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala def->format.video.eColorFormat != OMX_COLOR_FormatYUV420SemiPlanar && 576bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala def->format.video.eColorFormat != OMX_COLOR_FormatAndroidOpaque)) { 5775c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorUndefined; 5785c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 5795c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } else { 5805c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (def->format.video.eCompressionFormat != OMX_VIDEO_CodingAVC || 5815c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong (def->format.video.eColorFormat != OMX_COLOR_FormatUnused)) { 5825c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorUndefined; 5835c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 5845c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 5855c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 5865c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_ERRORTYPE err = SimpleSoftOMXComponent::internalSetParameter(index, params); 5875c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (OMX_ErrorNone != err) { 5885c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return err; 5895c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 5905c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 5915c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (def->nPortIndex == 0) { 5925c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mVideoWidth = def->format.video.nFrameWidth; 5935c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mVideoHeight = def->format.video.nFrameHeight; 5945c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mVideoFrameRate = def->format.video.xFramerate >> 16; 5955c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mVideoColorFormat = def->format.video.eColorFormat; 5965c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } else { 5975c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mVideoBitRate = def->format.video.nBitrate; 5985c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 5995c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 6005c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorNone; 6015c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 6025c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 6035c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong case OMX_IndexParamStandardComponentRole: 6045c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong { 6055c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong const OMX_PARAM_COMPONENTROLETYPE *roleParams = 6065c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong (const OMX_PARAM_COMPONENTROLETYPE *)params; 6075c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 6085c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (strncmp((const char *)roleParams->cRole, 6095c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong "video_encoder.avc", 6105c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_MAX_STRINGNAME_SIZE - 1)) { 6115c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorUndefined; 6125c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 6135c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 6145c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorNone; 6155c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 6165c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 6175c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong case OMX_IndexParamVideoPortFormat: 6185c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong { 6195c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong const OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams = 6205c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong (const OMX_VIDEO_PARAM_PORTFORMATTYPE *)params; 6215c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 6225c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (formatParams->nPortIndex > 1) { 6235c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorUndefined; 6245c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 6255c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 626bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala if (formatParams->nIndex > 2) { 6275c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorNoMore; 6285c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 6295c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 6305c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (formatParams->nPortIndex == 0) { 6315c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (formatParams->eCompressionFormat != OMX_VIDEO_CodingUnused || 6325c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ((formatParams->nIndex == 0 && 6335c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong formatParams->eColorFormat != OMX_COLOR_FormatYUV420Planar) || 6345c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong (formatParams->nIndex == 1 && 635bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala formatParams->eColorFormat != OMX_COLOR_FormatYUV420SemiPlanar) || 636bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala (formatParams->nIndex == 2 && 637bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala formatParams->eColorFormat != OMX_COLOR_FormatAndroidOpaque) )) { 6385c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorUndefined; 6395c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 6405c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mVideoColorFormat = formatParams->eColorFormat; 6415c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } else { 6425c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (formatParams->eCompressionFormat != OMX_VIDEO_CodingAVC || 6435c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong formatParams->eColorFormat != OMX_COLOR_FormatUnused) { 6445c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorUndefined; 6455c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 6465c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 6475c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 6485c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorNone; 6495c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 6505c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 6515c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong case OMX_IndexParamVideoAvc: 6525c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong { 6535c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_VIDEO_PARAM_AVCTYPE *avcType = 6545c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong (OMX_VIDEO_PARAM_AVCTYPE *)params; 6555c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 6565c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (avcType->nPortIndex != 1) { 6575c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorUndefined; 6585c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 6595c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 6605c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // PV's AVC encoder only supports baseline profile 6615c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (avcType->eProfile != OMX_VIDEO_AVCProfileBaseline || 6625c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcType->nRefFrames != 1 || 6635c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcType->nBFrames != 0 || 6645c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcType->bUseHadamard != OMX_TRUE || 6655c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong (avcType->nAllowedPictureTypes & OMX_VIDEO_PictureTypeB) != 0 || 6665c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcType->nRefIdx10ActiveMinus1 != 0 || 6675c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcType->nRefIdx11ActiveMinus1 != 0 || 6685c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcType->bWeightedPPrediction != OMX_FALSE || 6695c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcType->bEntropyCodingCABAC != OMX_FALSE || 6705c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcType->bconstIpred != OMX_FALSE || 6715c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcType->bDirect8x8Inference != OMX_FALSE || 6725c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcType->bDirectSpatialTemporal != OMX_FALSE || 6735c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong avcType->nCabacInitIdc != 0) { 6745c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorUndefined; 6755c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 6765c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 6775c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (OK != ConvertOmxAvcLevelToAvcSpecLevel(avcType->eLevel, &mAVCEncLevel)) { 6785c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorUndefined; 6795c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 6805c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 6815c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return OMX_ErrorNone; 6825c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 6835c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 684bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala case kStoreMetaDataExtensionIndex: 685bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala { 686bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala StoreMetaDataInBuffersParams *storeParams = 687bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala (StoreMetaDataInBuffersParams*)params; 688bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala if (storeParams->nPortIndex != 0) { 689bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala ALOGE("%s: StoreMetadataInBuffersParams.nPortIndex not zero!", 690bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala __FUNCTION__); 691bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala return OMX_ErrorUndefined; 692bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala } 693bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala 694bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala mStoreMetaDataInBuffers = storeParams->bStoreMetaData; 695bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala ALOGV("StoreMetaDataInBuffers set to: %s", 696bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala mStoreMetaDataInBuffers ? " true" : "false"); 697bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala 698bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala if (mStoreMetaDataInBuffers) { 699bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala mVideoColorFormat == OMX_COLOR_FormatYUV420SemiPlanar; 700bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala if (mInputFrameData == NULL) { 701bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala mInputFrameData = 702bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala (uint8_t *) malloc((mVideoWidth * mVideoHeight * 3 ) >> 1); 703bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala } 704bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala } 705bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala 706bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala return OMX_ErrorNone; 707bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala } 708bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala 7095c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong default: 7105c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return SimpleSoftOMXComponent::internalSetParameter(index, params); 7115c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 7125c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 7135c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 7145c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongvoid SoftAVCEncoder::onQueueFilled(OMX_U32 portIndex) { 7155c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (mSignalledError || mSawInputEOS) { 7165c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return; 7175c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 7185c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 7195c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (!mStarted) { 7205c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (OMX_ErrorNone != initEncoder()) { 7215c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return; 7225c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 7235c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 7245c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 7255c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong List<BufferInfo *> &inQueue = getPortQueue(0); 7265c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong List<BufferInfo *> &outQueue = getPortQueue(1); 7275c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 7285c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong while (!mSawInputEOS && !inQueue.empty() && !outQueue.empty()) { 7295c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong BufferInfo *inInfo = *inQueue.begin(); 7305c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader; 7315c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong BufferInfo *outInfo = *outQueue.begin(); 7325c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; 7335c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 7345c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outHeader->nTimeStamp = 0; 7355c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outHeader->nFlags = 0; 7365c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outHeader->nOffset = 0; 7375c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outHeader->nFilledLen = 0; 7385c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outHeader->nOffset = 0; 7395c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 7405c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong uint8_t *outPtr = (uint8_t *) outHeader->pBuffer; 7415c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong uint32_t dataLength = outHeader->nAllocLen; 7425c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 7435c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (!mSpsPpsHeaderReceived && mNumInputFrames < 0) { 7445c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // 4 bytes are reserved for holding the start code 0x00000001 7455c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // of the sequence parameter set at the beginning. 7465c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outPtr += 4; 7475c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong dataLength -= 4; 7485c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 7495c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 7505c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong int32_t type; 7515c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong AVCEnc_Status encoderStatus = AVCENC_SUCCESS; 7525c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 7535c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // Combine SPS and PPS and place them in the very first output buffer 7545c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // SPS and PPS are separated by start code 0x00000001 7555c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // Assume that we have exactly one SPS and exactly one PPS. 7565c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong while (!mSpsPpsHeaderReceived && mNumInputFrames <= 0) { 7575c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong encoderStatus = PVAVCEncodeNAL(mHandle, outPtr, &dataLength, &type); 7585c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (encoderStatus == AVCENC_WRONG_STATE) { 7595c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mSpsPpsHeaderReceived = true; 7605c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK_EQ(0, mNumInputFrames); // 1st video frame is 0 7615c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outHeader->nFlags = OMX_BUFFERFLAG_CODECCONFIG; 7625c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outQueue.erase(outQueue.begin()); 7635c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outInfo->mOwnedByUs = false; 7645c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong notifyFillBufferDone(outHeader); 7655c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return; 7665c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } else { 7675c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong switch (type) { 7685c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong case AVC_NALTYPE_SPS: 7695c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ++mNumInputFrames; 7705c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong memcpy((uint8_t *)outHeader->pBuffer, "\x00\x00\x00\x01", 4); 7715c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outHeader->nFilledLen = 4 + dataLength; 7725c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outPtr += (dataLength + 4); // 4 bytes for next start code 7735c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong dataLength = outHeader->nAllocLen - outHeader->nFilledLen; 7745c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong break; 7755c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong default: 7765c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK_EQ(AVC_NALTYPE_PPS, type); 7775c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ++mNumInputFrames; 7785c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong memcpy((uint8_t *) outHeader->pBuffer + outHeader->nFilledLen, 7795c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong "\x00\x00\x00\x01", 4); 7805c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outHeader->nFilledLen += (dataLength + 4); 7815c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outPtr += (dataLength + 4); 7825c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong break; 7835c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 7845c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 7855c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 7865c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 787bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala buffer_handle_t srcBuffer; // for MetaDataMode only 788bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala 7895c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // Get next input video frame 7905c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (mReadyForNextFrame) { 7915c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // Save the input buffer info so that it can be 7925c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // passed to an output buffer 7935c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong InputBufferInfo info; 7945c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong info.mTimeUs = inHeader->nTimeStamp; 7955c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong info.mFlags = inHeader->nFlags; 7965c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mInputBufferInfoVec.push(info); 7975c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mPrevTimestampUs = inHeader->nTimeStamp; 7985c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 7995c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) { 8005c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mSawInputEOS = true; 8015c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 8025c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 8035c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (inHeader->nFilledLen > 0) { 8045c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong AVCFrameIO videoInput; 8055c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong memset(&videoInput, 0, sizeof(videoInput)); 8065c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong videoInput.height = ((mVideoHeight + 15) >> 4) << 4; 8075c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong videoInput.pitch = ((mVideoWidth + 15) >> 4) << 4; 8085c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong videoInput.coding_timestamp = (inHeader->nTimeStamp + 500) / 1000; // in ms 809bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala uint8_t *inputData = NULL; 810bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala if (mStoreMetaDataInBuffers) { 811bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala if (inHeader->nFilledLen != 8) { 812bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala ALOGE("MetaData buffer is wrong size! " 813bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala "(got %lu bytes, expected 8)", inHeader->nFilledLen); 814bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala mSignalledError = true; 815bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 816bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala return; 817bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala } 818bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala inputData = 819bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala extractGrallocData(inHeader->pBuffer + inHeader->nOffset, 820bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala &srcBuffer); 821bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala if (inputData == NULL) { 822bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala ALOGE("Unable to extract gralloc buffer in metadata mode"); 823bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala mSignalledError = true; 824bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 825bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala return; 826bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala } 827bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala // TODO: Verify/convert pixel format enum 828bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala } else { 829bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala inputData = (uint8_t *)inHeader->pBuffer + inHeader->nOffset; 830bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala } 8315c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 8325c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (mVideoColorFormat != OMX_COLOR_FormatYUV420Planar) { 8335c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ConvertYUV420SemiPlanarToYUV420Planar( 8345c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong inputData, mInputFrameData, mVideoWidth, mVideoHeight); 8355c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong inputData = mInputFrameData; 8365c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 8375c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(inputData != NULL); 8385c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong videoInput.YCbCr[0] = inputData; 8395c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong videoInput.YCbCr[1] = videoInput.YCbCr[0] + videoInput.height * videoInput.pitch; 8405c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong videoInput.YCbCr[2] = videoInput.YCbCr[1] + 8415c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ((videoInput.height * videoInput.pitch) >> 2); 8425c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong videoInput.disp_order = mNumInputFrames; 8435c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 8445c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong encoderStatus = PVAVCEncSetInput(mHandle, &videoInput); 8455c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (encoderStatus == AVCENC_SUCCESS || encoderStatus == AVCENC_NEW_IDR) { 8465c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mReadyForNextFrame = false; 8475c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ++mNumInputFrames; 8485c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (encoderStatus == AVCENC_NEW_IDR) { 8495c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mIsIDRFrame = 1; 8505c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 8515c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } else { 8525c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (encoderStatus < AVCENC_SUCCESS) { 8535c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ALOGE("encoderStatus = %d at line %d", encoderStatus, __LINE__); 8545c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mSignalledError = true; 855bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala releaseGrallocData(srcBuffer); 8565c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 8575c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return; 8585c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } else { 8595c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ALOGV("encoderStatus = %d at line %d", encoderStatus, __LINE__); 8605c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong inQueue.erase(inQueue.begin()); 8615c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong inInfo->mOwnedByUs = false; 862bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala releaseGrallocData(srcBuffer); 8635c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong notifyEmptyBufferDone(inHeader); 8645c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return; 8655c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 8665c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 8675c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 8685c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 8695c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 8705c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong // Encode an input video frame 8715c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(encoderStatus == AVCENC_SUCCESS || encoderStatus == AVCENC_NEW_IDR); 8725c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong dataLength = outHeader->nAllocLen; // Reset the output buffer length 8735c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (inHeader->nFilledLen > 0) { 8745c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong encoderStatus = PVAVCEncodeNAL(mHandle, outPtr, &dataLength, &type); 8755c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (encoderStatus == AVCENC_SUCCESS) { 8765c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(NULL == PVAVCEncGetOverrunBuffer(mHandle)); 8775c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } else if (encoderStatus == AVCENC_PICTURE_READY) { 8785c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(NULL == PVAVCEncGetOverrunBuffer(mHandle)); 8795c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (mIsIDRFrame) { 8805c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outHeader->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; 8815c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mIsIDRFrame = false; 8825c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 8835c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mReadyForNextFrame = true; 8845c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong AVCFrameIO recon; 8855c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (PVAVCEncGetRecon(mHandle, &recon) == AVCENC_SUCCESS) { 8865c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong PVAVCEncReleaseRecon(mHandle, &recon); 8875c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 8885c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } else { 8895c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong dataLength = 0; 8905c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mReadyForNextFrame = true; 8915c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 8925c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 8935c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong if (encoderStatus < AVCENC_SUCCESS) { 8945c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ALOGE("encoderStatus = %d at line %d", encoderStatus, __LINE__); 8955c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mSignalledError = true; 896bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala releaseGrallocData(srcBuffer); 8975c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 8985c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return; 8995c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 9005c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } else { 9015c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong dataLength = 0; 9025c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 9035c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 9045c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong inQueue.erase(inQueue.begin()); 9055c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong inInfo->mOwnedByUs = false; 906bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala releaseGrallocData(srcBuffer); 9075c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong notifyEmptyBufferDone(inHeader); 9085c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 9095c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outQueue.erase(outQueue.begin()); 9105c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(!mInputBufferInfoVec.empty()); 9115c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong InputBufferInfo *inputBufInfo = mInputBufferInfoVec.begin(); 9125c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outHeader->nTimeStamp = inputBufInfo->mTimeUs; 9135c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outHeader->nFlags |= (inputBufInfo->mFlags | OMX_BUFFERFLAG_ENDOFFRAME); 914f547a36c8f0fe11c4c425168037e3ce1d1a697dfMartin Storsjo if (mSawInputEOS) { 915f547a36c8f0fe11c4c425168037e3ce1d1a697dfMartin Storsjo outHeader->nFlags |= OMX_BUFFERFLAG_EOS; 916f547a36c8f0fe11c4c425168037e3ce1d1a697dfMartin Storsjo } 9175c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outHeader->nFilledLen = dataLength; 9185c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong outInfo->mOwnedByUs = false; 9195c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong notifyFillBufferDone(outHeader); 920e61f13d2c710918f5267b3c835fcc20447b4e4d6Martin Storsjo mInputBufferInfoVec.erase(mInputBufferInfoVec.begin()); 9215c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 9225c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 9235c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 9245c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongint32_t SoftAVCEncoder::allocOutputBuffers( 9255c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong unsigned int sizeInMbs, unsigned int numBuffers) { 9265c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(mOutputBuffers.isEmpty()); 9275c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong size_t frameSize = (sizeInMbs << 7) * 3; 9285c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong for (unsigned int i = 0; i < numBuffers; ++i) { 9295c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong MediaBuffer *buffer = new MediaBuffer(frameSize); 9305c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong buffer->setObserver(this); 9315c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong mOutputBuffers.push(buffer); 9325c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong } 9335c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 9345c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return 1; 9355c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 9365c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 9375c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongvoid SoftAVCEncoder::unbindOutputBuffer(int32_t index) { 9385c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(index >= 0); 9395c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 9405c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 9415c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongint32_t SoftAVCEncoder::bindOutputBuffer(int32_t index, uint8_t **yuv) { 9425c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(index >= 0); 9435c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong CHECK(index < (int32_t) mOutputBuffers.size()); 9445c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong *yuv = (uint8_t *) mOutputBuffers[index]->data(); 9455c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 9465c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return 1; 9475c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 9485c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 9495c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongvoid SoftAVCEncoder::signalBufferReturned(MediaBuffer *buffer) { 9505c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong ALOGV("signalBufferReturned: %p", buffer); 9515c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 9525c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 953bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville TalvalaOMX_ERRORTYPE SoftAVCEncoder::getExtensionIndex( 954bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala const char *name, OMX_INDEXTYPE *index) { 955bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala if (!strcmp(name, "OMX.google.android.index.storeMetaDataInBuffers")) { 956bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala *(int32_t*)index = kStoreMetaDataExtensionIndex; 957bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala return OMX_ErrorNone; 958bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala } 959bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala return OMX_ErrorUndefined; 960bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala} 961bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala 962bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvalauint8_t *SoftAVCEncoder::extractGrallocData(void *data, buffer_handle_t *buffer) { 963bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala OMX_U32 type = *(OMX_U32*)data; 964bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala status_t res; 965bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala if (type != kMetadataBufferTypeGrallocSource) { 966bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala ALOGE("Data passed in with metadata mode does not have type " 967bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala "kMetadataBufferTypeGrallocSource (%d), has type %ld instead", 968bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala kMetadataBufferTypeGrallocSource, type); 969bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala return NULL; 970bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala } 971bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala buffer_handle_t imgBuffer = *(buffer_handle_t*)((uint8_t*)data + 4); 972bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala 973bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala const Rect rect(mVideoWidth, mVideoHeight); 974bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala uint8_t *img; 975bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala res = GraphicBufferMapper::get().lock(imgBuffer, 976bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala GRALLOC_USAGE_HW_VIDEO_ENCODER, 977bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala rect, (void**)&img); 978bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala if (res != OK) { 979bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala ALOGE("%s: Unable to lock image buffer %p for access", __FUNCTION__, 980bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala imgBuffer); 981bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala return NULL; 982bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala } 983bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala 984bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala *buffer = imgBuffer; 985bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala return img; 986bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala} 987bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala 988bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvalavoid SoftAVCEncoder::releaseGrallocData(buffer_handle_t buffer) { 989bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala if (mStoreMetaDataInBuffers) { 990bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala GraphicBufferMapper::get().unlock(buffer); 991bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala } 992bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala} 993bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala 9945c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} // namespace android 9955c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong 9965c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dongandroid::SoftOMXComponent *createSoftOMXComponent( 9975c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong const char *name, const OMX_CALLBACKTYPE *callbacks, 9985c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong OMX_PTR appData, OMX_COMPONENTTYPE **component) { 9995c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong return new android::SoftAVCEncoder(name, callbacks, appData, component); 10005c61b361d1c55a93a215cfb2c325b4987f57f1c5James Dong} 1001