//
//  APITest.m
//  AVCapture
//
//  Created by magewell on 2025/5/6.
//  Copyright © 2025 magewell. All rights reserved.
//

#import "APITest.h"
#include "LibMWCapture/MWCapture.h"
#include "LibMWCapture/WinTypes.h"

@implementation APITest

typedef void(*LPFN_HOT_PLUG_CALLBACK)(MWUSBHOT_PLUG_EVETN event, const char *pszDevicePath, void* pParam);

static void HotplugCheckCallback(MWUSBHOT_PLUG_EVETN event, const char *pszDevicePath, void* pParam)
{
    switch(event)
    {
        case USBHOT_PLUG_EVENT_DEVICE_ARRIVED:
            printf("\nDevice reconnect\n");
            break;
        case USBHOT_PLUG_EVENT_DEVICE_LEFT:
            printf("\nDevice disconnect\n");
            break;
        default:
            break;
    }
}

#pragma mark
- (id)init
{
    if (self = [super init]) {
        MWCaptureInitInstance();
    }
    return self;
}

- (void)destory
{
    MWCaptureExitInstance();
}
#pragma mark - ProCaptureAPI - Pro Capture Family
- (void)testProCaptureAPI
{

    NSLog(@"---Refres and Open---");
    MW_RESULT ret = MW_SUCCEEDED;
    
    ret = MWRefreshDevice();
    
    int channelCount = MWGetChannelCount();
    for (int i=0; i<channelCount; i++) {
        MWCAP_CHANNEL_INFO pChannelInfo;
        MWGetChannelInfoByIndex(i, &pChannelInfo);
        NSLog(@"Device SerialNo:%s-%02d-%d",pChannelInfo.szBoardSerialNo,pChannelInfo.byBoardIndex,pChannelInfo.byChannelIndex);
    }
    
//    char wPath[256] = {0};
//    ret = MWGetDevicePath(channelCount-1, wPath);
//    HCHANNEL channel2 = MWOpenChannelByPath(wPath);
    
    MWCAP_CHANNEL_INFO pChannelInfo;
    MWGetChannelInfoByIndex(channelCount-1, &pChannelInfo);
    HCHANNEL channel = MWOpenChannel(pChannelInfo.byBoardIndex, pChannelInfo.byChannelIndex);
    if (channel == NULL) {
        NSLog(@"open device fail");
        return;
    }
    

    {
        MWCAP_PTR hTimerEvent      = MWCreateEvent();
        HTIMER hTimerNotify = MWRegisterTimer(channel, hTimerEvent);
        LONGLONG llCurrentTime = 0LL;
        ret = MWGetDeviceTime(channel, &llCurrentTime);
        LONGLONG llExpireTime = llCurrentTime;
        NSLog(@"---log event MWScheduleTimer:%lld",llExpireTime-llCurrentTime);
        ret = MWScheduleTimer(channel, hTimerNotify, llExpireTime);
        NSLog(@"---log event MWWaitEvent");
        DWORD dwRet = MWWaitEvent(hTimerEvent, 1000); //ETIMEDOUT
        
        LONGLONG now = 0LL;
        ret = MWGetDeviceTime(channel, &now);

        NSLog(@"---log event MWWaitEvent dwRet:%d now:%lld",dwRet,now-llCurrentTime);
        NSLog(@"now:%lld",now-llCurrentTime);
    }

    MWCAP_VIDEO_SIGNAL_STATUS pVideoSignalStatus = {};
    ret = MWGetVideoSignalStatus(channel, &pVideoSignalStatus);
    if (ret != MW_SUCCEEDED) {
        NSLog(@"");
    }
    float fps = 10000000.0/pVideoSignalStatus.dwFrameDuration;
    NSLog(@"video signal colorFormat:%d %dx%d,%.2ffps",pVideoSignalStatus.colorFormat,pVideoSignalStatus.cx,pVideoSignalStatus.cy,fps);
//
    MWCAP_AUDIO_SIGNAL_STATUS pAudioSignalStatus = {0};
    ret = MWGetAudioSignalStatus(channel, &pAudioSignalStatus);
    NSLog(@"audio signal pcm:%d sampleRate:%d bitsPerSample:%d channelStatusValid:%d",pAudioSignalStatus.bLPCM,pAudioSignalStatus.dwSampleRate,pAudioSignalStatus.cBitsPerSample,pAudioSignalStatus.bChannelStatusValid);

    //    MWCAP_VIDEO_PROC_BRIGHTNESS,MWCAP_VIDEO_PROC_CONTRAST,MWCAP_VIDEO_PROC_HUE,MWCAP_VIDEO_PROC_SATURATION

    NSLog(@"---VideoProcParam sdk层实现---");
//    long plParamValueMin;
//    long plParamValueMax;
//    long plParamValueDef;
//    ret = MWGetVideoProcParamRange(channel, MWCAP_VIDEO_PROC_BRIGHTNESS, &plParamValueMin, &plParamValueMax, &plParamValueDef);
//    
//    ret = MWSetVideoProcParam(channel, MWCAP_VIDEO_PROC_BRIGHTNESS, plParamValueMin);
//
//    ret = MWGetVideoProcParamRange(channel, MWCAP_VIDEO_PROC_BRIGHTNESS, &plParamValueMin, &plParamValueMax, &plParamValueDef);
//
    NSLog(@"---BRIGHTNESS 不在支持---");
//    int pnBrightness;
//    ret = MWGetVideoBrightness(channel, &pnBrightness); //kIOReturnUnsupported
//    NSLog(@"API - MWGetVideoBrightness ret:%d",ret);
//    ret = MWSetVideoBrightness(channel, (int)plParamValueDef);  //kIOReturnUnsupported

    
    NSLog(@"---Time---");
    long long pllTime;
    ret = MWGetDeviceTime(channel, &pllTime);
    NSLog(@"API - MWGetDeviceTime ret:%d pllTime:%lld",ret, pllTime);

    pllTime += 1000*1000;
    ret = MWSetDeviceTime(channel, pllTime);    //kIOReturnBadArgument
    NSLog(@"API - MWSetDeviceTime ret:%d",ret);

    long long pllTime2;
    ret = MWGetDeviceTime(channel, &pllTime2);
    NSLog(@"API - MWGetDeviceTime ret:%d pllTime:%lld",ret, pllTime2);

    pllTime += 1000*1000;
    ret = MWRegulateDeviceTime(channel, pllTime);
    NSLog(@"API - MWRegulateDeviceTime ret:%d",ret);

    long long pllTime3;
    ret = MWGetDeviceTime(channel, &pllTime3);
    NSLog(@"API - MWGetDeviceTime ret:%d pllTime:%lld",ret, pllTime3);
    
    NSLog(@"---Event---");
    MWCAP_PTR hCaptureEvent = MWCreateEvent();  //kIOReturnUnsupported
    MWCAP_PTR hTimerEvent = MWCreateEvent();
    MWCAP_PTR hAudioEvent   = MWCreateEvent();
    if (hTimerEvent == 0) {
//        return;
    }
    
    HTIMER hTimerNotify = MWRegisterTimer(channel, hTimerEvent);
    ret = MWUnregisterTimer(channel, hTimerNotify);
    
    NSLog(@"-------");
    ret = MWStartVideoCapture(channel, hTimerNotify);
//    NSLog(@"-------");
//    ret = MWStartVideoCapture(channel, 1);
    
    HNOTIFY videoSignalNotify = MWRegisterNotify(channel, hCaptureEvent, MWCAP_NOTIFY_VIDEO_SIGNAL_CHANGE);
    ULONGLONG ullStatusBits = 0LL;
    ret = MWGetNotifyStatus(channel, videoSignalNotify, &ullStatusBits);
    if (ullStatusBits & MWCAP_NOTIFY_VIDEO_SIGNAL_CHANGE) {
        NSLog(@"");
    } else {
        NSLog(@"");
    }
    
    ret = MWUnregisterNotify(channel, videoSignalNotify);

    ret = MWStopVideoCapture(channel);
    
    HNOTIFY audioNotify = MWRegisterNotify(channel, hAudioEvent, MWCAP_NOTIFY_AUDIO_FRAME_BUFFERED);
    ret = MWUnregisterNotify(channel, audioNotify);

//    MWCAP_PTR pbFrame = {0};
//    unsigned int cbFrame = 0;
//    ret = MWPinVideoBuffer(channel, pbFrame, cbFrame);  //kIOReturnUnsupported
//    NSLog(@"API - MWPinVideoBuffer ret:%d",ret);
//    LPBYTE pbFrame2;
//    ret = MWUnpinVideoBuffer(channel, pbFrame2);
//    NSLog(@"API - MWUnpinVideoBuffer ret:%d",ret);

    MWCAP_VIDEO_BUFFER_INFO videoBufferInfo = {0};
    ret = MWGetVideoBufferInfo(channel, &videoBufferInfo);  //kIOReturnUnsupported
    NSLog(@"API - MWGetVideoBufferInfo ret:%d",ret);
    MWCAP_VIDEO_FRAME_INFO videoFrameInfo;
    ret = MWGetVideoFrameInfo(channel, videoBufferInfo.iNewestBufferedFullFrame, &videoFrameInfo);  //kIOReturnUnsupported
    NSLog(@"API - MWGetVideoFrameInfo ret:%d",ret);

    MWCAP_VIDEO_CAPTURE_STATUS captureStatus;
    ret = MWGetVideoCaptureStatus(channel, &captureStatus);
    NSLog(@"API - MWGetVideoCaptureStatus ret:%d",ret);
    
    ret = MWSetPostReconfig(channel, 1000);
    NSLog(@"API - MWSetPostReconfig ret:%d",ret);
    
//    HOSD image = MWCreateImage(channel, 1920, 1080);
//    if (image != 0) {
//        long plRet;
//        ret = MWOpenImage(channel, image, &plRet);
//        NSLog(@"API - MWOpenImage ret:%d",ret);
//
//        long plRet2;
//        ret = MWCloseImage(channel, image, &plRet2);
//        NSLog(@"API - MWCloseImage ret:%d",ret);
//    }
    
    unsigned int pnTemp;
    ret = MWGetTemperature(channel, &pnTemp);
    NSLog(@"API - MWGetTemperature ret:%d pnTemp:%d",ret,pnTemp);

//    MWCAP_VIDEO_OSD_SETTINGS pOSDSettings;
//    ret = MWGetVideoOSDSettings(channel, &pOSDSettings);
//    NSLog(@"API - MWGetVideoOSDSettings ret:%d enable:%d path:%s",ret,pOSDSettings.bEnable,pOSDSettings.szPNGFilePath);
//    
//    pOSDSettings.bEnable = !pOSDSettings.bEnable;
//    ret = MWSetVideoOSDSettings(channel, pOSDSettings);
//    NSLog(@"API - MWSetVideoOSDSettings ret:%d",ret);
//
//    MWCAP_VIDEO_OSD_IMAGE pOSDImage;
//    ret = MWGetVideoOSDImage(channel, &pOSDImage);
//    NSLog(@"API - MWGetVideoOSDImage ret:%d",ret);

//    int pnContrast;
//    ret = MWGetVideoContrast(channel, &pnContrast);
//    NSLog(@"API - MWGetVideoOSDImage ret:%d",ret);
//    ret = MWSetVideoContrast(channel, pnContrast);
//    NSLog(@"API - MWSetVideoContrast ret:%d",ret);
    
//    int pnHue;
//    ret = MWGetVideoHue(channel, &pnHue);
//    NSLog(@"API - MWGetVideoHue ret:%d",ret);
//    ret = MWSetVideoHue(channel, pnHue);
//    NSLog(@"API - MWSetVideoHue ret:%d",ret);
//    
//    int pnSaturation;
//    ret = MWGetVideoSaturation(channel, &pnSaturation);
//    NSLog(@"API - MWGetVideoSaturation ret:%d",ret);
//    ret = MWSetVideoSaturation(channel, pnSaturation);
//    NSLog(@"API - MWSetVideoSaturation ret:%d",ret);
//    
//    ret = MWSaveSettingsAsPreset(channel);
//    NSLog(@"API - MWSaveSettingsAsPreset ret:%d",ret);
//
//    ret = MWReloadPreset(channel);
//    NSLog(@"API - MWSaveSettingsAsPreset ret:%d",ret);

    BOOLEAN pbAuto;
    ret = MWGetVideoAutoHAlign(channel, &pbAuto);
    NSLog(@"API - MWGetVideoAutoHAlign ret:%d pbAuto:%d",ret, pbAuto);
    ret = MWSetVideoAutoHAlign(channel, !pbAuto);
    NSLog(@"API - MWSetVideoAutoHAlign ret:%d",ret);
    ret = MWGetVideoAutoHAlign(channel, &pbAuto);
    NSLog(@"API - MWGetVideoAutoHAlign ret:%d pbAuto:%d",ret, pbAuto);

    unsigned char pbyValue;
    ret = MWGetVideoSamplingPhase(channel, &pbyValue);
    NSLog(@"API - MWGetVideoSamplingPhase ret:%d",ret);
    ret = MWSetVideoSamplingPhase(channel, pbyValue);
    NSLog(@"API - MWSetVideoSamplingPhase ret:%d",ret);
    
    ret = MWGetVideoSamplingPhaseAutoAdjust(channel, &pbAuto);
    NSLog(@"API - MWGetVideoSamplingPhaseAutoAdjust ret:%d pbAuto:%d",ret, pbAuto);
    ret = MWSetVideoSamplingPhaseAutoAdjust(channel, !pbAuto);
    NSLog(@"API - MWSetVideoSamplingPhaseAutoAdjust ret:%d",ret);
    ret = MWGetVideoSamplingPhaseAutoAdjust(channel, &pbAuto);
    NSLog(@"API - MWGetVideoSamplingPhaseAutoAdjust ret:%d pbAuto:%d",ret, pbAuto);

    MWCAP_VIDEO_TIMING videoTiming;
    videoTiming.dwType = MWCAP_VIDEO_TIMING_LEGACY;
    ret = MWSetVideoTiming(channel, videoTiming);
    NSLog(@"API - MWSetVideoTiming ret:%d",ret);
    
    MWCAP_VIDEO_TIMING pVideoTiming;
    long count;
    ret = MWGetVideoPreferredTimingArray(channel, &pVideoTiming, &count);
    NSLog(@"API - MWGetVideoPreferredTimingArray ret:%d count:%ld",ret,count);

    //Custom Video Timings
    unsigned int pdwCount = 2;
    MWCAP_VIDEO_CUSTOM_TIMING* timingsArray = new MWCAP_VIDEO_CUSTOM_TIMING[pdwCount];
    timingsArray[0].syncInfo.bySyncType = VIDEO_SYNC_ALL;
    timingsArray[0].videoTimingSettings.cx = 1920;
    timingsArray[0].videoTimingSettings.cy = 1080;
    ret = MWSetCustomVideoTimingsArray(channel, timingsArray, pdwCount);
//    free(videoTiming);
    NSLog(@"API - MWSetCustomVideoTiming ret:%d",ret);

    ret = MWGetCustomVideoTimingsCount(channel, &pdwCount);
    NSLog(@"API - MWGetCustomVideoTimingsCount ret:%d pdwCount:%d",ret,pdwCount);
    
    MWCAP_VIDEO_CUSTOM_TIMING* videoCustomTiming = new MWCAP_VIDEO_CUSTOM_TIMING[pdwCount];
    ret = MWGetCustomVideoTimingsArray(channel, videoCustomTiming, &pdwCount);
    NSLog(@"API - MWGetCustomVideoTimingsCount ret:%d pdwCount:%d",ret,pdwCount);
    
    
    //Custom Video Resolutions
    pdwCount = 2;
    MWCAP_SIZE* resolutionSize = new MWCAP_SIZE[pdwCount];
    resolutionSize[0].cx = 1920;
    resolutionSize[0].cy = 1080;
    resolutionSize[1].cx = 1280;
    resolutionSize[1].cy = 720;
    ret = MWSetCustomVideoResolutionsArray(channel, resolutionSize, 2);
    NSLog(@"API - MWSetCustomVideoResolutionsArray ret:%d pdwCount:%d", ret, pdwCount);
    
    ret = MWGetCustomVideoResolutionsCount(channel, &pdwCount);
    NSLog(@"API - MWGetCustomVideoResolutionsCount ret:%d pdwCount:%d",ret,pdwCount);
    
    MWCAP_SIZE* pResolutionSize = new MWCAP_SIZE[pdwCount];
    ret = MWGetCustomVideoResolutionsArray(channel, pResolutionSize, &pdwCount);
    NSLog(@"API - MWGetCustomVideoResolutionsArray ret:%d pdwCount:%d [0].cx=%d", ret, pdwCount,pResolutionSize[0].cx);
    

    MWCloseChannel(channel);
    NSLog(@"");
    
}

