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
131
media / mojo / clients / mojo_video_encoder_metrics_provider.cc [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "media/mojo/clients/mojo_video_encoder_metrics_provider.h"
#include "base/sequence_checker.h"
#include "base/thread_annotations.h"
#include "media/base/encoder_status.h"
#include "media/base/svc_scalability_mode.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "ui/gfx/geometry/size.h"
namespace media {
class MojoVideoEncoderMetricsProviderFactory::MojoVideoEncoderMetricsProvider
: public VideoEncoderMetricsProvider {
public:
MojoVideoEncoderMetricsProvider(
scoped_refptr<MojoVideoEncoderMetricsProviderFactory> factory,
mojom::VideoEncoderUseCase use_case,
uint64_t encoder_id)
: factory_(std::move(factory)),
use_case_(use_case),
encoder_id_(encoder_id) {
DETACH_FROM_SEQUENCE(sequence_checker_);
}
~MojoVideoEncoderMetricsProvider() override {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (initialized_) {
CHECK(remote_);
(*remote_)->Complete(encoder_id_);
}
}
void Initialize(VideoCodecProfile codec_profile,
const gfx::Size& encode_size,
bool is_hardware_encoder,
SVCScalabilityMode svc_mode) override {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
initialized_ = true;
num_encoded_frames_ = 0;
if (!remote_) {
remote_ = factory_->GetRemote();
}
(*remote_)->Initialize(encoder_id_, use_case_, codec_profile, encode_size,
is_hardware_encoder, svc_mode);
}
void IncrementEncodedFrameCount() override {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!remote_) {
DLOG(WARNING) << __func__ << "is called before Initialize()";
return;
}
++num_encoded_frames_;
constexpr size_t kEncodedFrameCountBucketSize = 100;
// Basically update the number of encoded frames every 100 seconds to avoid
// the frequent mojo call. The exception is the first encoded frames update
// as it is important to represent whether the encoding actually starts.
if (num_encoded_frames_ % kEncodedFrameCountBucketSize == 0 ||
num_encoded_frames_ == 1u) {
(*remote_)->SetEncodedFrameCount(encoder_id_, num_encoded_frames_);
}
}
void SetError(const media::EncoderStatus& status) override {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
CHECK(!status.is_ok());
if (!remote_) {
DLOG(WARNING) << __func__ << "is called before Initialize()";
return;
}
(*remote_)->SetError(encoder_id_, status);
}
private:
// To guarantee |remote_| is valid as long as MojoVideoEncoderMetricsProvider
// is alive.
const scoped_refptr<MojoVideoEncoderMetricsProviderFactory> factory_;
raw_ptr<mojo::Remote<mojom::VideoEncoderMetricsProvider>> remote_
GUARDED_BY_CONTEXT(sequence_checker_){nullptr};
const mojom::VideoEncoderUseCase use_case_
GUARDED_BY_CONTEXT(sequence_checker_);
const uint64_t encoder_id_ GUARDED_BY_CONTEXT(sequence_checker_);
size_t num_encoded_frames_ GUARDED_BY_CONTEXT(sequence_checker_){0};
bool initialized_ GUARDED_BY_CONTEXT(sequence_checker_){false};
SEQUENCE_CHECKER(sequence_checker_);
};
MojoVideoEncoderMetricsProviderFactory::MojoVideoEncoderMetricsProviderFactory(
mojom::VideoEncoderUseCase use_case,
mojo::PendingRemote<mojom::VideoEncoderMetricsProvider> pending_remote)
: use_case_(use_case), pending_remote_(std::move(pending_remote)) {
DETACH_FROM_SEQUENCE(remote_sequence_checker_);
DETACH_FROM_SEQUENCE(create_provider_sequence_checker_);
}
MojoVideoEncoderMetricsProviderFactory::
~MojoVideoEncoderMetricsProviderFactory() {
DCHECK_CALLED_ON_VALID_SEQUENCE(remote_sequence_checker_);
}
MojoVideoEncoderMetricsProviderFactory::MojoVideoEncoderMetricsProviderFactory(
mojom::VideoEncoderUseCase use_case)
: use_case_(use_case) {
DETACH_FROM_SEQUENCE(remote_sequence_checker_);
DETACH_FROM_SEQUENCE(create_provider_sequence_checker_);
}
mojo::Remote<mojom::VideoEncoderMetricsProvider>*
MojoVideoEncoderMetricsProviderFactory::GetRemote() {
DCHECK_CALLED_ON_VALID_SEQUENCE(remote_sequence_checker_);
if (pending_remote_.is_valid()) {
remote_.Bind(std::move(pending_remote_));
}
return &remote_;
}
std::unique_ptr<VideoEncoderMetricsProvider>
MojoVideoEncoderMetricsProviderFactory::CreateVideoEncoderMetricsProvider() {
DCHECK_CALLED_ON_VALID_SEQUENCE(create_provider_sequence_checker_);
return std::make_unique<MojoVideoEncoderMetricsProvider>(this, use_case_,
encoder_id_++);
}
} // namespace media