AHK进行网络摄像头录制2

; https://www.autohotkey.com/boards/viewtopic.php?p=309519#p309519

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

minW:= 36, minH:= 36
file := "test.mp4"
video_bitrate := 2000000
video_fps := 25
duration := 10
capture_cursor := False ; 如果设置为true,我会得到双光标
hardware_encoding := false ; 如果您有工作的图形处理器,则设置为 true
; audiodevice := "PC扬声器 (Realtek High Definition Audio)" ; 设置您的初始设备(在开始时跳过提示)
audiodevice := "扬声器 (High Definition Audio Device)"  ; 不想录音就删除此行

;audiodevice := "Microphone (Realtek High Definition Audio)"
goto record
;hardware_encoder:= "NVIDIA H.264 Encoder MFT" ; upside down + mirrored -> retreaved by MFTEnumEx(...) !!!!
;hardware_encoder:= "H.264 Encoder MFT" ; ok
;hardware_encoder:= "Encoder MFT" ; ok

;hardware_encoder:= "GeForce MX 660M" ; ok
;hardware_encoder:= "Encoder GeForce MX 660M" ; ok
;hardware_encoder:= "H.264 Encoder GeForce MX 660M" ; ok
;hardware_encoder:= "NVIDIA H.264 Encoder GeForce MX 660M" ; upside down + mirrored !!!!!

;hardware_encoder:= "nvidia" ; upside down + mirrored
;hardware_encoder:= "NVIDIA" ; upside down + mirrored
;hardware_encoder:= "XXXXXXX" ; ok
;hardware_encoder:= "XXXXXXXNVIDIA" ; upside down + mirrored
;hardware_encoder:= "" ; ok (the same as non asigned at all)


CoordMode, Mouse, Screen
CoordMode, ToolTip, Screen

 ;x1 := 100, x2 := 1000, y1 := 100, y2 := 500
if !audiodevice {
    ShowAllAudioDevicesNames := true
    Gosub GetAudioDevice
}

Loop, 6
    GroupAdd, CrossAndFrame, outline%A_Index%
    
SoundBeep, 400
SoundBeep, 800
    
Return

F2::
    ErrorLevel:= ""
    KeyWait, F2, T.5
    if ErrorLevel {
        Gosub, Esc
        x1:= y1:= x2:= y2:= ""
    }
    if (!WinExist("ahk_group CrossAndFrame") || CrossOrFrame) && !ErrorLevel
        Return
    ToolTip, Recording started!, % nx1, % ny1
    Sleep, 300
    ToolTip
    ;Gosub, Esc
record:
setbatchlines -1
IDXGIFactory := CreateDXGIFactory()
if !IDXGIFactory
{
   MsgBox, 16, Error, Create IDXGIFactory failed.
   ExitApp
}
loop
{
   IDXGIFactory_EnumAdapters(IDXGIFactory, A_Index-1, IDXGIAdapter)
   loop
   {
      hr := IDXGIAdapter_EnumOutputs(IDXGIAdapter, A_Index-1, IDXGIOutput)
      if (hr = "DXGI_ERROR_NOT_FOUND")
         break
      VarSetCapacity(DXGI_OUTPUT_DESC, 88+A_PtrSize, 0)
      IDXGIOutput_GetDesc(IDXGIOutput, &DXGI_OUTPUT_DESC)
      Width := NumGet(DXGI_OUTPUT_DESC, 72, "int")
      Height := NumGet(DXGI_OUTPUT_DESC, 76, "int")
      AttachedToDesktop := NumGet(DXGI_OUTPUT_DESC, 80, "int")
      if (AttachedToDesktop = 1)
         break 2         
   }
}
if (AttachedToDesktop != 1)
{
   MsgBox, 16, Error, No adapter attached to desktop
   ExitApp
}
D3D11CreateDevice(IDXGIAdapter, D3D_DRIVER_TYPE_UNKNOWN := 0, 0, 0, 0, 0, D3D11_SDK_VERSION := 7, d3d_device, 0, d3d_context)
IDXGIOutput1 := IDXGIOutput1_Query(IDXGIOutput)
IDXGIOutput1_DuplicateOutput(IDXGIOutput1, d3d_device, Duplication)
VarSetCapacity(DXGI_OUTDUPL_DESC, 36, 0)
IDXGIOutputDuplication_GetDesc(Duplication, &DXGI_OUTDUPL_DESC)
DesktopImageInSystemMemory := NumGet(DXGI_OUTDUPL_DESC, 32, "uint")
sleep 50   ; As I understand - need some sleep for successful connecting to IDXGIOutputDuplication interface

VarSetCapacity(D3D11_TEXTURE2D_DESC, 44, 0)
NumPut(width, D3D11_TEXTURE2D_DESC, 0, "uint")   ; Width
NumPut(height, D3D11_TEXTURE2D_DESC, 4, "uint")   ; Height
NumPut(1, D3D11_TEXTURE2D_DESC, 8, "uint")   ; MipLevels
NumPut(1, D3D11_TEXTURE2D_DESC, 12, "uint")   ; ArraySize
NumPut(DXGI_FORMAT_B8G8R8A8_UNORM := 87, D3D11_TEXTURE2D_DESC, 16, "uint")   ; Format
NumPut(1, D3D11_TEXTURE2D_DESC, 20, "uint")   ; SampleDescCount
NumPut(0, D3D11_TEXTURE2D_DESC, 24, "uint")   ; SampleDescQuality
NumPut(D3D11_USAGE_STAGING := 3, D3D11_TEXTURE2D_DESC, 28, "uint")   ; Usage
NumPut(0, D3D11_TEXTURE2D_DESC, 32, "uint")   ; BindFlags
NumPut(D3D11_CPU_ACCESS_READ := 0x20000 | D3D11_CPU_ACCESS_WRITE := 0x10000, D3D11_TEXTURE2D_DESC, 36, "uint")   ; CPUAccessFlags
NumPut(0, D3D11_TEXTURE2D_DESC, 40, "uint")   ; MiscFlags
ID3D11Device_CreateTexture2D(d3d_device, &D3D11_TEXTURE2D_DESC, 0, staging_tex)
if (capture_cursor = true)
{
   VarSetCapacity(D3D11_TEXTURE2D_DESC, 44, 0)
   NumPut(width, D3D11_TEXTURE2D_DESC, 0, "uint")   ; Width
   NumPut(height, D3D11_TEXTURE2D_DESC, 4, "uint")   ; Height
   NumPut(1, D3D11_TEXTURE2D_DESC, 8, "uint")   ; MipLevels
   NumPut(1, D3D11_TEXTURE2D_DESC, 12, "uint")   ; ArraySize
   NumPut(DXGI_FORMAT_B8G8R8A8_UNORM := 87, D3D11_TEXTURE2D_DESC, 16, "uint")   ; Format
   NumPut(1, D3D11_TEXTURE2D_DESC, 20, "uint")   ; SampleDescCount
   NumPut(0, D3D11_TEXTURE2D_DESC, 24, "uint")   ; SampleDescQuality
   NumPut(D3D11_USAGE_DEFAULT := 0, D3D11_TEXTURE2D_DESC, 28, "uint")   ; Usage
   NumPut(D3D11_BIND_RENDER_TARGET := 0x20, D3D11_TEXTURE2D_DESC, 32, "uint")   ; BindFlags
   NumPut(0, D3D11_TEXTURE2D_DESC, 36, "uint")   ; CPUAccessFlags
   NumPut(D3D11_RESOURCE_MISC_GDI_COMPATIBLE := 0x200, D3D11_TEXTURE2D_DESC, 40, "uint")   ; MiscFlags
   ID3D11Device_CreateTexture2D(d3d_device, &D3D11_TEXTURE2D_DESC, 0, gdi_tex)
}

LOAD_DLL_Mf_Mfplat_Mfreadwrite()
MFStartup(version := 2, MFSTARTUP_FULL := 0)
VarSetCapacity(MFT_REGISTER_TYPE_INFO, 32, 0)
DllCall("RtlMoveMemory", "ptr", &MFT_REGISTER_TYPE_INFO, "ptr", MF_GUID(GUID, "MFMediaType_Video"), "ptr", 16)
DllCall("RtlMoveMemory", "ptr", &MFT_REGISTER_TYPE_INFO + 16, "ptr", MF_GUID(GUID, "MFVideoFormat_H264"), "ptr", 16)
if hardware_encoding ; added one line
    hardware_encoder := MFTEnumEx(MF_GUID(GUID, "MFT_CATEGORY_VIDEO_ENCODER"), MFT_ENUM_FLAG_HARDWARE := 0x04|MFT_ENUM_FLAG_SORTANDFILTER := 0x40, 0, &MFT_REGISTER_TYPE_INFO)
