java - 为什么我的 libVLC 程序在尝试绑定(bind)捕获设备时会死锁?

标签 java vlc jna libvlc vlcj

这是我最初在 VideoLan 论坛 ( thread ) 上发布的问题,但 VideoLan 支持完全过度劳累,无论如何我无法判断这是否是 libVLC、JNA 或 VLCj 的问题实现,所以我想我应该问 StackOverflow,看看是否有人有任何线索......

大家好,

我正在 Windows XP 上使用 VLCj 在 Groovy 中编写自动转码器。我的捕获设备是 Epiphan VGA2USB LR 图像采集卡设备,我通过 DirectShow 连接到该设备。此时,我只是尝试将此设备中的任何数据记录到文件中,但到目前为止我还没有运气。我知道该设备与 VLC 兼容 - 我可以使用 VLC GUI 打开该设备并在屏幕上查看其输出。

修复了之前困扰我的各种配置问题后,我现在发现当我尝试开始录制时,VLC 似乎挂起。这是我得到的输出,注释了何时发生的事情:

[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)

[这是代码中调用 play() 的位置]

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

[ 此时,执行停止。从不同的线程调用player.stop()会无限期地阻塞。 ]

[以下是从不同线程调用运行时关闭过程后的输出:]

[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

通过深入研究源代码,IMoniker->BindToObject() 似乎正在等待一个仅在程序终止时释放的资源 - 据我所知,阻塞的调用是 dshow.cpp:第1317章

                hr = p_moniker->BindToObject( NULL, 0, IID_IBaseFilter,
                                              (void **)&p_base_filter );

这一行是 VLC 调用 DirectShow API 来注册设备的地方,所以我完全不明白为什么它没有返回。在我看来,play() 操作成功完成,但当然,由于这是在程序终止时发生的,所以如果我们想实际记录任何内容,它是没有用的。

如果有人可以向我建议一种解决此问题的方法,或者告诉我我做错了什么导致了这个问题,我将永远感激不已!

最佳答案

事实证明,这个调用被阻塞了,因为从 playMedia 调用返回后,我的程序的主线程立即等待标准输入(以实现“按 Enter 退出”类型安排)- 它不是 VM shutdown 触发调用突然返回,而是控制台读取返回,因此 I/O 等待不再阻塞 DirectShow API 调用。

为什么控制台 I/O 调用会阻塞 DirectShow 中的某些内容,这完全超出了我的理解范围,但你知道了。通过在 playMedia() 调用后让执行控制台 I/O 的任何线程 hibernate 几秒钟(简单),或者在从控制台读取之前检查 VLC 对象是否已完成播放操作的启动,可以轻松解决此问题(不太容易,但更可靠)。

关于java - 为什么我的 libVLC 程序在尝试绑定(bind)捕获设备时会死锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11640597/

相关文章:

android - vlc-android-sdk - 无法查看 RTSP 实时视频

java - 如何在 OSX 中使用 Java 获取 Activity 应用程序标题?

java - Java 9 中的 requires 和 requires 传递语句有什么区别?

java - 积极的后向行为不正确

java - Hibernate 仅在基本类型上指定一次 @Column 注解

VLC 2.0.1 调整字幕时间

java - 用于将 PDF 文件转换为位图的最可靠的开源 Java 库

javascript - 当 playlist.m3u8 文件不断更新时,如何播放 HLS 流?

java - 如何将 16 位字符数组转换为 8 位字符数组并使用 JNA 发送到 C 代码?

java - 让 JNA 与第 3 方 DLL 交互的技巧是什么?