LINUX.ORG.RU

Пересжатие H264 с потерей кадров

 , , ,


0

4

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

Опять продолжение темы Запись сырого h264

Теоретический подсчет показал, что в сравнении с raw записью 1920х1080 MJPEG создающую нагрузку на носитель где то 1.2 Мб/c при 5 фпс, такая же запись H264 при 30 фпс создает поток где то 0.6 Мб/c, т.е. в принципе уже проверенную пропускную способность по записи укладываюсь, а вот с онлайн стримом вопрос.

Абсолютно точно придется пропускать кадры. Если для мжпег удалось сделать это очень равномерно, т.к. из очереди std::deque всегда брался для пересжатия из мжпег в х264 только последний кадр, то в случае с h264 нужно занусуть видео поток в канал где то до 2мбит/c, т.е. декодирование->масштабирование в 2-2.5 раза->сжатие. Все это делается на слабенькой arm пока без доступа к ядру гпу.

Первое что приходит в голову это подряд пересжимать кадры и сбрасывать очередь каждый раз при поступлении I кадра - да камера отдает I кадры каждую секунды и еще 29 P кадров, расстояние не большое, но «рывок» в конце каждой секунды все равно хоть как будет и скорее всего придется отбросить 2/3 кадров (по аналогии с мжпег пересжатием в х264).

Буду благодарен любой идее )

★★★

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

Не вижу требований на latency, так что…

Буду благодарен любой идее

Не страдать фигней и не пропускать кадры. В битрейт влезает? Если нет, просто понизь его.

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

в битрей не влезает, приблизительно в 2-2.5 раза больше он ширины канала.

понятно что пропускать, вопрос как так пропустить чтобы сравнительно гладкое видео получить?

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

и что это даст кроме загрузки цпу? рывок то все равно останется, т.е. из 30 кадров можно считать что пересжать в нужную ширину канала я успею кадров 10.

а стрим онлайновский ессесна, а не какой то видео по интернетам.

wolverin ★★★
() автор топика

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

ffprobe -show_frames

оценить нагрузку декодера и получилось от 50 до 75% на цпу, т.е. все кадры декодировать тоже не успею

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

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

Если у тебя I frame половину от общего битрейта, а остальное размазано на 50% и ты хочешь сделать в три раза меньше fps, то ты сэкономишь 1/6, превратив изображение в драный мусор.

Гораздо больше результата будет, если ты просто поставишь обычный нюк и тупо перекодируешь видео с помощью libx264 в два раза меньший битрейт.

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

max_lapshin

I кадры 140-145 Кб (не совсем показательно, т.к. в тесте снимаю потолок)

P кадры 13-15Кб (те же условия)

Битрейт сколько usb камера отдает не знаю, но VLC показывает до 5мбит/c

а что такое нюк?

ты хочешь сделать в три раза меньше fps

это следствие уже, главное меньше разрешение и естественно меньше битрейт

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

Видимо речь про intel nuc - нет это догага ) тысячи железок же у меня

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

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

У большества USB камер можно выбирать FPS.
03f0:e807 HP, Inc HP Webcam HD 4310

[0]: 'YUYV' (YUYV 4:2:2)
        Size: Discrete 1280x720
                Interval: Discrete 0.133s (7.500 fps)
        Size: Discrete 1920x1080
                Interval: Discrete 0.200s (5.000 fps)
        Size: Discrete 640x480
                Interval: Discrete 0.033s (30.000 fps)
                Interval: Discrete 0.040s (25.000 fps)
                Interval: Discrete 0.050s (20.000 fps)
                Interval: Discrete 0.067s (15.000 fps)
                Interval: Discrete 0.100s (10.000 fps)
                Interval: Discrete 0.133s (7.500 fps)
[1]: 'MJPG' (Motion-JPEG, compressed)
        Size: Discrete 1920x1080
                Interval: Discrete 0.033s (30.000 fps)
                Interval: Discrete 0.040s (25.000 fps)
                Interval: Discrete 0.050s (20.000 fps)
                Interval: Discrete 0.067s (15.000 fps)
                Interval: Discrete 0.100s (10.000 fps)
                Interval: Discrete 0.133s (7.500 fps)
        Size: Discrete 640x480
                ...
                Interval: Discrete 0.033s (30.000 fps)
                Interval: Discrete 0.040s (25.000 fps)
                Interval: Discrete 0.050s (20.000 fps)
                Interval: Discrete 0.067s (15.000 fps)
                Interval: Discrete 0.100s (10.000 fps)
                Interval: Discrete 0.133s (7.500 fps)

046d:0825 Logitech, Inc. Webcam C270

[0]: 'YUYV' (YUYV 4:2:2)
        Size: Discrete 1280x960
                Interval: Discrete 0.133s (7.500 fps)
                Interval: Discrete 0.200s (5.000 fps)
