1 /* 2 * Copyright 2018 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 #ifndef ANDROID_C2_SOFT_VPX_ENC_H__ 18 #define ANDROID_C2_SOFT_VPX_ENC_H__ 19 20 #include <media/stagefright/foundation/MediaDefs.h> 21 22 #include <C2PlatformSupport.h> 23 #include <Codec2BufferUtils.h> 24 #include <SimpleC2Component.h> 25 #include <SimpleC2Interface.h> 26 #include <util/C2InterfaceHelper.h> 27 28 #include "vpx/vpx_encoder.h" 29 #include "vpx/vpx_codec.h" 30 #include "vpx/vpx_image.h" 31 #include "vpx/vp8cx.h" 32 33 namespace android { 34 35 // TODO: These defs taken from deprecated OMX_VideoExt.h. Move these definitions 36 // to a new header file and include it. 37 38 /** Maximum number of temporal layers */ 39 #define MAXTEMPORALLAYERS 3 40 41 /** temporal layer patterns */ 42 typedef enum TemporalPatternType { 43 VPXTemporalLayerPatternNone = 0, 44 VPXTemporalLayerPatternWebRTC = 1, 45 VPXTemporalLayerPatternMax = 0x7FFFFFFF 46 } TemporalPatternType; 47 48 // Base class for a VPX Encoder Component 49 // 50 // Only following encoder settings are available (codec specific settings might 51 // be available in the sub-classes): 52 // - video resolution 53 // - target bitrate 54 // - rate control (constant / variable) 55 // - frame rate 56 // - error resilience 57 // - reconstruction & loop filters (g_profile) 58 // 59 // Only following color formats are recognized 60 // - C2PlanarLayout::TYPE_RGB 61 // - C2PlanarLayout::TYPE_RGBA 62 // 63 // Following settings are not configurable by the client 64 // - encoding deadline is realtime 65 // - multithreaded encoding utilizes a number of threads equal 66 // to online cpu's available 67 // - the algorithm interface for encoder is decided by the sub-class in use 68 // - fractional bits of frame rate is discarded 69 // - timestamps are in microseconds, therefore encoder timebase is fixed 70 // to 1/1000000 71 72 struct C2SoftVpxEnc : public SimpleC2Component { 73 class IntfImpl; 74 75 C2SoftVpxEnc(const char* name, c2_node_id_t id, 76 const std::shared_ptr<IntfImpl>& intfImpl); 77 78 // From SimpleC2Component 79 c2_status_t onInit() override final; 80 c2_status_t onStop() override final; 81 void onReset() override final; 82 void onRelease() override final; 83 c2_status_t onFlush_sm() override final; 84 85 void process( 86 const std::unique_ptr<C2Work> &work, 87 const std::shared_ptr<C2BlockPool> &pool) override final; 88 c2_status_t drain( 89 uint32_t drainMode, 90 const std::shared_ptr<C2BlockPool> &pool) override final; 91 92 protected: 93 std::shared_ptr<IntfImpl> mIntf; 94 virtual ~C2SoftVpxEnc(); 95 96 // Initializes vpx encoder with available settings. 97 status_t initEncoder(); 98 99 // Populates mCodecInterface with codec specific settings. 100 virtual void setCodecSpecificInterface() = 0; 101 102 // Sets codec specific configuration. 103 virtual void setCodecSpecificConfiguration() = 0; 104 105 // Sets codec specific encoder controls. 106 virtual vpx_codec_err_t setCodecSpecificControls() = 0; 107 108 // Get current encode flags. 109 virtual vpx_enc_frame_flags_t getEncodeFlags(); 110 111 enum TemporalReferences { 112 // For 1 layer case: reference all (last, golden, and alt ref), but only 113 // update last. 114 kTemporalUpdateLastRefAll = 12, 115 // First base layer frame for 3 temporal layers, which updates last and 116 // golden with alt ref dependency. 117 kTemporalUpdateLastAndGoldenRefAltRef = 11, 118 // First enhancement layer with alt ref dependency. 119 kTemporalUpdateGoldenRefAltRef = 10, 120 // First enhancement layer with alt ref dependency. 121 kTemporalUpdateGoldenWithoutDependencyRefAltRef = 9, 122 // Base layer with alt ref dependency. 123 kTemporalUpdateLastRefAltRef = 8, 124 // Highest enhacement layer without dependency on golden with alt ref 125 // dependency. 126 kTemporalUpdateNoneNoRefGoldenRefAltRef = 7, 127 // Second layer and last frame in cycle, for 2 layers. 128 kTemporalUpdateNoneNoRefAltref = 6, 129 // Highest enhancement layer. 130 kTemporalUpdateNone = 5, 131 // Second enhancement layer. 132 kTemporalUpdateAltref = 4, 133 // Second enhancement layer without dependency on previous frames in 134 // the second enhancement layer. 135 kTemporalUpdateAltrefWithoutDependency = 3, 136 // First enhancement layer. 137 kTemporalUpdateGolden = 2, 138 // First enhancement layer without dependency on previous frames in 139 // the first enhancement layer. 140 kTemporalUpdateGoldenWithoutDependency = 1, 141 // Base layer. 142 kTemporalUpdateLast = 0, 143 }; 144 enum { 145 kMaxTemporalPattern = 8 146 }; 147 148 // vpx specific opaque data structure that 149 // stores encoder state 150 vpx_codec_ctx_t* mCodecContext; 151 152 // vpx specific data structure that 153 // stores encoder configuration 154 vpx_codec_enc_cfg_t* mCodecConfiguration; 155 156 // vpx specific read-only data structure 157 // that specifies algorithm interface (e.g. vp8) 158 vpx_codec_iface_t* mCodecInterface; 159 160 // align stride to the power of 2 161 int32_t mStrideAlign; 162 163 // target bitrate set for the encoder, in bits per second 164 uint32_t mBitrate; 165 166 // target framerate set for the encoder 167 uint32_t mFramerate; 168 169 // Color format for the input port 170 vpx_img_fmt_t mColorFormat; 171 172 // If a request for a change it bitrate has been received. 173 bool mBitrateUpdated; 174 175 // Bitrate control mode, either constant or variable 176 vpx_rc_mode mBitrateControlMode; 177 178 // Parameter that denotes whether error resilience 179 // is enabled in encoder 180 bool mErrorResilience; 181 182 // Key frame interval in frames 183 uint32_t mKeyFrameInterval; 184 185 // Minimum (best quality) quantizer 186 uint32_t mMinQuantizer; 187 188 // Maximum (worst quality) quantizer 189 uint32_t mMaxQuantizer; 190 191 // Number of coding temporal layers to be used. 192 size_t mTemporalLayers; 193 194 // Temporal layer bitrare ratio in percentage 195 uint32_t mTemporalLayerBitrateRatio[MAXTEMPORALLAYERS]; 196 197 // Temporal pattern type 198 TemporalPatternType mTemporalPatternType; 199 200 // Temporal pattern length 201 size_t mTemporalPatternLength; 202 203 // Temporal pattern current index 204 size_t mTemporalPatternIdx; 205 206 // Frame type temporal pattern 207 TemporalReferences mTemporalPattern[kMaxTemporalPattern]; 208 209 // Last input buffer timestamp 210 uint64_t mLastTimestamp; 211 212 // Number of input frames 213 int64_t mNumInputFrames; 214 215 // Conversion buffer is needed to input to 216 // yuv420 planar format. 217 MemoryBlock mConversionBuffer; 218 219 // Request Key Frame 220 bool mKeyFrameRequested; 221 222 // Signalled EOS 223 bool mSignalledOutputEos; 224 225 // Signalled Error 226 bool mSignalledError; 227 228 C2_DO_NOT_COPY(C2SoftVpxEnc); 229 }; 230 231 class C2SoftVpxEnc::IntfImpl : public C2InterfaceHelper { 232 public: IntfImpl(const std::shared_ptr<C2ReflectorHelper> & helper)233 explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper>& helper) 234 : C2InterfaceHelper(helper) { 235 setDerivedInstance(this); 236 237 addParameter( 238 DefineParam(mInputFormat, C2_NAME_INPUT_STREAM_FORMAT_SETTING) 239 .withConstValue( 240 new C2StreamFormatConfig::input(0u, C2FormatVideo)) 241 .build()); 242 243 addParameter( 244 DefineParam(mOutputFormat, C2_NAME_OUTPUT_STREAM_FORMAT_SETTING) 245 .withConstValue( 246 new C2StreamFormatConfig::output(0u, C2FormatCompressed)) 247 .build()); 248 249 addParameter( 250 DefineParam(mInputMediaType, C2_NAME_INPUT_PORT_MIME_SETTING) 251 .withConstValue(AllocSharedString<C2PortMimeConfig::input>( 252 MEDIA_MIMETYPE_VIDEO_RAW)) 253 .build()); 254 255 addParameter( 256 DefineParam(mOutputMediaType, C2_NAME_OUTPUT_PORT_MIME_SETTING) 257 .withConstValue(AllocSharedString<C2PortMimeConfig::output>( 258 #ifdef VP9 259 MEDIA_MIMETYPE_VIDEO_VP9 260 #else 261 MEDIA_MIMETYPE_VIDEO_VP8 262 #endif 263 )) 264 .build()); 265 266 addParameter(DefineParam(mUsage, C2_NAME_INPUT_STREAM_USAGE_SETTING) 267 .withConstValue(new C2StreamUsageTuning::input( 268 0u, (uint64_t)C2MemoryUsage::CPU_READ)) 269 .build()); 270 271 addParameter( 272 DefineParam(mSize, C2_NAME_STREAM_VIDEO_SIZE_SETTING) 273 .withDefault(new C2VideoSizeStreamTuning::input(0u, 320, 240)) 274 .withFields({ 275 C2F(mSize, width).inRange(2, 2048, 2), 276 C2F(mSize, height).inRange(2, 2048, 2), 277 }) 278 .withSetter(SizeSetter) 279 .build()); 280 281 addParameter( 282 DefineParam(mFrameRate, C2_NAME_STREAM_FRAME_RATE_SETTING) 283 .withDefault(new C2StreamFrameRateInfo::output(0u, 30.)) 284 // TODO: More restriction? 285 .withFields({C2F(mFrameRate, value).greaterThan(0.)}) 286 .withSetter( 287 Setter<decltype(*mFrameRate)>::StrictValueWithNoDeps) 288 .build()); 289 290 addParameter( 291 DefineParam(mBitrate, C2_NAME_STREAM_BITRATE_SETTING) 292 .withDefault(new C2BitrateTuning::output(0u, 64000)) 293 .withFields({C2F(mBitrate, value).inRange(1, 40000000)}) 294 .withSetter( 295 Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps) 296 .build()); 297 } 298 SizeSetter(bool mayBlock,C2P<C2VideoSizeStreamTuning::input> & me)299 static C2R SizeSetter(bool mayBlock, 300 C2P<C2VideoSizeStreamTuning::input>& me) { 301 (void)mayBlock; 302 // TODO: maybe apply block limit? 303 C2R res = C2R::Ok(); 304 if (!me.F(me.v.width).supportsAtAll(me.v.width)) { 305 res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.width))); 306 } 307 if (!me.F(me.v.height).supportsAtAll(me.v.height)) { 308 res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.height))); 309 } 310 return res; 311 } 312 getWidth()313 uint32_t getWidth() const { return mSize->width; } getHeight()314 uint32_t getHeight() const { return mSize->height; } getFrameRate()315 float getFrameRate() const { return mFrameRate->value; } getBitrate()316 uint32_t getBitrate() const { return mBitrate->value; } 317 318 private: 319 std::shared_ptr<C2StreamFormatConfig::input> mInputFormat; 320 std::shared_ptr<C2StreamFormatConfig::output> mOutputFormat; 321 std::shared_ptr<C2PortMimeConfig::input> mInputMediaType; 322 std::shared_ptr<C2PortMimeConfig::output> mOutputMediaType; 323 std::shared_ptr<C2StreamUsageTuning::input> mUsage; 324 std::shared_ptr<C2VideoSizeStreamTuning::input> mSize; 325 std::shared_ptr<C2StreamFrameRateInfo::output> mFrameRate; 326 std::shared_ptr<C2BitrateTuning::output> mBitrate; 327 }; 328 329 } // namespace android 330 331 #endif // ANDROID_C2_SOFT_VPX_ENC_H__ 332