blob: 92a769f7e78a13d82fd4dc5bb5d877f305355de4 [file] [log] [blame]
/*
* Copyright 2018 The Chromium OS 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 CAMERA_COMMON_JPEG_JPEG_ENCODE_ACCELERATOR_IMPL_H_
#define CAMERA_COMMON_JPEG_JPEG_ENCODE_ACCELERATOR_IMPL_H_
#include <stdint.h>
#include <memory>
#include <unordered_map>
#include <vector>
#include <base/memory/weak_ptr.h>
#include <base/memory/writable_shared_memory_region.h>
#include <base/threading/thread.h>
#include "cros-camera/camera_mojo_channel_manager.h"
#include "cros-camera/future.h"
#include "cros-camera/jpeg_compressor.h"
#include "cros-camera/jpeg_encode_accelerator.h"
#include "mojo/cros_camera_service.mojom.h"
#include "mojo/gpu/jpeg_encode_accelerator.mojom.h"
namespace cros {
// Encapsulates a converter from JPEG to YU12 format.
// Before using this class, make sure mojo is initialized first.
class JpegEncodeAcceleratorImpl : public JpegEncodeAccelerator {
public:
explicit JpegEncodeAcceleratorImpl(CameraMojoChannelManager* mojo_manager);
JpegEncodeAcceleratorImpl(const JpegEncodeAcceleratorImpl&) = delete;
JpegEncodeAcceleratorImpl& operator=(const JpegEncodeAcceleratorImpl&) =
delete;
~JpegEncodeAcceleratorImpl() override;
// JpegEncodeAccelerator implementation.
bool Start() override;
// To be deprecated.
int EncodeSync(int input_fd,
const uint8_t* input_buffer,
uint32_t input_buffer_size,
int32_t coded_size_width,
int32_t coded_size_height,
const uint8_t* exif_buffer,
uint32_t exif_buffer_size,
int output_fd,
uint32_t output_buffer_size,
uint32_t* output_data_size) override;
int EncodeSync(uint32_t input_format,
const std::vector<JpegCompressor::DmaBufPlane>& input_planes,
const std::vector<JpegCompressor::DmaBufPlane>& output_planes,
const uint8_t* exif_buffer,
uint32_t exif_buffer_size,
int width,
int height,
uint32_t* output_data_size) override;
private:
// IPCBridge wraps all the IPC-related calls. Most of its methods should/will
// be run on IPC thread.
class IPCBridge {
public:
IPCBridge(CameraMojoChannelManager* mojo_manager,
CancellationRelay* cancellation_relay);
// It should only be triggered on IPC thread to ensure thread-safety.
~IPCBridge();
// Initialize Mojo channel to GPU pcorss in chrome.
void Start(base::Callback<void(bool)> callback);
// Destroy the instance.
void Destroy();
// Process encode request in IPC thread.
// Either |input_fd| or |input_buffer| has to be filled up.
void EncodeLegacy(int32_t task_id,
int input_fd,
const uint8_t* input_buffer,
uint32_t input_buffer_size,
int32_t coded_size_width,
int32_t coded_size_height,
const uint8_t* exif_buffer,
uint32_t exif_buffer_size,
int output_fd,
uint32_t output_buffer_size,
EncodeWithFDCallback callback);
// Process encode request in IPC thread.
void Encode(int32_t task_id,
uint32_t input_format,
const std::vector<JpegCompressor::DmaBufPlane>& input_planes,
const std::vector<JpegCompressor::DmaBufPlane>& output_planes,
const uint8_t* exif_buffer,
uint32_t exif_buffer_size,
int coded_size_width,
int coded_size_height,
EncodeWithDmaBufCallback callback);
// For synced Encode API.
void EncodeSyncCallback(base::Callback<void(int)> callback,
uint32_t* output_data_size,
int32_t task_id,
uint32_t output_size,
int status);
// Gets a weak pointer of the IPCBridge. This method can be called on
// non-IPC thread.
base::WeakPtr<IPCBridge> GetWeakPtr();
// Return true if the mojo channel is ready to use. This method can be
// called on non-IPC thread.
bool IsReady();
private:
// Initialize the JpegEncodeAccelerator.
void Initialize(base::Callback<void(bool)> callback);
// Error handler for JEA mojo channel.
void OnJpegEncodeAcceleratorError();
// Callback function for |jea_ptr_|->EncodeWithFD().
void OnEncodeAck(EncodeWithFDCallback callback,
int32_t task_id,
uint32_t output_size,
cros::mojom::EncodeStatus status);
// Callback function for |jea_ptr_|->EncodeWithDmaBuf().
void OnEncodeDmaBufAck(EncodeWithDmaBufCallback callback,
uint32_t output_size,
cros::mojom::EncodeStatus status);
// Camera Mojo channel manager.
// We use it to create JpegEncodeAccelerator Mojo channel.
CameraMojoChannelManager* mojo_manager_;
// Used to cancel pending futures when error occurs.
CancellationRelay* cancellation_relay_;
// The Mojo IPC task runner.
const scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner_;
// Pointer to local proxy of remote JpegEncodeAccelerator interface
// implementation.
// All the Mojo communication to |jea_ptr_| happens on |ipc_task_runner_|.
mojom::JpegEncodeAcceleratorPtr jea_ptr_;
// A map from buffer id to input and exif shared memory.
// |input_shm_map_| and |exif_shm_map_| should only be accessed on
// |ipc_task_runner_|.
// Since the input buffer may be from DMA buffer, we need to prepare a
// shared memory for JpegEncodeAccelerator interface. We will send the
// handles of the shared memory to the remote process, so we need to keep
// the shared memory referenced until we receive EncodeAck.
base::WeakPtrFactory<IPCBridge> weak_ptr_factory_{this};
};
// The id for current encode task.
int32_t task_id_;
// Mojo manager which is used for Mojo communication.
CameraMojoChannelManager* mojo_manager_;
// Used to cancel pending futures when error occurs.
std::unique_ptr<CancellationRelay> cancellation_relay_;
// The instance which deals with the IPC-related calls. It should always run
// and be deleted on IPC thread.
std::unique_ptr<IPCBridge> ipc_bridge_;
};
} // namespace cros
#endif // CAMERA_COMMON_JPEG_JPEG_ENCODE_ACCELERATOR_IMPL_H_