File: video_encoder.h

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (207 lines) | stat: -rw-r--r-- 7,836 bytes parent folder | download | duplicates (5)
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_VIDEO_ENCODER_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_VIDEO_ENCODER_H_

#include <memory>
#include <optional>

#include "base/containers/flat_map.h"
#include "base/time/time.h"
#include "media/base/video_codecs.h"
#include "media/base/video_color_space.h"
#include "media/base/video_encoder.h"
#include "media/base/video_frame_pool.h"
#include "media/video/video_encoder_info.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_encoded_video_chunk_output_callback.h"
#include "third_party/blink/renderer/modules/webcodecs/encoder_base.h"
#include "third_party/blink/renderer/modules/webcodecs/hardware_preference.h"
#include "third_party/blink/renderer/modules/webcodecs/video_frame.h"
#include "ui/gfx/color_space.h"

namespace media {
class GpuVideoAcceleratorFactories;
class VideoEncoderMetricsProvider;
class VideoEncoder;
struct VideoEncoderOutput;
}  // namespace media

namespace blink {

class VideoEncoderBuffer;
class VideoEncoderConfig;
class VideoEncoderInit;
class VideoEncoderEncodeOptions;
class VideoEncoderSupport;
class WebGraphicsContext3DVideoFramePool;
class BackgroundReadback;

class MODULES_EXPORT VideoEncoderTraits {
 public:
  struct ParsedConfig final : public GarbageCollected<ParsedConfig> {
    media::VideoCodec codec;
    media::VideoCodecProfile profile;
    uint8_t level;

    HardwarePreference hw_pref;

    media::VideoEncoder::Options options;
    String codec_string;
    std::optional<gfx::Size> display_size;

    std::optional<String> not_supported_error_message;

    String ToString();
    void Trace(Visitor*) const {}
  };

  using Init = VideoEncoderInit;
  using Config = VideoEncoderConfig;
  using InternalConfig = ParsedConfig;
  using Input = VideoFrame;
  using EncodeOptions = VideoEncoderEncodeOptions;
  using OutputChunk = EncodedVideoChunk;
  using OutputCallback = V8EncodedVideoChunkOutputCallback;
  using MediaEncoder = media::VideoEncoder;

  // Can't be a virtual method, because it's used from base ctor.
  static const char* GetName();
};

class MODULES_EXPORT VideoEncoder : public EncoderBase<VideoEncoderTraits> {
  DEFINE_WRAPPERTYPEINFO();

 public:
  static VideoEncoder* Create(ScriptState*,
                              const VideoEncoderInit*,
                              ExceptionState&);
  VideoEncoder(ScriptState*, const VideoEncoderInit*, ExceptionState&);
  ~VideoEncoder() override;

  static ScriptPromise<VideoEncoderSupport>
  isConfigSupported(ScriptState*, const VideoEncoderConfig*, ExceptionState&);

  HeapVector<Member<VideoEncoderBuffer>> getAllFrameBuffers(ScriptState*,
                                                            ExceptionState&);

  // EventTarget interface
  const AtomicString& InterfaceName() const override;

  // ScriptWrappable override.
  bool HasPendingActivity() const override;

  // GarbageCollected override.
  void Trace(Visitor*) const override;

  // If `is_error_message_from_software_codec` is true, `error_message` will be
  // updated to include `status.message()` if non-empty.
  void ReportError(const char* error_message,
                   const media::EncoderStatus& status,
                   bool is_error_message_from_software_codec);

  std::unique_ptr<media::VideoEncoderMetricsProvider> encoder_metrics_provider_
      GUARDED_BY_CONTEXT(sequence_checker_);

 protected:
  using Base = EncoderBase<VideoEncoderTraits>;
  using ParsedConfig = VideoEncoderTraits::ParsedConfig;

