VP8TrackEncoder.h (5793B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 4 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #ifndef VP8TrackEncoder_h_ 7 #define VP8TrackEncoder_h_ 8 9 #include <vpx/vpx_codec.h> 10 11 #include "TimeUnits.h" 12 #include "TrackEncoder.h" 13 #include "mozilla/RollingMean.h" 14 15 namespace mozilla { 16 17 typedef struct vpx_codec_ctx vpx_codec_ctx_t; 18 typedef struct vpx_codec_enc_cfg vpx_codec_enc_cfg_t; 19 typedef struct vpx_image vpx_image_t; 20 21 class VP8Metadata; 22 23 /** 24 * VP8TrackEncoder implements VideoTrackEncoder by using the libvpx library. 25 * We implement a realtime and variable frame rate encoder. In order to achieve 26 * that, there is a frame-drop encoding policy implemented in Encode(). 27 */ 28 class VP8TrackEncoder : public VideoTrackEncoder { 29 enum EncodeOperation { 30 ENCODE_NORMAL_FRAME, // VP8 track encoder works normally. 31 ENCODE_I_FRAME, // The next frame will be encoded as I-Frame. 32 SKIP_FRAME, // Skip the next frame. 33 }; 34 35 public: 36 VP8TrackEncoder(RefPtr<DriftCompensator> aDriftCompensator, 37 TrackRate aTrackRate, 38 MediaQueue<EncodedFrame>& aEncodedDataQueue, 39 FrameDroppingMode aFrameDroppingMode, 40 Maybe<float> aKeyFrameIntervalFactor = Nothing()); 41 virtual ~VP8TrackEncoder(); 42 43 already_AddRefed<TrackMetadataBase> GetMetadata() final; 44 45 protected: 46 nsresult Init(int32_t aWidth, int32_t aHeight, int32_t aDisplayWidth, 47 int32_t aDisplayHeight, float aEstimatedFrameRate) final; 48 49 private: 50 // Initiates the underlying vpx encoder. 51 nsresult InitInternal(int32_t aWidth, int32_t aHeight, 52 int32_t aMaxKeyFrameDistance); 53 54 // Get the EncodeOperation for next target frame. 55 EncodeOperation GetNextEncodeOperation(TimeDuration aTimeElapsed, 56 TimeDuration aProcessedDuration); 57 58 // Extracts the encoded data from the underlying encoder and returns it. 59 // Return value: An EncodedFrame if a frame was extracted. 60 // nullptr if we reached end-of-stream or nothing was available 61 // from the underlying encoder. 62 // An error nsresult otherwise. 63 Result<RefPtr<EncodedFrame>, nsresult> ExtractEncodedData(); 64 65 // Takes the data in aSegment, encodes it, extracts it, and pushes it to 66 // mEncodedDataQueue. 67 nsresult Encode(VideoSegment* aSegment) final; 68 69 // Prepare the input data to the mVPXImageWrapper for encoding. 70 nsresult PrepareRawFrame(VideoChunk& aChunk); 71 72 // Re-configures an existing encoder with a new frame size. 73 nsresult Reconfigure(int32_t aWidth, int32_t aHeight, 74 int32_t aMaxKeyFrameDistance); 75 76 // Destroys the context and image wrapper. Does not de-allocate the structs. 77 void Destroy(); 78 79 // Helper that calculates the desired max keyframe distance (vp8 config's 80 // max_kf_dist) based on configured key frame interval and recent framerate. 81 // Returns Nothing if not enough input data is available. 82 Maybe<int32_t> CalculateMaxKeyFrameDistance( 83 Maybe<float> aEstimatedFrameRate = Nothing()) const; 84 85 void SetMaxKeyFrameDistance(int32_t aMaxKeyFrameDistance); 86 87 // VP8 Metadata, set on successfuly Init and never modified again. 88 RefPtr<VP8Metadata> mMetadata; 89 90 // The width the encoder is currently configured with. The input frames to the 91 // underlying encoder must match this width, i.e., the underlying encoder will 92 // not do any resampling. 93 int mFrameWidth = 0; 94 95 // The height the encoder is currently configured with. The input frames to 96 // the underlying encoder must match this height, i.e., the underlying encoder 97 // will not do any resampling. 98 int mFrameHeight = 0; 99 100 // Encoded timestamp. 101 TrackTime mEncodedTimestamp = 0; 102 103 // Total duration in mTrackRate extracted from the underlying encoder. 104 CheckedInt64 mExtractedDuration; 105 106 // Total duration extracted from the underlying encoder. 107 media::TimeUnit mExtractedDurationUs; 108 109 // Muted frame, we only create it once. 110 RefPtr<layers::Image> mMuteFrame; 111 112 // I420 frame, for converting to I420. 113 UniquePtr<uint8_t[]> mI420Frame; 114 size_t mI420FrameSize = 0; 115 116 /** 117 * A duration of non-key frames in mTrackRate. 118 */ 119 TrackTime mDurationSinceLastKeyframe = 0; 120 121 /** 122 * The max interval at which a keyframe gets forced (causing video quality 123 * degradation). The encoder is configured to encode keyframes more often than 124 * this, though it can vary based on frame rate. 125 */ 126 const TimeDuration mKeyFrameInterval; 127 128 /** 129 * A factor used to multiply the estimated key-frame-interval based on 130 * mKeyFrameInterval (ms) with when configuring kf_max_dist in the encoder. 131 * The goal is to set it a bit below 1.0 to avoid falling back to forcing 132 * keyframes. 133 * NB that for purposes of testing the mKeyFrameInterval fallback this may be 134 * set to values higher than 1.0. 135 */ 136 float mKeyFrameIntervalFactor; 137 138 /** 139 * Time when we last updated the key-frame-distance. 140 */ 141 media::TimeUnit mLastKeyFrameDistanceUpdate; 142 143 /** 144 * The frame duration value last used to configure kf_max_dist. 145 */ 146 Maybe<int32_t> mMaxKeyFrameDistance; 147 148 /** 149 * The mean duration of recent frames. 150 */ 151 RollingMean<TimeDuration, TimeDuration> mMeanFrameDuration{30}; 152 153 /** 154 * The mean wall-clock time it took to encode recent frames. 155 */ 156 RollingMean<TimeDuration, TimeDuration> mMeanFrameEncodeDuration{30}; 157 158 // VP8 relative members. 159 // Codec context structure. 160 vpx_codec_ctx_t mVPXContext; 161 // Image Descriptor. 162 vpx_image_t mVPXImageWrapper; 163 }; 164 165 } // namespace mozilla 166 167 #endif