Pull to refresh

Comments 141

Очень круто, но ничего не понятно. А какая задача-то решалась в итоге? Просмотр видео с IP камер? Почему не подходили типовые варианты? Какие были начальные условия и ограничения? Какие нюансы передачи информации с глубины? Что именно делает ваш код? Зачем вообще эти простыни кода в теле статьи? Циклический буфер, метки высокой точности, запись с экрана, ок, ладно.
*картинка про троллейбус из хлеба жпг*
Все что вы спрашиваете перечислено в начале статьи.

Задача одной фразой: смотреть и записывать видео-поток с IP-камер робота.

Типовых вариантов нет. Если конечно вы не имеете ввиду стандартный софт от производителя камеры или доступ к камере через web-интерфейс или различные решения которые в основной массе рассчитаны под задачи видеонаблюдения.

Начальные условия одной фразой: есть IP-камеры передающие RTSP-поток.

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

Нюансы передачи информации с глубины на данную разработку не влияют. Разве что упомянутое в начале ограничение на пропускную способность кабеля не позволяющее передавать сразу 9 потоков в качестве Full HD.

Код делает то что написано в теле статьи и комментариях и причина его наличия в теле статьи проста — дать информацию тем людям которые решают схожую задачу и минимизировать стук головой в кирпичную стену. Возможно вам просто нет надобности рассматривать код так как это не является вашей предметной областью. Может просто статья нашла в вашем лице терпеливого, но не целевого читателя которому я все равно благодарен.
Дело в том, что несколько лет назад на старой работе передо мной стояли схожие задачи — писать, транскодить и ретранслировать потоки с IP камер. Возможно я сейчас не упомню всех нюансов, но задача это решалась слегка перекомпиленным ffmpeg и стрим-сервером fms, wowza. Вот я и не понимаю, без вникания в глубины глубин кода, что именно вы сделали такого, чего не было сделано до вас.
И про пропускную способность кабеля не очень понятно, кабель — 100мбит ethernet?
Думаю вы и так знаете что невозможно сделать такого, чего не было сделано до нас. И я конечно же догадываюсь что все что сделано можно сделать даже без перекомпиляции просто склеив тучу софта скотчем и бинтами. Однако у всякого готового решения есть цена. Вы должны знать что склеить, как склеить, как сделать так что бы не расклеилось и куда бежать когда нужно будет из фундамента этой конструкции вынуть кирпич. Плюс ко всему — как же самореализация)?
аа, всё, я понял, yet another обвязка вокруг ffmpeg. с третьего раза дошло. про кабель только расскажите, допустим глубина 11 км, что за кабель будет использоваться?
На таких глубинах этот аппарат пока не работал. Кабель по-честному лично я в руках не держал — для того что бы писать софт этого не требуется. А вообще кабель представляет из себя многооболочную антипетлевую конструкцию, усиленную кевларом, пропитанным водоостанавливающим составом, имеет нулевую плавучесть, выдерживает поперечное и продольное давление до 60 атм (даже в случае повреждения внешней оболочки). Усилие на разрыв кабеля до 350 кг.
При этом, судя по вашим комментариям в тексте, для передачи используется не оптика, а медь. Не знаете, почему так?
Оптика нужна если длина более 1 км, а так — с ней серьезные проблемы в походных условиях, при ремонте кабеля, разъем сложнее и сам кабель на порядок дороже.
Нет, это не ethernet кабель. Транспорт данных идет по тем же проводам по которым подается питание к агрегатам робота (450 В) через модемы работающие на частотах 10-50 МГц (сразу на нескольких частотах одновременно). Пропускная способность кабеля зависит от его длины. На 100 м можно достичь 50 Мб/с, а на 1 км уже 0,5 Мб/с.
Понимаю, что тут вопрос не совсем к вам, но но интересно было узнать, что это за модемы. Ибо стандартные модемы VDLS2 на 8a-Bandplan, ограниченные диапазоном в 8,5 Мгц, способны протащить порядка 10 Мбит/с в нисходящем потоке при длине линии в 2,5 км на кабеле ТПП 0,5 (от диапазона остаются рабочими на данной длине только 3 Мгц). Да, здесь иные напряжения в кабеле и иные уровни помех, но странно, что выбранные под это дело модемы обеспечивают столь малую дальность передачи. через 1 Мбит/с три FullHD картинки не протащить (да ещё и учётом ретрансмитов).
К сожалению про модемы большего чем рассказал не знаю
Хабр торт!

P.S. Но ссылки на гитхаб выглядели бы лучше, конечно, чем столько кода в тексте.
К сожалению пока не открыл для себя этот несомненно полезный ресурс.
Так а на какую глубину погружался аппарат?
На какую глубину рассчитан — в начале статьи указано, что максимальные глубины мирового океана, но даже 1 км — уже кабель не рассчитан…

Почему часто упоминается нагрузка на процессор? Там же водяное охлаждение, процессор можно легко поставить помощнее, а если 6е поколение интела, то как раз с декодированием видео он справляется на ура, а по питанию раза в два экономнее
Во время описанных в статье испытаний аппарат погружался в р. Волга — там глубину сложно назвать большой, можно попробовать отыскать конкретное значение глубины среди индикаторов интерфейса управления на первом видео, думаю до 5 м. Вообще данная модель рассчитана на глубину до 600 м (при некоторой доработке — до 2 км). Фраза «максимальные глубины мирового океана» в статье не использовалась.

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

«Основной целью при проектировании и создании Moby Dick было создание небольшого робота, способного погружаться на максимальные глубины мирового океана (в составе подъемно-спускового механизма), выдавать видео высокого разрешения (Full HD), брать пробы, образцы, проводить спасательные работы.»
Да, пропустил фразу, вы правы. Тут вся тонкость в многогранности русского языка. Глядите как нужно читать это предложение. Есть проект. Конечной целью этого проекта как и любого другого является абсолют — то есть некая сущность являющаяся конечным благом для всей Вселенной. Однако движение к цели процесс сложный и длительный. Moby Dick создали как первый этап движения к этой цели. Он может погружаться на глубины 600-2000 м (эти глубины нельзя назвать максимальными, но и малыми назвать я бы не решился). Однако в перспективе, развивая направление и аккумулируя опыт, лаборатория планирует получить аппарат с глубиной погружения до 12 км.
Ну то есть всё как обычно — заявлено одно, а при демонстрации результата включаются «тонкости многогранности русского языка»
Совершенно согласен с вами исправил двусмысленность в статье добавив "(в перспективе)"
Вы точно уверены, что Ваш «подводный аппарат» способен погрузиться хотя бы на 600 метров?
Практика показывает, что даже подводные аппараты с более «продуманным» конструктивом — не способны на подобное.
Так, например, наш аппарат TurtleROV мы позиционируем только до глубин в 400 м.
Кроме того, отдельный интересный вопрос — это передача питания на аппарат.
Вы представляете себе сечение проводов питания, чтобы «догнать» напряжение до глубины в 2 км.?
А вообще — мечтать не вредно :)
1 Добрый день коллеги
2 Это не мой аппарат, читайте внимательнее статью.
3 По техническим вопросам и обмену опытом именно в части аппарата вы можете связаться с лабораторией — ссылка есть в статье.
4 У меня хорошее воображение, я рад что есть люди которые как и я думают на подобные интересные темы.
5 Согласен, мечтать погрузиться до глубин 400 м на вашем аппарате тоже смело ;)
ссылка не вставилась: https://www.youtube.com/watch?v=b_2BZ2qjg2w
«Безусловно в идеальном мире где человек может позволить себе для любого чиха устанавливать дата центр с 1024 майнфреймами охлаждаемыми жидким гелием это знание никак не пригодится. „

