/////////////////////////////////////////////////////////////////////////////////////////
//                              INTEL CONFIDENTIAL
//              Copyright 2017 Intel Corporation All Rights Reserved.
/////////////////////////////////////////////////////////////////////////////////////////
//
// The source code contained or described herein and all documents related to the source
// code ("Material") are owned by Intel Corporation or its suppliers or licensors. Title
// to the Material remains with Intel Corporation or its suppliers and licensors. The
// Material may contain trade secrets and proprietary and confidential information of
// Intel Corporation and its suppliers and licensors, and is protected by worldwide
// copyright and trade secret laws and treaty provisions. No part of the Material may be
// used, copied, reproduced, modified, published, uploaded, posted, transmitted, distributed,
// or disclosed in any way without Intel’s prior express written permission.
//
// No license under any patent, copyright, trade secret or other intellectual property
// right is granted to or conferred upon you by disclosure or delivery of the Materials,
// either expressly, by implication, inducement, estoppel or otherwise. Any license under
// such intellectual property rights must be express and approved by Intel in writing.
/////////////////////////////////////////////////////////////////////////////////////////

#pragma once
#pragma pack(push, 1)

//////////////////////////////////////////////////////////////////////////
// Sensor Group GUID (currently only for reference, the usage is in the inf).
//////////////////////////////////////////////////////////////////////////

// {40830ED9-A2D3-455D-9DA8-BB14981204B2}
DEFINE_GUID(RS400_SENSOR_GROUP,
    0x40830ed9, 0xa2d3, 0x455d, 0x9d, 0xa8, 0xbb, 0x14, 0x98, 0x12, 0x4, 0xb2);

//////////////////////////////////////////////////////////////////////////
// This GUID is used to access the RS400 device MFT KS controls.
//
// Control types are listed below, followed by the data types for each control.
//
//////////////////////////////////////////////////////////////////////////

// {7DC07391-1BE4-405E-B134-564E6071DFDB}
DEFINE_GUID(RS400_DMFT_CONTROLS,
    0x7dc07391, 0x1be4, 0x405e, 0xb1, 0x34, 0x56, 0x4e, 0x60, 0x71, 0xdf, 0xdb);

typedef enum _RS400_CONTROL_TYPES
{
    RS400_API_VERSION = 0x0,
    RS400_CONTROL_HW_COMMAND = 0x1,
}RS400_CONTROL_TYPES, *PRS400_CONTROL_TYPES;

#define RS400_API_VER_MINOR 2
#define RS400_API_VER_MAJOR 3

typedef struct _KSPROPERTY_RS400_API_VERSION
{
    /* This field indicates an addition to the API. A change in this field doesn't break backwards compatibility. */
    /* The value should be >= RS400_API_VER_MINOR */
    UINT32 minor;
    /* This field indicates change in the API that break backwards compatibility. */
    /* The value MUST be == RS400_API_VER_MAJOR */
    UINT32 major;
}KSPROPERTY_RS400_API_VERSION, *PKSPROPERTY_RS400_API_VERSION;

typedef struct _KSPROPERTY_RS400_CONTROL_HW_COMMAND
{
    KSPROPERTY Property;
    UINT32 opCode;
    UINT32 param1;
    UINT32 param2;
    UINT32 param3;
    UINT32 param4;
} KSPROPERTY_RS400_CONTROL_HW_COMMAND, *PKSPROPERTY_RS400_CONTROL_HW_COMMAND;

//////////////////////////////////////////////////////////////////////////
// HW Extension unit KS controls.
//////////////////////////////////////////////////////////////////////////

// {707EAA8F - 1880 - 479B - 82AF - D1DDB27FEB56}
// {B8EC416E - A3AC - 4580 - 8D5C - 0BEE1597E43D}
DEFINE_GUID(KSPROPERTYSETID_RS400_COLOR_CONTROL,
    0XB8EC416E, 0XA3AC, 0X4580, 0X8D, 0X5C, 0X0B, 0XEE, 0X15, 0X97, 0XE4, 0X3D);

// {C9606CCB - 594C - 4D25 - AF47 - CCC496435995}
DEFINE_GUID(KSPROPERTYSETID_RS400_DEPTH_CONTROL,
    0xC9606CCB, 0x594C, 0x4D25, 0xAF, 0x47, 0xCC, 0xC4, 0x96, 0x43, 0x59, 0x95);