  void OnMediaEncoderInfoChanged(const media::VideoEncoderInfo& encoder_info);
  void CallOutputCallback(
      ParsedConfig* active_config,
      uint32_t reset_count,
      media::VideoEncoderOutput output,
      std::optional<media::VideoEncoder::CodecDescription> codec_desc);
  bool ReadyToProcessNextRequest() override;
  void ProcessEncode(Request* request) override;
  void ProcessConfigure(Request* request) override;
  void ProcessReconfigure(Request* request) override;
  void ResetInternal(DOMException* ex) override;
  void OnNewEncode(VideoFrame* input, ExceptionState& exception_state) override;

  void OnEncodeDone(Request* request, media::EncoderStatus status);
  media::VideoEncoder::EncodeOptions CreateEncodeOptions(Request* request);
  // This will execute shortly after the async readback completes.
  void OnReadbackDone(Request* request,
                      scoped_refptr<media::VideoFrame> txt_frame,
                      media::VideoEncoder::EncoderStatusCB done_callback,
                      scoped_refptr<media::VideoFrame> result_frame);
  static media::EncoderStatus::Or<std::unique_ptr<media::VideoEncoder>>
  CreateSoftwareVideoEncoder(VideoEncoder* self,
                             bool fallback,
                             media::VideoCodec codec);

  ParsedConfig* OnNewConfigure(const VideoEncoderConfig*,
                               ExceptionState&) override;
  bool VerifyCodecSupport(ParsedConfig*, String* js_error_message) override;

  // Virtual for UTs.
  // Returns the VideoEncoder.
  virtual media::EncoderStatus::Or<std::unique_ptr<media::VideoEncoder>>
  CreateMediaVideoEncoder(const ParsedConfig& config,
                          media::GpuVideoAcceleratorFactories* gpu_factories,
                          bool& is_platform_encoder);
  virtual std::unique_ptr<media::VideoEncoderMetricsProvider>
  CreateVideoEncoderMetricsProvider() const;

  void ContinueConfigureWithGpuFactories(
      Request* request,
      media::GpuVideoAcceleratorFactories* gpu_factories);
  media::EncoderStatus::Or<std::unique_ptr<media::VideoEncoder>>
  CreateAcceleratedVideoEncoder(
      media::VideoCodecProfile profile,
      const media::VideoEncoder::Options& options,
      media::GpuVideoAcceleratorFactories* gpu_factories,
      HardwarePreference hw_pref);
  bool CanReconfigure(ParsedConfig& original_config,
                      ParsedConfig& new_config) override;

  using ReadbackDoneCallback =
      base::OnceCallback<void(scoped_refptr<media::VideoFrame>)>;
  bool StartReadback(scoped_refptr<media::VideoFrame> frame,
                     ReadbackDoneCallback result_cb);

  std::unique_ptr<WebGraphicsContext3DVideoFramePool> accelerated_frame_pool_;
  Member<BackgroundReadback> background_readback_;

  // True if an error occurs during frame pool usage.
  bool disable_accelerated_frame_pool_ = false;

  // The number of encoding requests currently handled by |media_encoder_|
  // Should not exceed |max_active_encodes_|.
  int active_encodes_ = 0;

  // The current upper limit on |active_encodes_|.
  int max_active_encodes_;

  // True if a running video encoder is hardware accelerated.
  bool is_platform_encoder_ = false;

  // Per-frame metadata to be applied to outputs, linked by timestamp.
  struct FrameMetadata {
    base::TimeDelta duration;
    media::VideoTransformation transformation;
  };
  base::flat_map<base::TimeDelta, FrameMetadata> frame_metadata_;

  // Buffers returned by getAllFrameBuffers()
  HeapVector<Member<VideoEncoderBuffer>> frame_reference_buffers_;

  // The color space corresponding to the last emitted output. Used to update
  // emitted VideoDecoderConfig when necessary.
  gfx::ColorSpace last_output_color_space_;

  // The transformation corresponding to the last input received by
  // ProcessEncode(). Used to request a key frame.
  std::optional<media::VideoTransformation> first_input_transformation_;

  // Latest VideoEncoderInfo reported by encoder
  media::VideoEncoderInfo encoder_info_;
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_VIDEO_ENCODER_H_