1 // Copyright 2015 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef MEDIA_CAST_SENDER_SIZE_ADAPTABLE_VIDEO_ENCODER_BASE_H_ 6 #define MEDIA_CAST_SENDER_SIZE_ADAPTABLE_VIDEO_ENCODER_BASE_H_ 7 8 #include <stdint.h> 9 10 #include <memory> 11 12 #include "base/macros.h" 13 #include "base/memory/ref_counted.h" 14 #include "base/memory/weak_ptr.h" 15 #include "media/cast/cast_config.h" 16 #include "media/cast/cast_environment.h" 17 #include "media/cast/constants.h" 18 #include "media/cast/sender/video_encoder.h" 19 #include "ui/gfx/geometry/size.h" 20 21 namespace media { 22 namespace cast { 23 24 // Creates and owns a VideoEncoder instance. The owned instance is an 25 // implementation that does not support changing frame sizes, and so 26 // SizeAdaptableVideoEncoderBase acts as a proxy to automatically detect when 27 // the owned instance should be replaced with one that can handle the new frame 28 // size. 29 class SizeAdaptableVideoEncoderBase : public VideoEncoder { 30 public: 31 SizeAdaptableVideoEncoderBase( 32 const scoped_refptr<CastEnvironment>& cast_environment, 33 const FrameSenderConfig& video_config, 34 StatusChangeCallback status_change_cb); 35 36 ~SizeAdaptableVideoEncoderBase() override; 37 38 // VideoEncoder implementation. 39 bool EncodeVideoFrame(scoped_refptr<media::VideoFrame> video_frame, 40 base::TimeTicks reference_time, 41 FrameEncodedCallback frame_encoded_callback) final; 42 void SetBitRate(int new_bit_rate) final; 43 void GenerateKeyFrame() final; 44 std::unique_ptr<VideoFrameFactory> CreateVideoFrameFactory() final; 45 void EmitFrames() final; 46 47 protected: 48 // Accessors for subclasses. cast_environment()49 CastEnvironment* cast_environment() const { 50 return cast_environment_.get(); 51 } video_config()52 const FrameSenderConfig& video_config() const { return video_config_; } frame_size()53 const gfx::Size& frame_size() const { 54 return frame_size_; 55 } next_frame_id()56 FrameId next_frame_id() const { return next_frame_id_; } 57 58 // Returns a callback that calls OnEncoderStatusChange(). The callback is 59 // canceled by invalidating its bound weak pointer just before a replacement 60 // encoder is instantiated. In this scheme, OnEncoderStatusChange() can only 61 // be called by the most-recent encoder. 62 StatusChangeCallback CreateEncoderStatusChangeCallback(); 63 64 // Overridden by subclasses to create a new encoder instance that handles 65 // frames of the size specified by |frame_size()|. 66 virtual std::unique_ptr<VideoEncoder> CreateEncoder() = 0; 67 68 // Overridden by subclasses to perform additional steps when 69 // |replacement_encoder| becomes the active encoder. 70 virtual void OnEncoderReplaced(VideoEncoder* replacement_encoder); 71 72 // Overridden by subclasses to perform additional steps before/after the 73 // current encoder is destroyed. 74 virtual void DestroyEncoder(); 75 76 private: 77 // Create and initialize a replacement video encoder, if this not already 78 // in-progress. The replacement will call back to OnEncoderStatusChange() 79 // with success/fail status. 80 void TrySpawningReplacementEncoder(const gfx::Size& size_needed); 81 82 // Called when a status change is received from an encoder. 83 void OnEncoderStatusChange(OperationalStatus status); 84 85 // Called by the |encoder_| with the next EncodedFrame. 86 void OnEncodedVideoFrame(FrameEncodedCallback frame_encoded_callback, 87 std::unique_ptr<SenderEncodedFrame> encoded_frame); 88 89 const scoped_refptr<CastEnvironment> cast_environment_; 90 91 // This is not const since |video_config_.starting_bitrate| is modified by 92 // SetBitRate(), for when a replacement encoder is spawned. 93 FrameSenderConfig video_config_; 94 95 // Run whenever the underlying encoder reports a status change. 96 const StatusChangeCallback status_change_cb_; 97 98 // The underlying platform video encoder and the frame size it expects. 99 std::unique_ptr<VideoEncoder> encoder_; 100 gfx::Size frame_size_; 101 102 // The number of frames in |encoder_|'s pipeline. If this is set to 103 // kEncoderIsInitializing, |encoder_| is not yet ready to accept frames. 104 enum { kEncoderIsInitializing = -1 }; 105 int frames_in_encoder_; 106 107 // The ID for the next frame to be emitted. 108 FrameId next_frame_id_; 109 110 // NOTE: Weak pointers must be invalidated before all other member variables. 111 base::WeakPtrFactory<SizeAdaptableVideoEncoderBase> weak_factory_{this}; 112 113 DISALLOW_COPY_AND_ASSIGN(SizeAdaptableVideoEncoderBase); 114 }; 115 116 } // namespace cast 117 } // namespace media 118 119 #endif // MEDIA_CAST_SENDER_SIZE_ADAPTABLE_VIDEO_ENCODER_BASE_H_ 120