LINUX.ORG.RU

Опять хитрая очередь для 2х потоков на C++

 ,


0

1

Приветствую.

Сразу к сцути - пишет значит моя приблуда с 30 кадровой камеры мжпег кадры на SD карту на одноплатнике по кругу, для снижения нагрузки и получения некой равномерности делается это таким образом - меряю время в начале цикла записи, сравниваю после и оставшееся время либо сплю до частоты 10 фпс, либо пишу сразу следующий.

Все бы ничего, но иногда требуется как посмотреть текущее видео с камеры, которое перекодируется в х264 и отдается в ртсп, так и глянуть архив, которое хоть и не нагружает цпу у армки, но читает большие объемы с сд карты и шлет их активно в сеть по удп.

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

Но вот вопрос - как бы сделать так, чтобы на время записи-удаления из очереди И добавления в очередь - она НЕ БЛОКИРОВАЛАСЬ ??? Иба если блочить - очевидно опять будет неравномерность.

★★★

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

Так вот, блокировка будет только на время чтения/записи в очередь 4/8 байт. Эта операция занимает наносекунды для любой вменяемой реализации очереди на любом вменяемом процессоре. Один кадр у тебя приходит раз в 33 миллисекунд.

Где ты нашёл неравномерность?

KivApple ★★★★★
()
Последнее исправление: KivApple (всего исправлений: 2)

Но вот вопрос - как бы сделать так, чтобы на время записи-удаления из очереди И добавления в очередь - она НЕ БЛОКИРОВАЛАСЬ ??? Иба если блочить - очевидно опять будет неравномерность.

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

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

у тебя так работает?

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)

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

Но вот вопрос - как бы сделать так, чтобы на время записи-удаления из очереди И добавления в очередь - она НЕ БЛОКИРОВАЛАСЬ ??? Иба если блочить - очевидно опять будет неравномерность.

Я тебе схему как это делать уже описывал, но ты за своими бреднями про равномерную запись на флешку это, видимо, пропустил.

Повторюсь - очередь блокируется не на всё время записи, а только чтобы поток который пишет на флешку забрал себе из неё кадры. Это одно копирование указателя поэтому очень быстро и записи новых кадров мешать не будет.

slovazap ★★★★★
()
Ответ на: комментарий от wolverin

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

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от alysnix

у тебя так работает?

нет, для очереди в которую читает поток с камеры и 2 потока забирают (записи и трансляции онлайн видео) всегда только последние кадры я выделил массив указателей через ффмпег (какой длины он выделяет через av_packet_alloc не знаю), а очередь просто индексы этого массива переставляет, что позволяет не делать копирование ни указателей, ни тем более памяти.

wolverin ★★★
() автор топика
Последнее исправление: wolverin (всего исправлений: 1)

Может сделать наоборот? Отдавать сразу по ртсп всегда во вне и попутно в отдельном не блокируемым ничем треде по тому же ртсп локально принимать и записывать в малинке(или чего там у тебя) на флешку.

LINUX-ORG-RU ★★★★★
()

Так ты в udp шли без блокировки и будет тебе счастие. Псевдокод:

int fd = pselect(1ms, [socket_ready_to_write, file_ready_to_read]);
if (fd == file) {
    read(fd, frame);
} else if (fd == socket) {
    send(fd, frame);
}
faq2
()
Ответ на: комментарий от LINUX-ORG-RU

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

есть другая идея - что если выделить один большой буфер, а на атомиках или в очереди хранить только смещение СКОПИРОВАННЫХ туда кадров, тогда буфер будет неблокируемым и позволит после просадок с максимально возможной скоростью записывать большими кусками.

wolverin ★★★
() автор топика
Последнее исправление: wolverin (всего исправлений: 3)

ты делаешь какую-то кошмарную беспощадную вещь, к которой остается только один вопрос: ЗАЧЕМ?

У тебя уже есть h264 видео, нахрена ты ещё mjpeg таскаешь, который лишен какого либо инженерного смысла уже 15 лет как?

max_lapshin ★★★★★
()
Ответ на: комментарий от max_lapshin

х264 есть только для онлайн трансляции по запросу, он не пишется в архив, потому что это тяжело одноплатнику делать

wolverin ★★★
() автор топика
Последнее исправление: wolverin (всего исправлений: 1)

Пишешь циклично в буффер. Новый кад пишешь если только есть место дял него. Для записи на диск - получаешь указатель на первый кадр в буфере и используя этот указатель записываешь на диск. Потом освобождаешь эту память (сдвигаешь указатель головы) - вот на это время надо блокировать. Так у тебя и фрагментации не будет и память нормально будет использоваться. Если речь идет не о микроконтроллере, то можно чделать еще циклический буффер в котором можно будет получить указатель на непрерывный блок памяти даже если он в самом конце области памяти.

vromanov ★★★
()
Ответ на: комментарий от wolverin

Если ты гоняешь x264 на одноплатнике, то понятно что ему будет дурно.

Там надо использовать код, который жмет H264 аппаратно, без использования x264.

А уж со сжатым потоком почти любой одноплатник справится: потоков 10 на старой малинке можно записать без особых проблем. Но это только H264 потоков, потому что mjpeg — это страшный удар по любому компьютеру: более чем 10-кратный рост трафика по сравнению с H264

max_lapshin ★★★★★
()
Ответ на: комментарий от max_lapshin

Вот купил заказчик h264 камер, а они только 30фпс могут и на 2мп это почти 5 мбит/с что не влазит в 3мбит/с канал, а я пересжимая из мжпег получаю хоть и не 30, а 10 фпс, но это влазит в 1мбит/с канал и это смотрибельно - вот вам и один из ответов на зачем.

wolverin ★★★
() автор топика
Последнее исправление: wolverin (всего исправлений: 1)

как бы сделать так, чтобы на время записи-удаления из очереди И добавления в очередь - она НЕ БЛОКИРОВАЛАСЬ ???

Просто скочай с 1024core ихний «локфри» велосипед. Потом выяснишь что потоки успешно отдыхают на каком-нибудь независящем от твоего кода мьютексе и... что велосипед тебе не нужен... но потом.

slackwarrior ★★★★★
()
Ответ на: комментарий от wolverin

ты продолжаешь делать какой-то ужас. Вместо нормального решения инженерной задачи, рассказываешь какие-то прохладные истории о том, что у тебя h264 не влезает, а mjpeg влезает.

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

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

max_lapshin ★★★★★
()
Ответ на: комментарий от max_lapshin

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

wolverin ★★★
() автор топика
Ответ на: комментарий от max_lapshin

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

wolverin ★★★
() автор топика
Ответ на: комментарий от wolverin

дружище, твои бы старания на что-то побольше пустить.

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

max_lapshin ★★★★★
()
Ответ на: комментарий от ox55ff

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

wolverin ★★★
() автор топика
Последнее исправление: wolverin (всего исправлений: 1)
Ответ на: комментарий от ox55ff

тебе лучше купить ихний peeklio и закинуть в прошивку камеры

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

Причем нормальное железо стоит адекватных денег.

Малинка, конечно же, к нормальному железу никакого отношения не имеет. Одноплатники в своей массе — это демонстрационные девборды, непригодные для продакшн размещения на улице, причем они (что ожидаемо для девборд) стоят дороже.

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

max_lapshin ★★★★★
()
Ответ на: комментарий от max_lapshin

вообще мест для установки 10К ) а 500-600 уже стоит

а потом ваши покупатели узнаю, что можно дешевле )))

и главное без абонентской платы за сервера

wolverin ★★★
() автор топика
Последнее исправление: wolverin (всего исправлений: 3)