Конференция "Сети" » Видеопоток по idhttp. Зависание потока [D6, WinXP]
 
  • olikke (10.10.12 00:04) [20]

    >  Момент переброски в буфер должен быть обернут в критическую
    > секцию

    Сам TLiveStream обёрнут как в [16]
    function TLiveStream.Write(const aBuffer; aCount: Integer): Longint;
    begin
     Lock;
     try
       if Assigned(fOnWrite) then begin
         Result := fOnWrite(aBuffer, aCount);
       end else begin
         Result := aCount;
       end;
     finally
       UnLock;
     end;
    end;



    Буфер также обёрнут в потоке приёма данных по http
    Buffer[Numb].Lock;
     try
       Buffer[Numb].Size:=0;
       Buffer[Numb].Write(aBuffer,aCount);
       Buffer[Numb].Position:=0;
     finally
       Buffer[Numb].UnLock;
     end;



    И в единственном месте где он читается - в потоке UDP
    Buffer[Numb].Lock;
       try
         Buff:=Buffer[Numb].DataString;
       finally
         Buffer[Numb].UnLock;
       end;

  • olikke (10.10.12 00:16) [21]
    Я не понимаю вот чего:
    Есть у меня два потока  - Tst и UDP. Единственное чем они связаны - общим защищённым буфером и TEvent для пробуждения UDP.
    В такой связке они не могут друг другу мешать жить.
    Почему тогда:
    1) Если UDP просыпается по Event, читает буфер в промежуточную переменную (buff:String), но не делает непосредственно отправки -
    UDPClient.Send(TRIM(Table[Numb].Broadcast),UDPClient.Port,buff);

    , то всё работает сутками при всех недостатках idHTTP для приёма данных этого типа.
    2) А если всё то же, но отправка по UDP есть, то всё медленно умирает.
  • DVM © (10.10.12 00:31) [22]

    > olikke   (10.10.12 00:04) [20]

    Поставь отправку сразу за строкой Buff:=Buffer[Numb].DataString; внутри крит секции. Есть тут у меня одно подозрение.
  • olikke (10.10.12 00:35) [23]
    Ok. Завтра на работе проверю.
    И большое спасибо за ваше внимание.
  • olikke (10.10.12 12:25) [24]
    Поставила отправку UDP внутри критической секции.
    Видеосервер работал 30 минут. За это время отправлено 149491 пакетов по UDP, 73 пакета потеряны. В моём логе это выглядит так:

    { чтение данных TSt.LiveStreamWrite, запись в Buffer, установка tEvent }
    10:32:07:640 LiveStreamwrite 32768    
    {отправка данных UDPClient.Send(TRIM(Table[Numb].Broadcast),UDPClient.Port,buff);
    Если бы было исключение при отправке, то оно было бы здесь}

    10:32:07:656     UDP Execute 32768    
    10:32:07:671 LiveStreamwrite 32768
    10:32:07:671     UDP Execute 32768
    {Ну а вот пример пропуска фрейма. Меня он не смущает, т.к. бывает редко, и
    клиенты-приемники UDP потока умеют с ними справляться}

    10:32:07:671 LiveStreamwrite 32768  
    10:32:07:703 LiveStreamwrite 32768
    10:32:07:703     UDP Execute 32768
    10:32:07:703 LiveStreamwrite 32768
    10:32:07:718     UDP Execute 32768



    Последнее действие в логе - отправка данных по UDP, вот его окончание

    11:03:36:531 LiveStreamwrite 32768
    11:03:36:531     UDP Execute 32768
    11:03:36:562 LiveStreamwrite 32768
    11:03:36:562     UDP Execute 32768
    11:03:36:562 LiveStreamwrite 32768
    11:03:36:562     UDP Execute 32768



    Исключений нет. После этого событие TSt.LiveStreamWrite не наступает никогда.

    какое было подозрение?
  • DVM © (10.10.12 15:08) [25]

    > olikke   (10.10.12 12:25) [24]

    а у тебя логгирование потокобезопасное?
  • olikke (10.10.12 15:34) [26]
    Лог в критических секциях.
  • olikke (10.10.12 16:33) [27]
    Поскольку как я понимаю, с помощью индейского http добиться причины ошибки не удается, сделала следующий шаг:
    1. Взяла заведомо рабочий код, т.е. DVM Thttpinputthread из ветки " передача видео и звука с помощью indy".  
    2. Немного изменила - поставила в Thttpinputthread.readdata прямо отправку всех полученных данных (без выделения кадра) через idudpclient. Ну и вобработках всех исключений вписала лог. ( это только чтоб разобраться в причинах ошибки).
    3. Получила ошибку в thttpinputthread.readdata на функции found = select(...).    Found вернулся =0!!! Это при таймауте в 20 сек.
    4. Далее понятно socketdisconnect (вот теперь я на собственном опыте убедилась чем удобен winsock) и создание его заново.

    Чем был занят мой сокет в течение 20 сек?
  • olikke (10.10.12 16:38) [28]
    Какой минимальный таймаут на функцию select будет корректно поставить? Если я планирую получать поток порядка 20 кадров в сек, я могу поставить хотя бы 0.1 сек?
  • DVM © (11.10.12 11:04) [29]

    > olikke   (10.10.12 16:33) [27]

    Ну я самого начала и говорил, что multipart/x-mixed-replace не поддерживается TIdHTTP и Реми Лебо писал как то про это. Так что либо чистые сокеты, либо TIdTCP - с ним проблем нет тоже.


    > 3. Получила ошибку в thttpinputthread.readdata на функции
    > found = select(...).    Found вернулся =0!!! Это при таймауте
    > в 20 сек.

    Очень странно. И что это регулярно происходит со всем камерами?


    > Какой минимальный таймаут на функцию select будет корректно
    > поставить? Если я планирую получать поток порядка 20 кадров
    > в сек, я могу поставить хотя бы 0.1 сек?

    20 секунд и оставь, он не связан никак с фпс.
  • olikke (11.10.12 13:04) [30]

    > DVM ©   (11.10.12 11:04) [29]



    > 20 секунд и оставь, он не связан никак с фпс.


    Используя чистые сокеты я могу обработать ошибку
    > found = select(...).

    И соответственно переподключиться к моей камере максимально быстро. Если я уверена, что в нормальном режиме работы у меня кадры приходят с частотой 20 фпс, зачем мне ждать 20 сек? Жду 0.1 сек, создаю новый сокет и получаю поток дальше. Картинка на клиентах замораживается на 0,5 сек, что конечно некрасиво, но всё же лучше, чем было до этого.


    > Очень странно. И что это регулярно происходит со всем камерами?

    Ну реально к рабочей машине у меня сейчас подключена только одна Axis P1344. Я решила сначала добиться результата от неё.
    Частота вылетов в функции select напрямую зависит от частоты фрймов в потоке. Т.Е. если я ставлю resolution=1024x768&compression=20&fps=30 (фактически максимум для этой камеры), то вылетаю часто (~раза в минуту). Ну это я конечно для проверки такие параметры выставила.
    Сейчас установила B>resolution=1024x768&compression=40&fps=25, получаю ошибку раз в пол-часа (примерно). Т.е. пару раз в час моя картинка подвисает на 0,5 сек.
  • DVM © (11.10.12 13:48) [31]

    > olikke   (11.10.12 13:04) [30]
    >


    > Жду 0.1 сек, создаю новый сокет и получаю поток дальше.
    > Картинка на клиентах замораживается на 0,5 сек, что конечно
    > некрасиво, но всё же лучше, чем было до этого.

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

    Ты борешься с симптомами, а надо искать причину по которой данные перестают поступать от камеры столь длительне время. Ты говоришь, что проблема возникает когда ты включаешь ретрансляцию по UDP. Может эти широковещательные пакеты забивают всю сеть? Может есть какой то антифирус или файерволл? Их надо обязательно отключать при работе с камерами или добавлять программу в исключения.
  • olikke (11.10.12 16:39) [32]
    Антивирус и брандмауэр отключены.

    Настройки моей сети
    IP камера: ip 192.168.2.4 mask 255.255.255.0 100Мбит
    Видеосервер: ip 192.168.2.1 mask 255.255.255.128 1Гбит
    Клиент: ip 192.168.2.7 mask 255.255.255.128 1Гбит
    всё через коммутатор D-Link DGS-1060 1Гбит.

    Ретранслирую UDP на адрес 192.168.2.127 - данные от камеры перестают поступать.
    Ретранслирую UDP прямо клиенту 192.168.2.7 - всё работает.

    Мне очень стыдно. Но я не понимаю в чём дело....

    Самое главное, что я не хочу передавать udp для каждого клиента отдельно. Почему же не работает Broadcast?
  • DVM © (11.10.12 18:00) [33]

    > olikke   (11.10.12 16:39) [32]


    > Ретранслирую UDP на адрес 192.168.2.127 - данные от камеры
    > перестают поступать.

    А в тот момент когда данные с камеры перестают поступать она вообще доступна, через браузер например с нее видеопоток идет? Она случайно не перезагружается там?

    А порт UDP не пробовала менять? Может выбранный порт камера слушает и как то неадекватно реагирует на кучу пакетов. Ее бы попробовать отрезать от широковещательного UDP трафика твоего и посмотреть как она себя поведет.
  • olikke (12.10.12 11:55) [34]
    Порты я пробовала менять, не помогает.

    Тестировала сегодня свою систему и вот что интересного у меня получилось:

    Включила одновременно браузер (IE6) и свою программу с ретрансляцией UDP broadcast. Как обычнов моей программе начала появляться ошибка на функции select. При этом с браузером было вот что: видеопоток на нем один раз оборвался, причём вылезла ошибка что-то типа "не может быть произведён reconnect" (помогло обновление страницы). И ещё сниффером заметила, что порт подключения браузера к камере несколько раз изменился. Вывод: IP камера действительно обрывала поток (ошибки у меня и браузера возникали асинхронно). Браузер в этом случае предпринимал попытку переподключиться к ней самостоятельно, и только один раз для этого потребовалось участие пользователя (пока я это писала браузер уже два раза автоматически переподключился).
    Т.е. источник проблемы ясен.
    Теперь ищем причину.
    Как распространяется широковещательное сообщение по локальной сети?
    1:Широковещательный адрес распознаётся по IP-адресу, в котором все биты хоста установлены в 1.
    2:При широковещательной передаче все сетевые адаптеры, находящиеся в подсети соответствующей широковещательному запросу должны проверить нужен ли им входящий пакет. Для этого каждый широковещательный пакет должен быть принят и рассмотрен на транспортном уровне (UDP), где прописан порт-получатель. Только после этого пакет может быть принят или отторгнут.
    Здесь нужно обязательно добавить, что IP камеры 100МБитные, в отличие от остальных устройств в сети. А поток я сних беру немаленький + ретрансляция по UDP, итого получаю порядка 9-11% загрузки ГБитной сети.
    Именно поэтому я установила разные подсети для группы клиентов + видеосервер и для группы камер. Т.е. для сетевого подключения с маской 255.255.255.0 (для IP камер) пакет с адресом 192.168.2.127 не может быть широковещательным. В то время как для видеосервера и его клиентов маска выбрана 255.255.255.128. Таким образом я была твердо убеждена что мои широковещательные запросы не будут забивать сетевые подключения камер.
    Но сегодня мой мир перевернулся.
    Широковещательный запрос с адресом 192.168.2.127 проходит на сетевое подключение моей камеры (ip 192.168.2.4 mask 255.255.255.0)!!!!!
    Вывод:
    Как правильно предложил DVM, надо отрезать группу камер от широковещательного трафика. Для этого я хочу попробовать 2 варианта:
    1. Маршрутизатор.
    2.Ретрансляция не широковещательных запросов, а групповых.
  • DVM © (12.10.12 16:22) [35]

    > olikke   (12.10.12 11:55) [34]


    > широковещательный пакет должен быть принят и рассмотрен
    > на транспортном уровне (UDP), где прописан порт-получатель.
    >  Только после этого пакет может быть принят или отторгнут.
    >
    > Здесь нужно обязательно добавить, что IP камеры 100МБитные,
    >  в отличие от остальных устройств в сети. А поток я сних
    > беру немаленький + ретрансляция по UDP, итого получаю порядка
    > 9-11% загрузки ГБитной сети.

    Вот я и говорю, завалила ты камеры пакетами. Найди такую же камеру в интернет и попробуй с ней. Можно еще сделать так, на сайте аксиса есть эмулятор камер, его можно скачать, дать ему записи с камер и заменить камеры им, и запустить его на мощном ПК. Если надо дам ссылку на него.
  • olikke (12.10.12 22:32) [36]
    DVM, эмулятор камер был бы мне очень полезен. Если не затруднит дайте ссылку.
  • DVM © (15.10.12 23:06) [37]

    > olikke   (12.10.12 22:32) [36]


    > DVM, эмулятор камер был бы мне очень полезен

    как оказалось, он на их сайте находится в закрытом разделе для разработчиков
 
Конференция "Сети" » Видеопоток по idhttp. Зависание потока [D6, WinXP]
Есть новые Нет новых   [134436   +21][b:0][p:0.002]