blob: 5998b5b111ee413e1c7e6643652f5f7a0a41e66e [file] [log] [blame]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MEDIA_CAPTURE_VIDEO_FUCHSIA_VIDEO_CAPTURE_DEVICE_FUCHSIA_H_
#define MEDIA_CAPTURE_VIDEO_FUCHSIA_VIDEO_CAPTURE_DEVICE_FUCHSIA_H_
#include <fuchsia/camera3/cpp/fidl.h>
#include <memory>
#include "base/threading/thread_checker.h"
#include "base/time/time.h"
#include "media/capture/video/video_capture_device.h"
#include "media/fuchsia/common/sysmem_client.h"
#include "media/fuchsia/common/vmo_buffer.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
class CAPTURE_EXPORT VideoCaptureDeviceFuchsia final
: public VideoCaptureDevice {
public:
// Returns pixel format to which video frames in the specified sysmem pixel
// |format| will be converted. PIXEL_FORMAT_UNKNOWN is returned for
// unsupported formats.
static VideoPixelFormat GetConvertedPixelFormat(
fuchsia::sysmem::PixelFormatType format);
static bool IsSupportedPixelFormat(fuchsia::sysmem::PixelFormatType format);
explicit VideoCaptureDeviceFuchsia(
fidl::InterfaceHandle<fuchsia::camera3::Device> device);
~VideoCaptureDeviceFuchsia() override;
VideoCaptureDeviceFuchsia(const VideoCaptureDeviceFuchsia&) = delete;
VideoCaptureDeviceFuchsia& operator=(const VideoCaptureDeviceFuchsia&) =
delete;
// VideoCaptureDevice implementation.
void AllocateAndStart(const VideoCaptureParams& params,
std::unique_ptr<Client> client) override;
void StopAndDeAllocate() override;
private:
// Disconnects the |stream_| and resets related state.
void DisconnectStream();
// Reports the specified |error| to the client.
void OnError(base::Location location,
VideoCaptureError error,
const std::string& reason);
// Error handlers for the |device_| and |stream_|.
void OnDeviceError(zx_status_t status);
void OnStreamError(zx_status_t status);
// Watches for resolution updates and updates |frame_size_| accordingly.
void WatchResolution();
// Callback for WatchResolution().
void OnWatchResolutionResult(fuchsia::math::Size frame_size);
// Watches for orientation updates and updates |orientation_| accordingly.
void WatchOrientation();
// Callback for WatchOrientation().
void OnWatchOrientationResult(fuchsia::camera3::Orientation orientation);
// Watches for sysmem buffer collection updates from the camera.
void WatchBufferCollection();
// Initializes buffer collection using the specified token. Initialization is
// asynchronous. |buffer_reader_| will be set once the initialization is
// complete. Old buffer collection are dropped synchronously (whether they
// have finished initialization or not).
void InitializeBufferCollection(
fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken>
token_handle);
// Callback for SysmemCollectionClient::AcquireBuffers().
void OnBuffersAcquired(
std::vector<VmoBuffer> buffers,
const fuchsia::sysmem::SingleBufferSettings& buffer_settings);
// Calls Stream::GetNextFrame() in a loop to receive incoming frames.
void ReceiveNextFrame();
// Processes new frames received by ReceiveNextFrame() and passes it to the
// |client_|.
void ProcessNewFrame(fuchsia::camera3::FrameInfo frame_info);
fuchsia::camera3::DevicePtr device_;
fuchsia::camera3::StreamPtr stream_;
std::unique_ptr<Client> client_;
SysmemAllocatorClient sysmem_allocator_;
std::unique_ptr<SysmemCollectionClient> buffer_collection_;
std::vector<VmoBuffer> buffers_;
fuchsia::sysmem::ImageFormatConstraints buffers_format_;
absl::optional<gfx::Size> frame_size_;
fuchsia::camera3::Orientation orientation_ =
fuchsia::camera3::Orientation::UP;
base::TimeTicks start_time_;
bool started_ = false;
size_t frames_received_ = 0;
THREAD_CHECKER(thread_checker_);
};
} // namespace media
#endif // MEDIA_CAPTURE_VIDEO_FUCHSIA_VIDEO_CAPTURE_DEVICE_FUCHSIA_H_