私は C のバックグラウンドを持っていないので、ポインターは私の失敗のようです。本格的な Windows (Atom プロセッサ) を実行している Lenovo Thinkpad タブレットでの作業。サンプル プロジェクト DXSnap を vb.net に移植しました。ラップトップでは問題なく動作しますが、タブレットではエラーが発生します。
最初のエラー: 例外が発生しました: System.Runtime.InteropServices.COMException (0x80070032)。リクエストはサポートされていません。
2 番目のエラー (1 番目のエラーを閉じた後): BufferCB のバッファが初期化されていません。
主な問題は、どのビデオ設定を使用すればよいかわからないことだと思います。デフォルトの 640x480x24bpp から始めました。videoInfoHeader から取得したもの (448x252) に変更することで、最初の問題を回避しましたが、見た bpp は返されませんでした。
1 回の実行からのいくつかのサンプル データ: メディア フォーマット タイプ: 05589f80-c356-11ce-bf01-00aa0055595a : 128778240 m_ipBuffer: 81070712 バッファー長: 338688 '定数。大丈夫なはず
私にとって重要なサブ/機能:
Private Sub SetupGraph(dev As DsDevice, iWidth As Integer, iHeight As Integer, iBPP As Short, hControl As Control)
Dim hr As Integer
Dim sampGrabber As ISampleGrabber = Nothing
Dim capFilter As IBaseFilter = Nothing
Dim pCaptureOut As IPin = Nothing
Dim pSampleIn As IPin = Nothing
Dim pRenderIn As IPin = Nothing
' Get the graphbuilder object
m_FilterGraph = TryCast(New FilterGraph(), IFilterGraph2)
Try
#If DEBUG Then
m_rot = New DsROTEntry(m_FilterGraph)
#End If
' add the video input device
hr = m_FilterGraph.AddSourceFilterForMoniker(dev.Mon, Nothing, dev.Name, capFilter)
DsError.ThrowExceptionForHR(hr)
MsgBox(dev.Name.ToString & vbNewLine & dev.Mon.ToString & vbNewLine & capFilter.ToString)
' Find the still pin
m_pinStill = DsFindPin.ByCategory(capFilter, PinCategory.Still, 0)
' Didn't find one. Is there a preview pin?
If m_pinStill Is Nothing Then
m_pinStill = DsFindPin.ByCategory(capFilter, PinCategory.Preview, 0)
End If
' Still haven't found one. Need to put a splitter in so we have
' one stream to capture the bitmap from, and one to display. Ok, we
' don't *have* to do it that way, but we are going to anyway.
If m_pinStill Is Nothing Then
Dim pRaw As IPin = Nothing
Dim pSmart As IPin = Nothing
' There is no still pin
m_VidControl = Nothing
' Add a splitter
Dim iSmartTee As IBaseFilter = DirectCast(New SmartTee(), IBaseFilter)
Try
hr = m_FilterGraph.AddFilter(iSmartTee, "SmartTee")
DsError.ThrowExceptionForHR(hr)
' Find the find the capture pin from the video device and the
' input pin for the splitter, and connnect them
pRaw = DsFindPin.ByCategory(capFilter, PinCategory.Capture, 0)
pSmart = DsFindPin.ByDirection(iSmartTee, PinDirection.Input, 0)
hr = m_FilterGraph.Connect(pRaw, pSmart)
DsError.ThrowExceptionForHR(hr)
' Now set the capture and still pins (from the splitter)
m_pinStill = DsFindPin.ByName(iSmartTee, "Preview")
pCaptureOut = DsFindPin.ByName(iSmartTee, "Capture")
' If any of the default config items are set, perform the config
' on the actual video device (rather than the splitter)
If iHeight + iWidth + iBPP > 0 Then
SetConfigParms(pRaw, iWidth, iHeight, iBPP)
End If
Finally
If pRaw IsNot Nothing Then
Marshal.ReleaseComObject(pRaw)
End If
If Not pRaw Is pSmart Then
Marshal.ReleaseComObject(pSmart)
End If
If Not pRaw Is iSmartTee Then
Marshal.ReleaseComObject(iSmartTee)
End If
End Try
Else
' Get a control pointer (used in Click())
m_VidControl = TryCast(capFilter, IAMVideoControl)
pCaptureOut = DsFindPin.ByCategory(capFilter, PinCategory.Capture, 0)
' If any of the default config items are set
If iHeight + iWidth + iBPP > 0 Then
MsgBox("mPinStill: " & m_pinStill.ToString & vbNewLine & "iHeight: " & iHeight.ToString & vbNewLine & "iWidth: " & iWidth.ToString & vbNewLine & "bpp: " & iBPP.ToString)
SetConfigParms(m_pinStill, iWidth, iHeight, iBPP)
End If
End If
' Get the SampleGrabber interface
sampGrabber = TryCast(New SampleGrabber(), ISampleGrabber)
' Configure the sample grabber
Dim baseGrabFlt As IBaseFilter = TryCast(sampGrabber, IBaseFilter)
ConfigureSampleGrabber(sampGrabber)
pSampleIn = DsFindPin.ByDirection(baseGrabFlt, PinDirection.Input, 0)
' Get the default video renderer
Dim pRenderer As IBaseFilter = TryCast(New VideoRendererDefault(), IBaseFilter)
hr = m_FilterGraph.AddFilter(pRenderer, "Renderer")
DsError.ThrowExceptionForHR(hr)
pRenderIn = DsFindPin.ByDirection(pRenderer, PinDirection.Input, 0)
' Add the sample grabber to the graph
hr = m_FilterGraph.AddFilter(baseGrabFlt, "Ds.NET Grabber")
DsError.ThrowExceptionForHR(hr)
If m_VidControl Is Nothing Then
' Connect the Still pin to the sample grabber
hr = m_FilterGraph.Connect(m_pinStill, pSampleIn)
DsError.ThrowExceptionForHR(hr)
' Connect the capture pin to the renderer
hr = m_FilterGraph.Connect(pCaptureOut, pRenderIn)
DsError.ThrowExceptionForHR(hr)
Else
' Connect the capture pin to the renderer
hr = m_FilterGraph.Connect(pCaptureOut, pRenderIn)
DsError.ThrowExceptionForHR(hr)
' Connect the Still pin to the sample grabber
hr = m_FilterGraph.Connect(m_pinStill, pSampleIn)
DsError.ThrowExceptionForHR(hr)
End If
' Learn the video properties
SaveSizeInfo(sampGrabber)
ConfigVideoWindow(hControl)
' Start the graph
Dim mediaCtrl As IMediaControl = TryCast(m_FilterGraph, IMediaControl)
hr = mediaCtrl.Run()
DsError.ThrowExceptionForHR(hr)
Finally
If sampGrabber IsNot Nothing Then
Marshal.ReleaseComObject(sampGrabber)
sampGrabber = Nothing
End If
If pCaptureOut IsNot Nothing Then
Marshal.ReleaseComObject(pCaptureOut)
pCaptureOut = Nothing
End If
If pRenderIn IsNot Nothing Then
Marshal.ReleaseComObject(pRenderIn)
pRenderIn = Nothing
End If
If pSampleIn IsNot Nothing Then
Marshal.ReleaseComObject(pSampleIn)
pSampleIn = Nothing
End If
End Try
End Sub
Private Function BufferCB(SampleTime As Double, pBuffer As IntPtr, BufferLen As Integer) As Integer Implements ISampleGrabberCB.BufferCB
' Note that we depend on only being called once per call to Click. Otherwise
' a second call can overwrite the previous image.
Debug.Assert(BufferLen = Math.Abs(1344) * 252, "Incorrect buffer length")
'Debug.Assert(BufferLen = Math.Abs(m_stride) * m_videoHeight, "Incorrect buffer length")
If m_WantOne Then
m_WantOne = False
MsgBox("P Buffer: " & pBuffer.ToString & "- Buffer Length: " & BufferLen.ToString & vbNewLine & "m_ipBuffer: " & m_ipBuffer.ToString)
Debug.Assert(m_ipBuffer <> IntPtr.Zero, "Unitialized buffer")
' Save the buffer
CopyMemory(m_ipBuffer, pBuffer, BufferLen)
MsgBox("After CopyMemory", MsgBoxStyle.AbortRetryIgnore)
' Picture is ready.
m_PictureReady.[Set]()
End If
Return 0
End Function
BufferCB の CopyMemory が問題の原因のようです。そのため、バッファまたはビデオ サイズ/bpp に問題があると考えられます。