От чего питается робот? По кабелю, или от аккумуляторов?
Сейчас мощность процессора обычно рассчитывается уже не по стоимости железки, а по стоимости энергозатрат, а в случае автономного робота с аккумуляторами, энергоэкономный процессор это не майнфреймы с жидким гелием, а как раз выгода со всех сторон — видео обрабатывает быстрее, энергию экономит больше. Чтоже касается охлаждения — вокруг вода, вообще ничего не нужно, так что проблема перегрева не должна появляться.
Робот питается по кабелю. Процессор который упоминается в статье стоит в компьютере с которого управляется робот. То есть стоит наверху, а не в роботе. У робота, конечно, есть своя система для управления его агрегатами расположенная на борту, но это не моя область и я про эту систему практически ничего не знаю. Комментарий про стоимость не понял, наверное пока я писал статью отменили деньги. Охлаждать процессоры морской водой с частицами… на глубине… нет, о таком не слышал.
А если принимать информацию от камер на глубине, там обрабатывать и по кабелю передавать уже пережатый поток — пропускная способность могла бы увеличиться, и можно было бы использовать несколько камер в FULL HD режиме?

Ваш комментарий про морскую воду с частицами не понял. Главное во всем этом — отвод тепла. В воде прохладно, далеко отводить не нужно…
Почему-то логика подсказывает мне что пережать несколько Full HD в сигнал который который пройдёт там где такой поток информации не проходит нельзя. Или это будет уже не Full HD. Кодеки на IP-камерах достаточно совершенные — улучшить сжатие без потерь выряд ли удастся, а технических проблем добавится я думаю прилично.

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

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

Честно говоря по настойчивости с которой предлагалось охлаждение морской водой подумал именно о дикости с отмыванием процессора)
Извините, я не настойчивый, просто в меру любопытный ;)

Что же касается камер — x264 требует в общем-то неслабого процессора, не уверен, что в камерах стоит мощный. А сжатие отличается в разы… Ну и вы же сами пишете, что у вас Full HD одна камера, остальные 720 — я так понял это именно из-за нехватки канала передачи
Камеры отдают 264 поток. Ограничение — это для максимальной комплектации (когда 9 камер).
Поверьте, в IP-камерах стоят специализированные SoC, которые именно для этого и предназначены. Зачастую те-же SoC, что стоят в авторегистраторах и экшн-камерах, зачастую и более производительные. Да, можно взять камеры Prosilica от Alliedvision (https://www.alliedvision.com/en/products/cameras.html) или им подобные и подобрать более удачные параметры кодирования, придумать, как разместить и как питать ещё и отдельно стоящий видеосервер на этом агрегате. Но сколько будет стоить такая система? Время разработки тут не считаем, поскольку у этих камер отличное SDK и документация и получить с них изображение дело пары часов.
Камеры по RTSP уже отдают сжатый поток. При этом битрейт выбирается пользователем. Дальнейшие попытки его сжать приведут лишь к ухудшению качества/увеличению битрейта. Основная задача тут подобрать камеры, сжимающие максимально эффективно поток в рилтайм, обладающие нормальным буфером с нормальной реализацией RTSP-стриминга, ну и имеющие нормальную матрицу само собой.
Относительно кода, мне бы хотелось порекомендовать автору несколько вещей:
— Взять нормальный компилятор с поддержкой более новых стандартов. Например, бесплатную MSVS 2015, если так хочется именно Windows и продукты от MS.
Это позволит не городить велосипеды для работы со временем и потоками. Велосипеды тут плохи тем, что они врядли лучше кода в STL, а стороннему человеку вовсе не будут нужны.
— Почитать про RAII
Сюда же отнесу использование std::string/std::vector вместо ручного strdup + free.
— Именовать переменные согласно их назначения, профит очевиден.
AVFrame *frame; //кадр YUV420P
AVFrame *_frame; //кадр RGB32

Насколько проще было бы именовать
AVFrame *yuv_frame;
AVFrame *rgb_frame;

И комментарий не нужен, и код читать намного проще.
— Выложить код на github, чтобы не постить такие простыни кода.

Да, еще вопрос — зачем нужен динамический массив в классе t_buf_t?
Ведь там используется всегда только 2 последних сохраненных значения времени?
1 То что вам не нравятся WinAPI вызовы производимые для поддержки отметок времени и задержек высокой точности или создающие поток не означает что их нет в конкретной реализации тех самых классов ссылки на которые вы дали.
2 Вашу ссылку на RAII я не понял — вам не нравится что код DLL выполнен в стиле функциона́льного программи́рования? Ну как бы это DLL вообще то. Туда конечно можно и класс впихнуть, но мне это не нужно.
3 Я знаю что такое std::string/std::vector — здесь они не требуются
4 Относительно именования переменных полностью с вами согласен в данном месте вольность допущена исключительно по историческим причинам. Комментарии в любом случае были добавлены только в статью — в коде, пардон, их нет вообще :)
5 Если вы работаете с github это не означает что другие тоже работают с github. Я не вижу криминала в выкладывании тут кода если он есть проинформируйте меня что было сделано неверно в том что я выложил тут наиболее интересные на мой взгляд участки кода? Я же не впихнул сюда просто склеенный из всех исходников текстовый ужас.
6 Динамический массив нужен потому что размер заранее неизвестен. Используются два последних значения, но они каждый раз новые так как пополнение массива новым значением вытесняет самое старое значение.
Отрицание это первая стадия...
Я соглашусь с товарищем dreamer-dead — пока читал статью возникали примерно те же впечатления, но просто они не оформились в комментарий. Зачем в наше время так много платформозависимого WinAPI, ведь C++ эволюционировал и в стандартной библиотеке уже есть отличные инструменты многопоточности и синхронизации, например?
По поводу RAII — у Вас повсюду «честный» С-шный код с кучей очисток в конце функций. Справедливое замечание, и тип выходного файла (DLL) тут не при чем.
Я уже нахожусь на стадии Принятие…
Не нравится мне «современный» стандарт языка. Не признаю я его. Причины? Религиозного характера. Только вам их открою — нет нормального инструмента разработки под этот стандарт. Нормального в моем сугубо личном понимании. А ковыряться в том что считаешь ненормальным нормально ли для нормального человека)?

