Video Capture and multithread
Hi,
I am new to VB and programming on Windows as such. Mostly c++/gcc/linux.
I am trying to build this VB app that shows a streaming video from a camera and that needs to be overlaid with some custom graphics and text.
I used the code published here:
http://www.vb-helper.com/howto_net_video_capture.html
to get the capture part to work. It essentially uses the avicap32.dll that most of you would probably know.
My plan:
1) Capture frames using
Code:
SendMessage(windowHandle, WM_CAP_EDIT_COPY, 0, 0)
and then copy from clipboard.
2) Do whatever graphics/text overlay on the obtained bitmap
3) send it to some picturebox on some form that is being shown
4) Do step 1 to 3 in a loop by a spawned worker thread.
Firstly is this a reasonable way to do what I want? or is there a much more efficient/easier way to about?
Now the specific problem:
From my main thread directly if I do step 1 to 3 once
Code:
UIComponent.DrawImage(VideoComponent.GetBitmap())
It shows me once captured image as it should and all is good.
Just to clarify:
UIComponent is an object/instance that launches the Form and owns the picturebox I want to display on.
VideoComponent is an object/instance that has started the videocapture and owns the picturebox to which the video is being captured
But if I wrap the same call above in a function and launch a thread that would start with that function as its starting point, I see a blank screen.
Again, for testing purpose, I am only doing step 1 through 3 just once.
The thread part of the code is like this
Code:
Private drawthread As Thread
public sub main()
drawthread = New Thread(AddressOf threadfunc)
drawthread.Start()
drawthread.Join()
end sub
Private Sub threadfunc()
'While True
Try
Console.WriteLine("DBG: Should be drawing image in " & Thread.CurrentThread.GetHashCode)
UIComponent.DrawImage(VideoComponent.GetBitmap())
'Thread.Sleep(500)
Catch ex As Exception
'Exit While
End Try
'End While
End Sub
I would appreciate if you would let me know what is messed up. I guess I am doing something conceptually wrong somewhere. Also I see the console print messages fine.
Re: Video Capture and multithread
Pino's WebCam Class
Have a look at this thread posted by Pino in the CodeBank it is very helpful!
Re: Video Capture and multithread
Yes I have seen that class and the link i posted is pretty much doing the same thing. My problem is not with the capture itself. That seems to be working reliably. Problem is when i run it from a worker thread.
Re: Video Capture and multithread
alright so I narrowed it down a bit by stepping in through the code. I saw that the getbitmap function is returning Nothing when called from the thread and "accessibilityObject" is showing some message like invalid access. Object created in a thread different from the current one. (which is indeed the case, My objects VideoComponent and UIComponent are created as global objects before I launch the threads). But by the threading model that I understand, these should be shared by all the threads.
I did read some about the apartment business in windows but I gather that multi-thread apartment is default now in .Net and so my global objects should be shared indeed. So whats the catch.
I also tried to write a small testcase to understand this. Again a couple global objects created from the main thread but accessed by the child threads as shown below. But this seems to work fine and I get console messages as I would expect.
Code:
Imports System.Threading
Public Class test
Private var As Integer = 0
Public Sub setvar(ByVal newvar As Integer)
var = newvar
End Sub
Public Function getvar()
getvar = var
End Function
End Class
Module MainModule
Private myobj1 As New test
Private myobj2 As New test
Sub Main()
Console.WriteLine("Initially var is : " & myobj1.getvar())
For i As Integer = 1 To 5
Dim t As Thread = New Thread(AddressOf threadfunc)
't.SetApartmentState(ApartmentState.MTA)
myobj2.setvar(i)
t.Start()
t.Join()
Next i
Console.WriteLine("Finally var is : " & myobj1.getvar())
End Sub
Public Sub threadfunc()
myobj1.setvar(2 * myobj2.getvar())
Console.WriteLine("Thread made var : " & myobj1.getvar())
End Sub
End Module
Re: Video Capture and multithread
ok so I get it finally. Regular stuff is in multi-thread apartment but stupid windows form/control stays in single-thread apartments. No wonder my test code worked while the main guy didnt. I mean! this is the most obnoxious thing ever!!! At the least, I would have expected to see a compile/runtime error message about it!!
Anyway, instead of ranting away on my woes with marvelous Windows :p ..which would just take an eternity! ..I should post the link and hope to save someone time and frustration
MSDN Article