1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17// #define LOG_NDEBUG 0 18#define LOG_TAG "SoftVP9Encoder" 19#include "SoftVP9Encoder.h" 20 21#include <utils/Log.h> 22#include <utils/misc.h> 23 24#include <media/hardware/HardwareAPI.h> 25#include <media/hardware/MetadataBufferType.h> 26#include <media/stagefright/foundation/ADebug.h> 27#include <media/stagefright/MediaDefs.h> 28 29namespace android { 30 31static const CodecProfileLevel kVp9ProfileLevels[] = { 32 { OMX_VIDEO_VP9Profile0, OMX_VIDEO_VP9Level41 }, 33}; 34 35SoftVP9Encoder::SoftVP9Encoder( 36 const char *name, const OMX_CALLBACKTYPE *callbacks, OMX_PTR appData, 37 OMX_COMPONENTTYPE **component) 38 : SoftVPXEncoder( 39 name, callbacks, appData, component, "video_encoder.vp9", 40 OMX_VIDEO_CodingVP9, MEDIA_MIMETYPE_VIDEO_VP9, 4, 41 kVp9ProfileLevels, NELEM(kVp9ProfileLevels)), 42 mLevel(OMX_VIDEO_VP9Level1), 43 mTileColumns(0), 44 mFrameParallelDecoding(OMX_FALSE) { 45} 46 47void SoftVP9Encoder::setCodecSpecificInterface() { 48 mCodecInterface = vpx_codec_vp9_cx(); 49} 50 51void SoftVP9Encoder::setCodecSpecificConfiguration() { 52 mCodecConfiguration->g_profile = 0; 53} 54 55vpx_codec_err_t SoftVP9Encoder::setCodecSpecificControls() { 56 vpx_codec_err_t codecReturn = vpx_codec_control( 57 mCodecContext, VP9E_SET_TILE_COLUMNS, mTileColumns); 58 if (codecReturn != VPX_CODEC_OK) { 59 ALOGE("Error setting VP9E_SET_TILE_COLUMNS to %d. vpx_codec_control() " 60 "returned %d", mTileColumns, codecReturn); 61 return codecReturn; 62 } 63 codecReturn = vpx_codec_control( 64 mCodecContext, VP9E_SET_FRAME_PARALLEL_DECODING, 65 mFrameParallelDecoding); 66 if (codecReturn != VPX_CODEC_OK) { 67 ALOGE("Error setting VP9E_SET_FRAME_PARALLEL_DECODING to %d." 68 "vpx_codec_control() returned %d", mFrameParallelDecoding, 69 codecReturn); 70 return codecReturn; 71 } 72 codecReturn = vpx_codec_control(mCodecContext, VP9E_SET_ROW_MT, 1); 73 if (codecReturn != VPX_CODEC_OK) { 74 ALOGE("Error setting VP9E_SET_ROW_MT to 1. vpx_codec_control() " 75 "returned %d", codecReturn); 76 return codecReturn; 77 } 78 79 // For VP9, we always set CPU_USED to 8 (because the realtime default is 0 80 // which is too slow). 81 codecReturn = vpx_codec_control(mCodecContext, VP8E_SET_CPUUSED, 8); 82 if (codecReturn != VPX_CODEC_OK) { 83 ALOGE("Error setting VP8E_SET_CPUUSED to 8. vpx_codec_control() " 84 "returned %d", codecReturn); 85 return codecReturn; 86 } 87 return codecReturn; 88} 89 90OMX_ERRORTYPE SoftVP9Encoder::internalGetParameter( 91 OMX_INDEXTYPE index, OMX_PTR param) { 92 // can include extension index OMX_INDEXEXTTYPE 93 const int32_t indexFull = index; 94 95 switch (indexFull) { 96 case OMX_IndexParamVideoVp9: 97 return internalGetVp9Params( 98 (OMX_VIDEO_PARAM_VP9TYPE *)param); 99 100 default: 101 return SoftVPXEncoder::internalGetParameter(index, param); 102 } 103} 104 105OMX_ERRORTYPE SoftVP9Encoder::internalSetParameter( 106 OMX_INDEXTYPE index, const OMX_PTR param) { 107 // can include extension index OMX_INDEXEXTTYPE 108 const int32_t indexFull = index; 109 110 switch (indexFull) { 111 case OMX_IndexParamVideoVp9: 112 return internalSetVp9Params( 113 (const OMX_VIDEO_PARAM_VP9TYPE *)param); 114 115 default: 116 return SoftVPXEncoder::internalSetParameter(index, param); 117 } 118} 119 120OMX_ERRORTYPE SoftVP9Encoder::internalGetVp9Params( 121 OMX_VIDEO_PARAM_VP9TYPE *vp9Params) { 122 if (vp9Params->nPortIndex != kOutputPortIndex) { 123 return OMX_ErrorUnsupportedIndex; 124 } 125 126 vp9Params->eProfile = OMX_VIDEO_VP9Profile0; 127 vp9Params->eLevel = mLevel; 128 vp9Params->bErrorResilientMode = mErrorResilience; 129 vp9Params->nTileColumns = mTileColumns; 130 vp9Params->bEnableFrameParallelDecoding = mFrameParallelDecoding; 131 return OMX_ErrorNone; 132} 133 134OMX_ERRORTYPE SoftVP9Encoder::internalSetVp9Params( 135 const OMX_VIDEO_PARAM_VP9TYPE *vp9Params) { 136 if (vp9Params->nPortIndex != kOutputPortIndex) { 137 return OMX_ErrorUnsupportedIndex; 138 } 139 140 if (vp9Params->eProfile != OMX_VIDEO_VP9Profile0) { 141 return OMX_ErrorBadParameter; 142 } 143 144 if (vp9Params->eLevel == OMX_VIDEO_VP9Level1 || 145 vp9Params->eLevel == OMX_VIDEO_VP9Level11 || 146 vp9Params->eLevel == OMX_VIDEO_VP9Level2 || 147 vp9Params->eLevel == OMX_VIDEO_VP9Level21 || 148 vp9Params->eLevel == OMX_VIDEO_VP9Level3 || 149 vp9Params->eLevel == OMX_VIDEO_VP9Level31 || 150 vp9Params->eLevel == OMX_VIDEO_VP9Level4 || 151 vp9Params->eLevel == OMX_VIDEO_VP9Level41 || 152 vp9Params->eLevel == OMX_VIDEO_VP9Level5 || 153 vp9Params->eLevel == OMX_VIDEO_VP9Level51 || 154 vp9Params->eLevel == OMX_VIDEO_VP9Level52 || 155 vp9Params->eLevel == OMX_VIDEO_VP9Level6 || 156 vp9Params->eLevel == OMX_VIDEO_VP9Level61 || 157 vp9Params->eLevel == OMX_VIDEO_VP9Level62) { 158 mLevel = vp9Params->eLevel; 159 } else { 160 return OMX_ErrorBadParameter; 161 } 162 163 mErrorResilience = vp9Params->bErrorResilientMode; 164 mTileColumns = vp9Params->nTileColumns; 165 mFrameParallelDecoding = vp9Params->bEnableFrameParallelDecoding; 166 return OMX_ErrorNone; 167} 168 169} // namespace android 170