<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Серый форум &mdash; AHK: Запись экрана в видеофайл Directx9/11+Microsoft Media Foundation]]></title>
	<link rel="self" href="http://forum.script-coding.com/extern.php?action=feed&amp;tid=17641&amp;type=atom" />
	<updated>2023-03-10T12:29:25Z</updated>
	<generator>PunBB</generator>
	<id>http://forum.script-coding.com/viewtopic.php?id=17641</id>
		<entry>
			<title type="html"><![CDATA[AHK: Запись экрана в видеофайл Directx9/11+Microsoft Media Foundation]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=157069#p157069" />
			<content type="html"><![CDATA[<p><a href="https://docs.microsoft.com/en-us/windows/win32/medfound/tutorial--using-the-sink-writer-to-encode-video">https://docs.microsoft.com/en-us/window … code-video</a><br /><a href="https://docs.microsoft.com/en-us/windows/win32/api/mfreadwrite/">https://docs.microsoft.com/en-us/window … readwrite/</a><br />Записывает 5 секунд в h264.<br />DirectX 11 + DXGI<br />Выбирает хардверный кодек сходя из его merit.<br />Можно записывать звук, для этого надо вписать название audiodevice, которое можно получить в клипбоард, раскоментировав, ShowAllAudioDevicesNames := true<br />Также для избежания рассинхронизации стоит установить audioDelay (изначально равный 80ms).<br />Если при указании координат файл не создается, нужно раскоментировать CaptureCoordinatesWithCPU := true.<br />Если видеофайл создается перевернутым, то надо раскоментировать Rotate := true.<br />Если в конце выходит сообщение frames dropped != 0, значит компьютер не справляется - нужно уменьшить video_fps.<br />Если не хочется использовать хардверное ускорение (например Nvidia создает Variable Framerate при сильной загрузки проца и гпу, а такие файлы не все монтажки хорошо воспринимают), то надо раскоментировать UseSoftwareEncoding := true.</p><div class="codebox"><pre><code>file := &quot;test.mp4&quot;
video_bitrate := 2000000
video_fps := 25
duration := 5
capture_cursor := true
audiodevice := &quot;CABLE Output (VB-Audio Virtual Cable)&quot;
audioDelay := 80
; x1 := 100, x2 := 1000, y1 := 100, y2 := 500
; ShowAllAudioDevicesNames := true
; CaptureCoordinatesWithCPU := true
; Rotate := true
; UseSoftwareEncoding := true


setbatchlines -1
Global pSinkWriter, SourceReader, audioStreamIndex, Flush, IMFSourceReaderCallback
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 = &quot;DXGI_ERROR_NOT_FOUND&quot;)
         break
      VarSetCapacity(DXGI_OUTPUT_DESC, 88+A_PtrSize, 0)
      IDXGIOutput_GetDesc(IDXGIOutput, &amp;DXGI_OUTPUT_DESC)
      Width := NumGet(DXGI_OUTPUT_DESC, 72, &quot;int&quot;)
      Height := NumGet(DXGI_OUTPUT_DESC, 76, &quot;int&quot;)
      AttachedToDesktop := NumGet(DXGI_OUTPUT_DESC, 80, &quot;int&quot;)
      if (AttachedToDesktop = 1)
         break 2
      ObjRelease(IDXGIOutput)
   }
   ObjRelease(IDXGIAdapter)
}
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, &amp;DXGI_OUTDUPL_DESC)
DesktopImageInSystemMemory := NumGet(DXGI_OUTDUPL_DESC, 32, &quot;uint&quot;)
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, &quot;uint&quot;)   ; Width
NumPut(height, D3D11_TEXTURE2D_DESC, 4, &quot;uint&quot;)   ; Height
NumPut(1, D3D11_TEXTURE2D_DESC, 8, &quot;uint&quot;)   ; MipLevels
NumPut(1, D3D11_TEXTURE2D_DESC, 12, &quot;uint&quot;)   ; ArraySize
NumPut(DXGI_FORMAT_B8G8R8A8_UNORM := 87, D3D11_TEXTURE2D_DESC, 16, &quot;uint&quot;)   ; Format
NumPut(1, D3D11_TEXTURE2D_DESC, 20, &quot;uint&quot;)   ; SampleDescCount
NumPut(0, D3D11_TEXTURE2D_DESC, 24, &quot;uint&quot;)   ; SampleDescQuality
NumPut(D3D11_USAGE_STAGING := 3, D3D11_TEXTURE2D_DESC, 28, &quot;uint&quot;)   ; Usage
NumPut(0, D3D11_TEXTURE2D_DESC, 32, &quot;uint&quot;)   ; BindFlags
NumPut(D3D11_CPU_ACCESS_READ := 0x20000 | D3D11_CPU_ACCESS_WRITE := 0x10000, D3D11_TEXTURE2D_DESC, 36, &quot;uint&quot;)   ; CPUAccessFlags
NumPut(0, D3D11_TEXTURE2D_DESC, 40, &quot;uint&quot;)   ; MiscFlags
ID3D11Device_CreateTexture2D(d3d_device, &amp;D3D11_TEXTURE2D_DESC, 0, staging_tex)
if (capture_cursor = true)
{
   VarSetCapacity(D3D11_TEXTURE2D_DESC, 44, 0)
   NumPut(width, D3D11_TEXTURE2D_DESC, 0, &quot;uint&quot;)   ; Width
   NumPut(height, D3D11_TEXTURE2D_DESC, 4, &quot;uint&quot;)   ; Height
   NumPut(1, D3D11_TEXTURE2D_DESC, 8, &quot;uint&quot;)   ; MipLevels
   NumPut(1, D3D11_TEXTURE2D_DESC, 12, &quot;uint&quot;)   ; ArraySize
   NumPut(DXGI_FORMAT_B8G8R8A8_UNORM := 87, D3D11_TEXTURE2D_DESC, 16, &quot;uint&quot;)   ; Format
   NumPut(1, D3D11_TEXTURE2D_DESC, 20, &quot;uint&quot;)   ; SampleDescCount
   NumPut(0, D3D11_TEXTURE2D_DESC, 24, &quot;uint&quot;)   ; SampleDescQuality
   NumPut(D3D11_USAGE_DEFAULT := 0, D3D11_TEXTURE2D_DESC, 28, &quot;uint&quot;)   ; Usage
   NumPut(D3D11_BIND_RENDER_TARGET := 0x20, D3D11_TEXTURE2D_DESC, 32, &quot;uint&quot;)   ; BindFlags
   NumPut(0, D3D11_TEXTURE2D_DESC, 36, &quot;uint&quot;)   ; CPUAccessFlags
   NumPut(D3D11_RESOURCE_MISC_GDI_COMPATIBLE := 0x200, D3D11_TEXTURE2D_DESC, 40, &quot;uint&quot;)   ; MiscFlags
   ID3D11Device_CreateTexture2D(d3d_device, &amp;D3D11_TEXTURE2D_DESC, 0, gdi_tex)
}

LOAD_DLL_Mf_Mfplat_Mfreadwrite()
MFStartup(version := 2, MFSTARTUP_FULL := 0)
if (ShowAllAudioDevicesNames != 1)
{
   if (UseSoftwareEncoding != 1)
   {
      VarSetCapacity(MFT_REGISTER_TYPE_INFO, 32, 0)
      DllCall(&quot;RtlMoveMemory&quot;, &quot;ptr&quot;, &amp;MFT_REGISTER_TYPE_INFO, &quot;ptr&quot;, MF_GUID(GUID, &quot;MFMediaType_Video&quot;), &quot;ptr&quot;, 16)
      DllCall(&quot;RtlMoveMemory&quot;, &quot;ptr&quot;, &amp;MFT_REGISTER_TYPE_INFO + 16, &quot;ptr&quot;, MF_GUID(GUID, &quot;MFVideoFormat_H264&quot;), &quot;ptr&quot;, 16)
      hardware_encoder := MFTEnumEx(MF_GUID(GUID, &quot;MFT_CATEGORY_VIDEO_ENCODER&quot;), MFT_ENUM_FLAG_HARDWARE := 0x04|MFT_ENUM_FLAG_SORTANDFILTER := 0x40, 0, &amp;MFT_REGISTER_TYPE_INFO)
   }
   if (x1 != &quot;&quot;)
   {
      checkCoordinates(x1, x2, y1, y2, hardware_encoder)
      width := x2-x1
      height := y2-y1
      VarSetCapacity(D3D11_BOX, 24, 0)
      NumPut(x1, D3D11_BOX, 0, &quot;uint&quot;)   ; left
      NumPut(y1, D3D11_BOX, 4, &quot;uint&quot;)   ; top
      NumPut(0, D3D11_BOX, 8, &quot;uint&quot;)   ; front
      NumPut(x2, D3D11_BOX, 12, &quot;uint&quot;)   ; right
      NumPut(y2, D3D11_BOX, 16, &quot;uint&quot;)   ; bottom
      NumPut(1, D3D11_BOX, 20, &quot;uint&quot;)   ; back
   }
   if (hardware_encoder != &quot;&quot;)
   {
      MFCreateAttributes(pMFAttributes, 4)
      IMFAttributes_SetUINT32(pMFAttributes, MF_GUID(GUID, &quot;MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS&quot;), true)
   }
   else
      MFCreateAttributes(pMFAttributes, 3)
   IMFAttributes_SetGUID(pMFAttributes, MF_GUID(GUID, &quot;MF_TRANSCODE_CONTAINERTYPE&quot;), MF_GUID(GUID1, &quot;MFTranscodeContainerType_MPEG4&quot;))
   IMFAttributes_SetUINT32(pMFAttributes, MF_GUID(GUID, &quot;MF_SINK_WRITER_DISABLE_THROTTLING&quot;), true)
   IMFAttributes_SetUINT32(pMFAttributes, MF_GUID(GUID, &quot;MF_LOW_LATENCY&quot;), true)
   MFCreateSinkWriterFromURL(file, 0, pMFAttributes, pSinkWriter)
   Release(pMFAttributes)
   pMFAttributes := &quot;&quot;

   loop 2   ; 1 - input, 2 - output
   {
      MFCreateMediaType(pMediaType%A_Index%)
      IMFAttributes_SetGUID(pMediaType%A_Index%, MF_GUID(GUID, &quot;MF_MT_MAJOR_TYPE&quot;), MF_GUID(GUID1, &quot;MFMediaType_Video&quot;))
      if (A_Index = 1)
      {
         if !InStr(hardware_encoder, &quot;NVIDIA&quot;) or ((x1 != &quot;&quot;) and (CaptureCoordinatesWithCPU = true))
            IMFAttributes_SetGUID(pMediaType%A_Index%, MF_GUID(GUID, &quot;MF_MT_SUBTYPE&quot;), MF_GUID(GUID1, &quot;MFVideoFormat_RGB32&quot;))
         else
            IMFAttributes_SetGUID(pMediaType%A_Index%, MF_GUID(GUID, &quot;MF_MT_SUBTYPE&quot;), MF_GUID(GUID1, &quot;MFVideoFormat_ARGB32&quot;))
      }
      else
      {
         IMFAttributes_SetGUID(pMediaType%A_Index%, MF_GUID(GUID, &quot;MF_MT_SUBTYPE&quot;), MF_GUID(GUID1, &quot;MFVideoFormat_H264&quot;))
         IMFAttributes_SetUINT32(pMediaType%A_Index%, MF_GUID(GUID, &quot;MF_MT_AVG_BITRATE&quot;), video_bitrate)
      }
      IMFAttributes_SetUINT32(pMediaType%A_Index%, MF_GUID(GUID, &quot;MF_MT_INTERLACE_MODE&quot;), MFVideoInterlace_Progressive := 2)
      IMFAttributes_SetUINT64(pMediaType%A_Index%, MF_GUID(GUID, &quot;MF_MT_FRAME_SIZE&quot;), (width&lt;&lt;32)|height)
      IMFAttributes_SetUINT64(pMediaType%A_Index%, MF_GUID(GUID, &quot;MF_MT_FRAME_RATE&quot;), (video_fps&lt;&lt;32)|1)
      IMFAttributes_SetUINT64(pMediaType%A_Index%, MF_GUID(GUID, &quot;MF_MT_PIXEL_ASPECT_RATIO&quot;), (1&lt;&lt;32)|1)
   }
   IMFSinkWriter_AddStream(pSinkWriter, pMediaType2, videoStreamIndex)
   IMFSinkWriter_SetInputMediaType(pSinkWriter, videoStreamIndex, pMediaType1, 0)
   Release(pMediaType1)
   Release(pMediaType2)
   pMediaType1 := pMediaType2 := &quot;&quot;
}

