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;
}
我正在处理多节目 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;
}