IMediaControl :: stop没有信号时挂起 [英] IMediaControl::stop hangs when there is no signal

查看:207
本文介绍了IMediaControl :: stop没有信号时挂起的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个在Google中似乎很常见的问题,但这并没有帮助我。当我的应用尝试关闭所有内容时,释放对象之前调用的最后一个函数是IMediaControl :: stop。有信号时一切正常。但是,当我无信号启动应用程序(或在应用程序运行时终止它)时,程序永远不会从stop()返回。更重要的是,如果在信号已经挂起的情况下提供信号,一切都会恢复正常,程序会正确地退出并退出。

I have a problem that seems to be very common in Google, but it didn't help me. When my app is trying to close everything, the last function called before releasing objects is IMediaControl::stop. Everything is OK when there is signal. But when I launch app without signal (or terminate it while app is working) program never returns from stop(). What's more, if I provide signal while it's already hanged everything comes back to normal and program unhangs and exits correctly.

这是我的main代码的一部分:

This is a part of my code in main:

hr = connectFilters(pGraph, pCaptureDevice, AUDIO_INPUT_DEVICE_PIN_NAME,
pAnalyzerFilter, SPDIF_ANAL_FILTER_PIN_NAME);
if(SUCCEEDED(hr))
{
    // run the graph
    hr = pControl->Run();
    if(SUCCEEDED(hr))
    {        
        // wait for UI thread to finish
        pFilterObject->WaitForThread();

        // stop the graph and exit
        pControl->Stop();
    }
}

releaseObjects();
return 0;

Google建议死锁(的确是死锁)是由某些线程互相等待引起的。 UI线程似乎不是问题,因为我在没有Window的情况下基于此应用程序制作了一个DLL,而问题却是相同的。

Google suggests deadlock (and indeed it is) caused by some threads waiting for each other. The UI thread seems not to be the problem, because I did an DLL based on this app without Window and the problem is just the same.

在此先感谢您,

日食

编辑

我只有两个过滤器:源和转换。问题肯定在变换过滤器中,因为没有它,程序运行正常。这是不是在某个地方没有释放缓冲区或样本的问题?我不完全了解DirectShow的工作原理,但是如果没有信号,也许还需要做一些额外的事情?

I have only two filters: source and transform. The problem is for sure in transform filter, because program runs fine without it. TCould it be the problem of not released buffers or samples somewhere? I don't know exactly how DirectShow works but maybe some extra things need to be done if there is no signal?

编辑2

我在Google中发现有人在停止图形之前通过停止源过滤器解决了此问题。我做了同样的事情,它也挂了...我用它来获取源过滤器:

I found out in Google that someone solved this problem by stopping source filter before stopping the graph. I did the same and it also hangs... I use this to get source filter:

hr = pFG2->AddSourceFilterForMoniker(pMoniker, pContext, wszName, &pSource);
*ppF = pSource;
(*ppF)->AddRef();

当我附加VS调试器时,它说它无法显示代码,所以我认为它在某个地方在MS代码中。即使我注释了处理IMediaSamples的函数,它仍然挂起。现在我用尽了所有想法,出了什么问题。我还尝试了以不同方式停止和从图形中删除过滤器。

When I attach VS debugger it says that it can't display code, so I think it is somewhere in MS code. Even if I comment my function processing IMediaSamples it still hangs. Now I run out of the ideas what is wrong. I also tried stopping and removing filters from the graph in different ways.

推荐答案

尝试发送传入的消息时,我遇到了同样的问题从后台线程到WPF窗口的图像。一切都很好,直到我尝试停止mediacontrol或释放任何内容为止。

I had the same problem when trying to send the incoming image from a background thread up to the WPF window. Everything was fine until I tried to stop the mediacontrol or release anything.

问题出在动作的调度程序调用中,以将其传递到UI线程。我暂时将通话打掉了,这使视频完全停止在屏幕上显示,但是我可以随时在samplegrabber中打断它,并查看它实际上仍在运行。

The problem was with a dispatcher call of the action to get it to the UI thread. I temporarily commented out the call, which stopped the video from showing up on the screen at all, but I could break at any time in the samplegrabber and see it was still actually running.

需要在线程之间手动分离映像。泛型函数中的某些内容可以保留引用,因此com对象

Manually separating the image across threads is what needed to happen. Something in the generic functions keeps a reference around, so the com objects

要解决此问题,我在窗口中创建了一个dispatchertimer,将其间隔设置为1ms,将其回调设置为一个功能,它执行UI更新,然后在抓取器中,使buffercb事件将帧保存到独立变量中并启用计时器。

To fix it, I created a dispatchertimer in the window, set its interval to 1ms, its callback to a function that does the UI update, and then in the grabber, had the buffercb event save the frame to a standalone variable and enable the timer.

这里是一个简短的外观在我最后得到的结果是:

Here is a brief look at what I ended up with:

    InteropBitmap newbmp;
    DispatcherTimer refreshTimer;
    refreshTimer = new DispatcherTimer(TimeSpan.FromMilliseconds(1), DispatcherPriority.Render, ontimer, this.Dispatcher);
    videoSampleCB.newframearrived += capGrabber_NewFrameArrived;

    void capGrabber_NewFrameArrived(object sender, EventArgs e)
    {
        newbmp = videoSampleCB.newimage;
        refreshTimer.IsEnabled = true;
    }
    void ontimerobject sender, EventArgs e)
    {
        this.BitmapSource = newbmp;
        refreshTimer.IsEnabled = false;
    }
class VideoSampleGrabberCallBack : ISampleGrabberCB  
{
        event eventhandler newframearrived;

        public InteropImage newimage;
        public int BufferCB(double sampleTime, IntPtr buffer, int bufferLen)
        {
             newimage = ...
             newframearrived(this, eventargs.empty);
        }
}

这篇关于IMediaControl :: stop没有信号时挂起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