Фильтр демультиплексора MPEG-2 от Microsoft - могу ли я изменить PID элементарного потока во время работы графика? - PullRequest
0 голосов
/ 03 декабря 2018

Я работаю с многопрограммными потоками UDP MPEG-2 TS, которые, к сожалению, динамически переопределяют свои PID элементарного потока через случайные интервалы.Поток демультиплексируется с использованием фильтра демультиплексора MPEG-2 Microsoft.

Я использую фильтр PSI-Parser (пример фильтра, включенного в базовые классы DirectShow), чтобы реагировать на изменения PAT / PMT.

Код правильно реагирует на изменение, но у меня возникают некоторые странные сбои (повреждение кучи памяти) сразу после того, как я переназначаю выводы демультиплексора на их новые идентификаторы.(Переопределение выполняется внутри потока, который обрабатывает события графа, пока обрабатывается сообщение EC_PROGRAMCHANGED).

Возможно, сбой произошел из-за неисправного кода в моей части, но я не нашел никакой ссылкиэто говорит мне, безопасно ли менять отображение PID пин-кода во время работы графика.

Может ли кто-нибудь предоставить некоторую информацию, если эта операция безопасна, а если нет, что я могу сделать, чтобы минимизировать нарушение захвата?

1 Ответ

0 голосов
/ 12 декабря 2018

Мне удалось найти исходный код для версии фильтра демультиплексора 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 участник никогда не очищается .Таким образом, -apart от сообщения о неправильном количестве программ в таблице после сброса (поскольку оно обновляется постепенно для каждой программы, найденной в таблице) -, при следующей очистке таблицы она попытается освободить памятьэто было уже выпущено .

Вот моя обновленная версия, которая исправляет ошибки повреждения кучи:

_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;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...