#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 для непрерывной обработки данных в виде потока. Сама по себе повторная выборка выполняется достаточно быстро, проблема в обратном вызове больше связана с блокировкой / синхронизацией, а не с медленной обработкой.