;msgbox % "hardware-encoder - " hardware_encoder ; RRR commented one line
if (x1 != "")
{
   checkCoordinates(x1, x2, y1, y2, hardware_encoder)
   width := x2-x1
   height := y2-y1
   VarSetCapacity(D3D11_BOX, 24, 0)
   NumPut(x1, D3D11_BOX, 0, "uint")   ; left
   NumPut(y1, D3D11_BOX, 4, "uint")   ; top
   NumPut(0, D3D11_BOX, 8, "uint")   ; front
   NumPut(x2, D3D11_BOX, 12, "uint")   ; right
   NumPut(y2, D3D11_BOX, 16, "uint")   ; bottom
   NumPut(1, D3D11_BOX, 20, "uint")   ; back
}
if (hardware_encoder != "")
{
   MFCreateAttributes(pMFAttributes, 4)
   IMFAttributes_SetUINT32(pMFAttributes, MF_GUID(GUID, "MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS"), true)
}
else
   MFCreateAttributes(pMFAttributes, 3)
IMFAttributes_SetGUID(pMFAttributes, MF_GUID(GUID, "MF_TRANSCODE_CONTAINERTYPE"), MF_GUID(GUID1, "MFTranscodeContainerType_MPEG4"))
IMFAttributes_SetUINT32(pMFAttributes, MF_GUID(GUID, "MF_SINK_WRITER_DISABLE_THROTTLING"), true)
IMFAttributes_SetUINT32(pMFAttributes, MF_GUID(GUID, "MF_LOW_LATENCY"), true)
MFCreateSinkWriterFromURL(file, 0, pMFAttributes, pSinkWriter)
loop 2   ; 1 - input, 2 - output
{
   MFCreateMediaType(pMediaType%A_Index%)
   IMFAttributes_SetGUID(pMediaType%A_Index%, MF_GUID(GUID, "MF_MT_MAJOR_TYPE"), MF_GUID(GUID1, "MFMediaType_Video"))
   if (A_Index = 1)
   {
      if InStr(hardware_encoder, "NVIDIA")
         IMFAttributes_SetGUID(pMediaType%A_Index%, MF_GUID(GUID, "MF_MT_SUBTYPE"), MF_GUID(GUID1, "MFVideoFormat_ARGB32"))
      else
         IMFAttributes_SetGUID(pMediaType%A_Index%, MF_GUID(GUID, "MF_MT_SUBTYPE"), MF_GUID(GUID1, "MFVideoFormat_RGB32"))
   }
   else
   {
      IMFAttributes_SetGUID(pMediaType%A_Index%, MF_GUID(GUID, "MF_MT_SUBTYPE"), MF_GUID(GUID1, "MFVideoFormat_H264"))
      IMFAttributes_SetUINT32(pMediaType%A_Index%, MF_GUID(GUID, "MF_MT_AVG_BITRATE"), video_bitrate)
   }
   IMFAttributes_SetUINT32(pMediaType%A_Index%, MF_GUID(GUID, "MF_MT_INTERLACE_MODE"), MFVideoInterlace_Progressive := 2)
   IMFAttributes_SetUINT64(pMediaType%A_Index%, MF_GUID(GUID, "MF_MT_FRAME_SIZE"), (width<<32)|height)
   IMFAttributes_SetUINT64(pMediaType%A_Index%, MF_GUID(GUID, "MF_MT_FRAME_RATE"), (video_fps<<32)|1)
   IMFAttributes_SetUINT64(pMediaType%A_Index%, MF_GUID(GUID, "MF_MT_PIXEL_ASPECT_RATIO"), (1<<32)|1)
}
IMFSinkWriter_AddStream(pSinkWriter, pMediaType2, videoStreamIndex)
IMFSinkWriter_SetInputMediaType(pSinkWriter, videoStreamIndex, pMediaType1, 0)
Release(pMediaType1)
Release(pMediaType2)
Release(pMFAttributes)
pMediaType1 := pMediaType2 := pMFAttributes := ""

