DVD 导航器中的数据流

[与此页面关联的功能(DirectShow)是一项旧功能。 它已被 MediaPlayerIMFMediaEngine取代,并在媒体基金会 音频/视频捕获。 这些功能已针对 Windows 10 和 Windows 11 进行了优化。 Microsoft强烈建议新代码尽可能使用 MediaPlayerIMFMediaEngineMedia Foundation 中的音频/视频捕获,而不是 DirectShow。 Microsoft建议重写使用旧 API 的现有代码,以尽可能使用新 API。]

DVD 导航器具有停止和暂停播放的方法。 这些方法与 IMediaControl中的 StopPause 方法类似(但并不完全相同)。 下面是它们之间的差异:

  • IDvdControl2 方法更改 DVD 导航器从磁盘读取的内容。 它们不会更改图形的状态。
  • IMediaControl 方法更改图形的状态。 它们不会更改 DVD 导航器从磁盘读取的内容。 (下一节中介绍了与 Stop 方法相关的一个重要异常。

例如,IDvdControl2::P ause 方法发出附件 J“Pause_On”命令,但不暂停筛选器图。 另一方面,IMediaControl::P ause 方法暂停图形,但不发出任何 DVD 命令。

通常,使用 IMediaControl::P auseStop 方法,而不是相应的 IDvdControl2 方法。 IMediaControl 方法的延迟非常小,而 IDvdControl2 方法最多可以有两秒的延迟。

停止播放

IMediaControl::Stop 的行为取决于可以使用 IDvdControl2::SetOption 方法设置的标志。

  • 如果DVD_ResetOnStop标志 FALSEIMediaControl::Stop 停止图形,但不更改 DVD 导航器的域。 再次调用运行时,播放将从当前位置恢复。
  • 如果DVD_ResetOnStop TRUEIMediaControl::Stop 会导致 DVD 导航器重置。 再次调用 IMediaControl::Run 时,DVD 导航器将从第一个播放域播放,就像第一次插入 DVD 一样。

默认情况下,DVD_ResetOnStop标志 TRUE,以便与较旧的应用程序兼容。 但是,通常,应重写默认值并将标志设置为 FALSE。 原因是某些事件可能导致图形在播放期间停止。 例如,如果显示分辨率发生更改,筛选器图将停止,重新连接视频呈现器,然后重启。 如果DVD_ResetOnStop TRUE,则播放将从光盘的开头重新启动。这可能不是用户期望的。

因此,在应用程序的开头,调用 SetOption,并将DVD_ResetOnStop设置为 FALSE。 如果要停止播放并从同一位置恢复播放,请调用 IMediaControl::StopIMediaControl::P ause。 如果要停止播放并重置磁盘,请调用 SetOption,DVD_ResetOnStop等于 TRUE;然后调用 IMediaControl::Stop;最后,再次调用 SetOption,并将DVD_ResetOnStop重置为 FALSE

暂停播放

如果在图形暂停时向 DVD 导航器提供命令,则在图形再次运行时,该命令可能不会完成。 在某些情况下,这可能会导致应用程序中出现死锁。 应遵循两个规则来避免死锁:

  • 暂停时,不要发出多个异步 DVD 命令。
  • 暂停时,请勿阻止应用程序的 UI 线程或更改图形状态的线程。

第二条规则值得更详细地检查。 下面是可能导致死锁的一些特定方案:

  • 方案:暂停时,应用程序会发出带有阻止标志的 DVD 命令。 如果发出 DVD 命令的线程与发出运行命令的线程相同,则可能会导致死锁。 DVD 命令会阻止图形运行,但图形在命令完成之前无法运行。

    建议:在单独的工作线程上发出 DVD 命令,或者不使用阻止标志。

  • 方案:暂停时,应用程序发出 DVD 命令,然后在命令对象上调用 IDvdCmd::WaitForEnd。 这种情况等效于前面的示例。 如果从 UI 线程调用 Wait,则在 Wait 方法取消阻止之前,UI 线程无法运行图形,但在图形运行之前,Wait 方法不会解除阻止。

    建议:在工作线程上调用 等待

  • 方案:在图形运行时,应用程序会发出带有阻止标志的 DVD 命令,然后从另一个线程调用暂停。 这是可能的争用条件,因为图形可能会在发出命令之前暂停。 如果两个线程中的一个是 UI 线程,则可能会导致类似于前两个示例的死锁。 此示例演示了如果应用程序使用多个线程,则编写线程安全代码的重要性。

    建议:如果使用工作线程,请确保代码是线程安全的。

  • 方案:暂停时,应用程序从 UI 禁用运行命令,然后发出异步 DVD 命令。 这种情况并非完全是死锁,因为应用程序线程仍在运行。 但是,用户现在无法运行图形,因此该命令永远不会完成。

    建议:暂停时,请始终启用 run 命令。

将 DVD 查找到指定时间

若要准确查找光盘上的指定时间,请调用 IMediaControl::Run。 然后调用 IDvdControl2::P layAtTime,指定 dwFlags 设置为DVD_CMD_FLAG_Flush的时间和设置。

DVD 应用程序