[1]: 'MJPG' (Motion-JPEG, compressed)
        Size: Discrete 1280x960
                Interval: Discrete 0.033s (30.000 fps)
                Interval: Discrete 0.040s (25.000 fps)
                Interval: Discrete 0.050s (20.000 fps)
                Interval: Discrete 0.067s (15.000 fps)
                Interval: Discrete 0.100s (10.000 fps)
                Interval: Discrete 0.200s (5.000 fps)

Это 10% от всех размеров.

Есть правда 1871:0141 Aveo Technology Corp. Camera

        Size: Discrete 640x480
                Interval: Discrete 0.033s (30.000 fps)
        Size: Discrete 160x120
                Interval: Discrete 0.033s (30.000 fps)
        Size: Discrete 320x240
                Interval: Discrete 0.033s (30.000 fps)
        Size: Discrete 176x144
                Interval: Discrete 0.033s (30.000 fps)
        Size: Discrete 352x288
                Interval: Discrete 0.033s (30.000 fps)

Тут дела похуже.

IIIypuk ★★★★
()

Разрешение понизь и растяни до нужного. Я некоторые фильмы смотрю в 360p так это 360p аккуратно закодировано так что смотреть приятнее чем 1080p и без квадратиков дохлого битрейта и без дрыгалы пропуска кадров.

anonymous
()
Ответ на: комментарий от IIIypuk

IIIypuk

$ sudo v4l2-ctl --list-formats-ext -d 0
ioctl: VIDIOC_ENUM_FMT
        Index       : 0
        Type        : Video Capture
        Pixel Format: 'YUYV'
        Name        : YUYV 4:2:2
                Size: Discrete 640x360
                        Interval: Discrete 0.033s (30.000 fps)

        Index       : 1
        Type        : Video Capture
        Pixel Format: 'MJPG' (compressed)
        Name        : Motion-JPEG
                Size: Discrete 640x360
                        Interval: Discrete 0.033s (30.000 fps)
                Size: Discrete 1280x720
                        Interval: Discrete 0.033s (30.000 fps)
                Size: Discrete 1920x1080
                        Interval: Discrete 0.033s (30.000 fps)

        Index       : 2
        Type        : Video Capture
        Pixel Format: 'H264' (compressed)
        Name        : H.264
                Size: Discrete 640x360
                        Interval: Discrete 0.033s (30.000 fps)
                Size: Discrete 1280x720
                        Interval: Discrete 0.033s (30.000 fps)
                Size: Discrete 1920x1080
                        Interval: Discrete 0.033s (30.000 fps)

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

Разрешение понизь и растяни до нужного.

вопрос не в том, какой должен быть готовый поток, а как его получить - есть I кадры каждую секунду, есть P кадры по 29 раз в секунду, каждый P кадр зависит от предыдущего, чтобы восстановить ОНЛАЙН трансляцию для пересжатия требуется ВСЕ кадры декодировать, что невозможно сделать за 33мс на кадр на имеющемся оборудовании.

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

в аниме 8-12 кадров в секунду

больше скажу, если я возьму с камеры мжпег 30 фпс при 1920х1080, то я без проблем получу 10 фпс в х264 при разрешении 960х540, НО хочется ОДНОВРЕМЕННО писать х264 с разрешением 1920х1080 т.к. это дает БЕЗ нагрузки в два раза меньший объем хоть и 30 фпс придется писать, а не 5 в случае с мжпег

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

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

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

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

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

wolverin ★★★
() автор топика
8 мая 2024 г.
Ответ на: комментарий от wolverin

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

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

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

Да точно - нужно без декодирования отделять I от P кадров и в последних на одном кадре копить все изменения, что даст возможность без пересжатия отдать в приложение те же достаточные 10 фпс и записать 5 фпс с одного и того же потока с камеры

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

на одном кадре копить все изменения

  1. начальные точки векторов движения в P кадре не будут совпадать с конечными точками векторов в предыдущем P кадре;
  2. копить разницу между изображениями и предсказанными кадрами совсем не тривиально.
i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat
  1. это да, но тогда этот условный один кадр для каждого потока свой и к нему выполняется «досуммирование» всех до текущего взятого с камеры

  2. В кадров нет, есть только Р кадры, а это всегда только разница с предыдущим

wolverin ★★★
() автор топика
Последнее исправление: wolverin (всего исправлений: 5)
Ответ на: комментарий от i-rinat

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

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

правда если с определением И или Р кадр еще как то базово понятно куда искать, то как сложить к «устаревшему» Р кадру все до «текущего» пока вопросец ))

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