if (audiodevice != &quot;&quot;) or (ShowAllAudioDevicesNames = 1)
{
   NUM_CHANNELSMax := BITS_PER_SAMPLEMax := SAMPLES_PER_SECONDMax := BYTES_PER_SECONDMax := StreamNumberAudio := TypeNumberAudio := AudioSources := &quot;&quot;
   audiobasedevice := audiodevice
   IMFSourceReaderCallback := IMFSourceReaderCallback_new()
   MFCreateAttributes(pMFAttributes, 1)
   IMFAttributes_SetGUID(pMFAttributes, MF_GUID(GUID, &quot;MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE&quot;), MF_GUID(GUID1, &quot;MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_GUID&quot;))
   MFEnumDeviceSources(pMFAttributes, pppSourceActivate, pcSourceActivate)
   Loop % pcSourceActivate
   {
      IMFActivate := NumGet(pppSourceActivate + (A_Index - 1)*A_PtrSize)
      devicename := IMFActivate_GetAllocatedString(IMFActivate, MF_GUID(GUID, &quot;MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME&quot;))
      if (ShowAllAudioDevicesNames = 1)
      {
         basedevicename := devicename
         loop
         {
            if !InStr(Audiodevicenames, &quot;&quot;&quot;&quot; devicename &quot;&quot;&quot;`r`n&quot;)
               break
            devicename := basedevicename &quot;[&quot; A_Index+1 &quot;]&quot;
         }
         Audiodevicenames .= &quot;&quot;&quot;&quot; devicename &quot;&quot;&quot;`r`n&quot;
      }
      else
      {
         if RegexMatch(audiodevice, &quot;\[(\d)]$&quot;, match) and (devicename = RegexReplace(audiodevice, &quot;\[\d]$&quot;))
         {
            match1--
            if (match1 = 0)
               audiodevice := devicename
            else
               audiodevice := devicename &quot;[&quot; match1 &quot;]&quot;
         }
         if (devicename = audiodevice) and (MediaSourceAudio = &quot;&quot;)
            IMFActivate_ActivateObject(IMFActivate, IMFMediaSource := &quot;{279a808d-aec7-40c8-9c6b-a6b492c78a66}&quot;, MediaSourceAudio)
      }
      Release(IMFActivate)
      IMFActivate := &quot;&quot;
   }
   DllCall(&quot;ole32\CoTaskMemFree&quot;, &quot;ptr&quot;, pppSourceActivate)
   Release(pMFAttributes)
   pMFAttributes := &quot;&quot;
   if (ShowAllAudioDevicesNames = 1)
   {
      if (Audiodevicenames = &quot;&quot;)
         Audiodevicenames .= &quot;None&quot;
      msgbox % clipboard := &quot;Audio:`r`n&quot; Audiodevicenames
      ExitApp
   }
   if (MediaSourceAudio = &quot;&quot;)
   {
      msgbox % &quot;Cannot find Audio device - &quot;&quot;&quot; audiobasedevice &quot;&quot;&quot;&quot;
      ExitApp
   }
   MFCreateAttributes(pMFAttributes, 1)
   IMFAttributes_SetUnknown(pMFAttributes, MF_GUID(GUID, &quot;MF_SOURCE_READER_ASYNC_CALLBACK&quot;), IMFSourceReaderCallback)
   MFCreateSourceReaderFromMediaSource(MediaSourceAudio, pMFAttributes, SourceReader)
   loop
   {
      n := A_Index - 1
      if (IMFSourceReader_GetNativeMediaType(SourceReader, n, 0, ppMediaType) = &quot;MF_E_INVALIDSTREAMNUMBER&quot;)
         break
      Release(ppMediaType)
      ppMediaType := &quot;&quot;
      loop
      {
         k := A_Index - 1
         if (IMFSourceReader_GetNativeMediaType(SourceReader, n, k, ppMediaType) = &quot;MF_E_NO_MORE_TYPES&quot;)
            break
         IMFAttributes_GetGUID(ppMediaType, MF_GUID(GUID, &quot;MF_MT_MAJOR_TYPE&quot;), pguidValue)
         if (MemoryDifference(&amp;pguidValue, MF_GUID(GUID, &quot;MFMediaType_Audio&quot;), 16) = 0)
         {
            IMFAttributes_GetGUID(ppMediaType, MF_GUID(GUID, &quot;MF_MT_SUBTYPE&quot;), pguidValueSubType)
            AudioSources .= Format(&quot;0x{:x}&quot;, NumGet(pguidValueSubType, 0, &quot;int&quot;)) &quot;`n&quot;
            if (MemoryDifference(&amp;pguidValueSubType, MF_GUID(GUID, &quot;MFAudioFormat_PCM&quot;), 16) = 0) or (MemoryDifference(&amp;pguidValueSubType, MF_GUID(GUID, &quot;MFAudioFormat_Float&quot;), 16) = 0)
            {
               if (IMFAttributes_GetUINT32(ppMediaType, MF_GUID(GUID, &quot;MF_MT_AUDIO_AVG_BYTES_PER_SECOND&quot;), BYTES_PER_SECOND) = &quot;MF_E_ATTRIBUTENOTFOUND&quot;)
                  BYTES_PER_SECOND := 0
               if (IMFAttributes_GetUINT32(ppMediaType, MF_GUID(GUID, &quot;MF_MT_AUDIO_BITS_PER_SAMPLE&quot;), BITS_PER_SAMPLE) = &quot;MF_E_ATTRIBUTENOTFOUND&quot;)
                  BITS_PER_SAMPLE := 0
               if (IMFAttributes_GetUINT32(ppMediaType, MF_GUID(GUID, &quot;MF_MT_AUDIO_SAMPLES_PER_SECOND&quot;), SAMPLES_PER_SECOND) = &quot;MF_E_ATTRIBUTENOTFOUND&quot;)
                  SAMPLES_PER_SECOND := 0
               if (IMFAttributes_GetUINT32(ppMediaType, MF_GUID(GUID, &quot;MF_MT_AUDIO_NUM_CHANNELS&quot;), NUM_CHANNELS) = &quot;MF_E_ATTRIBUTENOTFOUND&quot;)
                  NUM_CHANNELS := 0
               if ((NUM_CHANNELSMax &lt; 2) and (NUM_CHANNELS &gt; NUM_CHANNELSMax)) or ((NUM_CHANNELSMax = 2) and (NUM_CHANNELS = 6)) or ((NUM_CHANNELSMax &gt; 2) and (NUM_CHANNELSMax != 6) and ((NUM_CHANNELS = 2) or (NUM_CHANNELS = 6))) or ((NUM_CHANNELS = NUM_CHANNELSMax) and (BITS_PER_SAMPLEMax != 16) and ((BITS_PER_SAMPLE = 16) or (BITS_PER_SAMPLE &gt; BITS_PER_SAMPLEMax))) or ((NUM_CHANNELS = NUM_CHANNELSMax) and (BITS_PER_SAMPLE = BITS_PER_SAMPLEMax) and (SAMPLES_PER_SECONDMax != 44100) and (SAMPLES_PER_SECONDMax != 48000) and ((SAMPLES_PER_SECOND = 44100) or (SAMPLES_PER_SECOND &gt; SAMPLES_PER_SECONDMax))) or ((SAMPLES_PER_SECONDMax != 48000) and (SAMPLES_PER_SECOND = 48000)) or ((NUM_CHANNELS = NUM_CHANNELSMax) and (BITS_PER_SAMPLE = BITS_PER_SAMPLEMax) and (SAMPLES_PER_SECOND = SAMPLES_PER_SECONDMax) and (BYTES_PER_SECOND &gt; BYTES_PER_SECONDMax))
               { 
                  NUM_CHANNELSMax := NUM_CHANNELS
                  BITS_PER_SAMPLEMax := BITS_PER_SAMPLE
                  SAMPLES_PER_SECONDMax := SAMPLES_PER_SECOND
                  BYTES_PER_SECONDMax := BYTES_PER_SECOND
                  StreamNumberAudio := n
                  TypeNumberAudio := k
               }
            }
         }
         Release(ppMediaType)
         ppMediaType := &quot;&quot;
      }
   }
   if (StreamNumberAudio = &quot;&quot;)
   {
      Sort, AudioSources, U
      msgbox % &quot;Current AudioSources not supported:`n&quot; AudioSources
      ExitApp
   }
   IMFSourceReader_SetStreamSelection(SourceReader, MF_SOURCE_READER_ALL_STREAMS := 0xFFFFFFFE, false)
   IMFSourceReader_SetStreamSelection(SourceReader, StreamNumberAudio, true)
   Release(pMFAttributes)
   pMFAttributes := &quot;&quot;
   if (NUM_CHANNELSMax = 0)
      NUM_CHANNELSMax := 1
   else if (NUM_CHANNELSMax &gt; 2) and (NUM_CHANNELSMax &lt; 6)
      NUM_CHANNELSMax := 2
   else if (NUM_CHANNELSMax &gt; 6)
      NUM_CHANNELSMax := 6
   if (SAMPLES_PER_SECONDMax &lt; 44100)
      SAMPLES_PER_SECONDMax := 44100
   else if (SAMPLES_PER_SECONDMax &gt; 44100)
      SAMPLES_PER_SECONDMax := 48000
   loop 2   ; 1 - input, 2 - output
   {
      MFCreateMediaType(pMediaTypeAudio%A_Index%)
      IMFAttributes_SetGUID(pMediaTypeAudio%A_Index%, MF_GUID(GUID, &quot;MF_MT_MAJOR_TYPE&quot;), MF_GUID(GUID1, &quot;MFMediaType_Audio&quot;))
      if (A_Index = 1)
         IMFAttributes_SetGUID(pMediaTypeAudio%A_Index%, MF_GUID(GUID, &quot;MF_MT_SUBTYPE&quot;), MF_GUID(GUID1, &quot;MFAudioFormat_PCM&quot;))
      else
      {
         IMFAttributes_SetGUID(pMediaTypeAudio%A_Index%, MF_GUID(GUID, &quot;MF_MT_SUBTYPE&quot;), MF_GUID(GUID1, &quot;MFAudioFormat_AAC&quot;))
         IMFAttributes_SetUINT32(pMediaTypeAudio%A_Index%, MF_GUID(GUID, &quot;MF_MT_AUDIO_AVG_BYTES_PER_SECOND&quot;), 20000)
      }
      IMFAttributes_SetUINT32(pMediaTypeAudio%A_Index%, MF_GUID(GUID, &quot;MF_MT_AUDIO_BITS_PER_SAMPLE&quot;), 16)
      IMFAttributes_SetUINT32(pMediaTypeAudio%A_Index%, MF_GUID(GUID, &quot;MF_MT_AUDIO_SAMPLES_PER_SECOND&quot;), SAMPLES_PER_SECONDMax)
      IMFAttributes_SetUINT32(pMediaTypeAudio%A_Index%, MF_GUID(GUID, &quot;MF_MT_AUDIO_NUM_CHANNELS&quot;), NUM_CHANNELSMax)
   }
   IMFSinkWriter_AddStream(pSinkWriter, pMediaTypeAudio2, audioStreamIndex)
   IMFSinkWriter_SetInputMediaType(pSinkWriter, audioStreamIndex, pMediaTypeAudio1, 0)
   IMFSourceReader_SetCurrentMediaType(SourceReader, StreamNumberAudio, 0, pMediaTypeAudio1)
   Release(pMediaTypeAudio1)
   Release(pMediaTypeAudio2)
   pMediaTypeAudio1 := pMediaTypeAudio2 := &quot;&quot;
}
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
CaptureDuration := duration*1000 - 2*fps
VarSetCapacity(TIMECAPS, 8, 0)
DllCall(&quot;winmm\timeGetDevCaps&quot;, &quot;ptr&quot;, &amp;TIMECAPS, &quot;uint&quot;, 8)
uPeriod := NumGet(TIMECAPS, 0, &quot;uint&quot;)
DllCall(&quot;Winmm\timeBeginPeriod&quot;, &quot;uint&quot;, uPeriod)

msgbox % &quot;hardware-encoder - &quot; ((hardware_encoder != &quot;&quot;) ? hardware_encoder : &quot;none&quot;)
loop
{
   if (A_Index != 1)
   {
      DllCall(&quot;QueryPerformanceCounter&quot;, &quot;int64*&quot;, ATickCount)
      sleepDuration := fps*(A_Index-1) - (ATickCount - start)*1000/freq
      SleepEnd := ATickCount + sleepDuration*freq/1000
      sleep % sleepDuration - 15
      DllCall(&quot;QueryPerformanceCounter&quot;, &quot;int64*&quot;, ATickCount)
      if (ATickCount &lt; SleepEnd)
         DllCall(&quot;Sleep&quot;, &quot;uint&quot;, (SleepEnd - ATickCount)*1000/freq)
   }
   VarSetCapacity(DXGI_OUTDUPL_FRAME_INFO, 48, 0)
   if (A_Index = 1)
      AcquireNextFrame := IDXGIOutputDuplication_AcquireNextFrame(Duplication, -1, &amp;DXGI_OUTDUPL_FRAME_INFO, desktop_resource)
   else
      AcquireNextFrame := IDXGIOutputDuplication_AcquireNextFrame(Duplication, 0, &amp;DXGI_OUTDUPL_FRAME_INFO, desktop_resource)
   if (AcquireNextFrame != &quot;DXGI_ERROR_WAIT_TIMEOUT&quot;)
   {
      if (A_Index = 1)
      {
         if (audiodevice != &quot;&quot;)
         {
            IMFSourceReader_ReadSample(SourceReader, MF_SOURCE_READER_ANY_STREAM := 0xFFFFFFFE, 0, 0, 0, 0, 0)
            if (audioDelay &gt; 0)
               DllCall(&quot;Sleep&quot;, &quot;uint&quot;, audioDelay)
         }
         DllCall(&quot;QueryPerformanceCounter&quot;, &quot;int64*&quot;, start)
         DllCall(&quot;QueryPerformanceFrequency&quot;, &quot;int64*&quot;, freq)
      }
      else
      {
         Release(pSample)
         Release(pBuffer)
         pSample := pBuffer := &quot;&quot;
      }
      tex := ID3D11Texture2D_Query(desktop_resource)
      if (capture_cursor = true)
      {
         VarSetCapacity(CURSORINFO, cbSize := 16 + A_PtrSize, 0)
         NumPut(cbSize, CURSORINFO, 0, &quot;uint&quot;)
      }
      if (capture_cursor = true) and DllCall(&quot;GetCursorInfo&quot;, &quot;ptr&quot;, &amp;CURSORINFO) and (NumGet(CURSORINFO, 4, &quot;uint&quot;) = 1)   ; CURSOR_SHOWING
      {
         hCursor := NumGet(CURSORINFO, 8)
         xCursor := NumGet(CURSORINFO, 8 + A_PtrSize, &quot;int&quot;)
         yCursor := NumGet(CURSORINFO, 12 + A_PtrSize, &quot;int&quot;)
         VarSetCapacity(ICONINFO, 8 + A_PtrSize*3, 0)
         DllCall(&quot;GetIconInfo&quot;, &quot;ptr&quot;, hCursor, &quot;ptr&quot;, &amp;ICONINFO)
         xHotspot := NumGet(ICONINFO, 4, &quot;uint&quot;)
         yHotspot := NumGet(ICONINFO, 8, &quot;uint&quot;)
         hbmMask  := NumGet(ICONINFO, 8 + A_PtrSize)
         hbmColor := NumGet(ICONINFO, 8 + A_PtrSize*2)
         ID3D11DeviceContext_CopyResource(d3d_context, gdi_tex, tex)
         gdi_Surface := IDXGISurface1_Query(gdi_tex)
         IDXGISurface1_GetDC(gdi_Surface, 0, hdc)
         DllCall(&quot;DrawIconEx&quot;, &quot;ptr&quot;, hdc, &quot;int&quot;, xCursor - xHotspot, &quot;int&quot;, yCursor - yHotspot, &quot;ptr&quot;, hCursor, &quot;int&quot;, 0, &quot;int&quot;, 0, &quot;uint&quot;, 0, &quot;ptr&quot;, 0, &quot;uint&quot;, DI_NORMAL := 0x0003 | DI_DEFAULTSIZE := 0x0008)
         if hbmMask
            DllCall(&quot;DeleteObject&quot;, &quot;ptr&quot;, hbmMask)
         if hbmColor
            DllCall(&quot;DeleteObject&quot;, &quot;ptr&quot;, hbmColor)
         hbmMask := hbmColor := &quot;&quot;
         IDXGISurface1_ReleaseDC(gdi_Surface, 0)
         if (x1 = &quot;&quot;)
            ID3D11DeviceContext_CopyResource(d3d_context, staging_tex, gdi_tex)
         else
            ID3D11DeviceContext_CopySubresourceRegion(d3d_context, staging_tex, 0, 0, 0, 0, gdi_tex, 0, &amp;D3D11_BOX)   ; set region
         ObjRelease(gdi_Surface)
         gdi_Surface := &quot;&quot;
      }
      else
      {
         if (x1 = &quot;&quot;)
            ID3D11DeviceContext_CopyResource(d3d_context, staging_tex, tex)
         else
            ID3D11DeviceContext_CopySubresourceRegion(d3d_context, staging_tex, 0, 0, 0, 0, tex, 0, &amp;D3D11_BOX)   ; set region
      }
      VarSetCapacity(D3D11_MAPPED_SUBRESOURCE, 8+A_PtrSize, 0)
      ID3D11DeviceContext_Map(d3d_context, staging_tex, 0, D3D11_MAP_READ := 1, 0, &amp;D3D11_MAPPED_SUBRESOURCE)
      pBits := NumGet(D3D11_MAPPED_SUBRESOURCE, 0, &quot;ptr&quot;)
      pitch := NumGet(D3D11_MAPPED_SUBRESOURCE, A_PtrSize, &quot;uint&quot;)

      MFCreateMemoryBuffer(cbBuffer, pBuffer)
      IMFMediaBuffer_Lock(pBuffer, pData, 0, 0)
      if !InStr(hardware_encoder, &quot;NVIDIA&quot;) or ((x1 != &quot;&quot;) and (CaptureCoordinatesWithCPU = true)) or (Rotate = true)
         MFCopyImage(pData, cbWidth, pBits+(height-1)*pitch, pitch*-1, cbWidth, height)
      else
         MFCopyImage(pData, cbWidth, pBits, pitch, 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 != &quot;DXGI_ERROR_WAIT_TIMEOUT&quot;)
   {
      ID3D11DeviceContext_Unmap(d3d_context, staging_tex, 0)
      ObjRelease(tex)
      Release(desktop_resource)
      tex := desktop_resource := &quot;&quot;
      IDXGIOutputDuplication_ReleaseFrame(duplication)
   }
   if ((ATickCount - start)/freq*1000 &gt;= CaptureDuration)
   {
      video_frame_countReal := A_Index
      if (audiodevice != &quot;&quot;)
      {
         flush := 1
         loop
         {
            if (flush = &quot;&quot;)
               break
            sleep 50
         }
      }
      break
   }
   rtStart += video_frame_duration
}
IMFSinkWriter_Finalize(pSinkWriter)
DllCall(&quot;Winmm\timeEndPeriod&quot;, &quot;uint&quot;, uPeriod)
if audiodevice
{
   Release(MediaSourceAudio)
   MediaSourceAudio := &quot;&quot;
}
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 := &quot;&quot;
}
pSample := pBuffer := pSinkWriter := staging_tex := d3d_device := d3d_context := duplication := IDXGIAdapter := IDXGIOutput := IDXGIOutput1 := IDXGIFactory := &quot;&quot;
MFShutdown()
msgbox % &quot;done`n&quot; video_frame_countReal &quot; captured`n&quot; video_frame_count-video_frame_countReal &quot; frames dropped&quot;
ExitApp




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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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



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

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

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

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

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

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

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

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

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

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

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

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

MFCreateCollection(ByRef ppIMFCollection)
{
   hr := DllCall(&quot;Mfplat.dll\MFCreateCollection&quot;, &quot;ptr*&quot;, ppIMFCollection)
   if hr or ErrorLevel
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
}

MFCreateAggregateSource(pSourceCollection, ByRef ppAggSource)
{
   hr := DllCall(&quot;Mf.dll\MFCreateAggregateSource&quot;, &quot;ptr&quot;, pSourceCollection, &quot;ptr*&quot;, ppAggSource)
   if hr or ErrorLevel
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
}

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

IMFSourceReader_SetStreamSelection(this, dwStreamIndex, fSelected)
{
   hr := DllCall(NumGet(NumGet(this+0)+4*A_PtrSize), &quot;ptr&quot;, this, &quot;uint&quot;, dwStreamIndex, &quot;int&quot;, fSelected)
   if hr or ErrorLevel
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
}

IMFSourceReader_GetNativeMediaType(this, dwStreamIndex, dwMediaTypeIndex, ByRef ppMediaType)
{
   hr := DllCall(NumGet(NumGet(this+0)+5*A_PtrSize), &quot;ptr&quot;, this, &quot;uint&quot;, dwStreamIndex, &quot;uint&quot;, dwMediaTypeIndex, &quot;ptr*&quot;, ppMediaType)
   if hr or ErrorLevel
   {
      if !ErrorLevel
      {
         if (hr&amp;=0xFFFFFFFF) = 0xC00D36B3   ; MF_E_INVALIDSTREAMNUMBER
            return &quot;MF_E_INVALIDSTREAMNUMBER&quot;
         if (hr&amp;=0xFFFFFFFF) = 0xC00D36B9   ; MF_E_NO_MORE_TYPES
            return &quot;MF_E_NO_MORE_TYPES&quot;
      }
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
   }
}

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

IMFSourceReader_Flush(this, dwStreamIndex)
{
   hr := DllCall(NumGet(NumGet(this+0)+10*A_PtrSize), &quot;ptr&quot;, this, &quot;uint&quot;, dwStreamIndex)
   if hr or ErrorLevel
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
}

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

IMFAttributes_GetUINT64(this, guidKey, ByRef punValue)
{
   hr := DllCall(NumGet(NumGet(this+0)+8*A_PtrSize), &quot;ptr&quot;, this, &quot;ptr&quot;, guidKey, &quot;uint64*&quot;, punValue)
   if hr or ErrorLevel
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
}

IMFAttributes_GetUINT32(this, guidKey, ByRef punValue)
{
   hr := DllCall(NumGet(NumGet(this+0)+7*A_PtrSize), &quot;ptr&quot;, this, &quot;ptr&quot;, guidKey, &quot;uint*&quot;, punValue)
   if hr or ErrorLevel
   {
      if !ErrorLevel
      {
         if (hr&amp;=0xFFFFFFFF) = 0xC00D36E6   ; MF_E_ATTRIBUTENOTFOUND
            return &quot;MF_E_ATTRIBUTENOTFOUND&quot;
      }
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
   }
}

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

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

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

IMFAttributes_SetUnknown(this, guidKey, pUnknown)
{
   hr := DllCall(NumGet(NumGet(this+0)+27*A_PtrSize), &quot;ptr&quot;, this, &quot;ptr&quot;, guidKey, &quot;ptr&quot;, pUnknown)
   if hr or ErrorLevel
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
}

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

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

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

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

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

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

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

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

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

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

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

IMFMediaSource_Shutdown(this)
{
   hr := DllCall(NumGet(NumGet(this+0)+12*A_PtrSize), &quot;ptr&quot;, this)
   if hr or ErrorLevel
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
}

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

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

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

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

IMFCollection_AddElement(this, pUnkElement)
{
   hr := DllCall(NumGet(NumGet(this+0)+5*A_PtrSize), &quot;ptr&quot;, this, &quot;ptr&quot;, pUnkElement)
   if hr or ErrorLevel
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; 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]
      _.MF_SOURCE_READER_DISCONNECT_MEDIASOURCE_ON_SHUTDOWN := [0x56b67165, 0x219e, 0x456d, 0xa2, 0x2e, 0x2d, 0x30, 0x04, 0xc7, 0xfe, 0x56]
      _.MF_SOURCE_READER_ASYNC_CALLBACK := [0x1e3dbeac, 0xbb43, 0x4c35, 0xb5, 0x07, 0xcd, 0x64, 0x44, 0x64, 0xc9, 0x65]
      _.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(&quot;H264&quot;) = 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]
      _.MFVideoFormat_I420 := [0x30323449, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71]
      _.MFVideoFormat_IYUV := [0x56555949, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71]
      _.MFVideoFormat_NV12 := [0x3231564E, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71]
      _.MFVideoFormat_YUY2 := [0x32595559, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71]
      _.MFVideoFormat_YV12 := [0x32315659, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71]
      _.MFVideoFormat_RGB24 := [0x00000014, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71]
   }
   if _.haskey(name)
   {
      p := _[name]
      VarSetCapacity(GUID,16)
      ,NumPut(p.1+(p.2&lt;&lt;32)+(p.3&lt;&lt;48),GUID,0,&quot;int64&quot;)
      ,NumPut(p.4+(p.5&lt;&lt;8)+(p.6&lt;&lt;16)+(p.7&lt;&lt;24)+(p.8&lt;&lt;32)+(p.9&lt;&lt;40)+(p.10&lt;&lt;48)+(p.11&lt;&lt;56),GUID,8,&quot;int64&quot;)
      return &amp;GUID
   }
   else return name
}

GUID(ByRef GUID, sGUID)
{
    VarSetCapacity(GUID, 16, 0)
    return DllCall(&quot;ole32\CLSIDFromString&quot;, &quot;WStr&quot;, sGUID, &quot;Ptr&quot;, &amp;GUID) &gt;= 0 ? &amp;GUID : &quot;&quot;
}

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

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

MemoryDifference(ptr1, ptr2, num)
{
   return DllCall(&quot;msvcrt\memcmp&quot;, &quot;ptr&quot;, ptr1, &quot;ptr&quot;, ptr2, &quot;int&quot;, num) 
}

_Error(val)
{
   msgbox % val
   ExitApp
}

checkCoordinates(ByRef start1, ByRef end1, ByRef start2, ByRef end2, hardware_encoder:=&quot;&quot;)
{
   if !InStr(hardware_encoder, &quot;NVIDIA&quot;) or ((x1 != &quot;&quot;) and (CaptureCoordinatesWithCPU = true))
      min1 := min2 := 33
   else
      min1 := 33, min2 := 17
   max1 := A_ScreenWidth, max2 := A_ScreenHeight
   loop 2
   {
      if (end%A_Index% - start%A_Index% &lt; min%A_Index%)
         end%A_Index% := start%A_Index% + min%A_Index%
      if (!InStr(hardware_encoder, &quot;NVIDIA&quot;) or ((x1 != &quot;&quot;) and (CaptureCoordinatesWithCPU = true))) and (mod(end%A_Index% - start%A_Index%, 2) != 0)
         end%A_Index%++
      if (end%A_Index% &gt; max%A_Index%)
      {
         start%A_Index% += max%A_Index%-end%A_Index%
         end%A_Index% := max%A_Index%
      }
   }
}



IMFSourceReaderCallback_new() {
   static VTBL := [ &quot;QueryInterface&quot;
                  , &quot;AddRef&quot;
                  , &quot;Release&quot;
                  , &quot;OnReadSample&quot; A_PtrSize
                  , &quot;OnFlush&quot;
                  , &quot;OnEvent&quot; ]
                  
        , heapSize := A_PtrSize*10
        , heapOffset := A_PtrSize*9
        
        , flags := (HEAP_GENERATE_EXCEPTIONS := 0x4) | (HEAP_NO_SERIALIZE := 0x1)
        , HEAP_ZERO_MEMORY := 0x8
   
   hHeap := DllCall(&quot;HeapCreate&quot;, &quot;UInt&quot;, flags, &quot;Ptr&quot;, 0, &quot;Ptr&quot;, 0, &quot;Ptr&quot;)
   addr := IMFSourceReaderCallback := DllCall(&quot;HeapAlloc&quot;, &quot;Ptr&quot;, hHeap, &quot;UInt&quot;, HEAP_ZERO_MEMORY, &quot;Ptr&quot;, heapSize, &quot;Ptr&quot;)
   addr := NumPut(addr + A_PtrSize, addr + 0)
   for k, v in VTBL
      addr := NumPut( RegisterSyncCallback(&quot;IMFSourceReaderCallback_&quot; . v), addr + 0 )
   NumPut(hHeap, IMFSourceReaderCallback + heapOffset)
   Return IMFSourceReaderCallback
}

IMFSourceReaderCallback_QueryInterface(this, riid, ppvObject)
{
   static IID_IUnknown, IID_IMFSourceReaderCallback
   if (!VarSetCapacity(IID_IUnknown))
   {
      VarSetCapacity(IID_IUnknown, 16), VarSetCapacity(IID_IMFSourceReaderCallback, 16)
      DllCall(&quot;ole32\CLSIDFromString&quot;, &quot;WStr&quot;, &quot;{00000000-0000-0000-C000-000000000046}&quot;, &quot;Ptr&quot;, &amp;IID_IUnknown)
      DllCall(&quot;ole32\CLSIDFromString&quot;, &quot;WStr&quot;, &quot;{deec8d99-fa1d-4d82-84c2-2c8969944867}&quot;, &quot;Ptr&quot;, &amp;IID_IMFSourceReaderCallback)
   }
   if (DllCall(&quot;ole32\IsEqualGUID&quot;, &quot;Ptr&quot;, riid, &quot;Ptr&quot;, &amp;IID_IMFSourceReaderCallback) || DllCall(&quot;ole32\IsEqualGUID&quot;, &quot;Ptr&quot;, riid, &quot;Ptr&quot;, &amp;IID_IUnknown))
   {
      NumPut(this, ppvObject+0, &quot;Ptr&quot;)
      IMFSourceReaderCallback_AddRef(this)
      return 0 ; S_OK
   }
   NumPut(0, ppvObject+0, &quot;Ptr&quot;)
   return 0x80004002 ; E_NOINTERFACE
}

IMFSourceReaderCallback_AddRef(this) {
   static refOffset := A_PtrSize*8
   NumPut(refCount := NumGet(this + refOffset, &quot;UInt&quot;) + 1, this + refOffset, &quot;UInt&quot;)
   Return refCount
}

