File: rtc_video_decoder_adapter.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 (162 lines) | stat: -rw-r--r-- 6,218 bytes parent folder | download | duplicates (9)
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
// Copyright 2018 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_PLATFORM_PEERCONNECTION_RTC_VIDEO_DECODER_ADAPTER_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_VIDEO_DECODER_ADAPTER_H_

#include <atomic>
#include <memory>
#include <vector>

#include "base/feature_list.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "build/build_config.h"
#include "media/base/decoder.h"
#include "media/base/video_decoder_config.h"
#include "third_party/blink/renderer/platform/peerconnection/resolution_monitor.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/webrtc/api/video_codecs/sdp_video_format.h"
#include "third_party/webrtc/api/video_codecs/video_decoder.h"
#include "third_party/webrtc/modules/video_coding/include/video_codec_interface.h"
#include "ui/gfx/geometry/size.h"

namespace base {
class SequencedTaskRunner;
}  // namespace base

namespace media {
class DecoderBuffer;
class GpuVideoAcceleratorFactories;
}  // namespace media

namespace blink {

// This class decodes video for WebRTC using a media::VideoDecoder. In
// particular, MojoVideoDecoder are used to provide access to hardware decoding
// in the GPU process.
//
// This is created and destroyed on a WebRTC DecodingThread and decoding happens
// also on the thread.
//
// The webrtc::VideoDecoder functions delegates |impl_| functions through
// posting the task to |media_task_runner_|.
class PLATFORM_EXPORT RTCVideoDecoderAdapter : public webrtc::VideoDecoder {
 public:
  // Minimum resolution that we'll consider "not low resolution" for the purpose
  // of falling back to software.
#if BUILDFLAG(IS_CHROMEOS)
  // Effectively opt-out CrOS, since it may cause tests to fail (b/179724180).
  static constexpr gfx::Size kMinResolution{2, 2};
#else
  static constexpr gfx::Size kMinResolution{320, 240};
#endif

  // Maximum number of decoder instances we'll allow before fallback to software
  // if the resolution is too low.  We'll allow more than this for high
  // resolution streams, but they'll fall back if they adapt below the limit.
  static constexpr int32_t kMaxDecoderInstances = 8;

  // Creates and initializes an RTCVideoDecoderAdapter. Returns nullptr if
  // |format| cannot be supported.
  // Called on the worker thread.
  static std::unique_ptr<RTCVideoDecoderAdapter> Create(
      media::GpuVideoAcceleratorFactories* gpu_factories,
      const webrtc::SdpVideoFormat& format,
      std::unique_ptr<ResolutionMonitor> resolution_monitor = nullptr);

  RTCVideoDecoderAdapter(const RTCVideoDecoderAdapter&) = delete;
  RTCVideoDecoderAdapter& operator=(const RTCVideoDecoderAdapter&) = delete;

  // Called on |media_task_runner_|.
  ~RTCVideoDecoderAdapter() override;

  // webrtc::VideoDecoder implementation.
  // Called on the DecodingThread.
  bool Configure(const Settings& _settings) override;
  int32_t RegisterDecodeCompleteCallback(
      webrtc::DecodedImageCallback* callback) override;
  int32_t Decode(const webrtc::EncodedImage& input_image,
                 bool missing_frames,
                 int64_t render_time_ms) override;
  // Called on the worker thread and on the DecodingThread.
  int32_t Release() override;
  // Called on the worker thread and on the DecodingThread.
  DecoderInfo GetDecoderInfo() const override { return decoder_info_; }

  // Gets / adjusts the current decoder count.
  // They are must be executed on media thread.
  static int GetCurrentDecoderCountForTesting();
  static void IncrementCurrentDecoderCountForTesting();
  static void DecrementCurrentDecoderCountForTesting();

  static std::atomic<int> g_num_decoders_;

 private:
  class Impl;

  enum class DecodeResult {
    kOk,
    kErrorRequestKeyFrame,
  };
  enum class Status : uint8_t {
    kOk = 0,            // Status other than kNeedKeyFrame and kError.
    kNeedKeyFrame = 1,  // A decoder needs a key frame.
    kError = 2,         // A decoder will never be able to decode frames.
  };

  // Called on the worker thread.
  RTCVideoDecoderAdapter(media::GpuVideoAcceleratorFactories* gpu_factories,
                         const media::VideoDecoderConfig& config,
                         std::unique_ptr<ResolutionMonitor> resolution_monitor);

  bool InitializeSync(const media::VideoDecoderConfig& config);
  std::optional<DecodeResult> DecodeInternal(
      const webrtc::EncodedImage& input_image,
      bool missing_frames,
      int64_t render_time_ms);
  bool ShouldReinitializeForSettingColorSpace(
      const webrtc::EncodedImage& input_image) const;
  bool ReinitializeSync(const media::VideoDecoderConfig& config);
  void ChangeStatus(Status new_status);
  bool CheckResolutionAndNumInstances(const media::DecoderBuffer& buffer);
  // Construction parameters.
  const scoped_refptr<base::SequencedTaskRunner> media_task_runner_;
  std::unique_ptr<Impl> impl_ GUARDED_BY_CONTEXT(decoding_sequence_checker_);

  // Construction parameters.
  media::VideoDecoderConfig config_;

  const std::unique_ptr<ResolutionMonitor> resolution_monitor_
      GUARDED_BY_CONTEXT(decoding_sequence_checker_);

  // Decoding thread members.
  // Has anything been sent to Decode() yet?
  Status status_ GUARDED_BY_CONTEXT(decoding_sequence_checker_){
      Status::kNeedKeyFrame};

  // DecoderInfo is constant after InitializeSync() is complete.
  DecoderInfo decoder_info_;

  bool have_started_decoding_ GUARDED_BY_CONTEXT(decoding_sequence_checker_){
      false};

  media::VideoDecoderType decoder_type_ GUARDED_BY_CONTEXT(
      decoding_sequence_checker_){media::VideoDecoderType::kUnknown};

  // Thread management.
  SEQUENCE_CHECKER(decoding_sequence_checker_);

  // This weak pointer is bound to |media_task_runner_|.
  base::WeakPtr<Impl> weak_impl_;

  // These are bound to |decoding_sequence_checker_|.
  base::WeakPtr<RTCVideoDecoderAdapter> weak_this_;
  base::WeakPtrFactory<RTCVideoDecoderAdapter> weak_this_factory_{this};
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_VIDEO_DECODER_ADAPTER_H_