Введи при кодировании особую разновидность P-кадров. Для определённости, пусть они называются Q кадры. P кадры будут зависеть только от I и P, а Q будут кодироваться так же, как P, но могут быть зависимы от Q, P и I. Тогда из потока IQPQPQPQPQPQIQPQPQPQPQPQ можно будет просто выбросить все Q кадры без проблем со связностью I и P кадров. Возможно, будут какие-то проблемы с кодированием номеров кадров, но это кажется относительно дёшево решаемым.

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

проблема в том, что я ничего не кодирую, просто беру с камеры как есть и нужно взять разрешение 1920х1080 для архива, а это при И кадр каждую секунду дает где то 6 мбит/c, что не влазит в ширину интернета при 30 фпс.

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

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

[h264 @ ] Increasing reorder buffer to 11
[h264 @ ] Increasing reorder buffer to 12
[h264 @ ] Increasing reorder buffer to 13
[h264 @ ] Increasing reorder buffer to 14
...

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

… мож сам декодер ффмпега умеет корректно обрабатывать пропущенные кадры, даже опорные!?

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

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

ffmpeg -f v4l2 -input_format h264 -c:v h264 -threads 4 -video_size 1920x1080 -i /dev/video0 -f null -

Input #0, video4linux2,v4l2, from '/dev/video0':
  Duration: N/A, bitrate: N/A
  Stream #0:0: Video: h264, none, 1920x1080, 30 fps, 30 tbr, 1000k tbn
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> wrapped_avframe (native))

230-280% из 400 потребление процессора и 40% потребление памяти только на декодер… но даже где то 28-29 фпс пишет, может попробовать хотя бы декодированные кадры отбрасывать как изначально планировал

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

продолжаем мозгоклюйство в отпуске )

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

(AVPacket.data[4] & 0x1F) == 7

правда пока это ничего не дает кроме того, что почему то иногда их бывает больше чем 1 раз в секунду

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

это nal_type и это не I frame

вообще не ясны ваши потуги

если цель сделать работу, то лучше в топик работы

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

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

да это понятно про тип, но написал кадр потому, что этот набор байт в ффмпег содержит SPS + PPS + SEI и чего то там еще включая И кадр, P кадр насколько вижу содержит только один NALU блок

) ну кто то может и научит бесплатно, может и нет, цель в поиске решения.

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

почему то иногда их бывает больше чем 1 раз в секунду

с этим разобрался, похоже ффмпег не гарантирует для h264 что в одном AVPacket будет только 1 кадр, поэтому и кажется что иногда бывает чаще

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

не знаю насчет ffmpeg

но GOP может идти чаще чем IDR SPS+PPS SEI можно дропнуть

если указать без B frames то P фремы можно дропать

но для этого надо делать полный реассемблинг уже готового H264

и это какой то треш

если есть ffmpeg который якобы генерит этот поток

то лучший способ это уменьшать битрейт настройками

все остальные решения это анонизм

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

реассемблинг уже готового H264

да, а его читаю с камеры через libav ффмпега, В кадров там нет, поэтому пока (если не появится новых идей) изучаю вопрос определение момента когда уже можно отбросить все не успевшие декодироваться Р кадры в момент прихода И кадра с камеры (но пока не придумал что делать если ГОП 2 секунды и более, т.к. рывок на видео будет еще сильнее в конце)

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

Во всем этом меня больше другой вопрос волнует - КАК мега дешевая камера успевает делать 30фпс для х264 при 1920х1080???????? Должно быть какое то упрощение в кадрах имхо!

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

Я пробовал кодер cedrus264 от ффмпега для nanopi neo core у которого в ТТХ написано аппаратное ускорение - не вникал ещё глубоко почему после софтового декодера так медленно получается, но тем не менее только 12 фпс после него для 2мп

Так что 99% выполняется какое то упрощение

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

любая камера умеющая из себя выдавать уже кодированный h264

так же умеет менять параметры этого h264 через свой интерфейс

будь то usb или другой

почему через него не поменять битрейт или fps

и заниматься изнасилованием уже готового потока h264

вот это мне непонятно

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

давайте решать не решаемую задачу

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

любое выбрасывание и прореживание закончится хренью

выбросьте все P фреймы и посмотрите какой по итогу он получится

наверняка все равно не будет устраивать по битрейту

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

выбираете или меньший размер с камеры

или ищите другую камеру

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

не вникал, но 99% мнение имею, третий год пошел, смари тут спека на h264 https://www.itu.int/rec/T-REC-H.264 она класная, подробная и с рекомендациями как запилить декодер и энкодер, при твоей производительности тебе до конца жизни хватит, ждем новые «интересные» топики по мотивам

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

все равно не будет устраивать по битрейту

Выбрасывал, по битрейту проходит

выбираете или меньший размер с камеры

Самое забавное что меньше это 1.3 МП и это почти столько же как 2 по трафику, тк отличие только по размеру И кадров несущественно

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