Форум: "Сети";
Текущий архив: 2006.05.21;
Скачать: [xml.tar.bz2];
ВнизОрганизация непрерывной передачи файлов по сети для видеочата Найти похожие ветки
← →
Setor (2005-10-26 01:42) [0]Пишу нечто вроде видеочата. Т.к. по сети нельзя передать видеопоток (по крайней мере информации по данной теме я не нашёл), передаю сжатые картинки (jpeg). На данный момент ситуация такова, что по таймеру я делаю запрос к серверу, а он мне отправляет картинку. При кол-ве запросов > 10 в секунду, иногда приложение зависает. Хотелось бы, если можно, не слать каждый раз запрос на получение картинки, а высылать их потоком друг за дружкой или быть может есть вариант лучше?
Видеозахват реализован при помощи DSPack
← →
Digitman © (2005-10-26 08:35) [1]
> по сети нельзя передать видеопоток
можно.
и видеопоток, и слышиопоток, и вообще любой поток любого рода информации
← →
Setor (2005-10-26 09:35) [2]Digitman, можно конечно, я не спорю, но как я уже сказал, на данный момент я не смог найти ни одного примера реализации подобного рода приложения на Delphi. Если ты можешь дать какую-то информацию по данной теме, буру рад выслушать, иначе твой пост бессмысленный!
← →
Digitman © (2005-10-26 10:03) [3]
> Setor (26.10.05 09:35) [2]
> твой пост бессмысленный
а твой разве имеет смысл без конкретики (какие компоненты Делфи пользуешь для работы с сетью, используешь ли вообще) ?
← →
DVM © (2005-10-26 10:24) [4]
> Т.к. по сети нельзя передать видеопоток (по крайней мере
> информации по данной теме я не нашёл)
Очень просто через HTTP. В MotionJPEG формате. jpeg - разделитель - jpeg - разделитель
← →
Eraser © (2005-10-26 17:17) [5]
> Setor (26.10.05 01:42)
Есть специальные потоковые видеоформаты.
Передавай через UDP или TCP.
← →
Arazel/NikNet (2005-10-26 19:00) [6]Передовай с помощью TMemoryStreem и TSocket
и оптимально и поточно!
← →
Setor (2005-10-26 21:18) [7]Описываю более подробно:
Имеется 2 приложения: Клиент и Сервер.
1) Сервер IdTCPServer
* При подключении клиента включается видеозахват (DSPack)
FilterGraph.ClearGraph;
FilterGraph.Active := false;
Filter.BaseFilter.Moniker := SysDev.GetMoniker( DefaultVideoDevice ); // DefaultVideoDevice = номер выбранного девайса
FilterGraph.Active := true;
with FilterGraph as ICaptureGraphBuilder2 do
RenderStream(@PIN_CATEGORY_CAPTURE, nil, Filter as IBaseFilter, nil, SampleGrabber as IBaseFilter );
FilterGraph.Play;
* Сервер ждёт команд клиента
* При получении команды от клиента, сервер берёт 1 кадр (bmp) конвертирует его в jpg опред. качества и отправляет клиенту
procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var
stream: TStream;
get : string; // команда клиента
jpg: TJpegImage;
bmp: TBitmap;
begin
get:= AThread.Connection.Readln;
if FilterGraph.Active = true then
begin
if get = "go" then
begin
stream:= TMemoryStream.Create;
try
stream.Position:= 0;
jpg:= TJpegImage.Create;
try
jpg.ProgressiveEncoding:= False;
jpg.CompressionQuality:= VideoQuality;
bmp:= TBitmap.Create;
try
SampleGrabber.GetBitmap( bmp );
jpg.Assign( bmp );
finally
bmp.Free;
end;
jpg.SaveToStream( stream );
AThread.Connection.WriteStream( stream, true, true );
finally
jpg.Free;
end;
finally
stream.Free;
end;
end;
end
end;
2) Клиент IdTCPClient
* Подключается к серверу
* Активируем таймер, по которому происходит запрос и получение кадра
procedure TForm2.Timer1Timer(Sender: TObject);
var
stream: TMemoryStream;
jpg: TJpegImage;
begin
if IdTCPClient1.Connected = false then
begin
ShowMessage( "Not Connected!" );
Stop1.Click;
exit;
end;
stream:= TMemoryStream.Create;
try
IdTCPClient1.WriteLn("go");
IdTCPClient1.ReadStream(stream);
stream.position:=0;
jpg:=TJpegImage.Create;
try
jpg.LoadFromStream( stream );
Image1.Canvas.Lock;
try
Image1.Picture.Bitmap.Assign(jpg);
finally
Image1.Canvas.Unlock;
end;
finally
jpg.Free;
end;
finally
stream.Free;
end;
end;
Как видите, всё чертовски просто! Приложение используется в локальной сети, проверено и работает без проблем.
В качестве дополнения:
1) можно указать скорость видеозахвата (не реализовано)
2) можно менять качество передаваемых jpg картинок (реализовано)
3) получать опр. количество кадров в секунду с сервера (изменить интервал таймера)
Загрузка процессора (Celeron 2GHz, RAM >= 512Mb):
Сервер:
* Видеозахват 320x240 (процесс System) кушает ~20%
* bmp->jpg (60% quality) 5-10 кадров/сек кушает ~15% CPU
Клиент:
* Отображение полученных jpeg изображений 5-10 кадров/сек кушает ~10% CPU
Возможно, что-то используется неоптимально, в дельфи я новичок.
← →
Digitman © (2005-10-27 08:40) [8]Для рамок ЛВС под управлением сетевого ПО от Майкрософт использовать TCP в кач-ве транспортного протокола для эффективного решения данной задачи, imho, неразумно. Гораздо лучших результатов (с т.з. производительности транспортной подсистемы) можно достичь с использованием именованых программных каналов (Namep Pipes). Если в ЛВС есть хосты под управлением иных ОС (не Windows), то в этом случае лучшим решением будет использование UDP в кач-ве транспортного протокола - он проще в реализации и потому ощутимо быстрей нежели ТСР.
К тому же я не вижу резона для организации ПИО в виде "клиент запрашивает кадр - сервер передает кадр". При подключении клиенту достаточно единожды сообщить серверу желаемые параметры видеопотока, такие, например, как FPS (число кадров , которые клиент способен принять и обработать в секунду), разрешение, глубина цветности, способ кодирования и т.п. После этого сервер начинает передавать видеопоток безо всяких подтверждений клиента о принятых им фрагментах. С этого момента уже клиент ответственен за максимально быструю обработку принимаемых фрагментов потока. Те фрагменты, которые клиент не успел обработать, попросту исключаются. Чтобы при этом не нарушалась синхронизация сервер должен включать в передаваемый поток метки времени и в зависимости от способа кодирования периодически передавать опорные кадры.
← →
Slym © (2005-10-27 10:22) [9]Причина зависа- фрагментация склейка пакетов...
как ты в потоке между собой JPGи отличаешь? никак! и получается один кадр ты перегрузил второй не догрузил...
Я бы сделал так:
1. раз сообщил FPS
2. на сервере отсылал картинку постоянно (без команды) и паузой для ФПС. (менше Sleep выше FPS больше загруз CPU)
3. Использовал ПРОТОКОЛ ПЕРЕДАЧИ, т.е. договоренность сторон об сигнатурах разделения картинок. Будь то boundary как в MotionJPG, или заголовок с указанным размером данных картинки.
← →
Slym © (2005-10-27 10:30) [10]4. Можно отсылать только изменения картинки
или на 1 этапе. флаг not changed для статичной картинки... фпс на статике выростет
← →
Setor (2005-10-27 11:23) [11]Digitman
> лучшим решением будет использование UDP в кач-ве транспортного
> протокола - он проще в реализации и потому ощутимо быстрей
> нежели ТСР
Я подумаю над этим вопросом. Изначально я тоже склонялся в сторону UDP, но т.к. с TCP я знаком намного лучше, решил взять его за основу для передачи данных.
Slym
> Причина зависа- фрагментация склейка пакетов...
Да, я уже не раз сталкивался с данной проблемой. Где-то на форуме мелькало одно из решений данной проблемы.
Digitman
> я не вижу резона для организации ПИО в виде "клиент запрашивает
> кадр - сервер передает кадр".
Мне тоже чертовски не нравится данная схема, по этому я собственно, и задал вопрос на форуме.
Digitman
> сервер должен в зависимости от способа кодирования
> периодически передавать опорные кадры
Если я правильно понял, речь идёт о сжатии видеопотока и передаче этого потока по сети? Я ещё не обладаю достаточными знаниями для реализации подобного алгоритма.
Slym
> Я бы сделал так:
> 3. Использовал ПРОТОКОЛ ПЕРЕДАЧИ, т.е. договоренность сторон
> об сигнатурах разделения картинок. Будь то boundary как
> в MotionJPG, или заголовок с указанным размером данных картинки.
Искал я в интернете информацию по поводу MotionJPEG... Её оказалось не так уж и много. Посмотрел кодек Morgan"а, а он денег стоит...
По поводу boundary - идея неплохая, лишь бы в коде картинок не встретилось комбинации символов, используемой для разделения картинок (boundary), иначе всё поломается...
Единственная проблема заключается в том, что я просто не у мею создавать кадры, класть них заголовки и тело, не знаю как потом разделить и пропарсить эти полученные кадры. У меня были в голове аналогичные идеи, но в связи с тем, что с Delphi я мало знаком, делал так, как умею. Моя основная специализация - WEB программист (PHP), а в создании приложений для Windows - я как рыба на суше.
Подведу итоги, то что хотелось бы изменить:
1) В качестве транспортного протокола использовать UDP
2) Клиент единожды сообщает серверу параметры захвата видео (размеры, глубина цвета и fps)
3) Сервер начинает передачу видеопотока
4) Клиент обрабатывает принятый поток
По 3му и 4му пункту - я не знаю как создать и обработать видеопоток. Я знаю лишь то, что это должно быть потоковое видео. Это был бы идеальный вариант. Пока что для меня самое простое - использовать текущую схему разбиения на картинки. Но как их разделить... Вот в чём вопрос!
← →
Digitman © (2005-10-27 12:06) [12]
> речь идёт о сжатии видеопотока и передаче этого потока по
> сети?
да.
> не обладаю достаточными знаниями для реализации подобного
> алгоритма
в таком случае есть резон воспользоваться готовыми алгоритмами, реализованными в различных инсталлированных и доступных в системе кодеках
открой в панели управления "Звук и мультимедиа", в закладке "Оборудование" выбери "Видеокодеки", найди в Сети и изучи материалы, касаемые характеристик того или иного интересующего тебя кодека ... если устраивает, найди в Сети материалы, касаемые программного доступа к интерфесам видеокодеков - базовые интерфейсы как правило стандартные для любого кодека
← →
Slym © (2005-10-27 14:53) [13]Незаметил- Фактически перед каждой картинкой посылаешь размер данных:
отправка
AThread.Connection.WriteStream(stream, true, true );
(первый 4х байтник размер данных)
прием
IdTCPClient1.ReadStream(stream);
прием первых 4х байт потом прием N данных
← →
Eraser © (2005-10-27 18:48) [14]
> Digitman © (27.10.05 08:40) [8]
> Гораздо лучших результатов (с т.з. производительности транспортной
> подсистемы) можно достичь с использованием именованых программных
> каналов (Namep Pipes).
А разве это не обёртка над TCP/IP, при использовании в сети, а не на локальном компьютере?
← →
Setor (2005-10-28 02:51) [15]Пытался передать видеопоток через UDP, но возникла проблема - слишком большие кадры... В принципе, их можно отправлять кусками. Только как этот поток теперь проиграть на обратной стороне...
Видеопоток получаю SampleGrabber"ом для проигрывания, хотелось бы, тоже воспользываться DirectShow (DSPack). Буду копать дальше...
P.S. В сети я нашёл лишь 1 исходник видеочата, написанного на Delphi, но он какой-то глючный и слишком сложный для меня...
← →
Digitman © (2005-10-28 08:35) [16]
> Eraser © (27.10.05 18:48) [14]
> разве это не обёртка над TCP/IP
нет , это не обертка.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/optimsql/odp_tun_1a_7fcj.asp
> Setor (28.10.05 02:51) [15]
> Пытался передать видеопоток через UDP, но возникла проблема
> - слишком большие кадры
максимальный размер дейтаграмм, передаваемых под управлением UDP, можно изменить (см. SetSockOpt)
← →
Verg © (2005-10-28 09:27) [17]http://book.itep.ru/4/44/rtp_4492.htm
← →
Idx © (2005-10-28 09:36) [18]Да дайте ему хороши пример и все!!!
Кстати посмотри компонент TMNN на toory
← →
Eraser © (2005-10-28 14:58) [19]
> Digitman © (28.10.05 08:35) [16]
И правда... Спасибо за ссылку, а то я сам по этой теме не нашёл ничего.
← →
Анонимщики © (2005-10-28 16:54) [20]Не так-то просто найти хороший пример на эту тему, поскольку затрагивается множество подтем: захват видео, обработка (в частности, с использованием кодеков), передача по сети (вопрос, использовать ли UDP (можно и широковещательно) или TCP/IP - не так уж и прост; в коммерческих программах, обычно, реализованы оба варианта), прием с другой стороны, протокол обмена(в частности, подтверждать-не подтверждать прием кадра (для TCP, естественно), в случае TCP - как производить взаимодействие с каждым из подключенных клиентов - тоже можно по-разному сделать). Если еще и звук добавить - количество проблем вырастет.
Совет Digitman"а, в принципе, годится, да только он недоукомплектован.
Я бы посоветовал следующий путь:
1. Изучаем DirectShow. Можно достаточно поверхностно, можно и поглубже, включая написание собственных фильтров.
2. Если поверхностно, берем готовые фильтры - то ли из майкрософтовского примера - NetSend, кажется, он называется (он не идет с DSPack"ом), то ли, скажем, элекардовский MPEG-2 сетевой фильтр. Если глубже, пытаемся написать свой фильтр (фильтры), который бы покрывал множество наших задач: широковещательная передача и точка-точка (с разными, возможно, вариантами взаимодействия с подключенными клиентами).
3. Что касается использования кодеков, то их следует использовать при построениии графа фильтров на сервере и клиентах.
4. Можно пойти дальше, и разобраться еще и с Windows Media. После этого разбора будет понятно, каким образом использовать на стороне клиента Windows Media Player, а на стороне сервера - Windows Media Encoder. Сетевыми протоколами в таких случаях могут быть уже RTP/RTSP или, скажем, MMS. При очень большом желании можно и с ними разобираться. Впрочем, я не видел (правда, не искал особо) готовой библиотеки для работы через MMS. А вот для RTP/RTSP - есть свободная (вот забыл как называется и где можно взять).
Ну, и не советую использовать этот самый DSPack - только голову заморочит, особенно поначалу
← →
Setor (2005-10-28 20:11) [21]Я конечно не претендую на высокий уровень и изучение целой кучи новых технологий на неродном языке займёт немало времени. Конечно, если бы речь шла о корпоративном или просто массовом решении, то во всём этом был бы резон, но у меня задача проста. И в принципе, она уже воплощена, т.к. всё работает... криво, но работает. Я конечно, попытаюсь его улучшить.
По поводу DSPack - он только облегчает работу с DirectShow, так зачем искать геммор на свою задницу? Сегодня я сделаю, а завтра забуду. Пусть лучше будет просто и красиво.
← →
PAVIA © (2005-10-28 21:05) [22]Лично я использовал vfw для воспроизведения видео MPEG-4. Я пробовал UDP, TCP. Показывать надо начинать от ключевого кадра. Обязательно нужна проверка на то, что кадр дошел. Так как, если не ключевой кадр теряеться то программа падает. А теряються они как на UDP так и на TCP. Для того чтобы программа показывала 25 кадров в секунду, а не 5-10 надо передовать потоком. То есть иными словами в одном пакете нужно передовать сразу несколько кадров, забить под завяску. И наче будет работать медлено, причина органезация сети. Но нужно помнить об ограничение пакета. Еще лучше сделать буферизацию запасом в 1 секунду.
← →
rrr8888 (2005-11-24 17:45) [23]А чем вам протоколы SIP и H.323 не подходят - специально же для передачи потокового аудио/видео созданы..
← →
zd © (2006-01-26 16:33) [24]Всем здрасте, а у меня возник вопрос, а как подключать кодеки и использовать их, я знаю только как обычный jpeg и ещё вопрос m-jpeg он создает поток или может работать и с одним кадром.
Страницы: 1 вся ветка
Форум: "Сети";
Текущий архив: 2006.05.21;
Скачать: [xml.tar.bz2];
Память: 0.54 MB
Время: 0.013 c