This is a question I originally posted over at the VideoLan forums (thread), but VideoLan support is totally overworked, and in any case I can't tell if this is an issue with libVLC, JNA, or the VLCj implementation, so I thought I would ask StackOverflow and see if anyone had any clues...
Hi all,
I'm writing an automated transcoder in Groovy, using VLCj, on Windows XP. My capture device is an Epiphan VGA2USB LR framegrabber device, which I connect to via DirectShow. At this point I'm just trying to record any data from this device to a file, but so far I've had no luck. I know the device is compatible with VLC- I can open the device using the VLC GUI and see its output on the screen.
Having fixed various configuration issues that were troubling me before, I'm now finding that VLC appears to hang when I try to start the recording. Here's the output I get, annotated with what happens at what time:
[00384d30] main libvlc debug: VLC media player - 2.0.2 Twoflower
[00384d30] main libvlc debug: Copyright � 1996-2012 VLC authors and VideoLAN
[00384d30] main libvlc debug: revision 2.0.2-14-gbc2c368
[00384d30] main libvlc debug: configured with ../extras/package/win32/../../../configure '--enable-update-check' '--enable-lua' '--enable-faad' '--enable-flac' '--enable-theora' '--enable-twolame' '--enable-quicktime' '--enable-avcodec' '--enable-merge-ffmpeg' '--enable-dca' '--enable-mpc' '--enable-libass' '--enable-x264' '--enable-schroedinger' '--enable-realrtsp' '--enable-live555' '--enable-dvdread' '--enable-shout' '--enable-goom' '--enable-caca' '--disable-portaudio' '--disable-sdl' '--enable-qt4' '--enable-skins2' '--enable-sse' '--enable-mmx' '--enable-libcddb' '--enable-zvbi' '--disable-telx' '--enable-sqlite' '--disable-dirac' '--host=i586-mingw32msvc' '--enable-crystalhd' 'host_alias=i586-mingw32msvc'
[00384d30] main libvlc debug: searching plug-in modules
[00384d30] main libvlc debug: loading plugins cache file C:\Documents and Settings\Administrator\digitizer\lib\libvlc-2.0.2\plugins\plugins.dat
[00384d30] main libvlc debug: recursively browsing `C:\Documents and Settings\Administrator\digitizer\lib\libvlc-2.0.2\plugins'
[00384d30] main libvlc debug: saving plugins cache C:\Documents and Settings\Administrator\digitizer\lib\libvlc-2.0.2\plugins\plugins.dat
[00384d30] main libvlc debug: plug-ins loaded: 388 modules
[00384d30] main libvlc debug: translation test: code is "C"
[00384d30] main libvlc debug: CPU has capabilities MMX MMXEXT SSE SSE2 SSE3 SSSE3 SSE4.1 SSE4.2 FPU
[00384d30] main libvlc debug: looking for memcpy module: 4 candidates
[00384d30] main libvlc debug: using memcpy module "memcpymmxext"
[0038c568] main interface debug: looking for interface module: 1 candidate
[0038c568] main interface debug: using interface module "hotkeys"
[0038c568] main interface debug: TIMER module_need() : 0.033 ms - Total 0.033 ms / 1 intvls (Avg 0.033 ms)
[this is the point in the code where play() is called]
24-07-2012 14:05:45 Digitizer: [DEBUG] Recording test-capture.mp4 start
[03f59340] main input debug: Creating an input for 'dshow://'
[03f5d578] main stream output debug: using sout chain=`transcode{vcodec=mp4v,vb=1024,scale=1}:standard{access=file,mux=mp4,dst="test-capture.mp4"}'
[03f5d578] main stream output debug: stream=`standard'
[03f4eb60] main stream out debug: looking for sout stream module: 1 candidate
[03f4eb60] main stream out debug: set config option: sout-standard-access to file
[03f4eb60] main stream out debug: set config option: sout-standard-mux to mp4
[03f4eb60] main stream out debug: set config option: sout-standard-dst to test-capture.mp4
[03f47c48] main access out debug: looking for sout access module: 1 candidate
[03f61ab8] main playlist debug: playlist threads correctly activated
[03f47c48] access_output_file access out debug: file access output opened (test-capture.mp4)
[03f47c48] main access out debug: using sout access module "access_output_file"
[03f47c48] main access out debug: TIMER module_need() : 1.176 ms - Total 1.176 ms / 1 intvls (Avg 1.176 ms)
[0038cbd8] main mux debug: looking for sout mux module: 1 candidate
[0038cbd8] mux_mp4 mux debug: Mp4 muxer opened
[0038cbd8] main mux debug: using sout mux module "mux_mp4"
[0038cbd8] main mux debug: TIMER module_need() : 0.907 ms - Total 0.907 ms / 1 intvls (Avg 0.907 ms)
[03f4eb60] stream_out_standard stream out debug: using `file/mp4://test-capture.mp4'
[03f4eb60] main stream out debug: using sout stream module "stream_out_standard"
[03f4eb60] main stream out debug: TIMER module_need() : 4.965 ms - Total 4.965 ms / 1 intvls (Avg 4.965 ms)
[03f5d578] main stream output debug: stream=`transcode'
[03f4ad70] main stream out debug: looking for sout stream module: 1 candidate
[03f4ad70] main stream out debug: set config option: sout-transcode-vcodec to mp4v
[03f4ad70] main stream out debug: set config option: sout-transcode-vb to 1024
[03f4ad70] main stream out debug: set config option: sout-transcode-scale to 1
[03f4ad70] stream_out_transcode stream out debug: codec video=mp4v 0x0 scaling: 1.000000 1024kb/s
[03f4ad70] main stream out debug: using sout stream module "stream_out_transcode"
[03f4ad70] main stream out debug: TIMER module_need() : 0.976 ms - Total 0.976 ms / 1 intvls (Avg 0.976 ms)
[03f59340] main input debug: using timeshift granularity of 50 MiB, in path 'C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp'
24-07-2012 14:05:45 Digitizer: [DEBUG] Recording started
[03f59340] main input debug: `dshow://' gives access `dshow' demux `' path `'
[03f59340] main input debug: creating demux: access='dshow' demux='' location='' file='(null)'
[03f4a898] main demux debug: looking for access_demux module: 1 candidate
[03f4a898] dshow demux debug: dshow-vdev: VGA2USB LR V3U48015
[03f4a898] dshow demux debug: dshow-adev:
[03f61ab8] main playlist debug: rebuilding array of current - root Playlist
[03f61ab8] main playlist debug: rebuild done - 0 items, index -1
[03f4a898] dshow demux debug: found device: VGA2USB LR V3U48015
[03f4a898] dshow demux debug: found device: VGA2USB LR V4U120503
[03f4a898] dshow demux debug: asking for device: VGA2USB LR V3U48015
[03f4a898] dshow demux debug: asked for VGA2USB LR V3U48015, binding to VGA2USB LR V3U48015
[ At this point, the execution stops. Calling player.stop() from a different thread blocks indefinitely. ]
[ The following is output after the runtime shutdown procedure is called from a different thread: ]
[03f4a898] dshow demux debug: using device: VGA2USB LR V3U48015
[03f4a898] dshow demux debug: EnumDeviceCaps: output pin: Capture
[03f4a898] dshow demux debug: EnumDeviceCaps: trying pin Capture
[03f4a898] dshow demux debug: EnumDeviceCaps: input pin default format configured
[03f4a898] dshow demux debug: EnumDeviceCaps: input pin accepts chroma: RV24, width:1024, height:768, fps:59.900326
[03f4a898] dshow demux debug: CaptureFilter::JoinFilterGraph
[03f4a898] dshow demux debug: connecting filters
[03f4a898] dshow demux debug: CaptureFilter::EnumPins
[03f4a898] dshow demux debug: CapturePin::QueryDirection
[03f4a898] dshow demux debug: CapturePin::ConnectedTo [not connected]
[03f4a898] dshow demux debug: CapturePin::QueryPinInfo
[03f4a898] dshow demux debug: CaptureFilter::QueryFilterInfo
[03f4a898] dshow demux debug: CapturePin::QueryPinInfo
[03f4a898] dshow demux debug: CaptureFilter::EnumPins
[03f4a898] dshow demux debug: CapturePin::QueryDirection
[03f4a898] dshow demux debug: CapturePin::QueryDirection
[03f4a898] dshow demux debug: CapturePin::QueryAccept [OK] (width=1024, height=768, chroma=RV24, fps=59.900326)
[03f4a898] dshow demux debug: CapturePin::ReceiveConnection [OK]
[03f4a898] dshow demux debug: CapturePin::NotifyAllocator
[03f4a898] dshow demux debug: ConnectFilters: graph_builder2 available.
[03f4a898] dshow demux warning: ConnectFilters: No crossBar routes found (incompatible pin types)
[03f4a898] dshow demux debug: filters connected successfully !
[03f4a898] dshow demux debug: MEDIATYPE_Video
[03f4a898] dshow demux debug: selected video pin accepts format: RV24
[03f4a898] dshow demux debug: found device: Creative Sound Blaster PCI
[03f4a898] dshow demux debug: asking for default device: Creative Sound Blaster PCI
[03f4a898] dshow demux debug: asked for Creative Sound Blaster PCI, binding to Creative Sound Blaster PCI
[03f4a898] dshow demux debug: using device: Creative Sound Blaster PCI
[03f4a898] dshow demux debug: EnumDeviceCaps: output pin: Capture
[03f4a898] dshow demux debug: EnumDeviceCaps: input pin: Stereo Mix
[03f4a898] dshow demux debug: EnumDeviceCaps: input pin: Phone Line
[03f4a898] dshow demux debug: EnumDeviceCaps: input pin: Aux Volume
[03f4a898] dshow demux debug: EnumDeviceCaps: input pin: Video Volume
[03f4a898] dshow demux debug: EnumDeviceCaps: input pin: Mic Volume
[03f4a898] dshow demux debug: EnumDeviceCaps: input pin: Line In
[03f4a898] dshow demux debug: EnumDeviceCaps: input pin: CD Audio
[03f4a898] dshow demux debug: EnumDeviceCaps: trying pin Capture
[03f4a898] dshow demux debug: EnumDeviceCaps: input pin default format configured
[03f4a898] dshow demux debug: EnumDeviceCaps: input pin accepts format: araw, channels:2, samples/sec:44100 bits/sample:16
[03f4a898] dshow demux debug: EnumDeviceCaps: input pin accepts format: araw, channels:2, samples/sec:44100 bits/sample:16
[03f4a898] dshow demux debug: EnumDeviceCaps: input pin accepts format: araw, channels:1, samples/sec:44100 bits/sample:16
[03f4a898] dshow demux debug: EnumDeviceCaps: input pin accepts format: araw, channels:2, samples/sec:32000 bits/sample:16
[03f4a898] dshow demux debug: EnumDeviceCaps: input pin accepts format: araw, channels:1, samples/sec:32000 bits/sample:16
[03f4a898] dshow demux debug: EnumDeviceCaps: input pin accepts format: araw, channels:2, samples/sec:22050 bits/sample:16
[03f4a898] dshow demux debug: EnumDeviceCaps: input pin accepts format: araw, channels:1, samples/sec:22050 bits/sample:16
[03f4a898] dshow demux debug: EnumDeviceCaps: input pin accepts format: araw, channels:2, samples/sec:11025 bits/sample:16
[03f4a898] dshow demux debug: EnumDeviceCaps: input pin accepts format: araw, channels:1, samples/sec:11025 bits/sample:16
[03f4a898] dshow demux debug: EnumDeviceCaps: input pin accepts format: araw, channels:2, samples/sec:8000 bits/sample:16
[03f4a898] dshow demux debug: EnumDeviceCaps: input pin accepts format: araw, channels:1, samples/sec:8000 bits/sample:16
[03f4a898] dshow demux debug: EnumDeviceCaps: input pin accepts format: araw, channels:2, samples/sec:44100 bits/sample:8
[03f4a898] dshow demux debug: EnumDeviceCaps: input pin accepts format: araw, channels:1, samples/sec:44100 bits/sample:8
[03f4a898] dshow demux debug: EnumDeviceCaps: input pin accepts format: araw, channels:2, samples/sec:22050 bits/sample:8
[03f4a898] dshow demux debug: EnumDeviceCaps: input pin accepts format: araw, channels:1, samples/sec:22050 bits/sample:8
[03f4a898] dshow demux debug: EnumDeviceCaps: input pin accepts format: araw, channels:2, samples/sec:11025 bits/sample:8
[03f4a898] dshow demux debug: EnumDeviceCaps: input pin accepts format: araw, channels:1, samples/sec:11025 bits/sample:8
[03f4a898] dshow demux debug: EnumDeviceCaps: input pin accepts format: araw, channels:2, samples/sec:8000 bits/sample:8
[03f4a898] dshow demux debug: EnumDeviceCaps: input pin accepts format: araw, channels:1, samples/sec:8000 bits/sample:8
[03f4a898] dshow demux debug: EnumDeviceCaps: input pin accepts format: araw, channels:2, samples/sec:48000 bits/sample:16
[03f4a898] dshow demux debug: EnumDeviceCaps: input pin accepts format: araw, channels:1, samples/sec:48000 bits/sample:16
[03f4a898] dshow demux debug: EnumDeviceCaps: input pin accepts format: araw, channels:2, samples/sec:96000 bits/sample:16
[03f4a898] dshow demux debug: EnumDeviceCaps: input pin accepts format: araw, channels:1, samples/sec:96000 bits/sample:16
[03f4a898] dshow demux debug: CaptureFilter::JoinFilterGraph
[03f4a898] dshow demux debug: connecting filters
[03f4a898] dshow demux debug: CaptureFilter::EnumPins
[03f4a898] dshow demux debug: CapturePin::QueryDirection
[03f4a898] dshow demux debug: CapturePin::ConnectedTo [not connected]
[03f4a898] dshow demux debug: CapturePin::QueryPinInfo
[03f4a898] dshow demux debug: CaptureFilter::QueryFilterInfo
[03f4a898] dshow demux debug: CapturePin::QueryPinInfo
[03f4a898] dshow demux debug: CaptureFilter::EnumPins
[03f4a898] dshow demux debug: CapturePin::QueryDirection
[03f4a898] dshow demux debug: CapturePin::QueryDirection
[03f4a898] dshow demux debug: CapturePin::QueryAccept [OK] (channels=2, samples/sec=44100, bits/samples=16, format=araw)
[03f4a898] dshow demux debug: CapturePin::ReceiveConnection [OK]
[03f4a898] dshow demux debug: CapturePin::NotifyAllocator
[03f4a898] dshow demux debug: filters connected successfully !
[03f4a898] dshow demux debug: MEDIATYPE_Audio
[03f4a898] dshow demux debug: selected audio pin accepts format: araw
[03f4a898] dshow demux debug: Playing...
[03f4a898] dshow demux debug: CapturePin::QueryPinInfo
[03f4a898] dshow demux debug: CaptureFilter::EnumPins
[03f4a898] dshow demux debug: CapturePin::QueryDirection
[03f4a898] dshow demux debug: CapturePin::QueryPinInfo
[03f4a898] dshow demux debug: CaptureFilter::EnumPins
[03f4a898] dshow demux debug: CapturePin::QueryDirection
[03f4a898] dshow demux debug: CaptureFilter::EnumPins
[03f4a898] dshow demux debug: CapturePin::QueryDirection
[03f4a898] dshow demux debug: CapturePin::QueryPinInfo
[03f4a898] dshow demux debug: CaptureFilter::EnumPins
[03f4a898] dshow demux debug: CapturePin::QueryDirection
[03f4a898] dshow demux debug: CapturePin::QueryPinInfo
[03f4a898] dshow demux debug: CaptureFilter::EnumPins
[03f4a898] dshow demux debug: CapturePin::QueryDirection
[03f4a898] dshow demux debug: CaptureFilter::EnumPins
[03f4a898] dshow demux debug: CapturePin::QueryDirection
[03f4a898] dshow demux debug: CaptureFilter::EnumPins
[03f4a898] dshow demux debug: CapturePin::QueryDirection
[03f4a898] dshow demux debug: CapturePin::ConnectedTo [OK]
[03f4a898] dshow demux debug: CaptureFilter::EnumPins
[03f4a898] dshow demux debug: CapturePin::QueryDirection
[03f4a898] dshow demux debug: CapturePin::ConnectedTo [OK]
[03f4a898] dshow demux debug: CaptureFilter::SetSyncSource
[03f4a898] dshow demux debug: CaptureFilter::SetSyncSource
[03f4a898] dshow demux debug: CaptureFilter::Pause
[03f4a898] dshow demux debug: CaptureFilter::Pause
[03f4a898] dshow demux debug: CaptureFilter::Run
[03f4a898] dshow demux debug: CaptureFilter::Run
[03f59340] main input debug: selecting program id=0
Process finished with exit code 0
From digging through the source code, it appears that IMoniker->BindToObject() is waiting for a resource that is only released when the program is terminated- as far as I can tell the call that is blocking is dshow.cpp:1317
hr = p_moniker->BindToObject( NULL, 0, IID_IBaseFilter,
(void **)&p_base_filter );
This line is where VLC calls into the DirectShow API to register the device, so why it is not returning is totally beyond me. It seems to me like the play() operation completes successfully, but of course since this happens as the program is terminating, it is useless if we want to actually record anything.
If anyone can suggest to me a way to work around this, or tell me what I'm doing wrong to cause it, I will be eternally grateful!
It turns out that this call was blocking because immediately after returning from the playMedia call, the main thread of my program then waited on standard input (to implement a 'press enter to exit' type arrangement)- it was not the VM shutdown that triggered the call to suddenly return, but rather the fact that the console read returned, so the I/O wait was no longer blocking the DirectShow API call.
Quite why a console I/O call was blocking something in DirectShow is entirely beyond me, but there you go. This issue can be easily worked around by sleeping any threads doing console I/O for a couple of seconds after the playMedia() call (easy), or checking that the VLC object has completed the initiation of the play operation before reading from the console (less easy, far more reliable).