Передача образцов видео MPEG4 в декодер - Как использовать CBaseOutputPin::DeliverNewSegment()?

Я написал свой собственный фильтр DirectShow RTSP Push Source (CBaseFilter), который работает на H264 как шарм! Но, когда я попытался поддержать MPEG4 (поток MP4V-ES), я наткнулся на проблему... Мой поток декодируется (с фильтром ffdshow Video Decoder или DivX Video Decoder) и воспроизводится идеально в течение ровно 10 секунд. Изображение бегло со скоростью 15 кадров в секунду, но через 10 секунд количество кадров в секунду резко падает, и декодируются только IVOP, а PVOP /BVOP отбрасываются... даже если я их получаю и вовремя отправляю их в декодер.

Затем я начал возиться со своим кодом и обнаружил, что правильно распаковываю полезную нагрузку MPEG4 RTP и отправляю образцы мультимедиа в декодер правильно, а также правильно их освобождаю. CBaseOutputPin::DecideBufferSize() делает свою работу как надо, и я звоню IMediaSample::SetTime() правильно... НО, если я изменю этот код, который доставляет образец в декодер:

hr = videoPin->Deliver(sample);
sample->Release();

с этим кодом (обратите внимание на первую строку):

videoPin->DeliverNewSegment(REFERENCE_TIME(start), REFERENCE_TIME(end), 1.0);                                               
hr = videoPin->Deliver(sample);
sample->Release();

видео бегло через 10 секунд и более (fps остается на 15), но картинка все испорчена... как будто IVOP не декодируется должным образом, и есть некоторые артефакты в статических частях сцены.

Итак, как мне использовать CBaseOutputPin::DeliverNewSegment()? И какого черта мне это нужно?

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

Я гуглил, но без удачи. Любая помощь будет оценена. Thanx.

ОБНОВИТЬ

В методе videoPin->DeliverNewSegment(tStart, tStop, dRate) Параметр dRate:

Скорость, с которой этот сегмент должен обрабатываться, в процентах от первоначальной ставки.

Так что если вместо 1.0 я кладу 100.0 поток идет так, как и должно быть, но с некоторой задержкой между кадрами. Но это пока лучшее!

1 ответ

Решение

Я не уверен, что NewSegment вызывает проблемы, которые вы видите. NewSegment используется в тех случаях, когда данные, которые вы отправляете в одном пакете, пересекают время начала или время окончания и позволяют декодеру доставлять только до времени остановки. В этом случае вы можете вызвать NewSegment (0, MAX_LONGLONG, 1) один раз в начале потоковой передачи, и все должно быть в порядке.

Если вы видите проблемы, то, возможно, вам следует проверить задержку на выходе декодера (сравнить временную метку с текущим временем потока).

г

Другие вопросы по тегам