Конференция "Сети" » Чем разделить видеопоток? [D7, WinXP]
 
  • ABolnykh © (06.10.09 15:25) [0]
    Здравствуйте, уважаемые Мастера!
    Кто-нибудь может подсказать направление решения следующей задачи?

    Имеется сетевая видеокамера со встроенным web-сервером.
    Когда к видеокамере подключается клиент, она начинает транслировать на его IP свой видеопоток.
    Когда к камере подключается второй клиент, она начинает транслировать свой видеопоток (тот же самый) и на его IP тоже.
    Когда к камере подключается десятый клиент, суммарное количество идентичных видеопотоков становится равно десяти.
    А если таких камер в сети - десятка полтора... Затык сети очевиден.

    Стоит задача: разработать некоторый дивайс (компьютер с программой с неким компонентом), в котором между видеокамерой и этим компонентом существовал бы один видеопоток, а уже этот компонент рассылал бы этот видеопоток всем подключившимся клиентам.
    Видеокамеры находятся в одной сети, клиенты - в другой.

    Прочитав "Глубины Indy", я, по простоте душевной, в качестве искомого компонента выбрал TIdMappedPort, посчитав, что на каждое подключение он, по умолчанию, самостоятельно создаст отдельный поток (Thread), что и требуется.

    Каково же было моё удивление, когда, написав пробный кусок программы и подключив через TIdMappedPort к камере трёх клиентов, а потом запросив лог видеокамеры, я обнаружил, что к камере подключены ТРИ клиента, а не один, как я ожидал. То есть, TIdMappedPort просто смаппировал обращённые к нему запросы к адресу камеры, а потоки же (Threads) если и создал для каждого подключения, то потоки обработки кода, а не видеопотоки. То есть, выбранный мною подход оказался неверным.

    Полазав как следует по Интернету в поисках ответа на вопрос, как же всё-таки люди решают подобную проблему, ничего не нашёл. :-( А судя по тому, что "видеонаблюдательные" программы сейчас плодятся, как грибы, проблема должна иметь простое или несложное решение.

    Может быть, кто-нибудь сталкивался с подобной задачей и может посоветовать если не готовый компонент, то хотя бы направление, в котором следует копать. Буду благодарен за любые наводящие мысли и советы.

    Пишу на Delphi 7, Indy 9.
  • CrytoGen (06.10.09 15:28) [1]
    По видимому вы плохо прочитали "Глубины Indy".
    А вообще для таких случаев обычно используют Mutlicast пакеты. В инди соответсвующие компоненты имеются.
    Дерзайте
  • ABolnykh © (07.10.09 10:50) [2]
    За слово "Multicast" спасибо. И хотя в "Глубинах Indy" оно упоминается всего пару раз, благодаря Интернету, я ознакомился с этой стороной жизни.

    А ещё что-нибудь наводящее, "поближе к телу"?
  • CrytoGen (07.10.09 12:57) [3]
    TIdIPMCastClient
    TIdIPMCastServer
    больше даже не знаю чего вам добавить.
  • ABolnykh © (07.10.09 13:20) [4]
    Вот это и нужно было добавить. :-)
    И хотя я сам уже почти вышел на эти компоненты, перелопатив кучу форумов, за подсказку СПАСИБО.

    Нелёгкое это дело - ходить в гости...
  • DVM © (07.10.09 16:37) [5]

    > ABolnykh ©   (06.10.09 15:25)  

    У меня есть программа которая тебе требуется, но она платная.

    Из компонентов интди тебе скорее понадобятся TIdTCPClient (или TIdHTTPClient) и TidHTTPServer.
  • ABolnykh © (08.10.09 09:06) [6]

    > У меня есть программа которая тебе требуется, но она платная.

    Спасибо за предложение, но мне дано задание написать программу, а не купить готовую. :-) :-) :-)
    К тому же, вряд ли Вам известны все подробности техзадания, так что, вполне вероятно, что это окажется и не совсем то, что мне требуется.

    В дальнейшем, на подобные предложения реагировать не буду, уж не обессудьте.
  • DVM © (08.10.09 11:17) [7]

    > ABolnykh ©   (08.10.09 09:06) [6]


    > К тому же, вряд ли Вам известны все подробности техзадания

    Пока из того, что ты написал, все 1 в 1. Я просто специализируюсь на IP камерах и сетевом видео, поэтому могу предположить, что тебе может понадобится.


    > В дальнейшем, на подобные предложения реагировать не буду,
    >  уж не обессудьте.

    Исходные тексты, я к сожалению, выслать не могу, не смотря на то что они есть. Но если возникнут вопросы - обращайся.
  • DVM © (08.10.09 11:21) [8]

    > ABolnykh ©   (08.10.09 09:06) [6]

    Кстати, что за камеры используешь?
  • ABolnykh © (08.10.09 14:05) [9]
    Использую Axis 207.

    Сразу оговариваюсь, что платить за советы могу только благодарностью, которую, как известно, в карман не положишь. Зато благодарность может иметь размерность Tiny, Small, Large, Huge - в зависимости от ценности совета.
    (Шучу, конечно. Это так, для разрядки.)

    Исходные тексты мне тоже не нужны, нужна ИДЕЯ, которая, хоть я и сижу уже второй день в прострации, самостоятельно приходить в голову почему-то никак не хочет. Если и понадобится исходник, то 5-10 строк, реализующих наиболее тонкий момент.

    Поставленная передо мной задача проста, как равнобедренный треугольник.
    В Интернете находятся несколько видеокамер. В локальной сети сидят несколько (N) наблюдателей-операторов и диспетчер, задающий, какому оператору что следует смотреть.
    Моя задача - написать буферное устройство, соединяющее эти две сети, плюс выполняющее некоторые сетевые команды диспетчера.

    Задачу уже можно было бы считать выполненной (всё работает!!!) и идти брать с полки пирожок, но тут неожиданно выяснилось, что... (см. первое сообщение этого топика.) И это явилось ударом под дых.
    Теперь непонятно: если делать Multicast-рассылку в локальной сети с помощью TIdIpMCastServer, то как смаппировать две сети? Если две сети уже смаппированы, то как сделать multicast-рассылку? То есть, как соединить MappedPort с MCast-сервером?

    В нашей организации это первая тема, связанная с сетевым программированием, так что спросить совета совершенно не у кого. Приходится изобретать очередной велосипед. Я же в сетевом программировании если уже не абсолютный ноль, но пока ещё не далеко от него ушедший, и потому задавать идиотские вопросы считаю своим прямым долгом и неотъемлемым правом. :)))
  • Eraser © (08.10.09 15:39) [10]
    > Теперь непонятно: если делать Multicast-рассылку в локальной
    > сети с помощью TIdIpMCastServer, то как смаппировать две
    > сети? Если две сети уже смаппированы, то как сделать multicast-
    > рассылку? То есть, как соединить MappedPort с MCast-сервером?

    что то перепуталось все... откуда то мультикаст вылез. я так понял, к камерам по TCP нужно соединяться?
  • ABolnykh © (08.10.09 15:59) [11]

    > что то перепуталось все... откуда то мультикаст вылез. я
    > так понял, к камерам по TCP нужно соединяться?

    Multicast вылез из сообщения [1].
    К камерам подсоединяюсь по TCP. Камеры и клиенты - в разных сетях.
    Проблема в том, что сколько подсоединений, столько и копий одного видеопотока в разные IP-адреса клиентов. А хотелось бы иметь ОДИН видеопоток и чтобы его принимали все, кому он нужен (т.е. кому положено его принимать, не бродкаст).
    А как это сделать - самому мне не додуматься, Brain.sys требует апгрейда до новой версии.  :-(

    Сейчас спрошу максимально тупо и конкретно. Если камера в своём логе сообщает, что к ней подключены 3 клиента - это что значит: что она посылает 3 видеопотока в подключенные адреса или 3 клиента принимают один транслируемый видеопоток? Конкретно осциллом в кабель я не заглядывал, но сдаётся мне почему-то, что видеопотоков она выдаёт три, оттого и испугался. Хотя, допускаю, что я и не прав.
    ?????????????????????
  • Eraser © (08.10.09 16:08) [12]
    > [11] ABolnykh ©   (08.10.09 15:59)


    > Проблема в том, что сколько подсоединений, столько и копий
    > одного видеопотока в разные IP-адреса клиентов. А хотелось
    > бы иметь ОДИН видеопоток и чтобы его принимали все, кому
    > он нужен (т.е. кому положено его принимать, не бродкаст)
    > .

    т.е. имеется
    камера <==> диспетчер (самописный) <==> клиент
    ?

    так вот
    тут ( диспетчер <==> клиент) количество соединений тоже критично?
  • ABolnykh © (08.10.09 16:23) [13]

    > так вот  
    тут ( диспетчер <==> клиент) количество соединений тоже критично?

    Тут некритично.
    Хотелось бы иметь один поток между камерой и самописным диспетчером.
  • Eraser © (08.10.09 16:49) [14]
    > [13] ABolnykh ©   (08.10.09 16:23)


    > Тут некритично.

    но в этом и состоит основная задача - делать пулл TCP потоков, либо использовать тот же мультикаст для рассылки картики клиентам.

    > Хотелось бы иметь один поток между камерой и самописным
    > диспетчером.

    с этим, как раз, никаких проблем нет.
  • ABolnykh © (08.10.09 16:59) [15]

    > но в этом и состоит основная задача - делать пулл TCP потоков,
    либо использовать тот же мультикаст для рассылки картики клиентам.

    Я понимаю, что дважды два - четыре, а трижды три - девять.
    Но вопрос-то был задан

    > Теперь непонятно: если делать Multicast-рассылку в локальной сети с помощью TIdIpMCastServer, то как смаппировать две сети? Если две сети уже смаппированы, то как сделать multicast-рассылку? То есть, как соединить MappedPort с MCast-сервером?

    и этот вопрос остался...
    Теперь уже до завтра.
  • DVM © (08.10.09 17:03) [16]

    > ABolnykh ©   (08.10.09 14:05) [9]


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

    :)


    > Использую Axis 207.

    Хорошие камеры, и главное документированные.


    > Поставленная передо мной задача проста, как равнобедренный
    > треугольник.

    Задача не так проста, как кажется. Просто тупо ретранслировать поток не выйдет, поток нужно принять, выделить кадры, затем собрать аналог потока. который транслировать клиенту.

    Данные камеры позволяют запбирать видеопоток двумя основными способами:
    1) HTTP
    2) RTSP

    Советую взять HTTP, это МНОГОООО проще. RTSP клиент и тем более сервер в разы сложнее.

    Работа ретранслятора грубо говоря выглядит следующим образом.

    1) Ретранслятор подключается к камере по HTTP и начинает принимать видеопоток.
    2) Выделяет очередной кадр (как разделены кадры в потоке см на сайте аксис HTTP API)
    3) После того как кадр выделен, мы его откладываем в некий буфер, затирая предыдущий.
    4) Продолжаем принимать входящий поток, обновляя наш буфер.
    5) Тут к ретранслятору подключается очередной клиент.
    6) Выдаем клиенту заголовок в соответствии с Axis HTTP API
    7) Начинаем высылать клиенту кадры, отделяя их друг от друга разделителями. Кадры берем из буфера. Между кадрами делаем паузы чтобы поддерживать нужную частоту кадров, которую например клиент может передать нам в запросе. Кадровый буфер причем должен быть потокобезопасный.
    8) Аналогично для второго третьего нн-ого клиентов.
    9) Кроме этого следует наверное отключаться от камеры если клиентов нет.

    Это наброски так сказать, так как сделано у меня.
    В двух словах не расскажешь, т.к. каждый шаг здесь отдельная длинная история.
  • DVM © (08.10.09 17:21) [17]

    > ABolnykh ©   (08.10.09 16:59) [15]

    Мультикаст использовать не рекомендую, т.к. во-первых это будет реально работоспособно только в локальной сети, да и то при поддержке свитча, во-вторых в данных камерах мультикаст основан на RTSP и намного сложнее в реализации.

    Кроме написания ретранслятора, понадобится еще какое то клиентское ПО, которое будет непосредственно обращаться к ретранслятору. Это может быть как отдельное приложение так и JavaScript / Java-апплет / ActiveX Control / Flash Player в веб интерфейсе самого ретранслятора.
  • Сергей М. © (10.10.09 13:08) [18]

    > как смаппировать две сети?


    см. IGMP-proxy
  • ABolnykh © (12.10.09 11:59) [19]

    > DVM ©   (08.10.09 17:03) [16]
    >
    > Работа ретранслятора грубо говоря выглядит следующим образом.
    > ..........................
    > Это наброски так сказать, так как сделано у меня.
    > В двух словах не расскажешь, т.к. каждый шаг здесь отдельная длинная история.

    "Ахренеть, дайте две!!!"

    Вам бы книжки писать - "Видеопрограммирование для чайников". Глядишь, через неделю и чайников бы не осталось. :-)

    Если, как я уже писал, до сих пор я просто пребывал в прострации, то после такого "хэлпа" у меня вообще опустилось всё, что только было к этому способно.

    Теперь у меня возник вопрос другого порядка.
    Если видеокамер у нас - 16, к каждой может подключаться штук 8 (пока ориентировочно) клиентов, для каждого видеопотока нужно организовать отдельный буфер, выделять и складывать в него кадры, отправлять их каждому подключившемуся клиенту, не забывая отделять кадры друг от друга разделителями и вставлять паузы, - какая мощность компьютера должна для этого быть? Обычный - не супер-пупер - потянет?
    Вопрос, на первый взгляд, может показаться дурацким, но я совершенно не в курсе, сколько вся эта арифметика затребует ресурсов.
  • Сергей М. © (12.10.09 13:40) [20]

    > Видеокамеры находятся в одной сети, клиенты - в другой


    Между этими подсетями есть "неподконтрольные" маршрутизаторы ?
    Т.е. такие, на которых нет возможности организовать проксирование мультикаст-пакетов ?
  • DVM © (12.10.09 14:12) [21]

    > ABolnykh ©   (12.10.09 11:59) [19]


    > Если видеокамер у нас - 16, к каждой может подключаться
    > штук 8 (пока ориентировочно) клиентов, для каждого видеопотока
    > нужно организовать отдельный буфер, выделять и складывать
    > в него кадры, отправлять их каждому подключившемуся клиенту,
    >  не забывая отделять кадры друг от друга разделителями и
    > вставлять паузы, - какая мощность компьютера должна для
    > этого быть? Обычный - не супер-пупер - потянет?

    Пропускная способность 100 мбит сети в идеале до 300 кадров/сек при размере кадра 640*480 точек и среднем сжатии (40 кбайт кадр). Для гигабитной примерно в 10 раз больше соответственно. Главное чтобы потянула сеть. Компьютер потянет. Я у себя тестировал значительно больше - работает нормально. Фактически вся нагрузка на компьютер - это поиск разделителей в принимаемом HTTP потоке. Если в потоке заданы Content-Length то поиск мгновенный.
    Компьютер лучше многоядерный (2-4 ядра), т.к. сервер инди он многопоточный и чем больше ядер тем ровнее будет загрузка процессора.
  • DVM © (12.10.09 14:17) [22]

    > ABolnykh ©   (12.10.09 11:59) [19]

    Есть такая бесплатная софтина под Linux: ZoneMinder. Так вот, она умеет все что тебе надо и она с исходниками на си++. http://www.zoneminder.com/
  • ABolnykh © (12.10.09 14:34) [23]

    > Сергей М. ©   (12.10.09 13:40) [20]
    >
    > Между этими подсетями есть "неподконтрольные" маршрутизаторы ?

    Камеры находятся в Интернете.
    Интернет есть Интернет. Там может быть, что угодно.
  • Сергей М. © (12.10.09 15:31) [24]

    > ABolnykh ©   (12.10.09 14:34) [23]


    Тогда мультакаст, конечно же, отпадает.
    Но тогда и расчитывать на сквозную пропускную способность даже в 10 мбод вряд ли приходится.
    А при таких скоростях производительность ретранслирующего хоста становится уже не критичной.
  • DVM © (12.10.09 15:49) [25]

    > Сергей М. ©   (12.10.09 15:31) [24]


    > А при таких скоростях производительность ретранслирующего
    > хоста становится уже не критичной.

    Да, но на один поток между камерой и ретранслятором может приходиться 100 потоков между ретранслятором и клиентами, если конечно ретранслятор не использует мультикаст.
  • ABolnykh © (12.10.09 16:08) [26]

    > Сергей М. ©   (12.10.09 15:31) [24]

    > Тогда мультакаст, конечно же, отпадает.

    А во вторичную-то сеть можно сделать мультикаст? То есть, принять своим дивайсом из Интернета нужный видеопоток, разложить его на кадры, а потом смультикастить каждый кадр процедурой SendBuffer компонента TIdIpMCastServer на нужный групповой адрес? Во вторичной локальной сети никаких маршрутизаторов быть не должно, по крайней мере, можно заранее оговорить обязательность наличия их отсутствия.
    Это было бы намного проще отслеживания подключения каждого клиента, формирования для него персональной задержки etc.

    Задача, действительно, начинает очень мало напоминать равнобедренный треугольник. Честно сказать, к покадровому дроблению видеопотока я был изначально морально не готов, думал обойтись использованием готовых компонентов.  :-(
  • Сергей М. © (12.10.09 16:17) [27]

    > ABolnykh ©   (12.10.09 16:08) [26]


    > во вторичную-то сеть можно сделать мультикаст?


    Да, конечно.
  • ABolnykh © (19.10.09 14:06) [28]

    > DVM ©   (08.10.09 17:03) [16]
    >
    > Задача не так проста, как кажется. Просто тупо ретранслировать поток не выйдет, поток нужно принять, выделить кадры, затем собрать аналог потока. который транслировать клиенту.
    >
    > Работа ретранслятора грубо говоря выглядит следующим образом.
    >
    > 1) Ретранслятор подключается к камере по HTTP и начинает принимать видеопоток.
    > 2) Выделяет очередной кадр (как разделены кадры в потоке см на сайте аксис HTTP API)
    > 3) После того как кадр выделен, мы его откладываем в некий буфер, затирая предыдущий.
    > 4) Продолжаем принимать входящий поток, обновляя наш буфер.
    > 5) Тут к ретранслятору подключается очередной клиент.
    > 6) Выдаем клиенту заголовок в соответствии с Axis HTTP API
    > 7) Начинаем высылать клиенту кадры, отделяя их друг от друга разделителями. Кадры берем из буфера. Между кадрами делаем паузы чтобы поддерживать нужную частоту кадров, которую например клиент может передать нам в запросе. Кадровый буфер причем должен быть потокобезопасный.
    > 8) Аналогично для второго третьего нн-ого клиентов.
    > 9) Кроме этого следует наверное отключаться от камеры если клиентов нет.
    >
    > В двух словах не расскажешь, т.к. каждый шаг здесь отдельная длинная история.

    [b]DVM[/b], ОГРОМНОЕ СПАСИБО ЗА ТАКОЙ ДЕТАЛЬНО ПРОРАБОТАННЫЙ "БИЗНЕС-ПЛАН"!

    И ещё парочка вопросов.
    Какое количество кадров можно считать оптимальным при приёме потока (чтобы, с одной стороны, не было эффекта "дёрганья" от частого переподключения к камере, а с другой стороны - не слишком раздувать буфер потока), и чем (как) формировать задержку между отправкой кадров?

    В идеале, конечно, было бы задать количество кадров = 0 (unlimited), тогда бы и все вопросы отпали. Как только получил и выделил очередной кадр - сразу смультикастил его во вторичную сеть, и не надо формировать никаких задержек. Но сразу встаёт вопрос переполнения потока при круглосуточном видеонаблюдении, и потом - куда воткнуть процедуру нахождения "--myboundary" в
    try http.get (url, stream);
    finally http.free;
    end;

  • Fr0sT (20.10.09 15:10) [29]
    Очень интересная тема, особенно в предчувствии того, что мне тоже предстоит делать нечто подобное. Возник вопрос: зачем влезать внутрь потока, разве нельзя просто его ретранслировать всем подключившимся клиентам?
  • Сергей М. © (20.10.09 15:28) [30]

    > разве нельзя просто его ретранслировать всем подключившимся
    > клиентам?
    >


    Ретрансляция по TCP может быть неприемлемой
  • Fr0sT (20.10.09 15:36) [31]
    Почему?
  • Сергей М. © (20.10.09 15:42) [32]
    Потому что TCP подразумевает гарантию доставки (квитирование) , что делает его ощутимо медленнее протоколов без квитирования, что, в свою очередь, может быть не приемлемым для доставки поточных данных клиентам с оч узким каналом доступа.
  • DVM © (20.10.09 15:44) [33]

    > ABolnykh ©   (19.10.09 14:06) [28]


    > Какое количество кадров можно считать оптимальным при приёме
    > потока

    Я считаю оптимальной 7 кадров в секунду. Это же все таки наблюдение за ситуацией а не кинофильм. Есть конечно маньяки которые с пеной у рта доказывают что надо 25, но сами не могут отличить 15 от 25 когда им показываешь.


    > а с другой стороны - не слишком раздувать буфер потока

    А у меня лично буфер всего на один кадр. Один буфер в один кадр на одну камеру. Камера обновляет буфер, клиенты получают обновления буфера.


    > и чем (как) формировать задержку между отправкой кадров?

    Формировать то ее можно банальным Sleep() но с расчетом ее мне пришлось повозиться.


    > Как только получил и выделил очередной кадр - сразу смультикастил
    > его во вторичную сеть, и не надо формировать никаких задержек.
    >

    Еще раз повторю, не надо копить кадры. Достаточно всегда иметь один кадр последний, его и шлем клиентам.


    > и потом - куда воткнуть процедуру нахождения "--myboundary"
    > в
    > try http.get (url, stream);

    С пом TIdHTTP можно получить только отдельный кадр (камеры аксис кстати могут отдавать и покадрово а не потоком). Отдельными кадрами тоже выход, правда несколько более грузит ПК и камеру. Для принятия потока лучше брать TidTCPClient (или как он там называется). Я вообще на чистых сокетах делал без обертки (пример разбора потока есть в коде ZoneMinder в файле remote_camera.c ).
  • DVM © (20.10.09 15:49) [34]

    > Fr0sT   (20.10.09 15:10) [29]

    Дело в том что скорость на участке камера - ретранслятор может быть выше чем скорость на участке ретранслятор - клиент и куда девать тогда лишние кадры. Их из потока не выкинешь просто так. А если пытаться в таких условиях отдать все что прислала камера то получится отставание изображения которое все более будет нарастать и занимать память (куда кадры то девать).

    Кроме этого отдельные клиенты могут захотеть принимать с меньшей частотой кадров изображение или другого размера и т.д. тут вариантов масса поэтому лучше ретранслировать собирая поток самому.

    Еще разные модели камер могут транслировать по разному устроенный поток а для клиента лучше чтобы он был единообразным, так лучше если ретранслятор будет адаптирован под разного вида потоки чем клиент.
  • Fr0sT (20.10.09 15:57) [35]
    > [32] Сергей М. ©   (20.10.09 15:42)
    Ок, точку зрения понял

    > [34] DVM ©   (20.10.09 15:49)
    Ага, вот оно что, на ретранслятор уже накладываются дополнительные функции! Тогда действительно, придётся разбирать.
  • DVM © (20.10.09 16:04) [36]
    Кстати, раз уж речь зашла о функциях ретранслятора. Ретранслятор должен уметь работать в обе стороны. Т.е. не только передавать видеопоток от камер клиентам, но и передавать команды клиентов камерам (например PTZ команды ил управление выходами DIO и т.д.)
  • ABolnykh © (21.10.09 11:05) [37]
    Несколько проясню подробности нашего текущего техзадания.

    Пока мы не волшебники, а только учимся, и потому решили сами несколько упростить себе ситуацию. А именно:
    - камеры используем ТОЛЬКО Axis 207, потому возможная чехарда с несовпадением возможностей различных камер отпадает сама собой;
    - все операторы смотрят картинку в одинаковом разрешении;
    - аналогично - никакого волюнтаризма со стороны клиентов в вопросе самостоятельного выбора частоты кадров изображения (что тебе дали - то и смотри; чай, не у себя дома сидишь :-)  );
    - никаких дополнительных функций на ретранслятор, в целях упрощения задачи, не возлагаем;
    - никакого прямого обращения операторов к видеокамерам не допускается. Если диспетчер (человек) захочет зачем-то напрямую обратиться к видеокамере (посмотреть лог, установить часы, прописать юзера etc.), для этих целей предусматриваем прямой доступ к камерам через TIdMappedPortTCP. Через них же будем посылать камере и все дополнительные команды, не связанные с трансляцией видеопотока.

    Клиентскую часть (программу для операторов) тоже пишем самостоятельно, и поскольку тоже не волшебники, все основные приёмно-отображательные функции решили возложить на лицензионно-покупной компонент TVideoGrabber. (Кстати, вопрос ретрансляции потока мы тоже попробовали возложить на него. Как ни странно, но работает (!), правда ОБАЛДЕННО грузит процессор: ретрансляция подключения ОДНОГО клиента (127.0.0.1) к ОДНОЙ видеокамере, подключенной к своей же сетевой карте, занимает примерно 65-70% процессорного времени моего P4 Celeron 2400 MHz. Плюс ко всему - огромная, секунд в 15-20, задержка отображения происходящего.)

    DVM, ещё раз: ОГРОМНОЕ ВАМ СПАСИБО ЗА ЦЕННЫЕ СОВЕТЫ И КОНСУЛЬТАЦИИ!!!

    И очередная порция идиотских вопросов.
    Как я понял, частоту обновления (frames per second) Вы рекомендуете выбирать = 7 - исходя из условия достаточности этого значения для наблюдения за происходящим. Я-то спрашивал, какой размер потока лучше задавать при подключении в команде
    http://<servername>/axis-cgi/mjpg/video.cgi?nbrofframes=_____?
    А если каждый раз запрашивать по одному кадру (nbrofframes=1), то, опять же, непонятно, зачем искать границу кадра? Камера и так прислала один кадр, , начинающейся с "--myboundary, Content-Type" и заканчивающегося какими-то хитрыми двоичными данными, - копируй его в буфер и мультикасть! И потом: где задавать частоту обновления? В команде
    http://<servername>/axis-cgi/mjpg/video.cgi?nbrofframes=1&fps=7   ???

    И опять же: если мы запрашиваем у камеры "в лоб" 7 кадров в секунду, получаем каждый раз по 1 кадру и тут же их мультикастим - зачем нам самим формировать Sleep? Сам TVideoGrabber разве не способен правильно (во времени) отобразить полученное?

    Кстати, DVM, какой населённый пункт нашей необъятной планеты Вы осчастливили, избрав местом своего проживания и творения? Если ответ на этот вопрос каким-то образом нарушает правила этого форума, можно ответить мне в личном сообщении.
  • DVM © (21.10.09 12:57) [38]

    > ABolnykh ©   (21.10.09 11:05) [37]


    > http://<servername>/axis-cgi/mjpg/video.cgi?nbrofframes=_____?
    >
    > А если каждый раз запрашивать по одному кадру (nbrofframes=1),
    >  то, опять же, непонятно, зачем искать границу кадра?

    Когда я все писал, параметра nbrofframes несуществовало и я им не пользуюсь.

    Если брать по одному кадру то проще будет вообще так:

    http://<servername>/axis-cgi/jpg/image.cgi
    Камера пришлет один единственный JPEG кадр. И никакаих --myboundary !!!

    Когда нужен будет еще один, надо обратиться еще раз к камере. Паузу между обращениями можете регулировать сами, тем самым получите желаемый фпс.


    > и заканчивающегося какими-то хитрыми двоичными данными,
    > - копируй его в буфер и мультикасть!

    Это JPEG данные. Начинаются и заканчиваются маркерами FFD8 и FFD9 соответственно.


    > И потом: где задавать частоту обновления? В команде
    > http://<servername>/axis-cgi/mjpg/video.cgi?nbrofframes=1&fps=7
    >   ???

    fps и есть частота обновления. Частоту обновления лучше всего задавать в пути.


    > И опять же: если мы запрашиваем у камеры "в лоб" 7 кадров
    > в секунду, получаем каждый раз по 1 кадру и тут же их мультикастим
    > - зачем нам самим формировать Sleep?

    Потому что возможности клиентов/сети камеры часто расходятся с желаниями/потребностями. В идеальных условиях локальной сети может и можно так как ты описал, но в условиях Интернет вряд ли.
    Начнутся затыки, расхождения, в результате все начнет отставать и т.д.


    > DVM, какой населённый пункт нашей необъятной планеты

    (с) рядом с моим ником нажми.
  • DVM © (21.10.09 13:12) [39]

    > > И потом: где задавать частоту обновления? В команде
    > > http://<servername>/axis-cgi/mjpg/video.cgi?nbrofframes=1&fps=7
    > >   ???
    >
    > fps и есть частота обновления. Частоту обновления лучше
    > всего задавать в пути.

    Только в данном случае (nbrofframes=1) задание fps=7 бессмысленно, т.к. кадр один. Если бы nbrofframes=10, тогда при fps=5 мы получили бы все кадры за 2 секунды, а так бессмсленно. Задание в пути fps имеет смысл только для потоков видео, а не для одиночных кадров. Для одиночных надо фпс задавать на принимающей стороне, т.е. выполнять запросы к камере через нужные промежутки времени.
  • ABolnykh © (22.10.09 11:36) [40]
    DVM, огромное Вам спасибо за полезные советы!
    Специалист ТАКОГО уровня в тяжкую и голодную годину без персонального бутерброда с красной икрой уж точно не останется!

    Но собственную шишку нужно набивать самостоятельно, отрицательный опыт - это тоже опыт, хотя бы для того, чтобы в будущем знать, как не надо делать, и потому желательно все плюсы и минусы увидеть своими глазами.

    Поэтому, прикинув мышь к носу, я для начала решил избрать следующую последовательность действий:
    1. Запрашиваю от камеры 1 кадр видеопотока по HTTP;
    2. Копирую его в буфер.
    3. Мультикастю буфер процедурой SendBuffer MCast-сервера на групповой адрес 224.0.0.1, порт 10500.
    4. Даю задержку на 100 мс.
    5. Перехожу на шаг 1.

    Какой-то поток от меня начинает исходить, я вижу его трафик в окошке DUMeter-а.

    Теперь очередной идиотский вопрос: как мне этот поток принять и отобразить? Если в строке адреса Internet Explorer-а я ввожу
    udp://224.0.0.1:10500
    то неизменно получаю "The page cannot be displayed".
    Если пытаюсь поймать поток ВидеоГраббером, устанавливая его свойство
    IpCameraUrl на тот же групповой адрес и порт, то тоже не получаю никакой картинки.  :-(

    Кстати, Вам приходилось иметь дело с компонентом TVideoGrabber (www.datastead.com)? Можете сказать про него что-нибудь хорошего или плохого?
  • Сергей М. © (22.10.09 11:52) [41]

    > ввожу
    > udp://224.0.0.1:10500
    > получаю "The page cannot be displayed".


    Браузер понятия не имеет что делать с поступающими оттуда данными, ибо udp не является протоколом прикладногго уровня.

    VideoGrabber тоже понятия не имеет, но пытается интерпретировать их в соответствии известными ему прикладными потоковыми протоколами. Соответствия не обнаруживает, потому и не рисует картинку.
  • ABolnykh © (22.10.09 12:44) [42]

    > Сергей М. ©   (22.10.09 11:52) [41]
    >
    > Браузер понятия не имеет что делать с поступающими оттуда данными, ибо udp не является протоколом прикладногго уровня.

    Похоже, что так. :-(

    Так чего делать-то, как жить дальше? Есть какой-нибудь способ отобразить смультикасченные данные?
  • Сергей М. © (22.10.09 12:49) [43]
    Для этого каст-сервер и каст-клиент должны взаимодействовать по единому известному обоим прикладному потоковому протоколу.
    А что у тебя за протокол используется  - ты и сам поди не знаешь)
  • Сергей М. © (22.10.09 12:58) [44]
    Для передачи потокового видео используются ряд сетевых протоколов, из которых важнейшими являются протокол RTSP и протокол IGMP.

    RTSP (Real-Time Streaming Protocol) - это протокол, с возможностью контролируемой передачи видео-потока в интернете. Протокол обеспечивает пересылку информации в виде пакетов между сервером и клиентом. При этом получатель может одновременно воспроизводить первый пакет данных, декодировать второй и получать третий.

    Протокол из этой же группы RTP (Real-time transport protocol) определяет и компенсирует потерянные пакеты, обеспечивает безопасность передачи контента и распознавание информации. Вместе с RTP работает протокол RTCP (Real-Time Control Protocol). Он отвечает за проверку идентичности отправленных и полученных пакетов, идентифицирует отправителя и контролирует загруженность сети.

    Для присоединения к сети или выхода из группы рассылки используется стандартный протокол IGMP (Internet Group Membership Protocol).
  • DVM © (22.10.09 13:09) [45]

    > ABolnykh ©   (22.10.09 11:36) [40]


    > DVM, огромное Вам спасибо за полезные советы!

    Не за что.


    > Кстати, Вам приходилось иметь дело с компонентом TVideoGrabber

    Давным давно, когда он был вроде бесплатный и с исходниками даже чуть-чуть я его изучал, в частности смотрел как там был сделан детектор движения (точнее активности, не знаю остался ли он там), мне не понравилось, ибо было медленно и на этом мое с ним знакомство закончилось.


    > Так чего делать-то, как жить дальше?

    Если хочешь транслировать через UDP, да еще мультикастом, то тебе придется либо изобретать свой протокол, либо обратить свой взор на связку RTSP/RTP/RTCP.

    А чтобы смотреть это дело через браузер, надо для браузера писать либо JavaApplet, либо FlashPlayer, либо QuickTime, либо ActiveX компонент (только для IE) или Silverlight компонент, который будет принимать поток в нужном формате. Сам браузер ясное дело не умеет.

    Из браузеров только FireFox умеет принимать и показывать  MJPEG over HTTP без всяких дополнений.

    Я тебе потому и советую безо всяких мультикастов и UDP для начала обойтись. Это проще в реализации как на сервере так и на клиенте.
  • DVM © (22.10.09 13:21) [46]

    > ABolnykh ©

    Ты научился получать отдельные кадры.
    Теперь научи TIDHTTPServer отдавать эти отдельные кадры по запросу, не надо пока формировать MJPEG поток.
    И все уже будет работоспособно более-менее. И смотреть тогда можно в браузере с пом например такого кода:


    <html>
     <head>
       <title>JavaScript</title>
       <meta http-equiv=Content-Type content="text/html;charset=windows-1251">

       <script language="javascript" type="text/javascript">

         var ch=1;  
         errorimg = 0;

         function LoadImage() {
           uniq = Math.random();
           document.images.webcam1.src = "http://127.0.0.1:80/jpeg.cgi?channel=" + ch + "&uniq=" + uniq;
           document.images.webcam1.onload = DoIt;
         }


         function ErrorImage() {
           errorimg++;
           if (errorimg > 3) {
             document.images.webcam1.onload = "";
             document.images.webcam1.onerror = "";
             document.images.webcam1.src = "http://127.0.0.1:80/images/failure.gif";
           }
    else {
             uniq = Math.random();
           document.images.webcam1.src = "http://127.0.0.1:80/jpeg.cgi?channel=" + ch + "&uniq=" + uniq;
           }

         }
     
         function DoIt()
         {
           errorimg = 0;
           window.setTimeout("LoadImage();", 40);
         }

     
       </script>  

     </head>
     <body onload="DoIt()">
       <center>
       <h2>Просмотр видео (JavaScript)</h2>
       <img src="http://127.0.0.1:80/images/failure.gif" class="webcam1_class" id="webcam1" />
       </center>
     </body>
    </html>




    Получится подобие видео.
  • DVM © (22.10.09 13:23) [47]
    В коде выше /jpeg.cgi это виртуальный путь, по которому вебсервер должен понять что от него хотят картинку, а параметр channel - определяет с какой камеры картинку.
 
Конференция "Сети" » Чем разделить видеопоток? [D7, WinXP]
Есть новые Нет новых   [134438   +31][b:0][p:0.002]