#pragma mark - CaptureAPI - Universal
- (void)testCaptureAPI
{
    MW_RESULT ret = MW_SUCCEEDED;
    BYTE pbyMaj;BYTE pbyMin;WORD pwBuild;
    ret = MWGetVersion(&pbyMaj, &pbyMin, &pwBuild);
    NSLog(@"API - MWGetVersion ret:%d version:%d.%d.%d",ret,pbyMaj,pbyMin,pwBuild);
    
    ret = MWRefreshDevice();
    NSLog(@"API - MWRefreshDevice ret:%d",ret);
    
    int channelCount = MWGetChannelCount();
    NSLog(@"API - channelCount ret:%d count:%d", MW_SUCCEEDED, channelCount);
    for (int i=0; i<channelCount; i++) {
        MWCAP_CHANNEL_INFO pChannelInfo;
        ret = MWGetChannelInfoByIndex(i, &pChannelInfo);
        NSLog(@"API - MWGetChannelInfoByIndex ret:%d Device SerialNo:%s-%02d-%d  driverVersion:%d.%d.%d",ret, pChannelInfo.szBoardSerialNo,pChannelInfo.byBoardIndex,pChannelInfo.byChannelIndex, (pChannelInfo.dwDriverVersion >> 24) , (pChannelInfo.dwDriverVersion >> 16) & 0x00ff, pChannelInfo.dwDriverVersion & 0xffff);
        
        MWCAP_PRO_CAPTURE_INFO pFamilyInfo = {0};
        ret = MWGetFamilyInfoByIndex(i, &pFamilyInfo, sizeof(MWCAP_PRO_CAPTURE_INFO));
        NSLog(@"API - MWGetFamilyInfoByIndex ret:%d bus:%d devId:%d linkType:%d",ret, pFamilyInfo.byPCIBusID, pFamilyInfo.byPCIDevID, pFamilyInfo.byLinkType);
    }
    
    char wPath[256] = {0};
    ret = MWGetDevicePath(channelCount-2, wPath);
    NSLog(@"API - MWGetDevicePath ret:%d path:%s",ret,wPath);
    

    HCHANNEL channel = MWOpenChannelByPath(wPath);
    if (channel == NULL) {
        NSLog(@"open device fail");
        NSLog(@"API - MWOpenChannelByPath ret:fail");
        return;
    } else {
        NSLog(@"API - MWOpenChannelByPath ret:%d",MW_SUCCEEDED);
    }
    
    char pszVideoDevicePath[256] = {0};
    ret = MWGetVideoDevicePathByChannel(channel, pszVideoDevicePath);
    NSLog(@"API - MWGetVideoDevicePathByChannel ret:%d path:%s",ret,pszVideoDevicePath);

    
    MWCAP_CHANNEL_INFO pChannelInfo;
    ret = MWGetChannelInfo(channel, &pChannelInfo);
    NSLog(@"API - MWGetChannelInfo ret:%d Device SerialNo:%s-%02d-%d",ret, pChannelInfo.szBoardSerialNo,pChannelInfo.byBoardIndex,pChannelInfo.byChannelIndex);

    MWUSBCAP_CAPTURE_INFO pfamilyInfo = {0};
    ret = MWGetFamilyInfo(channel, &pfamilyInfo, sizeof(MWUSBCAP_CAPTURE_INFO));
    NSLog(@"API - MWGetFamilyInfo ret:%d BoardIndex:%d USBSpeed:%d TotalMemorySize:%lld",ret, pfamilyInfo.byBoardIndex,pfamilyInfo.byUSBSpeed,pfamilyInfo.cbTotalMemorySize);

    MWCAP_VIDEO_CAPS pVideoCaps = {0};
    ret = MWGetVideoCaps(channel, &pVideoCaps);
    NSLog(@"API - MWGetVideoCaps ret:%d inPutWidth:%d inPutHeight:%d outPutWidth:%d outPutHeight:%d",ret, pVideoCaps.wMaxInputWidth, pVideoCaps.wMaxInputHeight, pVideoCaps.wMaxOutputWidth, pVideoCaps.wMaxOutputHeight);

    MWCAP_AUDIO_CAPS pAudioInfo = {0};
    ret = MWGetAudioCaps(channel, &pAudioInfo);
    NSLog(@"API - MWGetAudioCaps ret:%d CAPS:%d",ret, pAudioInfo.dwCaps);

    // Video Input Source
    DWORD dwVideoInputCount = 0;
    ret = MWGetVideoInputSourceArray(channel, NULL, &dwVideoInputCount);
    NSLog(@"API - MWGetVideoInputSourceArray ret:%d count:%d",ret, dwVideoInputCount);
    if (ret == MW_SUCCEEDED && dwVideoInputCount > 0) {
        DWORD* pVideoInput = new DWORD[dwVideoInputCount];
        ret = MWGetVideoInputSourceArray(channel, pVideoInput, &dwVideoInputCount);
        if (ret == MW_SUCCEEDED) {
            char szInputName[16] = { 0 };
            for (DWORD i = 0; i < dwVideoInputCount; i++) {
                GetVideoInputName(pVideoInput[i], szInputName, 16);
                NSLog(@"API - MWGetVideoInputSourceArray ret:%d input[%d] name:%s",ret, i, szInputName);
            }
        }
        delete[] pVideoInput;
    }
    
    DWORD dwVideoInput = 0;
    ret = MWGetVideoInputSource(channel, &dwVideoInput);
    NSLog(@"API - MWGetVideoInputSource ret:%d", ret);
    if (ret == MW_SUCCEEDED) {
        char szInputName[16] = { 0 };
        GetVideoInputName(dwVideoInput, szInputName, 16);
        NSLog(@"API - MWGetVideoInputSource ret:%d Input Source: %s", ret, szInputName);
    }
    
    ret = MWSetVideoInputSource(channel, dwVideoInput); //结果未验证
    NSLog(@"API - MWSetVideoInputSource ret:%d", ret);

    
    // Audio Input Source
    DWORD dwAudioInputCount = 0;
    ret = MWGetAudioInputSourceArray(channel, NULL, &dwAudioInputCount);
    NSLog(@"API - MWGetAudioInputSourceArray ret:%d count:%d", ret, dwAudioInputCount);

    if (ret == MW_SUCCEEDED && dwAudioInputCount > 0) {
        DWORD* pAudioInput = new DWORD[dwAudioInputCount];
        ret = MWGetAudioInputSourceArray(channel, pAudioInput, &dwAudioInputCount);
        if (ret == MW_SUCCEEDED) {
            char szInputName[16] = { 0 };
            for (DWORD i = 0; i < dwAudioInputCount; i++) {
                GetAudioInputName(pAudioInput[i], szInputName, 16);
                NSLog(@"API - MWGetAudioInputSourceArray ret:%d input[%d] %s", ret, i, szInputName);

            }
        }
        delete[] pAudioInput;
    }
    
    DWORD dwAudioInput = 0;
    ret = MWGetAudioInputSource(channel, &dwAudioInput);
    NSLog(@"API - MWGetAudioInputSource ret:%d", ret);
    if (ret == MW_SUCCEEDED) {
        char szInputName[16] = { 0 };
        GetAudioInputName(dwAudioInput, szInputName, 16);
        NSLog(@"API - MWGetAudioInputSource ret:%d name:%s", ret, szInputName);

    }
    
    ret = MWSetAudioInputSource(channel, 0);
    NSLog(@"API - MWSetAudioInputSource ret:%d", ret);

    
    NSLog(@"---video/audio signal status---");
    MWCAP_VIDEO_SIGNAL_STATUS pVideoSignalStatus = {};
    ret = MWGetVideoSignalStatus(channel, &pVideoSignalStatus);
    NSLog(@"API - MWGetVideoSignalStatus ret:%d  %d x %d", ret, pVideoSignalStatus.cx, pVideoSignalStatus.cy);

//
    MWCAP_AUDIO_SIGNAL_STATUS pAudioSignalStatus = {0};
    ret = MWGetAudioSignalStatus(channel, &pAudioSignalStatus);
    NSLog(@"API - MWGetAudioSignalStatus ret:%d wChannelValid:%d dwSampleRate:%d", ret, pAudioSignalStatus.wChannelValid, pAudioSignalStatus.dwSampleRate);

    
    
    NSLog(@"---SourceScan---");
    BOOLEAN scan;
    ret = MWGetInputSourceScan(channel, &scan);
    NSLog(@"API - MWGetInputSourceScan:%d scan:%d", ret, scan);
    
    ret = MWSetInputSourceScan(channel, !scan); //Not working
    NSLog(@"API - MWSetInputSourceScan:%d", ret);
    
    ret = MWGetInputSourceScan(channel, &scan);
    NSLog(@"API - MWGetInputSourceScan:%d scan:%d", ret, scan);

    NSLog(@"---CustomVideoResolutions---");
    DWORD resolutionsCount = 0;
    ret = MWGetCustomVideoResolutionsCount(channel, &resolutionsCount);   //kIOReturnUnsupported
    
    MWCAP_SIZE pResolutionSize = {0};
    DWORD pdwCount = 0;
    ret = MWGetCustomVideoResolutionsArray(channel, &pResolutionSize, &pdwCount);//kIOReturnUnsupported
    
    NSLog(@"---SourceLink---");
    BOOLEAN link;
    ret = MWGetAVInputSourceLink(channel, &link);
    NSLog(@"API - MWGetAVInputSourceLink:%d link:%d", ret, link);

    ret = MWSetAVInputSourceLink(channel, !link); //Not working
    NSLog(@"API - MWSetAVInputSourceLink:%d", ret);

    ret = MWGetAVInputSourceLink(channel, &link);
    NSLog(@"API - MWGetAVInputSourceLink:%d link:%d", ret, link);

    NSLog(@"---EDID---");
    ULONG ulSize = 256;
    BYTE byData[256]={0};
    ret = MWGetEDID(channel, byData, &ulSize);
    NSLog(@"API - MWGetEDID ret:%d EDID:%s", ret, byData);

    ret = MWSetEDID(channel, byData, ulSize);
    NSLog(@"API - MWSetEDID ret:%d", ret);

    NSLog(@"---InputSpecific---");
    MWCAP_INPUT_SPECIFIC_STATUS pInputStatus = {0};
    ret = MWGetInputSpecificStatus(channel, &pInputStatus);
    NSLog(@"API - MWGetInputSpecificStatus:%d Valid:%d VideoInputType:%d", ret, pInputStatus.bValid,pInputStatus.dwVideoInputType);
    
    NSLog(@"---HDMIInfoFrame---");
    unsigned int pdwValidFlag;
    ret = MWGetHDMIInfoFrameValidFlag(channel, &pdwValidFlag);
    NSLog(@"API - MWGetHDMIInfoFrameValidFlag ret:%d", ret);

    HDMIinfoFrameTest(pdwValidFlag,channel);
    
    NSLog(@"---VideoInputAspectRatio---");
    int pnAspectX,pnAspectY;
    ret = MWGetVideoInputAspectRatio(channel, &pnAspectX, &pnAspectY);
    NSLog(@"API - MWGetVideoInputAspectRatio ret:%d x:%d y:%d", ret, pnAspectX, pnAspectY);
    ret = MWSetVideoInputAspectRatio(channel, 5, 5);    //Not working
    NSLog(@"API - MWSetVideoInputAspectRatio ret:%d", ret);
    ret = MWGetVideoInputAspectRatio(channel, &pnAspectX, &pnAspectY);
    NSLog(@"API - MWGetVideoInputAspectRatio ret:%d x:%d y:%d", ret, pnAspectX, pnAspectY);

    NSLog(@"---ColorFormat---");
    MWCAP_VIDEO_COLOR_FORMAT pColorFormat;
    ret = MWGetVideoInputColorFormat(channel, &pColorFormat);
    NSLog(@"API - MWGetVideoInputColorFormat ret:%d colorFormat:%d", ret ,pColorFormat);
    ret = MWSetVideoInputColorFormat(channel, MWCAP_VIDEO_COLOR_FORMAT_YUV601);
    NSLog(@"API - MWSetVideoInputColorFormat ret:%d",ret);
    ret = MWGetVideoInputColorFormat(channel, &pColorFormat);
    NSLog(@"API - MWGetVideoInputColorFormat ret:%d colorFormat:%d", ret ,pColorFormat);

    
    
    NSLog(@"---QuantizationRange---");
    MWCAP_VIDEO_QUANTIZATION_RANGE pQuantRange;;
    ret = MWGetVideoInputQuantizationRange(channel, &pQuantRange);
    NSLog(@"API - MWGetVideoInputQuantizationRange ret:%d QuantRange:%d", ret ,pQuantRange);
    ret = MWSetVideoInputQuantizationRange(channel, MWCAP_VIDEO_QUANTIZATION_FULL);
    NSLog(@"API - MWSetVideoInputQuantizationRange ret:%d", ret);
    ret = MWGetVideoInputQuantizationRange(channel, &pQuantRange);
    NSLog(@"API - MWGetVideoInputQuantizationRange ret:%d QuantRange:%d", ret ,pQuantRange);
    
    NSLog(@"---LED---");
    ret = MWSetLEDMode(channel, 0); //kIOReturnBadArgument
    NSLog(@"API - MWSetLEDMode ret:%d", ret);

    NSLog(@"---FIRMWARE---确认不再支持");
//    MWCAP_FIRMWARE_STORAGE pFirmwareStorageInfo;
//    ret = MWGetFirmwareStorageInfo(channel, &pFirmwareStorageInfo); //kIOReturnUnsupported
//    NSLog(@"API - MWGetFirmwareStorageInfo ret:%d", ret);
//    int cbOffset = 0;
//    int cbErase = 0;
//    ret = MWEraseFirmwareData(channel, cbOffset, cbErase);  //kIOReturnUnsupported
//    NSLog(@"API - MWEraseFirmwareData ret:%d", ret);
//    BYTE pbyData;
//    DWORD pcbRead;
//    ret = MWReadFirmwareData(channel, 0, &pbyData, 100, &pcbRead);  //kIOReturnUnsupported
//    NSLog(@"API - MWReadFirmwareData ret:%d", ret);
//
//    ret = MWWriteFirmwareData(channel, 0, &pbyData, pcbRead);   //kIOReturnUnsupported
//    NSLog(@"API - MWWriteFirmwareData ret:%d", ret);


    
    MWCAP_AUDIO_NODE audioNode = MWCAP_AUDIO_EMBEDDED_CAPTURE;
    MWCAP_AUDIO_VOLUME pVolume;
    ret = MWGetAudioVolume(channel, audioNode, &pVolume);
    NSLog(@"API - MWGetAudioVolume ret:%d", ret);
    ret = MWSetAudioVolume(channel, audioNode, &pVolume);
    NSLog(@"API - MWSetAudioVolume ret:%d", ret);

    MWCAP_SDI_ANC_PACKET pPacket;
    ret = MWCaptureGetSDIANCPacket(channel, &pPacket);  //kIOReturnUnsupported
    NSLog(@"API - MWCaptureGetSDIANCPacket ret:%d", ret);

    BYTE byIndex = 0;
    BOOLEAN bHANC = false;
    BOOLEAN bVANC = false;
    
    ret = MWCaptureSetSDIANCType(channel, byIndex, bHANC, bVANC, pPacket.byDID, pPacket.bySDID);
    NSLog(@"API - MWCaptureSetSDIANCType ret:%d", ret);
    
    MWCAP_SDI_ANC_PACKET pPacket2;
    ret = MWCaptureGetSDIANCPacket(channel, &pPacket2);  //kIOReturnUnsupported
    NSLog(@"API - MWCaptureGetSDIANCPacket ret:%d", ret);
    

    MWCAP_VIDEO_RESOLUTION_MODE pMode;
    int pCount;
    ret = MWGetVideoCaptureSupportResolutionMode(channel, &pMode, &pCount);
    NSLog(@"API - MWGetVideoCaptureSupportResolutionMode ret:%d mode:%d count:%d", ret, pMode, pCount);

    MWCAP_VIDEO_RESOLUTION_RANGE pRange;
    ret = MWGetVideoCaptureSupportRangeResolution(channel, &pRange);
    NSLog(@"API - MWGetVideoCaptureSupportRangeResolution ret:%d nStepCx:%d nStepCy:%d minResolution:%d maxResolution:%d", ret, pRange.nStepCx, pRange.nStepCy,pRange.minResolution,pRange.maxResolution);

    MWCAP_VIDEO_RESOLUTION resolutions[256] = { 0 };
    MWCAP_VIDEO_RESOLUTION_LIST resList = { sizeof(resolutions)/sizeof(resolutions[0]), resolutions};
    ret = MWGetVideoCaptureSupportListResolution(channel, &resList);
    NSLog(@"API - MWGetVideoCaptureSupportListResolution ret:%d size:%d", ret, resList.nListSize);
    for(int i=0; i<resList.nListSize; i++) {
        printf("Support resolution[%d x %d]\n", resolutions[i].cx, resolutions[i].cy);
    }
    
    DWORD *pColorFourcc = (DWORD *)malloc(sizeof(DWORD)*10);
    int nCount=10;
    ret = MWGetVideoCaptureSupportColorFormat(channel, pColorFourcc, &nCount);
    NSLog(@"API - MWGetVideoCaptureSupportColorFormat ret:%d nCount:%d", ret, nCount);
    for (int i=0; i <nCount && i<10 ; i++) {
        DWORD colorFourcc = pColorFourcc[i];
        char strFourcc[5] = { 0 };
        *(uint32_t*)strFourcc = colorFourcc;
        NSLog(@"Support:%s", strFourcc);
    }
    free(pColorFourcc);
    
//    long plParamValueMin = 0;
//    long plParamValueMax = 0;
//    long plParamValueDef = 0;
//    ret = MWGetVideoProcParamRange(channel, MWCAP_VIDEO_PROC_BRIGHTNESS, &plParamValueMin, &plParamValueMax, &plParamValueDef);
//    NSLog(@"API - MWGetVideoProcParamRange ret:%d min:%ld max:%ld def:%ld", ret, plParamValueMin, plParamValueMax, plParamValueDef);
//    long plParamValue;
//    ret = MWGetVideoProcParam(channel, MWCAP_VIDEO_PROC_BRIGHTNESS, &plParamValue);
//    NSLog(@"API - MWGetVideoProcParam ret:%d plParamValue:%ld", ret, plParamValue);
//    ret = MWSetVideoProcParam(channel, MWCAP_VIDEO_PROC_BRIGHTNESS, plParamValueMin+1);
//    NSLog(@"API - MWSetVideoProcParam ret:%d ", ret);
//    ret = MWGetVideoProcParam(channel, MWCAP_VIDEO_PROC_BRIGHTNESS, &plParamValue);
//    NSLog(@"API - MWGetVideoProcParam ret:%d plParamValue:%ld", ret, plParamValue);
    
    
    NSLog(@"---CloseChannel---");
    MWCloseChannel(channel);
    NSLog(@"API - MWCloseChannel ret:%d",MW_SUCCEEDED);

    
    NSLog(@"");
}

