Тема: AHK: Запись экрана в видеофайл Directx9/11+Microsoft Media Foundation
Тема для обсуждения "Запись экрана в видеофайл Directx9/11+Microsoft Media Foundation".
http://forum.script-coding.com/viewtopic.php?id=17641
Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.
Серый форум → Общение → AutoHotkey → AHK: Запись экрана в видеофайл Directx9/11+Microsoft Media Foundation
Чтобы отправить ответ, вы должны войти или зарегистрироваться
Тема для обсуждения "Запись экрана в видеофайл Directx9/11+Microsoft Media Foundation".
http://forum.script-coding.com/viewtopic.php?id=17641
На Windows 7 первый пример выдаёт ошибку:
IMFSinkWriter_SetInputMediaType error: -1072875852
ErrorLevel: 0
Да, как оказалось тема весьма запутанная.
У Media Foundation существует хардверное кодирование и софтверное.
У хардверного кодирования потребление CPU намного меньше.
Определить возможности кодирования через функцию mftenumex у меня не получилось.
https://docs.microsoft.com/en-us/window … -mftenumex
Поэтому, если изображение выйдет перевернутое, значит hardware_encoding := true надо закомментировать.
Для Win 7 надо использовать вместо MFVideoFormat_ARGB32 - MFVideoFormat_RGB32.
Посты поправил.
Сейчас вроде всё ок. А координаты области экрана можно указывать?
Добавил через Directx11 с координатами.
Это как пример возможности AHK, или можно применять для записи с экрана? Какой размер файла за час записи?
Пробуйте применять.
Размер зависит от битрейта.
Добавил через Directx11 с координатами.
А к DirectX 9 как добавить?
Разобрался:
file := A_Desktop . "\test.mp4"
video_codec := "H264"
video_bitrate := 2000000
video_fps := 25
duration := 5
hardware_encoding := false
x := 100
y := 100
w := 300
h := 300
setbatchlines -1
d3d := Direct3DCreate9(D3D_SDK_VERSION := 32)
if !d3d
{
MsgBox, 16, Error, Direct3DCreate9 failed.
ExitApp
}
VarSetCapacity(D3DDISPLAYMODE, 16, 0)
IDirect3D9_GetAdapterDisplayMode(d3d, D3DADAPTER_DEFAULT := 0, &D3DDISPLAYMODE)
Windowed := true
BackBufferCount := 1
height := NumGet(D3DDISPLAYMODE, 4, "uint")
width := NumGet(D3DDISPLAYMODE, 0, "uint")
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, &D3DPRESENT_PARAMETERS, device)
IDirect3DDevice9_CreateOffscreenPlainSurface(device, width, height, D3DFMT_A8R8G8B8 := 21, D3DPOOL_SYSTEMMEM := 2, surface, 0)
Release(d3d)
d3d := ""
LOAD_DLL_Mfplat_Mfreadwrite()
MFStartup(version := 2, MFSTARTUP_FULL := 0)
MFCreateAttributes(pMFAttributes, 100)
IMFAttributes_SetGUID(pMFAttributes, MF_GUID(GUID, "MF_TRANSCODE_CONTAINERTYPE"), MF_GUID(GUID1, "MFTranscodeContainerType_MPEG4"))
if hardware_encoding
{
IMFAttributes_SetUINT32(pMFAttributes, MF_GUID(GUID, "MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS"), true)
IMFAttributes_SetUINT32(pMFAttributes, MF_GUID(GUID, "MF_SINK_WRITER_DISABLE_THROTTLING"), true)
IMFAttributes_SetUINT32(pMFAttributes, MF_GUID(GUID, "MF_LOW_LATENCY"), true)
}
MFCreateSinkWriterFromURL(file, 0, pMFAttributes, pSinkWriter)
loop 2 ; 1 - input, 2 - output
{
MFCreateMediaType(pMediaType%A_Index%)
IMFAttributes_SetGUID(pMediaType%A_Index%, MF_GUID(GUID, "MF_MT_MAJOR_TYPE"), MF_GUID(GUID1, "MFMediaType_Video"))
if (A_Index = 1)
{
if A_OSVersion in WIN_XP,WIN_VISTA,WIN_7
IMFAttributes_SetGUID(pMediaType%A_Index%, MF_GUID(GUID, "MF_MT_SUBTYPE"), MF_GUID(GUID1, "MFVideoFormat_RGB32"))
else
IMFAttributes_SetGUID(pMediaType%A_Index%, MF_GUID(GUID, "MF_MT_SUBTYPE"), MF_GUID(GUID1, "MFVideoFormat_ARGB32"))
}
else
{
IMFAttributes_SetGUID(pMediaType%A_Index%, MF_GUID(GUID, "MF_MT_SUBTYPE"), MF_GUID(GUID1, "MFVideoFormat_" video_codec))
IMFAttributes_SetUINT32(pMediaType%A_Index%, MF_GUID(GUID, "MF_MT_AVG_BITRATE"), video_bitrate)
}
IMFAttributes_SetUINT32(pMediaType%A_Index%, MF_GUID(GUID, "MF_MT_INTERLACE_MODE"), MFVideoInterlace_Progressive := 2)
IMFAttributes_SetUINT64(pMediaType%A_Index%, MF_GUID(GUID, "MF_MT_FRAME_SIZE"), (w<<32)|h)
IMFAttributes_SetUINT64(pMediaType%A_Index%, MF_GUID(GUID, "MF_MT_FRAME_RATE"), (video_fps<<32)|1)
IMFAttributes_SetUINT64(pMediaType%A_Index%, MF_GUID(GUID, "MF_MT_PIXEL_ASPECT_RATIO"), (1<<32)|1)
}
IMFSinkWriter_AddStream(pSinkWriter, pMediaType2, streamIndex)
IMFSinkWriter_SetInputMediaType(pSinkWriter, streamIndex, pMediaType1, 0)
IMFSinkWriter_BeginWriting(pSinkWriter)
Release(pMediaType1)
Release(pMediaType2)
Release(pMFAttributes)
pMediaType1 := pMediaType2 := pMFAttributes := ""
video_frame_duration := 10000000/video_fps
video_frame_count := duration*video_fps
cbWidth := 4 * w
cbBuffer := cbWidth * h
rtStart := 0
fps := 1000/video_fps
loop % video_frame_count
{
if (A_Index = 1)
timeElapsed := A_TickCount
else
{
loop
{
if (A_TickCount - timeElapsed >= fps)
{
timeElapsed+=fps
break
}
sleep 10
}
}
IDirect3DDevice9_GetFrontBufferData(device, 0, surface)
VarSetCapacity(D3DLOCKED_RECT, A_PtrSize*2, 0)
VarSetCapacity(RECT, 16, 0)
NumPut(x, RECT), NumPut(y, RECT, 4), NumPut(w - x, RECT, 8), NumPut(h - y, RECT, 12, "UInt")
IDirect3DSurface9_LockRect(surface, &D3DLOCKED_RECT, &RECT, 0)
pitch := NumGet(D3DLOCKED_RECT, 0, "int")
pBits := NumGet(D3DLOCKED_RECT, A_PtrSize, "ptr")
MFCreateMemoryBuffer(cbBuffer, pBuffer)
IMFMediaBuffer_Lock(pBuffer, pData, 0, 0)
if hardware_encodingh
MFCopyImage(pData, cbWidth, pBits, pitch, cbWidth, h)
else
MFCopyImage(pData, cbWidth, pBits+(h-1)*pitch, pitch*-1, cbWidth, h)
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 := ""
rtStart += video_frame_duration
}
IMFSinkWriter_Finalize(pSinkWriter)
Release(pSinkWriter)
Release(surface)
Release(device)
pSinkWriter := surface := device := ""
MFShutdown()
msgbox done
ExitApp
Direct3DCreate9(SDKVersion) {
if !DllCall("GetModuleHandle","str","d3d9")
DllCall("LoadLibrary","str","d3d9")
return DllCall("d3d9\Direct3DCreate9", "uint", SDKVersion)
}
IDirect3D9_GetAdapterDisplayMode(this,Adapter,pMode)
{
hr := DllCall(NumGet(NumGet(this+0)+8*A_PtrSize),"ptr",this,"uint",Adapter,"ptr",pMode)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IDirect3D9_CreateDevice(this,Adapter,DeviceType,hFocusWindow,BehaviorFlags,pPresentationParameters,ByRef ppReturnedDeviceInterface)
{
hr := DllCall(NumGet(NumGet(this+0)+16*A_PtrSize),"ptr",this,"uint",Adapter,"uint",DeviceType,"ptr",hFocusWindow,"uint",BehaviorFlags,"ptr",pPresentationParameters,"ptr*",ppReturnedDeviceInterface)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IDirect3DDevice9_GetFrontBufferData(this,iSwapChain,pDestSurface)
{
hr := DllCall(NumGet(NumGet(this+0)+33*A_PtrSize),"ptr",this,"uint",iSwapChain,"ptr",pDestSurface)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IDirect3DDevice9_CreateOffscreenPlainSurface(this,Width,Height,Format,Pool,ByRef ppSurface,pSharedHandle)
{
hr := DllCall(NumGet(NumGet(this+0)+36*A_PtrSize),"ptr",this,"uint",Width,"uint",Height,"uint",Format,"uint",Pool,"ptr*",ppSurface,"ptr",pSharedHandle)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IDirect3DSurface9_LockRect(this,pLockedRect,pRect,Flags)
{
hr := DllCall(NumGet(NumGet(this+0)+13*A_PtrSize),"ptr",this,"ptr",pLockedRect,"ptr",pRect,"uint",Flags)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IDirect3DSurface9_UnlockRect(this)
{
hr := DllCall(NumGet(NumGet(this+0)+14*A_PtrSize),"ptr",this)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
LOAD_DLL_Mfplat_Mfreadwrite()
{
if !DllCall("GetModuleHandle","str","Mfplat")
DllCall("LoadLibrary","Str", "Mfplat.dll", "ptr")
if !DllCall("GetModuleHandle","str","Mfreadwrite")
DllCall("LoadLibrary","Str", "Mfreadwrite.dll", "ptr")
}
MFStartup(version, dwFlags)
{
hr := DllCall("Mfplat.dll\MFStartup", "uint", version, "uint", dwFlags)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
MFShutdown()
{
hr := DllCall("Mfplat.dll\MFShutdown")
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
MFCreateSinkWriterFromURL(pwszOutputURL, pByteStream, pAttributes, ByRef ppSinkWriter)
{
hr := DllCall("Mfreadwrite.dll\MFCreateSinkWriterFromURL", "str", pwszOutputURL, "ptr", pByteStream, "ptr", pAttributes, "ptr*", ppSinkWriter)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
MFCreateMediaType(ByRef ppMFType)
{
hr := DllCall("Mfplat.dll\MFCreateMediaType", "ptr*", ppMFType)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
MFCreateAttributes(ByRef ppMFAttributes, cInitialSize)
{
hr := DllCall("Mfplat.dll\MFCreateAttributes", "ptr*", ppMFAttributes, "uint", cInitialSize)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
MFCreateSample(ByRef ppIMFSample)
{
hr := DllCall("Mfplat.dll\MFCreateSample", "ptr*", ppIMFSample)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
MFCreateMemoryBuffer(cbMaxLength, ByRef ppBuffer)
{
hr := DllCall("Mfplat.dll\MFCreateMemoryBuffer", "uint", cbMaxLength, "ptr*", ppBuffer)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
MFCopyImage(pDest, lDestStride, pSrc, lSrcStride, dwWidthInBytes, dwLines)
{
hr := DllCall("Mfplat.dll\MFCopyImage", "ptr", pDest, "int", lDestStride, "ptr", pSrc, "int", lSrcStride, "uint", dwWidthInBytes, "uint", dwLines)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFAttributes_SetUINT32(this, guidKey, unValue)
{
hr := DllCall(NumGet(NumGet(this+0)+21*A_PtrSize), "ptr", this, "ptr", guidKey, "uint", unValue)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFAttributes_SetUINT64(this, guidKey, unValue)
{
hr := DllCall(NumGet(NumGet(this+0)+22*A_PtrSize), "ptr", this, "ptr", guidKey, "uint64", unValue)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFAttributes_SetGUID(this, guidKey, guidValue)
{
hr := DllCall(NumGet(NumGet(this+0)+24*A_PtrSize), "ptr", this, "ptr", guidKey, "ptr", guidValue)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFSinkWriter_AddStream(this, pMediaTypeOut, ByRef pdwStreamIndex)
{
hr := DllCall(NumGet(NumGet(this+0)+3*A_PtrSize), "ptr", this, "ptr", pMediaTypeOut, "ptr*", pdwStreamIndex)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFSinkWriter_SetInputMediaType(this, dwStreamIndex, pInputMediaType, pEncodingParameters)
{
hr := DllCall(NumGet(NumGet(this+0)+4*A_PtrSize), "ptr", this, "uint", dwStreamIndex, "ptr", pInputMediaType, "ptr", pEncodingParameters)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFSinkWriter_BeginWriting(this)
{
hr := DllCall(NumGet(NumGet(this+0)+5*A_PtrSize), "ptr", this)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFSinkWriter_WriteSample(this, dwStreamIndex, pSample)
{
hr := DllCall(NumGet(NumGet(this+0)+6*A_PtrSize), "ptr", this, "uint", dwStreamIndex, "ptr", pSample)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFSinkWriter_Finalize(this)
{
hr := DllCall(NumGet(NumGet(this+0)+11*A_PtrSize), "ptr", this)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFMediaBuffer_Lock(this, ByRef ppbBuffer, ByRef pcbMaxLength, ByRef pcbCurrentLength)
{
hr := DllCall(NumGet(NumGet(this+0)+3*A_PtrSize), "ptr", this, "ptr*", ppbBuffer, "uint*", pcbMaxLength, "uint*", pcbCurrentLength)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFMediaBuffer_Unlock(this)
{
hr := DllCall(NumGet(NumGet(this+0)+4*A_PtrSize), "ptr", this)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFMediaBuffer_SetCurrentLength(this, cbCurrentLength)
{
hr := DllCall(NumGet(NumGet(this+0)+6*A_PtrSize), "ptr", this, "uint", cbCurrentLength)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFSample_AddBuffer(this, pBuffer)
{
hr := DllCall(NumGet(NumGet(this+0)+42*A_PtrSize), "ptr", this, "ptr", pBuffer)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFSample_SetSampleTime(this, hnsSampleTime)
{
hr := DllCall(NumGet(NumGet(this+0)+36*A_PtrSize), "ptr", this, "int64", hnsSampleTime)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFSample_SetSampleDuration(this, hnsSampleDuration)
{
hr := DllCall(NumGet(NumGet(this+0)+38*A_PtrSize), "ptr", this, "int64", hnsSampleDuration)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
MF_GUID(ByRef GUID, name)
{
static init:=1, _:={}
if init
{
init:=0
_.MF_MT_MAJOR_TYPE := [0x48eba18e, 0xf8c9, 0x4687, 0xbf, 0x11, 0x0a, 0x74, 0xc9, 0xf9, 0x6a, 0x8f]
,_.MF_MT_SUBTYPE := [0xf7e34c9a, 0x42e8, 0x4714, 0xb7, 0x4b, 0xcb, 0x29, 0xd7, 0x2c, 0x35, 0xe5]
,_.MF_MT_AVG_BITRATE := [0x20332624, 0xfb0d, 0x4d9e, 0xbd, 0x0d, 0xcb, 0xf6, 0x78, 0x6c, 0x10, 0x2e]
,_.MF_MT_INTERLACE_MODE := [0xe2724bb8, 0xe676, 0x4806, 0xb4, 0xb2, 0xa8, 0xd6, 0xef, 0xb4, 0x4c, 0xcd]
,_.MF_MT_FRAME_SIZE := [0x1652c33d, 0xd6b2, 0x4012, 0xb8, 0x34, 0x72, 0x03, 0x08, 0x49, 0xa3, 0x7d]
,_.MF_MT_FRAME_RATE := [0xc459a2e8, 0x3d2c, 0x4e44, 0xb1, 0x32, 0xfe, 0xe5, 0x15, 0x6c, 0x7b, 0xb0]
,_.MF_MT_PIXEL_ASPECT_RATIO := [0xc6376a1e, 0x8d0a, 0x4027, 0xbe, 0x45, 0x6d, 0x9a, 0x0a, 0xd3, 0x9b, 0xb6]
,_.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]
,_.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]
,_.MFMediaType_Video := [0x73646976, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71]
,_.MFVideoFormat_H264 := [0x34363248, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71] ; FCC("H264") = 0x34363248
,_.MFVideoFormat_RGB32 := [0x00000016, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71]
,_.MFVideoFormat_ARGB32 := [0x00000015, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71]
}
if _.haskey(name)
{
p := _[name]
VarSetCapacity(GUID,16)
,NumPut(p.1+(p.2<<32)+(p.3<<48),GUID,0,"int64")
,NumPut(p.4+(p.5<<8)+(p.6<<16)+(p.7<<24)+(p.8<<32)+(p.9<<40)+(p.10<<48)+(p.11<<56),GUID,8,"int64")
return &GUID
}
else return name
}
FCC(var)
{
c := StrSplit(var)
msgbox % clipboard := Format("{:#x}",((Asc(c[1])&255)+((Asc(c[2])&255)<<8)+((Asc(c[3])&255)<<16)+((Asc(c[4])&255)<<24)))
}
Release(this)
{
DllCall(NumGet(NumGet(this+0)+2*A_PtrSize), "ptr", this)
if ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
_Error(val)
{
msgbox % val
ExitApp
}
Определить возможности кодирования через функцию mftenumex у меня не получилось.
Насколько я понял, саму возможность можно так определить:
MFT_CATEGORY_VIDEO_ENCODER := "{F79EAC7D-E545-4387-BDEE-D647D7BDE42A}"
MFMediaType_Video := "{73646976-0000-0010-8000-00aa00389b71}"
MFVideoFormat_RGB32 := "{00000016-0000-0010-8000-00aa00389b71}"
MFVideoFormat_ARGB32 := "{00000015-0000-0010-8000-00aa00389b71}"
if A_OSVersion in WIN_XP,WIN_VISTA,WIN_7
MFVideoFormat := MFVideoFormat_RGB32
else
MFVideoFormat := MFVideoFormat_ARGB32
MFT_ENUM_FLAG_HARDWARE := 0x4
CLSIDFromString(MFT_CATEGORY_VIDEO_ENCODER, GUID_MFT_CATEGORY_VIDEO_ENCODER)
CLSIDFromString(MFMediaType_Video , GUID_MFMediaType_Video)
CLSIDFromString(MFVideoFormat , GUID_MFVideoFormat)
VarSetCapacity(MFT_REGISTER_TYPE_INFO, 32, 0)
DllCall("RtlMoveMemory", "Ptr", &MFT_REGISTER_TYPE_INFO, "Ptr", &GUID_MFMediaType_Video, "Ptr", 16)
DllCall("RtlMoveMemory", "Ptr", &MFT_REGISTER_TYPE_INFO + 16, "Ptr", &GUID_MFVideoFormat, "Ptr", 16)
res := DllCall("Mfplat\MFTEnumEx", "Ptr", &GUID_MFT_CATEGORY_VIDEO_ENCODER, "UInt", MFT_ENUM_FLAG_HARDWARE
, "Ptr", &MFT_REGISTER_TYPE_INFO, "Ptr", 0
, "PtrP", ppMFTActivate, "UIntP", numMFTActivate, "UInt")
Loop % numMFTActivate
ObjRelease( NumGet(ppMFTActivate + (A_Index - 1)*A_PtrSize) )
DllCall("ole32\CoTaskMemFree", "Ptr", ppMFTActivate)
MsgBox, % numMFTActivate
CLSIDFromString(IID, ByRef CLSID) {
VarSetCapacity(CLSID, 16, 0)
if res := DllCall("ole32\CLSIDFromString", "WStr", IID, "Ptr", &CLSID)
throw Exception("CLSIDFromString failed. Error: " . Format("{:#x}", res))
Return &CLSID
}
Если возвращается не ноль, значит возможность хардверного кодирования есть. По идее потом из этих указателей на IMFActivate interface надо что-то получать.
Я подобное пробовал и результат был такой же как и с твоим кодом.
Хардварное у меня используется, но показывается 0 и на ахк 32 бит вылетает.
Изменил коды.
Теперь идет проверка - если (x1 != ""), то захватываются координаты.
Если capture_cursor := true, то захватывается (рисуется через GetDC) курсор мыши.
ЗЫ насколько всё-таки Directx9 проще, чем Directx11 c его DXGI.
Кстати, для ahk32 бит надо запускать MFTEnumEx так:
MFT_CATEGORY_VIDEO_ENCODER := "{F79EAC7D-E545-4387-BDEE-D647D7BDE42A}"
DllCall("Mfplat\MFTEnumEx", "int64", 0xF79EAC7D|(0xE545<<32)|(0x4387<<48), "int64", 0xBD|(0xEE<<8)|(0xD6<<16)|(0x47<<24)|(0xD7<<32)|(0xBD<<40)|(0xE4<<48)|(0x2A<<56), "uint", 0x4, "ptr", 0, "ptr", 0, "ptr*", pppMFTActivate, "uint*", pnumMFTActivate)
msgbox % pnumMFTActivate
Ага, уже тоже разобрался. Можно проще:
res := DllCall("Mfplat\MFTEnumEx", "UInt64", NumGet(GUID_MFT_CATEGORY_VIDEO_ENCODER, 0, "UInt64")
, "UInt64", NumGet(GUID_MFT_CATEGORY_VIDEO_ENCODER, 8, "UInt64")
, "UInt", flags
, "Ptr", 0, "Ptr", &MFT_REGISTER_TYPE_INFO
, "PtrP", ppMFTActivate, "UIntP", numMFTActivate, "UInt")
Такое наваял:
MFT_CATEGORY_VIDEO_ENCODER := "{F79EAC7D-E545-4387-BDEE-D647D7BDE42A}"
MFMediaType_Video := "{73646976-0000-0010-8000-00AA00389B71}"
MFVideoFormat_H264 := "{34363248-0000-0010-8000-00AA00389B71}"
MFT_FRIENDLY_NAME_Attribute := "{314FFBAE-5B41-4C95-9C19-4E7D586FACE3}"
MFT_ENUM_FLAG_SYNCMFT := 0x01
MFT_ENUM_FLAG_ASYNCMFT := 0x02
MFT_ENUM_FLAG_HARDWARE := 0x04
MFT_ENUM_FLAG_SORTANDFILTER := 0x40
flags := MFT_ENUM_FLAG_HARDWARE|MFT_ENUM_FLAG_SORTANDFILTER ; указываем нужные флаги из перечисленных
CLSIDFromString(MFT_CATEGORY_VIDEO_ENCODER, GUID_MFT_CATEGORY_VIDEO_ENCODER)
CLSIDFromString(MFMediaType_Video , GUID_MFMediaType_Video)
CLSIDFromString(MFVideoFormat_H264 , GUID_MFVideoFormat_H264)
VarSetCapacity(MFT_REGISTER_TYPE_INFO, 32, 0)
DllCall("RtlMoveMemory", "Ptr", &MFT_REGISTER_TYPE_INFO, "Ptr", &GUID_MFMediaType_Video, "Ptr", 16)
DllCall("RtlMoveMemory", "Ptr", &MFT_REGISTER_TYPE_INFO + 16, "Ptr", &GUID_MFVideoFormat_H264, "Ptr", 16)
if (A_PtrSize = 8) {
res := DllCall("Mfplat\MFTEnumEx", "Ptr", &GUID_MFT_CATEGORY_VIDEO_ENCODER
, "UInt", flags
, "Ptr", 0, "Ptr", &MFT_REGISTER_TYPE_INFO
, "PtrP", ppMFTActivate, "UIntP", numMFTActivate, "UInt")
}
else {
res := DllCall("Mfplat\MFTEnumEx", "UInt64", NumGet(GUID_MFT_CATEGORY_VIDEO_ENCODER, 0, "UInt64")
, "UInt64", NumGet(GUID_MFT_CATEGORY_VIDEO_ENCODER, 8, "UInt64")
, "UInt", flags
, "Ptr", 0, "Ptr", &MFT_REGISTER_TYPE_INFO
, "PtrP", ppMFTActivate, "UIntP", numMFTActivate, "UInt")
}
if !numMFTActivate {
MsgBox, Не найдено
Return
}
CLSIDFromString(MFT_FRIENDLY_NAME_Attribute, GUID_MFT_FRIENDLY_NAME_Attribute)
Loop % numMFTActivate {
IMFActivate := NumGet(ppMFTActivate + (A_Index - 1)*A_PtrSize)
; здесь используем методы IMFActivate
res := VTable(IMFActivate, GetAllocatedString := 13).Call("Ptr", &GUID_MFT_FRIENDLY_NAME_Attribute, "PtrP", pwszValue, "UIntP", len, "UInt")
names .= StrGet(pwszValue, len, "UTF-16") . "`n"
DllCall("ole32\CoTaskMemFree", "Ptr", pwszValue)
ObjRelease(IMFActivate)
}
DllCall("ole32\CoTaskMemFree", "Ptr", ppMFTActivate)
MsgBox, % names
CLSIDFromString(IID, ByRef CLSID) {
VarSetCapacity(CLSID, 16, 0)
if res := DllCall("ole32\CLSIDFromString", "WStr", IID, "Ptr", &CLSID)
throw Exception("CLSIDFromString failed. Error: " . Format("{:#x}", res))
Return &CLSID
}
VTable(ppv, idx) {
Return Func("DllCall").Bind(NumGet(NumGet(ppv + 0) + A_PtrSize*idx), "Ptr", ppv)
}
С указанием входящего потока у меня почему-то ничего не находит.
MFT_CATEGORY_VIDEO_ENCODER := "{F79EAC7D-E545-4387-BDEE-D647D7BDE42A}"
MFMediaType_Video := "{73646976-0000-0010-8000-00AA00389B71}"
MFVideoFormat_H264 := "{34363248-0000-0010-8000-00AA00389B71}"
MFVideoFormat_ARGB32 := "{00000015-0000-0010-8000-00aa00389b71}"
MFT_FRIENDLY_NAME_Attribute := "{314FFBAE-5B41-4C95-9C19-4E7D586FACE3}"
MFT_ENUM_FLAG_SYNCMFT := 0x01
MFT_ENUM_FLAG_ASYNCMFT := 0x02
MFT_ENUM_FLAG_HARDWARE := 0x04
MFT_ENUM_FLAG_SORTANDFILTER := 0x40
flags := MFT_ENUM_FLAG_HARDWARE|MFT_ENUM_FLAG_SORTANDFILTER ; указываем нужные флаги из перечисленных
CLSIDFromString(MFT_CATEGORY_VIDEO_ENCODER, GUID_MFT_CATEGORY_VIDEO_ENCODER)
CLSIDFromString(MFMediaType_Video , GUID_MFMediaType_Video)
CLSIDFromString(MFVideoFormat_H264 , GUID_MFVideoFormat_H264)
CLSIDFromString(MFVideoFormat_ARGB32 , GUID_MFVideoFormat_ARGB32)
VarSetCapacity(MFT_REGISTER_TYPE_INFO_In, 32, 0)
DllCall("RtlMoveMemory", "Ptr", &MFT_REGISTER_TYPE_INFO_In, "Ptr", &GUID_MFMediaType_Video, "Ptr", 16)
DllCall("RtlMoveMemory", "Ptr", &MFT_REGISTER_TYPE_INFO_In + 16, "Ptr", &GUID_MFVideoFormat_ARGB32, "Ptr", 16)
VarSetCapacity(MFT_REGISTER_TYPE_INFO, 32, 0)
DllCall("RtlMoveMemory", "Ptr", &MFT_REGISTER_TYPE_INFO, "Ptr", &GUID_MFMediaType_Video, "Ptr", 16)
DllCall("RtlMoveMemory", "Ptr", &MFT_REGISTER_TYPE_INFO + 16, "Ptr", &GUID_MFVideoFormat_H264, "Ptr", 16)
if (A_PtrSize = 8) {
res := DllCall("Mfplat\MFTEnumEx", "Ptr", &GUID_MFT_CATEGORY_VIDEO_ENCODER
, "UInt", flags
, "Ptr", &MFT_REGISTER_TYPE_INFO_In, "Ptr", &MFT_REGISTER_TYPE_INFO
, "PtrP", ppMFTActivate, "UIntP", numMFTActivate, "UInt")
}
else {
res := DllCall("Mfplat\MFTEnumEx", "UInt64", NumGet(GUID_MFT_CATEGORY_VIDEO_ENCODER, 0, "UInt64")
, "UInt64", NumGet(GUID_MFT_CATEGORY_VIDEO_ENCODER, 8, "UInt64")
, "UInt", flags
, "Ptr", &MFT_REGISTER_TYPE_INFO_In, "Ptr", &MFT_REGISTER_TYPE_INFO
, "PtrP", ppMFTActivate, "UIntP", numMFTActivate, "UInt")
}
if !numMFTActivate {
MsgBox, Не найдено
Return
}
CLSIDFromString(MFT_FRIENDLY_NAME_Attribute, GUID_MFT_FRIENDLY_NAME_Attribute)
Loop % numMFTActivate {
IMFActivate := NumGet(ppMFTActivate + (A_Index - 1)*A_PtrSize)
; здесь используем методы IMFActivate
res := VTable(IMFActivate, GetAllocatedString := 13).Call("Ptr", &GUID_MFT_FRIENDLY_NAME_Attribute, "PtrP", pwszValue, "UIntP", len, "UInt")
names .= StrGet(pwszValue, len, "UTF-16") . "`n"
DllCall("ole32\CoTaskMemFree", "Ptr", pwszValue)
ObjRelease(IMFActivate)
}
DllCall("ole32\CoTaskMemFree", "Ptr", ppMFTActivate)
MsgBox, % names
CLSIDFromString(IID, ByRef CLSID) {
VarSetCapacity(CLSID, 16, 0)
if res := DllCall("ole32\CLSIDFromString", "WStr", IID, "Ptr", &CLSID)
throw Exception("CLSIDFromString failed. Error: " . Format("{:#x}", res))
Return &CLSID
}
VTable(ppv, idx) {
Return Func("DllCall").Bind(NumGet(NumGet(ppv + 0) + A_PtrSize*idx), "Ptr", ppv)
}
Разберёмся попозже.
А почему ты ставишь h264 как input stream?
Для энкодера надо же в out.
И как я понимаю, в кодировании использоваться будет самый первый кодек.
Почему ставлю? Я не ставлю. Я просто говорю, что у тебя не находится кодеков для MFVideoFormat_RGB32/MFVideoFormat_ARGB32, потому что, возможно, их и нет.
Да, возможно и нет, так как Windows 10 ltsc.
В общем, я провел тесты и у меня вышло так.
C Win10+Nvidia размеры координат должны быть:
(x2-x1>32) and (y2-y1>16)
input format: MFVideoFormat_ARGB32
Изображение нормальное
Win10 software или Intel:
(x2-x1>32) and (y2-y1>32) and (mod(x2-x1, 2) = 0) and (mod(y2-y1, 2) = 0)
Intel input format: только MFVideoFormat_RGB32
Software input format: MFVideoFormat_ARGB32, MFVideoFormat_RGB32
Изображение перевернутое
Win7 software или Intel:
(x2-x1>=64) and (y2-y1>=64) and (mod(x2-x1, 2) = 0) and (mod(y2-y1, 2) = 0)
Intel input format: MFVideoFormat_RGB32
Software input format: MFVideoFormat_RGB32
Изображение перевернутое
Надо бы еще поставить Nvidia на win7 и проверить.
Надо бы затестировать нагрузку на процессор, чтобы выставить приоритеты.
Добавил запись звука для Win8+.
У меня скрипт для Windows 10, если указать координаты, завершается некорректно, файл битый. Если не указывать — нормально, звук пишет.
А записывает с NVIDIA ускорением?
А как это определить? У меня показывает MsgBox hardware-encoder - NVIDIA H.264 Encoder MFT.
Ошибка при завершении 0xC0000005
Значтит Nvidia.
Попробуй эту функцию
checkCoordinates(ByRef start1, ByRef end1, ByRef start2, ByRef end2, hardware_encoder:="")
{
if InStr(hardware_encoder, "NVIDIA")
min1 := 33, min2 := 17
else if A_OSVersion in WIN_XP,WIN_VISTA,WIN_7
min1 := min2 := 64
else
min1 := min2 := 33
max1 := A_ScreenWidth, max2 := A_ScreenHeight
loop 2
{
if (end%A_Index% - start%A_Index% < min%A_Index%)
{
end%A_Index% := start%A_Index% + min%A_Index%
if !InStr(hardware_encoder, "NVIDIA") and (mod(end%A_Index% - start%A_Index%, 2) != 0)
end%A_Index%++
if (end%A_Index% > max%A_Index%)
{
start%A_Index% += max%A_Index%-end%A_Index%
end%A_Index% := max%A_Index%
}
}
}
}
заменить на эту:
checkCoordinates(ByRef start1, ByRef end1, ByRef start2, ByRef end2, hardware_encoder:="")
{
if A_OSVersion in WIN_XP,WIN_VISTA,WIN_7
min1 := min2 := 64
else
min1 := min2 := 33
max1 := A_ScreenWidth, max2 := A_ScreenHeight
loop 2
{
if (end%A_Index% - start%A_Index% < min%A_Index%)
{
end%A_Index% := start%A_Index% + min%A_Index%
if (mod(end%A_Index% - start%A_Index%, 2) != 0)
end%A_Index%++
if (end%A_Index% > max%A_Index%)
{
start%A_Index% += max%A_Index%-end%A_Index%
end%A_Index% := max%A_Index%
}
}
}
}
Не, та же ошибка. Координаты те, что в скрипте.
А если заменить это
if InStr(hardware_encoder, "NVIDIA")
IMFAttributes_SetGUID(pMediaType%A_Index%, MF_GUID(GUID, "MF_MT_SUBTYPE"), MF_GUID(GUID1, "MFVideoFormat_ARGB32"))
на это
if InStr(hardware_encoder, "NVIDIA") and (x1 = "")
IMFAttributes_SetGUID(pMediaType%A_Index%, MF_GUID(GUID, "MF_MT_SUBTYPE"), MF_GUID(GUID1, "MFVideoFormat_ARGB32"))
Теперь вверх ногами.
А какая карточка Nvidia и версия драйверов?
И без захвата курсора, но с указанием координат код из первого поста тоже вылетает?
Что ещё посмотреть?
Без захвата тоже вылетает.
Попробуй поставить последние дрова.
У меня 970 с последними дровами и на ней нет вылетов при использовании гпу в методе ID3D11DeviceContext::CopySubresourceRegion.
Попробую, но раньше ведь работало? Что там изменилось?
Раньше там флаг стоял hardware_enable = true.
И если его закоментировать, то кодировалось в софтверном режиме.
А сейчас определяет автоматом, если есть хардверный h264, то он и используется.
А тут видно либо твоя карта не поддерживает GPU в CopySubresourceRegion и используется CPU, который вылетает из-за формата MFVideoFormat_ARGB32, либо баг драйверов.
Сейчас скачиваю.
А сейчас определяет автоматом, если есть хардверный h264, то он и используется.
Раньше у меня было true.
Ну если еще не проапдейтился, то для проверки вот старая версия:
file := "test.mp4"
video_codec := "H264"
video_bitrate := 2000000
video_fps := 25
duration := 5
hardware_encoding := true
capture_cursor := true
; x1 := 100, x2 := 1000, y1 := 100, y2 := 500
setbatchlines -1
IDXGIFactory := CreateDXGIFactory()
if !IDXGIFactory
{
MsgBox, 16, Error, Create IDXGIFactory failed.
ExitApp
}
loop
{
IDXGIFactory_EnumAdapters(IDXGIFactory, A_Index-1, IDXGIAdapter)
loop
{
hr := IDXGIAdapter_EnumOutputs(IDXGIAdapter, A_Index-1, IDXGIOutput)
if (hr = "DXGI_ERROR_NOT_FOUND")
break
VarSetCapacity(DXGI_OUTPUT_DESC, 88+A_PtrSize, 0)
IDXGIOutput_GetDesc(IDXGIOutput, &DXGI_OUTPUT_DESC)
Width := NumGet(DXGI_OUTPUT_DESC, 72, "int")
Height := NumGet(DXGI_OUTPUT_DESC, 76, "int")
AttachedToDesktop := NumGet(DXGI_OUTPUT_DESC, 80, "int")
if (AttachedToDesktop = 1)
break 2
}
}
if (AttachedToDesktop != 1)
{
MsgBox, 16, Error, No adapter attached to desktop
ExitApp
}
D3D11CreateDevice(IDXGIAdapter, D3D_DRIVER_TYPE_UNKNOWN := 0, 0, 0, 0, 0, D3D11_SDK_VERSION := 7, d3d_device, 0, d3d_context)
IDXGIOutput1 := IDXGIOutput1_Query(IDXGIOutput)
IDXGIOutput1_DuplicateOutput(IDXGIOutput1, d3d_device, Duplication)
VarSetCapacity(DXGI_OUTDUPL_DESC, 36, 0)
IDXGIOutputDuplication_GetDesc(Duplication, &DXGI_OUTDUPL_DESC)
DesktopImageInSystemMemory := NumGet(DXGI_OUTDUPL_DESC, 32, "uint")
sleep 50 ; As I understand - need some sleep for successful connecting to IDXGIOutputDuplication interface
VarSetCapacity(D3D11_TEXTURE2D_DESC, 44, 0)
NumPut(width, D3D11_TEXTURE2D_DESC, 0, "uint") ; Width
NumPut(height, D3D11_TEXTURE2D_DESC, 4, "uint") ; Height
NumPut(1, D3D11_TEXTURE2D_DESC, 8, "uint") ; MipLevels
NumPut(1, D3D11_TEXTURE2D_DESC, 12, "uint") ; ArraySize
NumPut(DXGI_FORMAT_B8G8R8A8_UNORM := 87, D3D11_TEXTURE2D_DESC, 16, "uint") ; Format
NumPut(1, D3D11_TEXTURE2D_DESC, 20, "uint") ; SampleDescCount
NumPut(0, D3D11_TEXTURE2D_DESC, 24, "uint") ; SampleDescQuality
NumPut(D3D11_USAGE_STAGING := 3, D3D11_TEXTURE2D_DESC, 28, "uint") ; Usage
NumPut(0, D3D11_TEXTURE2D_DESC, 32, "uint") ; BindFlags
NumPut(D3D11_CPU_ACCESS_READ := 0x20000 | D3D11_CPU_ACCESS_WRITE := 0x10000, D3D11_TEXTURE2D_DESC, 36, "uint") ; CPUAccessFlags
NumPut(0, D3D11_TEXTURE2D_DESC, 40, "uint") ; MiscFlags
ID3D11Device_CreateTexture2D(d3d_device, &D3D11_TEXTURE2D_DESC, 0, staging_tex)
if (capture_cursor = true)
{
VarSetCapacity(D3D11_TEXTURE2D_DESC, 44, 0)
NumPut(width, D3D11_TEXTURE2D_DESC, 0, "uint") ; Width
NumPut(height, D3D11_TEXTURE2D_DESC, 4, "uint") ; Height
NumPut(1, D3D11_TEXTURE2D_DESC, 8, "uint") ; MipLevels
NumPut(1, D3D11_TEXTURE2D_DESC, 12, "uint") ; ArraySize
NumPut(DXGI_FORMAT_B8G8R8A8_UNORM := 87, D3D11_TEXTURE2D_DESC, 16, "uint") ; Format
NumPut(1, D3D11_TEXTURE2D_DESC, 20, "uint") ; SampleDescCount
NumPut(0, D3D11_TEXTURE2D_DESC, 24, "uint") ; SampleDescQuality
NumPut(D3D11_USAGE_DEFAULT := 0, D3D11_TEXTURE2D_DESC, 28, "uint") ; Usage
NumPut(D3D11_BIND_RENDER_TARGET := 0x20, D3D11_TEXTURE2D_DESC, 32, "uint") ; BindFlags
NumPut(0, D3D11_TEXTURE2D_DESC, 36, "uint") ; CPUAccessFlags
NumPut(D3D11_RESOURCE_MISC_GDI_COMPATIBLE := 0x200, D3D11_TEXTURE2D_DESC, 40, "uint") ; MiscFlags
ID3D11Device_CreateTexture2D(d3d_device, &D3D11_TEXTURE2D_DESC, 0, gdi_tex)
}
if (x1 != "")
{
width := x2-x1
height := y2-y1
VarSetCapacity(D3D11_BOX, 24, 0)
NumPut(x1, D3D11_BOX, 0, "uint") ; left
NumPut(y1, D3D11_BOX, 4, "uint") ; top
NumPut(0, D3D11_BOX, 8, "uint") ; front
NumPut(x2, D3D11_BOX, 12, "uint") ; right
NumPut(y2, D3D11_BOX, 16, "uint") ; bottom
NumPut(1, D3D11_BOX, 20, "uint") ; back
}
LOAD_DLL_Mfplat_Mfreadwrite()
MFStartup(version := 2, MFSTARTUP_FULL := 0)
MFCreateAttributes(pMFAttributes, 100)
IMFAttributes_SetGUID(pMFAttributes, MF_GUID(GUID, "MF_TRANSCODE_CONTAINERTYPE"), MF_GUID(GUID1, "MFTranscodeContainerType_MPEG4"))
if hardware_encoding
{
IMFAttributes_SetUINT32(pMFAttributes, MF_GUID(GUID, "MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS"), true)
IMFAttributes_SetUINT32(pMFAttributes, MF_GUID(GUID, "MF_SINK_WRITER_DISABLE_THROTTLING"), true)
IMFAttributes_SetUINT32(pMFAttributes, MF_GUID(GUID, "MF_LOW_LATENCY"), true)
}
MFCreateSinkWriterFromURL(file, 0, pMFAttributes, pSinkWriter)
loop 2 ; 1 - input, 2 - output
{
MFCreateMediaType(pMediaType%A_Index%)
IMFAttributes_SetGUID(pMediaType%A_Index%, MF_GUID(GUID, "MF_MT_MAJOR_TYPE"), MF_GUID(GUID1, "MFMediaType_Video"))
if (A_Index = 1)
IMFAttributes_SetGUID(pMediaType%A_Index%, MF_GUID(GUID, "MF_MT_SUBTYPE"), MF_GUID(GUID1, "MFVideoFormat_ARGB32"))
else
{
IMFAttributes_SetGUID(pMediaType%A_Index%, MF_GUID(GUID, "MF_MT_SUBTYPE"), MF_GUID(GUID1, "MFVideoFormat_" video_codec))
IMFAttributes_SetUINT32(pMediaType%A_Index%, MF_GUID(GUID, "MF_MT_AVG_BITRATE"), video_bitrate)
}
IMFAttributes_SetUINT32(pMediaType%A_Index%, MF_GUID(GUID, "MF_MT_INTERLACE_MODE"), MFVideoInterlace_Progressive := 2)
IMFAttributes_SetUINT64(pMediaType%A_Index%, MF_GUID(GUID, "MF_MT_FRAME_SIZE"), (width<<32)|height)
IMFAttributes_SetUINT64(pMediaType%A_Index%, MF_GUID(GUID, "MF_MT_FRAME_RATE"), (video_fps<<32)|1)
IMFAttributes_SetUINT64(pMediaType%A_Index%, MF_GUID(GUID, "MF_MT_PIXEL_ASPECT_RATIO"), (1<<32)|1)
}
IMFSinkWriter_AddStream(pSinkWriter, pMediaType2, streamIndex)
IMFSinkWriter_SetInputMediaType(pSinkWriter, streamIndex, pMediaType1, 0)
IMFSinkWriter_BeginWriting(pSinkWriter)
Release(pMediaType1)
Release(pMediaType2)
Release(pMFAttributes)
pMediaType1 := pMediaType2 := pMFAttributes := ""
video_frame_duration := 10000000/video_fps
video_frame_count := duration*video_fps
cbWidth := 4 * width
cbBuffer := cbWidth * height
rtStart := 0
fps := 1000/video_fps
loop % video_frame_count
{
if (A_Index = 1)
timeElapsed := A_TickCount
else
{
loop
{
if (A_TickCount - timeElapsed >= fps)
{
timeElapsed+=fps
break
}
sleep 10
}
}
VarSetCapacity(DXGI_OUTDUPL_FRAME_INFO, 48, 0)
AcquireNextFrame := IDXGIOutputDuplication_AcquireNextFrame(Duplication, 0, &DXGI_OUTDUPL_FRAME_INFO, desktop_resource)
if (AcquireNextFrame != "DXGI_ERROR_WAIT_TIMEOUT")
{
if (A_Index != 1)
{
Release(pSample)
Release(pBuffer)
pSample := pBuffer := ""
}
tex := ID3D11Texture2D_Query(desktop_resource)
if (capture_cursor = true)
{
VarSetCapacity(CURSORINFO, cbSize := 16 + A_PtrSize, 0)
NumPut(cbSize, CURSORINFO, 0, "uint")
}
if (capture_cursor = true) and DllCall("GetCursorInfo", "ptr", &CURSORINFO) and (NumGet(CURSORINFO, 4, "uint") = 1) ; CURSOR_SHOWING
{
hCursor := NumGet(CURSORINFO, 8)
xCursor := NumGet(CURSORINFO, 8 + A_PtrSize, "int")
yCursor := NumGet(CURSORINFO, 12 + A_PtrSize, "int")
ID3D11DeviceContext_CopyResource(d3d_context, gdi_tex, tex)
gdi_Surface := IDXGISurface1_Query(gdi_tex)
IDXGISurface1_GetDC(gdi_Surface, 0, hdc)
DllCall("DrawIconEx", "ptr", hdc, "int", xCursor, "int", yCursor, "ptr", hCursor, "int", 0, "int", 0, "uint", 0, "ptr", 0, "uint", DI_NORMAL := 0x0003 | DI_DEFAULTSIZE := 0x0008)
IDXGISurface1_ReleaseDC(gdi_Surface, 0)
if (x1 = "")
ID3D11DeviceContext_CopyResource(d3d_context, staging_tex, gdi_tex)
else
ID3D11DeviceContext_CopySubresourceRegion(d3d_context, staging_tex, 0, 0, 0, 0, gdi_tex, 0, &D3D11_BOX) ; set region
ObjRelease(gdi_Surface)
gdi_Surface := ""
}
else
{
if (x1 = "")
ID3D11DeviceContext_CopyResource(d3d_context, staging_tex, tex)
else
ID3D11DeviceContext_CopySubresourceRegion(d3d_context, staging_tex, 0, 0, 0, 0, tex, 0, &D3D11_BOX) ; set region
}
VarSetCapacity(D3D11_MAPPED_SUBRESOURCE, 8+A_PtrSize, 0)
ID3D11DeviceContext_Map(d3d_context, staging_tex, 0, D3D11_MAP_READ := 1, 0, &D3D11_MAPPED_SUBRESOURCE)
pBits := NumGet(D3D11_MAPPED_SUBRESOURCE, 0, "ptr")
pitch := NumGet(D3D11_MAPPED_SUBRESOURCE, A_PtrSize, "uint")
MFCreateMemoryBuffer(cbBuffer, pBuffer)
IMFMediaBuffer_Lock(pBuffer, pData, 0, 0)
if hardware_encoding
MFCopyImage(pData, cbWidth, pBits, pitch, cbWidth, height)
else
MFCopyImage(pData, cbWidth, pBits+(height-1)*pitch, pitch*-1, cbWidth, height)
IMFMediaBuffer_Unlock(pBuffer)
IMFMediaBuffer_SetCurrentLength(pBuffer, cbBuffer)
MFCreateSample(pSample)
IMFSample_AddBuffer(pSample, pBuffer)
}
IMFSample_SetSampleTime(pSample, rtStart)
IMFSample_SetSampleDuration(pSample, video_frame_duration)
IMFSinkWriter_WriteSample(pSinkWriter, streamIndex, pSample)
if (AcquireNextFrame != "DXGI_ERROR_WAIT_TIMEOUT")
{
ID3D11DeviceContext_Unmap(d3d_context, staging_tex, 0)
ObjRelease(tex)
Release(desktop_resource)
tex := desktop_resource := ""
IDXGIOutputDuplication_ReleaseFrame(duplication)
}
rtStart += video_frame_duration
}
IMFSinkWriter_Finalize(pSinkWriter)
Release(pSample)
Release(pBuffer)
Release(pSinkWriter)
Release(staging_tex)
Release(d3d_device)
Release(d3d_context)
Release(duplication)
Release(IDXGIAdapter)
Release(IDXGIOutput)
ObjRelease(IDXGIOutput1)
Release(IDXGIFactory)
if (capture_cursor = true)
{
Release(gdi_tex)
gdi_tex := ""
}
pSample := pBuffer := pSinkWriter := staging_tex := d3d_device := d3d_context := duplication := IDXGIAdapter := IDXGIOutput := IDXGIOutput1 := IDXGIFactory := ""
MFShutdown()
msgbox done
ExitApp
CreateDXGIFactory()
{
if !DllCall("GetModuleHandle","str","DXGI")
DllCall("LoadLibrary","str","DXGI")
if !DllCall("GetModuleHandle","str","D3D11")
DllCall("LoadLibrary","str","D3D11")
GUID(riid, "{7b7166ec-21c7-44ae-b21a-c9ae321ae369}")
hr := DllCall("DXGI\CreateDXGIFactory1", "ptr", &riid, "ptr*", ppFactory)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
return ppFactory
}
IDXGIFactory_EnumAdapters(this, Adapter, ByRef ppAdapter)
{
hr := DllCall(NumGet(NumGet(this+0)+7*A_PtrSize), "ptr", this, "uint", Adapter, "ptr*", ppAdapter)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IDXGIAdapter_EnumOutputs(this, Output, ByRef ppOutput)
{
hr := DllCall(NumGet(NumGet(this+0)+7*A_PtrSize), "ptr", this, "uint", Output, "ptr*", ppOutput)
if hr or ErrorLevel
{
if (hr&=0xFFFFFFFF) = 0x887A0002 ; DXGI_ERROR_NOT_FOUND
return "DXGI_ERROR_NOT_FOUND"
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
}
IDXGIAdapter_GetDesc(this, pDesc)
{
hr := DllCall(NumGet(NumGet(this+0)+8*A_PtrSize), "ptr", this, "ptr", pDesc)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IDXGIOutput_GetDesc(this, pDesc)
{
hr := DllCall(NumGet(NumGet(this+0)+7*A_PtrSize), "ptr", this, "ptr", pDesc)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IDXGIOutputDuplication_GetDesc(this, pDesc)
{
DllCall(NumGet(NumGet(this+0)+7*A_PtrSize), "ptr", this, "ptr", pDesc)
if ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IDXGIOutputDuplication_AcquireNextFrame(this, TimeoutInMilliseconds, pFrameInfo, ByRef ppDesktopResource)
{
hr := DllCall(NumGet(NumGet(this+0)+8*A_PtrSize), "ptr", this, "uint", TimeoutInMilliseconds, "ptr", pFrameInfo, "ptr*", ppDesktopResource)
if hr or ErrorLevel
{
if (hr&=0xFFFFFFFF) = 0x887A0027 ; DXGI_ERROR_WAIT_TIMEOUT
return "DXGI_ERROR_WAIT_TIMEOUT"
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
}
D3D11CreateDevice(pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, SDKVersion, ByRef ppDevice, ByRef pFeatureLevel, ByRef ppImmediateContext)
{
hr := DllCall("D3D11\D3D11CreateDevice", "ptr", pAdapter, "int", DriverType, "ptr", Software, "uint", Flags, "ptr", pFeatureLevels, "uint", FeatureLevels, "uint", SDKVersion, "ptr*", ppDevice, "ptr*", pFeatureLevel, "ptr*", ppImmediateContext)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
ID3D11Device_CreateTexture2D(this, pDesc, pInitialData, ByRef ppTexture2D)
{
hr := DllCall(NumGet(NumGet(this+0)+5*A_PtrSize), "ptr", this, "ptr", pDesc, "ptr", pInitialData, "ptr*", ppTexture2D)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IDXGIOutputDuplication_MapDesktopSurface(this, pLockedRect)
{
hr := DllCall(NumGet(NumGet(this+0)+12*A_PtrSize), "ptr", this, "ptr", pLockedRect)
if hr or ErrorLevel
{
if (hr&=0xFFFFFFFF) = 0x887A0004 ; DXGI_ERROR_UNSUPPORTED
return "DXGI_ERROR_UNSUPPORTED"
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
}
IDXGIOutputDuplication_UnMapDesktopSurface(this)
{
hr := DllCall(NumGet(NumGet(this+0)+13*A_PtrSize), "ptr", this)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IDXGIOutputDuplication_ReleaseFrame(this)
{
hr := DllCall(NumGet(NumGet(this+0)+14*A_PtrSize), "ptr", this)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IDXGIOutput1_DuplicateOutput(this, pDevice, ByRef ppOutputDuplication)
{
hr := DllCall(NumGet(NumGet(this+0)+22*A_PtrSize), "ptr", this, "ptr", pDevice, "ptr*", ppOutputDuplication)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IDXGISurface1_GetDC(this, Discard, ByRef phdc)
{
hr := DllCall(NumGet(NumGet(this+0)+11*A_PtrSize), "ptr", this, "int", Discard, "ptr*", phdc)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IDXGISurface1_ReleaseDC(this, pDirtyRect)
{
hr := DllCall(NumGet(NumGet(this+0)+12*A_PtrSize), "ptr", this, "ptr", pDirtyRect)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IDXGIOutput1_Query(IDXGIOutput)
{
hr := ComObjQuery(IDXGIOutput, "{00cddea8-939b-4b83-a340-a685226666cc}")
if !hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
return hr
}
ID3D11Texture2D_Query(desktop_resource)
{
hr := ComObjQuery(desktop_resource, "{6f15aaf2-d208-4e89-9ab4-489535d34f9c}")
if !hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
return hr
}
IDXGISurface1_Query(Texture2D)
{
hr := ComObjQuery(Texture2D, "{4AE63092-6327-4c1b-80AE-BFE12EA32B86}")
if !hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
return hr
}
ID3D11DeviceContext_CopyResource(this, pDstResource, pSrcResource)
{
hr := DllCall(NumGet(NumGet(this+0)+47*A_PtrSize), "ptr", this, "ptr", pDstResource, "ptr", pSrcResource)
if ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
ID3D11DeviceContext_CopySubresourceRegion(this, pDstResource, DstSubresource, DstX, DstY, DstZ, pSrcResource, SrcSubresource, pSrcBox)
{
hr := DllCall(NumGet(NumGet(this+0)+46*A_PtrSize), "ptr", this, "ptr", pDstResource, "uint", DstSubresource, "uint", DstX, "uint", DstY, "uint", DstZ, "ptr", pSrcResource, "uint", SrcSubresource, "ptr", pSrcBox)
if ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
ID3D11DeviceContext_Map(this, pResource, Subresource, MapType, MapFlags, pMappedResource)
{
hr := DllCall(NumGet(NumGet(this+0)+14*A_PtrSize), "ptr", this, "ptr", pResource, "uint", Subresource, "uint", MapType, "uint", MapFlags, "ptr", pMappedResource)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
ID3D11DeviceContext_Unmap(this, pResource, Subresource)
{
hr := DllCall(NumGet(NumGet(this+0)+15*A_PtrSize), "ptr", this, "ptr", pResource, "uint", Subresource)
if ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
GUID(ByRef GUID, sGUID)
{
VarSetCapacity(GUID, 16, 0)
return DllCall("ole32\CLSIDFromString", "WStr", sGUID, "Ptr", &GUID) >= 0 ? &GUID : ""
}
LOAD_DLL_Mfplat_Mfreadwrite()
{
if !DllCall("GetModuleHandle","str","Mfplat")
DllCall("LoadLibrary","Str", "Mfplat.dll", "ptr")
if !DllCall("GetModuleHandle","str","Mfreadwrite")
DllCall("LoadLibrary","Str", "Mfreadwrite.dll", "ptr")
}
MFStartup(version, dwFlags)
{
hr := DllCall("Mfplat.dll\MFStartup", "uint", version, "uint", dwFlags)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
MFShutdown()
{
hr := DllCall("Mfplat.dll\MFShutdown")
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
MFCreateSinkWriterFromURL(pwszOutputURL, pByteStream, pAttributes, ByRef ppSinkWriter)
{
hr := DllCall("Mfreadwrite.dll\MFCreateSinkWriterFromURL", "str", pwszOutputURL, "ptr", pByteStream, "ptr", pAttributes, "ptr*", ppSinkWriter)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
MFCreateMediaType(ByRef ppMFType)
{
hr := DllCall("Mfplat.dll\MFCreateMediaType", "ptr*", ppMFType)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
MFCreateAttributes(ByRef ppMFAttributes, cInitialSize)
{
hr := DllCall("Mfplat.dll\MFCreateAttributes", "ptr*", ppMFAttributes, "uint", cInitialSize)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
MFCreateSample(ByRef ppIMFSample)
{
hr := DllCall("Mfplat.dll\MFCreateSample", "ptr*", ppIMFSample)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
MFCreateMemoryBuffer(cbMaxLength, ByRef ppBuffer)
{
hr := DllCall("Mfplat.dll\MFCreateMemoryBuffer", "uint", cbMaxLength, "ptr*", ppBuffer)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
MFCopyImage(pDest, lDestStride, pSrc, lSrcStride, dwWidthInBytes, dwLines)
{
hr := DllCall("Mfplat.dll\MFCopyImage", "ptr", pDest, "int", lDestStride, "ptr", pSrc, "int", lSrcStride, "uint", dwWidthInBytes, "uint", dwLines)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFAttributes_SetUINT32(this, guidKey, unValue)
{
hr := DllCall(NumGet(NumGet(this+0)+21*A_PtrSize), "ptr", this, "ptr", guidKey, "uint", unValue)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFAttributes_SetUINT64(this, guidKey, unValue)
{
hr := DllCall(NumGet(NumGet(this+0)+22*A_PtrSize), "ptr", this, "ptr", guidKey, "uint64", unValue)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFAttributes_SetGUID(this, guidKey, guidValue)
{
hr := DllCall(NumGet(NumGet(this+0)+24*A_PtrSize), "ptr", this, "ptr", guidKey, "ptr", guidValue)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFSinkWriter_AddStream(this, pMediaTypeOut, ByRef pdwStreamIndex)
{
hr := DllCall(NumGet(NumGet(this+0)+3*A_PtrSize), "ptr", this, "ptr", pMediaTypeOut, "ptr*", pdwStreamIndex)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFSinkWriter_SetInputMediaType(this, dwStreamIndex, pInputMediaType, pEncodingParameters)
{
hr := DllCall(NumGet(NumGet(this+0)+4*A_PtrSize), "ptr", this, "uint", dwStreamIndex, "ptr", pInputMediaType, "ptr", pEncodingParameters)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFSinkWriter_BeginWriting(this)
{
hr := DllCall(NumGet(NumGet(this+0)+5*A_PtrSize), "ptr", this)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFSinkWriter_WriteSample(this, dwStreamIndex, pSample)
{
hr := DllCall(NumGet(NumGet(this+0)+6*A_PtrSize), "ptr", this, "uint", dwStreamIndex, "ptr", pSample)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFSinkWriter_Finalize(this)
{
hr := DllCall(NumGet(NumGet(this+0)+11*A_PtrSize), "ptr", this)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFMediaBuffer_Lock(this, ByRef ppbBuffer, ByRef pcbMaxLength, ByRef pcbCurrentLength)
{
hr := DllCall(NumGet(NumGet(this+0)+3*A_PtrSize), "ptr", this, "ptr*", ppbBuffer, "uint*", pcbMaxLength, "uint*", pcbCurrentLength)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFMediaBuffer_Unlock(this)
{
hr := DllCall(NumGet(NumGet(this+0)+4*A_PtrSize), "ptr", this)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFMediaBuffer_SetCurrentLength(this, cbCurrentLength)
{
hr := DllCall(NumGet(NumGet(this+0)+6*A_PtrSize), "ptr", this, "uint", cbCurrentLength)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFSample_AddBuffer(this, pBuffer)
{
hr := DllCall(NumGet(NumGet(this+0)+42*A_PtrSize), "ptr", this, "ptr", pBuffer)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFSample_SetSampleTime(this, hnsSampleTime)
{
hr := DllCall(NumGet(NumGet(this+0)+36*A_PtrSize), "ptr", this, "int64", hnsSampleTime)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFSample_SetSampleDuration(this, hnsSampleDuration)
{
hr := DllCall(NumGet(NumGet(this+0)+38*A_PtrSize), "ptr", this, "int64", hnsSampleDuration)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
MF_GUID(ByRef GUID, name)
{
static init:=1, _:={}
if init
{
init:=0
_.MF_MT_MAJOR_TYPE := [0x48eba18e, 0xf8c9, 0x4687, 0xbf, 0x11, 0x0a, 0x74, 0xc9, 0xf9, 0x6a, 0x8f]
,_.MF_MT_SUBTYPE := [0xf7e34c9a, 0x42e8, 0x4714, 0xb7, 0x4b, 0xcb, 0x29, 0xd7, 0x2c, 0x35, 0xe5]
,_.MF_MT_AVG_BITRATE := [0x20332624, 0xfb0d, 0x4d9e, 0xbd, 0x0d, 0xcb, 0xf6, 0x78, 0x6c, 0x10, 0x2e]
,_.MF_MT_INTERLACE_MODE := [0xe2724bb8, 0xe676, 0x4806, 0xb4, 0xb2, 0xa8, 0xd6, 0xef, 0xb4, 0x4c, 0xcd]
,_.MF_MT_FRAME_SIZE := [0x1652c33d, 0xd6b2, 0x4012, 0xb8, 0x34, 0x72, 0x03, 0x08, 0x49, 0xa3, 0x7d]
,_.MF_MT_FRAME_RATE := [0xc459a2e8, 0x3d2c, 0x4e44, 0xb1, 0x32, 0xfe, 0xe5, 0x15, 0x6c, 0x7b, 0xb0]
,_.MF_MT_PIXEL_ASPECT_RATIO := [0xc6376a1e, 0x8d0a, 0x4027, 0xbe, 0x45, 0x6d, 0x9a, 0x0a, 0xd3, 0x9b, 0xb6]
,_.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]
,_.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]
,_.MFMediaType_Video := [0x73646976, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71]
,_.MFVideoFormat_H264 := [0x34363248, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71] ; FCC("H264") = 0x34363248
,_.MFVideoFormat_RGB32 := [0x00000016, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71]
,_.MFVideoFormat_ARGB32 := [0x00000015, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71]
}
if _.haskey(name)
{
p := _[name]
VarSetCapacity(GUID,16)
,NumPut(p.1+(p.2<<32)+(p.3<<48),GUID,0,"int64")
,NumPut(p.4+(p.5<<8)+(p.6<<16)+(p.7<<24)+(p.8<<32)+(p.9<<40)+(p.10<<48)+(p.11<<56),GUID,8,"int64")
return &GUID
}
else return name
}
FCC(var)
{
c := StrSplit(var)
msgbox % clipboard := Format("{:#x}",((Asc(c[1])&255)+((Asc(c[2])&255)<<8)+((Asc(c[3])&255)<<16)+((Asc(c[4])&255)<<24)))
}
Release(this)
{
DllCall(NumGet(NumGet(this+0)+2*A_PtrSize), "ptr", this)
if ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
_Error(val)
{
msgbox % val
ExitApp
}
Проапдейтился, старая тоже вылетела.
Работает, только если hardware_encoding := false.
А так у тебя выходит 45056?
Setbatchlines -1
IDXGIFactory := CreateDXGIFactory()
if !IDXGIFactory
{
MsgBox, 16, Error, Create IDXGIFactory failed.
ExitApp
}
loop
{
IDXGIFactory_EnumAdapters(IDXGIFactory, A_Index-1, IDXGIAdapter)
loop
{
hr := IDXGIAdapter_EnumOutputs(IDXGIAdapter, A_Index-1, IDXGIOutput)
if (hr = "DXGI_ERROR_NOT_FOUND")
break
VarSetCapacity(DXGI_OUTPUT_DESC, 88+A_PtrSize, 0)
IDXGIOutput_GetDesc(IDXGIOutput, &DXGI_OUTPUT_DESC)
Width := NumGet(DXGI_OUTPUT_DESC, 72, "int")
Height := NumGet(DXGI_OUTPUT_DESC, 76, "int")
AttachedToDesktop := NumGet(DXGI_OUTPUT_DESC, 80, "int")
if (AttachedToDesktop = 1)
break 2
}
}
if (AttachedToDesktop != 1)
{
MsgBox, 16, Error, No adapter attached to desktop
ExitApp
}
D3D11CreateDevice(IDXGIAdapter, D3D_DRIVER_TYPE_UNKNOWN := 0, 0, 0, 0, 0, D3D11_SDK_VERSION := 7, d3d_device, D3D_FEATURE_LEVEL, d3d_context)
msgbox % clipboard := D3D_FEATURE_LEVEL
ExitApp
CreateDXGIFactory()
{
if !DllCall("GetModuleHandle","str","DXGI")
DllCall("LoadLibrary","str","DXGI")
if !DllCall("GetModuleHandle","str","D3D11")
DllCall("LoadLibrary","str","D3D11")
GUID(riid, "{7b7166ec-21c7-44ae-b21a-c9ae321ae369}")
hr := DllCall("DXGI\CreateDXGIFactory1", "ptr", &riid, "ptr*", ppFactory)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
return ppFactory
}
IDXGIFactory_EnumAdapters(this, Adapter, ByRef ppAdapter)
{
hr := DllCall(NumGet(NumGet(this+0)+7*A_PtrSize), "ptr", this, "uint", Adapter, "ptr*", ppAdapter)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IDXGIAdapter_EnumOutputs(this, Output, ByRef ppOutput)
{
hr := DllCall(NumGet(NumGet(this+0)+7*A_PtrSize), "ptr", this, "uint", Output, "ptr*", ppOutput)
if hr or ErrorLevel
{
if (hr&=0xFFFFFFFF) = 0x887A0002 ; DXGI_ERROR_NOT_FOUND
return "DXGI_ERROR_NOT_FOUND"
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
}
IDXGIAdapter_GetDesc(this, pDesc)
{
hr := DllCall(NumGet(NumGet(this+0)+8*A_PtrSize), "ptr", this, "ptr", pDesc)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IDXGIOutput_GetDesc(this, pDesc)
{
hr := DllCall(NumGet(NumGet(this+0)+7*A_PtrSize), "ptr", this, "ptr", pDesc)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IDXGIOutputDuplication_GetDesc(this, pDesc)
{
DllCall(NumGet(NumGet(this+0)+7*A_PtrSize), "ptr", this, "ptr", pDesc)
if ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IDXGIOutputDuplication_AcquireNextFrame(this, TimeoutInMilliseconds, pFrameInfo, ByRef ppDesktopResource)
{
hr := DllCall(NumGet(NumGet(this+0)+8*A_PtrSize), "ptr", this, "uint", TimeoutInMilliseconds, "ptr", pFrameInfo, "ptr*", ppDesktopResource)
if hr or ErrorLevel
{
if (hr&=0xFFFFFFFF) = 0x887A0027 ; DXGI_ERROR_WAIT_TIMEOUT
return "DXGI_ERROR_WAIT_TIMEOUT"
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
}
D3D11CreateDevice(pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, SDKVersion, ByRef ppDevice, ByRef pFeatureLevel, ByRef ppImmediateContext)
{
hr := DllCall("D3D11\D3D11CreateDevice", "ptr", pAdapter, "int", DriverType, "ptr", Software, "uint", Flags, "ptr", pFeatureLevels, "uint", FeatureLevels, "uint", SDKVersion, "ptr*", ppDevice, "ptr*", pFeatureLevel, "ptr*", ppImmediateContext)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
ID3D11Device_CreateTexture2D(this, pDesc, pInitialData, ByRef ppTexture2D)
{
hr := DllCall(NumGet(NumGet(this+0)+5*A_PtrSize), "ptr", this, "ptr", pDesc, "ptr", pInitialData, "ptr*", ppTexture2D)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IDXGIOutputDuplication_MapDesktopSurface(this, pLockedRect)
{
hr := DllCall(NumGet(NumGet(this+0)+12*A_PtrSize), "ptr", this, "ptr", pLockedRect)
if hr or ErrorLevel
{
if (hr&=0xFFFFFFFF) = 0x887A0004 ; DXGI_ERROR_UNSUPPORTED
return "DXGI_ERROR_UNSUPPORTED"
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
}
IDXGIOutputDuplication_UnMapDesktopSurface(this)
{
hr := DllCall(NumGet(NumGet(this+0)+13*A_PtrSize), "ptr", this)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IDXGIOutputDuplication_ReleaseFrame(this)
{
hr := DllCall(NumGet(NumGet(this+0)+14*A_PtrSize), "ptr", this)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IDXGIOutput1_DuplicateOutput(this, pDevice, ByRef ppOutputDuplication)
{
hr := DllCall(NumGet(NumGet(this+0)+22*A_PtrSize), "ptr", this, "ptr", pDevice, "ptr*", ppOutputDuplication)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IDXGISurface1_GetDC(this, Discard, ByRef phdc)
{
hr := DllCall(NumGet(NumGet(this+0)+11*A_PtrSize), "ptr", this, "int", Discard, "ptr*", phdc)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IDXGISurface1_ReleaseDC(this, pDirtyRect)
{
hr := DllCall(NumGet(NumGet(this+0)+12*A_PtrSize), "ptr", this, "ptr", pDirtyRect)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IDXGIOutput1_Query(IDXGIOutput)
{
hr := ComObjQuery(IDXGIOutput, "{00cddea8-939b-4b83-a340-a685226666cc}")
if !hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
return hr
}
ID3D11Texture2D_Query(desktop_resource)
{
hr := ComObjQuery(desktop_resource, "{6f15aaf2-d208-4e89-9ab4-489535d34f9c}")
if !hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
return hr
}
IDXGISurface1_Query(Texture2D)
{
hr := ComObjQuery(Texture2D, "{4AE63092-6327-4c1b-80AE-BFE12EA32B86}")
if !hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
return hr
}
ID3D11DeviceContext_CopyResource(this, pDstResource, pSrcResource)
{
hr := DllCall(NumGet(NumGet(this+0)+47*A_PtrSize), "ptr", this, "ptr", pDstResource, "ptr", pSrcResource)
if ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
ID3D11DeviceContext_CopySubresourceRegion(this, pDstResource, DstSubresource, DstX, DstY, DstZ, pSrcResource, SrcSubresource, pSrcBox)
{
hr := DllCall(NumGet(NumGet(this+0)+46*A_PtrSize), "ptr", this, "ptr", pDstResource, "uint", DstSubresource, "uint", DstX, "uint", DstY, "uint", DstZ, "ptr", pSrcResource, "uint", SrcSubresource, "ptr", pSrcBox)
if ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
ID3D11DeviceContext_Map(this, pResource, Subresource, MapType, MapFlags, pMappedResource)
{
hr := DllCall(NumGet(NumGet(this+0)+14*A_PtrSize), "ptr", this, "ptr", pResource, "uint", Subresource, "uint", MapType, "uint", MapFlags, "ptr", pMappedResource)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
ID3D11DeviceContext_Unmap(this, pResource, Subresource)
{
hr := DllCall(NumGet(NumGet(this+0)+15*A_PtrSize), "ptr", this, "ptr", pResource, "uint", Subresource)
if ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
LOAD_DLL_Mf_Mfplat_Mfreadwrite()
{
if !DllCall("GetModuleHandle","str","Mf")
DllCall("LoadLibrary","Str", "Mf.dll", "ptr")
if !DllCall("GetModuleHandle","str","Mfplat")
DllCall("LoadLibrary","Str", "Mfplat.dll", "ptr")
if !DllCall("GetModuleHandle","str","Mfreadwrite")
DllCall("LoadLibrary","Str", "Mfreadwrite.dll", "ptr")
}
MFStartup(version, dwFlags)
{
hr := DllCall("Mfplat.dll\MFStartup", "uint", version, "uint", dwFlags)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
MFShutdown()
{
hr := DllCall("Mfplat.dll\MFShutdown")
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
MFTEnumEx(guidCategory, Flags, pInputType, pOutputType)
{
if (A_PtrSize = 8)
hr := DllCall("Mfplat\MFTEnumEx", "ptr", guidCategory, "uint", Flags, "ptr", pInputType, "ptr", pOutputType, "ptr*", pppMFTActivate, "uint*", pnumMFTActivate)
else
hr := DllCall("Mfplat\MFTEnumEx", "uint64", NumGet(guidCategory+0, 0, "uint64"), "uint64", NumGet(guidCategory+0, 8, "uint64"), "uint", Flags, "ptr", pInputType, "ptr", pOutputType, "ptr*", pppMFTActivate, "uint*", pnumMFTActivate)
loop % pnumMFTActivate
{
IMFActivate := NumGet(pppMFTActivate + (A_Index - 1)*A_PtrSize)
if (A_Index = 1)
hardware_encoder := IMFActivate_GetAllocatedString(IMFActivate, MF_GUID(GUID, "MFT_FRIENDLY_NAME_Attribute"))
Release(IMFActivate)
}
DllCall("ole32\CoTaskMemFree", "ptr", pppMFTActivate)
return hardware_encoder
}
MFCreateSinkWriterFromURL(pwszOutputURL, pByteStream, pAttributes, ByRef ppSinkWriter)
{
hr := DllCall("Mfreadwrite.dll\MFCreateSinkWriterFromURL", "str", pwszOutputURL, "ptr", pByteStream, "ptr", pAttributes, "ptr*", ppSinkWriter)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
MFCreateSourceReaderFromMediaSource(pMediaSource, pAttributes, ByRef ppSourceReader)
{
hr := DllCall("Mfreadwrite.dll\MFCreateSourceReaderFromMediaSource", "ptr", pMediaSource, "ptr", pAttributes, "ptr*", ppSourceReader)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
MFCreateMediaType(ByRef ppMFType)
{
hr := DllCall("Mfplat.dll\MFCreateMediaType", "ptr*", ppMFType)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
MFCreateAttributes(ByRef ppMFAttributes, cInitialSize)
{
hr := DllCall("Mfplat.dll\MFCreateAttributes", "ptr*", ppMFAttributes, "uint", cInitialSize)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
MFCreateSample(ByRef ppIMFSample)
{
hr := DllCall("Mfplat.dll\MFCreateSample", "ptr*", ppIMFSample)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
MFCreateMemoryBuffer(cbMaxLength, ByRef ppBuffer)
{
hr := DllCall("Mfplat.dll\MFCreateMemoryBuffer", "uint", cbMaxLength, "ptr*", ppBuffer)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
MFCopyImage(pDest, lDestStride, pSrc, lSrcStride, dwWidthInBytes, dwLines)
{
hr := DllCall("Mfplat.dll\MFCopyImage", "ptr", pDest, "int", lDestStride, "ptr", pSrc, "int", lSrcStride, "uint", dwWidthInBytes, "uint", dwLines)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
MFEnumDeviceSources(pAttributes, ByRef pppSourceActivate, ByRef pcSourceActivate)
{
hr := DllCall("Mf.dll\MFEnumDeviceSources", "ptr", pAttributes, "ptr*", pppSourceActivate, "uint*", pcSourceActivate)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFSourceReader_SetCurrentMediaType(this, dwStreamIndex, pdwReserved, pMediaType)
{
hr := DllCall(NumGet(NumGet(this+0)+7*A_PtrSize), "ptr", this, "uint", dwStreamIndex, "uint", pdwReserved, "ptr", pMediaType)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFSourceReader_GetNativeMediaType(this, dwStreamIndex, dwMediaTypeIndex, ByRef ppMediaType)
{
hr := DllCall(NumGet(NumGet(this+0)+5*A_PtrSize), "ptr", this, "uint", dwStreamIndex, "uint", dwMediaTypeIndex, "ptr*", ppMediaType)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFSourceReader_ReadSample(this, dwStreamIndex, dwControlFlags, ByRef pdwActualStreamIndex, ByRef pdwStreamFlags, ByRef pllTimestamp, ByRef ppSample)
{
hr := DllCall(NumGet(NumGet(this+0)+9*A_PtrSize), "ptr", this, "uint", dwStreamIndex, "uint", dwControlFlags, "uint*", pdwActualStreamIndex, "uint*", pdwStreamFlags, "int64*", pllTimestamp, "ptr*", ppSample)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFMediaType_GetGUID(this, guidKey, ByRef pguidValue)
{
VarSetCapacity(pguidValue, 16, 0)
hr := DllCall(NumGet(NumGet(this+0)+10*A_PtrSize), "ptr", this, "ptr", guidKey, "ptr", &pguidValue)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
return &pguidValue
}
IMFMediaType_GetUINT32(this, guidKey, ByRef punValue)
{
hr := DllCall(NumGet(NumGet(this+0)+7*A_PtrSize), "ptr", this, "ptr", guidKey, "uint*", punValue)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFAttributes_SetUINT32(this, guidKey, unValue)
{
hr := DllCall(NumGet(NumGet(this+0)+21*A_PtrSize), "ptr", this, "ptr", guidKey, "uint", unValue)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFAttributes_SetUINT64(this, guidKey, unValue)
{
hr := DllCall(NumGet(NumGet(this+0)+22*A_PtrSize), "ptr", this, "ptr", guidKey, "uint64", unValue)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFAttributes_SetGUID(this, guidKey, guidValue)
{
hr := DllCall(NumGet(NumGet(this+0)+24*A_PtrSize), "ptr", this, "ptr", guidKey, "ptr", guidValue)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFActivate_GetAllocatedString(this, guidKey)
{
hr := DllCall(NumGet(NumGet(this+0)+13*A_PtrSize), "ptr", this, "ptr", guidKey, "ptr*", ppwszValue, "uint*", pcchLength)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
AllocatedString := StrGet(ppwszValue, pcchLength, "UTF-16")
DllCall("ole32\CoTaskMemFree", "ptr", ppwszValue)
return AllocatedString
}
IMFActivate_ActivateObject(this, riid, ByRef ppv)
{
GUID(riid, riid)
hr := DllCall(NumGet(NumGet(this+0)+33*A_PtrSize), "ptr", this, "ptr", &riid, "ptr*", ppv)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFSinkWriter_SendStreamTick(this, dwStreamIndex, llTimestamp)
{
hr := DllCall(NumGet(NumGet(this+0)+7*A_PtrSize), "ptr", this, "uint", dwStreamIndex, "int64", llTimestamp)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFSinkWriter_AddStream(this, pMediaTypeOut, ByRef pdwStreamIndex)
{
hr := DllCall(NumGet(NumGet(this+0)+3*A_PtrSize), "ptr", this, "ptr", pMediaTypeOut, "ptr*", pdwStreamIndex)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFSinkWriter_SetInputMediaType(this, dwStreamIndex, pInputMediaType, pEncodingParameters)
{
hr := DllCall(NumGet(NumGet(this+0)+4*A_PtrSize), "ptr", this, "uint", dwStreamIndex, "ptr", pInputMediaType, "ptr", pEncodingParameters)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFSinkWriter_BeginWriting(this)
{
hr := DllCall(NumGet(NumGet(this+0)+5*A_PtrSize), "ptr", this)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFSinkWriter_WriteSample(this, dwStreamIndex, pSample)
{
hr := DllCall(NumGet(NumGet(this+0)+6*A_PtrSize), "ptr", this, "uint", dwStreamIndex, "ptr", pSample)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFSinkWriter_Finalize(this)
{
hr := DllCall(NumGet(NumGet(this+0)+11*A_PtrSize), "ptr", this)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFMediaBuffer_Lock(this, ByRef ppbBuffer, ByRef pcbMaxLength, ByRef pcbCurrentLength)
{
hr := DllCall(NumGet(NumGet(this+0)+3*A_PtrSize), "ptr", this, "ptr*", ppbBuffer, "uint*", pcbMaxLength, "uint*", pcbCurrentLength)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFMediaBuffer_Unlock(this)
{
hr := DllCall(NumGet(NumGet(this+0)+4*A_PtrSize), "ptr", this)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFMediaBuffer_SetCurrentLength(this, cbCurrentLength)
{
hr := DllCall(NumGet(NumGet(this+0)+6*A_PtrSize), "ptr", this, "uint", cbCurrentLength)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFSample_AddBuffer(this, pBuffer)
{
hr := DllCall(NumGet(NumGet(this+0)+42*A_PtrSize), "ptr", this, "ptr", pBuffer)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFSample_SetSampleTime(this, hnsSampleTime)
{
hr := DllCall(NumGet(NumGet(this+0)+36*A_PtrSize), "ptr", this, "int64", hnsSampleTime)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFSample_GetSampleDuration(this, ByRef phnsSampleDuration)
{
hr := DllCall(NumGet(NumGet(this+0)+37*A_PtrSize), "ptr", this, "int64*", phnsSampleDuration)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IMFSample_SetSampleDuration(this, hnsSampleDuration)
{
hr := DllCall(NumGet(NumGet(this+0)+38*A_PtrSize), "ptr", this, "int64", hnsSampleDuration)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
MF_GUID(ByRef GUID, name)
{
static init:=1, _:={}
if init
{
init:=0
_.MF_MT_MAJOR_TYPE := [0x48eba18e, 0xf8c9, 0x4687, 0xbf, 0x11, 0x0a, 0x74, 0xc9, 0xf9, 0x6a, 0x8f]
_.MF_MT_SUBTYPE := [0xf7e34c9a, 0x42e8, 0x4714, 0xb7, 0x4b, 0xcb, 0x29, 0xd7, 0x2c, 0x35, 0xe5]
_.MF_MT_AVG_BITRATE := [0x20332624, 0xfb0d, 0x4d9e, 0xbd, 0x0d, 0xcb, 0xf6, 0x78, 0x6c, 0x10, 0x2e]
_.MF_MT_INTERLACE_MODE := [0xe2724bb8, 0xe676, 0x4806, 0xb4, 0xb2, 0xa8, 0xd6, 0xef, 0xb4, 0x4c, 0xcd]
_.MF_MT_FRAME_SIZE := [0x1652c33d, 0xd6b2, 0x4012, 0xb8, 0x34, 0x72, 0x03, 0x08, 0x49, 0xa3, 0x7d]
_.MF_MT_FRAME_RATE := [0xc459a2e8, 0x3d2c, 0x4e44, 0xb1, 0x32, 0xfe, 0xe5, 0x15, 0x6c, 0x7b, 0xb0]
_.MF_MT_PIXEL_ASPECT_RATIO := [0xc6376a1e, 0x8d0a, 0x4027, 0xbe, 0x45, 0x6d, 0x9a, 0x0a, 0xd3, 0x9b, 0xb6]
_.MF_MT_AUDIO_AVG_BYTES_PER_SECOND := [0x1aab75c8, 0xcfef, 0x451c, 0xab, 0x95, 0xac, 0x03, 0x4b, 0x8e, 0x17, 0x31]
_.MF_MT_AUDIO_BLOCK_ALIGNMENT := [0x322de230, 0x9eeb, 0x43bd, 0xab, 0x7a, 0xff, 0x41, 0x22, 0x51, 0x54, 0x1d]
_.MF_MT_AUDIO_SAMPLES_PER_SECOND := [0x5faeeae7, 0x0290, 0x4c31, 0x9e, 0x8a, 0xc5, 0x34, 0xf6, 0x8d, 0x9d, 0xba]
_.MF_MT_AUDIO_BITS_PER_SAMPLE := [0xf2deb57f, 0x40fa, 0x4764, 0xaa, 0x33, 0xed, 0x4f, 0x2d, 0x1f, 0xf6, 0x69]
_.MF_MT_AUDIO_NUM_CHANNELS := [0x37e48bf5, 0x645e, 0x4c5b, 0x89, 0xde, 0xad, 0xa9, 0xe2, 0x9b, 0x69, 0x6a]
_.MFT_CATEGORY_VIDEO_ENCODER := [0xf79eac7d, 0xe545, 0x4387, 0xbd, 0xee, 0xd6, 0x47, 0xd7, 0xbd, 0xe4, 0x2a]
_.MF_TRANSCODE_CONTAINERTYPE := [0x150ff23f, 0x4abc, 0x478b, 0xac, 0x4f, 0xe1, 0x91, 0x6f, 0xba, 0x1c, 0xca]
_.MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS := [0xa634a91c, 0x822b, 0x41b9, 0xa4, 0x94, 0x4d, 0xe4, 0x64, 0x36, 0x12, 0xb0]
_.MFTranscodeContainerType_MPEG4 := [0xdc6cd05d, 0xb9d0, 0x40ef, 0xbd, 0x35, 0xfa, 0x62, 0x2c, 0x1a, 0xb2, 0x8a]
_.MFT_FRIENDLY_NAME_Attribute := [0x314ffbae, 0x5b41, 0x4c95, 0x9c, 0x19, 0x4e, 0x7d, 0x58, 0x6f, 0xac, 0xe3]
_.MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME := [0x60d0e559, 0x52f8, 0x4fa2, 0xbb, 0xce, 0xac, 0xdb, 0x34, 0xa8, 0xec, 0x1]
_.MF_SINK_WRITER_DISABLE_THROTTLING := [0x08b845d8, 0x2b74, 0x4afe, 0x9d, 0x53, 0xbe, 0x16, 0xd2, 0xd5, 0xae, 0x4f]
_.MF_LOW_LATENCY := [0x9c27891a, 0xed7a, 0x40e1, 0x88, 0xe8, 0xb2, 0x27, 0x27, 0xa0, 0x24, 0xee]
_.MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE := [0xc60ac5fe, 0x252a, 0x478f, 0xa0, 0xef, 0xbc, 0x8f, 0xa5, 0xf7, 0xca, 0xd3]
_.MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_GUID := [0x14dd9a1c, 0x7cff, 0x41be, 0xb1, 0xb9, 0xba, 0x1a, 0xc6, 0xec, 0xb5, 0x71]
_.MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID := [0x8ac3587a, 0x4ae7, 0x42d8, 0x99, 0xe0, 0x0a, 0x60, 0x13, 0xee, 0xf9, 0x0f]
_.MFSampleExtension_Discontinuity := [0x9cdf01d9, 0xa0f0, 0x43ba, 0xb0, 0x77, 0xea, 0xa0, 0x6c, 0xbd, 0x72, 0x8a]
_.MFMediaType_Video := [0x73646976, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71]
_.MFMediaType_Audio := [0x73647561, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71]
_.MFAudioFormat_AAC := [0x1610, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71]
_.MFAudioFormat_Float := [0x0003, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71]
_.MFAudioFormat_PCM := [0x0001, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71]
_.MFVideoFormat_H264 := [0x34363248, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71] ; FCC("H264") = 0x34363248
_.MFVideoFormat_RGB32 := [0x00000016, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71]
_.MFVideoFormat_ARGB32 := [0x00000015, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71]
}
if _.haskey(name)
{
p := _[name]
VarSetCapacity(GUID,16)
,NumPut(p.1+(p.2<<32)+(p.3<<48),GUID,0,"int64")
,NumPut(p.4+(p.5<<8)+(p.6<<16)+(p.7<<24)+(p.8<<32)+(p.9<<40)+(p.10<<48)+(p.11<<56),GUID,8,"int64")
return &GUID
}
else return name
}
GUID(ByRef GUID, sGUID)
{
VarSetCapacity(GUID, 16, 0)
return DllCall("ole32\CLSIDFromString", "WStr", sGUID, "Ptr", &GUID) >= 0 ? &GUID : ""
}
FCC(var)
{
c := StrSplit(var)
msgbox % clipboard := Format("{:#x}",((Asc(c[1])&255)+((Asc(c[2])&255)<<8)+((Asc(c[3])&255)<<16)+((Asc(c[4])&255)<<24)))
}
Release(this)
{
DllCall(NumGet(NumGet(this+0)+2*A_PtrSize), "ptr", this)
if ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
_Error(val)
{
msgbox % val
ExitApp
}
checkCoordinates(ByRef start1, ByRef end1, ByRef start2, ByRef end2, hardware_encoder:="")
{
if InStr(hardware_encoder, "NVIDIA")
min1 := 33, min2 := 17
else if A_OSVersion in WIN_XP,WIN_VISTA,WIN_7
min1 := min2 := 64
else
min1 := min2 := 33
max1 := A_ScreenWidth, max2 := A_ScreenHeight
loop 2
{
if (end%A_Index% - start%A_Index% < min%A_Index%)
{
end%A_Index% := start%A_Index% + min%A_Index%
if !InStr(hardware_encoder, "NVIDIA") and (mod(end%A_Index% - start%A_Index%, 2) != 0)
end%A_Index%++
if (end%A_Index% > max%A_Index%)
{
start%A_Index% += max%A_Index%-end%A_Index%
end%A_Index% := max%A_Index%
}
}
}
}
Появляется.
Не знаю в чем причина такого поведения и какие параметры проверять у видеокарты.
Поэтому просто добавил условие CaptureCoordinatesWithCPU := true.
Ещё у тебя курсор не в том месте. hotspot надо учитывать.
Да. Поправил.
Перемудрил немного.
hCursor := NumGet(CURSORINFO, 8)
xCursor := NumGet(CURSORINFO, 8 + A_PtrSize, "Int")
yCursor := NumGet(CURSORINFO, 12 + A_PtrSize, "Int")
VarSetCapacity(ICONINFO, 8 + A_PtrSize*3, 0)
DllCall("GetIconInfo", "Ptr", hCursor, "Ptr", &ICONINFO)
xHotspot := NumGet(ICONINFO, 4, "UInt")
yHotspot := NumGet(ICONINFO, 8, "UInt")
xCursor -= xHotspot, yCursor -= yHotspot
А почему ты это убрал?
hbmMask := NumGet(ICONINFO, 8 + A_PtrSize)
hbmColor := NumGet(ICONINFO, 8 + A_PtrSize*2)
if hbmMask
DllCall("DeleteObject", "ptr", hbmMask)
if hbmColor
DllCall("DeleteObject", "ptr", hbmColor)
Эти же хендлы удалять надо.
Без CopyIcon работает, но тут почему-то автор для сохранения курсора эту функцию использует.
https://www.codeproject.com/Articles/12 … use-Cursor
Эти же хендлы удалять надо
Я не уверен, это ведь хендлы существующего курсора, а не копии, так что может и не надо.
Там же написано.
Remarks
GetIconInfo creates bitmaps for the hbmMask and hbmColor members of ICONINFO. The calling application must manage these bitmaps and delete them when they are no longer necessary.
https://docs.microsoft.com/en-us/window … eticoninfo
Да и меняются они с каждым запросом.
Так что надо.
А, точно.
Думаю, алгоритм захвата видеокартинки со звуком тут у меня не совсем верный.
Например, если процессор либо видеокарта не потянет захват 25 кадров в секунду, то звук будет пропадать.
Поэтому надо смотреть в сторону асинхронного получения сэмплов в IMFSourceReader::ReadSample.
Но там придется самому создавать IUknown интерфейс и колбэк на него.
Спасибо.
Не знал о такой возможности.
Изменил скрипт в первом посте на асинхронное подключение к аудиоустройству.
Для Windows 7 выдаёт ошибку, если число пикселей ширины или высоты нечётное. Также, как я понял, не определяется доступность hardware_encoding.
Да, надо будет поправить.
И заодно поддержку звука присобачить.
Поизучал тему с Windows 7, там надо делать ресэмплинг c FLOAT 32 bit на PCM 16 bit с помощью
https://docs.microsoft.com/en-us/window … oresampler
После чего записывать в файл через буфер, как это делаем с видео.
Пока нет времени этим заняться, но позже когда-нибудь доберусь до этого.
Вроде перенес для Windows 7, но проверить не могу - компьютер с Win-7 очень слабый.
Отлично, у меня работает! Но осталась проблема с нечётным количеством пикселей. На 58 строке MsgBox выскакивает.
Это я специально оставил.
А у тебя выскакивает ускорение с Nvidia?
Нет, никаких больше сообщений не было.
Я имею в виду, когда выходит это сообщение, то там написано
hardware-encoder - NVIDIA H.264 Encoder MFT
?
Нет, только hardware-encoder -
Вроде поправил.
Странно, что у тебя вообще не находит железного ускорения.
Так у меня на Window 7 его вроде и не должно быть.
Шапку потерял:
file := "test.mp4"
video_bitrate := 2000000
video_fps := 25
duration := 5
capture_cursor := true
audiodevice := "CABLE Output (VB-Audio Virtual Cable)"
; x1 := 100, x2 := 1000, y1 := 100, y2 := 500
; ShowAllAudioDevicesNames := true
Шапку вернул.
Я думаю здесь дело не в версии Windows, а в железе.
Потому как у меня на Win-7 показывает.
Я думаю здесь дело не в версии Windows, а в железе.
Да, оно же hardware. У меня семёрка на старом компьютере.
Исправил немного версию для Win-7.
Исправил неточный алгоритм распределения кадров.
Теперь кушает больше CPU, но это ИМХО естесственно для реалтайм энкодинга.
Проверил скрипт в поле.
Исправил несколько серьёзных багов, добавил опции + уменьшил нагрузку на проц.
Отлично! Интересная тема, хочу сделать интерфейс, чтобы мышью выделять область на экране, и записывать видео. Уже такое сделал для gif, только файл слишком толстый выходит, если цветов много.
А паковать гиф не пробовал через сторонний софт?
Или всё-равно файл большой?
Пробовал то, на что ты давал ссылку, уменьшает. Насколько — тоже зависит от количества цветов. Но если файл выходит 20 МБ, то тут уменьшай-не уменьшай, всё равно много получается.
Добавил кавычки в перечислении устройств + добавил энумерацию устройств с одинаковым именем.
А ты не интересовался, как можно исключить какие-либо окна из записи?
Если исключить, то самый простой вариант ИМХО через API лупы (пока его еще не убрали).
https://www.autohotkey.com/boards/viewt … 02#p299602
guest3456 подправил для обеих битностей.
Пока подробно не разбирался, а так можно исключить окно из записи видео? Там вроде исключается только для окна Magnifier.
Тут не имеет значения, пишем мы видео или сохраняем картинку.
API лупы дает возможность получить снимок экрана без ненужных нам окон, а так же дает возможность получить только нужные нам окна (работает только на виста).
То есть, из кода надо убрать всё, что касается DirectX и получать снимок экрана через лупу, который потом уже отправлять в SinkWriter.
А, теперь понял, попробую.
Кстати, а зачем тебе исключать окна?
Если сделать окно для интерфейса, предполагаю исключить его при съёмке всего экрана.
Тогда можно посмотреть в сторону WinRT Capture.
https://docs.microsoft.com/en-us/window … en-capture
https://blogs.windows.com/windowsdevelo … n-capture/
Так это вроде только для Windows 10.
Да. Я в том плане, чтоб подстраховаться на случай если апи лупы уберут в следующих апдейтах windows 10.
На Win7 он уже по-любому останется.
Тогда да, для десятки можно этим воспользоваться. Пока ещё руки не дошли.
Странно, что на автохотки не используют UWP API.
Там достаточно интересных возможностей.
https://docs.microsoft.com/en-us/uwp/api/
Наверно, та же причина — только под Windows 10, а AHK-скриптеры любят универсальные решения.
А не хочешь просто минимизировать своё окно при начале записи?
А как тогда на стоп и на паузу нажимать? Можно, конечно, по горячим клавишам, но это как дополнительный вариант.
Можно еще в трее меню создать с паузой и стопом.
На оконном интерфейсе будет видно, что именно сейчас происходит, если как-то по-другому делать — не будет наглядно.
Да, пользуюсь OBS Studio, очень не удобно что его окно попадает в запись.
OBS Studio через DirectX захватывает.
Возможно лупу не используют из-за скорости (просто предположение, не проверял).
Если же захватывать через UWP, то скорость тоже походу плохая:
https://github.com/mika-sandbox/dotnet- … with-delay
Тоже боюсь, что через лупу будет снижена производительность. Может через SetWindowDisplayAffinity можно исключить?
Не, вряд ли, будет чёрный прямоугольник.
Malcev
В общем исключить окна сложно, но для записи нужных окон DwmThumbnail хорошая штука. На 7 и 10 работает. Правда, в этом контексте не знаю.
А DirectX только для игр необходим?
Может через SetWindowDisplayAffinity можно исключить?
Можно, но только через UWP Api.
ExcludeFromCapture
We have added a new flag to the SetWindowDisplayAffinity function, which supports content protection by returning black in screen captures of these windows. Sometimes, applications want to simply exclude a window from capture and not return black because things like recording buttons are not always desirable in captured content. When the new flag, WDA_EXCLUDEFROMCAPTURE, is set, the window will be removed from capture entirely.
https://blogs.windows.com/windowsdevelo … n-capture/
serzh82saratov, не совсем понял тебя.
Через DwmThumbnail Api мы не можем сохранять информацию - это апи используется только для ретранслирования изображения с Thumbnail в наше окно.
DirectX Duplication API дает наибольшую скорость.
DwmSharedSurface API даёт нам возможность получать изображение через недокумментированные функции - я постил примеры.
Для игр идущих на весь экран, надо хукать игру и перехватывать ком методы, тоже постил примеры.
Пока не нашёл, где WDA_EXCLUDEFROMCAPTURE определено.
This API will start being available in 20H1, I don't believe any new capture features are showing up in 19H2.
Чтобы отправить ответ, вы должны войти или зарегистрироваться