// {F6C3C3D1-5CDE-4477-ADF0-4133F58DA6F4}
DEFINE_GUID(KSPROPERTYSETID_RS400_FISHEYE_CONTROL,
    0xF6C3C3D1, 0x5CDE, 0x4477, 0xAD, 0xF0, 0x41, 0x33, 0xF5, 0x8D, 0xA6, 0xF4);

enum class KSPROPERTY_XU_RS400_DEPTH
{
    UNDEFINED = 0,
    HWM = 1,
    LASER_MODE = 2,
    EXPOSURE = 3,
    LASER_POWER = 4,
    SINGLE_SHOT_HDR = 5,
    PRESET = 6,
    ERROR_CODE = 7,
    EXT_TRIG = 8,
    TEMPERATURE = 9,
    AUTO_WB = 10,
    AUTO_EXPOSURE = 11,
    EXTRINSICS = 12,
    INTRINSICS = 13,
};

enum class KSPROPERTY_XU_RS400_FISHEYE
{
    UNDEFINED = 0,
    MANUAL_EXPOSURE = 1,
    EXTRINSICS = 2,
    INTRINSICS = 3,
};

enum class KSPROPERTY_XU_RS400_COLOR
{
    UNDEFINED = 0x00,
    EXTRINSICS = 0x01,
    INTRINSICS = 0x02,
};


//////////////////////////////////////////////////////////////////////////
// Sample attributes
//////////////////////////////////////////////////////////////////////////

// {D3C6ABAC-291A-4C75-9F47-D7B284A52619}
DEFINE_GUID(REALSENSE_SAMPLE_RS400_HW_TIMESTAMP,
    0xd3c6abac, 0x291a, 0x4c75, 0x9f, 0x47, 0xd7, 0xb2, 0x84, 0xa5, 0x26, 0x19);


//////////////////////////////////////////////////////////////////////////
// Device Metadata
//////////////////////////////////////////////////////////////////////////

// {2BF10C23-BF48-4C54-B1F9-9BB19E70DB05}
DEFINE_GUID(REALSENSE_SAMPLE_RS400_CAPTURE_TIMING_METADATA,
    0x2bf10c23, 0xbf48, 0x4c54, 0xb1, 0xf9, 0x9b, 0xb1, 0x9e, 0x70, 0xdb, 0x5);


struct RealsenseRS400MetaDataIntelCaptureTiming
{
    uint32_t    version;
    uint32_t    flag;
    uint32_t    frameCounter;
    uint32_t    opticalTimestamp;   //In millisecond unit
    uint32_t    readoutTime;        //The readout time in millisecond second unit
    uint32_t    exposureTime;       //The exposure time in millisecond second unit
    uint32_t    frameInterval;     //The frame interval in millisecond second unit
    uint32_t    pipeLatency;        //The latency between start of frame to frame ready in USB buffer
};

////////////////////////
//Intel Depth Control //
////////////////////////

// {482F9B07-3668-43FE-AD28-E3DB3463BCB9}
DEFINE_GUID(REALSENSE_SAMPLE_RS400_DEPTH_CONTROL_METADATA,
    0x482f9b07, 0x3668, 0x43fe, 0xad, 0x28, 0xe3, 0xdb, 0x34, 0x63, 0xbc, 0xb9);

struct RealsenseRS400MetaDataIntelDepthControl
{
    uint32_t    version;
    union 
    {
        uint32_t raw;
        struct {
            uint32_t intel_depth_control_gain : 1;
            uint32_t intel_depth_control_manual_exposure : 1;
            uint32_t intel_depth_control_laser_power : 1;
            uint32_t intel_depth_control_ae_mode : 1;
            uint32_t intel_depth_control_exposure_priority : 1;
            uint32_t intel_depth_control_roi : 1;
            uint32_t intel_depth_control_preset : 1;
        }flags;
    } flags;
    uint32_t    manualGain;         //Manual gain value
    uint32_t    manualExposure;     //Manual exposure
    uint32_t    laserPower;        //Laser power value
    uint32_t    autoExposureMode;   //AE mode
    uint32_t    exposurePriority;
    uint32_t    exposureROILeft;
    uint32_t    exposureROIRight;
    uint32_t    exposureROITop;
    uint32_t    exposureROIBottom;
    uint32_t    preset;
    uint32_t    laserPowerMode;
};

////////////////////////
//Intel FishEye Control //
////////////////////////

// {787B705A-5CE2-4030-B52B-C294295223C7}
DEFINE_GUID(REALSENSE_SAMPLE_RS400_FISHEYE_CONTROL_METADATA,
    0x787b705a, 0x5ce2, 0x4030, 0xb5, 0x2b, 0xc2, 0x94, 0x29, 0x52, 0x23, 0xc7);