IMFSourceReaderCallback_Release(this) {
   static refOffset := A_PtrSize*8
        , heapOffset := A_PtrSize*9
   NumPut(refCount := NumGet(this + refOffset, &quot;UInt&quot;) - 1, this + refOffset, &quot;UInt&quot;)
   if (refCount = 0) {
      hHeap := NumGet(this + heapOffset)
      DllCall(&quot;HeapDestroy&quot;, &quot;Ptr&quot;, hHeap)
   }
   Return refCount
}

/*
    RegisterSyncCallback

    A replacement for RegisterCallback for use with APIs that will call
    the callback on the wrong thread.  Synchronizes with the script&#039;s main
    thread via a window message.

    This version tries to emulate RegisterCallback as much as possible
    without using RegisterCallback, so shares most of its limitations,
    and some enhancements that could be made are not.

    Other differences from v1 RegisterCallback:
      - Variadic mode can&#039;t be emulated exactly, so is not supported.
      - A_EventInfo can&#039;t be set in v1, so is not supported.
      - Fast mode is not supported (the option is ignored).
      - ByRef parameters are allowed (but ByRef is ignored).
      - Throws instead of returning &quot;&quot; on failure.
*/
RegisterSyncCallback(FunctionName, Options:=&quot;&quot;, ParamCount:=&quot;&quot;)
{
    if !(fn := Func(FunctionName)) || fn.IsBuiltIn
        throw Exception(&quot;Bad function&quot;, -1, FunctionName)
    if (ParamCount == &quot;&quot;)
        ParamCount := fn.MinParams
    if (ParamCount &gt; fn.MaxParams &amp;&amp; !fn.IsVariadic || ParamCount+0 &lt; fn.MinParams)
        throw Exception(&quot;Bad param count&quot;, -1, ParamCount)

    static sHwnd := 0, sMsg, sSendMessageW
    if !sHwnd
    {
        Gui RegisterSyncCallback: +Parent%A_ScriptHwnd% +hwndsHwnd
        OnMessage(sMsg := 0x8000, Func(&quot;RegisterSyncCallback_Msg&quot;))
        sSendMessageW := DllCall(&quot;GetProcAddress&quot;, &quot;ptr&quot;, DllCall(&quot;GetModuleHandle&quot;, &quot;str&quot;, &quot;user32.dll&quot;, &quot;ptr&quot;), &quot;astr&quot;, &quot;SendMessageW&quot;, &quot;ptr&quot;)
    }

    if !(pcb := DllCall(&quot;GlobalAlloc&quot;, &quot;uint&quot;, 0, &quot;ptr&quot;, 96, &quot;ptr&quot;))
        throw
    DllCall(&quot;VirtualProtect&quot;, &quot;ptr&quot;, pcb, &quot;ptr&quot;, 96, &quot;uint&quot;, 0x40, &quot;uint*&quot;, 0)

    p := pcb
    if (A_PtrSize = 8)
    {
        /*
        48 89 4c 24 08  ; mov [rsp+8], rcx
        48 89 54&#039;24 10  ; mov [rsp+16], rdx
        4c 89 44 24 18  ; mov [rsp+24], r8
        4c&#039;89 4c 24 20  ; mov [rsp+32], r9
        48 83 ec 28&#039;    ; sub rsp, 40
        4c 8d 44 24 30  ; lea r8, [rsp+48]  (arg 3, &amp;params)
        49 b9 ..        ; mov r9, .. (arg 4, operand to follow)
        */
        p := NumPut(0x54894808244c8948, p+0)
        p := NumPut(0x4c182444894c1024, p+0)
        p := NumPut(0x28ec834820244c89, p+0)
        p := NumPut(  0xb9493024448d4c, p+0) - 1
        lParamPtr := p, p += 8

        p := NumPut(0xba, p+0, &quot;char&quot;) ; mov edx, nmsg
        p := NumPut(sMsg, p+0, &quot;int&quot;)
        p := NumPut(0xb9, p+0, &quot;char&quot;) ; mov ecx, hwnd
        p := NumPut(sHwnd, p+0, &quot;int&quot;)
        p := NumPut(0xb848, p+0, &quot;short&quot;) ; mov rax, SendMessageW
        p := NumPut(sSendMessageW, p+0)
        /*
        ff d0        ; call rax
        48 83 c4 28  ; add rsp, 40
        c3           ; ret
        */
        p := NumPut(0x00c328c48348d0ff, p+0)
    }
    else ;(A_PtrSize = 4)
    {
        p := NumPut(0x68, p+0, &quot;char&quot;)      ; push ... (lParam data)
        lParamPtr := p, p += 4
        p := NumPut(0x0824448d, p+0, &quot;int&quot;) ; lea eax, [esp+8]
        p := NumPut(0x50, p+0, &quot;char&quot;)      ; push eax
        p := NumPut(0x68, p+0, &quot;char&quot;)      ; push nmsg
        p := NumPut(sMsg, p+0, &quot;int&quot;)
        p := NumPut(0x68, p+0, &quot;char&quot;)      ; push hwnd
        p := NumPut(sHwnd, p+0, &quot;int&quot;)
        p := NumPut(0xb8, p+0, &quot;char&quot;)      ; mov eax, &amp;SendMessageW
        p := NumPut(sSendMessageW, p+0, &quot;int&quot;)
        p := NumPut(0xd0ff, p+0, &quot;short&quot;)   ; call eax
        p := NumPut(0xc2, p+0, &quot;char&quot;)      ; ret argsize
        p := NumPut((InStr(Options, &quot;C&quot;) ? 0 : ParamCount*4), p+0, &quot;short&quot;)
    }
    NumPut(p, lParamPtr+0) ; To be passed as lParam.
    p := NumPut(&amp;fn, p+0)
    p := NumPut(ParamCount, p+0, &quot;int&quot;)
    return pcb
}

RegisterSyncCallback_Msg(wParam, lParam)
{
    if (A_Gui != &quot;RegisterSyncCallback&quot;)
        return
    fn := Object(NumGet(lParam + 0))
    paramCount := NumGet(lParam + A_PtrSize, &quot;int&quot;)
    params := []
    Loop % paramCount
        params.Push(NumGet(wParam + A_PtrSize * (A_Index-1)))
    return %fn%(params*)
}

IMFSourceReaderCallback_OnReadSample4(this_, hrStatus, dwStreamIndex, dwStreamFlags, llTimestamp, llTimestamp1, pSample)
{
   Static audioStart, gapAudio
   critical
   if hrStatus
      _Error(A_ThisFunc &quot; error: &quot; hrStatus &quot;`nErrorLevel: &quot; ErrorLevel)
   llTimestamp |= (llTimestamp1 &lt;&lt; 32)
   if (pSample != 0)
   {
      if (gapAudio = 1)
      {
         IMFAttributes_SetUINT32(pSample, MF_GUID(GUID, &quot;MFSampleExtension_Discontinuity&quot;), true)
         gapAudio := &quot;&quot;
      }
      if (audioStart = &quot;&quot;)
         audioStart := llTimestamp
      IMFSample_SetSampleTime(pSample, llTimestamp - audioStart)
      IMFSinkWriter_WriteSample(pSinkWriter, audioStreamIndex, pSample)
   }
   else if (dwStreamFlags &amp; MF_SOURCE_READERF_STREAMTICK := 256) and (audioStart != &quot;&quot;)
   {
      IMFSinkWriter_SendStreamTick(pSinkWriter, audioStreamIndex, llTimestamp - audioStart)
      gapAudio := 1
   }
   if (flush = &quot;&quot;)
      IMFSourceReader_ReadSample(SourceReader, MF_SOURCE_READER_ANY_STREAM := 0xFFFFFFFE, 0, 0, 0, 0, 0)
   else
   {
      Release(IMFSourceReaderCallback)
      Release(SourceReader)
      SourceReader := IMFSourceReaderCallback := flush := audioStart := gapAudio := &quot;&quot;
   }
   return
}

IMFSourceReaderCallback_OnReadSample8(this_, hrStatus, dwStreamIndex, dwStreamFlags, llTimestamp, pSample)
{
   Static audioStart, gapAudio
   critical
   if hrStatus
      _Error(A_ThisFunc &quot; error: &quot; hrStatus &quot;`nErrorLevel: &quot; ErrorLevel)
   if (pSample != 0)
   {
      if (gapAudio = 1)
      {
         IMFAttributes_SetUINT32(pSample, MF_GUID(GUID, &quot;MFSampleExtension_Discontinuity&quot;), true)
         gapAudio := &quot;&quot;
      }
      if (audioStart = &quot;&quot;)
         audioStart := llTimestamp
      IMFSample_SetSampleTime(pSample, llTimestamp - audioStart)
      IMFSinkWriter_WriteSample(pSinkWriter, audioStreamIndex, pSample)
   }
   else if (dwStreamFlags &amp; MF_SOURCE_READERF_STREAMTICK := 256) and (audioStart != &quot;&quot;)
   {
      IMFSinkWriter_SendStreamTick(pSinkWriter, audioStreamIndex, llTimestamp - audioStart)
      gapAudio := 1
   }
   if (flush = &quot;&quot;)
      IMFSourceReader_ReadSample(SourceReader, MF_SOURCE_READER_ANY_STREAM := 0xFFFFFFFE, 0, 0, 0, 0, 0)
   else
   {
      Release(IMFSourceReaderCallback)
      Release(SourceReader)
      SourceReader := IMFSourceReaderCallback := flush := audioStart := gapAudio := &quot;&quot;
   }
   return
}

IMFSourceReaderCallback_OnFlush(this_, dwStreamIndex)
{
   return
}

IMFSourceReaderCallback_OnEvent(this_)
{
   return
}</code></pre></div><p>DirectX 9 для win-7.<br /></p><div class="codebox"><pre><code>file := &quot;test.mp4&quot;
video_bitrate := 2000000
video_fps := 25
duration := 5
capture_cursor := true
audiodevice := &quot;CABLE Output (VB-Audio Virtual Cable)&quot;
audioDelay := 80
; x1 := 100, x2 := 1000, y1 := 100, y2 := 500
; ShowAllAudioDevicesNames := true
; CaptureCoordinatesWithCPU := true
; Rotate := true
; UseSoftwareEncoding := true


setbatchlines -1
Global pSinkWriter, SourceReader, audioStreamIndex, Flush, IMFSourceReaderCallback, IMFTransform, pTransform, MFT_OUTPUT_DATA_BUFFER, cbOutBytes
d3d := Direct3DCreate9(D3D_SDK_VERSION := 32) 
if !d3d
{
    MsgBox, 16, Error, Direct3DCreate9 failed.
    ExitApp
}
VarSetCapacity(D3DDISPLAYMODE, 16, 0)
IDirect3D9_GetAdapterDisplayMode(d3d, D3DADAPTER_DEFAULT := 0, &amp;D3DDISPLAYMODE)
Windowed := true
BackBufferCount := 1
height := NumGet(D3DDISPLAYMODE, 4, &quot;uint&quot;)
width := NumGet(D3DDISPLAYMODE, 0, &quot;uint&quot;)
SwapEffect := 1   ; D3DSWAPEFFECT_DISCARD
hDeviceWindow := 0
VarSetCapacity(D3DPRESENT_PARAMETERS, 48+2*A_PtrSize, 0) 
NumPut(width, D3DPRESENT_PARAMETERS, 0)
NumPut(height, D3DPRESENT_PARAMETERS, 4)
NumPut(BackBufferCount, D3DPRESENT_PARAMETERS, 12)
NumPut(SwapEffect, D3DPRESENT_PARAMETERS, 24)
NumPut(hDeviceWindow, D3DPRESENT_PARAMETERS, 24+A_PtrSize)
NumPut(Windowed, D3DPRESENT_PARAMETERS, 24+2*A_PtrSize)
IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT := 0, D3DDEVTYPE_HAL := 1, 0, D3DCREATE_SOFTWARE_VERTEXPROCESSING := 0x00000020, &amp;D3DPRESENT_PARAMETERS, device)
IDirect3DDevice9_CreateOffscreenPlainSurface(device, width, height, D3DFMT_A8R8G8B8 := 21, D3DPOOL_SYSTEMMEM := 2, surface, 0)
Release(d3d)
d3d := &quot;&quot;

LOAD_DLL_Mf_Mfplat_Mfreadwrite()
MFStartup(version := 2, MFSTARTUP_FULL := 0)
if (ShowAllAudioDevicesNames != 1)
{
   if (UseSoftwareEncoding != 1)
   {
      VarSetCapacity(MFT_REGISTER_TYPE_INFO, 32, 0)
      DllCall(&quot;RtlMoveMemory&quot;, &quot;ptr&quot;, &amp;MFT_REGISTER_TYPE_INFO, &quot;ptr&quot;, MF_GUID(GUID, &quot;MFMediaType_Video&quot;), &quot;ptr&quot;, 16)
      DllCall(&quot;RtlMoveMemory&quot;, &quot;ptr&quot;, &amp;MFT_REGISTER_TYPE_INFO + 16, &quot;ptr&quot;, MF_GUID(GUID, &quot;MFVideoFormat_H264&quot;), &quot;ptr&quot;, 16)
      hardware_encoder := MFTEnumEx(MF_GUID(GUID, &quot;MFT_CATEGORY_VIDEO_ENCODER&quot;), MFT_ENUM_FLAG_HARDWARE := 0x04|MFT_ENUM_FLAG_SORTANDFILTER := 0x40, 0, &amp;MFT_REGISTER_TYPE_INFO)
   }
   if (x1 != &quot;&quot;)
   {
      checkCoordinates(x1, x2, y1, y2, hardware_encoder)
      width := x2-x1
      height := y2-y1
      VarSetCapacity(RECT, 16, 0)
      NumPut(x1, RECT, 0, &quot;int&quot;)
      NumPut(y1, RECT, 4, &quot;int&quot;)
      NumPut(x2, RECT, 8, &quot;int&quot;)
      NumPut(y2, RECT, 12, &quot;int&quot;)
   }
   if (hardware_encoder != &quot;&quot;)
   {
      MFCreateAttributes(pMFAttributes, 4)
      IMFAttributes_SetUINT32(pMFAttributes, MF_GUID(GUID, &quot;MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS&quot;), true)
   }
   else
      MFCreateAttributes(pMFAttributes, 3)
   IMFAttributes_SetGUID(pMFAttributes, MF_GUID(GUID, &quot;MF_TRANSCODE_CONTAINERTYPE&quot;), MF_GUID(GUID1, &quot;MFTranscodeContainerType_MPEG4&quot;))
   IMFAttributes_SetUINT32(pMFAttributes, MF_GUID(GUID, &quot;MF_SINK_WRITER_DISABLE_THROTTLING&quot;), true)
   IMFAttributes_SetUINT32(pMFAttributes, MF_GUID(GUID, &quot;MF_LOW_LATENCY&quot;), true)
   MFCreateSinkWriterFromURL(file, 0, pMFAttributes, pSinkWriter)
   Release(pMFAttributes)
   pMFAttributes := &quot;&quot;

   loop 2   ; 1 - input, 2 - output
   {
      MFCreateMediaType(pMediaType%A_Index%)
      IMFAttributes_SetGUID(pMediaType%A_Index%, MF_GUID(GUID, &quot;MF_MT_MAJOR_TYPE&quot;), MF_GUID(GUID1, &quot;MFMediaType_Video&quot;))
      if (A_Index = 1)
      {
         if (A_OSVersion = &quot;WIN_7&quot;) or !InStr(hardware_encoder, &quot;NVIDIA&quot;) or ((x1 != &quot;&quot;) and (CaptureCoordinatesWithCPU = true))
            IMFAttributes_SetGUID(pMediaType%A_Index%, MF_GUID(GUID, &quot;MF_MT_SUBTYPE&quot;), MF_GUID(GUID1, &quot;MFVideoFormat_RGB32&quot;))
         else
            IMFAttributes_SetGUID(pMediaType%A_Index%, MF_GUID(GUID, &quot;MF_MT_SUBTYPE&quot;), MF_GUID(GUID1, &quot;MFVideoFormat_ARGB32&quot;))
      }
      else
      {
         IMFAttributes_SetGUID(pMediaType%A_Index%, MF_GUID(GUID, &quot;MF_MT_SUBTYPE&quot;), MF_GUID(GUID1, &quot;MFVideoFormat_H264&quot;))
         IMFAttributes_SetUINT32(pMediaType%A_Index%, MF_GUID(GUID, &quot;MF_MT_AVG_BITRATE&quot;), video_bitrate)
      }
      IMFAttributes_SetUINT32(pMediaType%A_Index%, MF_GUID(GUID, &quot;MF_MT_INTERLACE_MODE&quot;), MFVideoInterlace_Progressive := 2)
      IMFAttributes_SetUINT64(pMediaType%A_Index%, MF_GUID(GUID, &quot;MF_MT_FRAME_SIZE&quot;), (width&lt;&lt;32)|height)
      IMFAttributes_SetUINT64(pMediaType%A_Index%, MF_GUID(GUID, &quot;MF_MT_FRAME_RATE&quot;), (video_fps&lt;&lt;32)|1)
      IMFAttributes_SetUINT64(pMediaType%A_Index%, MF_GUID(GUID, &quot;MF_MT_PIXEL_ASPECT_RATIO&quot;), (1&lt;&lt;32)|1)
   }
   IMFSinkWriter_AddStream(pSinkWriter, pMediaType2, videoStreamIndex)
   IMFSinkWriter_SetInputMediaType(pSinkWriter, videoStreamIndex, pMediaType1, 0)
   Release(pMediaType1)
   Release(pMediaType2)
   pMediaType1 := pMediaType2 := &quot;&quot;
}

