Я использую DirectShow для кодирования MP4 в режиме реального времени из источника с веб-камеры. Я использую кодировщик Intel QuickSync для кодирования h264, а также их фильтр Muxing, все они подключены к стандартному File Writer.
Большую часть времени видео получаются великолепными - без проблем. Однако, похоже, существует условие состязания, при котором иногда создаваемые файлы выглядят так, как будто они являются неподвижными кадрами при открытии в WMP или VLC, но фактически вся информация, по-видимому, присутствует, поскольку их можно легко перекодировать для восстановления. - практически любой метод перекодировки, который я пробовал, делает свое дело.
Хотя перекодирование работает, я бы хотел решить проблему в источнике, а не удваивать работу.
Кто-нибудь сталкивался с этим раньше, чтобы дать представление о том, что может быть причиной проблемы? Я включу некоторый код, который я использую, чтобы остановить график, поскольку я предполагаю, что именно здесь вводится условие гонки.
Я пытался использовать методы Stop () и StopWhenReady () IMediaControl, с одинаковыми результатами. Я попытался проверить, не заблокирован ли файл перед возвратом из этого метода, но он никогда не блокируется после остановки, а также попытался выполнить кодирование с несколькими различными настройками качества.
int hr = 0;
IBaseFilter outputSampleGrabberFilter = null;
FilterState filterState;
try
{
IMediaControl mediaCtrl = filterGraph as IMediaControl;
hr = filterGraph.FindFilterByName(FilterIdentifier.OUTPUT_SAMPLE_GRABBER.ToString(),
out outputSampleGrabberFilter);
DsError.ThrowExceptionForHR(hr);
ISampleGrabber outputSampleGrabber = outputSampleGrabberFilter as ISampleGrabber;
hr = outputSampleGrabber.SetCallback(null, 0);
DsError.ThrowExceptionForHR(hr);
hr = mediaCtrl.Pause();
DsError.ThrowExceptionForHR(hr);
while (filterState != FilterState.Paused)
{
hr = mediaCtrl.GetState(100, out filterState);
DsError.ThrowExceptionForHR(hr);
}
hr = mediaCtrl.StopWhenReady();
DsError.ThrowExceptionForHR(hr);
hr = mediaCtrl.GetState(100, out filterState);
DsError.ThrowExceptionForHR(hr);
while (filterState != FilterState.Stopped)
{
hr = mediaCtrl.GetState(100, out filterState);
DsError.ThrowExceptionForHR(hr);
}
}
finally
{
DisposeComObject(ref outputSampleGrabberFilter);
}