chromium/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.h

// 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/callback_promise_adapter.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 ScopedWebCallbacks is a move-only scoper which helps manage the lifetime of
// a blink::WebCallbacks object. This is particularly useful when you're
// simultaneously dealing with the following two conditions:
//
//   1. Your WebCallbacks implementation requires either onSuccess or onError to
//      be called before it's destroyed. This is the case with
//      CallbackPromiseAdapter for example, because its underlying
//      ScriptPromiseResolverBase must be resolved or rejected before
//      destruction.
//
//   2. You are passing ownership of the WebCallbacks to code which may
//      silently drop it. A common way for this to happen is to bind the
//      WebCallbacks as an argument to a base::{Once, Repeating}Callback which
//      gets destroyed before it can run.
//
// While it's possible to individually track the lifetime of pending
// WebCallbacks, this becomes cumbersome when dealing with many different
// callbacks types. ScopedWebCallbacks provides a generic and relatively
// lightweight solution to this problem.
//
// Example usage:
//
//   using FooCallbacks = blink::WebCallbacks<const Foo&, const FooError&>;
//
//   void RespondWithSuccess(ScopedWebCallbacks<FooCallbacks> callbacks) {
//     callbacks.PassCallbacks()->onSuccess(Foo("everything is great"));
//   }
//
//   void OnCallbacksDropped(std::unique_ptr<FooCallbacks> callbacks) {
//     // Ownership of the FooCallbacks is passed to this function if
//     // ScopedWebCallbacks::PassCallbacks isn't called before the
//     // ScopedWebCallbacks is destroyed.
//     callbacks->onError(FooError("everything is terrible"));
//   }
//
//   // Blink client implementation
//   void FooClientImpl::doMagic(std::unique_ptr<FooCallbacks> callbacks) {
//     auto scoped_callbacks = make_scoped_web_callbacks(
//         std::move(callbacks), 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_callbacks)));
//   }
//
// If the bound RespondWithSuccess callback actually runs, PassCallbacks() will
// reliquish ownership of the WebCallbacks object to a temporary scoped_ptr
// which will be destroyed immediately after onSuccess is called.
//
// If the bound RespondWithSuccess callback is instead destroyed first,
// the ScopedWebCallbacks destructor will invoke OnCallbacksDropped, executing
// our desired default behavior before deleting the WebCallbacks.
template <typename CallbacksType>
class ScopedWebCallbacks {};

template <typename CallbacksType>
ScopedWebCallbacks<CallbacksType> MakeScopedWebCallbacks(
    std::unique_ptr<CallbacksType> callbacks,
    typename ScopedWebCallbacks<CallbacksType>::DestructionCallback
        destruction_callback) {}

ImageCaptureGrabFrameCallbacks;

// 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 {};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_IMAGECAPTURE_IMAGE_CAPTURE_FRAME_GRABBER_H_