Эффективное подключение асинхронного IMFSourceReader к синхронной IMFTransform

#ms-media-foundation

#ms-media-foundation

Вопрос:

Учитывая, что асинхронный IMFSourceReader подключен только к синхронной IMFTransform.

Тогда для обратного вызова IMFSourceReaderCallback::OnReadSample() не следует ли не вызывать IMFTransform::ProcessInput непосредственно в OnReadSample, а вместо этого поместить созданный образец в другую очередь, чтобы другой поток вызывал преобразования ProcessInput?

Или я просто буду копировать идентичные программы чтения исходных текстов, которые обычно выполняются внутри? Или, другими словами, может ли работа в OnReadSample блокировать любую дальнейшую работу по декодированию в программе чтения исходного кода, которая в противном случае могла бы выполняться более асинхронно?

Итак, я предлагаю что-то вроде:

 WorkQueue transformInputs;
...

//  Called back async
HRESULT OnReadSampleCallback(... IMFSample* sample)
{
    // Push sample and return immediately
    Push(transformInputs, sample); 
}

//  Different worker thread awoken for transformInputs queue samples
void OnTransformInputWork()
{
    //  Transform object is not async capable
    transform->TransformInput(0, Pop(transformInputs), 0);
    ...
}
  

Это затронуто, но не подробно описано здесь «Реализация интерфейса обратного вызова»:
https://learn.microsoft.com/en-us/windows/win32/medfound/using-the-source-reader-in-asynchronous-mode

Или это полностью зависит от того, что исходный reader настраивает внутренне, и его нелегко определить?

Ответ №1:

Не рекомендуется выполнять длительную операцию блокировки IMFSourceReaderCallback::OnReadSample . Ничто не будет фатальным или серьезным, но это не предполагаемое использование.

Принимая во внимание ваш предыдущий вопрос о преобразовании аудиоформата, преобразование данных аудио-сэмплов выполняется достаточно быстро, чтобы выполнить такой обратный вызов.

Кроме того, это неясно или не задокументировано (зависит от фактической реализации), ProcessInput часто выполняется мгновенно и ссылается только на входные данные. ProcessOutput в этом случае это будет дорого с точки зрения вычислений. Если вы не выполните ProcessOutput прямо там в том же обратном вызове, вы можете столкнуться с ситуацией, когда MFT больше не принимает входные данные, и поэтому вам все равно придется реализовать очередь.

Имея все это в виду, вы бы просто выполнили обработку в обратном вызове, пренебрегая влиянием на производительность, предполагая, что ваша обработка не слишком тяжелая, или в противном случае вы бы просто начали выполнять очередь в противном случае.

Комментарии:

1. Я также задаюсь вопросом, является ли наличие пула синхронизированных объектов IMFTransform (в моем текущем случае — передискретизаторов звука) для передачи в систему задач потенциально полезным для разработки. Но тогда вам нужно очистить преобразования, чтобы разграничить параллельно обработанные преобразованные фрагменты и убедиться, что они упорядочены впоследствии. Я подозреваю, что этот передискретизатор будет разграничивать фрагменты таким образом, чтобы избежать какой-либо внутренней буферизации частичных результатов. Как вы говорите, хотя для повторной выборки звука это, вероятно, уже очень быстро.

2. Нет необходимости в нескольких преобразованиях, и вы даже не сможете заставить это работать правильно. У вас будет один экземпляр MFT для непрерывной обработки данных в виде потока. Сама по себе повторная выборка выполняется достаточно быстро, проблема в обратном вызове больше связана с блокировкой / синхронизацией, а не с медленной обработкой.