if (audiodevice != &quot;&quot;) or (ShowAllAudioDevicesNames = 1)
{
   NUM_CHANNELSMax := BITS_PER_SAMPLEMax := SAMPLES_PER_SECONDMax := BYTES_PER_SECONDMax := StreamNumberAudio := TypeNumberAudio := AudioSources := &quot;&quot;
   audiobasedevice := audiodevice
   IMFSourceReaderCallback := IMFSourceReaderCallback_new()
   MFCreateAttributes(pMFAttributes, 1)
   IMFAttributes_SetGUID(pMFAttributes, MF_GUID(GUID, &quot;MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE&quot;), MF_GUID(GUID1, &quot;MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_GUID&quot;))
   MFEnumDeviceSources(pMFAttributes, pppSourceActivate, pcSourceActivate)
   Loop % pcSourceActivate
   {
      IMFActivate := NumGet(pppSourceActivate + (A_Index - 1)*A_PtrSize)
      devicename := IMFActivate_GetAllocatedString(IMFActivate, MF_GUID(GUID, &quot;MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME&quot;))
      if (ShowAllAudioDevicesNames = 1)
      {
         basedevicename := devicename
         loop
         {
            if !InStr(Audiodevicenames, &quot;&quot;&quot;&quot; devicename &quot;&quot;&quot;`r`n&quot;)
               break
            devicename := basedevicename &quot;[&quot; A_Index+1 &quot;]&quot;
         }
         Audiodevicenames .= &quot;&quot;&quot;&quot; devicename &quot;&quot;&quot;`r`n&quot;
      }
      else
      {
         if RegexMatch(audiodevice, &quot;\[(\d)]$&quot;, match) and (devicename = RegexReplace(audiodevice, &quot;\[\d]$&quot;))
         {
            match1--
            if (match1 = 0)
               audiodevice := devicename
            else
               audiodevice := devicename &quot;[&quot; match1 &quot;]&quot;
         }
         if (devicename = audiodevice) and (MediaSourceAudio = &quot;&quot;)
            IMFActivate_ActivateObject(IMFActivate, IMFMediaSource := &quot;{279a808d-aec7-40c8-9c6b-a6b492c78a66}&quot;, MediaSourceAudio)
      }
      Release(IMFActivate)
      IMFActivate := &quot;&quot;
   }
   DllCall(&quot;ole32\CoTaskMemFree&quot;, &quot;ptr&quot;, pppSourceActivate)
   Release(pMFAttributes)
   pMFAttributes := &quot;&quot;
   if (ShowAllAudioDevicesNames = 1)
   {
      if (Audiodevicenames = &quot;&quot;)
         Audiodevicenames .= &quot;None&quot;
      msgbox % clipboard := &quot;Audio:`r`n&quot; Audiodevicenames
      ExitApp
   }
   if (MediaSourceAudio = &quot;&quot;)
   {
      msgbox % &quot;Cannot find Audio device - &quot;&quot;&quot; audiobasedevice &quot;&quot;&quot;&quot;
      ExitApp
   }
   MFCreateAttributes(pMFAttributes, 1)
   IMFAttributes_SetUnknown(pMFAttributes, MF_GUID(GUID, &quot;MF_SOURCE_READER_ASYNC_CALLBACK&quot;), IMFSourceReaderCallback)
   MFCreateSourceReaderFromMediaSource(MediaSourceAudio, pMFAttributes, SourceReader)
   loop
   {
      n := A_Index - 1
      if (IMFSourceReader_GetNativeMediaType(SourceReader, n, 0, ppMediaType) = &quot;MF_E_INVALIDSTREAMNUMBER&quot;)
         break
      Release(ppMediaType)
      ppMediaType := &quot;&quot;
      loop
      {
         k := A_Index - 1
         if (IMFSourceReader_GetNativeMediaType(SourceReader, n, k, ppMediaType) = &quot;MF_E_NO_MORE_TYPES&quot;)
            break
         IMFAttributes_GetGUID(ppMediaType, MF_GUID(GUID, &quot;MF_MT_MAJOR_TYPE&quot;), pguidValue)
         if (MemoryDifference(&amp;pguidValue, MF_GUID(GUID, &quot;MFMediaType_Audio&quot;), 16) = 0)
         {
            IMFAttributes_GetGUID(ppMediaType, MF_GUID(GUID, &quot;MF_MT_SUBTYPE&quot;), pguidValueSubType)
            AudioSources .= Format(&quot;0x{:x}&quot;, NumGet(pguidValueSubType, 0, &quot;int&quot;)) &quot;`n&quot;
            if (MemoryDifference(&amp;pguidValueSubType, MF_GUID(GUID, &quot;MFAudioFormat_PCM&quot;), 16) = 0) or (MemoryDifference(&amp;pguidValueSubType, MF_GUID(GUID, &quot;MFAudioFormat_Float&quot;), 16) = 0)
            {
               if (IMFAttributes_GetUINT32(ppMediaType, MF_GUID(GUID, &quot;MF_MT_AUDIO_AVG_BYTES_PER_SECOND&quot;), BYTES_PER_SECOND) = &quot;MF_E_ATTRIBUTENOTFOUND&quot;)
                  BYTES_PER_SECOND := 0
               if (IMFAttributes_GetUINT32(ppMediaType, MF_GUID(GUID, &quot;MF_MT_AUDIO_BITS_PER_SAMPLE&quot;), BITS_PER_SAMPLE) = &quot;MF_E_ATTRIBUTENOTFOUND&quot;)
                  BITS_PER_SAMPLE := 0
               if (IMFAttributes_GetUINT32(ppMediaType, MF_GUID(GUID, &quot;MF_MT_AUDIO_SAMPLES_PER_SECOND&quot;), SAMPLES_PER_SECOND) = &quot;MF_E_ATTRIBUTENOTFOUND&quot;)
                  SAMPLES_PER_SECOND := 0
               if (IMFAttributes_GetUINT32(ppMediaType, MF_GUID(GUID, &quot;MF_MT_AUDIO_NUM_CHANNELS&quot;), NUM_CHANNELS) = &quot;MF_E_ATTRIBUTENOTFOUND&quot;)
                  NUM_CHANNELS := 0
               if (InStr(A_OSVersion, &quot;W&quot;) and (((NUM_CHANNELSMax != 1) and (NUM_CHANNELSMax != 2) and (NUM_CHANNELS &gt; 0)) or ((NUM_CHANNELSMax = 1) and (NUM_CHANNELS = 2)))) or (!InStr(A_OSVersion, &quot;W&quot;) and (((NUM_CHANNELSMax &lt; 2) and (NUM_CHANNELS &gt; NUM_CHANNELSMax)) or ((NUM_CHANNELSMax = 2) and (NUM_CHANNELS = 6)) or ((NUM_CHANNELSMax &gt; 2) and (NUM_CHANNELSMax != 6) and ((NUM_CHANNELS = 2) or (NUM_CHANNELS = 6))))) or ((NUM_CHANNELS = NUM_CHANNELSMax) and (BITS_PER_SAMPLEMax != 16) and ((BITS_PER_SAMPLE = 16) or (BITS_PER_SAMPLE &gt; BITS_PER_SAMPLEMax))) or ((NUM_CHANNELS = NUM_CHANNELSMax) and (BITS_PER_SAMPLE = BITS_PER_SAMPLEMax) and (SAMPLES_PER_SECONDMax != 44100) and (SAMPLES_PER_SECONDMax != 48000) and ((SAMPLES_PER_SECOND = 44100) or (SAMPLES_PER_SECOND &gt; SAMPLES_PER_SECONDMax))) or ((SAMPLES_PER_SECONDMax != 48000) and (SAMPLES_PER_SECOND = 48000)) or ((NUM_CHANNELS = NUM_CHANNELSMax) and (BITS_PER_SAMPLE = BITS_PER_SAMPLEMax) and (SAMPLES_PER_SECOND = SAMPLES_PER_SECONDMax) and (BYTES_PER_SECOND &gt; BYTES_PER_SECONDMax))
               {
                  if (MemoryDifference(&amp;pguidValueSubType, MF_GUID(GUID, &quot;MFAudioFormat_PCM&quot;), 16) = 0)
                     MFAudioFormat := &quot;MFAudioFormat_PCM&quot;
                  else
                     MFAudioFormat := &quot;MFAudioFormat_Float&quot; 
                  NUM_CHANNELSMax := NUM_CHANNELS
                  BITS_PER_SAMPLEMax := BITS_PER_SAMPLE
                  SAMPLES_PER_SECONDMax := SAMPLES_PER_SECOND
                  BYTES_PER_SECONDMax := BYTES_PER_SECOND
                  StreamNumberAudio := n
                  TypeNumberAudio := k
               }
            }
         }
         Release(ppMediaType)
         ppMediaType := &quot;&quot;
      }
   }
   if (StreamNumberAudio = &quot;&quot;)
   {
      Sort, AudioSources, U
      msgbox % &quot;Current AudioSources not supported:`n&quot; AudioSources
      ExitApp
   }
   IMFSourceReader_SetStreamSelection(SourceReader, MF_SOURCE_READER_ALL_STREAMS := 0xFFFFFFFE, false)
   IMFSourceReader_SetStreamSelection(SourceReader, StreamNumberAudio, true)
   Release(pMFAttributes)
   pMFAttributes := &quot;&quot;
   if (NUM_CHANNELSMax = 0)
      NUM_CHANNELS := 1
   else if (NUM_CHANNELSMax &gt; 2) and (NUM_CHANNELSMax &lt; 6)
      NUM_CHANNELS := 2
   else if (NUM_CHANNELSMax &gt;= 6)
   {
      if !InStr(A_OSVersion, &quot;W&quot;)
         NUM_CHANNELS := 6
      else
         NUM_CHANNELS := 2
   }
   if (SAMPLES_PER_SECONDMax &lt; 44100)
      SAMPLES_PER_SECOND := 44100
   else if (SAMPLES_PER_SECONDMax &gt; 44100)
      SAMPLES_PER_SECOND := 48000
   loop 2   ; 1 - input, 2 - output
   {
      MFCreateMediaType(pMediaTypeAudio%A_Index%)
      IMFAttributes_SetGUID(pMediaTypeAudio%A_Index%, MF_GUID(GUID, &quot;MF_MT_MAJOR_TYPE&quot;), MF_GUID(GUID1, &quot;MFMediaType_Audio&quot;))
      if (A_Index = 1)
         IMFAttributes_SetGUID(pMediaTypeAudio%A_Index%, MF_GUID(GUID, &quot;MF_MT_SUBTYPE&quot;), MF_GUID(GUID1, &quot;MFAudioFormat_PCM&quot;))
      else
      {
         IMFAttributes_SetGUID(pMediaTypeAudio%A_Index%, MF_GUID(GUID, &quot;MF_MT_SUBTYPE&quot;), MF_GUID(GUID1, &quot;MFAudioFormat_AAC&quot;))
         IMFAttributes_SetUINT32(pMediaTypeAudio%A_Index%, MF_GUID(GUID, &quot;MF_MT_AUDIO_AVG_BYTES_PER_SECOND&quot;), 20000)
      }
      IMFAttributes_SetUINT32(pMediaTypeAudio%A_Index%, MF_GUID(GUID, &quot;MF_MT_AUDIO_BITS_PER_SAMPLE&quot;), 16)
      IMFAttributes_SetUINT32(pMediaTypeAudio%A_Index%, MF_GUID(GUID, &quot;MF_MT_AUDIO_SAMPLES_PER_SECOND&quot;), SAMPLES_PER_SECOND)
      IMFAttributes_SetUINT32(pMediaTypeAudio%A_Index%, MF_GUID(GUID, &quot;MF_MT_AUDIO_NUM_CHANNELS&quot;), NUM_CHANNELS)
   }
   IMFSinkWriter_AddStream(pSinkWriter, pMediaTypeAudio2, audioStreamIndex)
   IMFSinkWriter_SetInputMediaType(pSinkWriter, audioStreamIndex, pMediaTypeAudio1, 0)
   if (IMFSourceReader_SetCurrentMediaType(SourceReader, StreamNumberAudio, 0, pMediaTypeAudio1) = &quot;MF_E_TOPO_CODEC_NOT_FOUND&quot;)
   {
      LOAD_DLL_Resampledmo_Mfaacenc()
      IMFTransform := 1
      cbOutBytes := 100000
      loop 2   ; 1 - input, 2 - output
      {
         MFCreateMediaType(pMedia%A_Index%)
         IMFAttributes_SetGUID(pMedia%A_Index%, MF_GUID(GUID, &quot;MF_MT_MAJOR_TYPE&quot;), MF_GUID(GUID1, &quot;MFMediaType_Audio&quot;))
         IMFAttributes_SetGUID(pMedia%A_Index%, MF_GUID(GUID, &quot;MF_MT_SUBTYPE&quot;), MF_GUID(GUID1, MFAudioFormat))
         IMFAttributes_SetUINT32(pMedia%A_Index%, MF_GUID(GUID, &quot;MF_MT_AUDIO_BITS_PER_SAMPLE&quot;), BITS_PER_SAMPLEMax)
         IMFAttributes_SetUINT32(pMedia%A_Index%, MF_GUID(GUID, &quot;MF_MT_AUDIO_NUM_CHANNELS&quot;), NUM_CHANNELSMax)
         IMFAttributes_SetUINT32(pMedia%A_Index%, MF_GUID(GUID, &quot;MF_MT_AUDIO_SAMPLES_PER_SECOND&quot;), SAMPLES_PER_SECONDMax)
         IMFAttributes_SetUINT32(pMedia%A_Index%, MF_GUID(GUID, &quot;MF_MT_AUDIO_BLOCK_ALIGNMENT&quot;), NUM_CHANNELSMax*BITS_PER_SAMPLEMax//8)
         IMFAttributes_SetUINT32(pMedia%A_Index%, MF_GUID(GUID, &quot;MF_MT_AUDIO_AVG_BYTES_PER_SECOND&quot;), SAMPLES_PER_SECONDMax*NUM_CHANNELSMax*BITS_PER_SAMPLEMax//8)
         IMFAttributes_SetUINT32(pMedia%A_Index%, MF_GUID(GUID, &quot;MF_MT_ALL_SAMPLES_INDEPENDENT&quot;), true)
         if (A_Index = 1)
            MFAudioFormat := &quot;MFAudioFormat_PCM&quot;, BITS_PER_SAMPLEMax := 16, NUM_CHANNELSMax := NUM_CHANNELS, SAMPLES_PER_SECONDMax := SAMPLES_PER_SECOND
      }
      spTransformUnk := ComObjCreate(CLSID_CResamplerMediaObject := &quot;{f447b69e-1884-4a7e-8055-346f74d6edb3}&quot;, IID_IUnknown := &quot;{00000000-0000-0000-C000-000000000046}&quot;)
      pTransform := ComObjQuery(spTransformUnk, IID_IMFTransform := &quot;{bf94c121-5b05-4e6f-8000-ba598961414d}&quot;)
      spResamplerProps := ComObjQuery(spTransformUnk, IID_IWMResamplerProps := &quot;{E7E9984F-F09F-4da4-903F-6E2E0EFE56B5}&quot;)
      IWMResamplerProps_SetHalfFilterLength(spResamplerProps, 60)
      IMFTransform_SetInputType(pTransform, 0, pMedia1, 0)
      IMFTransform_SetOutputType(pTransform, 0, pMedia2, 0)
      IMFTransform_GetInputStatus(pTransform, 0, mftStatus)
      if (mftStatus != 1)   ; MFT_INPUT_STATUS_ACCEPT_DATA
      {
         msgbox IMFTransform_GetInputStatus not accept data
         ExitApp
      }
      IMFTransform_ProcessMessage(pTransform, MFT_MESSAGE_COMMAND_FLUSH := 0, 0)
      IMFTransform_ProcessMessage(pTransform, MFT_MESSAGE_NOTIFY_BEGIN_STREAMING := 0x10000000, 0)
      IMFTransform_ProcessMessage(pTransform, MFT_MESSAGE_NOTIFY_START_OF_STREAM := 0x10000003, 0)
      Release(pMedia1)
      Release(pMedia2)
      pMedia1 := pMedia2 := &quot;&quot;
   }
   Release(pMediaTypeAudio1)
   Release(pMediaTypeAudio2)
   pMediaTypeAudio1 := pMediaTypeAudio2 := &quot;&quot;
}
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
CaptureDuration := duration*1000 - 2*fps
VarSetCapacity(TIMECAPS, 8, 0)
DllCall(&quot;winmm\timeGetDevCaps&quot;, &quot;ptr&quot;, &amp;TIMECAPS, &quot;uint&quot;, 8)
uPeriod := NumGet(TIMECAPS, 0, &quot;uint&quot;)
DllCall(&quot;Winmm\timeBeginPeriod&quot;, &quot;uint&quot;, uPeriod)

msgbox % &quot;hardware-encoder - &quot; ((hardware_encoder != &quot;&quot;) ? hardware_encoder : &quot;none&quot;)
loop
{
   if (A_Index = 1)
   {
      if (audiodevice != &quot;&quot;)
      {
         IMFSourceReader_ReadSample(SourceReader, MF_SOURCE_READER_ANY_STREAM := 0xFFFFFFFE, 0, 0, 0, 0, 0)
         if (audioDelay &gt; 0)
            DllCall(&quot;Sleep&quot;, &quot;uint&quot;, audioDelay)
      }
      DllCall(&quot;QueryPerformanceCounter&quot;, &quot;int64*&quot;, start)
      DllCall(&quot;QueryPerformanceFrequency&quot;, &quot;int64*&quot;, freq)
   }
   else
   {
      DllCall(&quot;QueryPerformanceCounter&quot;, &quot;int64*&quot;, ATickCount)
      sleepDuration := fps*(A_Index-1) - (ATickCount - start)*1000/freq
      SleepEnd := ATickCount + sleepDuration*freq/1000
      sleep % sleepDuration - 15
      DllCall(&quot;QueryPerformanceCounter&quot;, &quot;int64*&quot;, ATickCount)
      if (ATickCount &lt; SleepEnd)
         DllCall(&quot;Sleep&quot;, &quot;uint&quot;, (SleepEnd - ATickCount)*1000/freq)
   }

   IDirect3DDevice9_GetFrontBufferData(device, 0, surface)
   if (capture_cursor = true)
   {
      VarSetCapacity(CURSORINFO, cbSize := 16 + A_PtrSize, 0)
      NumPut(cbSize, CURSORINFO, 0, &quot;uint&quot;)
      if DllCall(&quot;GetCursorInfo&quot;, &quot;ptr&quot;, &amp;CURSORINFO) and (NumGet(CURSORINFO, 4, &quot;uint&quot;) = 1)   ; CURSOR_SHOWING
      {
         hCursor := NumGet(CURSORINFO, 8)
         xCursor := NumGet(CURSORINFO, 8 + A_PtrSize, &quot;int&quot;)
         yCursor := NumGet(CURSORINFO, 12 + A_PtrSize, &quot;int&quot;)
         VarSetCapacity(ICONINFO, 8 + A_PtrSize*3, 0)
         DllCall(&quot;GetIconInfo&quot;, &quot;ptr&quot;, hCursor, &quot;ptr&quot;, &amp;ICONINFO)
         xHotspot := NumGet(ICONINFO, 4, &quot;uint&quot;)
         yHotspot := NumGet(ICONINFO, 8, &quot;uint&quot;)
         hbmMask  := NumGet(ICONINFO, 8 + A_PtrSize)
         hbmColor := NumGet(ICONINFO, 8 + A_PtrSize*2)
         IDirect3DSurface9_GetDC(surface, hdc)
         DllCall(&quot;DrawIconEx&quot;, &quot;ptr&quot;, hdc, &quot;int&quot;, xCursor - xHotspot, &quot;int&quot;, yCursor - yHotspot, &quot;ptr&quot;, hCursor, &quot;int&quot;, 0, &quot;int&quot;, 0, &quot;uint&quot;, 0, &quot;ptr&quot;, 0, &quot;uint&quot;, DI_NORMAL := 0x0003 | DI_DEFAULTSIZE := 0x0008)
         if hbmMask
            DllCall(&quot;DeleteObject&quot;, &quot;ptr&quot;, hbmMask)
         if hbmColor
            DllCall(&quot;DeleteObject&quot;, &quot;ptr&quot;, hbmColor)
         hbmMask := hbmColor := &quot;&quot;
         IDirect3DSurface9_ReleaseDC(surface, hdc)
      }
   }
   VarSetCapacity(D3DLOCKED_RECT, A_PtrSize*2, 0)
   if (x1 = &quot;&quot;)
      IDirect3DSurface9_LockRect(surface, &amp;D3DLOCKED_RECT, 0, 0)
   else
      IDirect3DSurface9_LockRect(surface, &amp;D3DLOCKED_RECT, &amp;RECT, 0)
   pitch := NumGet(D3DLOCKED_RECT, 0, &quot;int&quot;)
   pBits := NumGet(D3DLOCKED_RECT, A_PtrSize, &quot;ptr&quot;)

   MFCreateMemoryBuffer(cbBuffer, pBuffer)
   IMFMediaBuffer_Lock(pBuffer, pData, 0, 0)
   if (A_OSVersion = &quot;WIN_7&quot;) or !InStr(hardware_encoder, &quot;NVIDIA&quot;) or ((x1 != &quot;&quot;) and (CaptureCoordinatesWithCPU = true)) or (Rotate = true)
      MFCopyImage(pData, cbWidth, pBits+(height-1)*pitch, pitch*-1, cbWidth, height)
   else
      MFCopyImage(pData, cbWidth, pBits, pitch, 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)

   IDirect3DSurface9_UnlockRect(surface)
   Release(pSample)
   Release(pBuffer)
   pSample := pBuffer := &quot;&quot;
   if ((ATickCount - start)/freq*1000 &gt;= CaptureDuration)
   {
      video_frame_countReal := A_Index
      if (audiodevice != &quot;&quot;)
      {
         flush := 1
         loop
         {
            if (flush = &quot;&quot;)
               break
            sleep 50
         }
      }
      break
   }
   rtStart += video_frame_duration
}
IMFSinkWriter_Finalize(pSinkWriter)
DllCall(&quot;Winmm\timeEndPeriod&quot;, &quot;uint&quot;, uPeriod)
if (audiodevice != &quot;&quot;)
{
   if (IMFTransform = 1)
   {
      Release(spResamplerProps)
      Release(pTransform)
      Release(spTransformUnk)
      spResamplerProps := pTransform := spTransformUnk := IMFTransform := &quot;&quot;
   }
   Release(MediaSourceAudio)
   MediaSourceAudio := &quot;&quot;
}
Release(pSinkWriter)
Release(surface)
Release(device)
pSinkWriter := surface := device := &quot;&quot;
MFShutdown()
msgbox % &quot;done`n&quot; video_frame_countReal &quot; captured`n&quot; video_frame_count-video_frame_countReal &quot; frames dropped&quot;
ExitApp





Direct3DCreate9(SDKVersion) {
    if !DllCall(&quot;GetModuleHandle&quot;,&quot;str&quot;,&quot;d3d9&quot;)
        DllCall(&quot;LoadLibrary&quot;,&quot;str&quot;,&quot;d3d9&quot;)
    return DllCall(&quot;d3d9\Direct3DCreate9&quot;, &quot;uint&quot;, SDKVersion)
}

IDirect3D9_GetAdapterDisplayMode(this,Adapter,pMode)
{
   hr := DllCall(NumGet(NumGet(this+0)+8*A_PtrSize),&quot;ptr&quot;,this,&quot;uint&quot;,Adapter,&quot;ptr&quot;,pMode)
   if hr or ErrorLevel
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
}

IDirect3D9_CreateDevice(this,Adapter,DeviceType,hFocusWindow,BehaviorFlags,pPresentationParameters,ByRef ppReturnedDeviceInterface)
{
   hr := DllCall(NumGet(NumGet(this+0)+16*A_PtrSize),&quot;ptr&quot;,this,&quot;uint&quot;,Adapter,&quot;uint&quot;,DeviceType,&quot;ptr&quot;,hFocusWindow,&quot;uint&quot;,BehaviorFlags,&quot;ptr&quot;,pPresentationParameters,&quot;ptr*&quot;,ppReturnedDeviceInterface)
   if hr or ErrorLevel
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
}

IDirect3DDevice9_GetFrontBufferData(this,iSwapChain,pDestSurface)
{
   hr := DllCall(NumGet(NumGet(this+0)+33*A_PtrSize),&quot;ptr&quot;,this,&quot;uint&quot;,iSwapChain,&quot;ptr&quot;,pDestSurface)
   if hr or ErrorLevel
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
}

IDirect3DDevice9_CreateOffscreenPlainSurface(this,Width,Height,Format,Pool,ByRef ppSurface,pSharedHandle)
{
   hr := DllCall(NumGet(NumGet(this+0)+36*A_PtrSize),&quot;ptr&quot;,this,&quot;uint&quot;,Width,&quot;uint&quot;,Height,&quot;uint&quot;,Format,&quot;uint&quot;,Pool,&quot;ptr*&quot;,ppSurface,&quot;ptr&quot;,pSharedHandle)
   if hr or ErrorLevel
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
}

IDirect3DSurface9_LockRect(this,pLockedRect,pRect,Flags)
{
   hr := DllCall(NumGet(NumGet(this+0)+13*A_PtrSize),&quot;ptr&quot;,this,&quot;ptr&quot;,pLockedRect,&quot;ptr&quot;,pRect,&quot;uint&quot;,Flags)
   if hr or ErrorLevel
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
}

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

IDirect3DSurface9_GetDC(this, ByRef phdc)
{
   hr := DllCall(NumGet(NumGet(this+0)+15*A_PtrSize),&quot;ptr&quot;,this,&quot;ptr*&quot;,phdc)
   if hr or ErrorLevel
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
}

IDirect3DSurface9_ReleaseDC(this,phdc)
{
   hr := DllCall(NumGet(NumGet(this+0)+16*A_PtrSize),&quot;ptr&quot;,this,&quot;ptr&quot;,phdc)
   if hr or ErrorLevel
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
}



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

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

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

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

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

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

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

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

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

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

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

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

MFCreateCollection(ByRef ppIMFCollection)
{
   hr := DllCall(&quot;Mfplat.dll\MFCreateCollection&quot;, &quot;ptr*&quot;, ppIMFCollection)
   if hr or ErrorLevel
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
}

MFCreateAggregateSource(pSourceCollection, ByRef ppAggSource)
{
   hr := DllCall(&quot;Mf.dll\MFCreateAggregateSource&quot;, &quot;ptr&quot;, pSourceCollection, &quot;ptr*&quot;, ppAggSource)
   if hr or ErrorLevel
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
}

IMFSourceReader_SetCurrentMediaType(this, dwStreamIndex, pdwReserved, pMediaType)
{
   hr := DllCall(NumGet(NumGet(this+0)+7*A_PtrSize), &quot;ptr&quot;, this, &quot;uint&quot;, dwStreamIndex, &quot;uint&quot;, pdwReserved, &quot;ptr&quot;, pMediaType)
   if hr or ErrorLevel
   {
      if !ErrorLevel
      {
         if (hr&amp;=0xFFFFFFFF) = 0xC00D5212   ; MF_E_TOPO_CODEC_NOT_FOUND
            return &quot;MF_E_TOPO_CODEC_NOT_FOUND&quot;
      }
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
   }
}

IMFSourceReader_SetStreamSelection(this, dwStreamIndex, fSelected)
{
   hr := DllCall(NumGet(NumGet(this+0)+4*A_PtrSize), &quot;ptr&quot;, this, &quot;uint&quot;, dwStreamIndex, &quot;int&quot;, fSelected)
   if hr or ErrorLevel
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
}

IMFSourceReader_GetNativeMediaType(this, dwStreamIndex, dwMediaTypeIndex, ByRef ppMediaType)
{
   hr := DllCall(NumGet(NumGet(this+0)+5*A_PtrSize), &quot;ptr&quot;, this, &quot;uint&quot;, dwStreamIndex, &quot;uint&quot;, dwMediaTypeIndex, &quot;ptr*&quot;, ppMediaType)
   if hr or ErrorLevel
   {
      if !ErrorLevel
      {
         if (hr&amp;=0xFFFFFFFF) = 0xC00D36B3   ; MF_E_INVALIDSTREAMNUMBER
            return &quot;MF_E_INVALIDSTREAMNUMBER&quot;
         if (hr&amp;=0xFFFFFFFF) = 0xC00D36B9   ; MF_E_NO_MORE_TYPES
            return &quot;MF_E_NO_MORE_TYPES&quot;
      }
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
   }
}

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

IMFSourceReader_Flush(this, dwStreamIndex)
{
   hr := DllCall(NumGet(NumGet(this+0)+10*A_PtrSize), &quot;ptr&quot;, this, &quot;uint&quot;, dwStreamIndex)
   if hr or ErrorLevel
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
}

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

IMFAttributes_GetUINT64(this, guidKey, ByRef punValue)
{
   hr := DllCall(NumGet(NumGet(this+0)+8*A_PtrSize), &quot;ptr&quot;, this, &quot;ptr&quot;, guidKey, &quot;uint64*&quot;, punValue)
   if hr or ErrorLevel
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
}

IMFAttributes_GetUINT32(this, guidKey, ByRef punValue)
{
   hr := DllCall(NumGet(NumGet(this+0)+7*A_PtrSize), &quot;ptr&quot;, this, &quot;ptr&quot;, guidKey, &quot;uint*&quot;, punValue)
   if hr or ErrorLevel
   {
      if !ErrorLevel
      {
         if (hr&amp;=0xFFFFFFFF) = 0xC00D36E6   ; MF_E_ATTRIBUTENOTFOUND
            return &quot;MF_E_ATTRIBUTENOTFOUND&quot;
      }
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
   }
}

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

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

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

IMFAttributes_SetUnknown(this, guidKey, pUnknown)
{
   hr := DllCall(NumGet(NumGet(this+0)+27*A_PtrSize), &quot;ptr&quot;, this, &quot;ptr&quot;, guidKey, &quot;ptr&quot;, pUnknown)
   if hr or ErrorLevel
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
}

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

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

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

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

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

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

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

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

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

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

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

IMFMediaSource_Shutdown(this)
{
   hr := DllCall(NumGet(NumGet(this+0)+12*A_PtrSize), &quot;ptr&quot;, this)
   if hr or ErrorLevel
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
}

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

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

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

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

IMFCollection_AddElement(this, pUnkElement)
{
   hr := DllCall(NumGet(NumGet(this+0)+5*A_PtrSize), &quot;ptr&quot;, this, &quot;ptr&quot;, pUnkElement)
   if hr or ErrorLevel
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
}

LOAD_DLL_Resampledmo_Mfaacenc()
{
   if !DllCall(&quot;GetModuleHandle&quot;,&quot;str&quot;,&quot;Resampledmo&quot;)
      DllCall(&quot;LoadLibrary&quot;,&quot;Str&quot;, &quot;Resampledmo.dll&quot;, &quot;ptr&quot;)
   if !DllCall(&quot;GetModuleHandle&quot;,&quot;str&quot;,&quot;Mfaacenc&quot;)
      DllCall(&quot;LoadLibrary&quot;,&quot;Str&quot;, &quot;Mfaacenc.dll&quot;, &quot;ptr&quot;)
}

IMFTransform_GetInputStatus(this, dwInputStreamID, ByRef pdwFlags)
{
   hr := DllCall(NumGet(NumGet(this+0)+19*A_PtrSize), &quot;ptr&quot;, this, &quot;uint&quot;, dwInputStreamID, &quot;uint*&quot;, pdwFlags)
   if hr or ErrorLevel
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
}

IMFTransform_ProcessMessage(this, eMessage, ulParam)
{
   hr := DllCall(NumGet(NumGet(this+0)+23*A_PtrSize), &quot;ptr&quot;, this, &quot;uint&quot;, eMessage, &quot;uint&quot;, ulParam)
   if hr or ErrorLevel
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
}

IMFTransform_ProcessOutput(this, dwFlags, cOutputBufferCount, pOutputSamples, ByRef pdwStatus)
{
   hr := DllCall(NumGet(NumGet(this+0)+25*A_PtrSize), &quot;ptr&quot;, this, &quot;uint&quot;, dwFlags, &quot;uint&quot;, cOutputBufferCount, &quot;ptr&quot;, pOutputSamples, &quot;uint*&quot;, pdwStatus)
   if hr or ErrorLevel
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
}

IMFTransform_ProcessInput(this, dwInputStreamID, pSample, dwFlags)
{
   hr := DllCall(NumGet(NumGet(this+0)+24*A_PtrSize), &quot;ptr&quot;, this, &quot;uint&quot;, dwInputStreamID, &quot;ptr&quot;, pSample, &quot;uint&quot;, dwFlags)
   if hr or ErrorLevel
   {
      if !ErrorLevel
      {
         if (hr&amp;=0xFFFFFFFF) = 0xC00D36B2   ; MF_E_INVALIDREQUEST
            return &quot;MF_E_INVALIDREQUEST&quot;
      }
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
   }
}

IMFTransform_GetOutputStreamInfo(this, dwInputStreamID, pStreamInfo)
{
   hr := DllCall(NumGet(NumGet(this+0)+7*A_PtrSize), &quot;ptr&quot;, this, &quot;uint&quot;, dwInputStreamID, &quot;ptr&quot;, pStreamInfo)
   if hr or ErrorLevel
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
}

IMFTransform_SetOutputType(this, dwInputStreamID, pType, dwFlags)
{
   hr := DllCall(NumGet(NumGet(this+0)+16*A_PtrSize), &quot;ptr&quot;, this, &quot;uint&quot;, dwInputStreamID, &quot;ptr&quot;, pType, &quot;uint&quot;, dwFlags)
   if hr or ErrorLevel
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
}

IMFTransform_SetInputType(this, dwInputStreamID, pType, dwFlags)
{
   hr := DllCall(NumGet(NumGet(this+0)+15*A_PtrSize), &quot;ptr&quot;, this, &quot;uint&quot;, dwInputStreamID, &quot;ptr&quot;, pType, &quot;uint&quot;, dwFlags)
   if hr or ErrorLevel
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
}

IWMResamplerProps_SetHalfFilterLength(this, lhalfFilterLen)
{
   hr := DllCall(NumGet(NumGet(this+0)+3*A_PtrSize), &quot;ptr&quot;, this, &quot;int&quot;, lhalfFilterLen)
   if hr or ErrorLevel
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; 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]
      _.MF_SOURCE_READER_DISCONNECT_MEDIASOURCE_ON_SHUTDOWN := [0x56b67165, 0x219e, 0x456d, 0xa2, 0x2e, 0x2d, 0x30, 0x04, 0xc7, 0xfe, 0x56]
      _.MF_MT_ALL_SAMPLES_INDEPENDENT := [0xc9173739, 0x5e56, 0x461c, 0xb7, 0x13, 0x46, 0xfb, 0x99, 0x5c, 0xb9, 0x5f]
      _.MF_SOURCE_READER_ASYNC_CALLBACK := [0x1e3dbeac, 0xbb43, 0x4c35, 0xb5, 0x07, 0xcd, 0x64, 0x44, 0x64, 0xc9, 0x65]
      _.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(&quot;H264&quot;) = 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]
      _.MFVideoFormat_I420 := [0x30323449, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71]
      _.MFVideoFormat_IYUV := [0x56555949, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71]
      _.MFVideoFormat_NV12 := [0x3231564E, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71]
      _.MFVideoFormat_YUY2 := [0x32595559, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71]
      _.MFVideoFormat_YV12 := [0x32315659, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71]
      _.MFVideoFormat_RGB24 := [0x00000014, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71]
   }
   if _.haskey(name)
   {
      p := _[name]
      VarSetCapacity(GUID,16)
      ,NumPut(p.1+(p.2&lt;&lt;32)+(p.3&lt;&lt;48),GUID,0,&quot;int64&quot;)
      ,NumPut(p.4+(p.5&lt;&lt;8)+(p.6&lt;&lt;16)+(p.7&lt;&lt;24)+(p.8&lt;&lt;32)+(p.9&lt;&lt;40)+(p.10&lt;&lt;48)+(p.11&lt;&lt;56),GUID,8,&quot;int64&quot;)
      return &amp;GUID
   }
   else return name
}

GUID(ByRef GUID, sGUID)
{
    VarSetCapacity(GUID, 16, 0)
    return DllCall(&quot;ole32\CLSIDFromString&quot;, &quot;WStr&quot;, sGUID, &quot;Ptr&quot;, &amp;GUID) &gt;= 0 ? &amp;GUID : &quot;&quot;
}

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

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

MemoryDifference(ptr1, ptr2, num)
{
   return DllCall(&quot;msvcrt\memcmp&quot;, &quot;ptr&quot;, ptr1, &quot;ptr&quot;, ptr2, &quot;int&quot;, num) 
}

_Error(val)
{
   msgbox % val
   ExitApp
}

checkCoordinates(ByRef start1, ByRef end1, ByRef start2, ByRef end2, hardware_encoder:=&quot;&quot;)
{
   if (A_OSVersion = &quot;WIN_7&quot;) or !InStr(hardware_encoder, &quot;NVIDIA&quot;) or ((x1 != &quot;&quot;) and (CaptureCoordinatesWithCPU = true))
      min1 := min2 := 33
   else
      min1 := 33, min2 := 17
   max1 := A_ScreenWidth, max2 := A_ScreenHeight
   loop 2
   {
      if (end%A_Index% - start%A_Index% &lt; min%A_Index%)
         end%A_Index% := start%A_Index% + min%A_Index%
      if ((A_OSVersion = &quot;WIN_7&quot;) or !InStr(hardware_encoder, &quot;NVIDIA&quot;) or ((x1 != &quot;&quot;) and (CaptureCoordinatesWithCPU = true))) and (mod(end%A_Index% - start%A_Index%, 2) != 0)
         end%A_Index%++
      if (end%A_Index% &gt; max%A_Index%)
      {
         start%A_Index% += max%A_Index%-end%A_Index%
         end%A_Index% := max%A_Index%
      }
   }
}



IMFSourceReaderCallback_new() {
   static VTBL := [ &quot;QueryInterface&quot;
                  , &quot;AddRef&quot;
                  , &quot;Release&quot;
                  , &quot;OnReadSample&quot; A_PtrSize
                  , &quot;OnFlush&quot;
                  , &quot;OnEvent&quot; ]
                  
        , heapSize := A_PtrSize*10
        , heapOffset := A_PtrSize*9
        
        , flags := (HEAP_GENERATE_EXCEPTIONS := 0x4) | (HEAP_NO_SERIALIZE := 0x1)
        , HEAP_ZERO_MEMORY := 0x8
   
   hHeap := DllCall(&quot;HeapCreate&quot;, &quot;UInt&quot;, flags, &quot;Ptr&quot;, 0, &quot;Ptr&quot;, 0, &quot;Ptr&quot;)
   addr := IMFSourceReaderCallback := DllCall(&quot;HeapAlloc&quot;, &quot;Ptr&quot;, hHeap, &quot;UInt&quot;, HEAP_ZERO_MEMORY, &quot;Ptr&quot;, heapSize, &quot;Ptr&quot;)
   addr := NumPut(addr + A_PtrSize, addr + 0)
   for k, v in VTBL
      addr := NumPut( RegisterSyncCallback(&quot;IMFSourceReaderCallback_&quot; . v), addr + 0 )
   NumPut(hHeap, IMFSourceReaderCallback + heapOffset)
   Return IMFSourceReaderCallback
}

IMFSourceReaderCallback_QueryInterface(this, riid, ppvObject)
{
   static IID_IUnknown, IID_IMFSourceReaderCallback
   if (!VarSetCapacity(IID_IUnknown))
   {
      VarSetCapacity(IID_IUnknown, 16), VarSetCapacity(IID_IMFSourceReaderCallback, 16)
      DllCall(&quot;ole32\CLSIDFromString&quot;, &quot;WStr&quot;, &quot;{00000000-0000-0000-C000-000000000046}&quot;, &quot;Ptr&quot;, &amp;IID_IUnknown)
      DllCall(&quot;ole32\CLSIDFromString&quot;, &quot;WStr&quot;, &quot;{deec8d99-fa1d-4d82-84c2-2c8969944867}&quot;, &quot;Ptr&quot;, &amp;IID_IMFSourceReaderCallback)
   }
   if (DllCall(&quot;ole32\IsEqualGUID&quot;, &quot;Ptr&quot;, riid, &quot;Ptr&quot;, &amp;IID_IMFSourceReaderCallback) || DllCall(&quot;ole32\IsEqualGUID&quot;, &quot;Ptr&quot;, riid, &quot;Ptr&quot;, &amp;IID_IUnknown))
   {
      NumPut(this, ppvObject+0, &quot;Ptr&quot;)
      IMFSourceReaderCallback_AddRef(this)
      return 0 ; S_OK
   }
   NumPut(0, ppvObject+0, &quot;Ptr&quot;)
   return 0x80004002 ; E_NOINTERFACE
}

IMFSourceReaderCallback_AddRef(this) {
   static refOffset := A_PtrSize*8
   NumPut(refCount := NumGet(this + refOffset, &quot;UInt&quot;) + 1, this + refOffset, &quot;UInt&quot;)
   Return refCount
}

IMFSourceReaderCallback_Release(this) {
   static refOffset := A_PtrSize*8
        , heapOffset := A_PtrSize*9
   NumPut(refCount := NumGet(this + refOffset, &quot;UInt&quot;) - 1, this + refOffset, &quot;UInt&quot;)
   if (refCount = 0) {
      hHeap := NumGet(this + heapOffset)
      DllCall(&quot;HeapDestroy&quot;, &quot;Ptr&quot;, hHeap)
   }
   Return refCount
}

/*
    RegisterSyncCallback

    A replacement for RegisterCallback for use with APIs that will call
    the callback on the wrong thread.  Synchronizes with the script&#039;s main
    thread via a window message.

    This version tries to emulate RegisterCallback as much as possible
    without using RegisterCallback, so shares most of its limitations,
    and some enhancements that could be made are not.

    Other differences from v1 RegisterCallback:
      - Variadic mode can&#039;t be emulated exactly, so is not supported.
      - A_EventInfo can&#039;t be set in v1, so is not supported.
      - Fast mode is not supported (the option is ignored).
      - ByRef parameters are allowed (but ByRef is ignored).
      - Throws instead of returning &quot;&quot; on failure.
*/
RegisterSyncCallback(FunctionName, Options:=&quot;&quot;, ParamCount:=&quot;&quot;)
{
    if !(fn := Func(FunctionName)) || fn.IsBuiltIn
        throw Exception(&quot;Bad function&quot;, -1, FunctionName)
    if (ParamCount == &quot;&quot;)
        ParamCount := fn.MinParams
    if (ParamCount &gt; fn.MaxParams &amp;&amp; !fn.IsVariadic || ParamCount+0 &lt; fn.MinParams)
        throw Exception(&quot;Bad param count&quot;, -1, ParamCount)

    static sHwnd := 0, sMsg, sSendMessageW
    if !sHwnd
    {
        Gui RegisterSyncCallback: +Parent%A_ScriptHwnd% +hwndsHwnd
        OnMessage(sMsg := 0x8000, Func(&quot;RegisterSyncCallback_Msg&quot;))
        sSendMessageW := DllCall(&quot;GetProcAddress&quot;, &quot;ptr&quot;, DllCall(&quot;GetModuleHandle&quot;, &quot;str&quot;, &quot;user32.dll&quot;, &quot;ptr&quot;), &quot;astr&quot;, &quot;SendMessageW&quot;, &quot;ptr&quot;)
    }

    if !(pcb := DllCall(&quot;GlobalAlloc&quot;, &quot;uint&quot;, 0, &quot;ptr&quot;, 96, &quot;ptr&quot;))
        throw
    DllCall(&quot;VirtualProtect&quot;, &quot;ptr&quot;, pcb, &quot;ptr&quot;, 96, &quot;uint&quot;, 0x40, &quot;uint*&quot;, 0)

    p := pcb
    if (A_PtrSize = 8)
    {
        /*
        48 89 4c 24 08  ; mov [rsp+8], rcx
        48 89 54&#039;24 10  ; mov [rsp+16], rdx
        4c 89 44 24 18  ; mov [rsp+24], r8
        4c&#039;89 4c 24 20  ; mov [rsp+32], r9
        48 83 ec 28&#039;    ; sub rsp, 40
        4c 8d 44 24 30  ; lea r8, [rsp+48]  (arg 3, &amp;params)
        49 b9 ..        ; mov r9, .. (arg 4, operand to follow)
        */
        p := NumPut(0x54894808244c8948, p+0)
        p := NumPut(0x4c182444894c1024, p+0)
        p := NumPut(0x28ec834820244c89, p+0)
        p := NumPut(  0xb9493024448d4c, p+0) - 1
        lParamPtr := p, p += 8

        p := NumPut(0xba, p+0, &quot;char&quot;) ; mov edx, nmsg
        p := NumPut(sMsg, p+0, &quot;int&quot;)
        p := NumPut(0xb9, p+0, &quot;char&quot;) ; mov ecx, hwnd
        p := NumPut(sHwnd, p+0, &quot;int&quot;)
        p := NumPut(0xb848, p+0, &quot;short&quot;) ; mov rax, SendMessageW
        p := NumPut(sSendMessageW, p+0)
        /*
        ff d0        ; call rax
        48 83 c4 28  ; add rsp, 40
        c3           ; ret
        */
        p := NumPut(0x00c328c48348d0ff, p+0)
    }
    else ;(A_PtrSize = 4)
    {
        p := NumPut(0x68, p+0, &quot;char&quot;)      ; push ... (lParam data)
        lParamPtr := p, p += 4
        p := NumPut(0x0824448d, p+0, &quot;int&quot;) ; lea eax, [esp+8]
        p := NumPut(0x50, p+0, &quot;char&quot;)      ; push eax
        p := NumPut(0x68, p+0, &quot;char&quot;)      ; push nmsg
        p := NumPut(sMsg, p+0, &quot;int&quot;)
        p := NumPut(0x68, p+0, &quot;char&quot;)      ; push hwnd
        p := NumPut(sHwnd, p+0, &quot;int&quot;)
        p := NumPut(0xb8, p+0, &quot;char&quot;)      ; mov eax, &amp;SendMessageW
        p := NumPut(sSendMessageW, p+0, &quot;int&quot;)
        p := NumPut(0xd0ff, p+0, &quot;short&quot;)   ; call eax
        p := NumPut(0xc2, p+0, &quot;char&quot;)      ; ret argsize
        p := NumPut((InStr(Options, &quot;C&quot;) ? 0 : ParamCount*4), p+0, &quot;short&quot;)
    }
    NumPut(p, lParamPtr+0) ; To be passed as lParam.
    p := NumPut(&amp;fn, p+0)
    p := NumPut(ParamCount, p+0, &quot;int&quot;)
    return pcb
}

RegisterSyncCallback_Msg(wParam, lParam)
{
    if (A_Gui != &quot;RegisterSyncCallback&quot;)
        return
    fn := Object(NumGet(lParam + 0))
    paramCount := NumGet(lParam + A_PtrSize, &quot;int&quot;)
    params := []
    Loop % paramCount
        params.Push(NumGet(wParam + A_PtrSize * (A_Index-1)))
    return %fn%(params*)
}

IMFSourceReaderCallback_OnReadSample4(this_, hrStatus, dwStreamIndex, dwStreamFlags, llTimestamp, llTimestamp1, pSample)
{
   Static audioStart, gapAudio
   critical
   if hrStatus
      _Error(A_ThisFunc &quot; error: &quot; hrStatus &quot;`nErrorLevel: &quot; ErrorLevel)
   llTimestamp |= (llTimestamp1 &lt;&lt; 32)
   if (pSample != 0)
   {
      if (gapAudio = 1)
      {
         IMFAttributes_SetUINT32(pSample, MF_GUID(GUID, &quot;MFSampleExtension_Discontinuity&quot;), true)
         gapAudio := &quot;&quot;
      }
      if (audioStart = &quot;&quot;)
         audioStart := llTimestamp
      IMFSample_SetSampleTime(pSample, llTimestamp - audioStart)
      if (IMFTransform = 1)
      {
         IMFSample_GetSampleDuration(pSample, llSampleDuration)
         loop
         {
            if (IMFTransform_ProcessInput(pTransform, 0, pSample, 0) != &quot;MF_E_INVALIDREQUEST&quot;)
               break
         }
         MFCreateSample(pSample1)
         VarSetCapacity(MFT_OUTPUT_DATA_BUFFER, 4*A_PtrSize, 0)
         NumPut(pSample1, MFT_OUTPUT_DATA_BUFFER, A_PtrSize, &quot;ptr&quot;)
         MFCreateMemoryBuffer(cbOutBytes, pBuffer)
         IMFSample_AddBuffer(pSample1, pBuffer)
         IMFTransform_ProcessOutput(pTransform, 0, 1, &amp;MFT_OUTPUT_DATA_BUFFER, processOutputStatus)
         IMFSample_SetSampleTime(pSample1, llTimestamp - audioStart)
         IMFSample_SetSampleDuration(pSample1, llSampleDuration)
         IMFSinkWriter_WriteSample(pSinkWriter, audioStreamIndex, pSample1)
         Release(pSample1)
         Release(pBuffer)
         pSample1 := pBuffer := &quot;&quot;
      }
      else
         IMFSinkWriter_WriteSample(pSinkWriter, audioStreamIndex, pSample)
   }
   else if (dwStreamFlags &amp; MF_SOURCE_READERF_STREAMTICK := 256) and (audioStart != &quot;&quot;)
   {
      IMFSinkWriter_SendStreamTick(pSinkWriter, audioStreamIndex, llTimestamp - audioStart)
      gapAudio := 1
   }
   if (flush = &quot;&quot;)
      IMFSourceReader_ReadSample(SourceReader, MF_SOURCE_READER_ANY_STREAM := 0xFFFFFFFE, 0, 0, 0, 0, 0)
   else
   {
      Release(IMFSourceReaderCallback)
      Release(SourceReader)
      SourceReader := IMFSourceReaderCallback := flush := audioStart := gapAudio := &quot;&quot;
   }
   return
}

IMFSourceReaderCallback_OnReadSample8(this_, hrStatus, dwStreamIndex, dwStreamFlags, llTimestamp, pSample)
{
   Static audioStart, gapAudio 
   critical
   if hrStatus
      _Error(A_ThisFunc &quot; error: &quot; hrStatus &quot;`nErrorLevel: &quot; ErrorLevel)
   if (pSample != 0)
   {
      if (gapAudio = 1)
      {
         IMFAttributes_SetUINT32(pSample, MF_GUID(GUID, &quot;MFSampleExtension_Discontinuity&quot;), true)
         gapAudio := &quot;&quot;
      }
      if (audioStart = &quot;&quot;)
         audioStart := llTimestamp
      IMFSample_SetSampleTime(pSample, llTimestamp - audioStart)
      if (IMFTransform = 1)
      {
         IMFSample_GetSampleDuration(pSample, llSampleDuration)
         loop
         {
            if (IMFTransform_ProcessInput(pTransform, 0, pSample, 0) != &quot;MF_E_INVALIDREQUEST&quot;)
               break
         }
         MFCreateSample(pSample1)
         VarSetCapacity(MFT_OUTPUT_DATA_BUFFER, 4*A_PtrSize, 0)
         NumPut(pSample1, MFT_OUTPUT_DATA_BUFFER, A_PtrSize, &quot;ptr&quot;)
         MFCreateMemoryBuffer(cbOutBytes, pBuffer)
         IMFSample_AddBuffer(pSample1, pBuffer)
         IMFTransform_ProcessOutput(pTransform, 0, 1, &amp;MFT_OUTPUT_DATA_BUFFER, processOutputStatus)
         IMFSample_SetSampleTime(pSample1, llTimestamp - audioStart)
         IMFSample_SetSampleDuration(pSample1, llSampleDuration)
         IMFSinkWriter_WriteSample(pSinkWriter, audioStreamIndex, pSample1)
         Release(pSample1)
         Release(pBuffer)
         pSample1 := pBuffer := &quot;&quot;
      }
      else
         IMFSinkWriter_WriteSample(pSinkWriter, audioStreamIndex, pSample)
   }
   else if (dwStreamFlags &amp; MF_SOURCE_READERF_STREAMTICK := 256) and (audioStart != &quot;&quot;)
   {
      IMFSinkWriter_SendStreamTick(pSinkWriter, audioStreamIndex, llTimestamp - audioStart)
      gapAudio := 1
   }
   if (flush = &quot;&quot;)
      IMFSourceReader_ReadSample(SourceReader, MF_SOURCE_READER_ANY_STREAM := 0xFFFFFFFE, 0, 0, 0, 0, 0)
   else
   {
      Release(IMFSourceReaderCallback)
      Release(SourceReader)
      SourceReader := IMFSourceReaderCallback := flush := audioStart := gapAudio := &quot;&quot;
   }
   return
}

IMFSourceReaderCallback_OnFlush(this_, dwStreamIndex)
{
   return
}

IMFSourceReaderCallback_OnEvent(this_)
{
   return
}</code></pre></div><p>Пример захвата части экрана (использовал скрипт выделения экрана by <strong>teadrinker</strong>).<br />f11 - начать запись<br />f12 - остановить запись<br />ctrl+x выбрать область экрана<br />mp4 сохранится в папке со скриптом как &quot;temp_&quot; A_TickCount &quot;.mp4&quot;.<br /></p><div class="codebox"><pre><code>
video_bitrate := 2000000
video_fps := 25
capture_cursor := true
;audiodevice := &quot;CABLE Output (VB-Audio Virtual Cable)&quot;
audioDelay := 80
; ShowAllAudioDevicesNames := true
; CaptureCoordinatesWithCPU := true
; Rotate := true
; UseSoftwareEncoding := true


setbatchlines -1
OnExit, ExitSub
Global pSinkWriter, SourceReader, audioStreamIndex, Flush, IMFSourceReaderCallback
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 = &quot;DXGI_ERROR_NOT_FOUND&quot;)
         break
      VarSetCapacity(DXGI_OUTPUT_DESC, 88+A_PtrSize, 0)
      IDXGIOutput_GetDesc(IDXGIOutput, &amp;DXGI_OUTPUT_DESC)
      Width := NumGet(DXGI_OUTPUT_DESC, 72, &quot;int&quot;)
      Height := NumGet(DXGI_OUTPUT_DESC, 76, &quot;int&quot;)
      AttachedToDesktop := NumGet(DXGI_OUTPUT_DESC, 80, &quot;int&quot;)
      if (AttachedToDesktop = 1)
         break 2
      ObjRelease(IDXGIOutput)
   }
   ObjRelease(IDXGIAdapter)
}
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, &amp;DXGI_OUTDUPL_DESC)
DesktopImageInSystemMemory := NumGet(DXGI_OUTDUPL_DESC, 32, &quot;uint&quot;)
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, &quot;uint&quot;)   ; Width
NumPut(height, D3D11_TEXTURE2D_DESC, 4, &quot;uint&quot;)   ; Height
NumPut(1, D3D11_TEXTURE2D_DESC, 8, &quot;uint&quot;)   ; MipLevels
NumPut(1, D3D11_TEXTURE2D_DESC, 12, &quot;uint&quot;)   ; ArraySize
NumPut(DXGI_FORMAT_B8G8R8A8_UNORM := 87, D3D11_TEXTURE2D_DESC, 16, &quot;uint&quot;)   ; Format
NumPut(1, D3D11_TEXTURE2D_DESC, 20, &quot;uint&quot;)   ; SampleDescCount
NumPut(0, D3D11_TEXTURE2D_DESC, 24, &quot;uint&quot;)   ; SampleDescQuality
NumPut(D3D11_USAGE_STAGING := 3, D3D11_TEXTURE2D_DESC, 28, &quot;uint&quot;)   ; Usage
NumPut(0, D3D11_TEXTURE2D_DESC, 32, &quot;uint&quot;)   ; BindFlags
NumPut(D3D11_CPU_ACCESS_READ := 0x20000 | D3D11_CPU_ACCESS_WRITE := 0x10000, D3D11_TEXTURE2D_DESC, 36, &quot;uint&quot;)   ; CPUAccessFlags
NumPut(0, D3D11_TEXTURE2D_DESC, 40, &quot;uint&quot;)   ; MiscFlags
ID3D11Device_CreateTexture2D(d3d_device, &amp;D3D11_TEXTURE2D_DESC, 0, staging_tex)
if (capture_cursor = true)
{
   VarSetCapacity(D3D11_TEXTURE2D_DESC, 44, 0)
   NumPut(width, D3D11_TEXTURE2D_DESC, 0, &quot;uint&quot;)   ; Width
   NumPut(height, D3D11_TEXTURE2D_DESC, 4, &quot;uint&quot;)   ; Height
   NumPut(1, D3D11_TEXTURE2D_DESC, 8, &quot;uint&quot;)   ; MipLevels
   NumPut(1, D3D11_TEXTURE2D_DESC, 12, &quot;uint&quot;)   ; ArraySize
   NumPut(DXGI_FORMAT_B8G8R8A8_UNORM := 87, D3D11_TEXTURE2D_DESC, 16, &quot;uint&quot;)   ; Format
   NumPut(1, D3D11_TEXTURE2D_DESC, 20, &quot;uint&quot;)   ; SampleDescCount
   NumPut(0, D3D11_TEXTURE2D_DESC, 24, &quot;uint&quot;)   ; SampleDescQuality
   NumPut(D3D11_USAGE_DEFAULT := 0, D3D11_TEXTURE2D_DESC, 28, &quot;uint&quot;)   ; Usage
   NumPut(D3D11_BIND_RENDER_TARGET := 0x20, D3D11_TEXTURE2D_DESC, 32, &quot;uint&quot;)   ; BindFlags
   NumPut(0, D3D11_TEXTURE2D_DESC, 36, &quot;uint&quot;)   ; CPUAccessFlags
   NumPut(D3D11_RESOURCE_MISC_GDI_COMPATIBLE := 0x200, D3D11_TEXTURE2D_DESC, 40, &quot;uint&quot;)   ; MiscFlags
   ID3D11Device_CreateTexture2D(d3d_device, &amp;D3D11_TEXTURE2D_DESC, 0, gdi_tex)
}
LOAD_DLL_Mf_Mfplat_Mfreadwrite()
MFStartup(version := 2, MFSTARTUP_FULL := 0)
return


