DVD 导航器中的数据流
[与此页面关联的功能 DirectShow 是旧版功能。 它已被 MediaPlayer、 IMFMediaEngine 和 Media Foundation 中的音频/视频捕获所取代。 这些功能已针对Windows 10和Windows 11进行了优化。 Microsoft 强烈建议新代码尽可能在 Media Foundation 中使用 MediaPlayer、 IMFMediaEngine 和 音频/视频捕获 ,而不是 DirectShow。 如果可能,Microsoft 建议重写使用旧 API 的现有代码以使用新 API。]
DVD 导航器具有停止和暂停播放的方法。 这些方法与 IMediaControl 中的 Stop 和 Pause 方法相似(但不完全相同)。 下面是它们之间的区别:
- IDvdControl2 方法更改 DVD 导航器从磁盘读取的内容。 它们不会更改图形的状态。
- IMediaControl 方法更改图形的状态。 它们不会更改 DVD 导航器从磁盘读取的内容。 (下一节中将介绍与 Stop 方法相关的一个重要异常)
例如, IDvdControl2::P ause 方法发出附件 J“Pause_On”命令,但不暂停筛选器图。 另一方面, IMediaControl::P ause 方法暂停图形,但不发出任何 DVD 命令。
通常,使用 IMediaControl::P ause 和 Stop 方法,而不是相应的 IDvdControl2 方法。 IMediaControl 方法的延迟非常小,而 IDvdControl2 方法的延迟可能长达两秒。
停止播放
IMediaControl::Stop 的行为取决于可以使用 IDvdControl2::SetOption 方法设置的标志。
- 如果DVD_ResetOnStop标志为 FALSE, 则 IMediaControl::Stop 将停止图形,但不更改 DVD 导航器的域。 再次调用 run 时,播放将从当前位置恢复。
- 如果DVD_ResetOnStop为 TRUE, 则 IMediaControl::Stop 会导致 DVD 导航器重置。 再次调用 IMediaControl::Run 时,DVD 导航器将从“第一个播放”域播放,就像你第一次插入 DVD 一样。
默认情况下,DVD_ResetOnStop标志为 TRUE ,以便与旧应用程序兼容。 但是,通常应重写默认值,并将标志设置为 FALSE。 原因是某些事件可能导致图形在播放期间停止。 例如,如果显示分辨率发生更改,筛选器图将停止、重新连接视频呈现器,然后重启。 如果DVD_ResetOnStop 为 TRUE,则播放将从光盘的开头重新启动。这可能不是用户所期望的。
因此,在应用程序开始时调用 SetOption ,DVD_ResetOnStop设置为 FALSE。 如果要停止播放并从同一位置恢复播放,请调用 IMediaControl::Stop 或 IMediaControl::P ause。 如果要停止播放并重置磁盘,请调用 setOption ,DVD_ResetOnStop等于 TRUE;然后调用 IMediaControl::Stop;最后,再次调用 SetOption 并将DVD_ResetOnStop重置为 FALSE。
暂停播放
如果在暂停图形时为 DVD 导航器提供命令,该命令可能不会完成,直到图形再次运行。 在某些情况下,这可能会导致应用程序中出现死锁。 应遵循两个规则以避免死锁:
- 暂停时,不要发出多个异步 DVD 命令。
- 暂停时,不要阻止应用程序的 UI 线程或更改图形状态的线程。
第二个规则值得更详细地研究。 下面是可能导致死锁的一些特定方案:
场景:暂停时,应用程序会发出带有阻止标志的 DVD 命令。 如果发出 DVD 命令的线程与发出 run 命令的线程相同,这可能会导致死锁。 DVD 命令会阻止,直到图形运行,但图形在命令完成之前无法运行。
建议:在单独的工作线程上发出 DVD 命令,或者不使用阻止标志。
场景:暂停时,应用程序会发出 DVD 命令,然后对命令对象调用 IDvdCmd::WaitForEnd 。 这种情况等效于上一个示例。 如果从 UI 线程调用 Wait ,则在 Wait 方法取消阻止之前,UI 线程无法运行图形,但 Wait 方法在图形运行之前不会取消阻止。
建议:在工作线程上调用 Wait 。
场景:在图形运行时,应用程序发出带有阻止标志的 DVD 命令,然后从另一个线程调用暂停。 这是可能的争用条件,因为图形可能会在发出命令之前暂停。 如果两个线程之一是 UI 线程,可能会导致死锁,类似于前两个示例。 此示例说明了在应用程序使用多个线程时编写线程安全代码的重要性。
建议:如果使用工作线程,请确保代码是线程安全的。
场景:暂停时,应用程序从 UI 禁用 run 命令,然后发出异步 DVD 命令。 这种情况并不是严格意义上的死锁,因为应用程序线程仍在运行。 但是,现在阻止用户运行图形,因此命令永远不会完成。
建议:暂停时,始终使 run 命令保持启用状态。
查找指定时间的 DVD
若要准确查找光盘上的指定时间,请调用 IMediaControl::Run。 然后调用 IDvdControl2::P layAtTime,指定时间并将 dwFlags 设置为 DVD_CMD_FLAG_Flush。
相关主题