#pragma mark - USB Capture Family
- (void)testUSBCaptureAPI
{
    MW_RESULT ret = MW_SUCCEEDED;
    BYTE pbyMaj;BYTE pbyMin;WORD pwBuild;
    ret = MWGetVersion(&pbyMaj, &pbyMin, &pwBuild);
    NSLog(@"API - MWGetVersion ret:%d version:%d.%d.%d",ret,pbyMaj,pbyMin,pwBuild);
    
    ret = MWRefreshDevice();
    NSLog(@"API - MWRefreshDevice ret:%d",ret);
    
    int channelCount = MWGetChannelCount();
    NSLog(@"Find %d channels",channelCount);
    if (channelCount <= 0){
        NSLog(@"ERROR: Can't find channels!\n");
        return;
    }
    int usbDeviceIndex = -1;
    for (int i = 0; i < channelCount; i++){
        MWCAP_CHANNEL_INFO info;
        ret = MWGetChannelInfoByIndex(i, &info);
        if (strcmp(info.szFamilyName, "USB Capture") == 0) {
            usbDeviceIndex = i;
            break;
        }
    }
    if (usbDeviceIndex < 0) {
        NSLog(@"ERROR: Can't find usb device!\n");
        return;
    }
    
    MWCAP_CHANNEL_INFO infoDevice;
    ret = MWGetChannelInfoByIndex(usbDeviceIndex, &infoDevice);
    NSLog(@"Family name: %s", infoDevice.szFamilyName);
    NSLog(@"Product name: %s", infoDevice.szProductName);
    NSLog(@"Serial number: %s", infoDevice.szBoardSerialNo);
    NSLog(@"Firmware version: %d.%d.%d", (infoDevice.dwDriverVersion >> 24) , (infoDevice.dwDriverVersion >> 16) & 0x00ff, infoDevice.dwDriverVersion & 0xffff);
    
    char wPath[256] = {0};
    ret = MWGetDevicePath(usbDeviceIndex, wPath);
    
    HCHANNEL hChannel = MWOpenChannelByPath(wPath);
    
    ret = MWUSBRegisterHotPlug(HotplugCheckCallback, NULL);
    NSLog(@"MWUSBRegisterHotPlug ret:%d",ret);
    ret = MWUSBUnRegisterHotPlug();
    NSLog(@"MWUSBUnRegisterHotPlug ret:%d",ret);
    
    MWCAP_NOTIFY_ENABLE *notifyEnable = (MWCAP_NOTIFY_ENABLE*)malloc(sizeof(MWCAP_NOTIFY_ENABLE));
    notifyEnable->bInterrupt = false;
    notifyEnable->ullEnableBits = 0;
    ret = MWUSBSetNotifyEnable(hChannel, notifyEnable);
    free(notifyEnable);
    NSLog(@"MWUSBSetNotifyEnable ret:%d",ret);

    uint64_t pullStatusBit;
    ret = MWUSBGetNotifyStatus(hChannel, &pullStatusBit);
    NSLog(@"MWUSBGetNotifyStatus ret:%d",ret);
    
//    MWUSBSetFirmwareErase
//    MWUSBGetFirmwareReadAddress
    char pbyEDID;
    uint32_t pcbEDID = 0;
    ret = MWUSBGetEDIDLoopThrough(hChannel, &pbyEDID, &pcbEDID);
    NSLog(@"MWUSBGetEDIDLoopThrough ret:%d", ret);
    
    bool_t pbValid;
    ret =  MWUSBGetLoopThroughValid(hChannel, &pbValid);
    NSLog(@"MWUSBGetLoopThroughValid ret:%d pbValid:%d", ret, pbValid);
    
    MWCAP_USB_AUDIO_NODE audioNode = MWCAP_USB_AUDIO_MICROPHONE;
    MWCAP_AUDIO_VOLUME pVolume;
    ret = MWUSBGetAudioVolume(hChannel, audioNode, &pVolume);
    NSLog(@"MWUSBGetAudioVolume ret:%d minVolume:%d maxVolume:%d", ret, pVolume.sVolumeMin, pVolume.sVolumeMax);
    
    MWCAP_AUDIO_VOLUME *Volume = (MWCAP_AUDIO_VOLUME*)malloc(sizeof(MWCAP_AUDIO_VOLUME));
    ret = MWUSBSetAudioVolume(hChannel, audioNode, Volume);
    free(Volume);
    NSLog(@"MWUSBSetAudioVolume ret:%d", ret);

    MWCAP_VIDEO_CONNECTION_FORMAT pConnFormat;
    ret = MWUSBGetVideoCaptureConnectionFormat(hChannel, &pConnFormat);
    NSLog(@"MWUSBGetVideoCaptureConnectionFormat ret:%d connected:%d cx:%ld cy:%ld", ret, pConnFormat.bConnected, pConnFormat.cx, pConnFormat.cx);
    
    MWCAP_VIDEO_PROCESS_SETTINGS pProcSettings;
    ret = MWUSBGetVideoCaptureProcessSettings(hChannel, &pProcSettings);
    NSLog(@"MWUSBGetVideoCaptureProcessSettings ret:%d colorFormat:%d", ret, pProcSettings.colorFormat);
    
    MWCAP_VIDEO_PROCESS_SETTINGS *procSettings = (MWCAP_VIDEO_PROCESS_SETTINGS*)malloc(sizeof(MWCAP_VIDEO_PROCESS_SETTINGS));
    ret = MWUSBSetVideoCaptureProcessSettings(hChannel, procSettings);
    free(procSettings);
    NSLog(@"MWUSBSetVideoCaptureProcessSettings ret:%d", ret);
    
    MWCAP_VIDEO_OUTPUT_FOURCC pOutputFourCC;
    ret = MWUSBGetVideoOutputFOURCC(hChannel, &pOutputFourCC);
    NSLog(@"MWUSBGetVideoOutputFOURCC ret:%d count:%d", ret, pOutputFourCC.byCount);

    MWCAP_VIDEO_OUTPUT_FOURCC *outputFourCC =  (MWCAP_VIDEO_OUTPUT_FOURCC*)malloc(sizeof(MWCAP_VIDEO_OUTPUT_FOURCC));
    ret = MWUSBSetVideoOutputFOURCC(hChannel, outputFourCC);
    free(outputFourCC);
    NSLog(@"MWUSBSetVideoOutputFOURCC ret:%d", ret);
    
    MWCAP_VIDEO_OUTPUT_FRAME_SIZE pFrameSize;
    ret = MWUSBGetVideoOutputFrameSize(hChannel, &pFrameSize);
    NSLog(@"MWUSBGetVideoOutputFrameSize ret:%d count:%d defult:%d", ret, pFrameSize.byCount, pFrameSize.byDefault);
    
    MWCAP_VIDEO_OUTPUT_FRAME_SIZE *frameSize =  (MWCAP_VIDEO_OUTPUT_FRAME_SIZE*)malloc(sizeof(MWCAP_VIDEO_OUTPUT_FRAME_SIZE));
    ret = MWUSBSetVideoOutputFrameSize(hChannel, frameSize);
    free(frameSize);
    NSLog(@"MWUSBSetVideoOutputFrameSize ret:%d", ret);
    
    MWCAP_VIDEO_OUTPUT_FRAME_INTERVAL pFrameInterval;
    MWUSBGetVideoOutputFrameInterval(hChannel, &pFrameInterval);
    NSLog(@"MWUSBGetVideoOutputFrameInterval ret:%d count:%d defult:%d", ret, pFrameInterval.byCount, pFrameInterval.byCount);
    
    MWCAP_VIDEO_OUTPUT_FRAME_INTERVAL *frameInterval =  (MWCAP_VIDEO_OUTPUT_FRAME_INTERVAL*)malloc(sizeof(MWCAP_VIDEO_OUTPUT_FRAME_INTERVAL));
    ret = MWUSBSetVideoOutputFrameInterval(hChannel, frameInterval);
    free(frameInterval);
    NSLog(@"MWUSBSetVideoOutputFrameInterval ret:%d", ret);
    
    //ImageMode
    MWCAP_STATUS_IMAGE_MODE pImageMode;
    ret = MWUSBGetStatusImageMode(hChannel, &pImageMode);
    NSLog(@"MWUSBGetStatusImageMode ret:%d mode:%d", ret, pImageMode);
    
    MWCAP_STATUS_IMAGE_MODE imageMode =  MWCAP_STATUS_IMAGE_BLUE;
    ret = MWUSBSetStatusImageMode(hChannel, &imageMode);
    NSLog(@"MWUSBSetStatusImageMode ret:%d", ret);
    
    MWCAP_STATUS_IMAGE_MODE pImageMode2;
    ret = MWUSBGetStatusImageMode(hChannel, &pImageMode2);
    NSLog(@"MWUSBGetStatusImageMode ret:%d mode:%d", ret, pImageMode2);

    //NameMode
    MWCAP_DEVICE_NAME_MODE pNameMode;
    ret = MWUSBGetDeviceNameMode(hChannel, &pNameMode);
    NSLog(@"MWUSBGetDeviceNameMode ret:%d mode:%d", ret,pNameMode);
    
    MWCAP_DEVICE_NAME_MODE nameMode =  MWCAP_DEVICE_NAME_DEFAULT;
    ret = MWUSBSetDeviceNameMode(hChannel, &nameMode);
    NSLog(@"MWUSBGetDeviceNameMode ret:%d", ret);
    
    MWCAP_DEVICE_NAME_MODE pNameMode2;
    ret = MWUSBGetDeviceNameMode(hChannel, &pNameMode2);
    NSLog(@"MWUSBGetDeviceNameMode ret:%d mode:%d", ret,pNameMode2);
    
    //Option
    ret = MWUSBSaveOptions(hChannel);
    NSLog(@"MWUSBSaveOptions ret:%d", ret);
    
    ret = MWUSBResetOptions(hChannel);
    NSLog(@"MWUSBResetOptions ret:%d", ret);
    
    ret = MWUSBLoadOptions(hChannel);
    NSLog(@"MWUSBLoadOptions ret:%d", ret);
    
    //AutoHAlign
    bool_t pbAutoHAlign;
    ret = MWUSBGetVideoAutoHAlign(hChannel, &pbAutoHAlign);
    NSLog(@"MWUSBGetVideoAutoHAlign ret:%d AutoHAlign:%d", ret,pNameMode2);
    
    ret = MWUSBSetVideoAutoHAlign(hChannel, !pbAutoHAlign);
    NSLog(@"MWUSBSetVideoAutoHAlign ret:%d", ret);
    
    bool_t pbAutoHAlign2;
    ret = MWUSBGetVideoAutoHAlign(hChannel, &pbAutoHAlign2);
    NSLog(@"MWUSBGetVideoAutoHAlign ret:%d AutoHAlign:%d", ret,pbAutoHAlign2);

    //VideoSamplingPhase
    uint8_t puSamplingPhase;
    ret = MWUSBGetVideoSamplingPhase(hChannel, &puSamplingPhase);
    NSLog(@"MWUSBGetVideoSamplingPhase ret:%d SamplingPhase:%d", ret,puSamplingPhase);
    
    uint8_t samplingPhase = 0;
    ret = MWUSBSetVideoSamplingPhase(hChannel, &samplingPhase);
    NSLog(@"MWUSBSetVideoSamplingPhase ret:%d", ret);
    
    uint8_t puSamplingPhase2;
    ret = MWUSBGetVideoSamplingPhase(hChannel, &puSamplingPhase2);
    NSLog(@"MWUSBGetVideoSamplingPhase ret:%d SamplingPhase:%d", ret,puSamplingPhase2);
    
    //VideoSamplingPhaseAutoAdjust
    bool_t pbAutoSamplingPhase;
    ret = MWUSBGetVideoSamplingPhaseAutoAdjust(hChannel, &pbAutoSamplingPhase);
    NSLog(@"MWUSBGetVideoSamplingPhaseAutoAdjust ret:%d AutoSamplingPhase:%d", ret,pbAutoSamplingPhase);
    
    bool_t autoSamplingPhase = !pbAutoSamplingPhase;;
    ret = MWUSBSetVideoSamplingPhaseAutoAdjust(hChannel, &autoSamplingPhase);
    NSLog(@"MWUSBSetVideoSamplingPhaseAutoAdjust ret:%d", ret);
    
    bool_t pbAutoSamplingPhase2;
    ret = MWUSBGetVideoSamplingPhaseAutoAdjust(hChannel, &pbAutoSamplingPhase2);
    NSLog(@"MWUSBGetVideoSamplingPhaseAutoAdjust ret:%d AutoSamplingPhase:%d", ret,pbAutoSamplingPhase2);
    
    //timing
    MWCAP_VIDEO_TIMING *timing =  (MWCAP_VIDEO_TIMING*)malloc(sizeof(MWCAP_VIDEO_TIMING));
    ret = MWUSBSetVideoTiming(hChannel, timing);
    free(timing);
    NSLog(@"MWUSBSetVideoTiming ret:%d", ret);
    
    MWCAP_VIDEO_TIMING_ARRAY paTimings;
    ret = MWUSBGetPreferredVideoTimings(hChannel, &paTimings);
    NSLog(@"MWUSBGetPreferredVideoTimings ret:%d", ret);
    
    MWCAP_VIDEO_CUSTOM_TIMING_ARRAY paCustomTimings;
    ret = MWUSBGetCustomVideoTimings(hChannel, &paCustomTimings);
    NSLog(@"MWUSBGetCustomVideoTimings ret:%d", ret);
    
    MWCAP_VIDEO_CUSTOM_TIMING_ARRAY *customTimings =  (MWCAP_VIDEO_CUSTOM_TIMING_ARRAY*)malloc(sizeof(MWCAP_VIDEO_CUSTOM_TIMING_ARRAY));
    ret = MWUSBSetCustomVideoTimings(hChannel, customTimings);
    free(customTimings);
    NSLog(@"MWUSBSetCustomVideoTimings ret:%d", ret);
    
    MWCAP_VIDEO_CUSTOM_TIMING *customTiming =  (MWCAP_VIDEO_CUSTOM_TIMING*)malloc(sizeof(MWCAP_VIDEO_CUSTOM_TIMING));
    ret = MWUSBSetCustomVideoTiming(hChannel, customTiming);
    free(customTiming);
    NSLog(@"MWUSBSetCustomVideoTiming ret:%d", ret);
    
    //CustomVideoResolutions
    MWCAP_VIDEO_CUSTOM_RESOLUTION_ARRAY paCustomResolutions;
    ret = MWUSBGetCustomVideoResolutions(hChannel,&paCustomResolutions);
    NSLog(@"MWUSBGetCustomVideoResolutions ret:%d", ret);
    
    MWCAP_VIDEO_CUSTOM_RESOLUTION_ARRAY *customResolutions =  (MWCAP_VIDEO_CUSTOM_RESOLUTION_ARRAY*)malloc(sizeof(MWCAP_VIDEO_CUSTOM_RESOLUTION_ARRAY));
    ret = MWUSBSetCustomVideoResolutions(hChannel, customResolutions);
    free(customResolutions);
    NSLog(@"MWUSBSetCustomVideoResolutions ret:%d", ret);
    
    //
    uint32_t pdwFlag;
    ret = MWUSBGetExtensionSupported(hChannel, &pdwFlag);
    NSLog(@"pdwFlag ret:%d pdwFlag:%d", ret, pdwFlag);
    
    bool_t pbScanning;
    ret = MWUSBGetInputSourceScanState(hChannel, &pbScanning);
    NSLog(@"MWUSBGetInputSourceScanState ret:%d pbScanning:%d", ret, pbScanning);
    
    //EDID mode
    MWCAP_EDID_MODE pMode;
    ret = MWUSBGetEDIDMode(hChannel, &pMode);
    NSLog(@"MWUSBGetEDIDMode ret:%d pMode:%d", ret, pMode);
    
    ret = MWUSBSetEDIDMode(hChannel, MWCAP_EDID_MODE_KEEP_LAST);
    NSLog(@"MWUSBSetEDIDMode ret:%d", ret);
    
    MWCAP_EDID_MODE pMode2;
    ret = MWUSBGetEDIDMode(hChannel, &pMode2);
    NSLog(@"MWUSBGetEDIDMode ret:%d pMode:%d", ret, pMode2);



    MWCloseChannel(hChannel);
}

