test3
This commit is contained in:
@@ -37,7 +37,8 @@ const (
|
|||||||
mftMessageNotifyEndOfStream = 0x10000002
|
mftMessageNotifyEndOfStream = 0x10000002
|
||||||
mftMessageNotifyEndStreaming = 0x10000001
|
mftMessageNotifyEndStreaming = 0x10000001
|
||||||
|
|
||||||
mftOutputStreamProvidesSamples = 0x00000100
|
mftOutputStreamProvidesSamples = 0x00000100
|
||||||
|
mftOutputStreamCanProvideSamples = 0x00000200
|
||||||
|
|
||||||
mfETransformNeedMoreInput = 0xC00D6D72
|
mfETransformNeedMoreInput = 0xC00D6D72
|
||||||
mfETransformStreamChange = 0xC00D6D61
|
mfETransformStreamChange = 0xC00D6D61
|
||||||
@@ -1067,7 +1068,7 @@ func (e *mfH264Encoder) processOutput() ([]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var outSample *mfSample
|
var outSample *mfSample
|
||||||
if info.flags&mftOutputStreamProvidesSamples == 0 {
|
if !mftCanAllocateOutputSample(info.flags) {
|
||||||
size := int(info.cbSize)
|
size := int(info.cbSize)
|
||||||
minSize := e.width * e.height * 3 / 2
|
minSize := e.width * e.height * 3 / 2
|
||||||
if size < minSize {
|
if size < minSize {
|
||||||
@@ -1098,7 +1099,11 @@ func (e *mfH264Encoder) processOutput() ([]byte, error) {
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
default:
|
default:
|
||||||
if failedHR(hr) {
|
if failedHR(hr) {
|
||||||
return nil, fmt.Errorf("mf h264: ProcessOutput failed 0x%x", hr)
|
allocation := "transform"
|
||||||
|
if outSample != nil {
|
||||||
|
allocation = "caller"
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("mf h264: ProcessOutput failed 0x%x stream_flags=0x%x output_sample=%s", hr, info.flags, allocation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if output.sample == nil {
|
if output.sample == nil {
|
||||||
@@ -1110,6 +1115,10 @@ func (e *mfH264Encoder) processOutput() ([]byte, error) {
|
|||||||
return sampleBytes(output.sample)
|
return sampleBytes(output.sample)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func mftCanAllocateOutputSample(flags uint32) bool {
|
||||||
|
return flags&(mftOutputStreamProvidesSamples|mftOutputStreamCanProvideSamples) != 0
|
||||||
|
}
|
||||||
|
|
||||||
func createVideoType(subtype windows.GUID, width, height, fps int) (*mfMediaType, error) {
|
func createVideoType(subtype windows.GUID, width, height, fps int) (*mfMediaType, error) {
|
||||||
var mt *mfMediaType
|
var mt *mfMediaType
|
||||||
hr, _, _ := procMFCreateMediaType.Call(uintptr(unsafe.Pointer(&mt)))
|
hr, _, _ := procMFCreateMediaType.Call(uintptr(unsafe.Pointer(&mt)))
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
//go:build windows
|
||||||
|
|
||||||
|
package capture
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestMFTCanAllocateOutputSample(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
flags uint32
|
||||||
|
want bool
|
||||||
|
}{
|
||||||
|
{name: "caller must allocate", flags: 0, want: false},
|
||||||
|
{name: "transform provides samples", flags: mftOutputStreamProvidesSamples, want: true},
|
||||||
|
{name: "transform can provide samples", flags: mftOutputStreamCanProvideSamples, want: true},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
if got := mftCanAllocateOutputSample(test.flags); got != test.want {
|
||||||
|
t.Fatalf("mftCanAllocateOutputSample(0x%x) = %t, want %t", test.flags, got, test.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1365,31 +1365,47 @@ func findOutput(factory *idxgiFactory1, desiredName string, desiredBounds image.
|
|||||||
}
|
}
|
||||||
|
|
||||||
func createD3DDevice(adapter *idxgiAdapter1) (*d3d11Device, *d3d11DeviceContext, error) {
|
func createD3DDevice(adapter *idxgiAdapter1) (*d3d11Device, *d3d11DeviceContext, error) {
|
||||||
var device *d3d11Device
|
flags := d3d11DeviceCreationFlagCandidates()
|
||||||
var context *d3d11DeviceContext
|
var firstHR uintptr
|
||||||
var featureLevel uint32
|
for attempt, creationFlags := range flags {
|
||||||
hr, _, _ := procD3D11CreateDevice.Call(
|
var device *d3d11Device
|
||||||
uintptr(unsafe.Pointer(adapter)),
|
var context *d3d11DeviceContext
|
||||||
uintptr(d3dDriverTypeUnknown),
|
var featureLevel uint32
|
||||||
0,
|
hr, _, _ := procD3D11CreateDevice.Call(
|
||||||
uintptr(d3d11CreateDeviceBgraSupport|d3d11CreateDeviceVideoSupport),
|
uintptr(unsafe.Pointer(adapter)),
|
||||||
0,
|
uintptr(d3dDriverTypeUnknown),
|
||||||
0,
|
0,
|
||||||
uintptr(d3d11SdkVersion),
|
uintptr(creationFlags),
|
||||||
uintptr(unsafe.Pointer(&device)),
|
0,
|
||||||
uintptr(unsafe.Pointer(&featureLevel)),
|
0,
|
||||||
uintptr(unsafe.Pointer(&context)),
|
uintptr(d3d11SdkVersion),
|
||||||
)
|
uintptr(unsafe.Pointer(&device)),
|
||||||
if hr != S_OK || device == nil || context == nil {
|
uintptr(unsafe.Pointer(&featureLevel)),
|
||||||
|
uintptr(unsafe.Pointer(&context)),
|
||||||
|
)
|
||||||
|
if hr == S_OK && device != nil && context != nil {
|
||||||
|
return device, context, nil
|
||||||
|
}
|
||||||
if context != nil {
|
if context != nil {
|
||||||
context.Release()
|
context.Release()
|
||||||
}
|
}
|
||||||
if device != nil {
|
if device != nil {
|
||||||
device.Release()
|
device.Release()
|
||||||
}
|
}
|
||||||
return nil, nil, fmt.Errorf("dxgi: D3D11CreateDevice failed 0x%x", hr)
|
if attempt == 0 {
|
||||||
|
firstHR = hr
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return nil, nil, fmt.Errorf("dxgi: D3D11CreateDevice failed video=0x%x fallback=0x%x", firstHR, hr)
|
||||||
|
}
|
||||||
|
return nil, nil, errors.New("dxgi: D3D11CreateDevice had no creation modes")
|
||||||
|
}
|
||||||
|
|
||||||
|
func d3d11DeviceCreationFlagCandidates() [2]uint32 {
|
||||||
|
return [2]uint32{
|
||||||
|
d3d11CreateDeviceBgraSupport | d3d11CreateDeviceVideoSupport,
|
||||||
|
d3d11CreateDeviceBgraSupport,
|
||||||
}
|
}
|
||||||
return device, context, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func convertBGRA(src []byte, pitch, width, height int, rotation uint32) *image.RGBA {
|
func convertBGRA(src []byte, pitch, width, height int, rotation uint32) *image.RGBA {
|
||||||
|
|||||||
@@ -49,6 +49,16 @@ func TestDesktopDuplicationToggleResetsState(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestD3D11DeviceCreationFlagsFallBackWithoutVideoSupport(t *testing.T) {
|
||||||
|
flags := d3d11DeviceCreationFlagCandidates()
|
||||||
|
if flags[0] != d3d11CreateDeviceBgraSupport|d3d11CreateDeviceVideoSupport {
|
||||||
|
t.Fatalf("first D3D11 creation flags = 0x%x, want BGRA and video support", flags[0])
|
||||||
|
}
|
||||||
|
if flags[1] != d3d11CreateDeviceBgraSupport {
|
||||||
|
t.Fatalf("fallback D3D11 creation flags = 0x%x, want BGRA only", flags[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestCaptureDisplayDXGI(t *testing.T) {
|
func TestCaptureDisplayDXGI(t *testing.T) {
|
||||||
if displayCount() == 0 {
|
if displayCount() == 0 {
|
||||||
t.Skip("no displays detected")
|
t.Skip("no displays detected")
|
||||||
|
|||||||
Reference in New Issue
Block a user