От кучи очисток в конце функций куда вы предлагаете мне деться если я оборачиваю «честный» C-шный код FFMPEG? Или вы его тоже считаете адовым?
нет нормального инструмента разработки под этот стандарт.

И чем же более новые и бесплатные (причём без ограничения на плагины) версии Visual Studio хуже, чем "старая добрая Microsoft Visual C++ 2008 Express Edition"?


От кучи очисток в конце функций куда вы предлагаете мне деться если я оборачиваю «честный» C-шный код FFMPEG?

Дык, вам предлагают использовать RAII.

Обсуждение достоинств и недостатков того или иного инструмента уведет нас в совсем ненужные дебри. Для меня достаточно того что «новые и бесплатные версии» жрут мое время — я должен выкачать все эти гигабайты, войти в учетную запись и… получить продукт который Hello world собирает аномальное количество времени и то после того как ему перебрали половину двигателя. Я уверен что это не ваш случай и на вашем оборудовании и с вашим опытом все работает хорошо.

Относительно RAII покажите мастер-класс: выделите проблемный участок и приведите ваше видение его реализации. Может мы просто не понимаем друг друга.
--Дело в том, что если рисовать непосредственно на кадре

я делал похожую задачу для одной компании что пишет для голивуда софт типа диспечерского места.

Они поток дробили на 5 секундные ролики, дальше скрипт вызывал ffmeg и он же вставлял заданную статичную картинку с номером камера, дальше последовательность подхватывается видеосервисом и поток выдается для просмотра в банальном броузере.

Никакого программирования не нужно для вашей задачи.
Как было уже отвечено выше «я конечно же догадываюсь что все что сделано можно сделать… просто склеив тучу софта скотчем и бинтами. Однако у всякого готового решения есть цена. Вы должны знать что склеить, как склеить, как сделать так что бы не расклеилось и куда бежать когда нужно будет из фундамента этой конструкции вынуть кирпич» Я знаю свой код и могу сделать с ним все что нужно если это вообще возможно. А вот сколько пробежит на этой дистанции человек жонглирующий оркестром из внешнего софта я сказать не берусь. FFMPEG как и многие другие решения которые можно объединить для решения этой задачи очень эффективные и мощные. Но во многих случаях для элементарного действия без кода вам придется забивать дрелью шуруп в гранитную стену.
Для вашей задачи вообще оверлея в браузере было бы достаточно. Цитату, выдранную из контекста, вы сами до конца не поняли. Если начинать рисовать сразу на экране, а не использовать двойной (тройной etc) буфер, картинка может успеть отрисоваться монитором когда на ней будет сформирована лишь часть изображения. В итого получим мерцающее отображение отдельных элементов либо всего изображения целиком, если мы ещё и заливку чёрным фона делаем на первой стадии.
Я не понял о какой цитате идёт речь + у меня куда-то подевался ваш комментарий ожидающий модерации — на почте письмо есть, а тут я его найти не могу (там про модемы спрашивается и про рассинхронизацию кадров и замену WM_PAINT на BitBlt) поэтому отвечу здесь: про модемы я к сожалению больше того что рассказал не знаю, камеры аппаратно не синхронизируются, но заметного рассогласования в кадрах это не даёт, задержка между фактическим действием и картинкой очень мала, заменять сообщение на прямое рисование не стал так как это насилие над системой — я буду затирать любое окно покрывающее область рисования в том числе и элементы интерфейса. Относительно последнего вашего комментария — я и не рисую напрямую по целому ряду причин: сглаживание неравномерности поступления кадров, предотвращение мерцания и т. п. — все пробовал детально расписать в статье поэтому не понял о чем вы сейчас меня спрашиваете.

О том чего достаточно и недостаточно для моей задачи я с удовольствием поговорю с вами в любое удобное для нас обоих время)
Моё вышестоящее сообщение было адресовано BalinTomsk. Для вас в нём содержится разве что объяснение причин мерцания, с которым вы столкнулись. Моё сообщение, которое вы потеряли, вы случайно отклонили при модерации, поэтому я первую часть вопроса по модемам продублировал выше. «я буду затирать любое окно покрывающее область рисования в том числе и элементы интерфейса» — вот тут я сильно сомневаюсь. Насколько помню, если вы получаете HDC от HANDLE конкретного элемента формы, то вы просто рисуете на нём. Все вышестоящие элементы должны остаться неповреждёнными, об этом думает винда, это её забота. Вы сможете из закрасить только в случае, если получите DeviceСontext от HANDLE, равного нулю, и будете на нём рисовать. Обработка WM_PAINT полезна в случае, если вам нужно перерисовать лишь часть вашего элемента, поскольку так можно получить конкретный регион, требующий перерисовки (который был перекрыт вышестоящим окном). В случае рисования в реальном времени от неё лучше уходить, кмк. Т.е. в repaint() вам вместо посыла форме сообщения на отрисовку можно было было бы сразу делать рендер, которые вы делаете в WM_PAINT. Но, задача решена, если все всех устраивает — то и замечательно.
Почему было мерцание я так и не понял — все рисовалось в памяти и только потом копировалось на экран. Об остальном подумаю, интересный ход мыслей.
В любом случае с рисованием средствами GDI через равные интервалы вам не уйти от возможных разрывов изображения на две части на экране, связанных с отсутствием контроля вертикальной синхронизации. На записи этого не видно поскольку вы просто записываете то, что отрендерили, но при наблюдении в реальном времени наверняка этот эффект прослеживается. По хорошему, вам нужно максимально уйти от временных меток и за опорный сигнал брать вертикальную синхронизацию. Как это лучше сделать сейчас — не подскажу, первый и последний раз делал это давным давно силами DirectDraw, а его успешно закопали. Попробуйте поэкспериментировать с LAV Filters, возможно добьётесь ещё и аппаратного декодирования видео.
Почему то у меня отложилось в памяти что проблемы синхронизации исчезли вместе с мониторами отличными от LCD… Или такое понятие и сама проблема все еще имеется?
Имеется, как ни странно. Если у вас его не наблюдается — ну и отлично. Если наблюдается — знаете, куда копать. Но, привязавшись именно к частоте обновления экрана, вы смоли бы получить наиболее плавный вывод картинки.
Отличный путь, попробую исследовать это направление!
Почему выбрали именно ffmpeg, который уже давно libav, а не gstreamer, например?
Я бы задал другой вопрос: зачем вообще выбрали ffmpeg, если можно было просто DirectShow заиспользовать, и не морочиться с кодеками вообще. Тут приходит в голову только сложность с пунктом «комфортный просмотр видео при кратковременном падении скорости передачи данных», но, вероятно, есть способы его решения.
Или вообще LAV Filters и получить ещё и аппаратный декодинг из коробки. Мои тесты на древних ATI-картах показывают, что три потока FullHD они на DXVA в параллели тянут без проблем. Четвёртый уже придётся декодировать программно.
Могу задать встречный вопрос — а почему не ещё чего-нибудь? Это статья о том как заточить карандаш точилкой, а не о том как залить спирт внутрь фломастера — FFMPEG решал мою задачу и этого мне было достаточно. Конечно есть и другие способы.
Переформулирую: вы выбрали libav потому что она решала ваши задачи и другие варианты вы не рассматривали за ненадобностью или потому что другие не подошли по каким-то причинам?
Потому что решала мои задачи и другие варианты если честно не рассматривал. Уже после реализации стал прикидывать варианты аппаратного кодирования, но пока еще не определился чем можно было бы это сделать.
из личного опыта — видеокарты nvidia: встроенное видеоядро тянет до 45 мегабит видео(а в линейке GTX9xx похоже уже больше, судя по загрузке видеоядра), причем это могут быть несколько потоков(проверяли 10 потоков — успешно)
А чем их туда подать если имеете такой опыт не подскажите?
В примерах CUDA SDK:
http://docs.nvidia.com/cuda/cuda-samples/index.html#cuda-video-decoder-gl-api
Там же описание:
http://docs.nvidia.com/cuda/samples/3_Imaging/cudaDecodeGL/doc/nvcuvid.pdf