#pragma mark -
void HDMIinfoFrameTest(unsigned int dwValidFlag, HCHANNEL hChannel)
{
    MW_RESULT xr;
    HDMI_INFOFRAME_PACKET packet;
    if (dwValidFlag & MWCAP_HDMI_INFOFRAME_MASK_AVI) {
        xr = MWGetHDMIInfoFramePacket(hChannel, MWCAP_HDMI_INFOFRAME_ID_AVI, &packet);
        if (xr == MW_SUCCEEDED) {
            printf("Get HDMI InfoFrame AVI OK!\n");
            
            printf("Length = %d, Buffer is ", packet.header.byLength);
            for (int i = 0; i < packet.header.byLength; i++) {
                printf("%02x ", packet.abyPayload[i]);
            }
            printf("\n\n");
        }
    }
    if (dwValidFlag & MWCAP_HDMI_INFOFRAME_MASK_AUDIO) {
        xr = MWGetHDMIInfoFramePacket(hChannel, MWCAP_HDMI_INFOFRAME_ID_AUDIO, &packet);
        if (xr == MW_SUCCEEDED) {
            printf("Get HDMI InfoFrame Audio OK!\n");
            printf("Length = %d, Buffer is ", packet.header.byLength);
            for (int i = 0; i < packet.header.byLength; i++) {
                printf("%02x ", packet.abyPayload[i]);
            }
            printf("\n\n");
        }
    }
    if (dwValidFlag & MWCAP_HDMI_INFOFRAME_MASK_SPD) {
        xr = MWGetHDMIInfoFramePacket(hChannel, MWCAP_HDMI_INFOFRAME_ID_SPD, &packet);
        if (xr == MW_SUCCEEDED) {
            printf("Get HDMI InfoFrame SPD OK!\n");
            printf("Length = %d, Buffer is ", packet.header.byLength);
            for (int i = 0; i < packet.header.byLength; i++) {
                printf("%02x ", packet.abyPayload[i]);
            }
            printf("\n\n");
        }
    }
    if (dwValidFlag & MWCAP_HDMI_INFOFRAME_MASK_MS) {
        xr = MWGetHDMIInfoFramePacket(hChannel, MWCAP_HDMI_INFOFRAME_ID_MS, &packet);
        if (xr == MW_SUCCEEDED) {
            printf("Get HDMI InfoFrame MS OK!\n");
            printf("Length = %d, Buffer is ", packet.header.byLength);
            for (int i = 0; i < packet.header.byLength; i++) {
                printf("%02x ", packet.abyPayload[i]);
            }
            printf("\n\n");
        }
    }
    if (dwValidFlag & MWCAP_HDMI_INFOFRAME_MASK_VS) {
        xr = MWGetHDMIInfoFramePacket(hChannel, MWCAP_HDMI_INFOFRAME_ID_VS, &packet);
        if (xr == MW_SUCCEEDED) {
            printf("Get HDMI InfoFrame VS OK!\n");
            printf("Length = %d, Buffer is ", packet.header.byLength);
            for (int i = 0; i < packet.header.byLength; i++) {
                printf("%02x ", packet.abyPayload[i]);
            }
            printf("\n\n");
        }
    }
    if (dwValidFlag & MWCAP_HDMI_INFOFRAME_MASK_ACP) {
        xr = MWGetHDMIInfoFramePacket(hChannel, MWCAP_HDMI_INFOFRAME_ID_ACP, &packet);
        if (xr == MW_SUCCEEDED) {
            printf("Get HDMI InfoFrame ACP OK!\n");
            printf("Length = %d, Buffer is ", packet.header.byLength);
            for (int i = 0; i < packet.header.byLength; i++) {
                printf("%02x ", packet.abyPayload[i]);
            }
            printf("\n\n");
        }
    }
    if (dwValidFlag & MWCAP_HDMI_INFOFRAME_MASK_ISRC1) {
        xr = MWGetHDMIInfoFramePacket(hChannel, MWCAP_HDMI_INFOFRAME_ID_ISRC1, &packet);
        if (xr == MW_SUCCEEDED) {
            printf("Get HDMI InfoFrame ISRC1 OK!\n");
            printf("Length = %d, Buffer is ", packet.header.byLength);
            for (int i = 0; i < packet.header.byLength; i++) {
                printf("%02x ", packet.abyPayload[i]);
            }
            printf("\n\n");
        }
    }
    if (dwValidFlag & MWCAP_HDMI_INFOFRAME_MASK_ISRC2) {
        xr = MWGetHDMIInfoFramePacket(hChannel, MWCAP_HDMI_INFOFRAME_ID_ISRC2, &packet);
        if (xr == MW_SUCCEEDED) {
            printf("Get HDMI InfoFrame ISRC2 OK!\n");
            printf("Length = %d, Buffer is ", packet.header.byLength);
            for (int i = 0; i < packet.header.byLength; i++) {
                printf("%02x ", packet.abyPayload[i]);
            }
            printf("\n\n");
        }
    }
    if (dwValidFlag & MWCAP_HDMI_INFOFRAME_MASK_GAMUT) {
        xr = MWGetHDMIInfoFramePacket(hChannel, MWCAP_HDMI_INFOFRAME_ID_GAMUT, &packet);
        if (xr == MW_SUCCEEDED) {
            printf("Get HDMI InfoFrame GAMUT OK!\n");
            printf("Length = %d, Buffer is ", packet.header.byLength);
            for (int i = 0; i < packet.header.byLength; i++) {
                printf("%02x ", packet.abyPayload[i]);
            }
            printf("\n\n");
        }
    }
    if (dwValidFlag & MWCAP_HDMI_INFOFRAME_MASK_HDR) {
        xr = MWGetHDMIInfoFramePacket(hChannel, MWCAP_HDMI_INFOFRAME_ID_HDR, &packet);
        if (xr == MW_SUCCEEDED) {
            printf("Get HDMI InfoFrame HDR OK!\n");
            printf("Length = %d, Buffer is ", packet.header.byLength);
            for (int i = 0; i < packet.header.byLength; i++) {
                printf("%02x ", packet.abyPayload[i]);
            }
            printf("\n\n");
        }
    }
}