^X::
area := GetArea()
x1 := area.x, x2 := area.x + area.w, y1 := area.y, y2 := area.y + area.h
return

f12::
stopCapture := 1
return

f11::
file := &quot;temp_&quot; A_TickCount &quot;.mp4&quot;
stopCapture := &quot;&quot;
if (ShowAllAudioDevicesNames != 1)
{
   if (UseSoftwareEncoding != 1)
   {
      VarSetCapacity(MFT_REGISTER_TYPE_INFO, 32, 0)
      DllCall(&quot;RtlMoveMemory&quot;, &quot;ptr&quot;, &amp;MFT_REGISTER_TYPE_INFO, &quot;ptr&quot;, MF_GUID(GUID, &quot;MFMediaType_Video&quot;), &quot;ptr&quot;, 16)
      DllCall(&quot;RtlMoveMemory&quot;, &quot;ptr&quot;, &amp;MFT_REGISTER_TYPE_INFO + 16, &quot;ptr&quot;, MF_GUID(GUID, &quot;MFVideoFormat_H264&quot;), &quot;ptr&quot;, 16)
      hardware_encoder := MFTEnumEx(MF_GUID(GUID, &quot;MFT_CATEGORY_VIDEO_ENCODER&quot;), MFT_ENUM_FLAG_HARDWARE := 0x04|MFT_ENUM_FLAG_SORTANDFILTER := 0x40, 0, &amp;MFT_REGISTER_TYPE_INFO)
   }
   if (x1 != &quot;&quot;)
   {
      checkCoordinates(x1, x2, y1, y2, hardware_encoder)
      width := x2-x1
      height := y2-y1
      VarSetCapacity(D3D11_BOX, 24, 0)
      NumPut(x1, D3D11_BOX, 0, &quot;uint&quot;)   ; left
      NumPut(y1, D3D11_BOX, 4, &quot;uint&quot;)   ; top
      NumPut(0, D3D11_BOX, 8, &quot;uint&quot;)   ; front
      NumPut(x2, D3D11_BOX, 12, &quot;uint&quot;)   ; right
      NumPut(y2, D3D11_BOX, 16, &quot;uint&quot;)   ; bottom
      NumPut(1, D3D11_BOX, 20, &quot;uint&quot;)   ; back
   }
   if (hardware_encoder != &quot;&quot;)
   {
      MFCreateAttributes(pMFAttributes, 4)
      IMFAttributes_SetUINT32(pMFAttributes, MF_GUID(GUID, &quot;MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS&quot;), true)
   }
   else
      MFCreateAttributes(pMFAttributes, 3)
   IMFAttributes_SetGUID(pMFAttributes, MF_GUID(GUID, &quot;MF_TRANSCODE_CONTAINERTYPE&quot;), MF_GUID(GUID1, &quot;MFTranscodeContainerType_MPEG4&quot;))
   IMFAttributes_SetUINT32(pMFAttributes, MF_GUID(GUID, &quot;MF_SINK_WRITER_DISABLE_THROTTLING&quot;), true)
   IMFAttributes_SetUINT32(pMFAttributes, MF_GUID(GUID, &quot;MF_LOW_LATENCY&quot;), true)
   MFCreateSinkWriterFromURL(file, 0, pMFAttributes, pSinkWriter)
   Release(pMFAttributes)
   pMFAttributes := &quot;&quot;

   loop 2   ; 1 - input, 2 - output
   {
      MFCreateMediaType(pMediaType%A_Index%)
      IMFAttributes_SetGUID(pMediaType%A_Index%, MF_GUID(GUID, &quot;MF_MT_MAJOR_TYPE&quot;), MF_GUID(GUID1, &quot;MFMediaType_Video&quot;))
      if (A_Index = 1)
      {
         if !InStr(hardware_encoder, &quot;NVIDIA&quot;) or ((x1 != &quot;&quot;) and (CaptureCoordinatesWithCPU = true))
            IMFAttributes_SetGUID(pMediaType%A_Index%, MF_GUID(GUID, &quot;MF_MT_SUBTYPE&quot;), MF_GUID(GUID1, &quot;MFVideoFormat_RGB32&quot;))
         else
            IMFAttributes_SetGUID(pMediaType%A_Index%, MF_GUID(GUID, &quot;MF_MT_SUBTYPE&quot;), MF_GUID(GUID1, &quot;MFVideoFormat_ARGB32&quot;))
      }
      else
      {
         IMFAttributes_SetGUID(pMediaType%A_Index%, MF_GUID(GUID, &quot;MF_MT_SUBTYPE&quot;), MF_GUID(GUID1, &quot;MFVideoFormat_H264&quot;))
         IMFAttributes_SetUINT32(pMediaType%A_Index%, MF_GUID(GUID, &quot;MF_MT_AVG_BITRATE&quot;), video_bitrate)
      }
      IMFAttributes_SetUINT32(pMediaType%A_Index%, MF_GUID(GUID, &quot;MF_MT_INTERLACE_MODE&quot;), MFVideoInterlace_Progressive := 2)
      IMFAttributes_SetUINT64(pMediaType%A_Index%, MF_GUID(GUID, &quot;MF_MT_FRAME_SIZE&quot;), (width&lt;&lt;32)|height)
      IMFAttributes_SetUINT64(pMediaType%A_Index%, MF_GUID(GUID, &quot;MF_MT_FRAME_RATE&quot;), (video_fps&lt;&lt;32)|1)
      IMFAttributes_SetUINT64(pMediaType%A_Index%, MF_GUID(GUID, &quot;MF_MT_PIXEL_ASPECT_RATIO&quot;), (1&lt;&lt;32)|1)
   }
   IMFSinkWriter_AddStream(pSinkWriter, pMediaType2, videoStreamIndex)
   IMFSinkWriter_SetInputMediaType(pSinkWriter, videoStreamIndex, pMediaType1, 0)
   Release(pMediaType1)
   Release(pMediaType2)
   pMediaType1 := pMediaType2 := &quot;&quot;
}

