我正在使用多程序UDP MPEG-2 TS流,但不幸的是,它们以随机间隔动态地重新映射其基本流PID。正在使用Microsoft的MPEG-2解复用器过滤器对该流进行解复用。
我正在使用PSI-Parser过滤器(DirectShow基类中包含的示例过滤器)来对PAT / PMT的变化做出反应。
代码对更改做出了适当的反应,但是在我将Demuxer引脚重新映射到其新ID之后,我遇到了一些奇怪的崩溃(堆内存损坏)。 (重新映射是在正在处理图形事件的线程内执行的,而正在处理EC_PROGRAMCHANGED消息)。
崩溃可能是由于我的代码错误所致,但是我还没有找到任何引用来告诉我在图形运行时更改引脚PID映射是否安全。
如果操作安全,谁能提供一些信息,如果操作不安全,我该怎么做以最大程度地减少捕获中断?
答案 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;
}