void GetVideoInputName(DWORD dwVideoInput, char* pszName, int nSize)
{
    switch (INPUT_TYPE(dwVideoInput)) {
        case MWCAP_VIDEO_INPUT_TYPE_NONE:
            strncpy(pszName, "None",nSize);
            break;
        case MWCAP_VIDEO_INPUT_TYPE_HDMI:
            strncpy(pszName, "HDMI", nSize);
            break;
        case MWCAP_VIDEO_INPUT_TYPE_VGA:
            strncpy(pszName, "VGA", nSize);
            break;
        case MWCAP_VIDEO_INPUT_TYPE_SDI:
            strncpy(pszName, "SDI",nSize);
            break;
        case MWCAP_VIDEO_INPUT_TYPE_COMPONENT:
            strncpy(pszName, "Component", nSize);
            break;
        case MWCAP_VIDEO_INPUT_TYPE_CVBS:
            strncpy(pszName, "CVBS",nSize);
            break;
        case MWCAP_VIDEO_INPUT_TYPE_YC:
            strncpy(pszName, "YC",nSize);
            break;
    }
}

void GetAudioInputName(DWORD dwAudioInput, char* pszName, int nSize)
{
    switch (INPUT_TYPE(dwAudioInput)) {
        case MWCAP_AUDIO_INPUT_TYPE_NONE:
            strncpy(pszName, "None",nSize);
            break;
        case MWCAP_AUDIO_INPUT_TYPE_HDMI:
            strncpy(pszName, "HDMI",nSize);
            break;
        case MWCAP_AUDIO_INPUT_TYPE_SDI:
            strncpy(pszName, "SDI",nSize);
            break;
        case MWCAP_AUDIO_INPUT_TYPE_LINE_IN:
            strncpy(pszName, "Line In", nSize);
            break;
        case MWCAP_AUDIO_INPUT_TYPE_MIC_IN:
            strncpy(pszName, "Mic In",nSize);
            break;
    }
}
@end
