Microsoft的MPEG-2多路分解器滤波器-图形运行时是否可以更改基本流引脚的PID?

时间:2018-12-03 19:56:00

标签: directshow mpeg2-ts

我正在使用多程序UDP MPEG-2 TS流,但不幸的是,它们以随机间隔动态地重新映射其基本流PID。正在使用Microsoft的MPEG-2解复用器过滤器对该流进行解复用。

我正在使用PSI-Parser过滤器(DirectShow基类中包含的示例过滤器)来对PAT / PMT的变化做出反应。

代码对更改做出了适当的反应,但是在我将Demuxer引脚重新映射到其新ID之后,我遇到了一些奇怪的崩溃(堆内存损坏)。 (重新映射是在正在处理图形事件的线程内执行的,而正在处理EC_PROGRAMCHANGED消息)。

崩溃可能是由于我的代码错误所致,但是我还没有找到任何引用来告诉我在图形运行时更改引脚PID映射是否安全。

如果操作安全,谁能提供一些信息,如果操作不安全,我该怎么做以最大程度地减少捕获中断?

1 个答案:

答案 0 :(得分:0)

我设法找到Windows CE版本的多路分解器过滤器的源代码。实际上,检查它,在过滤器运行时重新映射图钉似乎是安全的

我也设法通过PSI-Parser过滤器找到了问题的根源。

当检测到新的传输流或更改PAT版本时,将刷新PAT(删除所有程序,重新解析并重新填充表)。 CPATProcessor::flush()方法中有一个细微的错误。

//
// flush
//
// flush an array of struct: m_mpeg2_program[];
// and unmap all PMT_PIDs pids, except one: PAT
BOOL CPATProcessor::flush()
{
    BOOL bResult = TRUE;
    bResult = m_pPrograms->free_programs();   // CPrograms::free_programs() call
    if(bResult == FALSE)
        return bResult;
    bResult = UnmapPmtPid();
    return bResult;
}// flush

这是CPrograms::free_programs()的实现。

_inline BOOL free_programs()
    {
        for(int i= 0; i<m_ProgramCount; i++){
            if(!HeapFree(GetProcessHeap(), 0, (LPVOID) m_programs[i] ))
                return FALSE;
        }
        return TRUE;
    }

这里的问题是m_ProgramCount成员从未清除。因此,-除了刷新后在表中报告错误的程序数量(因为它会针对表中找到的每个程序进行增量更新)--下次刷新表时,它将尝试释放内存已经发布

这是我的更新版本,可修复堆损坏错误:

_inline BOOL free_programs()
    {
        for(int i= 0; i<m_ProgramCount; i++){
            if(!HeapFree(GetProcessHeap(), 0, (LPVOID) m_programs[i] ))
                return FALSE;
        }
        m_ProgramCount = 0;  // This was missing,  next call will try to free memory twice
        return TRUE;
    }