if (audiodevice != &quot;&quot;) or (ShowAllAudioDevicesNames = 1)
{
   NUM_CHANNELSMax := BITS_PER_SAMPLEMax := SAMPLES_PER_SECONDMax := BYTES_PER_SECONDMax := StreamNumberAudio := TypeNumberAudio := AudioSources := &quot;&quot;
   audiobasedevice := audiodevice
   IMFSourceReaderCallback := IMFSourceReaderCallback_new()
   MFCreateAttributes(pMFAttributes, 1)
   IMFAttributes_SetGUID(pMFAttributes, MF_GUID(GUID, &quot;MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE&quot;), MF_GUID(GUID1, &quot;MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_GUID&quot;))
   MFEnumDeviceSources(pMFAttributes, pppSourceActivate, pcSourceActivate)
   Loop % pcSourceActivate
   {
      IMFActivate := NumGet(pppSourceActivate + (A_Index - 1)*A_PtrSize)
      devicename := IMFActivate_GetAllocatedString(IMFActivate, MF_GUID(GUID, &quot;MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME&quot;))
      if (ShowAllAudioDevicesNames = 1)
      {
         basedevicename := devicename
         loop
         {
            if !InStr(Audiodevicenames, &quot;&quot;&quot;&quot; devicename &quot;&quot;&quot;`r`n&quot;)
               break
            devicename := basedevicename &quot;[&quot; A_Index+1 &quot;]&quot;
         }
         Audiodevicenames .= &quot;&quot;&quot;&quot; devicename &quot;&quot;&quot;`r`n&quot;
      }
      else
      {
         if RegexMatch(audiodevice, &quot;\[(\d)]$&quot;, match) and (devicename = RegexReplace(audiodevice, &quot;\[\d]$&quot;))
         {
            match1--
            if (match1 = 0)
               audiodevice := devicename
            else
               audiodevice := devicename &quot;[&quot; match1 &quot;]&quot;
         }
         if (devicename = audiodevice) and (MediaSourceAudio = &quot;&quot;)
            IMFActivate_ActivateObject(IMFActivate, IMFMediaSource := &quot;{279a808d-aec7-40c8-9c6b-a6b492c78a66}&quot;, MediaSourceAudio)
      }
      Release(IMFActivate)
      IMFActivate := &quot;&quot;
   }
   DllCall(&quot;ole32\CoTaskMemFree&quot;, &quot;ptr&quot;, pppSourceActivate)
   Release(pMFAttributes)
   pMFAttributes := &quot;&quot;
   if (ShowAllAudioDevicesNames = 1)
   {
      if (Audiodevicenames = &quot;&quot;)
         Audiodevicenames .= &quot;None&quot;
      msgbox % clipboard := &quot;Audio:`r`n&quot; Audiodevicenames
      ExitApp
   }
   if (MediaSourceAudio = &quot;&quot;)
   {
      msgbox % &quot;Cannot find Audio device - &quot;&quot;&quot; audiobasedevice &quot;&quot;&quot;&quot;
      ExitApp
   }
   MFCreateAttributes(pMFAttributes, 1)
   IMFAttributes_SetUnknown(pMFAttributes, MF_GUID(GUID, &quot;MF_SOURCE_READER_ASYNC_CALLBACK&quot;), IMFSourceReaderCallback)
   MFCreateSourceReaderFromMediaSource(MediaSourceAudio, pMFAttributes, SourceReader)
   loop
   {
      n := A_Index - 1
      if (IMFSourceReader_GetNativeMediaType(SourceReader, n, 0, ppMediaType) = &quot;MF_E_INVALIDSTREAMNUMBER&quot;)
         break
      Release(ppMediaType)
      ppMediaType := &quot;&quot;
      loop
      {
         k := A_Index - 1
         if (IMFSourceReader_GetNativeMediaType(SourceReader, n, k, ppMediaType) = &quot;MF_E_NO_MORE_TYPES&quot;)
            break
         IMFAttributes_GetGUID(ppMediaType, MF_GUID(GUID, &quot;MF_MT_MAJOR_TYPE&quot;), pguidValue)
         if (MemoryDifference(&amp;pguidValue, MF_GUID(GUID, &quot;MFMediaType_Audio&quot;), 16) = 0)
         {
            IMFAttributes_GetGUID(ppMediaType, MF_GUID(GUID, &quot;MF_MT_SUBTYPE&quot;), pguidValueSubType)
            AudioSources .= Format(&quot;0x{:x}&quot;, NumGet(pguidValueSubType, 0, &quot;int&quot;)) &quot;`n&quot;
            if (MemoryDifference(&amp;pguidValueSubType, MF_GUID(GUID, &quot;MFAudioFormat_PCM&quot;), 16) = 0) or (MemoryDifference(&amp;pguidValueSubType, MF_GUID(GUID, &quot;MFAudioFormat_Float&quot;), 16) = 0)
            {
               if (IMFAttributes_GetUINT32(ppMediaType, MF_GUID(GUID, &quot;MF_MT_AUDIO_AVG_BYTES_PER_SECOND&quot;), BYTES_PER_SECOND) = &quot;MF_E_ATTRIBUTENOTFOUND&quot;)
                  BYTES_PER_SECOND := 0
               if (IMFAttributes_GetUINT32(ppMediaType, MF_GUID(GUID, &quot;MF_MT_AUDIO_BITS_PER_SAMPLE&quot;), BITS_PER_SAMPLE) = &quot;MF_E_ATTRIBUTENOTFOUND&quot;)
                  BITS_PER_SAMPLE := 0
               if (IMFAttributes_GetUINT32(ppMediaType, MF_GUID(GUID, &quot;MF_MT_AUDIO_SAMPLES_PER_SECOND&quot;), SAMPLES_PER_SECOND) = &quot;MF_E_ATTRIBUTENOTFOUND&quot;)
                  SAMPLES_PER_SECOND := 0
               if (IMFAttributes_GetUINT32(ppMediaType, MF_GUID(GUID, &quot;MF_MT_AUDIO_NUM_CHANNELS&quot;), NUM_CHANNELS) = &quot;MF_E_ATTRIBUTENOTFOUND&quot;)
                  NUM_CHANNELS := 0
               if ((NUM_CHANNELSMax &lt; 2) and (NUM_CHANNELS &gt; NUM_CHANNELSMax)) or ((NUM_CHANNELSMax = 2) and (NUM_CHANNELS = 6)) or ((NUM_CHANNELSMax &gt; 2) and (NUM_CHANNELSMax != 6) and ((NUM_CHANNELS = 2) or (NUM_CHANNELS = 6))) or ((NUM_CHANNELS = NUM_CHANNELSMax) and (BITS_PER_SAMPLEMax != 16) and ((BITS_PER_SAMPLE = 16) or (BITS_PER_SAMPLE &gt; BITS_PER_SAMPLEMax))) or ((NUM_CHANNELS = NUM_CHANNELSMax) and (BITS_PER_SAMPLE = BITS_PER_SAMPLEMax) and (SAMPLES_PER_SECONDMax != 44100) and (SAMPLES_PER_SECONDMax != 48000) and ((SAMPLES_PER_SECOND = 44100) or (SAMPLES_PER_SECOND &gt; SAMPLES_PER_SECONDMax))) or ((SAMPLES_PER_SECONDMax != 48000) and (SAMPLES_PER_SECOND = 48000)) or ((NUM_CHANNELS = NUM_CHANNELSMax) and (BITS_PER_SAMPLE = BITS_PER_SAMPLEMax) and (SAMPLES_PER_SECOND = SAMPLES_PER_SECONDMax) and (BYTES_PER_SECOND &gt; BYTES_PER_SECONDMax))
               { 
                  NUM_CHANNELSMax := NUM_CHANNELS
                  BITS_PER_SAMPLEMax := BITS_PER_SAMPLE
                  SAMPLES_PER_SECONDMax := SAMPLES_PER_SECOND
                  BYTES_PER_SECONDMax := BYTES_PER_SECOND
                  StreamNumberAudio := n
                  TypeNumberAudio := k
               }
            }
         }
         Release(ppMediaType)
         ppMediaType := &quot;&quot;
      }
   }
   if (StreamNumberAudio = &quot;&quot;)
   {
      Sort, AudioSources, U
      msgbox % &quot;Current AudioSources not supported:`n&quot; AudioSources
      ExitApp
   }
   IMFSourceReader_SetStreamSelection(SourceReader, MF_SOURCE_READER_ALL_STREAMS := 0xFFFFFFFE, false)
   IMFSourceReader_SetStreamSelection(SourceReader, StreamNumberAudio, true)
   Release(pMFAttributes)
   pMFAttributes := &quot;&quot;
   if (NUM_CHANNELSMax = 0)
      NUM_CHANNELSMax := 1
   else if (NUM_CHANNELSMax &gt; 2) and (NUM_CHANNELSMax &lt; 6)
      NUM_CHANNELSMax := 2
   else if (NUM_CHANNELSMax &gt; 6)
      NUM_CHANNELSMax := 6
   if (SAMPLES_PER_SECONDMax &lt; 44100)
      SAMPLES_PER_SECONDMax := 44100
   else if (SAMPLES_PER_SECONDMax &gt; 44100)
      SAMPLES_PER_SECONDMax := 48000
   loop 2   ; 1 - input, 2 - output
   {
      MFCreateMediaType(pMediaTypeAudio%A_Index%)
      IMFAttributes_SetGUID(pMediaTypeAudio%A_Index%, MF_GUID(GUID, &quot;MF_MT_MAJOR_TYPE&quot;), MF_GUID(GUID1, &quot;MFMediaType_Audio&quot;))
      if (A_Index = 1)
         IMFAttributes_SetGUID(pMediaTypeAudio%A_Index%, MF_GUID(GUID, &quot;MF_MT_SUBTYPE&quot;), MF_GUID(GUID1, &quot;MFAudioFormat_PCM&quot;))
      else
      {
         IMFAttributes_SetGUID(pMediaTypeAudio%A_Index%, MF_GUID(GUID, &quot;MF_MT_SUBTYPE&quot;), MF_GUID(GUID1, &quot;MFAudioFormat_AAC&quot;))
         IMFAttributes_SetUINT32(pMediaTypeAudio%A_Index%, MF_GUID(GUID, &quot;MF_MT_AUDIO_AVG_BYTES_PER_SECOND&quot;), 20000)
      }
      IMFAttributes_SetUINT32(pMediaTypeAudio%A_Index%, MF_GUID(GUID, &quot;MF_MT_AUDIO_BITS_PER_SAMPLE&quot;), 16)
      IMFAttributes_SetUINT32(pMediaTypeAudio%A_Index%, MF_GUID(GUID, &quot;MF_MT_AUDIO_SAMPLES_PER_SECOND&quot;), SAMPLES_PER_SECONDMax)
      IMFAttributes_SetUINT32(pMediaTypeAudio%A_Index%, MF_GUID(GUID, &quot;MF_MT_AUDIO_NUM_CHANNELS&quot;), NUM_CHANNELSMax)
   }
   IMFSinkWriter_AddStream(pSinkWriter, pMediaTypeAudio2, audioStreamIndex)
   IMFSinkWriter_SetInputMediaType(pSinkWriter, audioStreamIndex, pMediaTypeAudio1, 0)
   IMFSourceReader_SetCurrentMediaType(SourceReader, StreamNumberAudio, 0, pMediaTypeAudio1)
   Release(pMediaTypeAudio1)
   Release(pMediaTypeAudio2)
   pMediaTypeAudio1 := pMediaTypeAudio2 := &quot;&quot;
}
IMFSinkWriter_BeginWriting(pSinkWriter)
video_frame_duration := 10000000/video_fps
cbWidth := 4 * width
cbBuffer := cbWidth * height
rtStart := 0
fps := 1000/video_fps
CaptureDuration := duration*1000 - 2*fps
VarSetCapacity(TIMECAPS, 8, 0)
DllCall(&quot;winmm\timeGetDevCaps&quot;, &quot;ptr&quot;, &amp;TIMECAPS, &quot;uint&quot;, 8)
uPeriod := NumGet(TIMECAPS, 0, &quot;uint&quot;)
DllCall(&quot;Winmm\timeBeginPeriod&quot;, &quot;uint&quot;, uPeriod)

loop
{
   if (A_Index != 1)
   {
      DllCall(&quot;QueryPerformanceCounter&quot;, &quot;int64*&quot;, ATickCount)
      sleepDuration := fps*(A_Index-1) - (ATickCount - start)*1000/freq
      SleepEnd := ATickCount + sleepDuration*freq/1000
      sleep % sleepDuration - 15
      DllCall(&quot;QueryPerformanceCounter&quot;, &quot;int64*&quot;, ATickCount)
      if (ATickCount &lt; SleepEnd)
         DllCall(&quot;Sleep&quot;, &quot;uint&quot;, (SleepEnd - ATickCount)*1000/freq)
   }
   VarSetCapacity(DXGI_OUTDUPL_FRAME_INFO, 48, 0)
   if (A_Index = 1)
      AcquireNextFrame := IDXGIOutputDuplication_AcquireNextFrame(Duplication, -1, &amp;DXGI_OUTDUPL_FRAME_INFO, desktop_resource)
   else
      AcquireNextFrame := IDXGIOutputDuplication_AcquireNextFrame(Duplication, 0, &amp;DXGI_OUTDUPL_FRAME_INFO, desktop_resource)
   if (AcquireNextFrame != &quot;DXGI_ERROR_WAIT_TIMEOUT&quot;)
   {
      if (A_Index = 1)
      {
         if (audiodevice != &quot;&quot;)
         {
            IMFSourceReader_ReadSample(SourceReader, MF_SOURCE_READER_ANY_STREAM := 0xFFFFFFFE, 0, 0, 0, 0, 0)
            if (audioDelay &gt; 0)
               DllCall(&quot;Sleep&quot;, &quot;uint&quot;, audioDelay)
         }
         DllCall(&quot;QueryPerformanceCounter&quot;, &quot;int64*&quot;, start)
         DllCall(&quot;QueryPerformanceFrequency&quot;, &quot;int64*&quot;, freq)
      }
      else
      {
         Release(pSample)
         Release(pBuffer)
         pSample := pBuffer := &quot;&quot;
      }
      tex := ID3D11Texture2D_Query(desktop_resource)
      if (capture_cursor = true)
      {
         VarSetCapacity(CURSORINFO, cbSize := 16 + A_PtrSize, 0)
         NumPut(cbSize, CURSORINFO, 0, &quot;uint&quot;)
      }
      if (capture_cursor = true) and DllCall(&quot;GetCursorInfo&quot;, &quot;ptr&quot;, &amp;CURSORINFO) and (NumGet(CURSORINFO, 4, &quot;uint&quot;) = 1)   ; CURSOR_SHOWING
      {
         hCursor := NumGet(CURSORINFO, 8)
         xCursor := NumGet(CURSORINFO, 8 + A_PtrSize, &quot;int&quot;)
         yCursor := NumGet(CURSORINFO, 12 + A_PtrSize, &quot;int&quot;)
         VarSetCapacity(ICONINFO, 8 + A_PtrSize*3, 0)
         DllCall(&quot;GetIconInfo&quot;, &quot;ptr&quot;, hCursor, &quot;ptr&quot;, &amp;ICONINFO)
         xHotspot := NumGet(ICONINFO, 4, &quot;uint&quot;)
         yHotspot := NumGet(ICONINFO, 8, &quot;uint&quot;)
         hbmMask  := NumGet(ICONINFO, 8 + A_PtrSize)
         hbmColor := NumGet(ICONINFO, 8 + A_PtrSize*2)
         ID3D11DeviceContext_CopyResource(d3d_context, gdi_tex, tex)
         gdi_Surface := IDXGISurface1_Query(gdi_tex)
         IDXGISurface1_GetDC(gdi_Surface, 0, hdc)
         DllCall(&quot;DrawIconEx&quot;, &quot;ptr&quot;, hdc, &quot;int&quot;, xCursor - xHotspot, &quot;int&quot;, yCursor - yHotspot, &quot;ptr&quot;, hCursor, &quot;int&quot;, 0, &quot;int&quot;, 0, &quot;uint&quot;, 0, &quot;ptr&quot;, 0, &quot;uint&quot;, DI_NORMAL := 0x0003 | DI_DEFAULTSIZE := 0x0008)
         if hbmMask
            DllCall(&quot;DeleteObject&quot;, &quot;ptr&quot;, hbmMask)
         if hbmColor
            DllCall(&quot;DeleteObject&quot;, &quot;ptr&quot;, hbmColor)
         hbmMask := hbmColor := &quot;&quot;
         IDXGISurface1_ReleaseDC(gdi_Surface, 0)
         if (x1 = &quot;&quot;)
            ID3D11DeviceContext_CopyResource(d3d_context, staging_tex, gdi_tex)
         else
            ID3D11DeviceContext_CopySubresourceRegion(d3d_context, staging_tex, 0, 0, 0, 0, gdi_tex, 0, &amp;D3D11_BOX)   ; set region
         ObjRelease(gdi_Surface)
         gdi_Surface := &quot;&quot;
      }
      else
      {
         if (x1 = &quot;&quot;)
            ID3D11DeviceContext_CopyResource(d3d_context, staging_tex, tex)
         else
            ID3D11DeviceContext_CopySubresourceRegion(d3d_context, staging_tex, 0, 0, 0, 0, tex, 0, &amp;D3D11_BOX)   ; set region
      }
      VarSetCapacity(D3D11_MAPPED_SUBRESOURCE, 8+A_PtrSize, 0)
      ID3D11DeviceContext_Map(d3d_context, staging_tex, 0, D3D11_MAP_READ := 1, 0, &amp;D3D11_MAPPED_SUBRESOURCE)
      pBits := NumGet(D3D11_MAPPED_SUBRESOURCE, 0, &quot;ptr&quot;)
      pitch := NumGet(D3D11_MAPPED_SUBRESOURCE, A_PtrSize, &quot;uint&quot;)

      MFCreateMemoryBuffer(cbBuffer, pBuffer)
      IMFMediaBuffer_Lock(pBuffer, pData, 0, 0)
      if !InStr(hardware_encoder, &quot;NVIDIA&quot;) or ((x1 != &quot;&quot;) and (CaptureCoordinatesWithCPU = true)) or (Rotate = true)
         MFCopyImage(pData, cbWidth, pBits+(height-1)*pitch, pitch*-1, cbWidth, height)
      else
         MFCopyImage(pData, cbWidth, pBits, pitch, 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 != &quot;DXGI_ERROR_WAIT_TIMEOUT&quot;)
   {
      ID3D11DeviceContext_Unmap(d3d_context, staging_tex, 0)
      ObjRelease(tex)
      Release(desktop_resource)
      tex := desktop_resource := &quot;&quot;
      IDXGIOutputDuplication_ReleaseFrame(duplication)
   }
   if stopCapture
   {
      video_frame_count := floor(((ATickCount - start)/freq*1000 + 2*fps)/1000*video_fps)
      video_frame_countReal := A_Index
      if (audiodevice != &quot;&quot;)
      {
         flush := 1
         loop
         {
            if (flush = &quot;&quot;)
               break
            sleep 50
         }
      }
      break
   }
   rtStart += video_frame_duration
}
IMFSinkWriter_Finalize(pSinkWriter)
DllCall(&quot;Winmm\timeEndPeriod&quot;, &quot;uint&quot;, uPeriod)
if MediaSourceAudio
{
   Release(MediaSourceAudio)
   MediaSourceAudio := &quot;&quot;
}
Release(pSample)
Release(pBuffer)
Release(pSinkWriter)
pSample := pBuffer := pSinkWriter := &quot;&quot;
msgbox % &quot;done`n&quot; video_frame_countReal &quot; captured`n&quot; video_frame_count-video_frame_countReal &quot; frames dropped&quot;
return



ExitSub:
if MediaSourceAudio
   Release(MediaSourceAudio)
if pSample
   Release(pSample)
if pBuffer
   Release(pBuffer)
if pSinkWriter
   Release(pSinkWriter)
if staging_tex
   Release(staging_tex)
if d3d_device
   Release(d3d_device)
if d3d_context
   Release(d3d_context)
if duplication
   Release(duplication)
if IDXGIAdapter
   Release(IDXGIAdapter)
if IDXGIOutput
   Release(IDXGIOutput)
if IDXGIOutput1
   Release(IDXGIOutput1)
if IDXGIFactory
   Release(IDXGIFactory)
if gdi_tex
   Release(gdi_tex)
MFShutdown()
ExitApp



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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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



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

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

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

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

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

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

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

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

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

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

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

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

MFCreateCollection(ByRef ppIMFCollection)
{
   hr := DllCall(&quot;Mfplat.dll\MFCreateCollection&quot;, &quot;ptr*&quot;, ppIMFCollection)
   if hr or ErrorLevel
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
}

MFCreateAggregateSource(pSourceCollection, ByRef ppAggSource)
{
   hr := DllCall(&quot;Mf.dll\MFCreateAggregateSource&quot;, &quot;ptr&quot;, pSourceCollection, &quot;ptr*&quot;, ppAggSource)
   if hr or ErrorLevel
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
}

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

IMFSourceReader_SetStreamSelection(this, dwStreamIndex, fSelected)
{
   hr := DllCall(NumGet(NumGet(this+0)+4*A_PtrSize), &quot;ptr&quot;, this, &quot;uint&quot;, dwStreamIndex, &quot;int&quot;, fSelected)
   if hr or ErrorLevel
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
}

IMFSourceReader_GetNativeMediaType(this, dwStreamIndex, dwMediaTypeIndex, ByRef ppMediaType)
{
   hr := DllCall(NumGet(NumGet(this+0)+5*A_PtrSize), &quot;ptr&quot;, this, &quot;uint&quot;, dwStreamIndex, &quot;uint&quot;, dwMediaTypeIndex, &quot;ptr*&quot;, ppMediaType)
   if hr or ErrorLevel
   {
      if !ErrorLevel
      {
         if (hr&amp;=0xFFFFFFFF) = 0xC00D36B3   ; MF_E_INVALIDSTREAMNUMBER
            return &quot;MF_E_INVALIDSTREAMNUMBER&quot;
         if (hr&amp;=0xFFFFFFFF) = 0xC00D36B9   ; MF_E_NO_MORE_TYPES
            return &quot;MF_E_NO_MORE_TYPES&quot;
      }
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
   }
}

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

IMFSourceReader_Flush(this, dwStreamIndex)
{
   hr := DllCall(NumGet(NumGet(this+0)+10*A_PtrSize), &quot;ptr&quot;, this, &quot;uint&quot;, dwStreamIndex)
   if hr or ErrorLevel
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
}

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

IMFAttributes_GetUINT64(this, guidKey, ByRef punValue)
{
   hr := DllCall(NumGet(NumGet(this+0)+8*A_PtrSize), &quot;ptr&quot;, this, &quot;ptr&quot;, guidKey, &quot;uint64*&quot;, punValue)
   if hr or ErrorLevel
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
}

IMFAttributes_GetUINT32(this, guidKey, ByRef punValue)
{
   hr := DllCall(NumGet(NumGet(this+0)+7*A_PtrSize), &quot;ptr&quot;, this, &quot;ptr&quot;, guidKey, &quot;uint*&quot;, punValue)
   if hr or ErrorLevel
   {
      if !ErrorLevel
      {
         if (hr&amp;=0xFFFFFFFF) = 0xC00D36E6   ; MF_E_ATTRIBUTENOTFOUND
            return &quot;MF_E_ATTRIBUTENOTFOUND&quot;
      }
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
   }
}

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

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

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

IMFAttributes_SetUnknown(this, guidKey, pUnknown)
{
   hr := DllCall(NumGet(NumGet(this+0)+27*A_PtrSize), &quot;ptr&quot;, this, &quot;ptr&quot;, guidKey, &quot;ptr&quot;, pUnknown)
   if hr or ErrorLevel
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
}

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

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

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

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

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

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

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

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

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

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

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

IMFMediaSource_Shutdown(this)
{
   hr := DllCall(NumGet(NumGet(this+0)+12*A_PtrSize), &quot;ptr&quot;, this)
   if hr or ErrorLevel
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; ErrorLevel)
}

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

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

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

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

IMFCollection_AddElement(this, pUnkElement)
{
   hr := DllCall(NumGet(NumGet(this+0)+5*A_PtrSize), &quot;ptr&quot;, this, &quot;ptr&quot;, pUnkElement)
   if hr or ErrorLevel
      _Error(A_ThisFunc &quot; error: &quot; hr &quot;`nErrorLevel: &quot; 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]
      _.MF_SOURCE_READER_DISCONNECT_MEDIASOURCE_ON_SHUTDOWN := [0x56b67165, 0x219e, 0x456d, 0xa2, 0x2e, 0x2d, 0x30, 0x04, 0xc7, 0xfe, 0x56]
      _.MF_SOURCE_READER_ASYNC_CALLBACK := [0x1e3dbeac, 0xbb43, 0x4c35, 0xb5, 0x07, 0xcd, 0x64, 0x44, 0x64, 0xc9, 0x65]
      _.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(&quot;H264&quot;) = 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]
      _.MFVideoFormat_I420 := [0x30323449, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71]
      _.MFVideoFormat_IYUV := [0x56555949, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71]
      _.MFVideoFormat_NV12 := [0x3231564E, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71]
      _.MFVideoFormat_YUY2 := [0x32595559, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71]
      _.MFVideoFormat_YV12 := [0x32315659, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71]
      _.MFVideoFormat_RGB24 := [0x00000014, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71]
   }
   if _.haskey(name)
   {
      p := _[name]
      VarSetCapacity(GUID,16)
      ,NumPut(p.1+(p.2&lt;&lt;32)+(p.3&lt;&lt;48),GUID,0,&quot;int64&quot;)
      ,NumPut(p.4+(p.5&lt;&lt;8)+(p.6&lt;&lt;16)+(p.7&lt;&lt;24)+(p.8&lt;&lt;32)+(p.9&lt;&lt;40)+(p.10&lt;&lt;48)+(p.11&lt;&lt;56),GUID,8,&quot;int64&quot;)
      return &amp;GUID
   }
   else return name
}

GUID(ByRef GUID, sGUID)
{
    VarSetCapacity(GUID, 16, 0)
    return DllCall(&quot;ole32\CLSIDFromString&quot;, &quot;WStr&quot;, sGUID, &quot;Ptr&quot;, &amp;GUID) &gt;= 0 ? &amp;GUID : &quot;&quot;
}

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

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

MemoryDifference(ptr1, ptr2, num)
{
   return DllCall(&quot;msvcrt\memcmp&quot;, &quot;ptr&quot;, ptr1, &quot;ptr&quot;, ptr2, &quot;int&quot;, num) 
}

_Error(val)
{
   msgbox % val
   ExitApp
}

checkCoordinates(ByRef start1, ByRef end1, ByRef start2, ByRef end2, hardware_encoder:=&quot;&quot;)
{
   if !InStr(hardware_encoder, &quot;NVIDIA&quot;) or ((x1 != &quot;&quot;) and (CaptureCoordinatesWithCPU = true))
      min1 := min2 := 33
   else
      min1 := 33, min2 := 17
   max1 := A_ScreenWidth, max2 := A_ScreenHeight
   loop 2
   {
      if (end%A_Index% - start%A_Index% &lt; min%A_Index%)
         end%A_Index% := start%A_Index% + min%A_Index%
      if (!InStr(hardware_encoder, &quot;NVIDIA&quot;) or ((x1 != &quot;&quot;) and (CaptureCoordinatesWithCPU = true))) and (mod(end%A_Index% - start%A_Index%, 2) != 0)
         end%A_Index%++
      if (end%A_Index% &gt; max%A_Index%)
      {
         start%A_Index% += max%A_Index%-end%A_Index%
         end%A_Index% := max%A_Index%
      }
   }
}



IMFSourceReaderCallback_new() {
   static VTBL := [ &quot;QueryInterface&quot;
                  , &quot;AddRef&quot;
                  , &quot;Release&quot;
                  , &quot;OnReadSample&quot; A_PtrSize
                  , &quot;OnFlush&quot;
                  , &quot;OnEvent&quot; ]
                  
        , heapSize := A_PtrSize*10
        , heapOffset := A_PtrSize*9
        
        , flags := (HEAP_GENERATE_EXCEPTIONS := 0x4) | (HEAP_NO_SERIALIZE := 0x1)
        , HEAP_ZERO_MEMORY := 0x8
   
   hHeap := DllCall(&quot;HeapCreate&quot;, &quot;UInt&quot;, flags, &quot;Ptr&quot;, 0, &quot;Ptr&quot;, 0, &quot;Ptr&quot;)
   addr := IMFSourceReaderCallback := DllCall(&quot;HeapAlloc&quot;, &quot;Ptr&quot;, hHeap, &quot;UInt&quot;, HEAP_ZERO_MEMORY, &quot;Ptr&quot;, heapSize, &quot;Ptr&quot;)
   addr := NumPut(addr + A_PtrSize, addr + 0)
   for k, v in VTBL
      addr := NumPut( RegisterSyncCallback(&quot;IMFSourceReaderCallback_&quot; . v), addr + 0 )
   NumPut(hHeap, IMFSourceReaderCallback + heapOffset)
   Return IMFSourceReaderCallback
}

IMFSourceReaderCallback_QueryInterface(this, riid, ppvObject)
{
   static IID_IUnknown, IID_IMFSourceReaderCallback
   if (!VarSetCapacity(IID_IUnknown))
   {
      VarSetCapacity(IID_IUnknown, 16), VarSetCapacity(IID_IMFSourceReaderCallback, 16)
      DllCall(&quot;ole32\CLSIDFromString&quot;, &quot;WStr&quot;, &quot;{00000000-0000-0000-C000-000000000046}&quot;, &quot;Ptr&quot;, &amp;IID_IUnknown)
      DllCall(&quot;ole32\CLSIDFromString&quot;, &quot;WStr&quot;, &quot;{deec8d99-fa1d-4d82-84c2-2c8969944867}&quot;, &quot;Ptr&quot;, &amp;IID_IMFSourceReaderCallback)
   }
   if (DllCall(&quot;ole32\IsEqualGUID&quot;, &quot;Ptr&quot;, riid, &quot;Ptr&quot;, &amp;IID_IMFSourceReaderCallback) || DllCall(&quot;ole32\IsEqualGUID&quot;, &quot;Ptr&quot;, riid, &quot;Ptr&quot;, &amp;IID_IUnknown))
   {
      NumPut(this, ppvObject+0, &quot;Ptr&quot;)
      IMFSourceReaderCallback_AddRef(this)
      return 0 ; S_OK
   }
   NumPut(0, ppvObject+0, &quot;Ptr&quot;)
   return 0x80004002 ; E_NOINTERFACE
}

IMFSourceReaderCallback_AddRef(this) {
   static refOffset := A_PtrSize*8
   NumPut(refCount := NumGet(this + refOffset, &quot;UInt&quot;) + 1, this + refOffset, &quot;UInt&quot;)
   Return refCount
}

IMFSourceReaderCallback_Release(this) {
   static refOffset := A_PtrSize*8
        , heapOffset := A_PtrSize*9
   NumPut(refCount := NumGet(this + refOffset, &quot;UInt&quot;) - 1, this + refOffset, &quot;UInt&quot;)
   if (refCount = 0) {
      hHeap := NumGet(this + heapOffset)
      DllCall(&quot;HeapDestroy&quot;, &quot;Ptr&quot;, hHeap)
   }
   Return refCount
}

/*
    RegisterSyncCallback

    A replacement for RegisterCallback for use with APIs that will call
    the callback on the wrong thread.  Synchronizes with the script&#039;s main
    thread via a window message.

    This version tries to emulate RegisterCallback as much as possible
    without using RegisterCallback, so shares most of its limitations,
    and some enhancements that could be made are not.

    Other differences from v1 RegisterCallback:
      - Variadic mode can&#039;t be emulated exactly, so is not supported.
      - A_EventInfo can&#039;t be set in v1, so is not supported.
      - Fast mode is not supported (the option is ignored).
      - ByRef parameters are allowed (but ByRef is ignored).
      - Throws instead of returning &quot;&quot; on failure.
*/
RegisterSyncCallback(FunctionName, Options:=&quot;&quot;, ParamCount:=&quot;&quot;)
{
    if !(fn := Func(FunctionName)) || fn.IsBuiltIn
        throw Exception(&quot;Bad function&quot;, -1, FunctionName)
    if (ParamCount == &quot;&quot;)
        ParamCount := fn.MinParams
    if (ParamCount &gt; fn.MaxParams &amp;&amp; !fn.IsVariadic || ParamCount+0 &lt; fn.MinParams)
        throw Exception(&quot;Bad param count&quot;, -1, ParamCount)

    static sHwnd := 0, sMsg, sSendMessageW
    if !sHwnd
    {
        Gui RegisterSyncCallback: +Parent%A_ScriptHwnd% +hwndsHwnd
        OnMessage(sMsg := 0x8000, Func(&quot;RegisterSyncCallback_Msg&quot;))
        sSendMessageW := DllCall(&quot;GetProcAddress&quot;, &quot;ptr&quot;, DllCall(&quot;GetModuleHandle&quot;, &quot;str&quot;, &quot;user32.dll&quot;, &quot;ptr&quot;), &quot;astr&quot;, &quot;SendMessageW&quot;, &quot;ptr&quot;)
    }

    if !(pcb := DllCall(&quot;GlobalAlloc&quot;, &quot;uint&quot;, 0, &quot;ptr&quot;, 96, &quot;ptr&quot;))
        throw
    DllCall(&quot;VirtualProtect&quot;, &quot;ptr&quot;, pcb, &quot;ptr&quot;, 96, &quot;uint&quot;, 0x40, &quot;uint*&quot;, 0)

    p := pcb
    if (A_PtrSize = 8)
    {
        /*
        48 89 4c 24 08  ; mov [rsp+8], rcx
        48 89 54&#039;24 10  ; mov [rsp+16], rdx
        4c 89 44 24 18  ; mov [rsp+24], r8
        4c&#039;89 4c 24 20  ; mov [rsp+32], r9
        48 83 ec 28&#039;    ; sub rsp, 40
        4c 8d 44 24 30  ; lea r8, [rsp+48]  (arg 3, &amp;params)
        49 b9 ..        ; mov r9, .. (arg 4, operand to follow)
        */
        p := NumPut(0x54894808244c8948, p+0)
        p := NumPut(0x4c182444894c1024, p+0)
        p := NumPut(0x28ec834820244c89, p+0)
        p := NumPut(  0xb9493024448d4c, p+0) - 1
        lParamPtr := p, p += 8

        p := NumPut(0xba, p+0, &quot;char&quot;) ; mov edx, nmsg
        p := NumPut(sMsg, p+0, &quot;int&quot;)
        p := NumPut(0xb9, p+0, &quot;char&quot;) ; mov ecx, hwnd
        p := NumPut(sHwnd, p+0, &quot;int&quot;)
        p := NumPut(0xb848, p+0, &quot;short&quot;) ; mov rax, SendMessageW
        p := NumPut(sSendMessageW, p+0)
        /*
        ff d0        ; call rax
        48 83 c4 28  ; add rsp, 40
        c3           ; ret
        */
        p := NumPut(0x00c328c48348d0ff, p+0)
    }
    else ;(A_PtrSize = 4)
    {
        p := NumPut(0x68, p+0, &quot;char&quot;)      ; push ... (lParam data)
        lParamPtr := p, p += 4
        p := NumPut(0x0824448d, p+0, &quot;int&quot;) ; lea eax, [esp+8]
        p := NumPut(0x50, p+0, &quot;char&quot;)      ; push eax
        p := NumPut(0x68, p+0, &quot;char&quot;)      ; push nmsg
        p := NumPut(sMsg, p+0, &quot;int&quot;)
        p := NumPut(0x68, p+0, &quot;char&quot;)      ; push hwnd
        p := NumPut(sHwnd, p+0, &quot;int&quot;)
        p := NumPut(0xb8, p+0, &quot;char&quot;)      ; mov eax, &amp;SendMessageW
        p := NumPut(sSendMessageW, p+0, &quot;int&quot;)
        p := NumPut(0xd0ff, p+0, &quot;short&quot;)   ; call eax
        p := NumPut(0xc2, p+0, &quot;char&quot;)      ; ret argsize
        p := NumPut((InStr(Options, &quot;C&quot;) ? 0 : ParamCount*4), p+0, &quot;short&quot;)
    }
    NumPut(p, lParamPtr+0) ; To be passed as lParam.
    p := NumPut(&amp;fn, p+0)
    p := NumPut(ParamCount, p+0, &quot;int&quot;)
    return pcb
}

RegisterSyncCallback_Msg(wParam, lParam)
{
    if (A_Gui != &quot;RegisterSyncCallback&quot;)
        return
    fn := Object(NumGet(lParam + 0))
    paramCount := NumGet(lParam + A_PtrSize, &quot;int&quot;)
    params := []
    Loop % paramCount
        params.Push(NumGet(wParam + A_PtrSize * (A_Index-1)))
    return %fn%(params*)
}

IMFSourceReaderCallback_OnReadSample4(this_, hrStatus, dwStreamIndex, dwStreamFlags, llTimestamp, llTimestamp1, pSample)
{
   Static audioStart, gapAudio
   critical
   if hrStatus
      _Error(A_ThisFunc &quot; error: &quot; hrStatus &quot;`nErrorLevel: &quot; ErrorLevel)
   llTimestamp |= (llTimestamp1 &lt;&lt; 32)
   if (pSample != 0)
   {
      if (gapAudio = 1)
      {
         IMFAttributes_SetUINT32(pSample, MF_GUID(GUID, &quot;MFSampleExtension_Discontinuity&quot;), true)
         gapAudio := &quot;&quot;
      }
      if (audioStart = &quot;&quot;)
         audioStart := llTimestamp
      IMFSample_SetSampleTime(pSample, llTimestamp - audioStart)
      IMFSinkWriter_WriteSample(pSinkWriter, audioStreamIndex, pSample)
   }
   else if (dwStreamFlags &amp; MF_SOURCE_READERF_STREAMTICK := 256) and (audioStart != &quot;&quot;)
   {
      IMFSinkWriter_SendStreamTick(pSinkWriter, audioStreamIndex, llTimestamp - audioStart)
      gapAudio := 1
   }
   if (flush = &quot;&quot;)
      IMFSourceReader_ReadSample(SourceReader, MF_SOURCE_READER_ANY_STREAM := 0xFFFFFFFE, 0, 0, 0, 0, 0)
   else
   {
      Release(IMFSourceReaderCallback)
      Release(SourceReader)
      SourceReader := IMFSourceReaderCallback := flush := audioStart := gapAudio := &quot;&quot;
   }
   return
}

IMFSourceReaderCallback_OnReadSample8(this_, hrStatus, dwStreamIndex, dwStreamFlags, llTimestamp, pSample)
{
   Static audioStart, gapAudio
   critical
   if hrStatus
      _Error(A_ThisFunc &quot; error: &quot; hrStatus &quot;`nErrorLevel: &quot; ErrorLevel)
   if (pSample != 0)
   {
      if (gapAudio = 1)
      {
         IMFAttributes_SetUINT32(pSample, MF_GUID(GUID, &quot;MFSampleExtension_Discontinuity&quot;), true)
         gapAudio := &quot;&quot;
      }
      if (audioStart = &quot;&quot;)
         audioStart := llTimestamp
      IMFSample_SetSampleTime(pSample, llTimestamp - audioStart)
      IMFSinkWriter_WriteSample(pSinkWriter, audioStreamIndex, pSample)
   }
   else if (dwStreamFlags &amp; MF_SOURCE_READERF_STREAMTICK := 256) and (audioStart != &quot;&quot;)
   {
      IMFSinkWriter_SendStreamTick(pSinkWriter, audioStreamIndex, llTimestamp - audioStart)
      gapAudio := 1
   }
   if (flush = &quot;&quot;)
      IMFSourceReader_ReadSample(SourceReader, MF_SOURCE_READER_ANY_STREAM := 0xFFFFFFFE, 0, 0, 0, 0, 0)
   else
   {
      Release(IMFSourceReaderCallback)
      Release(SourceReader)
      SourceReader := IMFSourceReaderCallback := flush := audioStart := gapAudio := &quot;&quot;
   }
   return
}

IMFSourceReaderCallback_OnFlush(this_, dwStreamIndex)
{
   return
}

IMFSourceReaderCallback_OnEvent(this_)
{
   return
}


GetArea() {
   area := []
   StartSelection(area)
   while !area.w
      Sleep, 100
   Return area
}
   
StartSelection(area) {
   handler := Func(&quot;Select&quot;).Bind(area)
   Hotkey, LButton, % handler, On
   ReplaceSystemCursors(&quot;IDC_CROSS&quot;)
}

Select(area) {
   static hGui := CreateSelectionGui()
   Hook := new WindowsHook(WH_MOUSE_LL := 14, &quot;LowLevelMouseProc&quot;, hGui)
   Loop {
      KeyWait, LButton
      WinGetPos, X, Y, W, H, ahk_id %hGui%
   } until w &gt; 0
   ReplaceSystemCursors(&quot;&quot;)
   Hotkey, LButton, Off
   Hook := &quot;&quot;
   Gui, %hGui%:Show, Hide
   for k, v in [&quot;x&quot;, &quot;y&quot;, &quot;w&quot;, &quot;h&quot;]
      area[v] := %v%
}

ReplaceSystemCursors(IDC = &quot;&quot;)
{
   static IMAGE_CURSOR := 2, SPI_SETCURSORS := 0x57
        , exitFunc := Func(&quot;ReplaceSystemCursors&quot;).Bind(&quot;&quot;)
        , SysCursors := { IDC_APPSTARTING: 32650
                        , IDC_ARROW      : 32512
                        , IDC_CROSS      : 32515
                        , IDC_HAND       : 32649
                        , IDC_HELP       : 32651
                        , IDC_IBEAM      : 32513
                        , IDC_NO         : 32648
                        , IDC_SIZEALL    : 32646
                        , IDC_SIZENESW   : 32643
                        , IDC_SIZENWSE   : 32642
                        , IDC_SIZEWE     : 32644
                        , IDC_SIZENS     : 32645 
                        , IDC_UPARROW    : 32516
                        , IDC_WAIT       : 32514 }
   if !IDC {
      DllCall(&quot;SystemParametersInfo&quot;, UInt, SPI_SETCURSORS, UInt, 0, UInt, 0, UInt, 0)
      OnExit(exitFunc, 0)
   }
   else  {
      hCursor := DllCall(&quot;LoadCursor&quot;, Ptr, 0, UInt, SysCursors[IDC], Ptr)
      for k, v in SysCursors  {
         hCopy := DllCall(&quot;CopyImage&quot;, Ptr, hCursor, UInt, IMAGE_CURSOR, Int, 0, Int, 0, UInt, 0, Ptr)
         DllCall(&quot;SetSystemCursor&quot;, Ptr, hCopy, UInt, v)
      }
      OnExit(exitFunc)
   }
}

CreateSelectionGui() {
   Gui, New, +hwndhGui +Alwaysontop -Caption +LastFound +ToolWindow +E0x20 -DPIScale
   WinSet, Transparent, 130
   Gui, Color, FFC800
   Return hGui
}

LowLevelMouseProc(nCode, wParam, lParam) {
   static WM_MOUSEMOVE := 0x200, WM_LBUTTONUP := 0x202
        , coords := [], startMouseX, startMouseY, hGui
        , timer := Func(&quot;LowLevelMouseProc&quot;).Bind(&quot;timer&quot;, &quot;&quot;, &quot;&quot;)
   
   if (nCode = &quot;timer&quot;) {
      while coords[1] {
         point := coords.RemoveAt(1)
         mouseX := point[1], mouseY := point[2]
         x := startMouseX &lt; mouseX ? startMouseX : mouseX
         y := startMouseY &lt; mouseY ? startMouseY : mouseY
         w := Abs(mouseX - startMouseX)
         h := Abs(mouseY - startMouseY)
         try Gui, %hGUi%: Show, x%x% y%y% w%w% h%h% NA
      }
   }
   else {
      (!hGui &amp;&amp; hGui := A_EventInfo)
      if (wParam = WM_LBUTTONUP)
         startMouseX := startMouseY := &quot;&quot;
      if (wParam = WM_MOUSEMOVE)  {
         mouseX := NumGet(lParam + 0, &quot;Int&quot;)
         mouseY := NumGet(lParam + 4, &quot;Int&quot;)
         if (startMouseX = &quot;&quot;) {
            startMouseX := mouseX
            startMouseY := mouseY
         }
         coords.Push([mouseX, mouseY])
         SetTimer, % timer, -10
      }
      Return DllCall(&quot;CallNextHookEx&quot;, Ptr, 0, Int, nCode, UInt, wParam, Ptr, lParam)
   }
}

class WindowsHook {
   __New(type, callback, eventInfo := &quot;&quot;, isGlobal := true) {
      this.callbackPtr := RegisterCallback(callback, &quot;Fast&quot;, 3, eventInfo)
      this.hHook := DllCall(&quot;SetWindowsHookEx&quot;, &quot;Int&quot;, type, &quot;Ptr&quot;, this.callbackPtr
                                              , &quot;Ptr&quot;, !isGlobal ? 0 : DllCall(&quot;GetModuleHandle&quot;, &quot;UInt&quot;, 0, &quot;Ptr&quot;)
                                              , &quot;UInt&quot;, isGlobal ? 0 : DllCall(&quot;GetCurrentThreadId&quot;), &quot;Ptr&quot;)
   }
   __Delete() {
      DllCall(&quot;UnhookWindowsHookEx&quot;, &quot;Ptr&quot;, this.hHook)
      DllCall(&quot;GlobalFree&quot;, &quot;Ptr&quot;, this.callBackPtr, &quot;Ptr&quot;)
   }
}</code></pre></div><p><a href="http://forum.script-coding.com/viewtopic.php?id=15098">Тема для обсуждения</a></p>]]></content>
			<author>
				<name><![CDATA[Malcev]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=26930</uri>
			</author>
			<updated>2023-03-10T12:29:25Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=157069#p157069</id>
		</entry>
</feed>
