Microsoft 的 MPEG-2 多路分解器过滤器 - 我可以在图形为 运行 时更改基本流 pin 的 PID 吗?

Microsoft's MPEG-2 demuxer filter - can I change an elementary stream pin's PID while the graph is running?

我正在处理多节目 UDP MPEG-2 TS 流,不幸的是,它们以随机间隔动态地重新映射它们的基本流 PID。正在使用 Microsoft 的 MPEG-2 多路分解器过滤器对流进行多路分解。

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

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

崩溃可能是由于我的代码错误造成的,但我还没有找到任何参考资料告诉我在图表为 运行 时更改引脚 PID 映射是否安全。

任何人都可以提供一些信息,如果这是操作是安全的,如果不是,我可以做些什么来尽量减少捕获中断?

我设法找到了 Windows CE 版本的多路分离器过滤器的源代码。检查它,确实,似乎在过滤器 运行.

时重新映射一个 pin 是安全的

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

当检测到新的传输流或 PAT 版本更改时,PAT 将被刷新(删除所有程序,重新解析并重新填充 table)。 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 成员 从未被清除 。因此,- 除了在刷新后报告 table 中错误的程序数量(因为它会针对 table 中找到的每个程序进行增量更新)-, 下一次table 被刷新,它会尝试释放已经释放的内存

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

_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;
    }