GetAudioDevice: ; RRR added two lines
devicenames:= ""
if audiodevice or ShowAllAudioDevicesNames
{
   MFCreateAttributes(pMFAttributes, 1)
   IMFAttributes_SetGUID(pMFAttributes, MF_GUID(GUID, "MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE"), MF_GUID(GUID1, "MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_GUID"))
   MFEnumDeviceSources(pMFAttributes, pppSourceActivate, pcSourceActivate)
   Loop % pcSourceActivate
   {
      IMFActivate := NumGet(pppSourceActivate + (A_Index - 1)*A_PtrSize)
      devicename := IMFActivate_GetAllocatedString(IMFActivate, MF_GUID(GUID, "MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME"))
      if ShowAllAudioDevicesNames
         devicenames .= devicename "`n"
      if (devicename = audiodevice)
         IMFActivate_ActivateObject(IMFActivate, IMFMediaSource := "{279a808d-aec7-40c8-9c6b-a6b492c78a66}", MediaSource)
      Release(IMFActivate)
      IMFActivate := ""
   }
   DllCall("ole32\CoTaskMemFree", "ptr", pppSourceActivate)
   if ShowAllAudioDevicesNames
   {
      ListDevices:= StrReplace(devicenames, "`n", "`n", Count)
      Gui, Margin, 2, 2
      Gui, +Delimiter`n -Caption +AlwaysOnTop
      Gui, Add, ListBox, r%Count% w300 vSlectedLine gSelectAudioDevice Choose1, % ListDevices
      Gui, show,, AudioDevices
      While (!audiodevice || Event == "Normal") && !EventEsc
        Sleep, 100
      Gui, Destroy
      ShowAllAudioDevicesNames := ""
      Return
      ;msgbox % clipboard := devicenames ; RRR commented two lines and added code above
      ;ExitApp
   }
   if (MediaSource = "")
   {
      msgbox 找不到音频设备 - "%audiodevice%"`n`n请设置正确后再试
      ExitApp
   }
   MFCreateSourceReaderFromMediaSource(MediaSource, pMFAttributes, SourceReader)
   Release(pMFAttributes)
   pMFAttributes := ""
   loop 2   ; 1 - input, 2 - output
   {
      MFCreateMediaType(pMediaType%A_Index%)
      IMFAttributes_SetGUID(pMediaType%A_Index%, MF_GUID(GUID, "MF_MT_MAJOR_TYPE"), MF_GUID(GUID1, "MFMediaType_Audio"))
      if (A_Index = 1)
         IMFAttributes_SetGUID(pMediaType%A_Index%, MF_GUID(GUID, "MF_MT_SUBTYPE"), MF_GUID(GUID1, "MFAudioFormat_PCM"))
      else
      {
         IMFAttributes_SetGUID(pMediaType%A_Index%, MF_GUID(GUID, "MF_MT_SUBTYPE"), MF_GUID(GUID1, "MFAudioFormat_AAC"))
         IMFAttributes_SetUINT32(pMediaType%A_Index%, MF_GUID(GUID, "MF_MT_AUDIO_AVG_BYTES_PER_SECOND"), 20000)
      }
      IMFAttributes_SetUINT32(pMediaType%A_Index%, MF_GUID(GUID, "MF_MT_AUDIO_BITS_PER_SAMPLE"), 16)
      IMFAttributes_SetUINT32(pMediaType%A_Index%, MF_GUID(GUID, "MF_MT_AUDIO_SAMPLES_PER_SECOND"), 44100)
      IMFAttributes_SetUINT32(pMediaType%A_Index%, MF_GUID(GUID, "MF_MT_AUDIO_NUM_CHANNELS"), 2)
   }
   IMFSinkWriter_AddStream(pSinkWriter, pMediaType2, audioStreamIndex)
   IMFSinkWriter_SetInputMediaType(pSinkWriter, audioStreamIndex, pMediaType1, 0)

   /*
   ; functions for getting source values
   IMFSourceReader_GetNativeMediaType(SourceReader, MF_SOURCE_READER_FIRST_AUDIO_STREAM := 0xFFFFFFFD, 0, ppMediaType)
   IMFMediaType_GetGUID(ppMediaType, MF_GUID(GUID, "MF_MT_SUBTYPE"), pguidValue)
   msgbox % numget(pguidValue, 0, "int")
   IMFMediaType_GetUINT32(ppMediaType, MF_GUID(GUID, "MF_MT_AUDIO_BITS_PER_SAMPLE"), punValue)
   msgbox % punValue
   Release(ppMediaType)
   ppMediaType := ""
   */

   IMFSourceReader_SetCurrentMediaType(SourceReader, MF_SOURCE_READER_FIRST_AUDIO_STREAM := 0xFFFFFFFD, 0, pMediaType1)
   Release(pMediaType1)
   Release(pMediaType2)
   pMediaType1 := pMediaType2 := ""
}
IMFSinkWriter_BeginWriting(pSinkWriter)

video_frame_duration := 10000000/video_fps
video_frame_count := duration*video_fps
cbWidth := 4 * width
cbBuffer := cbWidth * height
rtStart := 0
fps := 1000/video_fps

loop % video_frame_count
{
   DllCall("Winmm\timeBeginPeriod", "UInt", 3)
   if (A_Index = 1)
      timeElapsed := A_TickCount
   else
   {
      loop
      {
         if (A_TickCount - timeElapsed >= fps)
         {
            timeElapsed+=fps
            break
         }
         DllCall("Sleep", "UInt", 1)
      }
   }
   DllCall("Winmm\timeEndPeriod", "UInt", 3)

   VarSetCapacity(DXGI_OUTDUPL_FRAME_INFO, 48, 0)
   AcquireNextFrame := IDXGIOutputDuplication_AcquireNextFrame(Duplication, 0, &DXGI_OUTDUPL_FRAME_INFO, desktop_resource)
   if (AcquireNextFrame != "DXGI_ERROR_WAIT_TIMEOUT")
   {
      if (A_Index != 1)
      {
         Release(pSample)
         Release(pBuffer)
         pSample := pBuffer := ""
      }
      tex := ID3D11Texture2D_Query(desktop_resource)
      if (capture_cursor = true)
      {
         VarSetCapacity(CURSORINFO, cbSize := 16 + A_PtrSize, 0)
         NumPut(cbSize, CURSORINFO, 0, "uint")
      }
      if (capture_cursor = true) and DllCall("GetCursorInfo", "ptr", &CURSORINFO) and (NumGet(CURSORINFO, 4, "uint") = 1)   ; CURSOR_SHOWING
      {
         hCursor := NumGet(CURSORINFO, 8)
         xCursor := NumGet(CURSORINFO, 8 + A_PtrSize, "int")
         yCursor := NumGet(CURSORINFO, 12 + A_PtrSize, "int")
         ID3D11DeviceContext_CopyResource(d3d_context, gdi_tex, tex)
         gdi_Surface := IDXGISurface1_Query(gdi_tex)
         IDXGISurface1_GetDC(gdi_Surface, 0, hdc)
         DllCall("DrawIconEx", "ptr", hdc, "int", xCursor, "int", yCursor, "ptr", hCursor, "int", 0, "int", 0, "uint", 0, "ptr", 0, "uint", DI_NORMAL := 0x0003 | DI_DEFAULTSIZE := 0x0008)
         IDXGISurface1_ReleaseDC(gdi_Surface, 0)
         if (x1 = "")
            ID3D11DeviceContext_CopyResource(d3d_context, staging_tex, gdi_tex)
         else
            ID3D11DeviceContext_CopySubresourceRegion(d3d_context, staging_tex, 0, 0, 0, 0, gdi_tex, 0, &D3D11_BOX)   ; set region
         ObjRelease(gdi_Surface)
         gdi_Surface := ""
      }
      else
      {
         if (x1 = "")
            ID3D11DeviceContext_CopyResource(d3d_context, staging_tex, tex)
         else
            ID3D11DeviceContext_CopySubresourceRegion(d3d_context, staging_tex, 0, 0, 0, 0, tex, 0, &D3D11_BOX)   ; set region
      }
      VarSetCapacity(D3D11_MAPPED_SUBRESOURCE, 8+A_PtrSize, 0)
      ID3D11DeviceContext_Map(d3d_context, staging_tex, 0, D3D11_MAP_READ := 1, 0, &D3D11_MAPPED_SUBRESOURCE)
      pBits := NumGet(D3D11_MAPPED_SUBRESOURCE, 0, "ptr")
      pitch := NumGet(D3D11_MAPPED_SUBRESOURCE, A_PtrSize, "uint")

      MFCreateMemoryBuffer(cbBuffer, pBuffer)
      IMFMediaBuffer_Lock(pBuffer, pData, 0, 0)
      if InStr(hardware_encoder, "NVIDIA")
         MFCopyImage(pData, cbWidth, pBits, pitch, cbWidth, height)
      else
         MFCopyImage(pData, cbWidth, pBits+(height-1)*pitch, pitch*-1, cbWidth, height)
      IMFMediaBuffer_Unlock(pBuffer)
      IMFMediaBuffer_SetCurrentLength(pBuffer, cbBuffer)
      MFCreateSample(pSample)
      IMFSample_AddBuffer(pSample, pBuffer)
   }
   IMFSample_SetSampleTime(pSample, rtStart)
   IMFSample_SetSampleDuration(pSample, video_frame_duration)
   IMFSinkWriter_WriteSample(pSinkWriter, streamIndex, pSample)
   if (AcquireNextFrame != "DXGI_ERROR_WAIT_TIMEOUT")
   {
      ID3D11DeviceContext_Unmap(d3d_context, staging_tex, 0)
      ObjRelease(tex)
      Release(desktop_resource)
      tex := desktop_resource := ""
      IDXGIOutputDuplication_ReleaseFrame(duplication)
   }
   if audiodevice
   {
      IMFSourceReader_ReadSample(SourceReader, MF_SOURCE_READER_FIRST_AUDIO_STREAM := 0xFFFFFFFD, 0, ActualStreamIndex, StreamFlags, Timestamp, pSampleAudio)
      if (pSampleAudio != 0)
      {
         if (gap = 1)
         {
            IMFAttributes_SetUINT32(pSampleAudio, MF_GUID(GUID, "MFSampleExtension_Discontinuity"), true)
            gap := ""
         }
         IMFSample_SetSampleTime(pSampleAudio, rtStart)
         IMFSample_SetSampleDuration(pSampleAudio, video_frame_duration)
         IMFSinkWriter_WriteSample(pSinkWriter, audioStreamIndex, pSampleAudio)
         Release(pSampleAudio)
         pSampleAudio := ""
      }
      else if (StreamFlags & MF_SOURCE_READERF_STREAMTICK := 256)
      {
         IMFSinkWriter_SendStreamTick(pSinkWriter, audioStreamIndex, rtStart)
         gap := 1
      }
   }
   rtStart += video_frame_duration
}
IMFSinkWriter_Finalize(pSinkWriter)
if audiodevice
{
   Release(SourceReader)
   Release(MediaSource)
   SourceReader := MediaSource := ""
}
Release(pSample)
Release(pBuffer)
Release(pSinkWriter)
Release(staging_tex)
Release(d3d_device)
Release(d3d_context)
Release(duplication)
Release(IDXGIAdapter)
Release(IDXGIOutput)
ObjRelease(IDXGIOutput1)
Release(IDXGIFactory)
if (capture_cursor = true)
{
   Release(gdi_tex)
   gdi_tex := ""
}
pSample := pBuffer := pSinkWriter := staging_tex := d3d_device := d3d_context := duplication := IDXGIAdapter := IDXGIOutput := IDXGIOutput1 := IDXGIFactory := ""
MFShutdown()
;msgbox,,, done, .75
;Gosub, Esc
run % file
sleep, 10000
Reload
;ExitApp
Return



CreateDXGIFactory()
{
   if !DllCall("GetModuleHandle","str","DXGI")
      DllCall("LoadLibrary","str","DXGI")
   if !DllCall("GetModuleHandle","str","D3D11")
      DllCall("LoadLibrary","str","D3D11")
   GUID(riid, "{7b7166ec-21c7-44ae-b21a-c9ae321ae369}")
   hr := DllCall("DXGI\CreateDXGIFactory1", "ptr", &riid, "ptr*", ppFactory)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
   return ppFactory
}

IDXGIFactory_EnumAdapters(this, Adapter, ByRef ppAdapter)
{
   hr := DllCall(NumGet(NumGet(this+0)+7*A_PtrSize), "ptr", this, "uint", Adapter, "ptr*", ppAdapter)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IDXGIAdapter_EnumOutputs(this, Output, ByRef ppOutput)
{
   hr := DllCall(NumGet(NumGet(this+0)+7*A_PtrSize), "ptr", this, "uint", Output, "ptr*", ppOutput)
   if hr or ErrorLevel
   {
      if (hr&=0xFFFFFFFF) = 0x887A0002   ; DXGI_ERROR_NOT_FOUND
         return "DXGI_ERROR_NOT_FOUND"
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
   }
}

IDXGIAdapter_GetDesc(this, pDesc)
{
   hr := DllCall(NumGet(NumGet(this+0)+8*A_PtrSize), "ptr", this, "ptr", pDesc)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IDXGIOutput_GetDesc(this, pDesc)
{
   hr := DllCall(NumGet(NumGet(this+0)+7*A_PtrSize), "ptr", this, "ptr", pDesc)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IDXGIOutputDuplication_GetDesc(this, pDesc)
{
   DllCall(NumGet(NumGet(this+0)+7*A_PtrSize), "ptr", this, "ptr", pDesc)
   if ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IDXGIOutputDuplication_AcquireNextFrame(this, TimeoutInMilliseconds, pFrameInfo, ByRef ppDesktopResource)
{
   hr := DllCall(NumGet(NumGet(this+0)+8*A_PtrSize), "ptr", this, "uint", TimeoutInMilliseconds, "ptr", pFrameInfo, "ptr*", ppDesktopResource)
   if hr or ErrorLevel
   {
      if (hr&=0xFFFFFFFF) = 0x887A0027   ; DXGI_ERROR_WAIT_TIMEOUT
         return "DXGI_ERROR_WAIT_TIMEOUT"
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
   }
}

D3D11CreateDevice(pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, SDKVersion, ByRef ppDevice, ByRef pFeatureLevel, ByRef ppImmediateContext)
{
   hr := DllCall("D3D11\D3D11CreateDevice", "ptr", pAdapter, "int", DriverType, "ptr", Software, "uint", Flags, "ptr", pFeatureLevels, "uint", FeatureLevels, "uint", SDKVersion, "ptr*", ppDevice, "ptr*", pFeatureLevel, "ptr*", ppImmediateContext)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

ID3D11Device_CreateTexture2D(this, pDesc, pInitialData, ByRef ppTexture2D)
{
   hr := DllCall(NumGet(NumGet(this+0)+5*A_PtrSize), "ptr", this, "ptr", pDesc, "ptr", pInitialData, "ptr*", ppTexture2D)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IDXGIOutputDuplication_MapDesktopSurface(this, pLockedRect)
{
   hr := DllCall(NumGet(NumGet(this+0)+12*A_PtrSize), "ptr", this, "ptr", pLockedRect)
   if hr or ErrorLevel
   {
      if (hr&=0xFFFFFFFF) = 0x887A0004   ; DXGI_ERROR_UNSUPPORTED
         return "DXGI_ERROR_UNSUPPORTED"
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
   }
}

IDXGIOutputDuplication_UnMapDesktopSurface(this)
{
   hr := DllCall(NumGet(NumGet(this+0)+13*A_PtrSize), "ptr", this)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IDXGIOutputDuplication_ReleaseFrame(this)
{
   hr := DllCall(NumGet(NumGet(this+0)+14*A_PtrSize), "ptr", this)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IDXGIOutput1_DuplicateOutput(this, pDevice, ByRef ppOutputDuplication)
{
   hr := DllCall(NumGet(NumGet(this+0)+22*A_PtrSize), "ptr", this, "ptr", pDevice, "ptr*", ppOutputDuplication)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}


IDXGISurface1_GetDC(this, Discard, ByRef phdc)
{
   hr := DllCall(NumGet(NumGet(this+0)+11*A_PtrSize), "ptr", this, "int", Discard, "ptr*", phdc)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IDXGISurface1_ReleaseDC(this, pDirtyRect)
{
   hr := DllCall(NumGet(NumGet(this+0)+12*A_PtrSize), "ptr", this, "ptr", pDirtyRect)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IDXGIOutput1_Query(IDXGIOutput)
{ 
   hr := ComObjQuery(IDXGIOutput, "{00cddea8-939b-4b83-a340-a685226666cc}")
   if !hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
   return hr
}

ID3D11Texture2D_Query(desktop_resource)
{ 
   hr := ComObjQuery(desktop_resource, "{6f15aaf2-d208-4e89-9ab4-489535d34f9c}")
   if !hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
   return hr
}

IDXGISurface1_Query(Texture2D)
{ 
   hr := ComObjQuery(Texture2D, "{4AE63092-6327-4c1b-80AE-BFE12EA32B86}")
   if !hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
   return hr
}

ID3D11DeviceContext_CopyResource(this, pDstResource, pSrcResource)
{
   hr := DllCall(NumGet(NumGet(this+0)+47*A_PtrSize), "ptr", this, "ptr", pDstResource, "ptr", pSrcResource)
   if ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

ID3D11DeviceContext_CopySubresourceRegion(this, pDstResource, DstSubresource, DstX, DstY, DstZ, pSrcResource, SrcSubresource, pSrcBox)
{
   hr := DllCall(NumGet(NumGet(this+0)+46*A_PtrSize), "ptr", this, "ptr", pDstResource, "uint", DstSubresource, "uint", DstX, "uint", DstY, "uint", DstZ, "ptr", pSrcResource, "uint", SrcSubresource, "ptr", pSrcBox)
   if ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

ID3D11DeviceContext_Map(this, pResource, Subresource, MapType, MapFlags, pMappedResource)
{
   hr := DllCall(NumGet(NumGet(this+0)+14*A_PtrSize), "ptr", this, "ptr", pResource, "uint", Subresource, "uint", MapType, "uint", MapFlags, "ptr", pMappedResource)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

ID3D11DeviceContext_Unmap(this, pResource, Subresource)
{
   hr := DllCall(NumGet(NumGet(this+0)+15*A_PtrSize), "ptr", this, "ptr", pResource, "uint", Subresource)
   if ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}


LOAD_DLL_Mf_Mfplat_Mfreadwrite()
{
   if !DllCall("GetModuleHandle","str","Mf")
      DllCall("LoadLibrary","Str", "Mf.dll", "ptr")
   if !DllCall("GetModuleHandle","str","Mfplat")
      DllCall("LoadLibrary","Str", "Mfplat.dll", "ptr")
   if !DllCall("GetModuleHandle","str","Mfreadwrite")
      DllCall("LoadLibrary","Str", "Mfreadwrite.dll", "ptr")
}

MFStartup(version, dwFlags)
{
   hr := DllCall("Mfplat.dll\MFStartup", "uint", version, "uint", dwFlags)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

MFShutdown()
{
   hr := DllCall("Mfplat.dll\MFShutdown")
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

MFTEnumEx(guidCategory, Flags, pInputType, pOutputType)
{
   if (A_PtrSize = 8)
      hr := DllCall("Mfplat\MFTEnumEx", "ptr", guidCategory, "uint", Flags, "ptr", pInputType, "ptr", pOutputType, "ptr*", pppMFTActivate, "uint*", pnumMFTActivate)
   else
      hr := DllCall("Mfplat\MFTEnumEx", "uint64", NumGet(guidCategory+0, 0, "uint64"), "uint64", NumGet(guidCategory+0, 8, "uint64"), "uint", Flags, "ptr", pInputType, "ptr", pOutputType, "ptr*", pppMFTActivate, "uint*", pnumMFTActivate)
   loop % pnumMFTActivate
   {
      IMFActivate := NumGet(pppMFTActivate + (A_Index - 1)*A_PtrSize)
      if (A_Index = 1)
         hardware_encoder := IMFActivate_GetAllocatedString(IMFActivate, MF_GUID(GUID, "MFT_FRIENDLY_NAME_Attribute"))
      Release(IMFActivate)
   }
   DllCall("ole32\CoTaskMemFree", "ptr", pppMFTActivate)
   return hardware_encoder
}

MFCreateSinkWriterFromURL(pwszOutputURL, pByteStream, pAttributes, ByRef ppSinkWriter)
{
   hr := DllCall("Mfreadwrite.dll\MFCreateSinkWriterFromURL", "str", pwszOutputURL, "ptr", pByteStream, "ptr", pAttributes, "ptr*", ppSinkWriter)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

MFCreateSourceReaderFromMediaSource(pMediaSource, pAttributes, ByRef ppSourceReader)
{
   hr := DllCall("Mfreadwrite.dll\MFCreateSourceReaderFromMediaSource", "ptr", pMediaSource, "ptr", pAttributes, "ptr*", ppSourceReader)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

MFCreateMediaType(ByRef ppMFType)
{
   hr := DllCall("Mfplat.dll\MFCreateMediaType", "ptr*", ppMFType)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

MFCreateAttributes(ByRef ppMFAttributes, cInitialSize)
{
   hr := DllCall("Mfplat.dll\MFCreateAttributes", "ptr*", ppMFAttributes, "uint", cInitialSize)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

MFCreateSample(ByRef ppIMFSample)
{
   hr := DllCall("Mfplat.dll\MFCreateSample", "ptr*", ppIMFSample)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

MFCreateMemoryBuffer(cbMaxLength, ByRef ppBuffer)
{
   hr := DllCall("Mfplat.dll\MFCreateMemoryBuffer", "uint", cbMaxLength, "ptr*", ppBuffer)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

MFCopyImage(pDest, lDestStride, pSrc, lSrcStride, dwWidthInBytes, dwLines)
{
   hr := DllCall("Mfplat.dll\MFCopyImage", "ptr", pDest, "int", lDestStride, "ptr", pSrc, "int", lSrcStride, "uint", dwWidthInBytes, "uint", dwLines)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

MFEnumDeviceSources(pAttributes, ByRef pppSourceActivate, ByRef pcSourceActivate)
{
   hr := DllCall("Mf.dll\MFEnumDeviceSources", "ptr", pAttributes, "ptr*", pppSourceActivate, "uint*", pcSourceActivate)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IMFSourceReader_SetCurrentMediaType(this, dwStreamIndex, pdwReserved, pMediaType)
{
   hr := DllCall(NumGet(NumGet(this+0)+7*A_PtrSize), "ptr", this, "uint", dwStreamIndex, "uint", pdwReserved, "ptr", pMediaType)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IMFSourceReader_GetNativeMediaType(this, dwStreamIndex, dwMediaTypeIndex, ByRef ppMediaType)
{
   hr := DllCall(NumGet(NumGet(this+0)+5*A_PtrSize), "ptr", this, "uint", dwStreamIndex, "uint", dwMediaTypeIndex, "ptr*", ppMediaType)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IMFSourceReader_ReadSample(this, dwStreamIndex, dwControlFlags, ByRef pdwActualStreamIndex, ByRef pdwStreamFlags, ByRef pllTimestamp, ByRef ppSample)
{
   hr := DllCall(NumGet(NumGet(this+0)+9*A_PtrSize), "ptr", this, "uint", dwStreamIndex, "uint", dwControlFlags, "uint*", pdwActualStreamIndex, "uint*", pdwStreamFlags, "int64*", pllTimestamp, "ptr*", ppSample)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IMFMediaType_GetGUID(this, guidKey, ByRef pguidValue)
{
   VarSetCapacity(pguidValue, 16, 0)
   hr := DllCall(NumGet(NumGet(this+0)+10*A_PtrSize), "ptr", this, "ptr", guidKey, "ptr", &pguidValue)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
   return &pguidValue
}

IMFMediaType_GetUINT32(this, guidKey, ByRef punValue)
{
   hr := DllCall(NumGet(NumGet(this+0)+7*A_PtrSize), "ptr", this, "ptr", guidKey, "uint*", punValue)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IMFAttributes_SetUINT32(this, guidKey, unValue)
{
   hr := DllCall(NumGet(NumGet(this+0)+21*A_PtrSize), "ptr", this, "ptr", guidKey, "uint", unValue)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IMFAttributes_SetUINT64(this, guidKey, unValue)
{
   hr := DllCall(NumGet(NumGet(this+0)+22*A_PtrSize), "ptr", this, "ptr", guidKey, "uint64", unValue)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IMFAttributes_SetGUID(this, guidKey, guidValue)
{
   hr := DllCall(NumGet(NumGet(this+0)+24*A_PtrSize), "ptr", this, "ptr", guidKey, "ptr", guidValue)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IMFActivate_GetAllocatedString(this, guidKey)
{
   hr := DllCall(NumGet(NumGet(this+0)+13*A_PtrSize), "ptr", this, "ptr", guidKey, "ptr*", ppwszValue, "uint*", pcchLength)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
   AllocatedString := StrGet(ppwszValue, pcchLength, "UTF-16")
   DllCall("ole32\CoTaskMemFree", "ptr", ppwszValue)
   return AllocatedString
}

IMFActivate_ActivateObject(this, riid, ByRef ppv)
{
   GUID(riid, riid)
   hr := DllCall(NumGet(NumGet(this+0)+33*A_PtrSize), "ptr", this, "ptr", &riid, "ptr*", ppv)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IMFSinkWriter_SendStreamTick(this, dwStreamIndex, llTimestamp)
{
   hr := DllCall(NumGet(NumGet(this+0)+7*A_PtrSize), "ptr", this, "uint", dwStreamIndex, "int64", llTimestamp)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IMFSinkWriter_AddStream(this, pMediaTypeOut, ByRef pdwStreamIndex)
{
   hr := DllCall(NumGet(NumGet(this+0)+3*A_PtrSize), "ptr", this, "ptr", pMediaTypeOut, "ptr*", pdwStreamIndex)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IMFSinkWriter_SetInputMediaType(this, dwStreamIndex, pInputMediaType, pEncodingParameters)
{
   hr := DllCall(NumGet(NumGet(this+0)+4*A_PtrSize), "ptr", this, "uint", dwStreamIndex, "ptr", pInputMediaType, "ptr", pEncodingParameters)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IMFSinkWriter_BeginWriting(this)
{
   hr := DllCall(NumGet(NumGet(this+0)+5*A_PtrSize), "ptr", this)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IMFSinkWriter_WriteSample(this, dwStreamIndex, pSample)
{
   hr := DllCall(NumGet(NumGet(this+0)+6*A_PtrSize), "ptr", this, "uint", dwStreamIndex, "ptr", pSample)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IMFSinkWriter_Finalize(this)
{
   hr := DllCall(NumGet(NumGet(this+0)+11*A_PtrSize), "ptr", this)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IMFMediaBuffer_Lock(this, ByRef ppbBuffer, ByRef pcbMaxLength, ByRef pcbCurrentLength)
{
   hr := DllCall(NumGet(NumGet(this+0)+3*A_PtrSize), "ptr", this, "ptr*", ppbBuffer, "uint*", pcbMaxLength, "uint*", pcbCurrentLength)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IMFMediaBuffer_Unlock(this)
{
   hr := DllCall(NumGet(NumGet(this+0)+4*A_PtrSize), "ptr", this)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IMFMediaBuffer_SetCurrentLength(this, cbCurrentLength)
{
   hr := DllCall(NumGet(NumGet(this+0)+6*A_PtrSize), "ptr", this, "uint", cbCurrentLength)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IMFSample_AddBuffer(this, pBuffer)
{
   hr := DllCall(NumGet(NumGet(this+0)+42*A_PtrSize), "ptr", this, "ptr", pBuffer)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IMFSample_SetSampleTime(this, hnsSampleTime)
{
   hr := DllCall(NumGet(NumGet(this+0)+36*A_PtrSize), "ptr", this, "int64", hnsSampleTime)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IMFSample_GetSampleDuration(this, ByRef phnsSampleDuration)
{
   hr := DllCall(NumGet(NumGet(this+0)+37*A_PtrSize), "ptr", this, "int64*", phnsSampleDuration)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IMFSample_SetSampleDuration(this, hnsSampleDuration)
{
   hr := DllCall(NumGet(NumGet(this+0)+38*A_PtrSize), "ptr", this, "int64", hnsSampleDuration)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

MF_GUID(ByRef GUID, name)
{
   static init:=1, _:={}
   if init
   {
      init:=0
      _.MF_MT_MAJOR_TYPE := [0x48eba18e, 0xf8c9, 0x4687, 0xbf, 0x11, 0x0a, 0x74, 0xc9, 0xf9, 0x6a, 0x8f]
      _.MF_MT_SUBTYPE := [0xf7e34c9a, 0x42e8, 0x4714, 0xb7, 0x4b, 0xcb, 0x29, 0xd7, 0x2c, 0x35, 0xe5]
      _.MF_MT_AVG_BITRATE := [0x20332624, 0xfb0d, 0x4d9e, 0xbd, 0x0d, 0xcb, 0xf6, 0x78, 0x6c, 0x10, 0x2e]
      _.MF_MT_INTERLACE_MODE := [0xe2724bb8, 0xe676, 0x4806, 0xb4, 0xb2, 0xa8, 0xd6, 0xef, 0xb4, 0x4c, 0xcd]
      _.MF_MT_FRAME_SIZE := [0x1652c33d, 0xd6b2, 0x4012, 0xb8, 0x34, 0x72, 0x03, 0x08, 0x49, 0xa3, 0x7d]
      _.MF_MT_FRAME_RATE := [0xc459a2e8, 0x3d2c, 0x4e44, 0xb1, 0x32, 0xfe, 0xe5, 0x15, 0x6c, 0x7b, 0xb0]
      _.MF_MT_PIXEL_ASPECT_RATIO := [0xc6376a1e, 0x8d0a, 0x4027, 0xbe, 0x45, 0x6d, 0x9a, 0x0a, 0xd3, 0x9b, 0xb6]
      _.MF_MT_AUDIO_AVG_BYTES_PER_SECOND := [0x1aab75c8, 0xcfef, 0x451c, 0xab, 0x95, 0xac, 0x03, 0x4b, 0x8e, 0x17, 0x31]
      _.MF_MT_AUDIO_BLOCK_ALIGNMENT := [0x322de230, 0x9eeb, 0x43bd, 0xab, 0x7a, 0xff, 0x41, 0x22, 0x51, 0x54, 0x1d]
      _.MF_MT_AUDIO_SAMPLES_PER_SECOND := [0x5faeeae7, 0x0290, 0x4c31, 0x9e, 0x8a, 0xc5, 0x34, 0xf6, 0x8d, 0x9d, 0xba]
      _.MF_MT_AUDIO_BITS_PER_SAMPLE := [0xf2deb57f, 0x40fa, 0x4764, 0xaa, 0x33, 0xed, 0x4f, 0x2d, 0x1f, 0xf6, 0x69]
      _.MF_MT_AUDIO_NUM_CHANNELS := [0x37e48bf5, 0x645e, 0x4c5b, 0x89, 0xde, 0xad, 0xa9, 0xe2, 0x9b, 0x69, 0x6a]
      _.MFT_CATEGORY_VIDEO_ENCODER := [0xf79eac7d, 0xe545, 0x4387, 0xbd, 0xee, 0xd6, 0x47, 0xd7, 0xbd, 0xe4, 0x2a]
      _.MF_TRANSCODE_CONTAINERTYPE := [0x150ff23f, 0x4abc, 0x478b, 0xac, 0x4f, 0xe1, 0x91, 0x6f, 0xba, 0x1c, 0xca]
      _.MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS := [0xa634a91c, 0x822b, 0x41b9, 0xa4, 0x94, 0x4d, 0xe4, 0x64, 0x36, 0x12, 0xb0]
      _.MFTranscodeContainerType_MPEG4 := [0xdc6cd05d, 0xb9d0, 0x40ef, 0xbd, 0x35, 0xfa, 0x62, 0x2c, 0x1a, 0xb2, 0x8a]
      _.MFT_FRIENDLY_NAME_Attribute := [0x314ffbae, 0x5b41, 0x4c95, 0x9c, 0x19, 0x4e, 0x7d, 0x58, 0x6f, 0xac, 0xe3]
      _.MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME := [0x60d0e559, 0x52f8, 0x4fa2, 0xbb, 0xce, 0xac, 0xdb, 0x34, 0xa8, 0xec, 0x1]
      _.MF_SINK_WRITER_DISABLE_THROTTLING := [0x08b845d8, 0x2b74, 0x4afe, 0x9d, 0x53, 0xbe, 0x16, 0xd2, 0xd5, 0xae, 0x4f]
      _.MF_LOW_LATENCY := [0x9c27891a, 0xed7a, 0x40e1, 0x88, 0xe8, 0xb2, 0x27, 0x27, 0xa0, 0x24, 0xee]
      _.MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE := [0xc60ac5fe, 0x252a, 0x478f, 0xa0, 0xef, 0xbc, 0x8f, 0xa5, 0xf7, 0xca, 0xd3]
      _.MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_GUID := [0x14dd9a1c, 0x7cff, 0x41be, 0xb1, 0xb9, 0xba, 0x1a, 0xc6, 0xec, 0xb5, 0x71]
      _.MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID := [0x8ac3587a, 0x4ae7, 0x42d8, 0x99, 0xe0, 0x0a, 0x60, 0x13, 0xee, 0xf9, 0x0f]
      _.MFSampleExtension_Discontinuity := [0x9cdf01d9, 0xa0f0, 0x43ba, 0xb0, 0x77, 0xea, 0xa0, 0x6c, 0xbd, 0x72, 0x8a]
      _.MFMediaType_Video := [0x73646976, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71]
      _.MFMediaType_Audio := [0x73647561, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71]
      _.MFAudioFormat_AAC := [0x1610, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71]
      _.MFAudioFormat_Float := [0x0003, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71]
      _.MFAudioFormat_PCM := [0x0001, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71]
      _.MFVideoFormat_H264 := [0x34363248, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71]   ; FCC("H264") = 0x34363248
      _.MFVideoFormat_RGB32 := [0x00000016, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71]
      _.MFVideoFormat_ARGB32 := [0x00000015, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71]
   }
   if _.haskey(name)
   {
      p := _[name]
      VarSetCapacity(GUID,16)
      ,NumPut(p.1+(p.2<<32)+(p.3<<48),GUID,0,"int64")
      ,NumPut(p.4+(p.5<<8)+(p.6<<16)+(p.7<<24)+(p.8<<32)+(p.9<<40)+(p.10<<48)+(p.11<<56),GUID,8,"int64")
      return &GUID
   }
   else return name
}

GUID(ByRef GUID, sGUID)
{
    VarSetCapacity(GUID, 16, 0)
    return DllCall("ole32\CLSIDFromString", "WStr", sGUID, "Ptr", &GUID) >= 0 ? &GUID : ""
}

FCC(var)
{
   c := StrSplit(var)
   msgbox % clipboard := Format("{:#x}",((Asc(c[1])&255)+((Asc(c[2])&255)<<8)+((Asc(c[3])&255)<<16)+((Asc(c[4])&255)<<24)))
}

Release(this)
{
   DllCall(NumGet(NumGet(this+0)+2*A_PtrSize), "ptr", this)
   if ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

_Error(val)
{
   msgbox % val
   ExitApp
}

checkCoordinates(ByRef start1, ByRef end1, ByRef start2, ByRef end2, hardware_encoder:="")
{
   if InStr(hardware_encoder, "NVIDIA")
      min1 := 33, min2 := 17
   else if A_OSVersion in WIN_XP,WIN_VISTA,WIN_7
      min1 := min2 := 64
   else
      min1 := min2 := 33
   max1 := A_ScreenWidth, max2 := A_ScreenHeight
   loop 2
   {
      if (end%A_Index% - start%A_Index% < min%A_Index%)
      {
         end%A_Index% := start%A_Index% + min%A_Index%
         if !InStr(hardware_encoder, "NVIDIA") and (mod(end%A_Index% - start%A_Index%, 2) != 0)
            end%A_Index%++
         if (end%A_Index% > max%A_Index%)
         {
            start%A_Index% += max%A_Index%-end%A_Index%
            end%A_Index% := max%A_Index%
         }
      }
   }
}

#Esc::
    ;Send {LWin down}
    KeyWait Esc
    KeyWait LWin
    KeyWait RWin
    SoundBeep, 800
    SoundBeep, 400
    ;Send {LWin down}{vk0x07} ; not good
ExitApp

#LButton::
    if WinExist("AudioDevices")
        Return
    Loop, 6
        Gui, % A_Index+93 ": Hide"
    Hotkey, Left, DecreaseC, Off
    Hotkey, Right, IncreaseC, Off
    Hotkey, Right, Right, On
    Hotkey, Left, Left, On
    Hotkey, Up, Up, On
    Hotkey, Down, Down, On
    Hotkey, *LButton, *LButton, On
    CrossOrFrame:= 1, EnterBox:= ""
    
    if !GuiCreated
        Loop, 6 {
            Gui, % A_Index+93 ": -Caption +ToolWindow +AlwaysOnTop -DPIScale"
            Gui, % A_Index+93 ": Color", % Clr? Clr: Clr:="ff8080"
            Gui, % A_Index+93 ": Show", NA h0 w0, outline%A_Index%
        }   

    KeyWait, LButton
    ;While !GetKeyState("LButton", "P") {
    While !GetKeyState("LButton", "P") && CrossOrFrame  && !EnterBox {
        MouseGetPos, x1, y1
        Critical
        Gui, 94:Show, % "NA X" 0 " Y" y1 " W" A_ScreenWidth " H" 1, outline1
        Gui, 95:Show, % "NA X" x1 " Y" 0 " W" 1 " H" A_ScreenHeight, outline2
        Critical, Off
        Sleep, 50
    }
    If EnterBox {
        WinWaitNotActive, Enter ahk_class #32770
        MouseMove, x1, y1
        Goto #LButton
    }
    if !CrossOrFrame
        Return
    KeyWait, LButton
    Gui, 94:Hide
    Gui, 95:Hide
    Frame:
    EnterBox:= ""
    ;While !GetKeyState("LButton", "P") {
    While !GetKeyState("LButton", "P") && CrossOrFrame && !EnterBox {
        MouseGetPos, x2, y2
        Gosub, Arrows
        Sleep, 50
    }
    If EnterBox {
        WinWaitNotActive, Enter ahk_class #32770
        MouseMove, x2, y2
        Goto Frame
    }
    GuiCreated:= 1
    if !CrossOrFrame
        Return
    Hotkey, *LButton, *LButton, Off
    x1:= nx1, y1:= ny1, x2:= nx2, y2:= ny2
    x2-x1<minW? x2:= x1+minW: "", x2>A_ScreenWidth? (x1-=x2-A_ScreenWidth, x2:= A_ScreenWidth): ""
  , y2-y1<minH? y2:= y1+minH: "", y2>A_ScreenHeight? (y1-=y2-A_ScreenHeight, y2:= A_ScreenHeight): ""
    Gosub Arrows
    x1:= nx1, y1:= ny1, x2:= nx2, y2:= ny2, mod(x2-x1, 2)? x2++: "", mod(y2-y1, 2)? y2++: "", CrossOrFrame:= ""
Return

*F4::
    ErrorLevel:= ""
    KeyWait, F4, T.5
    if ErrorLevel {
        MouseGetPos, ax, ay
        ;Hotkey, Left, Left, Off
        ;Hotkey, Right, Right, Off
        ;Hotkey, Up, Up, Off
        ;Hotkey, Down, Down, Off
        Hotkey, *LButton, *LButton, Off
        ;Hotkey, Esc, Esc, Off
        ShowAllAudioDevicesNames:= CorssOrFrame:= true, EventEsc:= audiodevice:= devicenames:= ""
        Gosub GetAudioDevice
        ;Hotkey, Esc, Esc, On
        Hotkey, *LButton, *LButton, On
        Return
    }
    If !GuiCreated {
        ToolTip, No Frame was created yet!, % A_ScreenWidth//2-200, % A_ScreenHeight//2-20
        Sleep, 1000
        ToolTip
        Return
        ;Loop, 6 {
            ;Gui, % A_Index+93 ": -Caption +ToolWindow +AlwaysOnTop -DPIScale"
            ;Gui, % A_Index+93 ": Color", % Clr? Clr: Clr:="ff8080"
            ;Gui, % A_Index+93 ": Show", % A_Index<3? "Hide ": "" "NA h0 w0", outline%A_Index%
            ;GuiCreated:= 1, x1:= y1:= 1, x2:= A_ScreenWidth-1, y2:= A_ScreenHeight-1
            ;Gosub, Arrows
        ;}
    }
    Loop, 4
        Gui, % A_Index+95 ": Show", NA
Return

$F5::
    KeyWait, F5, T.5
    if ErrorLevel {
        oldFile:= File
        InputBox, newFile, Enter new File,,, 310, 105,,,,, % file
        if newFile
            FileMove, % file, % newFile
    } else Send, {F5}
Return

#IfWinActive, Enter ahk_class #32770
*Esc::Send, {Esc}
*Enter::Send, {Enter}
*Tab::Send, {Tab}
~*LButton::Send, {LButton}

#If WinActive("Enter duration ahk_class #32770")
WheelUp::
WheelDown::
    ;Critical
    if (A_TimeSincePriorHotkey < 500 && A_ThisHotkey = A_PriorHotkey)
        rNotch<=10? rNotch++: "", (rNotch>10&&rNotch<=20)? rNotch+=3: "", (rNotch>20&&rNotch<=30)? rNotch+=5: ""
    else rNotch:=1
    ControlGetFocus, Cf, Enter duration ahk_class #32770
    if InStr(Cf, "Edit") {
        ControlGetText, Ef, % Cf, Enter duration ahk_class #32770
        Ef:=(A_ThisHotkey="WheelUp")? Ef+rNotch: Ef-rNotch
        ControlSetText % Cf, % ((Ef<0)? 0: Ef), Enter duration ahk_class #32770
    }
Return

#IfWinActive, AudioDevices
~Enter::
SelectAudioDevice:
    if (Event:= A_GuiEvent = "Normal" && A_ThisHotkey != "~*LButton")
        Return
    if (A_GuiEvent = "DoubleClick" || A_ThisHotkey = "~Enter" || A_ThisHotkey = "~*LButton") {
        GuiControlGet audiodevice,, SlectedLine
        Clipboard:= audiodevice
    }
    if CrossOrFrame
        MouseMove, ax, ay
Return

~Esc::
        Gui, Destroy
        Microphone (Realtek High Definition Audio)
        if CrossOrFrame
            MouseMove, ax, ay
        if (A_ThisHotkey != "~*LButton")
            ShowAllAudioDevicesNames := devicenames:= "", EventEsc:= 1
Return

#IfWinExist, ahk_group CrossAndFrame
*LButton::
    if WinActive("AudioDevices") && A_ThisHotkey = A_PriorHotkey && A_TimeSincePriorHotkey < 500
    {
        Send, {LButton}
        Gosub ~Enter
        Gosub ~Esc
    }
Return

F3::
    KeyWait, F3, T.5
    if ErrorLevel
        v_bitrate:= 1
    EnterBox:= 1
    Hotkey, Enter, Enter, Off
    Hotkey, Esc, Esc, Off
    WinExist("outline1")? (xb:= x1, yb:= y1): (xb:= nx1, yb:= ny1)
    if v_bitrate
        InputBox, video_bitrate, Enter v_bitrate,,, 210, 105
            , % (xb>(rx:=A_ScreenWidth-265)? rx: xb), % (yb>(ry:=A_ScreenHeight-135)? ry: yb),,, % video_bitrate
    Else
        InputBox, duration, Enter duration,,, 210, 105
            , % (xb>(rx:=A_ScreenWidth-265)? rx: xb), % (yb>(ry:=A_ScreenHeight-135)? ry: yb),,, % duration
    v_bitrate:= ""
    Hotkey, Enter, Enter, On
    Hotkey, Esc, Esc, On
Return

F5::
    EnterBox:= 1
    Hotkey, Enter, Enter, Off
    Hotkey, Esc, Esc, Off
    WinExist("outline1")? (xb:= x1, yb:= y1): (xb:= nx1, yb:= ny1)
    InputBox, file, Enter File,,, 310, 105
            , % (xb>(rx:=A_ScreenWidth-390)? rx: xb), % (yb>(ry:=A_ScreenHeight-135)? ry: yb),,, % file
    Hotkey, Enter, Enter, On
    Hotkey, Esc, Esc, On
Return

F4::
   ErrorLevel:= ""
    KeyWait, F4, T.5
    if ErrorLevel
        Goto *F4
    ;if WinExist("outline1") || WinExist("outline3")  {
        if clr=0
            loop, 6
                Gui, % A_Index+93 ": Color", % Clr:="80ff80"
        else if clr=80ff80
            loop, 6
                Gui, % A_Index+93 ": Color", % Clr:="8080ff"
        else if clr=8080ff
            loop, 6
                Gui, % A_Index+93 ": Color", % Clr:="80ffff"
        else if clr=80ffff
            loop, 6
                Gui, % A_Index+93 ": Color", % Clr:="ff80ff"
        else if clr=ff80ff
            loop, 6
                Gui, % A_Index+93 ": Color", % Clr:="ffff80"
        else if clr=ffff80
            loop, 6
                Gui, % A_Index+93 ": Color", % Clr:="ff8080"
        else if clr=ff8080
            loop, 6
                Gui, % A_Index+93 ": Color", % Clr:="ffffff"
        else if clr=ffffff
            loop, 6
                Gui, % A_Index+93 ": Color", % Clr:="0"
    ;}
Return

Esc::
RButton::
    if WinExist("AudioDevices")
        Goto ~Esc
    x1:= nx1, y1:= ny1, x2:= nx2, y2:= ny2, mod(x2-x1, 2)? x2++: "", mod(y2-y1, 2)? y2++: "", CrossOrFrame:= ""
    ;Critical, 999
    Hotkey, Left, DecreaseC, Off
    Hotkey, Right, IncreaseC, Off
    Hotkey, Right, Right, On
    Hotkey, Left, Left, On
    Hotkey, Up, Up, On
    Hotkey, Down, Down, On
    ;Hotkey, *LButton, *LButton, Off
    Loop, 6
        Gui, % A_Index+93 ": Hide"
    ;Critical, Off
Return

Left::
    If WinExist("outline1")
        Return
    Coo:= "x1", Co:= "x2"
    Hotkey, Left, Left, Off
    ;Hotkey, Up, Up, Off
    ;Hotkey, Down, Down, Off
    Hotkey, Left, DecreaseC, On
    Hotkey, Right, IncreaseC, On
Return

Right::
    If WinExist("outline1")
        Return
    Coo:= "x2", Co:= "x1"
    Hotkey, Right, Right, Off
    ;Hotkey, Up, Up, Off
    ;Hotkey, Down, Down, Off
    Hotkey, Left, DecreaseC, On
    Hotkey, Right, IncreaseC, On
Return

Up::
    if WinActive("AudioDevices")
        Send, {Up}
    If WinExist("outline1")
        Return
    Coo:= "y1", Co:= "y2"
    Hotkey, Up, Up, Off
    ;Hotkey, Left, Left, Off
    ;Hotkey, Right, Right, Off
    Hotkey, Up, DecreaseC, On
    Hotkey, Down, IncreaseC, On
Return

Down::
    if WinActive("AudioDevices")
        Send, {Down}
    If WinExist("outline1")
        Return
    Coo:= "y2", Co:= "y1"
    Hotkey, Down, Down, Off
    ;Hotkey, Left, Left, Off
    ;Hotkey, Right, Right, Off
    Hotkey, Up, DecreaseC, On
    Hotkey, Down, IncreaseC, On
Return

DecreaseC:
    Critical, Off
    ;A_TimeSincePriorHotkey < 500 && A_ThisHotkey = A_PriorHotkey? (rNotch<=10? rNotch++: ""): rNotch:=1
    ;Sleep, -1
    ;loop, % rNotch {
        if %Coo%-1 < %Co%+(InStr(%Co%, "x")? minW: minH) && InStr(Coo, 2)
            Return
        %Coo%-=2
        Gosub, Arrows
        %Coo%:= %Coo%<0? 0: %Coo%, mod(%Coo%-%Co%, 2)? %Coo%++: ""
    ;}
Return

IncreaseC:
    Critical, Off
    ;A_TimeSincePriorHotkey < 500 && A_ThisHotkey = A_PriorHotkey? (rNotch<=10? rNotch++: ""): rNotch:=1
    ;Sleep, -1
    ;loop, % rNotch {
        if InStr(Coo, 1) && %Co%-(InStr(%Co%, "x")? minW: minH)<%Coo%+1
            Return
        %Coo%+=2
        Gosub, Arrows
        %Coo%:= %Coo%>(cc:=InStr(Coo, "x")? A_ScreenWidth: A_ScreenHeight)? cc: %Coo%, mod(%Coo%-%Co%, 2)? %Coo%--: ""
    ;}
Return

Enter::
    if WinExist("AudioDevices")
        Goto ~Enter
    Hotkey, Left, DecreaseC, Off
    Hotkey, Up, DecreaseC, Off
    Hotkey, Right, IncreaseC, Off
    Hotkey, Down, IncreaseC, Off
    Hotkey, Left, Left, On
    Hotkey, Up, Up, On
    Hotkey, Right, Right, On
    Hotkey, Down, Down, On
Return

Arrows:
        Critical
        if (x1<=x2 && y1<=y2) {
            nx1:=x1+((x2-x1)>1?1:0), ny1:=y1+((y2-y1)>1?1:0), nx2:=x2-((x2-x1)>1?1:0), ny2:=y2-((y2-y1)>1?1:0)
            Gui, 96:Show, % "NA X" x1+0 " Y" y1-4 " W" x2-x1+4 " H" 4
            Gui, 97:Show, % "NA X" x2+0 " Y" y1-0 " W" 4 " H" y2-y1+4
            Gui, 98:Show, % "NA X" x1-4 " Y" y2-0 " W" x2-x1+4 " H" 4
            Gui, 99:Show, % "NA X" x1-4 " Y" y1-4 " W" 4 " H" y2-y1+4
        } else if (x1>x2 && y1<=y2) {
            nx1:=x2+((x1-x2)>1?1:0), ny1:=y1+((y2-y1)>1?1:0), nx2:=x1-((x1-x2)>1?1:0), ny2:=y2-((y2-y1)>1?1:0)
            Gui, 96:Show, % "NA X" x2-4 " Y" y1-4 " W" x1-x2+4 " H" 4
            Gui, 97:Show, % "NA X" x1+0 " Y" y1-4 " W" 4 " H" y2-y1+4
            Gui, 98:Show, % "NA X" x2-0 " Y" y2-0 " W" x1-x2+4 " H" 4
            Gui, 99:Show, % "NA X" x2-4 " Y" y1+0 " W" 4 " H" y2-y1+4
        } else if (x1<=x2 && y1>y2) {
            nx1:=x1+((x2-x1)>1?1:0), ny1:=y2+((y1-y2)>1?1:0), nx2:=x2-((x2-x1)>1?1:0), ny2:=y1-((y1-y2)>1?1:0)
            Gui, 96:Show, % "NA X" x1-4 " Y" y2-4 " W" x2-x1+4 " H" 4
            Gui, 97:Show, % "NA X" x2+0 " Y" y2-4 " W" 4 " H" y1-y2+4
            Gui, 98:Show, % "NA X" x1-0 " Y" y1+0 " W" x2-x1+4 " H" 4
            Gui, 99:Show, % "NA X" x1-4 " Y" y2+0 " W" 4 " H" y1-y2+4
        } else if (x1>x2 && y1>y2) {
            nx1:=x2+((x1-x2)>1?1:0), ny1:=y2+((y1-y2)>1?1:0), nx2:=x1-((x1-x2)>1?1:0), ny2:=y1-((y1-y2)>1?1:0)
            Gui, 96:Show, % "NA X" x2-4 " Y" y2-4 " W" x1-x2+4 " H" 4
            Gui, 97:Show, % "NA X" x1+0 " Y" y2-4 " W" 4 " H" y1-y2+4
            Gui, 98:Show, % "NA X" x2-0 " Y" y1+0 " W" x1-x2+4 " H" 4
            Gui, 99:Show, % "NA X" x2-4 " Y" y2-0 " W" 4 " H" y1-y2+4
        }
      Critical, Off
Return

 

声明:站内资源为整理优化好的代码上传分享与学习研究,如果是开源代码基本都会标明出处,方便大家扩展学习路径。请不要恶意搬运,破坏站长辛苦整理维护的劳动成果。本站为爱好者分享站点,所有内容不作为商业行为。如若本站上传内容侵犯了原著者的合法权益,请联系我们进行删除下架。