Есть еще NVENC, но в «бытовых картах» там ограничили количество параллельных потоков.
Спасибо, посмотрю!
ffmpeg прекрасно умеет использовать различные API для аппаратного декодирования видео. В частности, для Windows поддерживается DXVA. Современный офисный компьютер (при поддержке со стороны Intel или NVidia) спокойно тянет 25 окон 720x576 (SD). Знаю, так как сам разрабатываю софт для телевидения и мы используем данную поддержку для Multiview телевизионных каналов. При этом загрузка CPU 20%.
Пока больше приглядывался именно к кодированию как к более нагружающему процессу и разбор кода для FFMPEG по данному вопросу не внушал оптимизма — для его поддержки придется скорее всего переписывать значительную часть кода что не совсем радует.
Посмотрите на решения от Intel — https://software.intel.com/en-us/intel-media-server-studio Ничего не могу по ним сказать, кроме того, что качество кодирования у них ниже софтового варианта судя по отзывам, но вам не кино в IMAX показывать.
К счастью, для вас, кодирование с ускорением, с использованием ffmpeg, намного проще чем декодирование. Для кодирования вообще ничего особенного не нужно делать, только указать qsv encoder, например. Декодирование с ускорением, существенно сложнее (для ffmpeg, но можно использовать DirectShow). Это связано с тем, что декодирование (в общем виде) происходит во внутренние буфер видеокарты (copy-back очень затратная операция), и эти буфера нужно будет готовить и обслуживать самостоятельно. Но, при желании, в этом можно разобраться.
Значит не тот гугл я смотрел, пойду перечитаю почему кодирование показалось мне сложным. Странно, если там все так хорошо и аппаратная поддержка реализована на сколько-нибудь значимом количестве железок почему просмотр и кодирование видео как правило не сильно быстро происходят? Во всяком случае не с нагрузкой 0% как вроде бы должно было быть, а приблизительно с такой нагрузкой с какой работает и моя программа…
Сложно сказать без конкретики, нужно смотреть. В идеале, декодирование HD отнимает 0% — 2% CPU. Кодирование побольше, так как, просто копирование (поставка) раскомпрессированого потока уже будет что-то занимать. Плюс, по словам Intel, например, некоторые промежуточные операции выполняются на CPU. При декодировании CPU почти не участвует. Могу лишь предположить, что вы пытаетесь копировать раскомпрессированный кадр обратно в RAM (copyback) чего делать не стоит. При декодировании, все, чем занимается CPU — это копирует несколько килобайт сжатого потока в буфера декодера и в нужный момент вызывает Blit. CPU там нечего делать.
Я не пытаюсь ничего обратно копировать — где вы это увидели? Все остальные приложения включая сам FFMPEG — тоже этим занимаются? Я допускаю что неверно интерпретирую данные, но ваше альтернативное объяснение пока никак не ложится на то что наблюдается. Про CPU и Blit не понял. CPU в любом случае лишь исполнительное устройство. Копирует и вызывает если можно так выразится программа. Да, она так и делает — вызывает функцию декодирования когда приходит новая порция сжатого потока до тех пор пока функция не сообщит о том что кадр получен. После этого готовый кадр копируется из буфера декодера. После этого в нужный момент вызывается BitBlt. Все это происходит в коде. Теория и рекламные статьи — это хорошо, но я вижу то что описал.
Это было сказано применительно к кодированию, в общем. Я видел код, и пытаюсь объяснить вам в чем будут проблемы при таком подходе. На практике, нужно очень хорошо представлять что кроется за вызовом той или иной функции. Direct-X более детерминированный путь по контролю за выводом графики чем очередь сообщений. Задача сгладить все неровности в распределении времени системой. Далее, я вас уверяю, что вы заблуждаетесь насчет практики и реально все работает и не жрет CPU. Про рекламу я не понял.
Да, это не DX. Это сделано по совсем другим принципам. Безусловно DX более прогрессивен чем рисование на форме однако программа не нарушает «законов» системы и не смотря на то что это менее производительное решение программа выполняет свои функции. Что на самом деле радует — можно сделать то что делает DX и иные тяжелые по уровню входа решения просто рисуя на форме.

Про рекламу я имел ввиду фразу «по словам Intel» — слова это хорошо, но ими оперировать не совсем честно в дискуссии ибо в этом случае обсуждение превращается в конкурс цитат в котором конечно же победит компания Intel — я не настолько мощен что бы завалить ее своими словами ;)

Не совсем понял как можно заблуждаться насчет практики если я вижу что нагрузка процессора при работе программы и при работе ffplay практически одинаковая — я же не голословно это утверждаю.
По скорости вывода битмапов GDI сравним с DirectX. В DirectX просто больше контроля данного процесса.
По поводу Intel: я их привел просто для примера. Под windows вообще лучше использовать DXVA, тогда вам будет все-равно что использовать для ускорения Intel, NVidia, AMD. Он сам позаботится об этом. Для проверки скорости я бы не рекомендовал ffplay. Я не знаю как он реализован внутри. Для сравнения лучше использовать windows mdia player, mpc, vlc или вообще GraphEdit из WindowsSDK. Выбрать в настройках поддержку аппаратного ускорения и самому убедиться в загрузке.
Я сравнивал скорость с ffplay просто для того что бы убедиться в том что производительность программы сопоставима с производительностью приложения от разработчика библиотеки. Иными словами я хотел убедить сам себя в том что я правильно работаю с функциями библиотеки и не вношу существенных задержек в процесс из-за того что рисую традиционными средствами. Этой проверки для меня достаточно — то есть я не ставил задачу сравнить решения примененные в программе со всеми возможными решениями. Для визуального восприятия привожу снимки экрана полученные только что. По ним видно что ffplay, программа и VLC имеют приблизительно одинаковые скорости. Незначительные отличия связаны с дрейфом загрузки. Аппаратное ускорение не включалось. Точнее я не знаю включено ли оно в VLC или где либо еще.


