0

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

我正在使用 PSI-Parser 过滤器(DirectShow 基类中包含的示例过滤器)来响应 PAT/PMT 更改。

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

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

如果这是安全的操作,任何人都可以提供一些信息,如果不是,我该怎么做才能最大限度地减少捕获中断?

4

1 回答 1

0

I managed to find the source code for a Windows CE version of the demuxer filter. Inspecting it, indeed, it seems that it is safe to remap a pin while the filter is running.

I also managed to find the source of my problems with the PSI-Parser filter.

When a new transport stream is detected, or the PAT version changes, the PAT is flushed, (all programs are removed, the table is re-parsed and repopulated). There is a subtle bug within the CPATProcessor::flush() method.

//
// 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

Here's the CPrograms::free_programs() implementation.

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

The problem here is that the m_ProgramCount member is never cleared. So, -apart from reporting the wrong number of programs in the table after a flush (since it is updated incrementally for each program found in the table)-, the next time the table is flushed, it will try to release memory that was already released.

Here's my updated version that fixes the heap corruption errors:

_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;
    }
于 2018-12-12T15:57:27.760 回答