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