На наколеночных тестах у меня год назад лучше всего себя в скорость DXVA показал именно MPC. При этом в качестве декодера он использовал LAV Filters. Это просто для информации :)
Посмотрел. Нет, гугл все тот же. Поверьте — если по отношению к вам как знающему человеку уместно такое обращение — в случае включения аппаратной поддержки придется конкретно полазать под капотом — одним волшебным флажком там не обошлось.
Особенно настораживает документация FFMPEG в которой прописано о необходимости "...build, configure with..." — то есть эта шутка вроде как по умолчанию не стоит и нам предлагают пересобрать FFMPEG (
Возможно требуется собрать с поддержкой QSV, например, это да. Просто — с точки зрения API. Все что от вас требуется — это настроить нужный аппаратный кодек, как и любой другой, и преобразовать кадры в формат NV12.
Безусловно это просто если слово просто означает «напишите код в соответствии с API аппаратного ускорителя». Но мне не ясно почему они просто не могли реализовать это в самом низу? То есть почему я не мог указать в словаре что хочу использовать аппаратное ускорение и продолжать использовать имеющийся код вызывающий avcodec_decode_video без изменений, но с большей производительностью? Зачем они сделали так, что я должен модифицировать код? Безусловно на это были причины. Просто жаль.
Ну так устроен ffmpeg/ Для кодирование все работает именно так, как вы хотите, все «внизу». Для декодирования это невозможно, так как ffmpeg не заниматся рендерингом. Он не знает какие API, платы, вы будете использовать для показа и как плотно интегрированы с GUI. Вам нужно, немного, ему помочь с аппаратными буферами, куда нужно будет класть декодированные кадры.
В первую очередь ваш подход в случае аппаратного кодирования не годится потому, что всё будет рендерится в буферы, находящиеся в памяти видеокарты. Записав данные в эти буферы, не стоит пытаться их вычитать обратно, что-то там поделать средствами CPU чтобы в конечном итоге отрендерить всё видеокартой. Гонять трафик по шине взад вперёд — не самое лучшее, чем можно занять это железо.
Я наверное понял о чем вы — декодирование на стороне карты не только выгоднее из-за аппаратной поддержки но и потому что кадр уже будет сформирован там где будет отображаться? Но мне нужно наложить на него свои элементы и вообще накапливать кадры для сглаживания вывода — получается что использовать оба преимущества я не смогу — только аппаратную поддержку, но не разгрузку шины, верно?
Создаёте столько буферов, сколько вам нужно, средствами DirectX. И все иные операции делаете этими же средствами.
Хм, звучит заманчиво попробую разобраться. Нет ли поваренной статьи — как вывести картину через DX?
Я это делал только средствами DirectDraw, который уже мёртв. Так то это к Videoman больше вопрос.
Я готов ответить, но:
1. Не пойму что нужно, пример кода? Типа взяли буфер из памяти и нарисовали в нужном месте через Direct3D? Не многовато кода будет в ответе?
2. Где можно посмотреть теги или что-то подобное для оформления ответов на habr-е?

Еще хотелось бы добавить по поводу вывода сразу на поверхности в видеопамяти:
В плане интерфейса, нет практически никаких ограничений. Мы например используем QT и рендерим через ANGLE.Так вот видео поверхности, без проблем, можно комбинировать с QT виджетами и рисовать над и под видео.
Нас могут наказать за код в ответе?
Тег я думаю тут будет один — C++ код — кнопочка выглядит так </>
Попробую задать вопрос понятнее: где можно посмотреть какие теги поддерживаются и как оформлять ответы. Если ли подсказка? Я тут первый раз просто.
Выдержка из https://wiki.qt.io/Qt_5_on_Windows_ANGLE_and_OpenGL:
Use Desktop OpenGL if
Your application uses OpenGL calls not part of OpenGL ES 2.0
Your application does not use OpenGL at all (since ANGLE implies additional deployment dependencies which are then not needed).
Your application needs to run on Windows XP. Although it is tempting to use ANGLE as a replacement for missing graphics drivers on this platform, it does not fully work and may lead to crashes, for example, when the security dialog is opened.

Use ANGLE if
You need OpenGL ES features, but not full OpenGL
You have a heterogeneous user base with different Windows versions & graphics cards
You do not want your user to have to install a recent graphics card driver
You want to use the video playback functionality of QtMultimedia (see QTBUG-31800 )
Your application needs to run over Windows Remote Desktop Protocol (see OpenGL and Remote Desktop)
Я так смотрю, Майкрософт продолжает вставлять палки в колёса OpenGL, что вынуждает даже гугл родить свой фреймворк. В итоге через ANGLE приходится писать на OpenGL?
Да. Microsoft продолжает продвигать свои продукты и разработки и их можно понять — конкуренция. По-этому, что бы делать interop DXVA (проприетарная технология которая, в свою очередь, требует Direct-X) и OpenGL (которая используется в QT) приходится компилировать QT с Angle. Так можно в рамках Angle конвертировать Direct3D поверхности в OpenGL поверхности, которые, в свою очередь, находятся в видео-памяти, без копирования.
Спасибо за информацию по этому фреймворку. Нет ли случаем полезных ссылок под рукой по DXVA силами ffmpeg? И, кстати, DirectShow вообще не используете? Какие преимущества/недостатки в использовании ffmpeg + Angle перед DirectShow?
Нет ли случаем полезных ссылок под рукой по DXVA силами ffmpeg?
Нет, вся информация собиралась по крупицам. Советую посмотреть исходники утилиты ffmpeg, файл ffmpeg_dxva2.c, если не ошибаюсь. Благо он один и вся работа с DXVA там сконцентрирована.
И, кстати, DirectShow вообще не используете?
У нас написана библиотека для проигрывания различных данных и используется в софте наподобие нелинейных редакторов. Библиотека написана на С++ и архитектура там своя, а вот компоненты библиотеки; источники, демуксеры, декодеры и т.д. используют как на ffmpeg, так и DirectShow фильтры. За счет единого интерфейса их можно комбинировать как угодно друг с другом. Т.е. сплиттер может быть ffmpeg, а декодер DirectShow, и наоборот. Рендереры все свои. В результате можно играть данные произвольных форматов, вперемешку, с произвольной скоростью, вперед и назад.
Какие преимущества/недостатки в использовании ffmpeg + Angle перед DirectShow?
ffmpeg — более гибкий, всегда можно посмотреть что и где неправильно работает, поддержка кучи экзотических форматов используемых в камерах и оборудовании.
DirectShow — проще использовать, но: платные компоненты, медленный старт-стоп, жрет ресурсы системы (память, хендлы и т.д.). Пришлось изобретать wrapper для фильтров, наподобие струпцины, чтобы пихать и забирать данные.
Благодарю за ответ. Вот действительно бы цикл статей от вас, но там работы на месяц только чтоб по верхам пройтись. При чём вы сами с этого ничего не поимеете. Вот так и живём.
Да, найти время и терпение для статьи нелегко. С момента внедрения приложения до выпуска этой статьи прошло 3-4 месяца. Надеюсь занятость не отнимет у нас ваш глубокий опыт в этом вопросе.
Как раз в занятости и проблема. Тема мультимедиа обширна и требуют некоторого начального багажа для понимания. Из-за этого всегда стоит дилемма, писать полностью с нуля, чтобы было интересно читать всем, или подразумевать что статья уже для продвинутых, сужая этим охват.
Приведу пример: вот хотим мы написать статью о том как правильно писать фильтры разных типов под DirectShow. Вроде бы все знаем, кода куча — короче, садись и пиши. И тут начинается. А там COM.
А о нем нужно рассказывать?! А там жуткая многопоточность, навязанная самой архитектурой. А про многопоточность нужно рассказывать, или предполагается, что человек знает что это такое и представляет какие есть примитивы в WinAPI ?! Для быстрой разработки у нас кругом свои обертки и врапперы. А наверное интереснее будет на голом С?! Значит нужно все переписывать и тестировать. В общем, я хочу сказать, нужно четкое понимания для кого писать и какая задача ставится. Для себя, я уже давно понял, что написание статей это отдельная большая и кропотливая работа, которая требует уйму времени.
Да, мне тоже было легче остаться при своем. Желание поделиться было сильнее.
Именно что мультимедиа обширна и вменяемого цикла статей не попадалось мне на глаза. Да и десять лет назад, когда мне было интересно окунуться в DicrectX, все развалы в городе излазил с дисками — ничего по DX не нашёл. Приходилось брать вместо этого диски с игрушками, отвязывать их через SoftICE от желания диска в приводе и обменивать за копейки на следующие. Но потом энтузиазм закончился и появилась потребность в деньгах. А сейчас начинаю задумываться, что свернул в своё время не туда. Теперь с моими обрывочными знаниями только индусов на апворке пугать бидами в пять долларов.
А можно еще несколько вопросов:
1. Почему не используется аппаратное ускорение (например DXVA под Windows) — это позволило бы показывать видео намного плавнее, т.к. загрузка CPU обычно падает до 1-5%.
2. Почему не используется отдельный поток для прямого рендеринга из него средствами Dirext-X. Посылка сообщений из другого потока, таких как WM_PAINT, по средством SendMessage, все-равно происходит синхронно. Т.е. тормозится вызывающий поток, потом стартует тот, которому отправлено сообщение, сообщение выполняется в другом потоке (у вас это WM_PAINT в основном потоке), после управление опять передается в вызывающий поток. Какой смысл отдельного потока, если отрисовка все-равно происходит синхронно в главном потоке.

Это, как минимум, две причины которые приводят к рывкам. Даже на том видео, которое вы прислали, заметно, что частота вывода плавает. Я уверен, что на более динамичном потоке эффект будет еще более заметным.
1 У меня ещё не было возможности разобраться с этим. Если у вас есть наработки я думаю былобы интересно их оформить статьей.
2 DX я не использую — пока ещё не было необходимости разбираться с этим — на мой вкус он достаточно тяжёл для входа. Посылка сообщения через функцию синхронизации действительно останавливает поток, я об этом знаю и это не влияет на производительность — поток который шлёт эти сообщения либо рисует либо спит — зачем мне рисовать быстрее если кадры идут с такой частотой с которой он справляется и после рисования все равно спит? Артефакты на видео (если вам не сложно укажите место где вы их заметили что бы я смог дополнительно проанализировать этот момент) скорее всего связаны не с работой программы, а с тяжёлыми условиями транспорта данных.
Наработок куча, так как уже лет 10 пишем профессиональный софт для телевидения. Это масса, достаточно сложных, «технологий» типа ffmpeg, DirectShow, Direct-X. Также весь этот зоопарк используется для кодирования и декодирования видео. У нас написаны свои рендереры видео и аудио максимально использующие поддержку со стороны аппаратуры. Тут, к сожалению, статьей не отделаться, тут нужно несколько книг писать, как все это использовать, применительно к видео обработке. Но собирать качественный рендерер видео из готовых компонентов уже не сложно.
По поводу вопроса про поток который показывает: его задача максимально быстро, без задержек, показать следующий кадр. Задержки больше чем 10 мс на кадр, а особенно если они плавающие, уже заметны на глаз. Подготовка самих кадров и все тяжелые операции должны выполняться в другом потоке. При использовании SendMessage, задержки на переключение контекста потоком не предсказуемы.
По артефакты: я имею ввиду «плавающую» частоту воспроизведения кадров. Когда робот движется, это более заметно.
Задача у вас интересная. Пока, как я понял по коду, решена в черновом варианте, но, при желании, тут много что можно улучшить.
Как вы совершенно правильно пишите все операции подготовки выполняются у меня в отдельном потоке обслуживающим камеру. Вывод идет в другом потоке и не делает с кадром ничего кроме самого вывода (от этой операции никуда не уйти учитывая назначение этого потока). Задержек такого порядка как вы описали я не наблюдал. Относительно максимальной быстроты вывода: как я уже сказал если поток вывода вывел кадр за 5 мс и спит 35 мс, то чем это отличается от ситуации когда он вывел кадр за 1 мс и спит 39 мс?
Для плавности важно не только что время есть в запасе, но и вывод кадра в строго запланированное время. Что бы было видно, достаточно что бы задержка при показе кадров плавала от 0мс до 40мс. Потом, видео-каналов момент быть много и все они будут друг на друга влиять. По коду, к сожаление, не видно как вы инициируете WM_PAINT. То что вывод связан с WM_PAINT, уже, говорит о том что вывод всегда будет с непредсказуемыми задержками и рывками, если только не создать отдельный цикл выборки сообщений в отдельном потоке, который рендерит. Но зачем это делать, если есть DirectX. Весь смысл такого сложного дизайна — показывать кадры со строго заданной частотой (насколько это возможно в системах не реального времени), а также нивелировать случайные непредсказуемые задержки и нагрузки CPU. У нас, типичная задержка при непосредственном выводе кадра — микросекунды (0 мс). Также, для плавной синхронизации, я очень рекомендую завести аналог референс-часов, по которым все компоненты синхронизируются друг с другом (в случае стереоскопичекого видео или звука очень даже актуально). В противном случае, у вас всегда будут проявляться все особенности реализации современных операционных систем в виде рывков…
Если бы задержка плавала 0-40 мс это было бы видно так что у людей бы глаза повыбивало. Судя по всему описанные вами эффекты в моем случае не проявляются, а вполне обоснованные предположения о задержках весьма преувеличены.
Вот, кстати, как к профессионалу в данной области вопрос — что здесь лучше использовать как референс? Пытаться привязаться к вертикальной синхронизации монитора или использовать какой-то мультимедиа-таймер из DirectShow? Или на современном железе системные таймеры стали довольно точны?
С вертикальной синхронизацией сейчас все плохо, т.к. сигнал эмулируется на современных цифровых интерфейсах и может быть задан каким угодно. Он оставлен для обратной совместимости со старым софтом. Проблема не в точности таймера, можно использовать хоть Sleep, проблема в точности планировщика потоков windows, то, как быстро он пробуждает поток после поступления сигнала. Тут лучше использовать мультимедийный таймер. Как только вы задаете частоту его срабатывания, windows меняет размер кванта потоков данного процесса в соответствии с заданной частой таймера со стандартной (порядка 15мс) до заданной.Другими словами, если вы создадите в процессе мультимедийный таймер с частотой срабатывания 1мс, то все потоки начнут планироваться и срабатывать с заданной частотой 1мс. Сам таймер можно использовать любой. В DirectShow например он выбирается динамически, сначала пытается брать часы источника (если есть) потом часы рендерера (если есть).
Хм. Т.е. разрешение Sleep в 15 мс, о котором я в курсе, это не разрешение Sleep, а время переключения контекста между потоками? Хорошо, допустим в таком случае мы не пишем медиакомбайн и не хотим использовать мультимедиатаймеры, а просто полагаемся на мьютексы и семафоры. У нас будет уходить до 15 мс на каждое переключение между потоками? Жесть. Средства C++11/14 предлагают что-то из коробки? Не нужно развёрнутого ответа, просто хочу понять, решена ли подобная проблема да и есть ли она вообще. Просто последний раз, когда для меня было критично по времени синхронно обрабатывать данные в рилтайм, поступающие с камеры, уходящие в железку по USB, приходящие обратно и после постобрабатываемые на процессоре между четырьмя потоками, я ещё на стадии разгребания каши после предыдущего разработчика с его понатыканными везде Sleep(1) был вынужден увеличить разрешение этого Sleep средствами системы Win7 (указал в качестве референсного таймер высокого разрешения) и успешно про это забыл к моменту, когда всё переписал и раскидал нормально по потокам без «магических» задержек вообще. Снимаемые логи показали, что я полностью укладываюсь в таймлайн, но с лишь с небольшим запасом на цикл, что всех устроило. Получается, я мог не уложиться, не проведя такую подготовочку системы на первом этапе?
Если коротко, то частое переключение потоков не приведет к быстрой обработке данных, скорее наоборот, за счет потери времени на переключение. Но, уменьшив квант, мы можем точнее реагировать на события. Для быстрой и эффективной передачи данных между потоками или устройствами лучше использовать очереди.
Спасибо. Придётся почитать литературу. Ибо пора менять род занятий с пусконаладки систем безопасности на что-то более нужное в этом мире.
«Опровержение слухов — слушайте факты» (С)
Как и говорилось ранее выводы о наличии дополнительных задержек связанных с работой очереди сообщений, синхронизацией потока с потоком GUI и рисованием на форме являются лишь теоретически верными, но практически не влияющими на работу программы. Тема заинтересовала меня и сегодня провел дополнительное тестирование — замерил время между вызовами WMPaint (то есть время между реальным рисованием кадров в окне) — пытался увидеть указанный вами эффект рывков и плавания задержек. Ничего не подтвердилось. Ни рывков ни дрейфа задержек нет. Во всяком случае на Intel Core2 Duo E8300 2.83 ГГц. Разность отметок между кадрами остается постоянной и равной фактическому периоду с которым поступают кадры — 40 мс. Единичные отклонения амплитудой до 180 мкс могут быть связаны с колебаниями загрузки, точностью отметок времени, описанными вами задержками или фазой Луны. На графике по оси X время в мс, по оси Y задержка между вызовами WMPaint в мс.
Как обычно — только логи расставляют всё по своим местам :)
«Человек предполагает, а тест располагает» ©
Осталось вам ещё на промышленные камеры (например, PointGray) и обеспечить полную синхронизацию картинок на аппаратном уровне.
На самом деле насущная проблема — это аппаратное кодирование и, возможно, движения в сторону отлова вертикальной синхронизации. Как я понял это требуют танцев со сборкой и обнимашек с DX. А гуру не хотят делится двумя с половиной строчками кода ;)…
при беглом поиске попадаются даже вот такие решения: https://github.com/trbotha/PointGrey_RPi
правда, я не понял из описания, через какую они шину протаскивают данные, но заявляют о рилтайм кодировании двух камер силами одной малины. для вас крайне бюджетное решение. не считая конской цены на сами камеры, но один только заявляемый Global Shutter на CMOS матрице того стоит. Global Shutter на CMOS, Карл! и как я мог пропустить такую фишку новых матриц Sony.
Совершенство все совершеннее ;)
Теория здесь как-раз важнее, так как у вас нет возможности проверить ваш софт на огромном парке машин. Никто не спорит, что на отдельно взятой машине, в вакуме, в идеальных условиях, где кроме одного приложения с одним окном видео больше ничего не работает, вы увидите вышеописанную картину. Вы не приводите ни разрешение видео, ни разрешение с которым оно показывается, ни текущую загрузку CPU в вашем тесте. Загрузите машину хорошо, процентов на 50, выведите 2 HD видео одновременно и еще 8 SD дополнительно. Желательно проделать данный эксперимент на 10 машинах с разной конфигураций. Только, когда во всех этих условиях вы получите идеальный результат, можно будет о чем-то говорить. Количество машин, на которых мы отлаживали систему, порядка сотни, и поверьте, написать хороший рендерер, это не такая простая задача как вам кажется.
Я не спорю с теорией просто в ряде случаев оптимизация превращается в пугало. Когда поставят задачу запустить 100 видео-потоков на кофеварке я конечно же задумаюсь где сэкономить еще 1 мс родив в результате непереносимого и несопровождаемого монстра эффективное решение. Относительно сферичности теста — запуск шел на железе которое как бы нельзя назвать топовым поэтому обоснованным является предположение о том что тест пройдет не менее успешно и на других машинах. Пока я еще не вижу в себе сил и не пытаюсь написать рендерер сопоставимый с теми что выпускаются компаниями которые специализируются в данной области.
Да я сам читаю, что не нужно переусложнять там, где можно обойтись более простым решением. Так все-таки, вы можете подтвердить, что ваши одна HD камера и 9 SD которые работаю одновременно для кругового обзора, дают такой же результат, как вы привели. Если да, то замечательно и больше тут ничего не нужно, задача решена.
Понаблюдать за работой системы в полной комплектации пока к сожалению не доводилось — негде просто взять столько камер. В статье лишь указано на такую возможность и на то, что полная комплектация начнет упираться в ограничения по транспортировке данных. Кроме того учитывая показатели загрузки процессора приведенные в статье запускать программу обслуживающую полную комплектацию придется как минимум на в два раза более производительном Intel Core2 Quad Q9400 2.66 ГГц. Таким образом поразить вас и себя фразой «все работает» мне не удастся. В дополнение лишь уточню, что тест задержек который я привел проводился для разрешения использованного в статье (1280 x 1024, одно окно просмотра), время работы процедуры WMPaint при этом стабильно находилось на уровне 4,2-5,0 мс, нагрузка на процессор составляла 4-5% (декодирование не проводилось, это был тест без потока — исключительно для проверки подсистемы вывода на экран).
Пардон, разрешение было 1280 x 720
Камеры обычно способны отдать несколько одинаковых потоков с себя. Так что для тестов полной загрузки вам хватит и одной камеры.
Ну и зачем такие синтетические тесты?! Рендерер, в моем понимании, это компонент, который сглаживает неравномерную загрузку, в том числе. Как можно говорить о том, что он плавно работает, если нет загрузки?!.. И потом 4% и 4мс, при холостом выводе, это очень много. Нужно ориентироваться на 0%.и микро секунды. Ну сами подумайте, вы выводите 25 раз в секунду с паузами между этими выводами. Для современного процессора и для видео процессора это вечность, они просто стоят и курят в сторонке. Для ссылки: средненький аппаратный декодер спокойно декодирует H264 со скоростью 500 кадров в секунду, а уж выводить на экран битмапки 1280х1024 — это тысячи.
Синтетический тест нужен что бы отделить пену от воды. Перед вами конкретные цифры которые приведены для отдельно взятой подсистемы которую вы оценили критически. Согласно этим цифрам на рисование тратится 5 мс при стабильных интервалах между кадрами 40 мс. Я в этих цифрах не вижу ни «задержки больше чем 10 мс на кадр» ни того что бы «задержка при показе кадров плавала от 0мс до 40мс». Я согласен с вами в том что аппаратная реализация быстрее. Все это я лишь привожу для того что бы показать что очередь сообщений являясь архаичным, но 100% переносимым по причине своей фундаментальности, механизмом в состоянии выполнять свои функции.
Я в этих цифрах не вижу ни «задержки больше чем 10 мс на кадр» ни того что бы «задержка при показе кадров плавала от 0мс до 40мс»..
Так, я все понял. Исходя из ваших ответов, вы не правильно представляете себе как работают современные операционные системы. Задержки берутся не из воздуха, задержки появляются тогда, когда планировщик распределяет общее время между несколькими работающими потоками. Если у вас нет загрузки системы, то и задержкам взяться не от куда.
Все это я лишь привожу для того что бы показать что очередь сообщений являясь архаичным, но 100% переносимым по причине своей фундаментальности, механизмом в состоянии выполнять свои функции.
Вы этим тестом показали лишь то, что без нагрузки процессор занят только вашей «логикой» и выполняет ваш код без прерываний на параллельные задания. Все. Больше этот тест ничего не показывает. Как только вы напишите «боевой» код и нагрузите процессор, ваши тайминги сразу же поплывут.
Я отдаю себе отчет в том что при оценке нагрузки 2 + 2 может не оказаться равным 4. Я затрудняюсь определить как именно мне нагрузить процессор что бы тест был признан вами правильным. Очевидно, что мне нужно просто «повесить» систему и отрапортовать о том, что тайминги действительно поплыли. Только тогда все будет признано достоверным.
Для начала, достаточно будет с помощью, того же, ffmpeg декодировать какой-нибудь видео-клип размером 1280х1024 и убедиться что тайминги также стоят как вкопанные.
Хм. Неожиданно. А что это даст? Серьезно.
Увидите как реально работает очередь.
Совсем не понял. Вы утверждаете что ffmpeg построен на очереди сообщений %/
Нет. Здесь речь о том, что на очередях построена ОС. А ffmpeg — очередной клиент в этой очереди, способной оттяпать от неё хорошенький кусочек.
Какое-то логическое зацикливание и бег по кругу… ОС построена на очередях… Речь идет об очереди сообщений окна? Сомневаюсь в том что приложения интенсивно не обращающиеся к этому механизму к коим я причисляю и ffmpeg что-то там способны оттяпать. Они способны оттяпать кванты — очередь им до лампочки.
Под очередью я понимаю ваш рендерер, построенный на очереди оконных сообщений. Причем тут ffmpeg, применительно к очереди?
Причем тут ffmpeg, применительно к очереди?