struct RealsenseRS400MetaDataIntelFishEyeControl
{
    uint32_t    version;
    union MyUnion
    {
        uint32_t raw;
        struct {
            uint32_t intel_fish_eye_control_gain : 1;
            uint32_t intel_fish_eye_control_manual_exposure : 1;
        }flags;
    }flags;
    uint32_t    manualGain;         //Manual gain value
    uint32_t    manualExposure;     //Manual exposure
};

////////////////////////
//Intel RGB Control //
////////////////////////
// {8DCFD1F9-859C-4548-8BBE-40629D36D5B3}
DEFINE_GUID(REALSENSE_SAMPLE_RS400_COLOR_CONTROL_METADATA,
    0x8dcfd1f9, 0x859c, 0x4548, 0x8b, 0xbe, 0x40, 0x62, 0x9d, 0x36, 0xd5, 0xb3);

struct RealsenseRS400MetaDataIntelColorControl
{
    uint32_t    version;
    union
    {
        uint32_t raw;
        struct {
            uint32_t intel_color_control_brightness : 1;
            uint32_t intel_color_control_manual_contrast : 1;
            uint32_t intel_color_control_laser_saturation : 1;
            uint32_t intel_color_control_sharpness : 1;
            uint32_t intel_color_control_ae_mode : 1;
            uint32_t intel_color_control_awb_temp : 1;
            uint32_t intel_color_control_gain : 1;
            uint32_t intel_color_control_laser_backlight_comp : 1;
            uint32_t intel_color_control_awb_gama : 1;
            uint32_t intel_color_control_hue : 1;
            uint32_t intel_color_control_manual_exp : 1;
            uint32_t intel_color_control_manual_wb : 1;
            uint32_t intel_color_control_power_line_frequency : 1;
            uint32_t intel_color_control_lowlight_comp : 1;
        }flags;
    }flags;
    uint32_t    brightness;
    uint32_t    contrast;
    uint32_t    saturation;
    uint32_t    sharpness;
    uint32_t    auto_Exp_Mode;
    uint32_t    auto_WB_Temp;
    uint32_t    gain;
    uint32_t    backlight_Comp;
    uint32_t    gamma;
    uint32_t    hue;
    uint32_t    manual_Exp;
    uint32_t    manual_WB;
    uint32_t    powerLineFrequncy;
    uint32_t    low_Light_Comp;
};

////////////////////////
//Intel Configuration //
////////////////////////

// {F93AF74F-3525-4172-BF69-32AD6EF81D7A}
DEFINE_GUID(REALSENSE_SAMPLE_RS400_INTEL_CONFIGURATION_METADATA,
    0xf93af74f, 0x3525, 0x4172, 0xbf, 0x69, 0x32, 0xad, 0x6e, 0xf8, 0x1d, 0x7a);

struct RealsenseRS400MetaDataIntelConfiguration
{
    uint32_t    version;
    union 
    {
        uint32_t raw;
        struct {
            uint32_t intel_configuration_hw_type : 1;
            uint32_t intel_configuration_sku_id : 1;
            uint32_t intel_configuration_cookie : 1;
            uint32_t intel_configuration_format : 1;
            uint32_t intel_configuration_width : 1;
            uint32_t intel_configuration_height : 1;
            uint32_t intel_configuration_fps : 1;
            uint32_t intel_configuration_trigger : 1;
            uint32_t intel_configuration_cal_count : 1;
        }flags;
    }flags;
    uint8_t     HWType;             //(IVCAM2 , DS5 etc)
    uint8_t     SKUsID;
    uint32_t    cookie;             //Place Holder enable FW to bundle cookie with control state and configuration.
    uint16_t    format;
    uint16_t    width;              //Requested resolution
    uint16_t    height;
    uint16_t    FPS;                //Requested FPS
    uint16_t    trigger;            /*Byte <0> – 0 free-running
                                    1 in sync
                                    2 external trigger (depth only)
                                    Byte <1> – configured delay (depth only)*/
    uint16_t    calibrationCount;
    uint8_t     Reserved[6];
};

///////////////
//Intel Stat //
///////////////

// {B28D4754-B0BF-4F7B-8B9D-35A18DBF83B8}
DEFINE_GUID(REALSENSE_SAMPLE_RS400_STATISTICS_METADATA,
    0xb28d4754, 0xb0bf, 0x4f7b, 0x8b, 0x9d, 0x35, 0xa1, 0x8d, 0xbf, 0x83, 0xb8);

