Стоит задача вещания по сети участка экрана. В качестве source фильтра — фильтр на базе PushSourceDesktop. Приложение должно сграбить в битмап картинку, сжать в MPEG и отправить по UDP в локальную сеть. Граф строится следующий:
Проблемы:
1. Такой граф успешно доставляет информацию, смотрю в VLC плеере, все хорошо первые несколько секунд, потом начинается запаздывание показа. В конечном итоге присланное показывается спустя секунд 20 при времени жизни кадра в видео рендерере 1/5 сек.
2. Если нагрузить серверный камп, то на клиенте показывается только первый кадр, остальное отбрасывается (считается как drop frames)
3. Если из графа убрать мультиплексер, то теряются все кадры. Наблюдаю квадрат Малевича другими словами.
Полагаю, что проблема с TimeStamps, однако source фильтр делает засечки так, как это указывалось в сэмпле D9 SDK:
// Set the timestamps that will govern playback frame rate.
// If this file is getting written out as an AVI,
// then you'll also need to configure the AVI Mux filter to
// set the Average Time Per Frame for the AVI Header.
// The current time is the sample's start.
REFERENCE_TIME rtStart = m_iFrameNumber * (m_rtFrameLength);
REFERENCE_TIME rtStop = rtStart + m_rtFrameLength;
pSample->SetTime(&rtStart, &rtStop);
m_iFrameNumber++;
// Set TRUE on every sample for uncompressed frames
pSample->SetSyncPoint(TRUE);
Кто-нибудь сталкивался с такими проблемами? Буду благодарен за любые комментарии.
Здравствуйте, vALP, Вы писали:
ALP>PushSourceDesktop -> MPEG Encoder -> Multiplexer -> NetRenderer.
ALP>Проблемы: ALP>1. Такой граф успешно доставляет информацию, смотрю в VLC плеере, все хорошо первые несколько секунд, потом начинается запаздывание показа. В конечном итоге присланное показывается спустя секунд 20 при времени жизни кадра в видео рендерере 1/5 сек. ALP>2. Если нагрузить серверный камп, то на клиенте показывается только первый кадр, остальное отбрасывается (считается как drop frames) ALP>3. Если из графа убрать мультиплексер, то теряются все кадры. Наблюдаю квадрат Малевича другими словами.
ALP>Полагаю, что проблема с TimeStamps, однако source фильтр делает засечки так, как это указывалось в сэмпле D9 SDK:
смотрел сорцы PushSourceDesktop фрэйм там берутся используя битБЛТ а это ну далеко не самый быстрый метод... как следствие когда пуш фильтр приходит очередной раз в fillbuffer там находится еще старый фрейм, а не новый который не успелся взяться... а пушсорс туда заходит ну очень часто... можете ради интереса не стримить, а записать результат в файл и увидите что за 10 секунд у вас запишется на порядок длинее файл...
как решать проблему:
1. mirror driver он позволит вам с достаточной скоростью брать снапшоты дэсктопа
2. не уверн, но можно пробовать после обработки буфера в fillbuffer обнулять его
Здравствуйте, D. Mon, Вы писали:
DM>Здравствуйте, dabeat_bf, Вы писали:
_>> как следствие когда пуш фильтр приходит очередной раз в fillbuffer там находится еще старый фрейм,
DM>А как он туда прийдет, когда старый еще не отправлен? Все ж делается в одном потоке и одном цикле..
честно говоря сам не понимаю как это происходит... но постройте цепочку
PushDesctopSource -> avi_Mux -> file_writer и запишите секунд 10 видео с фрэймреэтом допустим 25 а потом посмотрите сколько секунд будет видео... и это при том что я не уврен что у битБЛТ будет хорошо получаться брать даже 25 в секунду...
Здравствуйте, D. Mon, Вы писали:
DM>Имхо, за скорость bitblt Вы зря боитесь, а в данном случае все банально упрется в скорость записи на диск.
какая скорость записи на диск? вы о чем? я пишу 10 секунд с фрэймрэйтом 25, а получаю видео под минуту с тем же фремрейтом! вроде так было, если не ошибаюсь
Ошибаетесь и других вводите в заблуждение.
Только что собрал тот фильтр (с 25 fps) и предложенный граф.
Записывал в течение почти 14 секунд. Получился всего 51 кадр (2 секунды). Потому что размер одного кадра — 5 мегов, а диск 125 мегов в секунду писать не будет. Играется тоже медленно, ибо диск. Загрузка процессора была в пределах 10%.
См. http://files.rsdn.ru/58130/desksource.png
Здравствуйте, D. Mon, Вы писали:
DM>Ошибаетесь и других вводите в заблуждение. DM>Только что собрал тот фильтр (с 25 fps) и предложенный граф. DM>Записывал в течение почти 14 секунд. Получился всего 51 кадр (2 секунды). Потому что размер одного кадра — 5 мегов, а диск 125 мегов в секунду писать не будет. Играется тоже медленно, ибо диск. Загрузка процессора была в пределах 10%. DM>См. http://files.rsdn.ru/58130/desksource.png
я конечно извиняюсь что ввел кого-то в заблуждение, видимо я писал другим разрешением экрана — это 1 и собственно 2 наверное таки был там перед авимуксом энкодер... проверьте думаю получите мой результат...
Если с энкодером, чтобы в диск не упиралось, то естественно — кадры будут писаться на максимальной скорости, никак не связанной с заданным fps (это значение в данном фильтре влияет на таймстемпы и воспроизведение, но никак не на запись). Но все равно все происходит последовательно и каждый следующий FillBuffer будет вызван только после завершения предыдущего.
Re[7]: потери кадров PushSource через сеть
От:
Аноним
Дата:
07.04.08 20:38
Оценка:
Здравствуйте, D. Mon, Вы писали:
DM>Только что собрал тот фильтр (с 25 fps) и предложенный граф. DM>Записывал в течение почти 14 секунд. Получился всего 51 кадр (2 секунды). Потому что размер одного кадра — 5 мегов, а диск 125 мегов в секунду писать не будет. Играется тоже медленно, ибо диск. Загрузка процессора была в пределах 10%.
По временным засечкам есть какие-нибудь мысли ? Влияет ли энкодер (или кто-нибудь еще дальше по графу) на подсчет времени? Главный вопрос, который меня напрягает — это почему теряются кадры при передаче по сети.
Большинство фильтров (включая компрессоры) на таймстемпы не влияют — получил кадр, пожал, с тем же таймстемпом отправил дальше.
Кадры могут или теряться при самой передаче, или отбрасываться рендерером как устаревшие. Советую построить пару графов (отправляющий и принимающий), добавить в каждый по Sample Grabber'y и в GraphEditPlus посмотреть логи грабберов — будет видно какие кадры с какими временами когда где идут, есть ли потери и в каком месте.