【问题标题】:Directshow Issue Running 2 Graphs运行 2 个图表的 Directshow 问题
【发布时间】:2012-05-29 11:28:53
【问题描述】:

我有直接显示的 Mp4 捕获应用程序。在我的应用程序中,我需要连续捕获 30 分钟(或说一些动态值)视频。我的图表如下

Video Source --> x264vfw - H.264/MPEG-4 AVC Codec --------->GDCL MPEG-4 Multiplexer --> File Writer                                             
                                                        | 
Audio Source --> ACM Wrapper --> Monogram AAC Encoder --|

为此,我制定了类似的逻辑 -->

  1. 捕获类,其中包含制作图表所需的所有内容 构建器、获取设备、构建图、启动和停止捕获图。
  2. 为捕获类创建 2 个指针对象并为第一个和构建图形 第二个对象。
  3. 运行第一个图并在 30 分钟超时后启动第二个图并 停止第一张图

以相同的方式连续运行图表,我想这个逻辑应该可以正常工作......并且几乎在逻辑上是正确的

当我构建第一个图形时,它成功生成了第一个图形,并使用第二个指针对象为该对象构建图形,它不会将 Audio Source PinACM WrapeerHRESULT = -2147220969 连接起来

有人知道这种行为吗??

如果需要,我可以粘贴我的代码。

谢谢。

@Roman R.,我正在编辑我的帖子以添加我的代码片段,我希望我在这里添加了所需的详细信息。

编辑:

// Create 1st Capture Instance
Capture *capodd = new Capture();
capodd->destination = capinfo.destination;
capodd->periodicity = capinfo.periodicity;

// Select 1st Audio and 1st Video Device from Devices add their filters to graph
capodd->SelectDevice(1,1);

// Build Graph for the 1st Capture Instance
capodd->BuildMp4CaptureGraph();

// Create 2nd Capture Instance
Capture *capeven = new Capture();
capeven->destination = capinfo.destination;
capeven->periodicity = capinfo.periodicity;

// Select 1st Audio and 1st Video Device from Devices add their filters to graph
capeven->SelectDevice(1,1);

// Build Graph for the 2nd Capture Instance
capeven->BuildMp4CaptureGraph();


while(1)
{
    // set current capture file 
    Capture *capcurrent = new Capture();
    if(!capodd.Fcapturing && !capeven.Fcapturing)
    {
        capcurrent = capodd
        capodd->StopCapture();
    }
    else if(capodd.Fcapturing)
    {
        capcurrent = capeven;
        capodd->StopCapture();
    }
    else
    {
        capcurrent = capodd;
        capeven->StopCapture();
    }



    // Set the Capture File name 
    capcurrent->setCaptureInfo();

    // start capturing
    capcurrent->StartCapture();

    HANDLE hTimer = NULL;
    HANDLE hTimerQueue = NULL;
    int arg = 123;
    gDoneEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    if (NULL == gDoneEvent)
    {
        capcurrent->ErrMsg(TEXT("CreateEvent failed (%d)\n"), GetLastError());
        return FALSE;
    }

     hTimerQueue = CreateTimerQueue();
    if (NULL == hTimerQueue)
    {
        capcurrent->ErrMsg(TEXT("CreateTimerQueue failed (%d)\n"), GetLastError());
        return FALSE;
    }

    // Set a timer to call the timer routine in 10 seconds.
    if (!CreateTimerQueueTimer( &hTimer, hTimerQueue, 
        (WAITORTIMERCALLBACK)TimerRoutine, &arg , (capcurrent->dwTimeLimit)*1000, 0, 0))
    {
        capcurrent->ErrMsg(TEXT("CreateTimerQueueTimer failed (%d)\n"), GetLastError());
        return FALSE;
    }

    if (WaitForSingleObject(gDoneEvent, ((capcurrent->dwTimeLimit)*1000)+1000) != WAIT_OBJECT_0)
        capcurrent->ErrMsg(TEXT("WaitForSingleObject failed (%d)\n"), GetLastError());

    CloseHandle(gDoneEvent);

    // Delete all timers in the timer queue.
    if (!DeleteTimerQueue(hTimerQueue))
        capcurrent->ErrMsg(TEXT("DeleteTimerQueue failed (%d)\n"), GetLastError());


}

选择设备获取音频和视频过滤器设备并将所选过滤器添加到图形

BuildMp4CaptureGraph 创建了上图的图形,ACM Wrapper 和 GDCL Mux 过滤器被创建并使用 CoCreateInstance 从此方法添加到图形

我猜有些资源需要对外释放,不确定。

【问题讨论】:

  • 你考虑过只使用一张图吗?只需在 30 分钟停止,更改输出文件名并重新启动?
  • 是的,我们已经做到了……但我丢失了大约 100 毫秒到 150 毫秒的数据。但我们需要非常高的准确度

标签: visual-c++ directshow video-capture multiple-instances


【解决方案1】:

-2147220969 -> 0x80040217 -> VFW_E_CANNOT_CONNECT:

找不到中间过滤器的组合来建立连接。

也就是说,您第二次构建图表的尝试失败了。您需要检查图表上的过滤器,以将错误隔离到特定的引脚连接。

另请注意,您通常不能在 2 个以上的图表中使用相同的捕获设备,它们被活动管道独占锁定。

【讨论】:

  • 感谢@Roman R.,对于您的回复,我保存了使用我的应用程序构建的图表,我的问题中有所有如上图所示的过滤器,其中所有视频捕获过滤器已连接和音频捕获过滤器未连接,关闭我的应用程序后,我可以手动连接Audio Source PinACM Wrapeer。那么这可能是锁定设备资源的问题吗?但如果是这种情况,那么我的视频捕获图也不应该连接,但它们会连接。你有什么想法??
  • 所以你看到了断开的连接,它导致了失败。这是您开始故障排除的依据。正如我提到的,排他锁很可能会发生。还要确保通过名字对象(而不是 CoCreateInstance)创建捕获过滤器。
  • 感谢@Roman R. 的回复......好吧,我从 2 天开始就解决了这个问题,仍然没有任何理由或方法来解决这个问题 :( :(,我正在制作视频和使用名字对象的音频捕获过滤器...我们是否需要仅使用名字对象创建ACM Wrapper 和其他音频过滤器??还有一件事...我还尝试停止第一个图,然后构建并运行第二个图,他们也我得到同样的错误??在这种情况下,因为第一个图没有使用资源,那么它应该允许第二个图运行......但它没有发生??有什么建议吗??
  • 好的,如果您可以在创建第二个图表的位置发布代码片段,这可能会有所帮助。
  • 嗨@Roman R. 实际代码非常大,我使用Directshow's AMCap 代码作为参考。所以,StartCaptureStopCapture 方法是一样的。我已将TimerQueue 用于捕获所需的视频,并在Timer Signal 上,我首先将StopCapture 用于第一张图,然后将StartCapture 用于第二张图。我在那里编辑帖子和一些代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多