struct RealsenseRS400MetaDataIntelStat
{
    uint32_t    version;
    union
    {
        uint32_t raw;
        struct {
            uint32_t intel_stat_left_sum : 1;
            uint32_t intel_stat_left_dark_count : 1;
            uint32_t intel_stat_left_bright_count : 1;
            uint32_t intel_stat_right_sum : 1;
            uint32_t intel_stat_right_dark_count : 1;
            uint32_t intel_stat_right_bright_count : 1;
            uint32_t intel_stat_rec_frame_count : 1;
            uint32_t intel_stat_left_red_sum : 1;
            uint32_t intel_stat_left_green1_sum : 1;
            uint32_t intel_stat_left_green2_sum : 1;
            uint32_t intel_stat_stat_left_blue_sum : 1;
            uint32_t intel_stat_right_red_sum : 1;
            uint32_t intel_stat_right_green1_sum : 1;
            uint32_t intel_stat_right_green2_sum : 1;
            uint32_t intel_stat_right_blue_sum : 1;
        } flags;
    }flags;
    uint32_t    exposureLeftSum;
    uint32_t    exposureLeftDarkCount;
    uint32_t    exposureLeftBrightCount;
    uint32_t    exposureRightSum;
    uint32_t    exposureRightDarkCount;
    uint32_t    exposureRightBrightCount;
    uint32_t    recFrameCount;
    uint32_t    leftRedSum;
    uint32_t    leftGreen1Sum;
    uint32_t    leftGreen2Sum;
    uint32_t    leftBlueSum;
    uint32_t    rightRedSum;
    uint32_t    rightGreen1Sum;
    uint32_t    rightGreen2Sum;
    uint32_t    rightBlueSum;
    uint32_t    Reserved;

};

///////////////////////
// Fisheye Extrinsics //
///////////////////////

struct STMFCameraExtrinsicCalibratedFishEyeTransform
{
    GUID    calibrationId;     //GUID
    float   R_FE[3][3];        // [1x3]: FishEye rotation angles
    float   T_FE[3];           // [1x3]: FishEye translation vector, mm
};

// {FC3B0B6C-FA7E-44A4-BA7D-0CA873337488}
DEFINE_GUID(REALSENSE_SAMPLE_RS400_FISHEYE_EXTRINSICS,
    0xfc3b0b6c, 0xfa7e, 0x44a4, 0xba, 0x7d, 0xc, 0xa8, 0x73, 0x33, 0x74, 0x88);

// {F19B3A16-CE1D-4B98-800E-1CA5B496F65F}
DEFINE_GUID(REALSENSE_STREAM_RS400_FISHEYE_EXTRINSICS,
    0xf19b3a16, 0xce1d, 0x4b98, 0x80, 0xe, 0x1c, 0xa5, 0xb4, 0x96, 0xf6, 0x5f);


struct STMFCameraFishEyeExtrinsics
{
    uint32_t transformCount;
    STMFCameraExtrinsicCalibratedFishEyeTransform CalibratedFishEyeTransforms[1];
};

//////////////////////////////////////////////////////////////////////////
//
// Sample code for sending KS control to the RS400 device from media capture code.
// In this example we set the laser power to 7
// ksPropSetId contains the control GUID and the id (KSPROPERTYSETID_RS400_DEPTH_CONTROL KSPROPERTY_XU_RS400_DEPTH::LASER_POWER).
// value contains the laser power (7).
//
// Notice that the Device MFT wraps extension unit KS controls so you can't call extension units without installing the DMFT.
//
//////////////////////////////////////////////////////////////////////////
#if 0
const string ksPropSetId = "{C9606CCB-594C-4D25-AF47-CCC496435995} 2"
int laserPower = 7;
byte[] value = BitConverter.GetBytes(laserPower);
Object propVal = PropertyValue.CreateUInt8Array(value);
// Option 1 (will throw exception if failed).
source.Controller.VideoDeviceController.SetDeviceProperty(ksPropSetId, propVal); 
// Option 2: (will return error if failed).
MediaFrameSourceSetPropertyStatus result = source.Controller.SetPropertyAsync(ksPropSetId, propVal);
#endif

// There are many samples in Git Hub that can be used as a reference.
// It is best to start with CameraFrames: https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/CameraFrames
// Download the sources from: https://github.com/Microsoft/Windows-universal-samples

#pragma pack(pop)