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