File: image_capture_frame_grabber.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 (133 lines) | stat: -rw-r--r-- 5,129 bytes parent folder | download | duplicates (6)
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
// Copyright 2016 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_IMAGECAPTURE_IMAGE_CAPTURE_FRAME_GRABBER_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_IMAGECAPTURE_IMAGE_CAPTURE_FRAME_GRABBER_H_

#include <memory>

#include "base/functional/callback.h"
#include "base/memory/weak_ptr.h"
#include "base/task/single_thread_task_runner.h"
#include "base/threading/thread_checker.h"
#include "third_party/blink/public/platform/web_callbacks.h"
#include "third_party/blink/public/web/modules/mediastream/media_stream_video_sink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h"
#include "third_party/skia/include/core/SkRefCnt.h"

class SkImage;

namespace blink {

class ImageBitmap;
class MediaStreamComponent;

// A ScopedPromiseResolver is a move-only wrapper for ScriptPromiseResolver that
// assures the promise is always settled. This is particularly useful when
// you are passing callbacks binding the resolver through code which may
// silently drop them.
//
// Example usage:
//
//   void RespondWithSuccess(ScopedPromiseResolver<Foo> resolver) {
//     resolver.TakeResolver()->Resolve(Foo("everything is great"));
//   }
//
//   void OnCallbacksDropped(Persistent<PromiseResolver<Foo>> resolver) {
//     // Ownership of the promise resolver is passed to this function if
//     // ScopedPromiseResolver::TakeResolver isn't called before the
//     // ScopedPromiseResolver is destroyed.
//     resolver->Reject(FooError("everything is terrible"));
//   }
//
//   // Blink client implementation
//   void FooClientImpl::doMagic(PromiseResolver<Foo>* resolver) {
//     ScopedPromiseResolver scoped_resolver(resolver,
//         WTF::BindOnce(&OnCallbacksDropped));
//
//     // Call to some lower-level service which may never run the callback we
//     // give it.
//     foo_service_->DoMagic(WTF::BindOnce(&RespondWithSuccess,
//                                          std::move(scoped_resolver)));
//   }
//
// If the bound RespondWithSuccess callback actually runs, TakeResolver() will
// relinquish ownership of the resolver.
//
// If the bound RespondWithSuccess callback is instead destroyed first,
// the ScopedPromiseResolver destructor will invoke OnCallbacksDropped,
// executing our desired default behavior.
template <typename ResolveType>
class ScopedPromiseResolver {
 public:
  using DestructionCallback = base::OnceCallback<void(
      Persistent<ScriptPromiseResolver<ResolveType>> resolver)>;

  ScopedPromiseResolver(ScriptPromiseResolver<ResolveType>* resolver,
                        DestructionCallback destruction_callback)
      : resolver_(resolver),
        destruction_callback_(std::move(destruction_callback)) {}

  ~ScopedPromiseResolver() {
    if (destruction_callback_ && resolver_) {
      std::move(destruction_callback_).Run(resolver_);
    }
  }

  ScopedPromiseResolver(ScopedPromiseResolver&& other) = default;
  ScopedPromiseResolver(const ScopedPromiseResolver& other) = delete;

  ScopedPromiseResolver& operator=(ScopedPromiseResolver&& other) = default;
  ScopedPromiseResolver& operator=(const ScopedPromiseResolver& other) = delete;

  ScriptPromiseResolver<ResolveType>* TakeResolver() {
    ScriptPromiseResolver<ResolveType>* result = resolver_;
    resolver_ = nullptr;
    return result;
  }

 private:
  Persistent<ScriptPromiseResolver<ResolveType>> resolver_;
  DestructionCallback destruction_callback_;
};

// This class grabs Video Frames from a given Media Stream Video Track, binding
// a method of an ephemeral SingleShotFrameHandler every time grabFrame() is
// called. This method receives an incoming media::VideoFrame on a background
// thread and converts it into the appropriate SkBitmap which is sent back to
// OnSkBitmap(). This class is single threaded throughout.
class ImageCaptureFrameGrabber final : public MediaStreamVideoSink {
 public:
  ImageCaptureFrameGrabber() = default;

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

  ~ImageCaptureFrameGrabber() override;

  void GrabFrame(MediaStreamComponent* component,
                 ScriptPromiseResolver<ImageBitmap>* resolver,
                 scoped_refptr<base::SingleThreadTaskRunner> task_runner,
                 base::TimeDelta timeout);

 private:
  // Internal class to receive, convert and forward one frame.
  class SingleShotFrameHandler;

  void OnSkImage(ScopedPromiseResolver<ImageBitmap> resolver,
                 sk_sp<SkImage> image);
  void OnTimeout();

  // Flag to indicate that there is a frame grabbing in progress.
  bool frame_grab_in_progress_ = false;
  TaskHandle timeout_task_handle_;

  THREAD_CHECKER(thread_checker_);
  base::WeakPtrFactory<ImageCaptureFrameGrabber> weak_factory_{this};
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_IMAGECAPTURE_IMAGE_CAPTURE_FRAME_GRABBER_H_