эм…
ffmpeg — очередной клиент в этой очереди, способной оттяпать от неё хорошенький кусочек

0.0

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

1 — я знаю и согласен с вами что аппаратное кодирование / декодирование и вывод на экран средствами DirectX / SDL / иного_специализированного_решения более эффективен, однако, как вы сами знаете, эти методы имеют более высокую планку входа, сильнее зависят от аппаратного обеспечения и программной среды в которой исполняется приложение, несут с собой целый ряд побочных задач никак не связанных с основной, но обязательных для решения (первое что приходит в голову — построение графического интерфейса пользователя и реализация несколько отличающегося от традиционно принятого в Windows механизма работы с окнами требуемого по условиям задачи).

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

3 — после того как инструменты определены работает только логика которая в руках любого человека даст ту архитектуру которая описана:
-декодирование (в отдельном потоке);
-отображение кадров посредством периодической перерисовки формы (процедура перерисовки вызывается в отдельном потоке, сам вызов синхронизируется с потоком графического интерфейса пользователя так как этого требует документация среды разработки);
-собственно рисование кадра реализовано посредством перекрытия обработчика сообщения WM_PAINT так как это самый низкоуровневый способ из доступных при такой реализации.

Таким образом приведённое решение приближено к идеальному в своём классе, но не в глобальном плане (как и любое другое — нет серебряной пули).
Тут все как сами пожелаете. Про конкретное решение решение и степень его применимости не шло никакой речи. Обсуждались лишь теоретические аспекты реализации работы с видео и их плюсы и минусы, а также от том, как должны, в идеале, быть устроены модули для работы с видео, для того чтобы их можно было бы применять во всех своих решения, а не писать велосипед каждый раз под каждый новый случай, а потом бороться с последствиями упрощений.
Конечно, то что я сейчас скажу спекуляция, но всегда новые велосипеды без устали пишут днём и ночью те кто в струе технологий потому что технологии дают дуба быстрее чем хотелось бы, и велосипеды эти реально очень быстрые, но только на трассе для формулы один, а на обычной дороге едут так же как и мой деревянный самокат ;)
А можно попросить остальные потоки слегка подвинуться, запросив у системы повышенный приоритет для своих. Но, похоже, всё сводится к мультимедиа-таймерам в потоке рендеринга.
При создании потока можно задать приоритет
Картинки интересные, жаль только спойлеров не завезли.
Подкину из личных запасов:
<spoiler title="">
</spoiler>
Есть один) Хабракат)
«Основной целью при проектировании и создании *Moby Dick* было создание *небольшого* робота...» — это, все-таки, пять)))
Не совсем понимаю ваше веселье) Робот действительно небольшой — человек может поднять его одной рукой
image

Я так понимаю, что дело в названии. Ведь "Моби Дик" — гигантский кит.

Игра слов? Тонко ;)
«Моби Дик» не от размеров, а от глубины погружения — кашалоты погружаются на глубину до 3 км)
Интересная статья, спасибо.
Кстати по теме отлично было рассказано и показано в фильме опасное погружение, там капсула в океане застряла, а водолазы пытаются выжить, кислород кончается… Много съемок там на глубине около 5 км.
Sign up to leave a comment.

Articles