mirror of
https://github.com/starr-dusT/citra.git
synced 2024-10-02 10:26:17 -07:00

The settings.h file doesn't actually need all of the definitions on cam.h, only some of the enums. They can, therefore, be separated into another file, which is included by settings.h instead. The other changes are fixing files that included settings.h and depended on indirect includes from includes of includes of cam.h
779 lines
24 KiB
C++
779 lines
24 KiB
C++
// Copyright 2015 Citra Emulator Project
|
|
// Licensed under GPLv2 or any later version
|
|
// Refer to the license.txt file included.
|
|
|
|
#pragma once
|
|
|
|
#include <array>
|
|
#include <deque>
|
|
#include <future>
|
|
#include <memory>
|
|
#include <vector>
|
|
#include <boost/serialization/array.hpp>
|
|
#include <boost/serialization/deque.hpp>
|
|
#include <boost/serialization/shared_ptr.hpp>
|
|
#include <boost/serialization/unique_ptr.hpp>
|
|
#include <boost/serialization/version.hpp>
|
|
#include "common/common_types.h"
|
|
#include "common/swap.h"
|
|
#include "core/global.h"
|
|
#include "core/hle/result.h"
|
|
#include "core/hle/service/cam/cam_params.h"
|
|
#include "core/hle/service/service.h"
|
|
|
|
namespace Core {
|
|
class System;
|
|
}
|
|
|
|
namespace Camera {
|
|
class CameraInterface;
|
|
}
|
|
|
|
namespace Core {
|
|
struct TimingEventType;
|
|
}
|
|
|
|
namespace Kernel {
|
|
class Process;
|
|
}
|
|
|
|
namespace Service::CAM {
|
|
|
|
/// Stereo camera calibration data.
|
|
struct StereoCameraCalibrationData {
|
|
u8 isValidRotationXY; ///< Bool indicating whether the X and Y rotation data is valid.
|
|
INSERT_PADDING_BYTES(3);
|
|
float_le scale; ///< Scale to match the left camera image with the right.
|
|
float_le rotationZ; ///< Z axis rotation to match the left camera image with the right.
|
|
float_le translationX; ///< X axis translation to match the left camera image with the right.
|
|
float_le translationY; ///< Y axis translation to match the left camera image with the right.
|
|
float_le rotationX; ///< X axis rotation to match the left camera image with the right.
|
|
float_le rotationY; ///< Y axis rotation to match the left camera image with the right.
|
|
float_le angleOfViewRight; ///< Right camera angle of view.
|
|
float_le angleOfViewLeft; ///< Left camera angle of view.
|
|
float_le distanceToChart; ///< Distance between cameras and measurement chart.
|
|
float_le distanceCameras; ///< Distance between left and right cameras.
|
|
s16_le imageWidth; ///< Image width.
|
|
s16_le imageHeight; ///< Image height.
|
|
INSERT_PADDING_BYTES(16);
|
|
};
|
|
static_assert(sizeof(StereoCameraCalibrationData) == 64,
|
|
"StereoCameraCalibrationData structure size is wrong");
|
|
|
|
/**
|
|
* Resolution parameters for the camera.
|
|
* The native resolution of 3DS camera is 640 * 480. The captured image will be cropped in the
|
|
* region [crop_x0, crop_x1] * [crop_y0, crop_y1], and then scaled to size width * height as the
|
|
* output image. Note that all cropping coordinates are inclusive.
|
|
*/
|
|
struct Resolution {
|
|
u16 width;
|
|
u16 height;
|
|
u16 crop_x0;
|
|
u16 crop_y0;
|
|
u16 crop_x1;
|
|
u16 crop_y1;
|
|
|
|
private:
|
|
template <class Archive>
|
|
void serialize(Archive& ar, const unsigned int) {
|
|
ar& width;
|
|
ar& height;
|
|
ar& crop_x0;
|
|
ar& crop_y0;
|
|
ar& crop_x1;
|
|
ar& crop_y1;
|
|
}
|
|
friend class boost::serialization::access;
|
|
};
|
|
|
|
struct PackageParameterWithoutContext {
|
|
u8 camera_select;
|
|
s8 exposure;
|
|
WhiteBalance white_balance;
|
|
s8 sharpness;
|
|
bool auto_exposure;
|
|
bool auto_white_balance;
|
|
FrameRate frame_rate;
|
|
PhotoMode photo_mode;
|
|
Contrast contrast;
|
|
LensCorrection lens_correction;
|
|
bool noise_filter;
|
|
u8 padding;
|
|
s16 auto_exposure_window_x;
|
|
s16 auto_exposure_window_y;
|
|
s16 auto_exposure_window_width;
|
|
s16 auto_exposure_window_height;
|
|
s16 auto_white_balance_window_x;
|
|
s16 auto_white_balance_window_y;
|
|
s16 auto_white_balance_window_width;
|
|
s16 auto_white_balance_window_height;
|
|
INSERT_PADDING_WORDS(4);
|
|
};
|
|
|
|
static_assert(sizeof(PackageParameterWithoutContext) == 44,
|
|
"PackageParameterCameraWithoutContext structure size is wrong");
|
|
|
|
struct PackageParameterWithContext {
|
|
u8 camera_select;
|
|
u8 context_select;
|
|
Flip flip;
|
|
Effect effect;
|
|
Size size;
|
|
INSERT_PADDING_BYTES(3);
|
|
INSERT_PADDING_WORDS(3);
|
|
|
|
Resolution GetResolution() const;
|
|
};
|
|
|
|
static_assert(sizeof(PackageParameterWithContext) == 20,
|
|
"PackageParameterWithContext structure size is wrong");
|
|
|
|
struct PackageParameterWithContextDetail {
|
|
u8 camera_select;
|
|
u8 context_select;
|
|
Flip flip;
|
|
Effect effect;
|
|
Resolution resolution;
|
|
INSERT_PADDING_WORDS(3);
|
|
|
|
Resolution GetResolution() const {
|
|
return resolution;
|
|
}
|
|
};
|
|
|
|
static_assert(sizeof(PackageParameterWithContextDetail) == 28,
|
|
"PackageParameterWithContextDetail structure size is wrong");
|
|
|
|
class Module final {
|
|
public:
|
|
explicit Module(Core::System& system);
|
|
~Module();
|
|
void ReloadCameraDevices();
|
|
|
|
class Interface : public ServiceFramework<Interface> {
|
|
public:
|
|
Interface(std::shared_ptr<Module> cam, const char* name, u32 max_session);
|
|
~Interface();
|
|
|
|
std::shared_ptr<Module> GetModule() const;
|
|
|
|
protected:
|
|
/**
|
|
* Starts capturing at the selected port.
|
|
* Inputs:
|
|
* 0: 0x00010040
|
|
* 1: u8 selected port
|
|
* Outputs:
|
|
* 0: 0x00010040
|
|
* 1: ResultCode
|
|
*/
|
|
void StartCapture(Kernel::HLERequestContext& ctx);
|
|
|
|
/**
|
|
* Stops capturing from the selected port.
|
|
* Inputs:
|
|
* 0: 0x00020040
|
|
* 1: u8 selected port
|
|
* Outputs:
|
|
* 0: 0x00020040
|
|
* 1: ResultCode
|
|
*/
|
|
void StopCapture(Kernel::HLERequestContext& ctx);
|
|
|
|
/**
|
|
* Gets whether the selected port is currently capturing.
|
|
* Inputs:
|
|
* 0: 0x00030040
|
|
* 1: u8 selected port
|
|
* Outputs:
|
|
* 0: 0x00030080
|
|
* 1: ResultCode
|
|
* 2: 0 if not capturing, 1 if capturing
|
|
*/
|
|
void IsBusy(Kernel::HLERequestContext& ctx);
|
|
|
|
/**
|
|
* Clears the buffer of selected ports.
|
|
* Inputs:
|
|
* 0: 0x00040040
|
|
* 1: u8 selected port
|
|
* Outputs:
|
|
* 0: 0x00040040
|
|
* 2: ResultCode
|
|
*/
|
|
void ClearBuffer(Kernel::HLERequestContext& ctx);
|
|
|
|
/**
|
|
* Unknown
|
|
* Inputs:
|
|
* 0: 0x00050040
|
|
* 1: u8 selected port
|
|
* Outputs:
|
|
* 0: 0x00050042
|
|
* 1: ResultCode
|
|
* 2: Descriptor: Handle
|
|
* 3: Event handle
|
|
*/
|
|
void GetVsyncInterruptEvent(Kernel::HLERequestContext& ctx);
|
|
|
|
/**
|
|
* Unknown
|
|
* Inputs:
|
|
* 0: 0x00060040
|
|
* 1: u8 selected port
|
|
* Outputs:
|
|
* 0: 0x00060042
|
|
* 1: ResultCode
|
|
* 2: Descriptor: Handle
|
|
* 3: Event handle
|
|
*/
|
|
void GetBufferErrorInterruptEvent(Kernel::HLERequestContext& ctx);
|
|
|
|
/**
|
|
* Sets the target buffer to receive a frame of image data and starts the transfer. Each
|
|
* camera port has its own event to signal the end of the transfer.
|
|
*
|
|
* Inputs:
|
|
* 0: 0x00070102
|
|
* 1: Destination address in calling process
|
|
* 2: u8 selected port
|
|
* 3: Image size (in bytes)
|
|
* 4: u16 Transfer unit size (in bytes)
|
|
* 5: Descriptor: Handle
|
|
* 6: Handle to destination process
|
|
* Outputs:
|
|
* 0: 0x00070042
|
|
* 1: ResultCode
|
|
* 2: Descriptor: Handle
|
|
* 3: Handle to event signalled when transfer finishes
|
|
*/
|
|
void SetReceiving(Kernel::HLERequestContext& ctx);
|
|
|
|
/**
|
|
* Gets whether the selected port finished receiving a frame.
|
|
* Inputs:
|
|
* 0: 0x00080040
|
|
* 1: u8 selected port
|
|
* Outputs:
|
|
* 0: 0x00080080
|
|
* 1: ResultCode
|
|
* 2: 0 if not finished, 1 if finished
|
|
*/
|
|
void IsFinishedReceiving(Kernel::HLERequestContext& ctx);
|
|
|
|
/**
|
|
* Sets the number of lines the buffer contains.
|
|
* Inputs:
|
|
* 0: 0x00090100
|
|
* 1: u8 selected port
|
|
* 2: u16 Number of lines to transfer
|
|
* 3: u16 Width
|
|
* 4: u16 Height
|
|
* Outputs:
|
|
* 0: 0x00090040
|
|
* 1: ResultCode
|
|
* @todo figure out how the "buffer" actually works.
|
|
*/
|
|
void SetTransferLines(Kernel::HLERequestContext& ctx);
|
|
|
|
/**
|
|
* Gets the maximum number of lines that fit in the buffer
|
|
* Inputs:
|
|
* 0: 0x000A0080
|
|
* 1: u16 Width
|
|
* 2: u16 Height
|
|
* Outputs:
|
|
* 0: 0x000A0080
|
|
* 1: ResultCode
|
|
* 2: Maximum number of lines that fit in the buffer
|
|
* @todo figure out how the "buffer" actually works.
|
|
*/
|
|
void GetMaxLines(Kernel::HLERequestContext& ctx);
|
|
|
|
/**
|
|
* Sets the number of bytes the buffer contains.
|
|
* Inputs:
|
|
* 0: 0x000B0100
|
|
* 1: u8 selected port
|
|
* 2: u16 Number of bytes to transfer
|
|
* 3: u16 Width
|
|
* 4: u16 Height
|
|
* Outputs:
|
|
* 0: 0x000B0040
|
|
* 1: ResultCode
|
|
* @todo figure out how the "buffer" actually works.
|
|
*/
|
|
void SetTransferBytes(Kernel::HLERequestContext& ctx);
|
|
|
|
/**
|
|
* Gets the number of bytes to the buffer contains.
|
|
* Inputs:
|
|
* 0: 0x000C0040
|
|
* 1: u8 selected port
|
|
* Outputs:
|
|
* 0: 0x000C0080
|
|
* 1: ResultCode
|
|
* 2: The number of bytes the buffer contains
|
|
* @todo figure out how the "buffer" actually works.
|
|
*/
|
|
void GetTransferBytes(Kernel::HLERequestContext& ctx);
|
|
|
|
/**
|
|
* Gets the maximum number of bytes that fit in the buffer.
|
|
* Inputs:
|
|
* 0: 0x000D0080
|
|
* 1: u16 Width
|
|
* 2: u16 Height
|
|
* Outputs:
|
|
* 0: 0x000D0080
|
|
* 1: ResultCode
|
|
* 2: Maximum number of bytes that fit in the buffer
|
|
* @todo figure out how the "buffer" actually works.
|
|
*/
|
|
void GetMaxBytes(Kernel::HLERequestContext& ctx);
|
|
|
|
/**
|
|
* Enables or disables trimming.
|
|
* Inputs:
|
|
* 0: 0x000E0080
|
|
* 1: u8 selected port
|
|
* 2: u8 bool Enable trimming if true
|
|
* Outputs:
|
|
* 0: 0x000E0040
|
|
* 1: ResultCode
|
|
*/
|
|
void SetTrimming(Kernel::HLERequestContext& ctx);
|
|
|
|
/**
|
|
* Gets whether trimming is enabled.
|
|
* Inputs:
|
|
* 0: 0x000F0040
|
|
* 1: u8 selected port
|
|
* Outputs:
|
|
* 0: 0x000F0080
|
|
* 1: ResultCode
|
|
* 2: u8 bool Enable trimming if true
|
|
*/
|
|
void IsTrimming(Kernel::HLERequestContext& ctx);
|
|
|
|
/**
|
|
* Sets the position to trim.
|
|
* Inputs:
|
|
* 0: 0x00100140
|
|
* 1: u8 selected port
|
|
* 2: x start
|
|
* 3: y start
|
|
* 4: x end (exclusive)
|
|
* 5: y end (exclusive)
|
|
* Outputs:
|
|
* 0: 0x00100040
|
|
* 1: ResultCode
|
|
*/
|
|
void SetTrimmingParams(Kernel::HLERequestContext& ctx);
|
|
|
|
/**
|
|
* Gets the position to trim.
|
|
* Inputs:
|
|
* 0: 0x00110040
|
|
* 1: u8 selected port
|
|
*
|
|
* Outputs:
|
|
* 0: 0x00110140
|
|
* 1: ResultCode
|
|
* 2: x start
|
|
* 3: y start
|
|
* 4: x end (exclusive)
|
|
* 5: y end (exclusive)
|
|
*/
|
|
void GetTrimmingParams(Kernel::HLERequestContext& ctx);
|
|
|
|
/**
|
|
* Sets the position to trim by giving the width and height. The trimming window is always
|
|
* at the center.
|
|
* Inputs:
|
|
* 0: 0x00120140
|
|
* 1: u8 selected port
|
|
* 2: s16 Trim width
|
|
* 3: s16 Trim height
|
|
* 4: s16 Camera width
|
|
* 5: s16 Camera height
|
|
* Outputs:
|
|
* 0: 0x00120040
|
|
* 1: ResultCode
|
|
*/
|
|
void SetTrimmingParamsCenter(Kernel::HLERequestContext& ctx);
|
|
|
|
/**
|
|
* Selects up to two physical cameras to enable.
|
|
* Inputs:
|
|
* 0: 0x00130040
|
|
* 1: u8 selected camera
|
|
* Outputs:
|
|
* 0: 0x00130040
|
|
* 1: ResultCode
|
|
*/
|
|
void Activate(Kernel::HLERequestContext& ctx);
|
|
|
|
/**
|
|
* Switches the context of camera settings.
|
|
* Inputs:
|
|
* 0: 0x00140080
|
|
* 1: u8 selected camera
|
|
* 2: u8 selected context
|
|
* Outputs:
|
|
* 0: 0x00140040
|
|
* 1: ResultCode
|
|
*/
|
|
void SwitchContext(Kernel::HLERequestContext& ctx);
|
|
|
|
/**
|
|
* Sets flipping of images
|
|
* Inputs:
|
|
* 0: 0x001D00C0
|
|
* 1: u8 selected camera
|
|
* 2: u8 Type of flipping to perform (`Flip` enum)
|
|
* 3: u8 selected context
|
|
* Outputs:
|
|
* 0: 0x001D0040
|
|
* 1: ResultCode
|
|
*/
|
|
void FlipImage(Kernel::HLERequestContext& ctx);
|
|
|
|
/**
|
|
* Sets camera resolution from custom parameters. For more details see the Resolution
|
|
* struct.
|
|
* Inputs:
|
|
* 0: 0x001E0200
|
|
* 1: u8 selected camera
|
|
* 2: width
|
|
* 3: height
|
|
* 4: crop x0
|
|
* 5: crop y0
|
|
* 6: crop x1
|
|
* 7: crop y1
|
|
* 8: u8 selected context
|
|
* Outputs:
|
|
* 0: 0x001E0040
|
|
* 1: ResultCode
|
|
*/
|
|
void SetDetailSize(Kernel::HLERequestContext& ctx);
|
|
|
|
/**
|
|
* Sets camera resolution from preset resolution parameters.
|
|
* Inputs:
|
|
* 0: 0x001F00C0
|
|
* 1: u8 selected camera
|
|
* 2: u8 Camera frame resolution (`Size` enum)
|
|
* 3: u8 selected context
|
|
* Outputs:
|
|
* 0: 0x001F0040
|
|
* 1: ResultCode
|
|
*/
|
|
void SetSize(Kernel::HLERequestContext& ctx);
|
|
|
|
/**
|
|
* Sets camera framerate.
|
|
* Inputs:
|
|
* 0: 0x00200080
|
|
* 1: u8 selected camera
|
|
* 2: u8 Camera framerate (`FrameRate` enum)
|
|
* Outputs:
|
|
* 0: 0x00200040
|
|
* 1: ResultCode
|
|
*/
|
|
void SetFrameRate(Kernel::HLERequestContext& ctx);
|
|
|
|
/**
|
|
* Sets effect on the output image
|
|
* Inputs:
|
|
* 0: 0x002200C0
|
|
* 1: u8 selected camera
|
|
* 2: u8 image effect (`Effect` enum)
|
|
* 3: u8 selected context
|
|
* Outputs:
|
|
* 0: 0x00220040
|
|
* 1: ResultCode
|
|
*/
|
|
void SetEffect(Kernel::HLERequestContext& ctx);
|
|
|
|
/**
|
|
* Sets format of the output image
|
|
* Inputs:
|
|
* 0: 0x002500C0
|
|
* 1: u8 selected camera
|
|
* 2: u8 image format (`OutputFormat` enum)
|
|
* 3: u8 selected context
|
|
* Outputs:
|
|
* 0: 0x00250040
|
|
* 1: ResultCode
|
|
*/
|
|
void SetOutputFormat(Kernel::HLERequestContext& ctx);
|
|
|
|
/**
|
|
* Synchronizes the V-Sync timing of two cameras.
|
|
* Inputs:
|
|
* 0: 0x00290080
|
|
* 1: u8 selected camera 1
|
|
* 2: u8 selected camera 2
|
|
* Outputs:
|
|
* 0: 0x00280040
|
|
* 1: ResultCode
|
|
*/
|
|
void SynchronizeVsyncTiming(Kernel::HLERequestContext& ctx);
|
|
|
|
/**
|
|
* Gets the vsync timing record of the specified camera for the specified number of signals.
|
|
* Inputs:
|
|
* 0: 0x002A0080
|
|
* 1: Port
|
|
* 2: Number of timings to get
|
|
* 64: ((PastTimings * 8) << 14) | 2
|
|
* 65: s64* TimingsOutput
|
|
* Outputs:
|
|
* 0: 0x002A0042
|
|
* 1: ResultCode
|
|
* 2-3: Output static buffer
|
|
*/
|
|
void GetLatestVsyncTiming(Kernel::HLERequestContext& ctx);
|
|
|
|
/**
|
|
* Returns calibration data relating the outside cameras to each other, for use in AR
|
|
* applications.
|
|
*
|
|
* Inputs:
|
|
* 0: 0x002B0000
|
|
* Outputs:
|
|
* 0: 0x002B0440
|
|
* 1: ResultCode
|
|
* 2-17: `StereoCameraCalibrationData` structure with calibration values
|
|
*/
|
|
void GetStereoCameraCalibrationData(Kernel::HLERequestContext& ctx);
|
|
|
|
/**
|
|
* Batch-configures context-free settings.
|
|
*
|
|
* Inputs:
|
|
* 0: 0x003302C0
|
|
* 1-7: struct PachageParameterWithoutContext
|
|
* 8-11: unused
|
|
* Outputs:
|
|
* 0: 0x00330040
|
|
* 1: ResultCode
|
|
*/
|
|
void SetPackageParameterWithoutContext(Kernel::HLERequestContext& ctx);
|
|
|
|
/**
|
|
* Batch-configures context-related settings with preset resolution parameters.
|
|
*
|
|
* Inputs:
|
|
* 0: 0x00340140
|
|
* 1-2: struct PackageParameterWithContext
|
|
* 3-5: unused
|
|
* Outputs:
|
|
* 0: 0x00340040
|
|
* 1: ResultCode
|
|
*/
|
|
void SetPackageParameterWithContext(Kernel::HLERequestContext& ctx);
|
|
|
|
/**
|
|
* Batch-configures context-related settings with custom resolution parameters
|
|
*
|
|
* Inputs:
|
|
* 0: 0x003501C0
|
|
* 1-4: struct PackageParameterWithContextDetail
|
|
* 5-7: unused
|
|
* Outputs:
|
|
* 0: 0x00350040
|
|
* 1: ResultCode
|
|
*/
|
|
void SetPackageParameterWithContextDetail(Kernel::HLERequestContext& ctx);
|
|
|
|
/**
|
|
* Unknown
|
|
* Inputs:
|
|
* 0: 0x00360000
|
|
* Outputs:
|
|
* 0: 0x00360080
|
|
* 1: ResultCode
|
|
* 2: ?
|
|
*/
|
|
void GetSuitableY2rStandardCoefficient(Kernel::HLERequestContext& ctx);
|
|
|
|
/**
|
|
* Unknown
|
|
* Inputs:
|
|
* 0: 0x00380040
|
|
* 1: u8 Sound ID
|
|
* Outputs:
|
|
* 0: 0x00380040
|
|
* 1: ResultCode
|
|
*/
|
|
void PlayShutterSound(Kernel::HLERequestContext& ctx);
|
|
|
|
/**
|
|
* Initializes the camera driver. Must be called before using other functions.
|
|
* Inputs:
|
|
* 0: 0x00390000
|
|
* Outputs:
|
|
* 0: 0x00390040
|
|
* 1: ResultCode
|
|
*/
|
|
void DriverInitialize(Kernel::HLERequestContext& ctx);
|
|
|
|
/**
|
|
* Shuts down the camera driver.
|
|
* Inputs:
|
|
* 0: 0x003A0000
|
|
* Outputs:
|
|
* 0: 0x003A0040
|
|
* 1: ResultCode
|
|
*/
|
|
void DriverFinalize(Kernel::HLERequestContext& ctx);
|
|
|
|
protected:
|
|
std::shared_ptr<Module> cam;
|
|
};
|
|
|
|
private:
|
|
void CompletionEventCallBack(u64 port_id, s64);
|
|
void VsyncInterruptEventCallBack(u64 port_id, s64 cycles_late);
|
|
|
|
// Starts a receiving process on the specified port. This can only be called when is_busy = true
|
|
// and is_receiving = false.
|
|
void StartReceiving(int port_id);
|
|
|
|
// Cancels any ongoing receiving processes at the specified port. This is used by functions that
|
|
// stop capturing.
|
|
// TODO: what is the exact behaviour on real 3DS when stopping capture during an ongoing
|
|
// process? Will the completion event still be signaled?
|
|
void CancelReceiving(int port_id);
|
|
|
|
// Activates the specified port with the specfied camera.
|
|
void ActivatePort(int port_id, int camera_id);
|
|
|
|
template <typename PackageParameterType>
|
|
ResultCode SetPackageParameter(const PackageParameterType& package);
|
|
|
|
struct ContextConfig {
|
|
Flip flip{Flip::None};
|
|
Effect effect{Effect::None};
|
|
OutputFormat format{OutputFormat::YUV422};
|
|
Resolution resolution = {0, 0, 0, 0, 0, 0};
|
|
|
|
private:
|
|
template <class Archive>
|
|
void serialize(Archive& ar, const unsigned int) {
|
|
ar& flip;
|
|
ar& effect;
|
|
ar& format;
|
|
ar& resolution;
|
|
}
|
|
friend class boost::serialization::access;
|
|
};
|
|
|
|
struct CameraConfig {
|
|
std::unique_ptr<Camera::CameraInterface> impl;
|
|
std::array<ContextConfig, 2> contexts;
|
|
int current_context{0};
|
|
FrameRate frame_rate{FrameRate::Rate_15};
|
|
|
|
private:
|
|
template <class Archive>
|
|
void serialize(Archive& ar, const unsigned int file_version) {
|
|
// For compatibility: put a nullptr here
|
|
if (file_version == 0) {
|
|
std::unique_ptr<Camera::CameraInterface> x;
|
|
ar& x;
|
|
}
|
|
ar& contexts;
|
|
ar& current_context;
|
|
ar& frame_rate;
|
|
}
|
|
friend class boost::serialization::access;
|
|
};
|
|
|
|
struct PortConfig {
|
|
int camera_id{0};
|
|
|
|
bool is_active{false}; // set when the port is activated by an Activate call.
|
|
|
|
// set if SetReceiving is called when is_busy = false. When StartCapture is called then,
|
|
// this will trigger a receiving process and reset itself.
|
|
bool is_pending_receiving{false};
|
|
|
|
// set when StartCapture is called and reset when StopCapture is called.
|
|
bool is_busy{false};
|
|
|
|
bool is_receiving{false}; // set when there is an ongoing receiving process.
|
|
|
|
bool is_trimming{false};
|
|
u16 x0{0}; // x-coordinate of starting position for trimming
|
|
u16 y0{0}; // y-coordinate of starting position for trimming
|
|
u16 x1{0}; // x-coordinate of ending position for trimming
|
|
u16 y1{0}; // y-coordinate of ending position for trimming
|
|
|
|
u16 transfer_bytes{256};
|
|
|
|
std::shared_ptr<Kernel::Event> completion_event;
|
|
std::shared_ptr<Kernel::Event> buffer_error_interrupt_event;
|
|
std::shared_ptr<Kernel::Event> vsync_interrupt_event;
|
|
|
|
std::deque<s64> vsync_timings;
|
|
|
|
std::future<std::vector<u16>> capture_result; // will hold the received frame.
|
|
Kernel::Process* dest_process{nullptr};
|
|
VAddr dest{0}; // the destination address of the receiving process
|
|
u32 dest_size{0}; // the destination size of the receiving process
|
|
|
|
void Clear();
|
|
|
|
private:
|
|
template <class Archive>
|
|
void serialize(Archive& ar, const unsigned int) {
|
|
ar& camera_id;
|
|
ar& is_active;
|
|
ar& is_pending_receiving;
|
|
ar& is_busy;
|
|
ar& is_receiving;
|
|
ar& is_trimming;
|
|
ar& x0;
|
|
ar& y0;
|
|
ar& x1;
|
|
ar& y1;
|
|
ar& transfer_bytes;
|
|
ar& completion_event;
|
|
ar& buffer_error_interrupt_event;
|
|
ar& vsync_interrupt_event;
|
|
ar& vsync_timings;
|
|
// Ignore capture_result. In-progress captures might be affected but this is OK.
|
|
ar& dest_process;
|
|
ar& dest;
|
|
ar& dest_size;
|
|
}
|
|
friend class boost::serialization::access;
|
|
};
|
|
|
|
void LoadCameraImplementation(CameraConfig& camera, int camera_id);
|
|
|
|
Core::System& system;
|
|
std::array<CameraConfig, NumCameras> cameras;
|
|
std::array<PortConfig, 2> ports;
|
|
Core::TimingEventType* completion_event_callback;
|
|
Core::TimingEventType* vsync_interrupt_event_callback;
|
|
std::atomic<bool> is_camera_reload_pending{false};
|
|
|
|
template <class Archive>
|
|
void serialize(Archive& ar, const unsigned int);
|
|
friend class boost::serialization::access;
|
|
};
|
|
|
|
std::shared_ptr<Module> GetModule(Core::System& system);
|
|
|
|
void InstallInterfaces(Core::System& system);
|
|
|
|
} // namespace Service::CAM
|
|
|
|
SERVICE_CONSTRUCT(Service::CAM::Module)
|
|
BOOST_CLASS_VERSION(Service::CAM::Module::CameraConfig, 1)
|