ChatCrawlerпоиск по публичному Telegram ПоискКаталог Открыть приложение
P
ветка · 2026-08-01 17:49 UTC

-rw-r--r-- 1 user user 15024000 Aug 1 17:48 /tmp/frame.raw

Ы
< -rw-r--r-- 1 user user 15024000 Aug 1 17:48 /tmp/frame.raw

300 ответов · 2 участника · последний

S
Кадр снят. 15 024 000 байт — это 4000×3000 с выравниванием строки до 5008 байт, ровно как должно быть. Смотрим картинку и пробуем остальное: ./raw10preview /tmp/frame.raw /tmp/preview.ppm 4000 3000 convert /tmp/preview.ppm /tmp/preview.png sed -i 's/^W=4000/W=8000/; s/^H=3000/H=6000/' capture.sh sh capture.sh # полный кадр, 2099 Мбит/с на линию D=$(media-ctl -d /dev/media0 -e "dw9768 12-000c") v4l2-ctl -d "$D" --list-ctrls Три вопроса, на которые это ответит: нормальная ли картинка в бинированном режиме, тянет ли плата полную скорость (60 000 000 байт), и виден ли орган наводки. Если полный кадр не пойдёт — не страшно, у нас есть рабочий 4000×3000 на 30 кадрах, а разница по скорости линии там почти вдвое. 💰 20.73₽ · ⬇️ 868.5k / ⬆️ 700 · opus-5 · max · 13с
Ы
S
ыв полном кадре какие то белые синие белые желтые и тд полоски. а другой хз какой Camera Controls focus_absolute 0x009a090a (int) : min=0 max=1023 step=1 default=0 value=0 flags=has-min-max
Полный кадр, значит, доезжает, но рвётся — полосы это и есть потерянные пакеты. Ровно то, чего я опасался: 2099 Мбит/с на линию для этого приёма многовато. И наводка на месте: focus_absolute от 0 до 1023. Два лечения полного кадра, оба без перезагрузки. Первое — поднять такт самой физики: mainline берёт первую подходящую частоту из списка и на 1049 МГц линка останавливается на 300 МГц, а вендор на этом режиме ставит 384. cd ~/linux-7.2 python3 - <<'EOF' p='drivers/media/platform/qcom/camss/camss.c' s=open(p).read() i=s.index('static const struct camss_subdev_resources csiphy_res_7150[]') j=s.index('\n};', i) blk=s[i:j].replace('{ 300000000, 384000000, 400000000 }','{ 384000000, 400000000, 300000000 }') s=s[:i]+blk+s[j:]; open(p,'w').write(s) print("заменено:", blk.count('384000000, 400000000, 300000000')) EOF make -j8 modules && sudo make modules_install sudo pkill -f wireplumber; sudo pkill -f pipewire sudo modprobe -r qcom_camss && sudo modprobe qcom_camss cd ~/lanekit && sh capture.sh Если полосы останутся — второе: включить вендорную таблицу настроек линий, ту самую с разными значениями на каждую линию, которую я перенёс в драйвер и которую мы так и не проверили на верной раскладке: echo 1 | sudo tee /sys/module/qcom_camss/parameters/vendor_lane_regs sh capture.sh А пока идёт это, посмотри бинированный кадр с наводкой — вот теперь она должна дать резкость: sed -i 's/^W=8000/W=4000/; s/^H=6000/H=3000/' capture.sh D=$(media-ctl -d /dev/media0 -e "dw9768 12-000c") v4l2-ctl -d "$D" --set-ctrl focus_absolute=300 sh capture.sh && ./raw10preview /tmp/frame.raw /tmp/f300.ppm 4000 3000 v4l2-ctl -d "$D" --set-ctrl focus_absolute=600 sh capture.sh && ./raw10preview /tmp/frame.raw /tmp/f600.ppm 4000 3000 💰 22.04₽ · ⬇️ 869.4k / ⬆️ 1.9k · opus-5 · max · 31с
Ы
S
ыsudo modprobe -r qcom_camss && sudo modprobe qcom_camss modprobe: FATAL: Module qcom_camss is in use.
Кто-то держит устройства. Найди и прибей: sudo fuser -k /dev/video0 /dev/video3 /dev/media0 2>/dev/null ls -l /proc/*/fd 2>/dev/null | grep -E "video|media" lsmod | grep "^qcom_camss" Вторая команда покажет, чьи это дескрипторы, третья — счётчик ссылок. После этого: sudo modprobe -r qcom_camss && sudo modprobe qcom_camss Если счётчик ненулевой, а держателя не видно — значит какой-то v4l2-ctl завис в ядре на STREAMON и не умирает; тогда проще перезагрузиться, всё равно модули уже установлены. 💰 21.02₽ · ⬇️ 871.3k / ⬆️ 512 · opus-5 · max · 11с
Ы
stdvectorclaudebotКто-то держит устройства. Найди и прибей: sudo fuser -k /dev/video0 /dev/video3 /dev/media0 2>/dev/null ls -l /proc/*/fd 2>/dev/null | grep -E "video|media" lsmod | grep "^qcom_camss" Вторая команда покажет, чьи это дескрипторы, третья — счётчик ссылок. После этого: sudo modprobe -r qcom_camss &&
qcom-sm7150:~/linux-7.2$ sudo fuser -k /dev/video0 /dev/video3 /dev/media0 2>/dev/null 12083 qcom-sm7150:~/linux-7.2$ ls -l /proc/*/fd 2>/dev/null | grep -E "video|media" lrwx------ 1 user user 64 Aug 1 17:56 26 -> /dev/media0 lrwx------ 1 user user 64 Aug 1 17:56 33 -> /dev/video0 qcom-sm7150:~/linux-7.2$ lsmod | grep "^qcom_camss" qcom_camss 679936 15
S
ыqcom-sm7150:~/linux-7.2$ sudo fuser -k /dev/video0 /dev/video3 /dev/media0 2>/dev/null 12083 qcom-sm7150:~/linux-7.2$ ls -l /proc/*/fd 2>/dev/null | grep -E "video|media" lrwx------ 1 user user 64 Aug 1 17:56 26 -> /dev/media0 lrwx------ 1 user user 64 Aug 1 17
Кто-то из сеанса снова открыл камеру. Найди кто и сделай выгрузку одной строкой, чтобы он не успел вернуться: for p in /proc/[0-9]*; do ls -l $p/fd 2>/dev/null | grep -q "video0\|media0" && echo "$p $(tr '\0' ' ' < $p/cmdline)"; done sudo pkill -9 -f wireplumber; sudo pkill -9 -f pipewire; sudo modprobe -r qcom_camss && sudo modprobe qcom_camss && echo перезагружен Первая команда назовёт виновника (почти наверняка wireplumber, его перезапускает сеанс). Вторая — убивает и сразу выгружает, пока он не поднялся снова. Если снова не выйдет, останови его по-настоящему на время работы: systemctl --user mask wireplumber 2>/dev/null || echo "не systemd, тогда просто перезагрузись" 💰 20.81₽ · ⬇️ 872.1k / ⬆️ 760 · opus-5 · max · 15с
Ы
S
ыполосы пропали. на картинке теперь вместо полос просто шум из разноцветных пикселей
А это, скорее всего, не помехи, а моя же смотрелка. В полном кадре сенсор отдаёт квадро-байеровский узор — цвета идут группами 2×2: R R G G R R G G G G B B G G B B а распаковщик считает, что порядок обычный, и раскладывает цвета по соседним точкам. Получается ровно «шум из разноцветных точек». В бинированном режиме такого нет, потому что там сенсор сам сводит четвёрки в одну точку и отдаёт нормальный байер — потому картинка и вышла обычной. Добавляю узор: gcc -O2 -o raw10preview raw10preview.c -lm ./raw10preview /tmp/frame.raw /tmp/full.ppm 8000 6000 quad convert /tmp/full.ppm /tmp/full.png (если снятый полный кадр уже перезаписан бинированным, сними заново: sed -i 's/^W=4000/W=8000/; s/^H=3000/H=6000/' capture.sh && sh capture.sh) Если с узором quad картинка станет нормальной — значит полный кадр тоже работает, и подъём такта физики до 384 МГц вылечил разрывы. Тогда у нас оба режима: 4000×3000 на тридцати кадрах и 8000×6000 на пятнадцати. А для сравнения посмотри тот же кадр со старым узором: ./raw10preview /tmp/frame.raw /tmp/full_rggb.ppm 8000 6000 rggb Разница между двумя картинками сразу скажет, было ли это моё неверное толкование узора или всё-таки битые данные. 💰 63.51₽ · ⬇️ 2.62M / ⬆️ 2.7k · opus-5 · max · 47с
Ы
S
ычот все равно разноцветный шум
Тогда это не узор, а данные. Посмотрим, что говорит приёмник именно на этом кадре: echo 1 | sudo tee /sys/module/qcom_camss/parameters/debug_rx_irq sed -i 's/^W=4000/W=8000/; s/^H=3000/H=6000/' capture.sh sh capture.sh printf 'rx_irq_seen = 0x%x\n' $(cat /sys/module/qcom_camss/parameters/rx_irq_seen) sudo dmesg | grep -E "csiphy:|receiver:" | tail -4 И контрольный опыт, чтобы отделить режим от общего состояния: sed -i 's/^W=8000/W=4000/; s/^H=6000/H=3000/' capture.sh sh capture.sh ./raw10preview /tmp/frame.raw /tmp/bin.ppm 4000 3000 && convert /tmp/bin.ppm /tmp/bin.png Если бинированный по-прежнему нормальный, а полный — шум, то дело именно в скорости 2099 Мбит/с, и следующий ход у нас уже готов: вендорная таблица настроек линий (vendor_lane_regs=1), где у каждой линии свои подстройки вместо одинаковых. Мы её так и не пробовали на правильной раскладке. 💰 21.04₽ · ⬇️ 875.9k / ⬆️ 1.0k · opus-5 · max · 18с
Ы
stdvectorclaudebotТогда это не узор, а данные. Посмотрим, что говорит приёмник именно на этом кадре: echo 1 | sudo tee /sys/module/qcom_camss/parameters/debug_rx_irq sed -i 's/^W=4000/W=8000/; s/^H=3000/H=6000/' capture.sh sh capture.sh printf 'rx_irq_seen = 0x%x\n' $(cat /sys/module/qcom_camss/parameters/rx_irq_see
qcom-sm7150:~/lanekit$ printf 'rx_irq_seen = 0x%x\n' $(cat /sys/module/qcom_camss/parameters/rx_irq_seen) rx_irq_seen = 0x4800ff qcom-sm7150:~/lanekit$ sudo dmesg | grep -E "csiphy:|receiver:" | tail -4 [ 852.582836] qcom-camss ace0000.camss: receiver: lanes 4, assignment 0x3210, phy 0, cfg0 0x00032103 [ 852.582845] qcom-camss ace0000.camss: csiphy: link 1049400000 Hz, timer 300000000 Hz, settle count 20 [ 852.582852] qcom-camss ace0000.camss: csiphy: lane mask 0xd5 from 4 lanes [ 852.582936] qcom-camss ace0000.camss: csiphy: settle high bytes 00 00 00 00 ff бинированный тож шум ток более мелкий что ли
S
ыqcom-sm7150:~/lanekit$ printf 'rx_irq_seen = 0x%x\n' $(cat /sys/module/qcom_camss/parameters/rx_irq_seen) rx_irq_seen = 0x4800ff qcom-sm7150:~/lanekit$ sudo dmesg | grep -E "csiphy:|receiver:" | tail -4 [ 852.582836] qcom-camss ace0000.camss: receiver: lanes 4, assignment 0x3210, phy 0, cfg0 0x0003
Приём стал чистым: маска 0xd5, раскладка 0x3210, признаки начала и конца передачи на всех четырёх линиях, ошибок целостности нет вовсе — из подозрительного только переполнение очереди нулевой линии и «неотображённый VC/DT» (это отбрасываемые пакеты другого типа, они норма). Значит данные доезжают, а вот выглядят они шумом. Проверим, что в файле — картинка или мусор: od -An -tu1 -j 7500000 -N 48 /tmp/frame.raw od -An -tu1 -j 7500048 -N 48 /tmp/frame.raw У настоящего изображения соседние байты плавные: значения гуляют десятками, а не по всему диапазону. Если там скачки от 0 до 255 подряд — это мусор, и я буду смотреть, что с распаковкой; если плавно — картинка есть, а виновата моя смотрелка. И заодно, чтобы отделить одно от другого, сними испытательную картинку прямо из сенсора: он умеет рисовать цветные полосы сам, и тогда сразу видно, теряются данные в дороге или нет. S=$(media-ctl -d /dev/media0 -e "imx586 12-001a") v4l2-ctl -d "$S" --set-ctrl test_pattern=2 sh capture.sh && ./raw10preview /tmp/frame.raw /tmp/tp.ppm 4000 3000 v4l2-ctl -d "$S" --set-ctrl test_pattern=0 Если полосы получатся ровными — тракт исправен целиком, и разбираться надо будет только с настройками самой матрицы. 💰 22.78₽ · ⬇️ 877.5k / ⬆️ 2.1k · opus-5 · max · 37с
Ы
S
ыod -An -tu1 -j 7500000 -N 48 /tmp/frame.raw 3 16 16 16 16 0 16 16 16 16 0 16 16 16 15 209 16 16 16 15 208 16 16 16 15 208 16 16 16 16 0 16 16 16 16 0 16 16 16 16 4 16 16 16 16 0 15 16 od -An -tu1 -j 7500048 -N 48 /tmp/frame.raw 15 16 55 16
Данные в основном 16, изредка 208, 209, 195 — это уровень чёрного (16 << 2 = 64) с редкими светлыми точками. То есть кадр почти полностью тёмный, а «разноцветный шум» в превью — работа моего же выравнивания белого и гаммы: при однородно чёрном кадре они растягивают шум матрицы во всю яркость и раскрашивают его. Тракт исправен. Наведи на свет и сними ещё раз: sh capture.sh ./raw10preview /tmp/frame.raw /tmp/preview.ppm 4000 3000 Смотри на строку brightest sample N of 1023 — на прошлом удачном кадре было 614. Если сейчас будет меньше сотни, добавь выдержки и усиления: S=$(media-ctl -d /dev/media0 -e "imx586 12-001a") v4l2-ctl -d "$S" --list-ctrls | grep -E "exposure|gain" v4l2-ctl -d "$S" --set-ctrl analogue_gain=400 sh capture.sh && ./raw10preview /tmp/frame.raw /tmp/preview.ppm 4000 3000 А испытательная картинка из сенсора всё равно стоит того, чтобы её снять: она рисуется внутри матрицы и не зависит ни от света, ни от выдержки, так что даёт чистый ответ, доезжает ли всё без потерь. 💰 21.98₽ · ⬇️ 879.9k / ⬆️ 1.0k · opus-5 · max · 19с
Ы
stdvectorclaudebotДанные в основном 16, изредка 208, 209, 195 — это уровень чёрного (16 << 2 = 64) с редкими светлыми точками. То есть кадр почти полностью тёмный, а «разноцветный шум» в превью — работа моего же выравнивания белого и гаммы: при однородно чёрном кадре они растягивают шум матрицы во всю яркость и раскр
~/raw10preview /tmp/frame.raw /tmp/preview.ppm 4000 3000 channel means 67 66 65, gains 1.00 1.00 1.03 written 500x375, brightest sample 75 of 1023 после выдержки и усиления sh capture.sh && ~/raw10preview /tmp/frame.raw /tmp/preview.ppm 4000 3000 < -rw-r--r-- 1 user user 15024000 Aug 1 18:05 /tmp/frame.raw channel means 68 68 65, gains 1.00 1.00 1.04 written 500x375, brightest sample 81 of 1023
S
ы~/raw10preview /tmp/frame.raw /tmp/preview.ppm 4000 3000 channel means 67 66 65, gains 1.00 1.00 1.03 written 500x375, brightest sample 75 of 1023 после выдержки и усиления sh capture.sh && ~/raw10preview /tmp/frame.raw /tmp/preview.ppm 4000 3000 < -rw-r--r-- 1 user user 15024000 Aug
Кадр практически чёрный: среднее по каналам 66–68 при уровне чёрного 64, самая яркая точка 81 из 1023. Усиление ничего не изменило, значит света в объектив не попадает вовсе — либо он чем-то закрыт, либо телефон снова лежит. Но раз уж так, снимем то, что от света не зависит вообще: S=$(media-ctl -d /dev/media0 -e "imx586 12-001a") v4l2-ctl -d "$S" --set-ctrl test_pattern=2 sh capture.sh ~/raw10preview /tmp/frame.raw /tmp/tp.ppm 4000 3000 convert /tmp/tp.ppm /tmp/tp.png v4l2-ctl -d "$S" --set-ctrl test_pattern=0 Матрица нарисует цветные полосы сама, внутри себя. Если они придут ровными — тракт полностью исправен, и разговор дальше только про свет и выдержку. Если полосы будут рваными — значит потери есть, просто на чёрном кадре их не видно. Заодно покажи выдержку и усиление, которые сейчас стоят: v4l2-ctl -d "$S" --list-ctrls 💰 21.51₽ · ⬇️ 881.2k / ⬆️ 1.0k · opus-5 · max · 20с
Ы
S
ыон был с фанариком просто то чо обычно темное
Тогда всё сходится: с фонариком по тёмной сцене 81 из 1023 — это правдоподобно, просто мало света. Тем не менее две вещи стоит увидеть: S=$(media-ctl -d /dev/media0 -e "imx586 12-001a") v4l2-ctl -d "$S" --list-ctrls Хочу проверить, какая выдержка реально выставлена — у нас драйвер её считает от длины кадра, и если там оказалось маленькое число, то темнота объясняется этим, а не сценой. И испытательная картинка, она от света не зависит: v4l2-ctl -d "$S" --set-ctrl test_pattern=2 sh capture.sh && ~/raw10preview /tmp/frame.raw /tmp/tp.ppm 4000 3000 v4l2-ctl -d "$S" --set-ctrl test_pattern=0 Ровные полосы будут означать, что тракт исправен целиком и можно переходить к нормальной съёмке при свете, к наводке и к полному кадру. 💰 21.39₽ · ⬇️ 882.2k / ⬆️ 966 · opus-5 · max · 19с
Ы
stdvectorclaudebotТогда всё сходится: с фонариком по тёмной сцене 81 из 1023 — это правдоподобно, просто мало света. Тем не менее две вещи стоит увидеть: S=$(media-ctl -d /dev/media0 -e "imx586 12-001a") v4l2-ctl -d "$S" --list-ctrls Хочу проверить, какая выдержка реально выставлена — у нас драйвер её считает от д
User Controls exposure 0x00980911 (int) : min=4 max=3006 step=1 default=1214 value=1214 flags=has-min-max horizontal_flip 0x00980914 (bool) : default=0 value=0 flags=modify-layout, has-min-max vertical_flip 0x00980915 (bool) : default=0 value=0 flags=modify-layout, has-min-max Camera Controls camera_orientation 0x009a0922 (menu) : min=0 max=2 default=1 value=1 (Back) flags=read-only, has-min-max camera_sensor_rotation 0x009a0923 (int) : min=180 max=180 step=1 default=180 value=180 flags=read-only, has-min-max Image Source Controls vertical_blanking 0x009e0901 (int) : min=54 max=62535 step=1 default=54 value=54 flags=has-min-max horizontal_blanking 0x009e0902 (int) : min=3872 max=3872 step=1 default=3872 value=3872 flags=read-only, has-min-max analogue_gain 0x009e0903 (int) : min=0 max=960 step=1 default=0 value=400 flags=has-min-max Image Processing Controls link_frequency 0x009f0901 (intmenu): min=0 max=3 default=0 value=0 (572400000 0x221e2180) flags=read-only, has-min-max pixel_rate 0x009f0902 (int64) : min=839520000 max=839520000 step=1 default=839520000 value=839520000 flags=read-only, has-min-max test_pattern 0x009f0903 (menu) : min=0 max=4 default=0 value=0 (Disabled) flags=has-min-max в tp.png тем временем белая желтая бирюзовая зеленая фиолетовая красная синяя черная вертикальные ровные полосы
S
ыUser Controls exposure 0x00980911 (int) : min=4 max=3006 step=1 default=1214 value=1214 flags=has-min-max horizontal_flip 0x00980914 (bool) : default=0 value=0 flags=modify-layout, has-min-max vertical_flip 0x00980915 (bool) : default=
Полосы ровные — белая, жёлтая, бирюзовая, зелёная, фиолетовая, красная, синяя, чёрная. Это стандартный порядок, и то, что цвета вышли правильными, означает сразу три вещи: тракт от матрицы до памяти работает без потерь, распаковка десятибитной упаковки верна, и порядок цветовых точек rggb угадан правильно. То есть камера работает. Тёмный кадр был просто тёмной сценой. Выдержка сейчас 1214 строк из 3006 возможных — это около тринадцати миллисекунд. Для тёмной комнаты мало, поставь на предел: S=$(media-ctl -d /dev/media0 -e "imx586 12-001a") v4l2-ctl -d "$S" --set-ctrl exposure=3000,analogue_gain=600 sh capture.sh && ~/raw10preview /tmp/frame.raw /tmp/p.ppm 4000 3000 И наводка — теперь она должна быть видна на глаз: D=$(media-ctl -d /dev/media0 -e "dw9768 12-000c") for f in 100 300 500 700; do v4l2-ctl -d "$D" --set-ctrl focus_absolute=$f sh capture.sh >/dev/null && ~/raw10preview /tmp/frame.raw /tmp/f$f.ppm 4000 3000 8000 2>&1 | tail -1 done Заодно нашёл у себя мелкий изъян: pixel_rate показывает 839 520 000 — значение полного кадра, хотя режим бинированный. Я создал этот орган с жёстко заданными пределами по первому режиму, и смена значения молча не проходит. На картинку не влияет (camss по нему выбирает частоту VFE и берёт с запасом), но поправить надо — сделаю вместе со следующей правкой. 💰 22.42₽ · ⬇️ 883.9k / ⬆️ 1.6k · opus-5 · max · 29с
Ы
S
ыизображение видно нормально👍 < unknown pattern 8000 < unknown pattern 8000 < unknown pattern 8000 < unknown pattern 8000
Ошибка в моей команде: пятый аргумент — это узор, а не размер блока. Правильно так: D=$(media-ctl -d /dev/media0 -e "dw9768 12-000c") for f in 100 300 500 700 900; do v4l2-ctl -d "$D" --set-ctrl focus_absolute=$f sh capture.sh >/dev/null 2>&1 ~/raw10preview /tmp/frame.raw /tmp/f$f.ppm 4000 3000 rggb 4 echo " ^ положение $f" done Блок 4 даст картинку 1000×750 — на ней резкость видно куда лучше, чем на 500×375. А по существу: основная камера снимает. Работает всё, что мы поднимали последние часы: вендорные таблицы этого телефона, четыре линии D-PHY с правильной раскладкой, приёмник без единой ошибки целостности, распаковка, цвета, испытательная картинка, наводка объектива. Осталось по мелочи: Полный кадр 8000×6000 — данные шли, но на 2099 Мбит/с была рябь; после подъёма такта физики до 384 МГц надо переснять при свете и посмотреть честно. pixel_rate с жёсткими пределами — моя недоработка, поправлю. Телевик — правка clock-lanes у него не подхватилась, там та же болезнь, что мы только что вылечили у основной камеры. И заплаты в camss, которые больше не нужны: ручки lane_base/lane_count и отладочные печати. Их надо убрать, оставив только два настоящих исправления — снятое требование к такту таймера и перестановку частот, — и вот эти два уже можно оформлять наверх. 💰 21.52₽ · ⬇️ 885.6k / ⬆️ 765 · opus-5 · max · 18с
Ы
stdvectorclaudebotОшибка в моей команде: пятый аргумент — это узор, а не размер блока. Правильно так: D=$(media-ctl -d /dev/media0 -e "dw9768 12-000c") for f in 100 300 500 700 900; do v4l2-ctl -d "$D" --set-ctrl focus_absolute=$f sh capture.sh >/dev/null 2>&1 ~/raw10preview /tmp/frame.raw /tmp/f$f.ppm 4
channel means 68 70 66, gains 1.02 1.00 1.06 written 1000x750, brightest sample 96 of 1023 ^ положение 100 channel means 68 70 66, gains 1.02 1.00 1.06 written 1000x750, brightest sample 96 of 1023 ^ положение 300 channel means 68 70 66, gains 1.02 1.00 1.05 written 1000x750, brightest sample 94 of 1023 ^ положение 500 channel means 68 70 66, gains 1.02 1.00 1.05 written 1000x750, brightest sample 88 of 1023 ^ положение 700 channel means 68 70 66, gains 1.02 1.00 1.05 written 1000x750, brightest sample 88 of 1023 ^ положение 900 но смотрю на камеру и не видно чото глазами. мб плохо смотрю
S
ыchannel means 68 70 66, gains 1.02 1.00 1.06 written 1000x750, brightest sample 96 of 1023 ^ положение 100 channel means 68 70 66, gains 1.02 1.00 1.06 written 1000x750, brightest sample 96 of 1023 ^ положение 300 channel means 68 70 66, gains 1.02 1.00 1.05 written 1000x750, brightest sample 94
Понял, почему темно: capture.sh каждый раз заново задаёт формат, а установка формата в драйвере сбрасывает выдержку к значению по умолчанию. То есть мои --set-ctrl exposure=3000 умирали раньше, чем начиналась съёмка. Поправь скрипт, чтобы он ставил выдержку после настройки формата: cd ~/lanekit python3 - <<'EOF' s=open('capture.sh').read() s=s.replace('''V=$(media-ctl -d $M -e msm_vfe0_video0)''', '''S=$(media-ctl -d $M -p | grep -o "imx586 [0-9-]*" | head -1) SD=$(media-ctl -d $M -e "$S") [ -n "$EXPOSURE" ] && v4l2-ctl -d "$SD" --set-ctrl exposure=$EXPOSURE [ -n "$GAIN" ] && v4l2-ctl -d "$SD" --set-ctrl analogue_gain=$GAIN V=$(media-ctl -d $M -e msm_vfe0_video0)''') open('capture.sh','w').write(s) print("готово") EOF Теперь так: EXPOSURE=3000 GAIN=600 sh capture.sh ~/raw10preview /tmp/frame.raw /tmp/p.ppm 4000 3000 rggb 4 Яркость должна заметно подскочить. А насчёт «не видно глазами» — движение линзы в таком приводе меньше миллиметра, разглядеть его почти нельзя. Судить надо по резкости: наведи на что-нибудь освещённое и мелкое с расстояния сантиметров тридцати (лист с текстом, экран другого телефона) и прогони перебор — на снимках разница будет очевидной. 💰 22.12₽ · ⬇️ 886.7k / ⬆️ 1.5k · opus-5 · max · 25с
Ы
stdvectorclaudebotПонял, почему темно: capture.sh каждый раз заново задаёт формат, а установка формата в драйвере сбрасывает выдержку к значению по умолчанию. То есть мои --set-ctrl exposure=3000 умирали раньше, чем начиналась съёмка. Поправь скрипт, чтобы он ставил выдержку после настройки формата: cd ~/lanekit py
EXPOSURE=3000 GAIN=600 sh capture.sh Cannot open device Entity 'imx586 12-001' not found, exiting. Cannot open device Entity 'imx586 12-001' not found, exiting. < -rw-r--r-- 1 user user 15024000 Aug 1 18:13 /tmp/frame.raw ~/raw10preview /tmp/frame.raw /tmp/p.ppm 4000 3000 rggb 4 channel means 68 70 66, gains 1.02 1.00 1.05 written 1000x750, brightest sample 88 of 1023
S
ыEXPOSURE=3000 GAIN=600 sh capture.sh Cannot open device Entity 'imx586 12-001' not found, exiting. Cannot open device Entity 'imx586 12-001' not found, exiting. < -rw-r--r-- 1 user user 15024000 Aug 1 18:13 /tmp/frame.raw ~/raw10preview /tmp/frame.raw /tmp/p.ppm 4000 3000 rggb 4 channel
Опечатка в моём же шаблоне: адрес 12-001a заканчивается буквой, а я разрешил только цифры. Правлю: cd ~/lanekit sed -i 's/imx586 \[0-9-\]\*/imx586 [0-9a-f-]*/' capture.sh sed -i 's/ov8856 \[0-9-\]\*/ov8856 [0-9a-f-]*/' capture-tele.sh EXPOSURE=3000 GAIN=600 sh capture.sh ~/raw10preview /tmp/frame.raw /tmp/p.ppm 4000 3000 rggb 4 Теперь имя подузла найдётся целиком, выдержка встанет после настройки формата, и кадр должен посветлеть примерно втрое. 💰 21.32₽ · ⬇️ 888.4k / ⬆️ 516 · opus-5 · max · 11с
Ы
S
ы~/raw10preview /tmp/frame.raw /tmp/p.ppm 4000 3000 rggb 4 channel means 74 78 69, gains 1.05 1.00 1.12 written 1000x750, brightest sample 120 of 1023 и это в целом на премлемо освященную комнату
Проверим, работают ли органы управления вообще — поставь предел по обоим и сравни: EXPOSURE=3006 GAIN=960 sh capture.sh ~/raw10preview /tmp/frame.raw /tmp/p2.ppm 4000 3000 rggb 4 Усиление 960 по формуле Sony это примерно шестнадцатикратное против нынешнего двух с половиной, так что яркость обязана вырасти в разы. Если вырастет — всё в порядке, просто выдержка у нас пока короткая для комнаты (32 миллисекунды при усилении 2.4 — это действительно немного). Если не вырастет — значит записи не доезжают до матрицы, и я проверю обратным чтением: sh capture.sh > /dev/null 2>&1 & sleep 3 for r in 0202 0203 0204 0205; do printf "0x%s = " $r sudo i2ctransfer -f -y 12 w2@0x1a $(( 0x$r >> 8 )) $(( 0x$r & 0xff )) r1 done wait Там должно быть 0x0202/0x0203 = 0x0B 0xBE при выдержке 3006 и 0x0204/0x0205 = 0x03 0xC0 при усилении 960. 💰 21.52₽ · ⬇️ 889.1k / ⬆️ 1.1k · opus-5 · max · 25с
Ы
S
ы~/raw10preview /tmp/frame.raw /tmp/p2.ppm 4000 3000 rggb 4 channel means 131 157 98, gains 1.20 1.00 1.61 written 1000x750, brightest sample 411 of 1023
Отлично — выдержка и усиление работают и масштабируются как положено: яркость выросла со 120 до 411, средние по каналам 131/157/98 (зелёный сильнее всех, синий слабее — обычная картина для сырого сенсора). Теперь перебор наводки при нормальной яркости. Наведи на что-нибудь с мелкими деталями — лист с текстом, экран — с расстояния сантиметров тридцать: cd ~/lanekit D=$(media-ctl -d /dev/media0 -e "dw9768 12-000c") for f in 0 200 400 600 800 1000; do v4l2-ctl -d "$D" --set-ctrl focus_absolute=$f EXPOSURE=3006 GAIN=960 sh capture.sh >/dev/null 2>&1 ~/raw10preview /tmp/frame.raw /tmp/f$f.ppm 4000 3000 rggb 4 >/dev/null 2>&1 echo "положение $f -> /tmp/f$f.ppm" done Потом посмотри их подряд — резкое положение будет видно сразу. Ноль это бесконечность, тысяча — макро, для тридцати сантиметров ожидаю где-то 400–700. Если разница между снимками окажется нулевой, значит привод не двигается, и я проверю, доходят ли записи до микросхемы: у него всего два регистра, 0x03 и 0x04, прочитаем их напрямую. 💰 21.21₽ · ⬇️ 892.9k / ⬆️ 820 · opus-5 · max · 18с
Ы
S
ызачем? convert работает хорошг
Понял, convert и оставим. Тогда просто скрипт, который снимает перебор, переводит всё в PNG и складывает в архив: cp ~/shots.sh ~/lanekit/ && cd ~/lanekit && sh shots.sh Снимет шесть кадров от бесконечности до макро, каждый переведёт в PNG (1000×750) и упакует в /tmp/shots.tar.gz. По ходу печатает яркость каждого кадра, так что сразу видно, не тёмные ли они. Настройки через переменные: W=8000 H=6000 PAT=quad sh shots.sh # полный кадр POSITIONS="300 400 500 600" sh shots.sh # только интересный участок EXPOSURE=1500 GAIN=300 sh shots.sh # если сцена яркая Архив забирается на компьютер обычным scp — там и посмотришь, какое положение резкое. 💰 64.56₽ · ⬇️ 2.71M / ⬆️ 2.3k · opus-5 · max · 40с
Ы
S
ытебе ж вроде говорили через команду в тексте файлы отправлять есле эт разумно. чо ты опять файлом кидаш
Верно, для полусотни строк это лишнее. Вот тем же куском, вставляется целиком: cat > ~/lanekit/shots.sh <<'SH' #!/bin/sh # Sweep the lens, render every frame to PNG and pack the lot into one archive. W=${W:-4000}; H=${H:-3000}; PAT=${PAT:-rggb}; BLOCK=${BLOCK:-4} EXPOSURE=${EXPOSURE:-3006}; GAIN=${GAIN:-960} POSITIONS=${POSITIONS:-"0 200 400 600 800 1000"} PREVIEW=${PREVIEW:-$HOME/raw10preview} OUT=/tmp/shots command -v convert >/dev/null || { echo "imagemagick is not installed"; exit 1; } [ -x "$PREVIEW" ] || { echo "no raw10preview at $PREVIEW"; exit 1; } rm -rf $OUT; mkdir -p $OUT D=$(media-ctl -d /dev/media0 -e "dw9768 12-000c" 2>/dev/null) sed -i "s/^W=[0-9]*/W=$W/; s/^H=[0-9]*/H=$H/" capture.sh for f in $POSITIONS; do if [ -n "$D" ]; then v4l2-ctl -d "$D" --set-ctrl focus_absolute=$f >/dev/null 2>&1 sleep 1 fi EXPOSURE=$EXPOSURE GAIN=$GAIN sh capture.sh $OUT/f$f.raw >/dev/null 2>&1 sz=$(stat -c %s $OUT/f$f.raw 2>/dev/null || echo 0) [ "$sz" -lt 1000 ] && { echo "position $f: no frame"; continue; } line=$("$PREVIEW" $OUT/f$f.raw $OUT/f$f.ppm $W $H $PAT $BLOCK 2>&1 | tail -1) convert $OUT/f$f.ppm $OUT/f$f.png && rm -f $OUT/f$f.ppm $OUT/f$f.raw echo "position $f: $line" done tar czf /tmp/shots.tar.gz -C /tmp shots ls -l /tmp/shots.tar.gz SH cd ~/lanekit && sh shots.sh Дальше по вкусу: W=8000 H=6000 PAT=quad sh shots.sh # полный кадр POSITIONS="300 400 500 600" sh shots.sh # только интересный участок 💰 21.70₽ · ⬇️ 903.6k / ⬆️ 1.0k · opus-5 · max · 13с
Ы
S
ына f600 текст видно хорошо. работаед! картинка вроде правильная ток некрасивая какая то
Значит камера работает целиком: наводка на 600 даёт резкий текст, выдержка и усиление слушаются, оба режима снимают. «Некрасиво» — это ожидаемо, и вот почему. Сейчас картинка получается так: вычитается уровень чёрного, каналы уравниваются по среднему (серый мир) и накладывается гамма. Всё, чего в ней нет: Матрица цветокоррекции. Сырые R, G, B сенсора — это не sRGB, у них другие спектральные кривые. Без пересчёта цвета выходят блёклыми и с уводом в зелень. Коррекция затемнения по краям. У широкоугольного объектива края темнее середины процентов на тридцать, это лечится картой поправок. Настоящий баланс белого. Серый мир — грубая оценка: если в кадре преобладает один цвет, он же и уедет. Приличная демозаика. У меня усреднение блоками, поэтому теряется половина разрешения. Всё это — работа libcamera, а не ядра: у неё есть программный ISP, который делает и то, и другое, и третье, и ему нужен файл настройки под этот сенсор. Мы к этому уже подготовились: патч со свойствами сенсоров лежит готовый. Дальше по порядку могу заняться любым из: • проверить полный кадр при свете (после подъёма такта физики он должен идти чисто); • вылечить телевик — там та же болезнь с clock-lanes, что мы победили на основной; • прибрать заплаты в camss (ручки и печати), оставив два настоящих исправления, и оформить их наверх; • завести libcamera и получить нормальную картинку с автоэкспозицией. Что берём? 💰 21.96₽ · ⬇️ 904.7k / ⬆️ 1.0k · opus-5 · max · 24с
Ы
S
ыа телевик это ваще про чо и зачем давай ты пока весь код прибереш и нормально оформиш?
Телевик — это вторая задняя камера, восьмимегапиксельный OV8856 с двукратным приближением (в Mi 9T их три: широкая, которую мы подняли, телевик и сверхширокая). Он висит на CSIPHY3, драйвер у него уже в mainline, а в дереве этого форка он объявлен — то есть работы там на один вечер, и болезнь ровно та же, которую мы только что вылечили: clock-lanes конфликтует с линиями данных. Ценность — оптическое приближение без потери качества. Но раз просишь — прибираю код. Сначала мелкий изъян в драйвере, про который я говорил: Теперь уборка в camss. Соберу «грязную» копию из тех же заплат, что стоят у тебя, и напишу очистку, проверив её сравнением с исходником: Почти чисто. Осталась пустая строка, которую я лишний раз съел, и удалённый отладочный printk форка (его как раз и стоит оставить удалённым). Правлю: Теперь собираю набор начисто. Правлю дерево (то, что мы чинили руками на телефоне) и пишу установщик: Прибрано. Главное — отладочные леса и настоящие исправления теперь разделены. camss-clean.sh снимает с дерева всё, что мы наставили по ходу: ручки lane_base, lane_count, settle_cnt_override, clear_settle_high, vendor_lane_regs, накопитель прерываний приёмника с чтением его счётчиков, все отладочные печати и вендорную таблицу настроек линий. Проверено сравнением: после очистки camss-csiphy-3ph-1-0.c побайтово совпадает с исходником, в остальных остаются только нужные правки. camss-fixes.sh оставляет ровно два изменения: Снятое требование к такту таймера CSIPHY — он тактует только счётчик времени установления и данных не несёт, а правило держало его на уровне байтового такта; на этом чипе его источник выше 300 МГц не поднимается по устройству, отсюда и вечное «Pixel clock is too high». Порядок частот в таблицах для 7150 — драйвер берёт первую подходящую, а список начинался с самой низкой, поэтому физика работала на 300 МГц там, где вендор ставит 384. Плюс восстановленное соответствие имён и частот у CSIPHY3, где они разъезжались и оставляли такт с единственным нулём — из-за этого телевик и не снимал никогда. Оба скрипта идемпотентные, и я проверил, что после них дерево совпадает с тем состоянием, на котором кадр реально снялся. В README записано всё, что стоило записать: откуда взяты таблицы и чем проверено их извлечение, обе правки camss с обоснованием, и та ловушка с clock-lanes, которая стоила нам большей части дня — одна строка в логе, сказанная ровно один раз. Отладочные заплаты не выброшены, а сложены в debug/ — если понадобится снова смотреть, что происходит на шине, они под рукой. 💰 295₽ · ⬇️ 11.91M / ⬆️ 16.4k · opus-5 · max · 261с
Ы
S
ыа таки зач телевик нужен то. если это быстро то закинь исправление кода с ним. тестировать потом будем. ну и давай libcamera делодь
Телевик — это оптическое приближение вдвое: восьмимегапиксельный OV8856 со своим объективом, снимает то же самое, но крупнее, без цифрового растягивания. И исправление для него уже в отправленном наборе: в дереве стоит &csiphy3_ep { /delete-property/ clock-lanes; data-lanes = <0 1>; }; а восстановленное соответствие тактов у CSIPHY3 — в camss-fixes.sh. Для проверки там же лежит capture-tele.sh, который ведёт его через CSIPHY3 → CSID1 → VFE1 и снимает 1640×1232. Теперь libcamera. Сначала посмотрим, что вообще есть: apk list -I 2>/dev/null | grep -i libcamera which cam qcam libcamera-hello 2>/dev/null Если пусто — ставим: sudo apk add libcamera libcamera-tools И пробуем перечислить камеры (перед этим убрать pipewire, чтобы не мешался): sudo pkill -f wireplumber; sudo pkill -f pipewire cam -l Ожидаю увидеть одну камеру с именем вроде \_SB_.PCI0... или путь媒体-устройства. Если она появится — сразу снимем через неё: cam -c 1 --capture=2 --file=/tmp/lc_#.raw -s width=4000,height=3000 Тогда libcamera сама настроит конвейер, а её программный ISP разложит байер в картинку с автоматической экспозицией и балансом белого — то есть ровно то, чего не хватало нашим сырым кадрам. Если cam -l ничего не покажет или ругнётся — присылай вывод целиком, там обычно прямо написано, какого узла или свойства ей не хватило. 💰 22.84₽ · ⬇️ 925.2k / ⬆️ 1.5k · opus-5 · max · 28с
Ы
stdvectorclaudebotТелевик — это оптическое приближение вдвое: восьмимегапиксельный OV8856 со своим объективом, снимает то же самое, но крупнее, без цифрового растягивания. И исправление для него уже в отправленном наборе: в дереве стоит &csiphy3_ep { /delete-property/ clock-lanes; data-lanes = <0 1>; }; а восстан
sh tmp18.sh [0:43:53.440068332] [16937] INFO Camera camera_manager.cpp:340 libcamera v0.7.1 [0:43:53.492595534] [16938] ERROR V4L2 v4l2_subdevice.cpp:1192 'ov8856 13-0036': Unable to get rectangle 2 on pad 0/0: Not a tty [0:43:53.492656680] [16938] WARN CameraSensor camera_sensor_legacy.cpp:402 'ov8856 13-0036': The PixelArraySize property has been defaulted to 1640x1232 [0:43:53.492670014] [16938] ERROR V4L2 v4l2_subdevice.cpp:1192 'ov8856 13-0036': Unable to get rectangle 1 on pad 0/0: Not a tty [0:43:53.492679545] [16938] WARN CameraSensor camera_sensor_legacy.cpp:413 'ov8856 13-0036': The PixelArrayActiveAreas property has been defaulted to (0, 0)/1640x1232 [0:43:53.492692149] [16938] ERROR V4L2 v4l2_subdevice.cpp:1192 'ov8856 13-0036': Unable to get rectangle 0 on pad 0/0: Not a tty [0:43:53.492700951] [16938] WARN CameraSensor camera_sensor_legacy.cpp:421 'ov8856 13-0036': Failed to retrieve the sensor crop rectangle [0:43:53.492709545] [16938] WARN CameraSensor camera_sensor_legacy.cpp:427 'ov8856 13-0036': The sensor kernel driver needs to be fixed [0:43:53.492717253] [16938] WARN CameraSensor camera_sensor_legacy.cpp:429 'ov8856 13-0036': See Documentation/sensor_driver_requirements.rst in the libcamera sources for more information [0:43:53.492986474] [16938] WARN CameraSensorProperties camera_sensor_properties.cpp:538 No static properties available for 'ov8856' [0:43:53.493025068] [16938] WARN CameraSensorProperties camera_sensor_properties.cpp:540 Please consider updating the camera sensor properties database [0:43:53.493042360] [16938] WARN CameraSensor camera_sensor_legacy.cpp:502 'ov8856 13-0036': No sensor delays found in static properties. Assuming unverified defaults. [0:43:53.493543977] [16938] WARN CameraSensorProperties camera_sensor_properties.cpp:538 No static properties available for 'imx586' [0:43:53.493583405] [16938] WARN CameraSensorProperties camera_sensor_properties.cpp:540 Please consider updating the camera sensor properties database [0:43:54.005469719] [16938] WARN CameraSensor camera_sensor_legacy.cpp:502 'imx586 12-001a': No sensor delays found in static properties. Assuming unverified defaults. [0:43:54.016475882] [16938] WARN IPAProxy ipa_proxy.cpp:196 Configuration file 'ov8856.yaml' not found for IPA module 'simple', falling back to '/usr/share/libcamera/ipa/simple/uncalibrated.yaml' [0:43:54.016665570] [16938] ERROR V4L2 v4l2_subdevice.cpp:1192 'ov8856 13-0036': Unable to get rectangle 0 on pad 0/0: Not a tty [0:43:54.016725883] [16938] WARN CameraSensor camera_sensor_legacy.cpp:881 'ov8856 13-0036': The analogue crop rectangle has been defaulted to the active area size [0:43:54.016887082] [16938] WARN IPASoft soft_simple.cpp:104 IPASoft: Failed to create camera sensor helper for ov8856 [0:43:54.021853780] [16938] INFO Camera camera_manager.cpp:223 Adding camera '/base/soc@0/cci@ac4a000/i2c-bus@1/camera@36' for pipeline handler simple [0:43:54.025210363] [16938] WARN IPAProxy ipa_proxy.cpp:196 Configuration file 'imx586.yaml' not found for IPA module 'simple', falling back to '/usr/share/libcamera/ipa/simple/uncalibrated.yaml' [0:43:54.025455104] [16938] WARN IPASoft soft_simple.cpp:104 IPASoft: Failed to create camera sensor helper for imx586 [0:43:54.033133329] [16938] INFO Camera camera_manager.cpp:223 Adding camera '/base/soc@0/cci@ac4a000/i2c-bus@0/camera@1a' for pipeline handler simple Available cameras: 1: Internal back camera (/base/soc@0/cci@ac4a000/i2c-bus@1/camera@36) 2: Internal back camera (/base/soc@0/cci@ac4a000/i2c-bus@0/camera@1a)
S
ыsh tmp18.sh [0:43:53.440068332] [16937] INFO Camera camera_manager.cpp:340 libcamera v0.7.1 [0:43:53.492595534] [16938] ERROR V4L2 v4l2_subdevice.cpp:1192 'ov8856 13-0036': Unable to get rectangle 2 on pad 0/0: Not a tty [0:43:53.492656680] [16938] WARN CameraSensor camera_sensor_legacy.cpp:402 '
Обе камеры видны libcamera 0.7.1 — и широкая, и телевик, обе через обработчик simple. Это большой шаг: значит граф, форматы и подузлы описаны так, как libcamera ожидает. Сразу пробуем снять через неё — программный ISP разложит байер сам: cam -c 2 --capture=2 -s width=1920,height=1080,pixelformat=RGB888 --file=/tmp/lc_#.rgb ls -l /tmp/lc_*.rgb Камера номер 2 — это наша широкая (camera@1a). Если пойдёт, получим уже готовые кадры с автоматической экспозицией и балансом белого. По жалобам в выводе — три штуки, и все чинятся: «No static properties available for imx586» — ровно то, что закрывает наш патч, только я в нём назвал запись imx582, а libcamera опознаёт сенсор по имени сущности, а оно у нас imx586. Поправлю на оба имени. «Failed to create camera sensor helper for imx586» — libcamera не знает, как пересчитывать код усиления в разы. У Sony это усиление = 1024 / (1024 − код), и в libcamera для такого есть готовая форма; допишу. «Unable to get rectangle … Not a tty» — это про телевик: драйвер ov8856 не отвечает на запрос границ обрезки. У нашего imx586 таких жалоб нет, потому что мы это как раз добавили. Для телевика поправим позже, оно не мешает. Готовлю оба патча, а ты пока сними — интересно, что выйдет с автоматикой. 💰 24.70₽ · ⬇️ 928.5k / ⬆️ 2.1k · opus-5 · max · 42с
Ы
S
ыls -l /tmp/lc_*.rgb -rw-r--r-- 1 user user 8294400 Aug 1 18:32 /tmp/lc_cam0-stream0-000000.rgb -rw-r--r-- 1 user user 8294400 Aug 1 18:32 /tmp/lc_cam0-stream0-000001.rgb но пока он объективом вниз лежит. давай пока патчи применим
Кадры получились: 8 294 400 байт это 1920×1080 по четыре байта на точку — программный ISP отработал, картинка уже разложена и обработана. Готовлю патчи. Смотрю, как в libcamera описывают пересчёт усиления: Патч закрывает всё три жалобы разом. Свойства сенсоров — записи под оба имени Sony (imx582 и imx586, потому что libcamera опознаёт по имени сущности, а оно идёт от совместимости в дереве) и под ov8856. Размер точки 0.8 мкм у широкой и 1.12 у телевика — без этого libcamera считает точку метровой и врёт про поле зрения. Пересчёт усиления — то, из-за чего ISP не мог управлять яркостью: gain_ = AnalogueGainLinear{ 0, 1024, -1, 1024 }; /* усиление = 1024 / (1024 − код) */ blackLevel_ = 4096; /* 64 при десяти битах */ Это стандартная формула семейства, у imx219 в libcamera та же с числом 256, у imx258 с 512. Нашему коду усиления 960 соответствует шестнадцатикратное — сходится с пределом органа управления в драйвере. Чтобы это заработало, нужна пересборка libcamera из исходников: sudo apk add git meson ninja g++ pkgconf openssl-dev gnutls-dev python3-dev py3-yaml py3-jinja2 py3-ply git clone --depth 1 https://git.libcamera.org/libcamera/libcamera.git cd libcamera && patch -p1 < ~/libcamera-mi9t.patch meson setup build -Dpipelines=simple -Dipas=simple -Dcam=enabled -Dqcam=disabled -Ddocumentation=disabled ninja -C build && sudo ninja -C build install На восьми ядрах это минут пятнадцать. Без пересборки камера всё равно работает — предупреждения не смертельные, просто автоматика экспозиции будет грубее. А пока подними телефон и сними через libcamera при свете: cam -c 2 --capture=4 -s width=1920,height=1080,pixelformat=RGB888 --file=/tmp/lc_#.rgb convert -size 1920x1080 -depth 8 bgra:/tmp/lc_cam0-stream0-000003.rgb /tmp/lc.png Четыре кадра нужны, чтобы автоматика успела подобрать выдержку — первый обычно тёмный. 💰 158₽ · ⬇️ 6.54M / ⬆️ 5.6k · opus-5 · max · 98с
Ы
stdvectorclaudebotКадры получились: 8 294 400 байт это 1920×1080 по четыре байта на точку — программный ISP отработал, картинка уже разложена и обработана. Готовлю патчи. Смотрю, как в libcamera описывают пересчёт усиления: Патч закрывает всё три жалобы разом. Свойства сенсоров — записи под оба имени Sony (imx582
patch -p1 < ~/libcamera-mi9t.patch patching file src/libcamera/sensor/camera_sensor_properties.cpp Hunk #1 FAILED at 325. Hunk #2 FAILED at 495. 2 out of 2 hunks FAILED -- saving rejects to file src/libcamera/sensor/camera_sensor_properties.cpp.rej patching file src/ipa/libipa/camera_sensor_helper.cpp patch: **** malformed patch at line 99: @@ -830,6 +844,17 @@
S
ыpatch -p1 < ~/libcamera-mi9t.patch patching file src/libcamera/sensor/camera_sensor_properties.cpp Hunk #1 FAILED at 325. Hunk #2 FAILED at 495. 2 out of 2 hunks FAILED -- saving rejects to file src/libcamera/sensor/camera_sensor_properties.cpp.rej patching file src/ipa/libipa/camera_sensor_helper.c
Мой заголовок куска посчитан неверно (я его правил руками при переносе в сообщение), да и номера строк у тебя другие — libcamera с тех пор поменялась. Давай без patch, скриптом по содержимому: cd ~/libcamera && python3 - <<'EOF' import re, sys, os props = 'src/libcamera/sensor/camera_sensor_properties.cpp' helper = 'src/ipa/libipa/camera_sensor_helper.cpp' sony = """\t\t{ "%s", { \t\t\t.unitCellSize = { 800, 800 }, \t\t\t.testPatternModes = { \t\t\t\t{ controls::draft::TestPatternModeOff, 0 }, \t\t\t\t{ controls::draft::TestPatternModeSolidColor, 1 }, \t\t\t\t{ controls::draft::TestPatternModeColorBars, 2 }, \t\t\t\t{ controls::draft::TestPatternModeColorBarsFadeToGray, 3 }, \t\t\t\t{ controls::draft::TestPatternModePn9, 4 }, \t\t\t}, \t\t\t.sensorDelays = { \t\t\t\t.exposureDelay = 2, \t\t\t\t.gainDelay = 2, \t\t\t\t.vblankDelay = 3, \t\t\t\t.hblankDelay = 3 \t\t\t}, \t\t} }, """ omni = """\t\t{ "ov8856", { \t\t\t.unitCellSize = { 1120, 1120 }, \t\t\t.testPatternModes = { \t\t\t\t{ controls::draft::TestPatternModeOff, 0 }, \t\t\t\t{ controls::draft::TestPatternModeColorBars, 1 }, \t\t\t\t{ controls::draft::TestPatternModeColorBarsFadeToGray, 2 }, \t\t\t}, \t\t\t.sensorDelays = { }, \t\t} }, """ s = open(props).read() if '"imx586"' in s: print("свойства уже добавлены") else: m = re.search(r'^\t\t\{ "ov', s, re.M) if not m: sys.exit("не нашёл, куда вставлять свойства") add = (sony % "imx582") + (sony % "imx586") + omni s = s[:m.start()] + add + s[m.start():] open(props, 'w').write(s) print("свойства добавлены: imx582, imx586, ov8856") s = open(helper).read() if 'CameraSensorHelperImx586' in s: print("пересчёт усиления уже добавлен") else: add = """class CameraSensorHelperImx586 : public CameraSensorHelper { public: \tCameraSensorHelperImx586() \t{ \t\t/* From the register tables: black level 64 at 10 bits. */ \t\tblackLevel_ = 4096; \t\tgain_ = AnalogueGainLinear{ 0, 1024, -1, 1024 }; \t} }; REGISTER_CAMERA_SENSOR_HELPER("imx582", CameraSensorHelperImx586) REGISTER_CAMERA_SENSOR_HELPER("imx586", CameraSensorHelperImx586) class CameraSensorHelperOv8856 : public CameraSensorHelper { public: \tCameraSensorHelperOv8856() \t{ \t\t/* Same 1/128 step as its sibling. */ \t\tgain_ = AnalogueGainLinear{ 1, 0, 0, 128 }; \t} }; REGISTER_CAMERA_SENSOR_HELPER("ov8856", CameraSensorHelperOv8856) """ i = s.rindex('} /* namespace */') s = s[:i] + add + s[i:] open(helper, 'w').write(s) print("пересчёт усиления добавлен") EOF Классы вставляются в конец безымянного пространства имён, поэтому порядок не важен, а записи свойств — перед первым сенсором OmniVision, где им и место по алфавиту. Скрипт можно гонять повторно, второй раз он ничего не сделает. Потом убери мусор от неудачной попытки и собирай: rm -f src/libcamera/sensor/camera_sensor_properties.cpp.rej git diff --stat meson setup build -Dpipelines=simple -Dipas=simple -Dcam=enabled -Dqcam=disabled -Ddocumentation=disabled ninja -C build 💰 24.87₽ · ⬇️ 949.4k / ⬆️ 2.9k · opus-5 · max · 38с
Ы
S
ысвойства уже добавлены Traceback (most recent call last): File "<stdin>", line 74, in <module> ValueError: substring not found
Две помарки в моём скрипте. Проверка на «уже добавлено» слишком широкая — строка imx586 могла попасться где угодно, — а закрывающий комментарий пространства имён в их версии называется иначе. Вот исправленный, с показом того, что нашлось: cd ~/libcamera && python3 - <<'EOF' import re, sys props = 'src/libcamera/sensor/camera_sensor_properties.cpp' helper = 'src/ipa/libipa/camera_sensor_helper.cpp' s = open(props).read() print("что уже есть в свойствах:", re.findall(r'\{ "(imx58\d|ov885\d)", \{', s) or "ничего из наших") sony = """\t\t{ "%s", { \t\t\t.unitCellSize = { 800, 800 }, \t\t\t.testPatternModes = { \t\t\t\t{ controls::draft::TestPatternModeOff, 0 }, \t\t\t\t{ controls::draft::TestPatternModeSolidColor, 1 }, \t\t\t\t{ controls::draft::TestPatternModeColorBars, 2 }, \t\t\t\t{ controls::draft::TestPatternModeColorBarsFadeToGray, 3 }, \t\t\t\t{ controls::draft::TestPatternModePn9, 4 }, \t\t\t}, \t\t\t.sensorDelays = { \t\t\t\t.exposureDelay = 2, \t\t\t\t.gainDelay = 2, \t\t\t\t.vblankDelay = 3, \t\t\t\t.hblankDelay = 3 \t\t\t}, \t\t} }, """ omni = """\t\t{ "ov8856", { \t\t\t.unitCellSize = { 1120, 1120 }, \t\t\t.testPatternModes = { \t\t\t\t{ controls::draft::TestPatternModeOff, 0 }, \t\t\t\t{ controls::draft::TestPatternModeColorBars, 1 }, \t\t\t\t{ controls::draft::TestPatternModeColorBarsFadeToGray, 2 }, \t\t\t}, \t\t\t.sensorDelays = { }, \t\t} }, """ add = "".join(t for t, n in ((sony % "imx582", "imx582"), (sony % "imx586", "imx586"), (omni, "ov8856")) if ('{ "%s", {' % n) not in s) if not add: print("свойства: всё на месте") else: m = re.search(r'^\t\t\{ "ov', s, re.M) s = s[:m.start()] + add + s[m.start():] open(props, 'w').write(s) print("свойства дописаны") s = open(helper).read() if 'CameraSensorHelperImx586' in s: print("пересчёт усиления: уже на месте") else: last = list(re.finditer(r'^REGISTER_CAMERA_SENSOR_HELPER\([^\n]*\)\n', s, re.M))[-1] add = """ class CameraSensorHelperImx586 : public CameraSensorHelper { public: \tCameraSensorHelperImx586() \t{ \t\t/* From the register tables: black level 64 at 10 bits. */ \t\tblackLevel_ = 4096; \t\tgain_ = AnalogueGainLinear{ 0, 1024, -1, 1024 }; \t} }; REGISTER_CAMERA_SENSOR_HELPER("imx582", CameraSensorHelperImx586) REGISTER_CAMERA_SENSOR_HELPER("imx586", CameraSensorHelperImx586) class CameraSensorHelperOv8856 : public CameraSensorHelper { public: \tCameraSensorHelperOv8856() \t{ \t\t/* Same 1/128 step as its sibling. */ \t\tgain_ = AnalogueGainLinear{ 1, 0, 0, 128 }; \t} }; REGISTER_CAMERA_SENSOR_HELPER("ov8856", CameraSensorHelperOv8856) """ s = s[:last.end()] + add + s[last.end():] open(helper, 'w').write(s) print("пересчёт усиления дописан после последнего зарегистрированного сенсора") EOF git diff --stat Первая строка вывода покажет, что там уже было — если окажется, что imx586 в свойствах действительно есть, значит его добавили в libcamera без нас, и наша часть сведётся к пересчёту усиления. 💰 25.09₽ · ⬇️ 952.4k / ⬆️ 2.1k · opus-5 · max · 27с
Ы
S
ыот теперь прошел патч
Тогда собираем: cd ~/libcamera meson setup build -Dpipelines=simple -Dipas=simple -Dcam=enabled -Dqcam=disabled -Ddocumentation=disabled ninja -C build sudo ninja -C build install sudo ldconfig 2>/dev/null || true Установится в /usr/local, поверх пакетной не полезет — то есть cam из /usr/local/bin будет пользоваться новой библиотекой, а всё остальное в системе останется на старой. Для проверки это то, что нужно. Потом: sudo pkill -f wireplumber; sudo pkill -f pipewire /usr/local/bin/cam -l 2>&1 | grep -iE "warn|error|Adding camera" Из вывода должны пропасть три строки: про отсутствующие свойства imx586, про отсутствующие задержки сенсора и про то, что не удалось создать пересчёт усиления. Останется, скорее всего, только жалоба на отсутствующий файл настройки imx586.yaml — это уже про цвет, им займёмся отдельно. И сразу снимок при свете, теперь автоматика должна работать осмысленно: /usr/local/bin/cam -c 2 --capture=6 -s width=1920,height=1080,pixelformat=RGB888 --file=/tmp/lc_#.rgb convert -size 1920x1080 -depth 8 bgra:/tmp/lc_cam0-stream0-000005.rgb /tmp/lc.png Шесть кадров — чтобы выдержка успела сойтись; последний и смотрим. 💰 23.34₽ · ⬇️ 954.5k / ⬆️ 836 · opus-5 · max · 16с
Ы
S
ыsrc/apps/meson.build:8:11: ERROR: Dependency "libevent_pthreads" not found (tried pkg-config) A full log can be found at /home/user/libcamera/build/meson-logs/meson-log.txt
cam собирается поверх libevent. Ставим и повторяем: sudo apk add libevent-dev cd ~/libcamera && meson setup --wipe build -Dpipelines=simple -Dipas=simple -Dcam=enabled -Dqcam=disabled -Ddocumentation=disabled ninja -C build Если ещё чего-то не хватит — оно назовёт зависимость так же понятно, присылай строку. Или можно вовсе не собирать приложение, нам ведь нужна библиотека: meson setup --wipe build -Dpipelines=simple -Dipas=simple -Dcam=disabled -Dqcam=disabled -Ddocumentation=disabled ninja -C build && sudo ninja -C build install а проверять пакетным cam, подсунув ему свежую библиотеку: LD_LIBRARY_PATH=/usr/local/lib cam -l Второй путь быстрее, потому что не тянет ни libevent, ни остальную обвязку приложения. 💰 22.47₽ · ⬇️ 957.7k / ⬆️ 702 · opus-5 · max · 14с
Ы
stdvectorclaudebotcam собирается поверх libevent. Ставим и повторяем: sudo apk add libevent-dev cd ~/libcamera && meson setup --wipe build -Dpipelines=simple -Dipas=simple -Dcam=enabled -Dqcam=disabled -Ddocumentation=disabled ninja -C build Если ещё чего-то не хватит — оно назовёт зависимость так же понятно, присы
../src/ipa/libipa/camera_sensor_helper.h:91:42: error: redefinition of 'libcamera::ipa::CameraSensorHelperFactory<libcamera::ipa::CameraSensorHelperImx586> libcamera::ipa::global_CameraSensorHelperImx586Factory' 91 | static CameraSensorHelperFactory<helper> global_##helper##Factory(name); | ^~~~~ ../src/ipa/libipa/camera_sensor_helper.cpp:901:1: note: in expansion of macro 'REGISTER_CAMERA_SENSOR_HELPER' 901 | REGISTER_CAMERA_SENSOR_HELPER("imx586", CameraSensorHelperImx586) | ^~~~~~~~~~~~~~~~~~~~~~~~~ ../src/ipa/libipa/camera_sensor_helper.h:91:42: note: 'libcamera::ipa::CameraSensorHelperFactory<libcamera::ipa::CameraSensorHelperImx586> libcamera::ipa::global_CameraSensorHelperImx586Factory' previously declared here 91 | static CameraSensorHelperFactory<helper> global_##helper##Factory(name); | ^~~ ../src/ipa/libipa/camera_sensor_helper.cpp:900:1: note: in expansion of macro 'REGISTER_CAMERA_SENSOR_HELPER' 900 | REGISTER_CAMERA_SENSOR_HELPER("imx582", CameraSensorHelperImx586) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ ninja: subcommand failed
S
ы../src/ipa/libipa/camera_sensor_helper.h:91:42: error: redefinition of 'libcamera::ipa::CameraSensorHelperFactory<libcamera::ipa::CameraSensorHelperImx586> libcamera::ipa::global_CameraSensorHelperImx586Factory' 91 | static CameraSensorHelperFactory<helper> global_##helper##Factory(name); |
Макрос создаёт глобальную переменную с именем от класса, поэтому дважды один класс зарегистрировать нельзя. Нужен второй, наследник: cd ~/libcamera && python3 - <<'EOF' p='src/ipa/libipa/camera_sensor_helper.cpp' s=open(p).read() s=s.replace('''REGISTER_CAMERA_SENSOR_HELPER("imx582", CameraSensorHelperImx586) REGISTER_CAMERA_SENSOR_HELPER("imx586", CameraSensorHelperImx586)''', '''REGISTER_CAMERA_SENSOR_HELPER("imx586", CameraSensorHelperImx586) /* The same part, under the name the other compatible gives its entity. */ class CameraSensorHelperImx582 : public CameraSensorHelperImx586 { }; REGISTER_CAMERA_SENSOR_HELPER("imx582", CameraSensorHelperImx582)''') open(p,'w').write(s) print("исправлено") EOF ninja -C build Заодно и по смыслу честнее: два имени — два класса, второй просто наследует первый без изменений. 💰 23.28₽ · ⬇️ 971.2k / ⬆️ 743 · opus-5 · max · 12с
Ы
stdvectorclaudebotcam собирается поверх libevent. Ставим и повторяем: sudo apk add libevent-dev cd ~/libcamera && meson setup --wipe build -Dpipelines=simple -Dipas=simple -Dcam=enabled -Dqcam=disabled -Ddocumentation=disabled ninja -C build Если ещё чего-то не хватит — оно назовёт зависимость так же понятно, присы
LD_LIBRARY_PATH=/usr/local/lib /usr/local/bin/cam -l [1:14:30.339139896] [19899] INFO Camera camera_manager.cpp:340 libcamera v0.0.0+1-244572db-dirty (2026-08-01T19:01:32GMT) [1:14:30.344918075] [19900] ERROR V4L2 v4l2_subdevice.cpp:1192 'ov8856 13-0036': Unable to get rectangle 2 on pad 0/0: Not a tty [1:14:30.344997815] [19900] WARN CameraSensor camera_sensor_legacy.cpp:402 'ov8856 13-0036': The PixelArraySize property has been defaulted to 1640x1232 [1:14:30.345040836] [19900] ERROR V4L2 v4l2_subdevice.cpp:1192 'ov8856 13-0036': Unable to get rectangle 1 on pad 0/0: Not a tty [1:14:30.345059950] [19900] WARN CameraSensor camera_sensor_legacy.cpp:413 'ov8856 13-0036': The PixelArrayActiveAreas property has been defaulted to (0, 0)/1640x1232 [1:14:30.345080263] [19900] ERROR V4L2 v4l2_subdevice.cpp:1192 'ov8856 13-0036': Unable to get rectangle 0 on pad 0/0: Not a tty [1:14:30.345103075] [19900] WARN CameraSensor camera_sensor_legacy.cpp:421 'ov8856 13-0036': Failed to retrieve the sensor crop rectangle [1:14:30.345119690] [19900] WARN CameraSensor camera_sensor_legacy.cpp:427 'ov8856 13-0036': The sensor kernel driver needs to be fixed [1:14:30.345137242] [19900] WARN CameraSensor camera_sensor_legacy.cpp:429 'ov8856 13-0036': See Documentation/sensor_driver_requirements.rst in the libcamera sources for more information [1:14:30.345991617] [19900] WARN CameraSensor camera_sensor_legacy.cpp:502 'ov8856 13-0036': No sensor delays found in static properties. Assuming unverified defaults. [1:14:30.891269282] [19900] WARN IPAProxy ipa_proxy.cpp:196 Configuration file 'ov8856.yaml' not found for IPA module 'simple', falling back to '/usr/local/share/libcamera/ipa/simple/uncalibrated.yaml' [1:14:30.891483345] [19900] ERROR V4L2 v4l2_subdevice.cpp:1192 'ov8856 13-0036': Unable to get rectangle 0 on pad 0/0: Not a tty [1:14:30.891564855] [19900] WARN CameraSensor camera_sensor_legacy.cpp:881 'ov8856 13-0036': The analogue crop rectangle has been defaulted to the active area size [1:14:30.934827685] [19901] INFO IPAProxySoftWorker soft_ipa_proxy_worker.cpp:443 Starting worker for IPA module /usr/local/lib/libcamera/ipa/ipa_soft_simple.so with IPC fd = 24 [1:14:30.946549981] [19900] INFO Camera camera_manager.cpp:223 Adding camera '/base/soc@0/cci@ac4a000/i2c-bus@1/camera@36' for pipeline handler simple [1:14:30.952784671] [19900] WARN IPAProxy ipa_proxy.cpp:196 Configuration file 'imx586.yaml' not found for IPA module 'simple', falling back to '/usr/local/share/libcamera/ipa/simple/uncalibrated.yaml' [1:14:30.991114218] [19902] INFO IPAProxySoftWorker soft_ipa_proxy_worker.cpp:443 Starting worker for IPA module /usr/local/lib/libcamera/ipa/ipa_soft_simple.so with IPC fd = 29 [1:14:31.002176045] [19900] INFO Camera camera_manager.cpp:223 Adding camera '/base/soc@0/cci@ac4a000/i2c-bus@0/camera@1a' for pipeline handler simple Available cameras: 1: Internal back camera (/base/soc@0/cci@ac4a000/i2c-bus@1/camera@36) 2: Internal back camera (/base/soc@0/cci@ac4a000/i2c-bus@0/camera@1a)
S
ыLD_LIBRARY_PATH=/usr/local/lib /usr/local/bin/cam -l [1:14:30.339139896] [19899] INFO Camera camera_manager.cpp:340 libcamera v0.0.0+1-244572db-dirty (2026-08-01T19:01:32GMT) [1:14:30.344918075] [19900] ERROR V4L2 v4l2_subdevice.cpp:1192 'ov8856 13-0036': Unable to get rectangle 2 on pad 0/0: Not a
Патч работает: обе жалобы про imx586 исчезли — и про свойства, и про пересчёт усиления. Осталась только одна, про отсутствующий файл настройки, а это уже про цвет. Снимай при свете: sudo pkill -f wireplumber; sudo pkill -f pipewire LD_LIBRARY_PATH=/usr/local/lib /usr/local/bin/cam -c 2 --capture=8 \ -s width=1920,height=1080,pixelformat=RGB888 --file=/tmp/lc_#.rgb convert -size 1920x1080 -depth 8 bgra:/tmp/lc_cam0-stream0-000007.rgb /tmp/lc.png Восемь кадров, смотрим последний — к нему автоматика уже подберёт выдержку и баланс. Что осталось из вывода: imx586.yaml не найден — файл цветовой настройки. Это следующий большой шаг: матрица цветокоррекции, кривая гаммы, коррекция затемнения по краям. Делается по снимкам эталонной таблицы, но простой вариант можно собрать и на глаз. Телевику не хватает границ обрезки — ov8856 не отвечает на запрос области, и libcamera прямо пишет, что драйвер надо чинить. Это тот же get_selection, который мы добавили своему сенсору; в mainline его драйверу не хватает — хороший кандидат на отдельный патч наверх, полезный не только нам. У телевика нет задержек в свойствах — я поставил пустые, как у соседа ov8858. Если понадобится, проставим двойки, это одна строка. 💰 24.21₽ · ⬇️ 973.8k / ⬆️ 1.1k · opus-5 · max · 24с
Ы
stdvectorclaudebotПатч работает: обе жалобы про imx586 исчезли — и про свойства, и про пересчёт усиления. Осталась только одна, про отсутствующий файл настройки, а это уже про цвет. Снимай при свете: sudo pkill -f wireplumber; sudo pkill -f pipewire LD_LIBRARY_PATH=/usr/local/lib /usr/local/bin/cam -c 2 --capture=8
cam0: Capture 8 frames 4532.762104 (0.00 fps) cam0-stream0 seq: 000000 bytesused: 6220800 4532.795425 (30.01 fps) cam0-stream0 seq: 000001 bytesused: 6220800 4532.828749 (30.01 fps) cam0-stream0 seq: 000002 bytesused: 6220800 4532.862080 (30.00 fps) cam0-stream0 seq: 000003 bytesused: 6220800 4532.895395 (30.02 fps) cam0-stream0 seq: 000004 bytesused: 6220800 4532.928715 (30.01 fps) cam0-stream0 seq: 000005 bytesused: 6220800 4532.962034 (30.01 fps) cam0-stream0 seq: 000006 bytesused: 6220800 4532.995354 (30.01 fps) cam0-stream0 seq: 000007 bytesused: 6220800 WARNING: The convert command is deprecated in IMv7, use "magick" instead of "convert" or "magick convert" convert: unexpected end-of-file '/tmp/lc_cam0-stream0-000007.rgb': No such file or directory @ error/bgr.c/ReadBGRImage/247. convert: no images defined `/tmp/lc.png' @ error/deprecate.c/ConvertImageCommand/3375.
S
ыcam0: Capture 8 frames 4532.762104 (0.00 fps) cam0-stream0 seq: 000000 bytesused: 6220800 4532.795425 (30.01 fps) cam0-stream0 seq: 000001 bytesused: 6220800 4532.828749 (30.01 fps) cam0-stream0 seq: 000002 bytesused: 6220800 4532.862080 (30.00 fps) cam0-stream0 seq: 000003 bytesused: 6220800 4532.8
Тридцать кадров в секунду, непрерывно — это уже видео, а не одиночные снимки. И размер кадра 6 220 800 это ровно 1920×1080×3, то есть на этот раз формат упакованный, без лишнего байта. Файла нет, скорее всего, из-за имени — посмотри, что получилось: ls -l /tmp/lc_* 2>/dev/null | tail -3 А переводить надо как трёхбайтовый, и с учётом того, что libcamera называет форматы по упакованному значению, порядок в памяти обратный: F=$(ls -t /tmp/lc_*.rgb | head -1); echo $F magick -size 1920x1080 -depth 8 bgr:$F /tmp/lc.png magick -size 1920x1080 -depth 8 rgb:$F /tmp/lc_rgb.png Какая из двух картинок выйдет с правильными цветами (небо синее, а не оранжевое), та и верная — заодно и запомним. Кстати, вычёркиваем ещё пункт из списка «чего не хватает до main»: видео с камеры работает, тридцать кадров при 1920×1080 через программный ISP. 💰 23.85₽ · ⬇️ 975.3k / ⬆️ 1.1k · opus-5 · max · 20с
Ы
S
ыls -l /tmp/lc_* 2>/dev/null | tail -3 -rw-r--r-- 1 user user 6220800 Aug 1 19:03 /tmp/lc_cam0-stream0-000005.rgb -rw-r--r-- 1 user user 6220800 Aug 1 19:03 /tmp/lc_cam0-stream0-000006.rgb -rw-r--r-- 1 user user 6220800 Aug 1 19:03 /tmp/lc_cam0-stream0-000007
Файлы на месте, а convert ругался потому, что я велел ему читать четырёхбайтовый формат — он ждал 8 294 400 байт и упёрся в конец файла на 6 220 800. Правильно так: magick -size 1920x1080 -depth 8 bgr:/tmp/lc_cam0-stream0-000007.rgb /tmp/lc_bgr.png magick -size 1920x1080 -depth 8 rgb:/tmp/lc_cam0-stream0-000007.rgb /tmp/lc_rgb.png Смотри обе: у одной цвета будут настоящими, у другой красное с синим переставлены. Заодно интересно, как отработала автоматика — восьмой кадр снят через четверть секунды после начала, выдержка к нему уже должна сойтись. 💰 23.03₽ · ⬇️ 976.6k / ⬆️ 438 · opus-5 · max · 14с
Ы
S
ыа чо он ваще нафоткал. говно какое то
Опиши, что именно — цветной шум, полосы, или картинка узнаётся, но цвета не те? От этого зависит, где искать. Подозрение у меня такое: libcamera на запрос 1920×1080 выбрала наш режим с бинированием четыре на четыре, а при таком сведении порядок цветовых точек может сдвинуться. Драйвер же во всех режимах объявляет один и тот же SRGGB10, и если на самом деле там, скажем, GRBG, картинка получится с переставленными цветами и «грязью» на переходах. Проверяется быстро, нашим же распаковщиком — снимем тот же режим напрямую и переберём четыре варианта: cd ~/lanekit sed -i 's/^W=[0-9]*/W=1920/; s/^H=[0-9]*/H=1080/' capture.sh EXPOSURE=1000 GAIN=400 sh capture.sh for p in rggb bggr grbg gbrg; do ~/raw10preview /tmp/frame.raw /tmp/b_$p.ppm 1920 1080 $p 2 >/dev/null 2>&1 magick /tmp/b_$p.ppm /tmp/b_$p.png done ls -l /tmp/b_*.png Какой из четырёх окажется с натуральными цветами, тот и правильный для этого режима — и тогда я поправлю драйвер, чтобы он объявлял код по режиму, а не один на всех. 💰 23.58₽ · ⬇️ 977.1k / ⬆️ 1.2k · opus-5 · max · 25с
Ы
S
ыкартинка не узнается. вроде размытое какое то все очень уж. и ваще ничо не разобрать.
Тогда сначала отделим камеру от обработки — сними тот же режим нашим путём (команду я дал в прошлом сообщении) и посмотри /tmp/b_rggb.png. Если и там мыло, дело не в libcamera. И проверь наводку: мы её ставили на 600, но libcamera про объектив ничего не знает и наверняка оставила линзу там, где она была после её собственных настроек — то есть, скорее всего, на нуле, а это бесконечность. Для комнаты нужно ближе: D=$(media-ctl -d /dev/media0 -e "dw9768 12-000c") v4l2-ctl -d "$D" --set-ctrl focus_absolute=600 v4l2-ctl -d "$D" --get-ctrl focus_absolute Потом повтори съёмку через libcamera — она положение линзы не трогает, так что оно останется. Ещё одно подозрение по этому режиму: у вендора он сделан бинированием четыре на четыре с длиной строки 2912, и если при таком сведении сенсор отдаёт кадр иначе, чем мы объявляем, то и получится каша. Наш собственный снимок это как раз и покажет. 💰 23.59₽ · ⬇️ 978.4k / ⬆️ 902 · opus-5 · max · 20с
Ы
S
ыдай команды
cd ~/lanekit D=$(media-ctl -d /dev/media0 -e "dw9768 12-000c") v4l2-ctl -d "$D" --set-ctrl focus_absolute=600 # наш путь, тот же режим 1920x1080 sed -i 's/^W=[0-9]*/W=1920/; s/^H=[0-9]*/H=1080/' capture.sh EXPOSURE=1000 GAIN=400 sh capture.sh for p in rggb bggr grbg gbrg; do ~/raw10preview /tmp/frame.raw /tmp/b_$p.ppm 1920 1080 $p 2 >/dev/null 2>&1 magick /tmp/b_$p.ppm /tmp/b_$p.png done # для сравнения — заведомо рабочий режим sed -i 's/^W=[0-9]*/W=4000/; s/^H=[0-9]*/H=3000/' capture.sh EXPOSURE=3006 GAIN=600 sh capture.sh ~/raw10preview /tmp/frame.raw /tmp/ctl.ppm 4000 3000 rggb 4 && magick /tmp/ctl.ppm /tmp/ctl.png ls -l /tmp/b_*.png /tmp/ctl.png Смотри ctl.png — он должен быть таким же нормальным, как раньше. Если он хороший, а все четыре b_*.png мутные, значит режим 1920×1080 у нас поднимается неверно, и я буду разбирать его таблицу отдельно: там бинирование четыре на четыре, длина строки 2912, и вполне может оказаться, что сенсор отдаёт кадр другого размера, чем мы объявляем приёмнику. 💰 23.25₽ · ⬇️ 979.4k / ⬆️ 722 · opus-5 · max · 13с
S
ыEXPOSURE=1000 GAIN=400 sh capture.sh [sudo: authenticate] Password: VIDIOC_STREAMON returned -1 (Broken pipe) -rw-r--r-- 1 user user 0 Aug 1 19:07 /tmp/frame.raw
Покажи, на чём именно споткнулось: sudo dmesg | grep -vE "link_setup|got IRQ" | tail -12 media-ctl -d /dev/media0 -p | grep -A3 "entity 171" | tail -3 v4l2-ctl -d $(media-ctl -d /dev/media0 -e msm_vfe0_video0) --get-fmt-video | tail -4 «Broken pipe» на запуске потока в camss означает несогласованность форматов по цепочке: либо какой-то пад не принял 1920×1080, либо на видеоузле остался прежний размер. Первая команда назовёт причину прямо, вторая покажет, что стоит у сенсора, третья — что на выходе. Подозреваю вот что: в драйвере, который сейчас загружен, предел органа pixel_rate жёстко привязан к первому режиму — я эту оплошность нашёл и поправил, но пересборки после правки ещё не было. Для 1920×1080 значение выходит за предел, установка молча не проходит, и дальше camss считает поток точек неверным. Если так и есть, лечится пересборкой драйвера из прибранного набора — там уже правильно. 💰 23.75₽ · ⬇️ 980.4k / ⬆️ 1.1k · opus-5 · max · 24с
Ы
stdvectorclaudebotПокажи, на чём именно споткнулось: sudo dmesg | grep -vE "link_setup|got IRQ" | tail -12 media-ctl -d /dev/media0 -p | grep -A3 "entity 171" | tail -3 v4l2-ctl -d $(media-ctl -d /dev/media0 -e msm_vfe0_video0) --get-fmt-video | tail -4 «Broken pipe» на запуске потока в camss означает несогласованн
sudo dmesg | grep -vE "link_setup|got IRQ" | tail -12 [ 4800.173239] qcom-camss ace0000.camss: VFE:0 HW Version = 1.3.0 [ 4800.173293] csid_reset called [ 4800.173322] qcom-camss ace0000.camss: CSID:0 HW Version = 2.0.0 [ 4800.173347] qcom-camss ace0000.camss: validating link "msm_csid0":1 -> "msm_vfe0_rdi0":0 [ 4800.173353] qcom-camss ace0000.camss: validating stream "msm_csid0":1:0 -> "msm_vfe0_rdi0":0:0 [ 4800.173362] qcom-camss ace0000.camss: validating link "msm_csiphy0":1 -> "msm_csid0":0 [ 4800.173367] qcom-camss ace0000.camss: validating stream "msm_csiphy0":1:0 -> "msm_csid0":0:0 [ 4800.173374] qcom-camss ace0000.camss: validating link "imx586 12-001a":0 -> "msm_csiphy0":0 [ 4800.173379] qcom-camss ace0000.camss: validating stream "imx586 12-001a":0:0 -> "msm_csiphy0":0:0 [ 4800.173385] qcom-camss ace0000.camss: v4l2_subdev_link_validate_default: media bus code does not match (source 0x00003007, sink 0x0000300f) [ 4800.173391] qcom-camss ace0000.camss: v4l2_subdev_link_validate_default: link was "imx586 12-001a":0 -> "msm_csiphy0":0 [ 4800.173399] qcom-camss ace0000.camss: Failed to start media pipeline: -32 media-ctl -d /dev/media0 -p | grep -A3 "entity 171" | tail -3 type V4L2 subdev subtype Sensor flags 0 device node name /dev/v4l-subdev16 pad0: SOURCE v4l2-ctl -d $(media-ctl -d /dev/media0 -e msm_vfe0_video0) --get-fmt-video | tail -4 Quantization : Full Range Plane 0 : Bytes per Line : 2400 Size Image : 2592000
S
ыsudo dmesg | grep -vE "link_setup|got IRQ" | tail -12 [ 4800.173239] qcom-camss ace0000.camss: VFE:0 HW Version = 1.3.0 [ 4800.173293] csid_reset called [ 4800.173322] qcom-camss ace0000.camss: CSID:0 HW Version = 2.0.0 [ 4800.173347] qcom-camss ace0000.camss: validating link "msm_csid0":1 -> "msm_v
Причина в логе прямым текстом: media bus code does not match (source 0x00003007, sink 0x0000300f) 0x300f это SRGGB10, а 0x3007 — SBGGR10. То есть сенсор сейчас сообщает другой порядок цветовых точек, и вот почему: libcamera выставила оба зеркала, потому что в дереве у нас rotation = <180> — модуль стоит вверх ногами, и она это компенсирует. Наш драйвер честно поменял код формата (отражение переставляет цвета в квадрате), а capture.sh продолжает требовать прежний. То есть всё работает правильно, просто мой скрипт про это не знает. Лечим — сбрасываем зеркала перед своей съёмкой: cd ~/lanekit python3 - <<'EOF' s=open('capture.sh').read() s=s.replace('[ -n "$EXPOSURE" ]', '''v4l2-ctl -d "$SD" --set-ctrl horizontal_flip=0,vertical_flip=0 2>/dev/null [ -n "$EXPOSURE" ]''') open('capture.sh','w').write(s) EOF EXPOSURE=1000 GAIN=400 sh capture.sh for p in rggb bggr grbg gbrg; do ~/raw10preview /tmp/frame.raw /tmp/b_$p.ppm 1920 1080 $p 2 >/dev/null 2>&1 magick /tmp/b_$p.ppm /tmp/b_$p.png done ls -l /tmp/b_*.png А заодно это объясняет и «нафоткал говно» через libcamera: она снимает с обоими зеркалами, то есть кадр перевёрнут на сто восемьдесят градусов — и если смотреть на него как на обычный, всё выглядит бессмысленно. Переверни lc_bgr.png и посмотри снова: magick /tmp/lc_bgr.png -rotate 180 /tmp/lc_rot.png 💰 24.83₽ · ⬇️ 982.4k / ⬆️ 1.7k · opus-5 · max · 27с
Ы
S
ылан ща отойду ненадолго. ты думай пока чо. типа думай ищи и читай
Пока ты ходишь — разберу режим 1920×1080, там что-то не так с геометрией. Смотрю его вендорную таблицу целиком: Геометрия режима 1920×1080 оказалась в порядке: область считывания 8000×5152 (это как раз широкий кадр), бинирование четыре на четыре даёт 2000×1288, из них вырезается 1920×1080 со смещением 40 по горизонтали — то есть по центру. Фаза цветовых точек при этом сохраняется, потому что и бинирование, и смещение чётные. Значит «неразборчиво» — это, скорее всего, тот самый поворот на 180 градусов от libcamera, и картинка просто вверх ногами. Пока смотрю дальше — что нужно программному ISP для нормального цвета: Полезное открытие: уровень чёрного программный ISP берёт из того самого пересчёта усиления, который мы добавили: if (camHelper_->blackLevel().has_value()) ... camHelper_->blackLevel().value() / 256; То есть наши 4096 (это 64 при десяти битах) уже работают, и вычитание чёрного у libcamera теперь правильное. А отдельных файлов настройки под сенсоры в libcamera пока нет вовсе — там только uncalibrated.yaml, и матрица цветокоррекции в нём закомментирована с пометкой «включать только если настроено». Без снимка эталонной таблицы честно настроить её нельзя, так что это отложим. Зато сделаю то, что можно сделать чтением — заплату для телевика, о которой libcamera прямо просит: Пока тебя нет, разобрал три вещи. Режим 1920×1080 в порядке. Вендорная таблица: область считывания 8000×5152 (широкий кадр), бинирование четыре на четыре даёт 2000×1288, из них вырезается 1920×1080 со смещением 40 по горизонтали — то есть ровно по центру. И бинирование, и смещение чётные, поэтому порядок цветовых точек не сдвигается. Значит «неразборчиво» было от поворота на 180 градусов, который libcamera делает по свойству из дерева. Уровень чёрного у libcamera теперь наш. Программный ISP берёт его не из файла настройки, а из пересчёта усиления: if (camHelper_->blackLevel().has_value()) ... camHelper_->blackLevel().value() / 256; Мы туда положили 4096, то есть 64 при десяти битах — значит вычитание чёрного у неё уже правильное, это не догадка, а прочитанный код. Файлов настройки под сенсоры в libcamera нет вообще — только uncalibrated.yaml, и матрица цветокоррекции в нём закомментирована с пометкой «включать только если настроено». Так что цвет без снимка эталонной таблицы честно не поправить, и я не буду делать вид, что можно. Зато сделал заплату для телевика — ту, о которой libcamera прямо просит («The sensor kernel driver needs to be fixed»). Драйвер ov8856 не отвечает на запрос области, поэтому libcamera подставляет размеры наугад. Добавлены размеры матрицы и get_selection: #define OV8856_NATIVE_WIDTH 3296U /* вся матрица */ #define OV8856_NATIVE_HEIGHT 2480U #define OV8856_PIXEL_ARRAY_WIDTH 3280U /* рабочая область */ #define OV8856_PIXEL_ARRAY_HEIGHT 2464U /* со смещением 8, 8 */ Заплата годится и наверх: она чинит предупреждение у всех, кто использует этот сенсор, а не только у нас. Дам команду, когда вернёшься. 💰 146₽ · ⬇️ 5.93M / ⬆️ 7.4k · opus-5 · max · 121с
Ы
S
ыпоресерчи пока в сторону передней камеры
Хорошие новости по обеим оставшимся камерам. Передняя — S5K3T2 (CSIPHY1, шина cci0 i2c0 — та же, что у широкой, но другой адрес; MCLK0 на ножке 13, сброс 23, питание ядра через ножку 57). Драйвера в mainline нет. Сверхширокая — S5K3L6, и вот тут сюрприз: драйвер в mainline есть, s5k3l6xx.c. Смотрю, годится ли он нам: Разобрал обе оставшиеся камеры. Итог такой. Сверхширокая S5K3L6 — почти даром. Драйвер в mainline есть (s5k3l6xx.c, совместимость samsung,s5k3l6xx), режимы до 4208×3120, число линий читает из дерева, границы обрезки сообщает — то есть libcamera к нему претензий иметь не будет. Питание просит тремя именами: vddio, vdda, vddd. Разводка из вендорного дерева: CSIPHY2, шина cci0 i2c1, MCLK1 на ножке 14, сброс на 25, питание ядра через ножку 29, напряжения те же, что у широкой (1.8 / bob / 1.352 / смещение l9). Адрес в черновике форка 0x10. Работы — узел в дереве и проверка, то есть вечер. Передняя S5K3T2 — драйвера нет. Ни в mainline, ни где-либо ещё я его не нашёл. Но теперь это не приговор: вендорный файл настроек com.qti.sensormodule.davinci_sunny_s5k3t2.bin лежит на телефоне, а формат мы разобрали — оттуда достанутся начальная последовательность, все режимы, число линий, раскладка и частоты линка, ровно как для IMX582. За образец возьму s5k3m5.c или s5kjn1.c — это Samsung того же поколения, у них та же схема регистров. Разводка: CSIPHY1, шина cci0 i2c0 (та же, что у широкой, но другой адрес), MCLK0 на ножке 13, сброс на 23, питание ядра через 57. Чтобы двигаться дальше, скопируй мне два файла с телефона, когда будет удобно: cp /mnt/vendor/lib/camera/com.qti.sensormodule.davinci_ofilm_s5k3l6.bin ~/ cp /mnt/vendor/lib/camera/com.qti.sensormodule.davinci_sunny_s5k3t2.bin ~/ Из первого я вытащу число линий и частоты для сверхширокой (чтобы не гадать, как гадали с широкой), из второго — всё для передней. 💰 143₽ · ⬇️ 5.98M / ⬆️ 5.0k · opus-5 · max · 96с
Ы
S
ыне забывай чо она выдвижная. кста зач они такуйу сделали
Помню — и это как раз плюс: мотор от драйвера сенсора не зависит, его можно поднимать отдельно и проверять хоть сегодня. Нашёл всю разводку. Механика — обычный шаговик с драйвером класса DRV8834: DIR на ножке 55, nSLEEP 88, nENBL 90, микрошаг M0 91 и M1 66, nFAULT 43 (обратно в SoC — сообщает о заклине/перегреве). А вот STEP_CLK — не на TLMM, а на pm6150l GPIO10, то есть тактовые импульсы шагов генерирует сама PMIC своим LPG. Это хорошая новость: в mainline pm6150l.dtsi узел pm6150l_lpg: pwm уже объявлен и драйвер leds-qcom-lpg его подхватывает как PWM-чип. Значит шаги даёт железо ровным клоком, а не дрыганье ножкой из софта — шаговику это принципиально. Положение камеры телефон читает цифровым холлом AKM09970 на i2c9 по адресу 0x0c (плюс линии сброса 64 и прерывания 93). Его в mainline нет — в iio/magnetometer только ak8974/ak8975, это другой чип. Ещё вендор ловит свободное падение акселерометром и втягивает камеру на лету. Первый шаг тут вообще без ядра: скрипт в userspace — gpioset на DIR/EN/SLEEP/M0/M1 и PWM через sysfs на канал LPG. Проверь пока, есть ли чем: zcat /proc/config.gz | grep -E 'LEDS_QCOM_LPG|GPIO_CDEV'; ls /sys/class/pwm/ А зачем такое сделали — это 2019-й, гонка за экраном без выреза. Дырка в матрице тогда была дорогой и только у Samsung, подэкранных камер ещё не существовало, а Xiaomi хотела честный безрамочный AMOLED в среднем ценнике. Выдвижной блок это решал разом, да ещё и работал как аттракцион на витрине. Платили за это толщиной, весом под 191 г, пылью в щели, отсутствием влагозащиты и ресурсом механизма (обещали 300 тысяч циклов, на деле мотор — типовая болячка K20). Как только дырка в экране подешевела, вся идея умерла за год. 💰 68.99₽ · ⬇️ 500.6k / ⬆️ 8.2k · opus-5 · max · 351с
Ы
S
ывырез в экране эт некрасиво. а тут ещо видно када снимают и скрытно не выйдет чо как бы плюс
Согласен, и это не только эстетика. Выдвижная камера — единственная честная гарантия приватности: софт не может тихо включить съёмку, потому что модуль физически лежит внутри корпуса, а чтобы вылезти — надо крутить мотор с характерным жужжанием. Индикаторы-точки в Android и iOS появились именно как попытка изобразить то же самое программно, но их рисует та же система, которой ты и не доверяешь. Тут же механика: закрыто значит закрыто. Для нас это ещё и практическая мелочь при отладке. Когда дойдём до передней камеры, чёрный кадр не будет означать, что драйвер сломан — сначала надо будет убедиться, что блок вообще выехал. Так что порядок работ выходит обратный привычному: сперва мотор, потом сенсор. Заодно и приятнее — жужжание и вылезающий глазок видно сразу, в отличие от возни с регистрами. 💰 2.95₽ · ⬇️ 62.8k / ⬆️ 651 · opus-5 · max · 16с
Ы
S
ыжалко что идея умерла
Она умерла не потому, что плохая, а потому, что приватность не продаётся. В таблице характеристик выдвижной блок выглядит как минус: толще, тяжелее, нет влагозащиты, лишний узел, который ломается и стоит денег в сервисе. А «нельзя снимать незаметно» в строчку не впишешь и в рекламе не покажешь. Отчасти идея всё-таки живёт: у Zenfone был поворотный блок аж до 8-го, в ноутбуках шторки стали нормой, а на телефонах теперь подэкранные камеры — вырез спрятали, но подглядывать они могут круглосуточно. Так что красоту вернули, а честность потеряли. Зато у нас на руках последний экземпляр эпохи, да ещё и с открытым ядром. Подниму мотор — будет жужжать как в 2019-м. 💰 2.31₽ · ⬇️ 63.5k / ⬆️ 521 · opus-5 · max · 12с
Ы
S
ыда ядро и в стоке открыто. кроме всего остального
Справедливо, поправка принята. Разница не в открытости, а в том, что вендорское ядро — это разовый выброс 4.14 без истории коммитов, замороженный навсегда: обновлений нет, собрать современным тулчейном нельзя, а патчи безопасности за шесть лет никто не носил. Мы же сегодня трогали 7.2, которое живёт дальше само. Хотя именно эта GPL-обязаловка нас сегодня и вытащила: арифметику линий CSIPHY я прочитал ровно в вендорном cam_csiphy_core.c. А вот таблицы сенсора лежали в блобе, который никому ничего не должен — и их пришлось выковыривать вручную из бинаря. Разница между этими двумя вечерами очень наглядная. 💰 2.49₽ · ⬇️ 64.1k / ⬆️ 711 · opus-5 · max · 15с
Ы
S
ыа есть ли в пмосе устройства которые отлично работают в даунстриме на халиум
Ссылка
нажмите — покажем
Коротко: в pmOS такого класса устройств толком нет — и это осознанная позиция проекта. Halium там вообще не используется, это стек Ubuntu Touch (Volla, Fairphone, Pixel 3a). Plasma Mobile выкинула поддержку Halium ещё в 2020-м, сделав ставку на устройства с открытыми драйверами. pmOS же умеет собираться с вендорным ядром напрямую, без libhybris-прослойки, но графика тогда упирается в отсутствие hwcomposer, и обычно всё сводится к «загружается, ssh есть, дальше как повезёт». В 2025-м это ещё и формализовали: даунстрим-порты вынесли в отдельную категорию downstream, pmbootstrap теперь показывает предупреждение при их выборе, а бинарные пакеты для них с версии 25.06 просто перестали собирать — формулировка была «они, как правило, не особо полезны». В community и testing остались только близкие к mainline порты. Из ~700 устройств ядро сейчас поддерживает около 450, и миграция идёт в одну сторону. Так что «отлично работает» и «даунстрим» в pmOS почти не встречаются в одном предложении. Наш случай ровно про это: камера у нас теперь живёт нативным V4L2, а на халиум-устройстве камера — это всегда чужой Android-HAL в контейнере, который никуда не развивается. Источники: про разделение категорий, Plasma Mobile и Halium, позиция pmOS про халиум. 💰 11.85₽ · ⬇️ 132.4k / ⬆️ 2.2k · opus-5 · max · 55с
Ы
S
ыа чо не портируют люди халиумом? чтоб расширить поддержку и устройствами чо у убунту тач. пользователей оно прибавит
Потому что Halium — это не «порт», а способ жизни, несовместимый с тем, как устроен pmOS. Технически ты берёшь целиком андроидное userspace нужной версии, запускаешь его в контейнере и через libhybris ходишь во все HAL'ы: графика — EGL-блоб и hwcomposer, камера — camera HAL, звук, сенсоры, радио — свои демоны-прослойки. Значит весь дистрибутив выше должен быть собран с оглядкой на bionic. У pmOS же ровно противоположная идея: Alpine, обычный Linux userspace, апстрим-ядро и одинаковые бинарные пакеты на все устройства сразу. Плюс блобы нельзя перераспространять, а pmOS раздаёт готовые пакеты из репозитория — модель ломается на юридическом уровне. Экономика ещё хуже. Каждый halium-порт заморожен на вендорном ядре 3.18–4.14 без обновлений безопасности и умирает вместе с андроид-базой, под которую собран. И главное — работа непереносима: починил камеру на устройстве A, устройству B от этого ноль. В mainline наоборот: тот же camss, который мы сегодня чинили, обслуживает все SDM845/SM7150 разом, а два найденных бага после отправки в апстрим достанутся всем, включая тех, кто про давинчи не слышал. Отсюда и правило «450 устройств уже мигрировали». Есть и практическая мелочь: на halium-устройстве контейнер уже занят андроидом, поэтому Waydroid не запустить. То есть андроид-приложения ты получаешь только те, что крутятся в базовом образе, а на mainline-устройстве Waydroid ставится штатно. И да — люди это делают, просто не в pmOS: ровно эту нишу занимает Droidian (Debian поверх halium-адаптации) и сам Ubuntu Touch. Дублировать их pmOS сознательно не хочет — там считают, что дешевле дотащить железо до mainline один раз, чем вечно чинить чужие блобы. Мы сегодня, в общем, живая иллюстрация: день работы — и камера отдаёт кадры честным V4L2, без единого куска андроида в системе. 💰 4.69₽ · ⬇️ 69.1k / ⬆️ 2.1k · opus-5 · max · 42с
Ы
S
ывейдроид работает в убунту тач жеж
Ссылка
нажмите — покажем
Тут ты прав, а я нет — снимаю это утверждение. Waydroid на Ubuntu Touch работает, причём на Halium 9 и новее он вообще идёт предустановленным в базе focal, а не как самоделка. Ошибся я в механике: я думал про старые порты, где в ядре было три статических binder-устройства и второй андроид туда просто не влезал. С binderfs доменов может быть сколько угодно, поэтому системный контейнер и вейдроидовский спокойно живут рядом. Ограничение осталось только снизу — на Halium 5 и 7 это не заводится никак, и на не-Treble устройствах приходится руками докладывать в вейдроидовский rootfs вендорные библиотеки (gralloc, libui, libbinder, configstore). То есть довод «на халиуме нет андроид-приложений» отпадает целиком. Остаются те, что про сопровождение: мёртвое ядро, блобы без права раздачи и непереносимость работы между устройствами. Ирония в том, что вейдроид там крутится поверх ядра 4.9, у которого патчей безопасности нет с позапрошлой эпохи. Источники: гайд по Waydroid на UT, ветка про halium 9 + waydroid, требования по binderfs. 💰 15.60₽ · ⬇️ 146.1k / ⬆️ 1.6k · opus-5 · max · 58с
Ы
S
ытак основную работу в убунту тач сделали жеж. ток перенести. даж если не поддерживать особ в рамках пмос но прост чтоб было
Проблема в том, что «просто перенести» — это перенести не приложение, а весь графический стек. На Ubuntu Touch поверх халиума работает Lomiri на Mir, у которого есть свой бэкенд к hwcomposer. В pmOS никакого Lomiri нет, там Phosh, Plasma Mobile и GNOME, а они ходят напрямую в DRM/KMS. Плазма выкинула поддержку халиума в 2020-м, у wlroots hwcomposer-бэкенд живёт только в виде патчей, которые кто-то должен вечно тащить за апстримом. Плюс Alpine — это musl, а вся связка hybris заточена под glibc и bionic. Получается не «перенос», а постоянный форк Mesa, wlroots и libhybris, который надо чинить после каждого релиза каждого компонента. И этот форк уже существует: ровно этим занимается Droidian — Debian, glibc, пропатченный wlroots, Phosh поверх hwcomposer. Если цель «чтоб было» — оно есть, просто не под вывеской pmOS. Делать вторую такую же реализацию на musl ради того же результата смысла мало. Ниша «чтоб было» в pmOS тоже занята — это категория downstream. Туда порт с вендорным ядром принимают, никто не запрещает, но пакеты не собирают и в багтрекере не разбирают. Опыт показал, что такие порты живут ровно до тех пор, пока автору интересно, а дальше висят мёртвым грузом и создают у людей ложное впечатление, что их телефон поддержан. Отсюда и предупреждение в pmbootstrap при выборе. Так что расчёт у них простой: тот же человеко-месяц, вложенный в mainline, даёт не одно устройство, а весь SoC разом — и не протухает. Мы сегодня как раз этот вариант и отрабатываем. 💰 4.44₽ · ⬇️ 75.7k / ⬆️ 2.1k · opus-5 · max · 41с
Ы
S
ыну эт удобно чо устройство может жить скока хочеш. пока совсем не износится. а батарею поменять можна
Именно. Железо у телефона изнашивается по-настоящему только в двух местах: аккумулятор и флеш-память. Батарея на давинчи меняется отвёрткой и феном за полчаса, копии ещё лет десять будут продаваться. UFS в телефоне, который не крутит сутками андроид с его логами и телеметрией, проживёт дольше владельца. Всё остальное — стекло, разъём, кнопки — расходники, которые чинятся. И мы сегодня ровно это и получили: аппарат 2019 года работает на ядре 7.2, которое вышло на днях, и камера в нём заведена не потому, что кто-то из Xiaomi разрешил, а потому что драйвер лежит в общем дереве и будет ехать дальше сам. Единственное, что остаётся чужим и подписанным — прошивка модема, но она живёт в своём процессоре и до системы не дотягивается. Прикольно, кстати, что при таком раскладе телефон перестаёт быть телефоном в смысле «модель такого-то года». Это просто небольшой ARM-компьютер с экраном, батареей и, скоро, выдвижной камерой. 💰 3.42₽ · ⬇️ 77.9k / ⬆️ 653 · opus-5 · max · 16с
Ы
S
ыс камерой завтра продолжим. сохрани пока все твои патчи и прогресс. скинь архивом.
Собрал всё в архив (копия распакована на сервере в /data/work/chat_-1001429467665/mi9t-camera/, чтобы не пропала вместе с /tmp). Что добавилось с прошлой версии: • capture.sh — теперь сбрасывает флипы перед съёмкой. Это та самая причина Broken pipe в последнем тесте: libcamera выставляет оба флипа (в дереве написано, что модуль перевёрнут), драйвер честно начинает отдавать другой байеровский порядок, а формат в приёмнике остаётся старым. Заодно сенсор ищется по graph'у, а не по захардкоженному 12-001a, и появились W/H/EXPOSURE/GAIN/FOCUS через окружение. • davinci-camera.dtsi — параметры мотора фокуса заменены на вендорные: AAC4 с делителем 2, то есть звон гасится за 9.75 мс вместо дефолтных 6.65. Значения не выдуманы, они прочитаны из блоба (0x06=0x60, 0x07=0x02). • ov8856-get-selection.patch — телевик наконец сообщает свою геометрию (матрица 3296×2480, активное окно 3280×2464 с отступом 8), а то libcamera её угадывала. • NOTES-next.md — вся сегодняшняя разведка по трём оставшимся камерам: распиновка сверхширокой и передней, какие блобы с них надо снять, и полная схема выдвижного механизма с мотором и холлом. Завтра логичный порядок такой: сначала прогнать телевик (он готов, нужен только тест), потом сверхширокая — там драйвер уже в ядре, работы на узел в дереве, а дальше передняя, но начиная с мотора, а не с сенсора. 💰 52.04₽ · ⬇️ 1.41M / ⬆️ 10.2k · opus-5 · max · 161с
Ы
S
ыа наскок сложно ваще блобы реверсить как либрефоновцы делают. чтобе получить полностью свободную систему
Сложность там очень разная — она распадается на четыре слоя, и полезно их не путать. Слой первый: данные. Таблицы регистров, калибровки, board-файлы Wi-Fi. Это вообще не код, просто структурированные байты, и вскрывается за вечер-два, как мы сегодня и сделали с настройками сенсора. Тут никакой магии: находишь схему, находишь область данных, проверяешь себя по физике — частота вышла ровно 19.2 МГц, геометрия сошлась с описанием режима, значит читаешь правильно. Слой второй: драйверы в userspace. Camera HAL, hwcomposer, графика. Их обычно не реверсят построчно — пишут заново, а блоб используют как справочник: трассируешь, что он пишет в железо, и повторяешь смысл. Так делали freedreno для Adreno и etnaviv для Vivante. Работает отлично, но это годы работы небольшой группы: Роб Кларк начал freedreno в 2012-м, а полноценным драйвером в Mesa оно стало ближе к 2018-му. Слой третий: прошивки отдельных процессоров. GPU, DSP, модем, Wi-Fi. Знание тут добывается так же, но упирается не в непонимание, а в криптографию: код подписан, и загрузчик просто не примет чужой. На Adreno 6xx даже свободный драйвер вынужден подгружать вендорный zap-shader, чтобы вывести GPU из secure-режима. Идеально отреверсенная замена бесполезна — её нечем подписать. Слой четвёртый: цепочка загрузки. Прошито в fuse'ах намертво. Поэтому «либрефоновцы» на самом деле блобы почти не реверсят. Стратегия Purism — обход и изоляция: взять SoC без принудительной подписи (i.MX8M вместо Qualcomm), а несвободные куски вынести за шину — модем отдельной M.2-картой по USB, Wi-Fi отдельной картой. Тогда чужая прошивка крутится в своём процессоре и до твоей памяти не дотягивается. Это признание, что победить подпись нельзя, но можно лишить её значения. Прагматичная позиция ядра примерно та же: блоб на отдельном ядре за IOMMU — терпимо, блоб в твоём адресном пространстве — нет. У нас на давинчи модем ровно такой, а вот камера с сегодняшнего дня без единого блоба вообще: драйвер свободный, таблицы прочитаны и переписаны как исходник. Так и выглядит реалистичное освобождение — по кусочку, снизу вверх, а не одним героическим реверсом всего. 💰 5.49₽ · ⬇️ 105.1k / ⬆️ 2.4k · opus-5 · max · 49с
Ы
S
ылибрефоновцы блобы и реверсят. это LibrePhone от fsf
Ссылка
нажмите — покажем
Точно, спутал с Purism — беру назад. Librephone это другое, и там реверс как раз основная деятельность. Проект FSF объявила 14 октября 2025-го, технический руководитель — Роб Савой (тот самый, что делал DejaGNU и Gnash), финансирование началось с пожертвования Джона Гилмора, который обнаружил, что его LineageOS с microG всё равно тащит проприетарные модули из прошивки конкретных телефонов. Формулировка у Савоя аккуратная: он не строит свободную мобильную ОС, а освобождает нижний слой, который управляет железом — чтобы результатом могла пользоваться любая система. Приоритет он выбрал самый тяжёлый из возможных: радио. Wi-Fi, Bluetooth, NFC и сотовая связь. По летнему бюллетеню 2026-го, за полгода он разобрал прошивки из более чем двухсот установочных пакетов Lineage, перемолол 85 ГБ файлов и сложил результаты анализа в PostgreSQL, чтобы сравнивать блобы между устройствами. То есть первые полгода ушли в инвентаризацию — и это, честно говоря, лучшая иллюстрация масштаба: до собственно замены хоть одного блоба дело ещё не дошло. Логика у него ровно та же, что и в нашем споре про mainline: блобы переиспользуются между устройствами, поэтому освобождённый один раз кусок закрывает сразу много моделей. И жалуется он на то же, на что жаловались бы мы, не окажись у нас вендорного ядра под GPL — на невозможность получить даташиты. Про модем FSF прямо пишет, что это самое сложное место, так что мой тезис про подпись остаётся в силе: знание добывается, а вот подписать замену всё равно нечем. Источники: бюллетень FSF, лето 2026, librephone.org, интервью Савоя The Register. 💰 16.34₽ · ⬇️ 217.8k / ⬆️ 1.4k · opus-5 · max · 47с
Ы
S
ыну Fairphone 6 они то выбрали как цель
Ссылка
нажмите — покажем
Да, страница по нему на сайте проекта есть — и это явный фаворит. Только формально там всё ещё стадия отбора: страница подписана как справочник для портирования вообще (Librephone, postmarketOS, LineageOS), перечня блобов на ней нет и статуса работ тоже. Савой с самого начала описывал первый шаг как триаж — найти телефон с наименьшим и наиболее чинибельным набором проблем, — и FP6 на эту роль подходит идеально: 10 из 10 по ремонтопригодности, восемь лет обновлений и живой производитель, с которым можно разговаривать. Забавное для нас: там Snapdragon 7s Gen 3, он же SM7635 — то есть родня нашему SM7150, с тем же camss, теми же CSIPHY и той же вендорной обвязкой. Камеры: основная Sony IMX896, сверхширокая OmniVision OV13B10, фронталка Samsung S5KKD1. Значит камерная часть их работы — это ровно то, чем мы занимались сегодня: таблицы лежат в блобах того же кечиповского формата com.qti.sensormodule.*, читаются той же схемой, а дальше пишется свободный драйвер. Метод переносится один в один, разве что модуль другой. Так что если они дойдут до камеры на FP6, наш сегодняшний разбор формата им буквально пригодится. Что, кстати, аргумент отправить всё это не только в linux-media, но и куда-нибудь, где они увидят. Источники: страница FP6 у Librephone, обзор проекта на LWN. 💰 28.03₽ · ⬇️ 341.9k / ⬆️ 1.6k · opus-5 · max · 71с
Ы
S
ыэх вот бы денег чтоб этот телефон раздобыть. но лан. мб либрефоновцы чо сделают чоб и на текущем мойом оно завелось без блобов
Твой-то как раз в неплохой форме. После сегодняшнего у давинчи камера работает вообще без единого блоба — там, где на стоке был целый camera HAL плюс модули настроек. Осталось немного и всё известное: прошивка модема, zap-шейдер и микрокод Adreno, прошивка Wi-Fi с board-файлом, звуковой DSP и кодеки видео. Это не бесконечный список, а конкретные пять пунктов. И работа Librephone тут реально может приехать к тебе сама: они начали с радио, а прошивка WCN3990 в твоём телефоне — та же самая, что в десятках других qualcomm-аппаратов той эпохи. В этом весь смысл их подхода: блоб освобождается один раз, а закрывает сразу целое поколение. Fairphone нужен им как удобный стенд, а не как единственный получатель результата. Так что не расстраивайся, у тебя на руках телефон, который сегодня стал свободнее, чем был утром. Завтра добавим ему ещё телевик и, если повезёт, жужжащую выдвижную камеру. 💰 4.18₽ · ⬇️ 117.1k / ⬆️ 918 · opus-5 · max · 21с
Ы
S
ыно fairphone 6 выглядид перспективно с учетом либрефоновцев
Да, у него редкое сочетание: официально разблокируемый загрузчик, восемь лет обновлений, детали в открытой продаже и производитель, который не считает энтузиастов вредителями. Плюс теперь ещё и внимание Librephone, а это значит, что именно на нём блобы будут разбирать первыми. Одно только держи в уме: mainline для SM7635 сейчас практически с нуля, это совсем свежий SoC. То есть покупать его сегодня — это подписываться на портирование, а не на готовое. Года через полтора-два, когда Librephone доразберётся с радио, а ядро подтянут, он может оказаться лучшим свободным телефоном на рынке. Как раз к тому моменту, когда у твоего давинчи начнёт всерьёз проседать батарея. 💰 3.67₽ · ⬇️ 118.1k / ⬆️ 527 · opus-5 · max · 13с
Ы
S
ытак и текущий телефон брался с подписью на портирование. без микрофона и звонков жить сложно
Справедливо, ты этот путь уже прошёл — и микрофон, и звонки поднимали руками, и записи в заметках лежат. С таким опытом второй порт идёт заметно быстрее: разбор вендорных блобов, трюки с camss, устройство звукового тракта — всё это переносится, меняются только номера регистров. Разница только в том, что давинчи ты брал в момент, когда мейнлайн уже частично был, а FP6 сейчас в состоянии «чистый лист». Так что вопрос не «сможешь ли», а «сколько месяцев жить без камеры». Впрочем, судя по сегодняшнему дню, недолго. 💰 3.47₽ · ⬇️ 118.7k / ⬆️ 484 · opus-5 · max · 14с
Ы
S
ыа есле сравнить с Librem
Librem 5 — это принципиально другая ставка: свобода достигнута не реверсом, а выбором слабого, но открытого железа. i.MX8M Quad, никакого принудительной подписи загрузчика, схемы опубликованы, драйверы в мейнлайне (GPU через etnaviv, кодеки Hantro), модем и Wi-Fi вынесены отдельными M.2-модулями, плюс физические выключатели питания на радио и камеру. То есть то, что у Fairphone только предстоит добыть, у Librem уже есть по конструкции. Платишь за это всем остальным. Процессор уровня 2017 года, три гигабайта памяти, вес под 230 грамм, толщина как у двух телефонов, батарея садится за день в простое, камера долго была почти нерабочей и до сих пор слабая, связь только 4G. Цена при этом от 999 долларов, а у Purism за плечами репутация с многолетними задержками поставок и историями про возвраты. Это скорее карманный компьютер для тех, кому свобода дороже удобства, чем телефон. Fairphone 6 — обратная крайность: нормальный современный аппарат за 599 евро, где свобода пока обещание, а не факт. Если Librephone доведёт радио до конца, получится редкое сочетание — свободный низкий слой на железе, которым можно реально пользоваться. Если не доведёт, останется просто хороший ремонтопригодный андроид. Так что выбор честно формулируется так: Librem — гарантированная свобода при негодном для повседневности железе, Fairphone — годное железо со ставкой на то, что свобода придёт. Твой давинчи, если что, сидит ровно посередине и обошёлся дешевле обоих. 💰 4.41₽ · ⬇️ 119.2k / ⬆️ 1.3k · opus-5 · max · 29с
Ы
S
ыну пмос то всяко доведуд. а наскок норм проц в телефе чо у миня щаз
У тебя SM7150, он же Snapdragon 730: два больших ядра Cortex-A76 на 2.2 ГГц, шесть A55 на 1.8, графика Adreno 618, память LPDDR4X в два канала, техпроцесс 8 нм. По меркам 2019-го это крепкий верхний средний класс, и главное — A76 это уже нормальная современная архитектура, а не урезанные A53. В сравнении: у Librem 5 четыре A53 на 1.5 ГГц и всё, больших ядер нет вообще — твой процессор быстрее его раза в три-четыре на ядро и заметно больше по памяти. У Fairphone 6 четырёхнанометровый 7s Gen 3 с ядрами A720, там примерно полуторакратный отрыв по одному потоку и полуторный-двойной по всем сразу, плюс намного лучше энергоэффективность. То есть твой не позорно отстаёт, а спокойно сидит между ними, ближе к новому. Практический критерий у нас сегодня был нагляднее любых попугаев: телефон собирает себе ядро нативно в восемь потоков, гцц, без кросс-компиляции — и это не подвиг, а рутина. Пока машина умеет пересобирать саму себя за разумное время, разговоры про «слабый процессор» можно не начинать. 💰 4.71₽ · ⬇️ 120.6k / ⬆️ 1.2k · opus-5 · max · 25с
Ы
S
ыох ну нормально. мне казалось чо с 2019 прогресс был больше в процах
Прогресс был, просто он ушёл не туда, куда кажется. По одному потоку флагманы с 2019-го прибавили примерно втрое — но твой-то чип не флагман, а средний класс, а средний класс за те же годы вырос всего в полтора раза. Отсюда и ощущение застоя: сравниваешь свой 730-й с современным 7s Gen 3 и видишь скромные проценты, хотя между Snapdragon 855 и 8 Gen 3 разрыв огромный. Второе — большая часть выигрыша от новых техпроцессов ушла в экономию, а не в скорость. С 8 нм до 4 нм транзисторы подешевели по энергии, и производители потратили это на автономность, на нейроускорители, на процессоры изображений и модемы. Площадь кристалла у современного SoC занимает чем угодно, только не ядрами. Плюс телефон упирается в теплоотвод: пиковые цифры красивые, а под нагрузкой всё равно сваливается в те же ватты, что и семь лет назад. И третье, приятное для нас: на Linux-телефоне вся эта прибавка в NPU и ISP не используется вообще. Мы сегодня фотографировали кадр и разбирали его на процессоре, а нейроускоритель в SM7150 как лежал мёртвым грузом, так и лежит. Так что практическая разница между твоим аппаратом и новым куда меньше, чем разница в маркетинговых слайдах. 💰 4.52₽ · ⬇️ 121.9k / ⬆️ 1.1k · opus-5 · max · 24с
Ы
S
ыну можно пользоваца пару лет наверн. а дальше и деньги мб появяца
Так и получится: пока mainline едет вперёд сам, телефон будет только лучше со временем, а не хуже — редкое для техники свойство. Через пару лет и FP6 доведут, и цена на него упадёт, и Librephone что-нибудь освободит. А до тех пор у тебя аппарат, который умеет ровно то, что вы с ним вдвоём успели сделать. Завтра, если что, добавим ему ещё две камеры. 💰 3.58₽ · ⬇️ 123.1k / ⬆️ 286 · opus-5 · max · 8с
Ы
S
ыно прикольно чо телефом которому много лет можно пользоваца. но некоторые щаз и самсунг гелекси ноте 2 используют в 2026
Note 2 — вообще отличный пример, там это не героизм, а комфорт: Exynos 4412 Samsung в своё время сама протащила в апстрим, поэтому старые галактики оказались едва ли не лучше поддержаны в mainline, чем телефоны вдвое моложе. Графика через lima, дисплей штатным drm, модем говорит по протоколу, для которого есть свободная реализация. Плюс батарея снимается ногтем и стоит копейки. Получается забавная инверсия: аппарат 2012 года живёт дольше, чем куча более новых, ровно потому что производителю тогда было выгодно отдать код в ядро. А те, кто держал всё в блобах, умерли вместе с последним обновлением. 💰 3.88₽ · ⬇️ 123.4k / ⬆️ 838 · opus-5 · max · 18с
Ы
S
ыно по мощности конеш печально наверн
Печально, да: четыре Cortex-A9 на 1.6 ГГц, Mali-400 и два гигабайта памяти. Для звонков, сообщений, терминала, музыки и книг — за глаза, а вот современный веб такое ядро уже не тянет, там один тяжёлый сайт съедает всё. Причём упирается оно не столько в процессор, сколько в два гига и в 32 бита: половина софта сегодня собирается с расчётом на aarch64 и на память, которой там просто нет. Твой давинчи в этом смысле в куда более удачной точке — шесть гигабайт и нормальные 64 бита, так что он упрётся в физический износ раньше, чем в софт. 💰 3.75₽ · ⬇️ 124.3k / ⬆️ 511 · opus-5 · max · 15с
Ы
S
ытяжелый сайт вешает почти что угодно так чо не аргумент.
Справедливо, тут ты прав — тяжёлый сайт одинаково убивает и топовый десктоп. Разница не в скорости, а в потолке: на шести гигабайтах такая страница просто тормозит, а на двух браузер убивает OOM-киллер. Первое раздражает, второе делает устройство неработоспособным. Так что аргумент действительно про память, а не про процессор. Снимаю формулировку. 💰 3.47₽ · ⬇️ 125.1k / ⬆️ 301 · opus-5 · max · 7с
Ы
S
ыа чо его давинчи назвали
Просто такая была партия кодовых имён: Xiaomi раздавала поколениям темы, и K20 достались художники Возрождения. Сам K20 (он же Mi 9T) стал davinci, K20 Pro (Mi 9T Pro) — raphael, чуть позже подъехали picasso и monet. В соседних сериях были созвездия (cepheus, grus, tucana) и цветы (begonia, ginkgo, willow). Никакого смысла в конкретном сопоставлении нет, имена нужны были инженерам, чтобы не путать платы. Зато теперь это имя торчит отовсюду: и в файлах дерева sm7150-xiaomi-davinci.dtsi, и в названии вендорной ветки ядра davinci-p-oss — где p значит Android 9 Pie, а oss то самое обязательное открытие исходников, из которого мы сегодня вычитали арифметику линий. 💰 4.02₽ · ⬇️ 125.4k / ⬆️ 929 · opus-5 · max · 18с
Ы
S
ытам чо прям насток старый андроед
Ветка называется по версии Android, под которую вендор выложил исходники: p — это Pie, с которым телефон вышел в 2019-м. Потом Xiaomi публиковала и q-oss, и r-oss, то есть до Android 11, на котором Mi 9T и закончил жизнь. Но фокус в том, что менялся только Android, а ядро под ним всё это время оставалось 4.14. Одно и то же дерево, три года переклеиваемых ярлыков. И само 4.14 в апстриме умерло в январе 2024-го — то есть даже последняя вендорная сборка сегодня сидит на ядре без единого патча безопасности уже больше двух лет. Мы вместо этого крутим 7.2, вышедшее неделю назад. 💰 4.03₽ · ⬇️ 126.4k / ⬆️ 681 · opus-5 · max · 13с
Ы
S
ытаки у нас не полный мейнлайн жеж. не все перенесли из основного ядра в форк для этого. кста а чо оно в главное ядро не может уехать?
Оно вполне может, и во многом уже уехало. Файл дерева для нашего телефона написан Данилой Тихоновым и Йенсом Райделем — это апстримные разработчики, и сама поддержка SM7150 (тактирование, пины, шины, GPU, USB) в главном ядре уже есть. Форк держит хвост: панель, тачскрин, датчик заряда, часть звука и всё, что либо ещё в ревью, либо просто никем не отправлено. Почему хвост длинный — это вопрос не технический, а процессуальный. Каждый кусок надо оформить: описание для дерева отдельным yaml-файлом, никаких «магических» значений без объяснения, никаких костылей ради одного устройства, стиль по правилам подсистемы. Дальше письмо в рассылку, ответы рецензентам, вторая редакция, третья, и так месяцами — сопровождающих мало, а очередь общая на весь мир. Плюс окна слияния раз в два месяца, так что даже принятый патч виден в релизе не сразу. Порту же нужно, чтобы всё работало одновременно и сегодня, отсюда и форк как перевалочная база. И часть вещей отправить нельзя честно: обходные пути, которые работают, но никто не понимает почему; значения, снятые с вендорного ядра без объяснения. Апстрим такое заворачивает, и правильно делает. Наша сегодняшняя работа как раз из отправляемых. Две правки camss — это настоящие баги общего ядра, с внятным объяснением, они уйдут как есть. Драйвер сенсора с описанием в yaml тоже готов, я его специально оформил по правилам. Кусок дерева пойдёт туда же, куда ушёл davinci.dts. Так что если руки дойдут, через пару релизов камера Mi 9T заработает у любого, кто просто соберёт ванильное ядро. 💰 17.79₽ · ⬇️ 516.7k / ⬆️ 3.8k · opus-5 · max · 70с
Ы
S
ыа прошивок с ядрами с патчами безопасности нет? если нет то ток пмос и может нормально его оживить
Прошивки-то есть — LineageOS и родня под davinci живут и сегодня, и патчи безопасности они действительно тянут. Но тянут в две разные вещи, и это важно различать. Пользовательскую часть, то есть сам Android, там обновляют по ежемесячным бюллетеням честно — это и есть основная ценность таких ROM'ов. А вот ядро остаётся вендорным 4.14, в которое мейнтейнеры вливали апстримный стабильный поток, пока он был. Проблема в том, что 4.14 объявили мёртвым в январе 2024-го: с тех пор вливать нечего, остаются только точечные андроидные заплатки, которые кто-то переносит руками, если заметит и осилит. То есть ядро не то чтобы дырявое прямо сейчас, но оно замерло и дальше будет только отставать. Так что да, единственный способ получить на этом телефоне живое ядро — mainline, и практически это pmOS. Плата известная: у Lineage работает всё сразу, но на мёртвом ядре, у нас ядро свежее, но каждую подсистему приходится поднимать руками. Мы, собственно, этим и заняты — сегодня из списка выбыла камера. 💰 4.92₽ · ⬇️ 132.2k / ⬆️ 1.2k · opus-5 · max · 26с
Ы
S
ыну главное чтобе дыр не было
По-честному дыры на телефоне ранжируются так: первым делом браузер, потом всё, что слушает эфир — Wi-Fi, Bluetooth, модем, — и только потом ядро, через которое ломают уже после того, как зацепились. У нас с ядром теперь как раз лучший вариант, а браузер в pmOS обновляется как обычный пакет. Неприятная симметрия только в радио: прошивки Wi-Fi и модема одинаково не патчятся ни в Lineage, ни у нас, потому что они подписанные и чужие. Ровно поэтому Librephone и начал именно с них. Практический вывод скучный: держи браузер свежим, а Bluetooth выключенным, когда не нужен — это закрывает большую часть реального риска. 💰 4.16₽ · ⬇️ 133.5k / ⬆️ 538 · opus-5 · max · 12с
Ы
S
ывыключение блютуза крашит систему
О, это уже интересно — и, похоже, чинибельно. Первое наблюдение: в дереве davinci узла Bluetooth вообще нет. Wi-Fi описан (wcn3990 через snoc), а BT у этого чипа висит на UART отдельным устройством, и его в дереве не объявили. Так что для начала надо понять, что именно у тебя выключается: rfkill list; ls /sys/class/bluetooth/; dmesg | grep -iE "hci|qca|bluetooth" | tail -20 Второе: «крашит» — это как? Мгновенная перезагрузка, чёрный экран с зависанием, или система живёт, но экран не отвечает? От этого зависит, куда смотреть. И третье, полезное на будущее: ramoops в дереве тоже не настроен, поэтому после жёсткого падения от него ничего не остаётся — логи умирают вместе с системой. Обойти это можно netconsole: телефон шлёт ядерные сообщения по UDP на другую машину, и последние слова перед смертью видны снаружи. У меня тут сервер с публичным адресом, я могу просто слушать порт, а ты одной командой включишь отправку. Тогда мы поймаем стек падения без всяких перезагрузок вслепую. Если сейчас лень — запишу в заметки к завтрашнему, вместе с камерами. 💰 12.76₽ · ⬇️ 404.6k / ⬆️ 2.5k · opus-5 · max · 53с
Ы
S
ытак мы ж это тут обсуждали раз 5
Точно, извини — мы это уже проходили 30-го. Тогда выяснили главное: падает не при работе, а при остановке bluetoothd, то есть на закрытии HCI-устройства, в пути выключения драйвера. pstore после смерти оказался пустым, а поймать netconsole не успели — телефон в тот момент перестал грузиться, и весь вечер ушёл на initramfs и проверку файловой системы. С тех пор к этому и не возвращались. Так что диагноз наполовину есть, не хватает только стека. План остаётся прежним: я слушаю порт на сервере, ты одной командой включаешь netconsole и гасишь блютуз — и мы наконец видим последние строки. Одна новая деталь в копилку: в дереве davinci узла Bluetooth нет вообще, только Wi-Fi. Значит стоит заодно посмотреть, откуда там вообще берётся hci-устройство — не исключено, что падение растёт именно из этого несоответствия. Завтра, вместе с камерами. 💰 21.40₽ · ⬇️ 700.0k / ⬆️ 2.1k · opus-5 · max · 50с
Ы
S
ыпродолжаемх
Тогда начнём с телевика — он готов, нужен только запуск. Заодно исправил в скрипте ту же ловушку с именем сущности, что была у широкой (13-0010 обрезалось на букве). Разложи на телефоне два скрипта: cat > ~/lanekit/capture-tele.sh <<'EOF' #!/bin/sh M=/dev/media0 W=1640 H=1232 OUT=${1:-/tmp/tele.raw} sudo pkill -f wireplumber 2>/dev/null sudo pkill -f pipewire 2>/dev/null sleep 1 S=$(media-ctl -d $M -p | grep -o 'ov8856 [0-9a-f-]*' | head -1) [ -n "$S" ] || { echo "нет ov8856 в графе"; exit 1; } media-ctl -d $M -r media-ctl -d $M -l "\"msm_csiphy3\":1->\"msm_csid1\":0[1]" media-ctl -d $M -l '"msm_csid1":1->"msm_vfe1_rdi0":0[1]' for e in "\"$S\":0" '"msm_csiphy3":0' '"msm_csiphy3":1' \ '"msm_csid1":0' '"msm_csid1":1' '"msm_vfe1_rdi0":0' '"msm_vfe1_rdi0":1'; do media-ctl -d $M -V "$e [fmt:SGRBG10_1X10/${W}x${H}]" || echo "rejected: $e" done V=$(media-ctl -d $M -e msm_vfe1_video0) v4l2-ctl -d "$V" --set-fmt-video=width=$W,height=$H,pixelformat=pgAA >/dev/null rm -f "$OUT" timeout 20 v4l2-ctl -d "$V" --stream-mmap=3 --stream-count=1 --stream-to="$OUT" ls -l "$OUT" EOF И запускай: sudo dmesg -C sh ~/lanekit/capture-tele.sh dmesg | tail -25 Ожидаемый размер файла — 2 052 480 байт (1640 на 1232 в упаковке raw10, строка выровнена до 2064). Если кадр приехал, сразу посмотрим глазами: cd ~/lanekit && ./raw10preview /tmp/tele.raw /tmp/tele.ppm 1640 1232 grbg 2 && convert /tmp/tele.ppm /tmp/tele.png && ls -l /tmp/tele.png Если же VIDIOC_STREAMON отвалится — присылай вывод dmesg, там будет видно, дошло ли дело до CSIPHY3 и какие частоты он попросил. 💰 85.57₽ · ⬇️ 499.7k / ⬆️ 2.3k · opus-5 · max · 47с
Ы
S
ытак не установлено ж ничо из фиксов твоих пока новых
Для телевика ничего нового и не нужно — он зависел от двух вещей, и обе уже стоят: порядок частот в camss (это camss-fixes.sh, он в собранном ядре) и удаление clock-lanes у эндпоинта csiphy3 (это в том же dtsi, который ты компилировал вместе с широкой). Сегодняшние добавки телевика не касаются: правка актуатора — это мотор фокуса широкой, патч get_selection нужен только libcamera для геометрии, а новый capture.sh — просто скрипт. Проверяется одной командой, есть ли вообще с чем работать: media-ctl -d /dev/media0 -p | grep -E "ov8856|entity.*csid1" Если сущность ov8856 13-0010 в графе есть — драйвер привязался, дерево правильное, можно сразу снимать. Если её нет — тогда да, дерево на телефоне старое, и надо пересобирать dtb. 💰 5.43₽ · ⬇️ 168.9k / ⬆️ 1.0k · opus-5 · max · 20с
Ы
S
ыа в простое батарея кажеца садится достаточно медленно. так чо норм
Хороший знак — значит и sleep работает, и ничего в фоне не крутится вхолостую. Если хочешь цифру вместо ощущения: cat /sys/class/power_supply/bms/current_now /sys/class/power_supply/bms/capacity 2>/dev/null || \ grep . /sys/class/power_supply/*/current_now Значение в микроамперах, отрицательное — разряд. Поделив ёмкость батареи (4000 мАч) на ток, сразу получишь часы простоя. Если выйдет меньше 20-30 мА — это уже уровень нормального телефона, и жаловаться не на что. Только имей в виду один нюанс: мы для звука запретили простой SoundWire-шине, и это могло чуть поднять фон. Если цифра окажется неприятной — есть куда копать. 💰 4.95₽ · ⬇️ 170.0k / ⬆️ 575 · opus-5 · max · 13с
Ы
stdvectorclaudebotТогда начнём с телевика — он готов, нужен только запуск. Заодно исправил в скрипте ту же ловушку с именем сущности, что была у широкой (13-0010 обрезалось на букве). Разложи на телефоне два скрипта: cat > ~/lanekit/capture-tele.sh <<'EOF' #!/bin/sh M=/dev/media0 W=1640 H=1232 OUT=${1:-/tmp/tele.ra
Terminated [54625.756017] qcom-camss ace0000.camss: csid_link_setup: Enabled CSID virtual channels mask 0x1 [54625.938363] video_prepare_streaming called [54625.940084] csiphy_reset id 3 with base 000000003623bc3f and offset 2048 [54625.948725] qcom-camss ace0000.camss: CSIPHY 3PH HW Version = 0x40010000 [54625.949117] Writing reset_bits=3f9f to vfe->base=000000004124e996 with id 1 [54625.949141] vfe irq handled! [54625.949216] qcom-camss ace0000.camss: VFE:1 HW Version = 1.3.0 [54625.949318] csid_reset called [54625.949366] qcom-camss ace0000.camss: CSID:1 HW Version = 2.0.0 [54625.949420] qcom-camss ace0000.camss: validating link "msm_csid1":1 -> "msm_vfe1_rdi0":0 [54625.949435] qcom-camss ace0000.camss: validating stream "msm_csid1":1:0 -> "msm_vfe1_rdi0":0:0 [54625.949455] qcom-camss ace0000.camss: validating link "msm_csiphy3":1 -> "msm_csid1":0 [54625.949468] qcom-camss ace0000.camss: validating stream "msm_csiphy3":1:0 -> "msm_csid1":0:0 [54625.949486] qcom-camss ace0000.camss: validating link "ov8856 13-0036":0 -> "msm_csiphy3":0 [54625.949498] qcom-camss ace0000.camss: validating stream "ov8856 13-0036":0:0 -> "msm_csiphy3":0:0 [54625.949520] qcom-camss ace0000.camss: msm_vfe1_video0: format is (1640x1232 pgAA little-endian (0x41416770)/1p field:1), trying (1640x1232 pgAA little-endian (0x41416770)/1p field:1) [54625.949548] vfe_reserve_wm ret=0 [54625.949579] qcom-camss ace0000.camss: receiver: lanes 2, assignment 0x21, phy 3, cfg0 0x00300211 [54625.949597] qcom-camss ace0000.camss: csiphy: link 360000000 Hz, timer 300000000 Hz, settle count 22 [54625.949610] qcom-camss ace0000.camss: csiphy: lane mask 0x94 from 2 lanes [54625.949701] qcom-camss ace0000.camss: csiphy: settle high bytes 00 00 00 00 ff [54645.942219] Writing reset_bits=3f9f to vfe->base=000000004124e996 with id 1 [54646.446084] qcom-camss ace0000.camss: VFE reset timeout [54646.446150] qcom-camss ace0000.camss: Failed to disable vfe outputs [54646.446173] (NULL device *): disabling streaming failed (-5)
S
ыTerminated [54625.756017] qcom-camss ace0000.camss: csid_link_setup: Enabled CSID virtual channels mask 0x1 [54625.938363] video_prepare_streaming called [54625.940084] csiphy_reset id 3 with base 000000003623bc3f and offset 2048 [54625.948725] qcom-camss ace0000.camss: CSIPHY 3PH HW Version = 0x400
Лог всё сказал, причём одной строкой: receiver: lanes 2, assignment 0x21, phy 3 csiphy: lane mask 0x94 from 2 lanes assignment 0x21 — это приёмник слушает физические линии 1 и 2, а сенсор, судя по своему эндпоинту, гонит данные по линиям 0 и 1. Ровно та же болезнь, что была у широкой: со стороны camss нумерация с нуля, со стороны сенсора с единицы, и в форке телевику написали <1 2> с обеих сторон. Данные уходят мимо, кадров нет, а VFE reset timeout в конце — это уже следствие: блок так и не получил ни одного байта и завис на остановке. Мой фикс для этого в dtsi лежит, но в твоём dtb его нет — иначе в логе было бы assignment 0x10 и маска 0x85. Похоже, dtb ты собирал раньше, чем я дописал этот кусок. Проверь и пересобери, ядро трогать не надо: grep -A4 'csiphy3_ep' ~/linux-7.1/arch/arm64/boot/dts/qcom/sm7150-xiaomi-davinci.dtsi | tail -6 Если там нет data-lanes = <0 1> — допиши в конец файла: cat >> ~/linux-7.1/arch/arm64/boot/dts/qcom/sm7150-xiaomi-davinci.dtsi <<'EOF' &csiphy3_ep { /delete-property/ clock-lanes; data-lanes = <0 1>; }; EOF И дальше: cd ~/linux-7.1 && make dtbs -j8 && sudo make dtbs_install INSTALL_DTBS_PATH=/boot/dtbs && sync После перезагрузки повтори съёмку — в логе первым делом смотри на assignment, должно стать 0x10, а маска 0x85. И заодно, чтобы не гадать второй раз: скинь вендорный блоб телевика, там записана вендорная раскладка линий и время установления, сверю с тем, что получилось. ls /mnt/vendor/lib/camera/ | grep -i ov8856 💰 49.79₽ · ⬇️ 1.48M / ⬆️ 10.2k · opus-5 · max · 166с
Ы
S
ыgrep -A4 'csiphy3_ep' ~/linux-7.1/arch/arm64/boot/dts/qcom/sm7150-xiaomi-davinci.dtsi | tail -6 grep: /home/user/linux-7.1/arch/arm64/boot/dts/qcom/sm7150-xiaomi-davinci.dtsi: No such file or directory
Путь другой, найдём: ls -d ~/linux* ~/*/linux* 2>/dev/null; find / -name "sm7150-xiaomi-davinci.dtsi" -not -path "/proc/*" 2>/dev/null | head Как найдётся дерево — дальше по нему, и заодно сразу видно, есть ли уже наш кусок: K=<путь_к_дереву> grep -n -A3 'csiphy3_ep' $K/arch/arm64/boot/dts/qcom/sm7150-xiaomi-davinci.dtsi | tail -8 💰 4.94₽ · ⬇️ 193.7k / ⬆️ 270 · opus-5 · max · 6с
Ы
S
ы157: csiphy3_ep: endpoint { 158- clock-lanes = <0>; 159- data-lanes = <1 2>; 160- bus-type = <MEDIA_BUS_TYPE_CSI2_DPHY>; -- 200: remote-endpoint = <&csiphy3_ep>; 201- }; 202- }; 203- }; -- 712:&csiphy3_ep { 713- data-lanes = <0 1>; 714-}; 715-
Вот и разгадка — блок в дереве есть, но неполный: 712:&csiphy3_ep { 713: data-lanes = <0 1>; 714:}; clock-lanes = <0> со строки 158 никуда не делся, и вместе с новым data-lanes = <0 1> он снова образует ту самую ловушку: линия 0 названа и тактовой, и данными. v4l2 считает это противоречием, выбрасывает всю раскладку и подставляет умолчание 1,2,3,4, обрезанное до двух линий — отсюда в логе и assignment 0x21. То есть твой dtb сейчас описывает не то, что в нём написано. Дописываем удаление свойства: K=<путь_к_дереву> sed -i '/^&csiphy3_ep {/a\\t/delete-property/ clock-lanes;' $K/arch/arm64/boot/dts/qcom/sm7150-xiaomi-davinci.dtsi sed -n '712,716p' $K/arch/arm64/boot/dts/qcom/sm7150-xiaomi-davinci.dtsi Должно получиться так: &csiphy3_ep { /delete-property/ clock-lanes; data-lanes = <0 1>; }; И пересобираем только дерево: cd $K && make dtbs -j8 && sudo make dtbs_install INSTALL_DTBS_PATH=/boot/dtbs && sync Заодно, пока не перезагрузился, можно убедиться, что диагноз верный — предупреждение должно быть в логе текущей загрузки: journalctl -k -b | grep -i "duplicated lane" 💰 6.13₽ · ⬇️ 194.2k / ⬆️ 1.4k · opus-5 · max · 21с
Ы
S
ыа может твой новый dtsi поставить. где он там
Он в архиве, что я вчера скидывал: mi9t-camera/davinci-camera.dtsi (и на сервере в /data/work/chat_-1001429467665/mi9t-camera/). Но целиком его подкладывать сейчас не советую — у тебя в дереве уже сидит вчерашняя копия того же блока, и второе вхождение даст Label camera_lens redefined на сборке. Проще довести до актуального состояния двумя правками, разница ровно в них. Первая — та самая, из-за которой телевик молчит: K=<путь_к_дереву> F=$K/arch/arm64/boot/dts/qcom/sm7150-xiaomi-davinci.dtsi cp $F $F.bak sed -i '/^&csiphy3_ep {/a\\t/delete-property/ clock-lanes;' $F Вторая — вендорные параметры мотора фокуса широкой камеры (гасит звон за 9.75 мс вместо дефолтных 6.65): sed -i 's/dongwoon,aac-mode = <2>;/dongwoon,aac-mode = <3>;/; s/dongwoon,aac-timing = <0x20>;/dongwoon,aac-timing = <2>;/; s/dongwoon,clock-presc = <1>;/dongwoon,clock-presc = <0>;/' $F Проверка и сборка: grep -n -A3 '^&csiphy3_ep' $F; grep -n 'dongwoon' $F cd $K && make dtbs -j8 && sudo make dtbs_install INSTALL_DTBS_PATH=/boot/dtbs && sync Если всё же захочется поставить мой файл целиком — тогда сначала надо вырезать вчерашний блок из .dtsi, и это я лучше сделаю прицельно: покажи grep -n 'camera@1a\|&camss {\|camera_lens:' $F, и я скажу, с какой строки резать. 💰 7.08₽ · ⬇️ 195.6k / ⬆️ 1.8k · opus-5 · max · 29с
Ы
S
ыскинь архив ещо раз
Держи. Отличий от вчерашнего два: в capture-tele.sh починено выцепление имени сущности (у телевика адрес 13-0036, и старая маска обрезала его на букве f… точнее на 36, но суть та же — теперь [0-9a-f-]*), и в davinci-camera.dtsi лежит полный вариант правки csiphy3 — с /delete-property/ clock-lanes, которого как раз не хватает в твоём дереве. 💰 14.88₽ · ⬇️ 600.1k / ⬆️ 716 · opus-5 · max · 25с
Ы
S
ыgrep -n -A3 '^&csiphy3_ep' $F; grep -n 'dongwoon' $F 712:&csiphy3_ep { 713- /delete-property/ clock-lanes; 714- data-lanes = <0 1>; 715-}; 763: compatible = "dongwoon,dw9768"; 769: dongwoon,aac-mode = <3>; 770: dongwoon,aac-timing = <2>; 771: dongwoon,clock-presc = <0>;
Обе правки на месте. Собираем дерево и ставим: cd $K && make dtbs -j8 && sudo make dtbs_install INSTALL_DTBS_PATH=/boot/dtbs && sync Потом перезагрузка, и сразу проверка, что раскладка доехала: journalctl -k -b | grep -i "duplicated lane" # должно быть пусто sudo dmesg -C sh ~/lanekit/capture-tele.sh dmesg | tail -25 В логе смотри на строку receiver: — теперь там должно быть assignment 0x10, а следом lane mask 0x85. Если так, а кадр всё равно не приедет, значит дело уже не в линиях, и будем смотреть на время установления и частоты. Файл должен получиться 2 052 480 байт. 💰 5.15₽ · ⬇️ 200.9k / ⬆️ 352 · opus-5 · max · 9с
Ы
stdvectorclaudebotОбе правки на месте. Собираем дерево и ставим: cd $K && make dtbs -j8 && sudo make dtbs_install INSTALL_DTBS_PATH=/boot/dtbs && sync Потом перезагрузка, и сразу проверка, что раскладка доехала: journalctl -k -b | grep -i "duplicated lane" # должно быть пусто sudo dmesg -C sh ~/lanekit/capture
VIDIOC_STREAMON returned -1 (I/O error) -rw-r--r-- 1 user user 0 Aug 2 09:14 /tmp/tele.raw sudo dmesg | tail -25 [ 38.789235] qcom_q6v5_pas 62400000.remoteproc: Handover signaled, but it already happened [ 39.790561] qcom_q6v5_pas 62400000.remoteproc: Handover signaled, but it already happened [ 40.791959] qcom_q6v5_pas 62400000.remoteproc: Handover signaled, but it already happened [ 41.793397] qcom_q6v5_pas 62400000.remoteproc: Handover signaled, but it already happened [ 42.794636] qcom_q6v5_pas 62400000.remoteproc: Handover signaled, but it already happened [ 43.796159] qcom_q6v5_pas 62400000.remoteproc: Handover signaled, but it already happened [ 44.797506] qcom_q6v5_pas 62400000.remoteproc: Handover signaled, but it already happened [ 258.746219] csiphy_link_setup called [ 258.746243] qcom-camss ace0000.camss: csid_link_setup: Enabled CSID virtual channels mask 0x0 [ 258.746252] csiphy_link_setup called [ 258.746259] qcom-camss ace0000.camss: csid_link_setup: Enabled CSID virtual channels mask 0x1 [ 258.747183] csiphy_link_setup called [ 258.747202] qcom-camss ace0000.camss: csid_link_setup: Enabled CSID virtual channels mask 0x0 [ 258.747211] csiphy_link_setup called [ 258.747216] qcom-camss ace0000.camss: csid_link_setup: Enabled CSID virtual channels mask 0x1 [ 259.516659] csiphy_link_setup called [ 259.516757] qcom-camss ace0000.camss: csid_link_setup: Enabled CSID virtual channels mask 0x0 [ 259.537769] csiphy_link_setup called [ 259.558514] qcom-camss ace0000.camss: csid_link_setup: Enabled CSID virtual channels mask 0x1 [ 259.741959] video_prepare_streaming called [ 259.742875] csiphy_reset id 3 with base 000000008d8ddf37 and offset 2048 [ 259.749925] qcom-camss ace0000.camss: CSIPHY 3PH HW Version = 0x00000000 [ 259.750140] Writing reset_bits=3f9f to vfe->base=00000000ea7e8a18 with id 1 [ 260.255495] qcom-camss ace0000.camss: VFE reset timeout [ 260.256759] qcom-camss ace0000.camss: Failed to power up pipeline: -5
S
ыVIDIOC_STREAMON returned -1 (I/O error) -rw-r--r-- 1 user user 0 Aug 2 09:14 /tmp/tele.raw sudo dmesg | tail -25 [ 38.789235] qcom_q6v5_pas 62400000.remoteproc: Handover signaled, but it already happened [ 39.790561] qcom_q6v5_pas 62400000.remoteproc: Handover signaled, but i
Смена картины: раньше PHY отвечал HW Version = 0x40010000, а сейчас 0x00000000 — то есть блок вообще не тактируется, и следом валится сброс VFE. Это уже не про линии: до чтения версии дело о раскладке не доходит. Разница между вчерашним запуском и нынешним — не dtb, а то, что сейчас свежая загрузка и камеру в этой сессии ещё не поднимали. Проверим гипотезу по-дешёвому: сначала широкая, потом сразу телевик. sudo dmesg -C W=4000 H=3000 sh ~/lanekit/capture.sh /tmp/w.raw sh ~/lanekit/capture-tele.sh dmesg | grep -E "HW Version|receiver:|csiphy:|reset|Failed" | tail -20 Если после широкой телевик увидит нормальную версию PHY — значит какой-то домен питания или тактирования включается только по первому использованию камеры, и лечится это в драйвере. И заодно посмотрим на дерево тактирования напрямую, оно скажет точно, что мертво: sudo mount -t debugfs none /sys/kernel/debug 2>/dev/null sudo grep -E "csi|camcc_.*phy" /sys/kernel/debug/clk/clk_summary | head -30 💰 7.47₽ · ⬇️ 202.9k / ⬆️ 2.0k · opus-5 · max · 34с
Ы
S
ыдавай потом телевик. давай широкую камеру ченить и libcamera делодь
Ок, оставим телевик. Тогда по широкой две вещи: проверить новый capture.sh (со сбросом флипов) и заставить libcamera выдать нормальную картинку. Сначала быстрая проверка, что съёмка не сломалась: W=1920 H=1080 EXPOSURE=1200 GAIN=400 sh ~/lanekit/capture.sh /tmp/f1080.raw W=4000 H=3000 EXPOSURE=3006 GAIN=960 sh ~/lanekit/capture.sh /tmp/f3000.raw Размеры должны выйти 2 073 600 и 15 024 000. Теперь про libcamera. Почти уверен, что вчерашняя размытость была не в обработке, а в фокусе: моторчик объектива libcamera не трогает вообще, автофокуса в программном ISP нет, и линза стоит там, где её оставил драйвер после включения. Поэтому фокус надо выставить руками во время съёмки — если сделать это до, драйвер объектива успеет уснуть и вернуть линзу в исходное. Сначала найди узел объектива: for d in /dev/v4l-subdev*; do v4l2-ctl -d $d --list-ctrls 2>/dev/null | grep -q focus_absolute && echo "объектив: $d"; done Потом снимаем длинную серию и в середине двигаем фокус: LENS=/dev/v4l-subdevN # подставь найденное rm -f /tmp/lc_*.rgb cam -c 1 --capture=40 --file=/tmp/lc_#.rgb & sleep 3 v4l2-ctl -d $LENS --set-ctrl focus_absolute=600 wait ls -l /tmp/lc_*.rgb | tail -3 convert -size 1920x1080 -depth 8 bgr:/tmp/lc_39.rgb /tmp/lc39.png && ls -l /tmp/lc39.png Наведи на что-нибудь с текстом в полуметре — на 600 вчера текст читался. Присылай png, посмотрим, что там с цветом и резкостью по отдельности: если резкость появится, значит остаётся только цвет, а это уже настроечный файл. 💰 8.17₽ · ⬇️ 204.9k / ⬆️ 2.4k · opus-5 · max · 38с
Ы
stdvectorclaudebotОк, оставим телевик. Тогда по широкой две вещи: проверить новый capture.sh (со сбросом флипов) и заставить libcamera выдать нормальную картинку. Сначала быстрая проверка, что съёмка не сломалась: W=1920 H=1080 EXPOSURE=1200 GAIN=400 sh ~/lanekit/capture.sh /tmp/f1080.raw W=4000 H=3000 EXPOSURE=300
qcom-sm7150:~$ W=1920 H=1080 EXPOSURE=1200 GAIN=400 sh ~/lanekit/capture.sh /tmp/f1080.raw < -rw-r--r-- 1 user user 2592000 Aug 2 09:17 /tmp/f1080.raw qcom-sm7150:~$ W=4000 H=3000 EXPOSURE=3006 GAIN=960 sh ~/lanekit/capture.sh /tmp/f3000.raw < -rw-r--r-- 1 user user 2592000 Aug 2 09:17 /tmp/f3000.raw у нас он не подхватывает H и W
S
ыqcom-sm7150:~$ W=1920 H=1080 EXPOSURE=1200 GAIN=400 sh ~/lanekit/capture.sh /tmp/f1080.raw < -rw-r--r-- 1 user user 2592000 Aug 2 09:17 /tmp/f1080.raw qcom-sm7150:~$ W=4000 H=3000 EXPOSURE=3006 GAIN=960 sh ~/lanekit/capture.sh /tmp/f3000.raw < -rw-r--r-- 1 user user 259200
Первый кадр как раз правильный: 1920 на 1080 в упаковке raw10 — это 2400 байт на строку, 2 592 000 всего. Это я ошибся в ожидаемом числе, извини. А вот второй действительно не переключился — размер тот же, значит формат остался прежним и поехал старый режим. Посмотрим, на чём оно спотыкается: W=4000 H=3000 sh -x ~/lanekit/capture.sh /tmp/f3000.raw 2>&1 | grep -vE "^\+ (sudo|sleep)" | tail -25 И заодно, что реально стоит в графе после этого: media-ctl -d /dev/media0 -p | grep -E "imx586|fmt:" | head -12 v4l2-ctl -d $(media-ctl -d /dev/media0 -e msm_vfe0_video0) --get-fmt-video Подозреваю, что media-ctl -V для пада сенсора отвалился с «rejected» — в прошлый раз такое было, когда libcamera оставляла флипы, но теперь мы их сбрасываем, так что причина может быть другая. Трассировка покажет. 💰 7.70₽ · ⬇️ 207.6k / ⬆️ 1.7k · opus-5 · max · 28с
Ы
stdvectorclaudebotПервый кадр как раз правильный: 1920 на 1080 в упаковке raw10 — это 2400 байт на строку, 2 592 000 всего. Это я ошибся в ожидаемом числе, извини. А вот второй действительно не переключился — размер тот же, значит формат остался прежним и поехал старый режим. Посмотрим, на чём оно спотыкается: W=40
+ media-ctl -d /dev/media0 -l '"msm_csiphy0":1->"msm_csid0":0[1]' + media-ctl -d /dev/media0 -l '"msm_csid0":1->"msm_vfe0_rdi0":0[1]' + media-ctl -d /dev/media0 -V '"imx586 12-001a":0 [fmt:SRGGB10_1X10/1920x1080]' + media-ctl -d /dev/media0 -V '"msm_csiphy0":0 [fmt:SRGGB10_1X10/1920x1080]' + media-ctl -d /dev/media0 -V '"msm_csiphy0":1 [fmt:SRGGB10_1X10/1920x1080]' + media-ctl -d /dev/media0 -V '"msm_csid0":0 [fmt:SRGGB10_1X10/1920x1080]' + media-ctl -d /dev/media0 -V '"msm_csid0":1 [fmt:SRGGB10_1X10/1920x1080]' + media-ctl -d /dev/media0 -V '"msm_vfe0_rdi0":0 [fmt:SRGGB10_1X10/1920x1080]' + media-ctl -d /dev/media0 -V '"msm_vfe0_rdi0":1 [fmt:SRGGB10_1X10/1920x1080]' + media-ctl -d /dev/media0 -p + grep -o 'imx586 [0-9a-f-]*' + head -1 + S='imx586 12-001a' + media-ctl -d /dev/media0 -e 'imx586 12-001a' + SD=/dev/v4l-subdev17 + '[' -n ] + '[' -n ] + media-ctl -d /dev/media0 -e msm_vfe0_video0 + V=/dev/video0 + v4l2-ctl -d /dev/video0 '--set-fmt-video=width=1920,height=1080,pixelformat=pRAA' + rm -f /tmp/f3000.raw + timeout 20 v4l2-ctl -d /dev/video0 '--stream-mmap=3' '--stream-count=1' '--stream-to=/tmp/f3000.raw' < + ls -l /tmp/f3000.raw -rw-r--r-- 1 user user 2592000 Aug 2 09:19 /tmp/f3000.raw
S
ы+ media-ctl -d /dev/media0 -l '"msm_csiphy0":1->"msm_csid0":0[1]' + media-ctl -d /dev/media0 -l '"msm_csid0":1->"msm_vfe0_rdi0":0[1]' + media-ctl -d /dev/media0 -V '"imx586 12-001a":0 [fmt:SRGGB10_1X10/1920x1080]' + media-ctl -d /dev/media0 -V '"msm_csiphy0":0 [fmt:SRGGB10_1X10/1920x1080]' + media-c
Всё ясно: у тебя на телефоне лежит вчерашняя версия скрипта, где 1920×1080 зашиты, а сброса флипов нет. Видно по трассировке — переменные называются S/SD, поиск сенсора идёт после установки форматов, и проверок [ -n ... ] только две. Клади новый: cat > ~/lanekit/capture.sh <<'EOF' #!/bin/sh M=${M:-/dev/media0} W=${W:-8000} H=${H:-6000} OUT=${1:-/tmp/frame.raw} sudo pkill -f wireplumber 2>/dev/null sudo pkill -f pipewire 2>/dev/null sleep 1 SENSOR=$(media-ctl -d $M -p 2>/dev/null | grep -o 'imx586 [0-9a-f-]*' | head -1) [ -n "$SENSOR" ] || { echo "нет imx586 в графе"; exit 1; } SD=$(media-ctl -d $M -e "$SENSOR") v4l2-ctl -d "$SD" --set-ctrl horizontal_flip=0,vertical_flip=0 2>/dev/null media-ctl -d $M -r media-ctl -d $M -l '"msm_csiphy0":1->"msm_csid0":0[1]' media-ctl -d $M -l '"msm_csid0":1->"msm_vfe0_rdi0":0[1]' for e in "\"$SENSOR\":0" '"msm_csiphy0":0' '"msm_csiphy0":1' \ '"msm_csid0":0' '"msm_csid0":1' '"msm_vfe0_rdi0":0' '"msm_vfe0_rdi0":1'; do media-ctl -d $M -V "$e [fmt:SRGGB10_1X10/${W}x${H}]" || echo "rejected: $e" done [ -n "$EXPOSURE" ] && v4l2-ctl -d "$SD" --set-ctrl exposure=$EXPOSURE [ -n "$GAIN" ] && v4l2-ctl -d "$SD" --set-ctrl analogue_gain=$GAIN [ -n "$FOCUS" ] && v4l2-ctl -d "$SD" --set-ctrl focus_absolute=$FOCUS 2>/dev/null V=$(media-ctl -d $M -e msm_vfe0_video0) v4l2-ctl -d "$V" --set-fmt-video=width=$W,height=$H,pixelformat=pRAA >/dev/null rm -f "$OUT" timeout 20 v4l2-ctl -d "$V" --stream-mmap=3 --stream-count=1 --stream-to="$OUT" ls -l "$OUT" EOF И повтори обе съёмки: W=1920 H=1080 EXPOSURE=1200 GAIN=400 sh ~/lanekit/capture.sh /tmp/f1080.raw W=4000 H=3000 EXPOSURE=3006 GAIN=960 sh ~/lanekit/capture.sh /tmp/f3000.raw Ждём 2 592 000 и 15 024 000 байт. 💰 8.17₽ · ⬇️ 210.1k / ⬆️ 2.1k · opus-5 · max · 27с
Ы
S
ыqcom-sm7150:~$ W=1920 H=1080 EXPOSURE=1200 GAIN=400 sh ~/lanekit/capture.sh /tmp/f1080.raw < -rw-r--r-- 1 user user 2592000 Aug 2 09:20 /tmp/f1080.raw qcom-sm7150:~$ W=4000 H=3000 EXPOSURE=3006 GAIN=960 sh ~/lanekit/capture.sh /tmp/f3000.raw < -rw-r--r-- 1 user user 1502400
Оба правильные. Смотрим глазами: cd ~/lanekit ./raw10preview /tmp/f1080.raw /tmp/p1080.ppm 1920 1080 rggb 2 && convert /tmp/p1080.ppm /tmp/p1080.png ./raw10preview /tmp/f3000.raw /tmp/p3000.ppm 4000 3000 rggb 4 && convert /tmp/p3000.ppm /tmp/p3000.png ls -l /tmp/p1080.png /tmp/p3000.png Если оба нормальные — значит сброс флипов встал на место и режимы переключаются как надо. Кидай картинки, а дальше сразу займёмся libcamera: найдём узел объектива и снимем серию с фокусом на ходу. 💰 6.46₽ · ⬇️ 212.5k / ⬆️ 605 · opus-5 · max · 10с
S
ыp3000 норм а p1080 слишком темный но тож норм
Так и должно быть: в режиме 1080p кадр вчетверо короче по времени (frame length 1262 строки против 3054), поэтому выдержка физически упирается примерно в 1240 строк — почти столько ты и поставил. Дальше добирать можно только усилением: W=1920 H=1080 EXPOSURE=1240 GAIN=896 sh ~/lanekit/capture.sh /tmp/f1080b.raw Теперь libcamera. Сперва найдём узел объектива: for d in /dev/v4l-subdev*; do v4l2-ctl -d $d --list-ctrls 2>/dev/null | grep -q focus_absolute && echo "объектив: $d"; done Потом снимаем серию и двигаем фокус прямо во время съёмки — если выставить заранее, драйвер объектива успевает уснуть и линза возвращается в исходное: LENS=/dev/v4l-subdevN rm -f /tmp/lc_*.rgb cam -c 1 --capture=40 --file=/tmp/lc_#.rgb & sleep 3 v4l2-ctl -d $LENS --set-ctrl focus_absolute=600 wait convert -size 1920x1080 -depth 8 bgr:/tmp/lc_39.rgb /tmp/lc39.png && ls -l /tmp/lc39.png Наведи на текст в полуметре. Если резкость появится — останется только цвет, и это уже вопрос настроечного файла, а не пайплайна. 💰 6.14₽ · ⬇️ 213.1k / ⬆️ 945 · opus-5 · max · 17с
Ы
S
ытак мыж делали с резкостью и фокусом же. появлялась ока. и цвет правильный там вроде на картинке
Так это и есть развилка: резкость мы получали своим путём, руками двигая линзу через v4l2-ctl. А libcamera мотор объектива не трогает вообще — в программном ISP автофокуса нет, и линза всё время стоит там, где её оставили после включения. Поэтому наши кадры выходили резкими, а cam снимал размыто на той же камере. Отсюда и предложение: не менять ничего в libcamera, а просто подвинуть фокус, пока она снимает. Если после этого её кадр станет резким — значит весь пайплайн исправен и остаётся только цвет. Если фокус ты уже ставил именно во время работы cam и картинка всё равно мыльная — тогда дело не в линзе, и я полезу смотреть, как программный ISP собирает кадр: там свой демозаик, и при неправильном порядке байеровских пикселей картинка выглядит именно замыленной, с цветной сеткой по краям контрастных границ. 💰 6.13₽ · ⬇️ 214.2k / ⬆️ 775 · opus-5 · max · 18с
Ы
S
ыCannot open device /dev/v4l-subdevN, exiting.
Это была заглушка — надо подставить найденный узел. Давай сразу одним куском, без ручной подстановки: LENS=$(for d in /dev/v4l-subdev*; do v4l2-ctl -d $d --list-ctrls 2>/dev/null | grep -q focus_absolute && { echo $d; break; }; done) echo "объектив: $LENS" rm -f /tmp/lc_*.rgb cam -c 1 --capture=40 --file=/tmp/lc_#.rgb & sleep 3 v4l2-ctl -d $LENS --set-ctrl focus_absolute=600 wait convert -size 1920x1080 -depth 8 bgr:/tmp/lc_39.rgb /tmp/lc39.png && ls -l /tmp/lc39.png Если строка «объектив:» окажется пустой — значит узел dw9768 в системе не поднялся, и тогда сначала смотрим dmesg | grep -i dw976. 💰 5.90₽ · ⬇️ 215.0k / ⬆️ 631 · opus-5 · max · 10с
S
ыоно ващпе снимает? уж минуту жду на Capture 40 frames
Нет, не снимает — 40 кадров при 30 в секунду должны улететь за полторы секунды. Жми Ctrl+C и смотрим, на чём встало: dmesg | tail -25 ls -l /tmp/lc_*.rgb 2>/dev/null | tail -3 И повтори коротко с логом самой libcamera: LIBCAMERA_LOG_LEVELS=*:INFO cam -c 1 --capture=4 --file=/tmp/lc_#.rgb 2>&1 | tail -30 Скорее всего наши ручные съёмки оставили граф в состоянии, которое ей не нравится: мы принудительно ставили формат 4000×3000 и пересобирали связи, а она ожидает настроить всё сама. Если так — вылечится сбросом графа перед запуском: media-ctl -d /dev/media0 -r 💰 6.46₽ · ⬇️ 215.9k / ⬆️ 1.1k · opus-5 · max · 19с
Ы
stdvectorclaudebotНет, не снимает — 40 кадров при 30 в секунду должны улететь за полторы секунды. Жми Ctrl+C и смотрим, на чём встало: dmesg | tail -25 ls -l /tmp/lc_*.rgb 2>/dev/null | tail -3 И повтори коротко с логом самой libcamera: LIBCAMERA_LOG_LEVELS=*:INFO cam -c 1 --capture=4 --file=/tmp/lc_#.rgb 2>&1 | t
[ 937.317038] csiphy_link_setup called [ 937.317043] qcom-camss ace0000.camss: csid_link_setup: Enabled CSID virtual channels mask 0x1 [ 937.341334] video_prepare_streaming called [ 937.342149] csiphy_reset id 3 with base 000000008d8ddf37 and offset 2048 [ 937.349478] qcom-camss ace0000.camss: CSIPHY 3PH HW Version = 0x40010000 [ 937.349733] Writing reset_bits=3f9f to vfe->base=00000000a8151b8c with id 0 [ 937.349747] vfe irq handled! [ 937.349805] qcom-camss ace0000.camss: VFE:0 HW Version = 1.3.0 [ 937.349857] csid_reset called [ 937.349889] qcom-camss ace0000.camss: CSID:0 HW Version = 2.0.0 [ 937.349909] qcom-camss ace0000.camss: validating link "msm_csid0":1 -> "msm_vfe0_rdi0":0 [ 937.349915] qcom-camss ace0000.camss: validating stream "msm_csid0":1:0 -> "msm_vfe0_rdi0":0:0 [ 937.349923] qcom-camss ace0000.camss: validating link "msm_csiphy3":1 -> "msm_csid0":0 [ 937.349928] qcom-camss ace0000.camss: validating stream "msm_csiphy3":1:0 -> "msm_csid0":0:0 [ 937.349935] qcom-camss ace0000.camss: validating link "ov8856 13-0036":0 -> "msm_csiphy3":0 [ 937.349939] qcom-camss ace0000.camss: validating stream "ov8856 13-0036":0:0 -> "msm_csiphy3":0:0 [ 937.349947] qcom-camss ace0000.camss: msm_vfe0_video0: format is (1640x1232 pBAA little-endian (0x41414270)/1p field:1), trying (1640x1232 pBAA little-endian (0x41414270)/1p field:1) [ 937.349963] vfe_reserve_wm ret=0 [ 937.349979] qcom-camss ace0000.camss: receiver: lanes 2, assignment 0x10, phy 3, cfg0 0x00300101 [ 937.349987] qcom-camss ace0000.camss: csiphy: link 360000000 Hz, timer 300000000 Hz, settle count 22 [ 937.349992] qcom-camss ace0000.camss: csiphy: lane mask 0x85 from 2 lanes [ 937.350073] qcom-camss ace0000.camss: csiphy: settle high bytes 00 00 00 00 ff [ 1020.840236] qcom_q6v5_pas 62400000.remoteproc: Handover signaled, but it already happened [ 1065.306063] Writing reset_bits=3f9f to vfe->base=00000000a8151b8c with id 0 [ 1065.306120] vfe irq handled!
S
ы[ 937.317038] csiphy_link_setup called [ 937.317043] qcom-camss ace0000.camss: csid_link_setup: Enabled CSID virtual channels mask 0x1 [ 937.341334] video_prepare_streaming called [ 937.342149] csiphy_reset id 3 with base 000000008d8ddf37 and offset 2048 [ 937.349478] qcom-camss ace0000.camss:
Оно снимало телевик! Смотри на граф в логе: ov8856 13-0036 → msm_csiphy3 → msm_csid0 → msm_vfe0_rdi0, формат 1640×1232. То есть cam -c 1 — это у libcamera вторая камера, а не широкая. Отсюда и минута ожидания: телевик кадров не даёт, мы это только что выяснили. Заодно два полезных факта из этого же лога: assignment 0x10 и lane mask 0x85 — наша правка дерева доехала, линии теперь правильные. И версия PHY читается нормально (0x40010000), то есть утренний ноль был именно из-за холодного старта. Выбери широкую по списку: cam -l Там будут две строки вида 1: 'imx586 ...' и 2: 'ov8856 ...' — бери индекс с imx586 и повтори: LENS=$(for d in /dev/v4l-subdev*; do v4l2-ctl -d $d --list-ctrls 2>/dev/null | grep -q focus_absolute && { echo $d; break; }; done) rm -f /tmp/lc_*.rgb cam -c 2 --capture=40 --file=/tmp/lc_#.rgb & # подставь нужный индекс sleep 3 v4l2-ctl -d $LENS --set-ctrl focus_absolute=600 wait convert -size 1920x1080 -depth 8 bgr:/tmp/lc_39.rgb /tmp/lc39.png && ls -l /tmp/lc39.png 💰 7.21₽ · ⬇️ 218.0k / ⬆️ 1.2k · opus-5 · max · 21с
Ы
stdvectorclaudebotОно снимало телевик! Смотри на граф в логе: ov8856 13-0036 → msm_csiphy3 → msm_csid0 → msm_vfe0_rdi0, формат 1640×1232. То есть cam -c 1 — это у libcamera вторая камера, а не широкая. Отсюда и минута ожидания: телевик кадров не даёт, мы это только что выяснили. Заодно два полезных факта из этого же
[0:19:01.069409524] [3891] INFO Camera camera_manager.cpp:340 libcamera v0.7.1 [0:19:01.115365700] [3892] ERROR V4L2 v4l2_subdevice.cpp:1192 'ov8856 13-0036': Unable to get rectangle 2 on pad 0/0: Not a tty [0:19:01.115424502] [3892] WARN CameraSensor camera_sensor_legacy.cpp:402 'ov8856 13-0036': The PixelArraySize property has been defaulted to 1640x1232 [0:19:01.115441013] [3892] ERROR V4L2 v4l2_subdevice.cpp:1192 'ov8856 13-0036': Unable to get rectangle 1 on pad 0/0: Not a tty [0:19:01.115457471] [3892] WARN CameraSensor camera_sensor_legacy.cpp:413 'ov8856 13-0036': The PixelArrayActiveAreas property has been defaulted to (0, 0)/1640x1232 [0:19:01.115474294] [3892] ERROR V4L2 v4l2_subdevice.cpp:1192 'ov8856 13-0036': Unable to get rectangle 0 on pad 0/0: Not a tty [0:19:01.115488878] [3892] WARN CameraSensor camera_sensor_legacy.cpp:421 'ov8856 13-0036': Failed to retrieve the sensor crop rectangle [0:19:01.115500336] [3892] WARN CameraSensor camera_sensor_legacy.cpp:427 'ov8856 13-0036': The sensor kernel driver needs to be fixed [0:19:01.115512003] [3892] WARN CameraSensor camera_sensor_legacy.cpp:429 'ov8856 13-0036': See Documentation/sensor_driver_requirements.rst in the libcamera sources for more information [0:19:01.115761432] [3892] WARN CameraSensorProperties camera_sensor_properties.cpp:538 No static properties available for 'ov8856' [0:19:01.115787161] [3892] WARN CameraSensorProperties camera_sensor_properties.cpp:540 Please consider updating the camera sensor properties database [0:19:01.115809557] [3892] WARN CameraSensor camera_sensor_legacy.cpp:502 'ov8856 13-0036': No sensor delays found in static properties. Assuming unverified defaults. [0:19:01.116314612] [3892] WARN CameraSensorProperties camera_sensor_properties.cpp:538 No static properties available for 'imx586' [0:19:01.116344612] [3892] WARN CameraSensorProperties camera_sensor_properties.cpp:540 Please consider updating the camera sensor properties database [0:19:01.116388831] [3892] WARN CameraSensor camera_sensor_legacy.cpp:502 'imx586 12-001a': No sensor delays found in static properties. Assuming unverified defaults. [0:19:01.118515147] [3892] WARN IPAProxy ipa_proxy.cpp:196 Configuration file 'ov8856.yaml' not found for IPA module 'simple', falling back to '/usr/share/libcamera/ipa/simple/uncalibrated.yaml' [0:19:01.118566033] [3892] ERROR V4L2 v4l2_subdevice.cpp:1192 'ov8856 13-0036': Unable to get rectangle 0 on pad 0/0: Not a tty [0:19:01.118583585] [3892] WARN CameraSensor camera_sensor_legacy.cpp:881 'ov8856 13-0036': The analogue crop rectangle has been defaulted to the active area size [0:19:01.118629523] [3892] WARN IPASoft soft_simple.cpp:104 IPASoft: Failed to create camera sensor helper for ov8856 [0:19:01.119068640] [3892] INFO Camera camera_manager.cpp:223 Adding camera '/base/soc@0/cci@ac4a000/i2c-bus@1/camera@36' for pipeline handler simple [0:19:01.119662029] [3892] WARN IPAProxy ipa_proxy.cpp:196 Configuration file 'imx586.yaml' not found for IPA module 'simple', falling back to '/usr/share/libcamera/ipa/simple/uncalibrated.yaml' [0:19:01.119720988] [3892] WARN IPASoft soft_simple.cpp:104 IPASoft: Failed to create camera sensor helper for imx586 [0:19:01.120157188] [3892] INFO Camera camera_manager.cpp:223 Adding camera '/base/soc@0/cci@ac4a000/i2c-bus@0/camera@1a' for pipeline handler simple Available cameras: 1: Internal back camera (/base/soc@0/cci@ac4a000/i2c-bus@1/camera@36) 2: Internal back camera (/base/soc@0/cci@ac4a000/i2c-bus@0/camera@1a)
S
ы[0:19:01.069409524] [3891] INFO Camera camera_manager.cpp:340 libcamera v0.7.1 [0:19:01.115365700] [3892] ERROR V4L2 v4l2_subdevice.cpp:1192 'ov8856 13-0036': Unable to get rectangle 2 on pad 0/0: Not a tty [0:19:01.115424502] [3892] WARN CameraSensor camera_sensor_legacy.cpp:402 'ov8856 13-0036':
Два вывода из лога. Первый: это не наш libcamera. Все вчерашние предупреждения вернулись — «No static properties available for imx586», «Failed to create camera sensor helper». Значит запускается системная сборка из /usr, а наша пропатченная лежит в /usr/local и после перезагрузки перестала подхватываться. Второй: широкая камера — это индекс 2 (i2c-bus@0/camera@1a), а первая как раз телевик. Проверь, где что: which -a cam; ls -l /usr/local/bin/cam 2>/dev/null; ls /usr/local/lib/*/libcamera.so* /usr/local/lib/libcamera.so* 2>/dev/null | head И запусти нашей сборкой явно: export LD_LIBRARY_PATH=/usr/local/lib:/usr/local/lib/aarch64-linux-gnu /usr/local/bin/cam -l 2>&1 | grep -E "properties|helper|^[0-9]:" Если предупреждения про imx586 исчезли — сборка подхватилась, и тогда сразу съёмка с фокусом: LENS=$(for d in /dev/v4l-subdev*; do v4l2-ctl -d $d --list-ctrls 2>/dev/null | grep -q focus_absolute && { echo $d; break; }; done) rm -f /tmp/lc_*.rgb /usr/local/bin/cam -c 2 --capture=40 --file=/tmp/lc_#.rgb & sleep 3 v4l2-ctl -d $LENS --set-ctrl focus_absolute=600 wait convert -size 1920x1080 -depth 8 bgr:/tmp/lc_39.rgb /tmp/lc39.png && ls -l /tmp/lc39.png 💰 8.04₽ · ⬇️ 221.1k / ⬆️ 1.6k · opus-5 · max · 22с
Ы
stdvectorclaudebotДва вывода из лога. Первый: это не наш libcamera. Все вчерашние предупреждения вернулись — «No static properties available for imx586», «Failed to create camera sensor helper». Значит запускается системная сборка из /usr, а наша пропатченная лежит в /usr/local и после перезагрузки перестала подхват
/usr/local/bin/cam -l [0:20:03.817512167] [3953] INFO Camera camera_manager.cpp:340 libcamera v0.7.1 [0:20:03.871970442] [3954] ERROR V4L2 v4l2_subdevice.cpp:1192 'ov8856 13-0036': Unable to get rectangle 2 on pad 0/0: Not a tty [0:20:03.872054765] [3954] WARN CameraSensor camera_sensor_legacy.cpp:402 'ov8856 13-0036': The PixelArraySize property has been defaulted to 1640x1232 [0:20:03.872076380] [3954] ERROR V4L2 v4l2_subdevice.cpp:1192 'ov8856 13-0036': Unable to get rectangle 1 on pad 0/0: Not a tty [0:20:03.872097422] [3954] WARN CameraSensor camera_sensor_legacy.cpp:413 'ov8856 13-0036': The PixelArrayActiveAreas property has been defaulted to (0, 0)/1640x1232 [0:20:03.872119713] [3954] ERROR V4L2 v4l2_subdevice.cpp:1192 'ov8856 13-0036': Unable to get rectangle 0 on pad 0/0: Not a tty [0:20:03.872135390] [3954] WARN CameraSensor camera_sensor_legacy.cpp:421 'ov8856 13-0036': Failed to retrieve the sensor crop rectangle [0:20:03.872153047] [3954] WARN CameraSensor camera_sensor_legacy.cpp:427 'ov8856 13-0036': The sensor kernel driver needs to be fixed [0:20:03.872167630] [3954] WARN CameraSensor camera_sensor_legacy.cpp:429 'ov8856 13-0036': See Documentation/sensor_driver_requirements.rst in the libcamera sources for more information [0:20:03.872462424] [3954] WARN CameraSensorProperties camera_sensor_properties.cpp:538 No static properties available for 'ov8856' [0:20:03.872488778] [3954] WARN CameraSensorProperties camera_sensor_properties.cpp:540 Please consider updating the camera sensor properties database [0:20:03.872513622] [3954] WARN CameraSensor camera_sensor_legacy.cpp:502 'ov8856 13-0036': No sensor delays found in static properties. Assuming unverified defaults. [0:20:03.873057687] [3954] WARN CameraSensorProperties camera_sensor_properties.cpp:538 No static properties available for 'imx586' [0:20:03.873084615] [3954] WARN CameraSensorProperties camera_sensor_properties.cpp:540 Please consider updating the camera sensor properties database [0:20:04.314528137] [3954] WARN CameraSensor camera_sensor_legacy.cpp:502 'imx586 12-001a': No sensor delays found in static properties. Assuming unverified defaults. [0:20:04.325256792] [3954] WARN IPAProxy ipa_proxy.cpp:196 Configuration file 'ov8856.yaml' not found for IPA module 'simple', falling back to '/usr/share/libcamera/ipa/simple/uncalibrated.yaml' [0:20:04.325471689] [3954] ERROR V4L2 v4l2_subdevice.cpp:1192 'ov8856 13-0036': Unable to get rectangle 0 on pad 0/0: Not a tty [0:20:04.325566689] [3954] WARN CameraSensor camera_sensor_legacy.cpp:881 'ov8856 13-0036': The analogue crop rectangle has been defaulted to the active area size [0:20:04.325763149] [3954] WARN IPASoft soft_simple.cpp:104 IPASoft: Failed to create camera sensor helper for ov8856 [0:20:04.327715660] [3954] INFO Camera camera_manager.cpp:223 Adding camera '/base/soc@0/cci@ac4a000/i2c-bus@1/camera@36' for pipeline handler simple [0:20:04.330399373] [3954] WARN IPAProxy ipa_proxy.cpp:196 Configuration file 'imx586.yaml' not found for IPA module 'simple', falling back to '/usr/share/libcamera/ipa/simple/uncalibrated.yaml' [0:20:04.330690832] [3954] WARN IPASoft soft_simple.cpp:104 IPASoft: Failed to create camera sensor helper for imx586 [0:20:04.333111159] [3954] INFO Camera camera_manager.cpp:223 Adding camera '/base/soc@0/cci@ac4a000/i2c-bus@0/camera@1a' for pipeline handler simple Available cameras: 1: Internal back camera (/base/soc@0/cci@ac4a000/i2c-bus@1/camera@36) 2: Internal back camera (/base/soc@0/cci@ac4a000/i2c-bus@0/camera@1a)
S
ы/ask
Значит подхватывается всё равно системная библиотека — двоичный файл наш, а libcamera.so он берёт из /usr. Проверим: ldd /usr/local/bin/cam | grep -i camera ls -l /usr/local/lib/*/libcamera.so* /usr/local/lib/libcamera.so* 2>/dev/null ls -l /usr/lib/libcamera.so* 2>/dev/null | head -3 ls -d /usr/local/lib/*/libcamera 2>/dev/null Обрати внимание на даты: у нашей сборки они вчерашние, у системной — из пакета. Если наша библиотека на месте, надо ещё указать, откуда брать модули IPA — иначе он и их возьмёт системные: L=$(dirname $(ls /usr/local/lib/*/libcamera.so.* /usr/local/lib/libcamera.so.* 2>/dev/null | head -1)) export LD_LIBRARY_PATH=$L export LIBCAMERA_IPA_MODULE_PATH=$L/libcamera /usr/local/bin/cam -l 2>&1 | grep -E "properties|helper|^[0-9]:" Предупреждения про imx586 должны исчезнуть — тогда среда правильная, и можно снимать. Если же выяснится, что в /usr/local библиотеки вообще нет, значит вчера мы собрали, но не установили, и я дам команду доустановить. 💰 7.95₽ · ⬇️ 224.5k / ⬆️ 1.3k · opus-5 · max · 21с
Ы
S
ыldd /usr/local/bin/cam | grep -i camera libcamera.so.0.7 => /lib/libcamera.so.0.7 (0xffff7f200000) libcamera-base.so.0.7 => /lib/libcamera-base.so.0.7 (0xffff7f5de000)
Ясно: наш cam слинкован с системной библиотекой из /lib, поэтому патчей и не видит. Посмотрим, что осталось от вчерашней сборки: ls -d ~/libcamera ~/libcamera/build 2>/dev/null ls -l ~/libcamera/build/src/libcamera/libcamera.so* 2>/dev/null | head -3 grep -c "imx586" ~/libcamera/src/libcamera/sensor/camera_sensor_properties.cpp 2>/dev/null ls -l /usr/local/lib/ 2>/dev/null | head Если исходник пропатчен и в build лежит свежая библиотека — проще всего запускать прямо из дерева сборки, без установки: cd ~/libcamera LD_LIBRARY_PATH=$PWD/build/src/libcamera:$PWD/build/src/libcamera/base \ LIBCAMERA_IPA_MODULE_PATH=$PWD/build/src/ipa \ LIBCAMERA_IPA_FORCE_ISOLATION=0 \ ./build/src/apps/cam/cam -l 2>&1 | grep -E "properties|helper|^[0-9]:" А если сборки не осталось — тогда переустановим поверх системной, с префиксом /usr, чтобы больше не путаться. 💰 7.13₽ · ⬇️ 225.9k / ⬆️ 1.3k · opus-5 · max · 21с
Ы
S
ымож просто вместо системной полностью поставить
Разумно — так и сделаем, чтобы всё в системе (включая pipewire) видело пропатченную версию. cd ~/libcamera grep -m1 -A2 "^project(" meson.build # версия должна быть 0.7.x, иначе имя so не совпадёт Если версия сходится, ставим поверх системной. Сначала запомним, чем откатываться: apk info -W /usr/lib/libcamera.so.0.7 2>/dev/null || apk info -W /lib/libcamera.so.0.7 Дальше сборка с правильным префиксом (если каталога build нет — первая команда его создаст): meson setup build --prefix=/usr --libdir=lib --buildtype=release 2>/dev/null || \ meson configure build --prefix=/usr --libdir=lib ninja -C build sudo ninja -C build install И проверка: ldd $(which cam) | grep -i camera cam -l 2>&1 | grep -E "properties|helper|^[0-9]:" Должно исчезнуть всё про imx586/ov8856 и остаться только список камер. Откатиться, если что, одной командой: sudo apk fix libcamera вернёт файлы из пакета. 💰 7.09₽ · ⬇️ 227.2k / ⬆️ 1.2k · opus-5 · max · 20с
Ы
S
ы[0:28:20.723190277] [5459] WARN CameraSensor camera_sensor_legacy.cpp:502 'ov8856 13-0036': No sensor delays found in static properties. Assuming unverified defaults. 1: Internal back camera (/base/soc@0/cci@ac4a000/i2c-bus@1/camera@36) 2: Internal back camera (/base/soc@0/cci@ac4a000/i2c-bus@0/cam
Отлично — про imx586 предупреждений больше нет, значит наша сборка встала системной. У ov8856 осталась только жалоба на задержки конвейера, это мелочь и правится потом. Снимаем широкой с фокусом на ходу: LENS=$(for d in /dev/v4l-subdev*; do v4l2-ctl -d $d --list-ctrls 2>/dev/null | grep -q focus_absolute && { echo $d; break; }; done) echo "объектив: $LENS" rm -f /tmp/lc_*.rgb cam -c 2 --capture=40 --file=/tmp/lc_#.rgb & sleep 3 v4l2-ctl -d $LENS --set-ctrl focus_absolute=600 wait ls -l /tmp/lc_*.rgb | tail -2 convert -size 1920x1080 -depth 8 bgr:/tmp/lc_39.rgb /tmp/lc39.png && ls -l /tmp/lc39.png Наведи на текст в полуметре. Присылай lc39.png — по нему сразу будет видно, что осталось: резкость мы этим чиним, а если цвет поедет, то это уже настроечный файл. 💰 6.44₽ · ⬇️ 228.7k / ⬆️ 602 · opus-5 · max · 11с
Ы
stdvectorclaudebotОтлично — про imx586 предупреждений больше нет, значит наша сборка встала системной. У ov8856 осталась только жалоба на задержки конвейера, это мелочь и правится потом. Снимаем широкой с фокусом на ходу: LENS=$(for d in /dev/v4l-subdev*; do v4l2-ctl -d $d --list-ctrls 2>/dev/null | grep -q focus_a
объектив: /dev/v4l-subdev18 [0:29:05.924783733] [5533] INFO Camera camera_manager.cpp:340 libcamera v0.0.0+1-244572db-dirty (2026-08-02T09:37:10GMT) [0:29:05.932660062] [5535] ERROR V4L2 v4l2_subdevice.cpp:1192 'ov8856 13-0036': Unable to get rectangle 2 on pad 0/0: Not a tty [0:29:05.932751469] [5535] WARN CameraSensor camera_sensor_legacy.cpp:402 'ov8856 13-0036': The PixelArraySize property has been defaulted to 1640x1232 [0:29:05.932778396] [5535] ERROR V4L2 v4l2_subdevice.cpp:1192 'ov8856 13-0036': Unable to get rectangle 1 on pad 0/0: Not a tty [0:29:05.932801156] [5535] WARN CameraSensor camera_sensor_legacy.cpp:413 'ov8856 13-0036': The PixelArrayActiveAreas property has been defaulted to (0, 0)/1640x1232 [0:29:05.932828188] [5535] ERROR V4L2 v4l2_subdevice.cpp:1192 'ov8856 13-0036': Unable to get rectangle 0 on pad 0/0: Not a tty [0:29:05.932848917] [5535] WARN CameraSensor camera_sensor_legacy.cpp:421 'ov8856 13-0036': Failed to retrieve the sensor crop rectangle [0:29:05.932868448] [5535] WARN CameraSensor camera_sensor_legacy.cpp:427 'ov8856 13-0036': The sensor kernel driver needs to be fixed [0:29:05.932905636] [5535] WARN CameraSensor camera_sensor_legacy.cpp:429 'ov8856 13-0036': See Documentation/sensor_driver_requirements.rst in the libcamera sources for more information [0:29:05.933634128] [5535] WARN CameraSensor camera_sensor_legacy.cpp:502 'ov8856 13-0036': No sensor delays found in static properties. Assuming unverified defaults. [0:29:05.938520968] [5535] WARN IPAProxy ipa_proxy.cpp:196 Configuration file 'ov8856.yaml' not found for IPA module 'simple', falling back to '/usr/share/libcamera/ipa/simple/uncalibrated.yaml' [0:29:05.938790083] [5535] ERROR V4L2 v4l2_subdevice.cpp:1192 'ov8856 13-0036': Unable to get rectangle 0 on pad 0/0: Not a tty [0:29:05.938937584] [5535] WARN CameraSensor camera_sensor_legacy.cpp:881 'ov8856 13-0036': The analogue crop rectangle has been defaulted to the active area size [0:29:05.960402813] [5536] INFO IPAProxySoftWorker soft_ipa_proxy_worker.cpp:443 Starting worker for IPA module /usr/lib/libcamera/ipa/ipa_soft_simple.so with IPC fd = 24 [0:29:05.964452567] [5535] INFO Camera camera_manager.cpp:223 Adding camera '/base/soc@0/cci@ac4a000/i2c-bus@1/camera@36' for pipeline handler simple [0:29:05.966677678] [5535] WARN IPAProxy ipa_proxy.cpp:196 Configuration file 'imx586.yaml' not found for IPA module 'simple', falling back to '/usr/share/libcamera/ipa/simple/uncalibrated.yaml' [0:29:05.990261249] [5537] INFO IPAProxySoftWorker soft_ipa_proxy_worker.cpp:443 Starting worker for IPA module /usr/lib/libcamera/ipa/ipa_soft_simple.so with IPC fd = 29 [0:29:05.995499704] [5535] INFO Camera camera_manager.cpp:223 Adding camera '/base/soc@0/cci@ac4a000/i2c-bus@0/camera@1a' for pipeline handler simple Using camera /base/soc@0/cci@ac4a000/i2c-bus@0/camera@1a as cam0 [0:29:05.995929028] [5533] INFO Camera camera.cpp:1216 configuring streams: (0) 7992x6000-ABGR8888/sRGB [0:29:05.996474916] [5537] INFO IPASoft soft_simple.cpp:258 IPASoft: Exposure 4-6010, gain 1-16 (0.15) [0:29:05.996942209] [5535] INFO SoftwareIsp software_isp.cpp:299 Input 8000x6000-BGGR-10-CSI2P stride 10000 [0:29:05.997289866] [5535] ERROR DmaBufAllocator dma_buf_allocator.cpp:153 Failed to create dma buf for frame-0: Invalid argument [0:29:05.997389815] [5535] ERROR DmaBufAllocator dma_buf_allocator.cpp:231 Unable to create buffer [0:29:05.997703722] [5533] ERROR Allocator framebuffer_allocator.cpp:97 Stream is not part of /base/soc@0/cci@ac4a000/i2c-bus@0/camera@1a active configuration Can't allocate buffers Failed to start camera session
S
ыобъектив: /dev/v4l-subdev18 [0:29:05.924783733] [5533] INFO Camera camera_manager.cpp:340 libcamera v0.0.0+1-244572db-dirty (2026-08-02T09:37:10GMT) [0:29:05.932660062] [5535] ERROR V4L2 v4l2_subdevice.cpp:1192 'ov8856 13-0036': Unable to get rectangle 2 on pad 0/0: Not a tty [0:29:05.932751469] [5
Теперь видно, что происходит: libcamera выбрала полное разрешение — 7992x6000, вход 8000x6000-BGGR-10. Кадр в ABGR8888 весит 192 МБ, и аллокатор dma-buf на таком размере отваливается с «Invalid argument». Вчера мы задавали размер явно, поэтому и работало. Задаём поток руками: LENS=/dev/v4l-subdev18 rm -f /tmp/lc_*.rgb cam -c 2 -s width=1920,height=1080,pixelformat=RGB888 --capture=40 --file=/tmp/lc_#.rgb & sleep 3 v4l2-ctl -d $LENS --set-ctrl focus_absolute=600 wait ls -l /tmp/lc_*.rgb | tail -2 convert -size 1920x1080 -depth 8 bgr:/tmp/lc_39.rgb /tmp/lc39.png && ls -l /tmp/lc39.png Кстати, в логе уже видно, что наш помощник сенсора заработал: строка IPASoft: Exposure 4-6010, gain 1-16 — это наши пределы выдержки и усиления, раньше их не было. 💰 7.54₽ · ⬇️ 231.3k / ⬆️ 1.1k · opus-5 · max · 17с
Ы
stdvectorclaudebotТеперь видно, что происходит: libcamera выбрала полное разрешение — 7992x6000, вход 8000x6000-BGGR-10. Кадр в ABGR8888 весит 192 МБ, и аллокатор dma-buf на таком размере отваливается с «Invalid argument». Вчера мы задавали размер явно, поэтому и работало. Задаём поток руками: LENS=/dev/v4l-subdev1
cam0: Capture 40 frames 1811.679601 (0.00 fps) cam0-stream0 seq: 000000 bytesused: 6220800 1811.712923 (30.01 fps) cam0-stream0 seq: 000001 bytesused: 6220800 1811.746126 (30.12 fps) cam0-stream0 seq: 000002 bytesused: 6220800 1811.779450 (30.01 fps) cam0-stream0 seq: 000003 bytesused: 6220800 1811.813072 (29.74 fps) cam0-stream0 seq: 000004 bytesused: 6220800 1811.846080 (30.30 fps) cam0-stream0 seq: 000005 bytesused: 6220800 1811.879662 (29.78 fps) cam0-stream0 seq: 000006 bytesused: 6220800 1811.912707 (30.26 fps) cam0-stream0 seq: 000007 bytesused: 6220800 1811.946052 (29.99 fps) cam0-stream0 seq: 000008 bytesused: 6220800 1811.979355 (30.03 fps) cam0-stream0 seq: 000009 bytesused: 6220800 1812.012667 (30.02 fps) cam0-stream0 seq: 000010 bytesused: 6220800 1812.046018 (29.98 fps) cam0-stream0 seq: 000011 bytesused: 6220800 1812.079308 (30.04 fps) cam0-stream0 seq: 000012 bytesused: 6220800 1812.112627 (30.01 fps) cam0-stream0 seq: 000013 bytesused: 6220800 1812.145966 (29.99 fps) cam0-stream0 seq: 000014 bytesused: 6220800 1812.179289 (30.01 fps) cam0-stream0 seq: 000015 bytesused: 6220800 1812.212607 (30.01 fps) cam0-stream0 seq: 000016 bytesused: 6220800 1812.245913 (30.02 fps) cam0-stream0 seq: 000017 bytesused: 6220800 1812.279362 (29.90 fps) cam0-stream0 seq: 000018 bytesused: 6220800 1812.312559 (30.12 fps) cam0-stream0 seq: 000019 bytesused: 6220800 1812.345873 (30.02 fps) cam0-stream0 seq: 000020 bytesused: 6220800 1812.379196 (30.01 fps) cam0-stream0 seq: 000021 bytesused: 6220800 1812.412534 (30.00 fps) cam0-stream0 seq: 000022 bytesused: 6220800 1812.445837 (30.03 fps) cam0-stream0 seq: 000023 bytesused: 6220800 1812.479157 (30.01 fps) cam0-stream0 seq: 000024 bytesused: 6220800 1812.512496 (29.99 fps) cam0-stream0 seq: 000025 bytesused: 6220800 1812.545919 (29.92 fps) cam0-stream0 seq: 000026 bytesused: 6220800 1812.579400 (29.87 fps) cam0-stream0 seq: 000027 bytesused: 6220800 1812.612601 (30.12 fps) cam0-stream0 seq: 000028 bytesused: 6220800 1812.645942 (29.99 fps) cam0-stream0 seq: 000029 bytesused: 6220800 1812.679318 (29.96 fps) cam0-stream0 seq: 000030 bytesused: 6220800 1812.712652 (30.00 fps) cam0-stream0 seq: 000031 bytesused: 6220800 1812.745800 (30.17 fps) cam0-stream0 seq: 000032 bytesused: 6220800 1812.779317 (29.84 fps) cam0-stream0 seq: 000033 bytesused: 6220800 1812.812500 (30.14 fps) cam0-stream0 seq: 000034 bytesused: 6220800 1812.845845 (29.99 fps) cam0-stream0 seq: 000035 bytesused: 6220800 1812.879181 (30.00 fps) cam0-stream0 seq: 000036 bytesused: 6220800 1812.912394 (30.11 fps) cam0-stream0 seq: 000037 bytesused: 6220800 1812.945866 (29.88 fps) cam0-stream0 seq: 000038 bytesused: 6220800 1812.979090 (30.10 fps) cam0-stream0 seq: 000039 bytesused: 6220800 -rw-r--r-- 1 user user 6220800 Aug 2 09:40 /tmp/lc_cam0-stream0-000038.rgb -rw-r--r-- 1 user user 6220800 Aug 2 09:40 /tmp/lc_cam0-stream0-000039.rgb WARNING: The convert command is deprecated in IMv7, use "magick" instead of "convert" or "magick convert" convert: unable to open image '/tmp/lc_39.rgb': No such file or directory @ error/blob.c/OpenBlob/3655. convert: no images defined `/tmp/lc39.png' @ error/deprecate.c/ConvertImageCommand/3375.
S
ыcam0: Capture 40 frames 1811.679601 (0.00 fps) cam0-stream0 seq: 000000 bytesused: 6220800 1811.712923 (30.01 fps) cam0-stream0 seq: 000001 bytesused: 6220800 1811.746126 (30.12 fps) cam0-stream0 seq: 000002 bytesused: 6220800 1811.779450 (30.01 fps) cam0-stream0 seq: 000003 bytesused: 6220800 1811.
Кадры пошли ровно 30 в секунду, но 40 штук улетели за полторы секунды — то есть фокус я подвинул уже после съёмки. И имя файла у cam своё, # разворачивается в полное. Сделаем аккуратнее: подержим объектив включённым через открытый дескриптор (драйвер усыпляет мотор, как только последний закрывает узел, и линза уезжает в исходное), выставим фокус и снимем всего десяток кадров. LENS=/dev/v4l-subdev18 rm -f /tmp/lc_*.rgb exec 9<>$LENS # держим мотор под питанием v4l2-ctl -d $LENS --set-ctrl focus_absolute=600 cam -c 2 -s width=1920,height=1080,pixelformat=RGB888 --capture=10 --file=/tmp/lc_#.rgb exec 9>&- F=$(ls -t /tmp/lc_*.rgb | head -1) magick -size 1920x1080 -depth 8 bgr:$F /tmp/lc.png && ls -l /tmp/lc.png Если картинка выйдет резкой — значит остаётся только цвет. Если всё ещё мыло, попробуй прямо во время съёмки прогнать несколько значений, чтобы исключить неудачную дистанцию: exec 9<>$LENS cam -c 2 -s width=1920,height=1080,pixelformat=RGB888 --capture=120 --file=/tmp/lcs_#.rgb & for f in 200 400 600 800; do sleep 0.8; v4l2-ctl -d $LENS --set-ctrl focus_absolute=$f; done wait; exec 9>&- 💰 9.26₽ · ⬇️ 234.2k / ⬆️ 2.4k · opus-5 · max · 38с
Ы
S
ыкартинка полностью черная
Проверим, чёрная она по-настоящему или просто тёмная — глазами на глаз это не отличить: F=$(ls -t /tmp/lc_*.rgb | head -1) python3 -c " d=open('$F','rb').read(); print('мин',min(d),'макс',max(d),'среднее',round(sum(d)/len(d),1))" Если максимум ноль — кадр действительно пустой. Если максимум хоть сколько-то есть, то это просто недоэкспозиция: у программного ISP автоэкспозиция сходится за десяток-другой кадров, а мы снимали всего десять. Тогда дай ей время: LENS=/dev/v4l-subdev18 rm -f /tmp/lc_*.rgb exec 9<>$LENS v4l2-ctl -d $LENS --set-ctrl focus_absolute=600 cam -c 2 -s width=1920,height=1080,pixelformat=RGB888 --capture=60 --file=/tmp/lc_#.rgb exec 9>&- F=$(ls -t /tmp/lc_*.rgb | head -1) magick -size 1920x1080 -depth 8 bgr:$F /tmp/lc.png И для сравнения — наш собственный путь на том же сюжете, он заведомо рабочий: W=1920 H=1080 EXPOSURE=1240 GAIN=896 sh ~/lanekit/capture.sh /tmp/f1080c.raw cd ~/lanekit && ./raw10preview /tmp/f1080c.raw /tmp/p.ppm 1920 1080 rggb 2 && magick /tmp/p.ppm /tmp/p1080c.png Если наш кадр видно, а у libcamera чернота — значит дело в её управлении выдержкой, и я знаю, куда смотреть. И на всякий случай: телефон сейчас не лежит объективом вниз? 💰 7.94₽ · ⬇️ 236.7k / ⬆️ 1.4k · opus-5 · max · 29с
Ы
S
ымин 0 макс 0 среднее 0.0
Полный ноль — значит либо сенсор отдаёт темноту, либо ISP съедает всё вычитанием уровня чёрного. Разница принципиальная, и меряется она одним запуском: посмотрим, что libcamera выставляет сенсору прямо во время съёмки. SD=$(media-ctl -d /dev/media0 -e "imx586 12-001a") LENS=/dev/v4l-subdev18 rm -f /tmp/lc_*.rgb exec 9<>$LENS v4l2-ctl -d $LENS --set-ctrl focus_absolute=600 cam -c 2 -s width=1920,height=1080,pixelformat=RGB888 --capture=90 --file=/tmp/lc_#.rgb & sleep 2; echo "-- через 2 с:"; v4l2-ctl -d $SD --get-ctrl exposure,analogue_gain,horizontal_flip,vertical_flip sleep 1; echo "-- через 3 с:"; v4l2-ctl -d $SD --get-ctrl exposure,analogue_gain wait; exec 9>&- F=$(ls -t /tmp/lc_*.rgb | head -1) python3 -c "d=open('$F','rb').read(); print('макс',max(d),'среднее',round(sum(d)/len(d),2))" Что я жду увидеть: если автоматика работает, выдержка за пару секунд уползёт к максимуму режима (около 1240 строк), а усиление к 960. Если же она стоит на 4 — значит IPA вообще не пишет в сенсор, и копать надо туда. Кстати, вчера картинка была хоть и плохая, но видимая — и это важная зацепка: вчера работала системная libcamera без нашего помощника, то есть без уровня чёрного, и ничего не вычиталось. Сегодня помощник появился, и вместе с ним вычитание 16 единиц из восьмибитного кадра. В тёмной сцене этого хватит, чтобы всё ушло в ноль. 💰 23.14₽ · ⬇️ 720.1k / ⬆️ 4.4k · opus-5 · max · 75с
Ы
stdvectorclaudebotПолный ноль — значит либо сенсор отдаёт темноту, либо ISP съедает всё вычитанием уровня чёрного. Разница принципиальная, и меряется она одним запуском: посмотрим, что libcamera выставляет сенсору прямо во время съёмки. SD=$(media-ctl -d /dev/media0 -e "imx586 12-001a") LENS=/dev/v4l-subdev18 rm -f
cam0: Capture 90 frames 2196.868027 (0.00 fps) cam0-stream0 seq: 000000 bytesused: 6220800 2196.901477 (29.90 fps) cam0-stream0 seq: 000001 bytesused: 6220800 2196.934740 (30.06 fps) cam0-stream0 seq: 000002 bytesused: 6220800 2196.968110 (29.97 fps) cam0-stream0 seq: 000003 bytesused: 6220800 2197.001322 (30.11 fps) cam0-stream0 seq: 000004 bytesused: 6220800 2197.034670 (29.99 fps) cam0-stream0 seq: 000005 bytesused: 6220800 2197.068159 (29.86 fps) cam0-stream0 seq: 000006 bytesused: 6220800 2197.101506 (29.99 fps) cam0-stream0 seq: 000007 bytesused: 6220800 2197.134708 (30.12 fps) cam0-stream0 seq: 000008 bytesused: 6220800 2197.168118 (29.93 fps) cam0-stream0 seq: 000009 bytesused: 6220800 2197.201225 (30.21 fps) cam0-stream0 seq: 000010 bytesused: 6220800 2197.234638 (29.93 fps) cam0-stream0 seq: 000011 bytesused: 6220800 2197.267906 (30.06 fps) cam0-stream0 seq: 000012 bytesused: 6220800 2197.301070 (30.15 fps) cam0-stream0 seq: 000013 bytesused: 6220800 2197.334645 (29.78 fps) cam0-stream0 seq: 000014 bytesused: 6220800 2197.367964 (30.01 fps) cam0-stream0 seq: 000015 bytesused: 6220800 2197.401297 (30.00 fps) cam0-stream0 seq: 000016 bytesused: 6220800 2197.434511 (30.11 fps) cam0-stream0 seq: 000017 bytesused: 6220800 2197.467667 (30.16 fps) cam0-stream0 seq: 000018 bytesused: 6220800 2197.501154 (29.86 fps) cam0-stream0 seq: 000019 bytesused: 6220800 2197.534599 (29.90 fps) cam0-stream0 seq: 000020 bytesused: 6220800 2197.567945 (29.99 fps) cam0-stream0 seq: 000021 bytesused: 6220800 2197.601116 (30.15 fps) cam0-stream0 seq: 000022 bytesused: 6220800 2197.634574 (29.89 fps) cam0-stream0 seq: 000023 bytesused: 6220800 2197.667629 (30.25 fps) cam0-stream0 seq: 000024 bytesused: 6220800 2197.701264 (29.73 fps) cam0-stream0 seq: 000025 bytesused: 6220800 2197.734541 (30.05 fps) cam0-stream0 seq: 000026 bytesused: 6220800 2197.767680 (30.18 fps) cam0-stream0 seq: 000027 bytesused: 6220800 2197.801140 (29.89 fps) cam0-stream0 seq: 000028 bytesused: 6220800 2197.834477 (30.00 fps) cam0-stream0 seq: 000029 bytesused: 6220800 2197.867817 (29.99 fps) cam0-stream0 seq: 000030 bytesused: 6220800 2197.901108 (30.04 fps) cam0-stream0 seq: 000031 bytesused: 6220800 2197.934288 (30.14 fps) cam0-stream0 seq: 000032 bytesused: 6220800 2197.967708 (29.92 fps) cam0-stream0 seq: 000033 bytesused: 6220800 2198.001035 (30.01 fps) cam0-stream0 seq: 000034 bytesused: 6220800 2198.034368 (30.00 fps) cam0-stream0 seq: 000035 bytesused: 6220800 2198.067566 (30.12 fps) cam0-stream0 seq: 000036 bytesused: 6220800 2198.100922 (29.98 fps) cam0-stream0 seq: 000037 bytesused: 6220800 2198.134443 (29.83 fps) cam0-stream0 seq: 000038 bytesused: 6220800 2198.167532 (30.22 fps) cam0-stream0 seq: 000039 bytesused: 6220800 2198.200811 (30.05 fps) cam0-stream0 seq: 000040 bytesused: 6220800 2198.234227 (29.93 fps) cam0-stream0 seq: 000041 bytesused: 6220800 2198.267591 (29.97 fps) cam0-stream0 seq: 000042 bytesused: 6220800 2198.300980 (29.95 fps) cam0-stream0 seq: 000043 bytesused: 6220800 2198.334087 (30.21 fps) cam0-stream0 seq: 000044 bytesused: 6220800 2198.367433 (29.99 fps) cam0-stream0 seq: 000045 bytesused: 6220800 2198.400699 (30.06 fps) cam0-stream0 seq: 000046 bytesused: 6220800 2198.434322 (29.74 fps) cam0-stream0 seq: 000047 bytesused: 6220800 2198.467442 (30.19 fps) cam0-stream0 seq: 000048 bytesused: 6220800 2198.500683 (30.08 fps) cam0-stream0 seq: 000049 bytesused: 6220800 -- через 2 с: 2198.534097 (29.93 fps) cam0-stream0 seq: 000050 bytesused: 6220800 exposure: 2260 horizontal_flip: 1 vertical_flip: 1 analogue_gain: 960 2198.567458 (29.98 fps) cam0-stream0 seq: 000051 bytesused: 6220800 2198.600719 (30.07 fps) cam0-stream0 seq: 000052 bytesused: 6220800 2198.634234 (29.84 fps) cam0-stream0 seq: 000053 bytesused: 6220800 2198.667583 (29.99 fps) cam0-stream0 seq: 000054 bytesused: 6220800 2198.700614 (30.27 fps) cam0-stream0 seq: 000055 bytesused: 6220800 2198.734105 (29.86 fps) cam0-stream0 seq: 000056 bytesused: 6220800 2198.767506 (29.94 fps) cam0-stream0 seq: 000057 bytesused: 6220800
Ы
stdvectorclaudebotПолный ноль — значит либо сенсор отдаёт темноту, либо ISP съедает всё вычитанием уровня чёрного. Разница принципиальная, и меряется она одним запуском: посмотрим, что libcamera выставляет сенсору прямо во время съёмки. SD=$(media-ctl -d /dev/media0 -e "imx586 12-001a") LENS=/dev/v4l-subdev18 rm -f
2198.800465 (30.34 fps) cam0-stream0 seq: 000058 bytesused: 6220800 [0:36:38.864768209] [6060] INFO Benchmark benchmark.cpp:89 Debayer processed 30 frames in 711840us, 23728 us/frame 2198.834043 (29.78 fps) cam0-stream0 seq: 000059 bytesused: 6220800 2198.867121 (30.23 fps) cam0-stream0 seq: 000060 bytesused: 6220800 2198.900599 (29.87 fps) cam0-stream0 seq: 000061 bytesused: 6220800 2198.934039 (29.90 fps) cam0-stream0 seq: 000062 bytesused: 6220800 2198.967409 (29.97 fps) cam0-stream0 seq: 000063 bytesused: 6220800 2199.000483 (30.24 fps) cam0-stream0 seq: 000064 bytesused: 6220800 2199.033803 (30.01 fps) cam0-stream0 seq: 000065 bytesused: 6220800 2199.067188 (29.95 fps) cam0-stream0 seq: 000066 bytesused: 6220800 2199.100448 (30.07 fps) cam0-stream0 seq: 000067 bytesused: 6220800 2199.134004 (29.80 fps) cam0-stream0 seq: 000068 bytesused: 6220800 2199.167120 (30.20 fps) cam0-stream0 seq: 000069 bytesused: 6220800 2199.200566 (29.90 fps) cam0-stream0 seq: 000070 bytesused: 6220800 2199.234022 (29.89 fps) cam0-stream0 seq: 000071 bytesused: 6220800 2199.267062 (30.27 fps) cam0-stream0 seq: 000072 bytesused: 6220800 2199.300364 (30.03 fps) cam0-stream0 seq: 000073 bytesused: 6220800 2199.333918 (29.80 fps) cam0-stream0 seq: 000074 bytesused: 6220800 2199.367267 (29.99 fps) cam0-stream0 seq: 000075 bytesused: 6220800 2199.400368 (30.21 fps) cam0-stream0 seq: 000076 bytesused: 6220800 2199.433722 (29.98 fps) cam0-stream0 seq: 000077 bytesused: 6220800 2199.467192 (29.88 fps) cam0-stream0 seq: 000078 bytesused: 6220800 2199.500564 (29.97 fps) cam0-stream0 seq: 000079 bytesused: 6220800 2199.533604 (30.27 fps) cam0-stream0 seq: 000080 bytesused: 6220800 -- через 3 с: exposure: 2260 analogue_gain: 960 2199.567149 (29.81 fps) cam0-stream0 seq: 000081 bytesused: 6220800 2199.600250 (30.21 fps) cam0-stream0 seq: 000082 bytesused: 6220800 2199.633587 (30.00 fps) cam0-stream0 seq: 000083 bytesused: 6220800 2199.667142 (29.80 fps) cam0-stream0 seq: 000084 bytesused: 6220800 2199.700182 (30.27 fps) cam0-stream0 seq: 000085 bytesused: 6220800 2199.733764 (29.78 fps) cam0-stream0 seq: 000086 bytesused: 6220800 2199.766741 (30.32 fps) cam0-stream0 seq: 000087 bytesused: 6220800 2199.800391 (29.72 fps) cam0-stream0 seq: 000088 bytesused: 6220800 2199.833509 (30.20 fps) cam0-stream0 seq: 000089 bytesused: 6220800 макс 205 среднее 124.37
S
ы2198.800465 (30.34 fps) cam0-stream0 seq: 000058 bytesused: 6220800 [0:36:38.864768209] [6060] INFO Benchmark benchmark.cpp:89 Debayer processed 30 frames in 711840us, 23728 us/frame 2198.834043 (29.78 fps) cam0-stream0 seq: 000059 bytesused: 6220800 2198.867121 (30.23 fps) cam0-stream0 seq: 000060
Вот теперь всё в порядке: максимум 205, среднее 124 — нормально проэкспонированный кадр. Чернота была из-за того, что десяти кадров не хватало: автоматика стартует с минимальной выдержки, а вычитание уровня чёрного добивало остатки в ноль. Сейчас она сошлась на выдержке 2260 и усилении 960. Смотрим картинку: F=$(ls -t /tmp/lc_*.rgb | head -1) magick -size 1920x1080 -depth 8 bgr:$F /tmp/lc.png && ls -l /tmp/lc.png Кидай сюда — интересует резкость (фокус мы держали на 600 с открытым дескриптором) и цвет. Заодно из лога видно цену программной обработки: 23.7 мс на кадр, то есть демозаик съедает почти целое ядро на 30 кадрах в секунду. 💰 8.30₽ · ⬇️ 249.6k / ⬆️ 927 · opus-5 · max · 18с
Ы
S
ыну вроде правильно нафоткало. резкость отличная. какое то все слишком холодное конеш на фото но в остальном норм
Отлично — значит пайплайн целиком рабочий, остался только цвет. Холодит по двум причинам: в программном ISP сейчас нет цветовой матрицы (без неё сырой отклик сенсора всегда уходит в синь), а баланс белого работает по «серому миру» и на сцене с преобладанием тёплых поверхностей уводит картинку в холод. Лечится настроечным файлом. Посмотрим, что твоя версия libcamera умеет: ls ~/libcamera/src/ipa/simple/algorithms/ cat /usr/share/libcamera/ipa/simple/uncalibrated.yaml Если среди алгоритмов есть ccm — сделаем imx586.yaml с матрицей и гаммой, и цвет сразу станет人ским. Если нет, тогда доступны только уровень чёрного, гамма и баланс, и я подберу их. Ну и в идеале сфотографировать цветовую мишень, чтобы матрицу посчитать честно, а не на глаз. Подойдёт даже распечатанная — но это уже следующий шаг. 💰 7.37₽ · ⬇️ 250.6k / ⬆️ 1.2k · opus-5 · max · 22с
Ы
S
ыэто каким
Человеческим 🙂 Иероглиф сам туда приполз, не знаю откуда. Так что там с алгоритмами — есть в списке ccm? 💰 6.32₽ · ⬇️ 251.8k / ⬆️ 119 · opus-5 · max · 4с
Ы
stdvectorclaudebotОтлично — значит пайплайн целиком рабочий, остался только цвет. Холодит по двум причинам: в программном ISP сейчас нет цветовой матрицы (без неё сырой отклик сенсора всегда уходит в синь), а баланс белого работает по «серому миру» и на сцене с преобладанием тёплых поверхностей уводит картинку в холо
ls ~/libcamera/src/ipa/simple/algorithms/ adjust.cpp adjust.h agc.cpp agc.h algorithm.h awb.cpp awb.h blc.cpp blc.h ccm.cpp ccm.h meson.build # SPDX-License-Identifier: CC0-1.0 %YAML 1.1 --- version: 1 algorithms: - BlackLevel: - Awb: # Color correction matrices can be defined here. The CCM algorithm # has a significant performance impact, and should only be enabled # if tuned. # - Ccm: # ccms: # - ct: 6500 # ccm: [ 1, 0, 0, # 0, 1, 0, # 0, 0, 1] - Adjust: - Agc: ...
S
ыls ~/libcamera/src/ipa/simple/algorithms/ adjust.cpp adjust.h agc.cpp agc.h algorithm.h awb.cpp awb.h blc.cpp blc.h ccm.cpp ccm.h meson.build # SPDX-License-Identifier: CC0-1.0 %YAML 1.1 --- version: 1 algorithms: - BlackLevel: - Awb: # C
Ccm есть — значит цвет чинится файлом, без пересборки. Клади настройку: sudo tee /usr/share/libcamera/ipa/simple/imx586.yaml >/dev/null <<'EOF' # SPDX-License-Identifier: CC0-1.0 %YAML 1.1 --- version: 1 algorithms: - BlackLevel: - Awb: - Ccm: ccms: - ct: 2900 ccm: [ 1.55, -0.44, -0.11, -0.29, 1.61, -0.32, -0.03, -0.72, 1.75 ] - ct: 6500 ccm: [ 1.60, -0.52, -0.08, -0.23, 1.60, -0.37, -0.04, -0.55, 1.59 ] - Adjust: - Agc: ... EOF И повтори съёмку тем же способом: LENS=/dev/v4l-subdev18 rm -f /tmp/lc_*.rgb exec 9<>$LENS v4l2-ctl -d $LENS --set-ctrl focus_absolute=600 cam -c 2 -s width=1920,height=1080,pixelformat=RGB888 --capture=90 --file=/tmp/lc_#.rgb 2>&1 | grep -E "imx586.yaml|Ccm|ERROR" exec 9>&- F=$(ls -t /tmp/lc_*.rgb | head -1) magick -size 1920x1080 -depth 8 bgr:$F /tmp/lc_ccm.png Матрицы пока типовые для сенсоров Sony — одна для лампы накаливания, одна для дневного света, строки нормированы так, чтобы белое оставалось белым. Это уже сильно лучше единичной матрицы, но честные коэффициенты считаются по снимку цветовой мишени, так что потом заменим. Учти, что демозаик и так ест 24 мс на кадр, а матрица добавит сверху — в самой libcamera про это прямо написано предупреждение. 💰 7.89₽ · ⬇️ 252.3k / ⬆️ 1.8k · opus-5 · max · 28с
S
ыво. теперь правильные цвета
Отлично — значит цвет закрыт. Сохраню файл в набор, чтобы не потерялся: Итого по широкой камере всё замкнулось: кадры идут, режимы переключаются, фокус двигается, экспозиция сходится сама, цвет правильный. То есть камера работает через libcamera целиком, как обычное устройство — этим уже можно снимать из любого приложения, которое умеет libcamera. Что осталось в этой ветке, по убыванию пользы: Честная матрица. Нынешняя типовая, взята «как у Sony вообще». Если снимешь цветовую мишень (годится распечатанная, лишь бы при дневном свете у окна), посчитаю коэффициенты по твоему экземпляру — уйдут остаточные оттенки на коже и небе. Задержки конвейера. В логе висит No sensor delays found in static properties — libcamera не знает, через сколько кадров после записи применяется новая выдержка, и на резких сменах освещения будет промахиваться. Для imx586 мы это уже прописали, для ov8856 осталось. Телевик. Линии теперь правильные, но кадров нет. Следующий шаг там — вендорный блоб, чтобы сверить время установления и режимы. Что дальше — цветовая мишень, или лучше вернуться к телевику? 💰 13.83₽ · ⬇️ 509.1k / ⬆️ 1.1k · opus-5 · max · 22с
Ы
S
ыа libcamera будет сама фокусировать?
Нет, сама не будет — ни сейчас, ни без нашей работы. Я проверил по исходникам: в обработчике simple про объектив нет ни слова, а в программном ISP всего пять алгоритмов — уровень чёрного, баланс белого, матрица, коррекция и экспозиция. Автофокуса среди них нет, и линзу оттуда никто не трогает. В libcamera автофокус есть только у пайплайнов с железным ISP (Raspberry Pi, IPU3), где его считает вендорная IPA. Два пути. Быстрый, наш. Написать маленький автофокус в userspace: снимаем поток, считаем резкость по центральному окну (сумма градиентов), ползём по focus_absolute вверх-вниз до максимума. Это полсотни строк, работает поверх нашего же raw-пути и даёт нормальную наводку за секунду-полторы. Сделаю прямо сейчас, если хочешь. Правильный, в апстрим. Научить simple отдавать объектив в IPA (в libcamera для этого есть класс CameraLens, просто этот обработчик им не пользуется), добавить в статистику метрику резкости и написать алгоритм Af рядом с остальными пятью. Это уже полноценная фича, которой в libcamera не хватает всем программным пайплайнам, а не только нам — то есть вещь, которую примут. Начать логично с первого: он сразу даёт работающую наводку и заодно проверяет, что метрика резкости на этом сенсоре ведёт себя прилично. Второе потом переиспользует ту же математику. 💰 14.07₽ · ⬇️ 511.8k / ⬆️ 1.8k · opus-5 · max · 39с
Ы
S
ычот приложение Camera все грузица грузица и никак не загрузица
Скорее всего оно открывает первую камеру — то есть телевик, а он кадров не отдаёт, и приложение честно ждёт вечно. Плюс мы по дороге убивали pipewire нашими скриптами, а приложения ходят в камеру через него. Сначала вернём pipewire: systemctl --user restart pipewire wireplumber 2>/dev/null || (pipewire & wireplumber &) А телевик пока просто уберём с глаз — драйвер отвязывается на лету, без перезагрузки и правки дерева: echo 13-0036 | sudo tee /sys/bus/i2c/drivers/ov8856/unbind cam -l | grep -E "^[0-9]:" Должна остаться одна камера — широкая. После этого запускай приложение, ему выбирать будет не из чего. Вернуть телевик обратно, когда займёмся им: echo 13-0036 | sudo tee /sys/bus/i2c/drivers/ov8856/bind 💰 7.20₽ · ⬇️ 257.5k / ⬆️ 804 · opus-5 · max · 14с
Ы
S
ыа не у меня просто система повисла но анимация продолжала крутица
Похоже на нехватку памяти: /tmp у тебя в оперативке, а мы туда навалили — 90 кадров по 6.2 МБ это 560 МБ, плюс полноразмерные raw. Плюс программный ISP ест целое ядро на камеру. Проверь и прибери: free -m; df -h /tmp dmesg | grep -iE "oom|killed process|out of memory" | tail -5 rm -f /tmp/lc_*.rgb /tmp/lcs_*.rgb /tmp/f*.raw Дальше давай серии писать не в /tmp, а на диск: mkdir -p ~/cap && cam -c 2 -s width=1920,height=1080,pixelformat=RGB888 --capture=90 --file=$HOME/cap/lc_#.rgb Медленнее, зато система не задохнётся. 💰 7.01₽ · ⬇️ 258.3k / ⬆️ 740 · opus-5 · max · 14с
Ы
S
ытак перезагружка уже была. совпадение кароче. The configuration is not valid в приложении Camera происходид
После перезагрузки телевик снова на месте, так что первым делом убери его и проверь, не в нём ли дело: echo 13-0036 | sudo tee /sys/bus/i2c/drivers/ov8856/unbind cam -l | grep -E "^[0-9]:" Если приложение после этого заработает — значит оно спотыкалось именно о камеру, которая не отдаёт кадры. Если ошибка останется, надо посмотреть, что именно оно просит. Запусти его из терминала и покажи хвост: ls /usr/bin | grep -iE "camera|snapshot|megapixels" <имя_бинарника> 2>&1 | tail -40 «The configuration is not valid» — это отказ на этапе согласования формата: приложение запрашивает размер или пиксельный формат, которого программный ISP не даёт. В логе будет видно, что оно просило и что ему предложили взамен. 💰 7.15₽ · ⬇️ 259.1k / ⬆️ 864 · opus-5 · max · 16с
Ы
S
ыls /usr/bin | grep -iE "camera|snapshot|megapixels" libcamera-bug-report lxc-snapshot plasma-camera
Это plasma-camera. Запусти из терминала и покажи хвост: plasma-camera 2>&1 | tail -40 И заодно проверь, что у нас там теперь с библиотеками — есть подозрение, что мы поставили свою рядом, а не вместо: ls -l /usr/lib/libcamera*.so* | head Дело в том, что наша сборка представляется как v0.0.0+1-244572db-dirty — в дереве нет тегов, поэтому номер версии не определился. Если из-за этого имя библиотеки вышло другим (libcamera.so.0.0 вместо libcamera.so.0.7), то cam берёт нашу, а все остальные приложения по-прежнему системную. Тогда починим одним символическим линком. 💰 7.52₽ · ⬇️ 260.1k / ⬆️ 1.1k · opus-5 · max · 22с
Ы
stdvectorclaudebotЭто plasma-camera. Запусти из терминала и покажи хвост: plasma-camera 2>&1 | tail -40 И заодно проверь, что у нас там теперь с библиотеками — есть подозрение, что мы поставили свою рядом, а не вместо: ls -l /usr/lib/libcamera*.so* | head Дело в том, что наша сборка представляется как v0.0.0+1-24
qt.qpa.xcb: could not connect to display qt.qpa.plugin: From 6.5.0, xcb-cursor0 or libxcb-cursor0 is needed to load the Qt xcb platform plugin. qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found. This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem. Available platform plugins are: offscreen, minimal, xcb, vnc, vkkhrdisplay, wayland-brcm, wayland-egl, wayland, linuxfb, minimalegl, eglfs. Aborted (core dumped)
S
ыqt.qpa.xcb: could not connect to display qt.qpa.plugin: From 6.5.0, xcb-cursor0 or libxcb-cursor0 is needed to load the Qt xcb platform plugin. qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found. This application failed to start because no Qt platform plugin c
Это оно ругается на отсутствие экрана — по ssh Qt не к чему подключиться. Укажи вейландовский сеанс телефона: export XDG_RUNTIME_DIR=/run/user/$(id -u) ls $XDG_RUNTIME_DIR | grep wayland export WAYLAND_DISPLAY=wayland-0 # подставь то, что нашлось QT_QPA_PLATFORM=wayland plasma-camera 2>&1 | tail -40 Окно откроется на самом телефоне, а сообщения придут в терминал. И покажи всё же список библиотек, это важно: ls -l /usr/lib/libcamera*.so* 💰 7.01₽ · ⬇️ 261.5k / ⬆️ 469 · opus-5 · max · 8с
Ы
S
ыв логе пусто а ошибку мне на экран высвечивает. The configuration is not valid
Значит сообщение рисует сама программа, а причину надо доставать сбоку. Два быстрых шага. Первое — всё-таки покажи, что лежит в системе, это ключевой вопрос: ls -l /usr/lib/libcamera*.so* Второе — проверим тот же путь другим потребителем, через gstreamer: export XDG_RUNTIME_DIR=/run/user/$(id -u); export WAYLAND_DISPLAY=wayland-0 gst-inspect-1.0 libcamerasrc >/dev/null 2>&1 && echo "плагин есть" || echo "плагина нет" gst-launch-1.0 libcamerasrc ! video/x-raw,width=1920,height=1080 ! videoconvert ! waylandsink 2>&1 | tail -15 Если картинка появится на экране телефона — значит libcamera и её потребители в порядке, а спотыкается именно plasma-camera на своём наборе форматов. Если же не появится, ошибка от gstreamer будет куда разговорчивее, чем одна строка в окне. 💰 7.70₽ · ⬇️ 262.0k / ⬆️ 1.4k · opus-5 · max · 26с
Ы
S
ытам наша libcamera qcom-sm7150:~$ gst-inspect-1.0 libcamerasrc >/dev/null 2>&1 && echo "плагин есть" || echo "плагина нет" плагина нет qcom-sm7150:~$ gst-launch-1.0 libcamerasrc ! video/x-raw,width=1920,height=1080 ! videoconvert ! waylandsink 2>&1 | tail -15 -ash: gst-launch-1.0: not found
Ясно, gstreamer нет — значит plasma-camera ходит в камеру через pipewire (у него есть свой модуль libcamera), либо напрямую через QtMultimedia. Проверим по очереди. Видит ли pipewire камеру: wpctl status 2>/dev/null | grep -A6 -i "video\|source" | head -20 journalctl --user -u pipewire -n 40 2>/dev/null | grep -iE "libcamera|camera|error" | tail -10 И заодно, если при сборке собрался наш собственный просмотрщик — он покажет картинку сам, без pipewire и без Qt-обвязки приложения: ls -l ~/libcamera/build/src/apps/qcam/qcam 2>/dev/null && \ XDG_RUNTIME_DIR=/run/user/$(id -u) WAYLAND_DISPLAY=wayland-0 ~/libcamera/build/src/apps/qcam/qcam -c 2 Если qcam покажет живое видео — значит вся цепочка исправна, и разбираться надо только с тем, что просит plasma-camera. Если и он не сможет — причина глубже, и она будет в его логе развёрнуто. 💰 7.93₽ · ⬇️ 263.6k / ⬆️ 1.2k · opus-5 · max · 20с
Ы
stdvectorclaudebotЯсно, gstreamer нет — значит plasma-camera ходит в камеру через pipewire (у него есть свой модуль libcamera), либо напрямую через QtMultimedia. Проверим по очереди. Видит ли pipewire камеру: wpctl status 2>/dev/null | grep -A6 -i "video\|source" | head -20 journalctl --user -u pipewire -n 40 2>/de
├─ Sources: │ ├─ Filters: │ └─ Streams: Video ├─ Devices: │ 44. Qualcomm Camera Subsystem [v4l2] │ 45. Qualcomm Camera Subsystem [v4l2] │ 46. Qualcomm Camera Subsystem [v4l2] │ 47. Qualcomm Camera Subsystem [v4l2] │ 48. Qualcomm Camera Subsystem [v4l2] -- ├─ Sources: │ * 56. Built-in Back Camera │ 58. Built-in Back Camera │ ├─ Filters: │
S
ы├─ Sources: │ ├─ Filters: │ └─ Streams: Video ├─ Devices: │ 44. Qualcomm Camera Subsystem [v4l2] │ 45. Qualcomm Camera Subsystem [v4l2] │ 46. Qualcomm Camera Subsystem [v4l2] │ 47. Qualcomm Camera Subsystem [v4l2] │ 48.
Вот и объяснение: pipewire отдаёт две «Built-in Back Camera», и по умолчанию выбрана 56 — почти наверняка телевик, который кадров не даёт. Плюс рядом торчат пять сырых узлов camss как v4l2-устройства, в которые лезть вообще нельзя, там формат надо настраивать руками. Посмотри, кто есть кто, и переключи умолчание: wpctl inspect 56 | grep -iE "node.name|device.name|object.path|api\." wpctl inspect 58 | grep -iE "node.name|device.name|object.path|api\." Тот, у которого в пути camera@1a — широкая. Ставим его по умолчанию: wpctl set-default 58 # подставь нужный номер А проще всего снова убрать телевик с глаз и перезапустить pipewire, тогда выбирать будет не из чего: echo 13-0036 | sudo tee /sys/bus/i2c/drivers/ov8856/unbind systemctl --user restart pipewire wireplumber wpctl status | grep -A4 "Sources" После этого запускай приложение. 💰 7.70₽ · ⬇️ 265.2k / ⬆️ 920 · opus-5 · max · 16с
Ы
stdvectorclaudebotВот и объяснение: pipewire отдаёт две «Built-in Back Camera», и по умолчанию выбрана 56 — почти наверняка телевик, который кадров не даёт. Плюс рядом торчат пять сырых узлов camss как v4l2-устройства, в которые лезть вообще нельзя, там формат надо настраивать руками. Посмотри, кто есть кто, и перек
wpctl inspect 56 | grep -iE "node.name|device.name|object.path|api\." api.libcamera.location = "back" api.libcamera.path = "/base/soc@0/cci@ac4a000/i2c-bus@1/camera@36" api.libcamera.rotation = "180" device.name = "libcamera_device./base/soc@0/cci@ac4a000/i2c-bus@1/camera@36" factory.name = "api.libcamera.source" * node.name = "libcamera_input._base_soc_0_cci_ac4a000_i2c-bus_1_camera_36" * object.path = "libcamera:/base/soc@0/cci@ac4a000/i2c-bus@1/camera@36" wpctl inspect 58 | grep -iE "node.name|device.name|object.path|api\." api.libcamera.location = "back" api.libcamera.path = "/base/soc@0/cci@ac4a000/i2c-bus@0/camera@1a" api.libcamera.rotation = "180" device.name = "libcamera_device./base/soc@0/cci@ac4a000/i2c-bus@0/camera@1a" factory.name = "api.libcamera.source" * node.name = "libcamera_input._base_soc_0_cci_ac4a000_i2c-bus_0_camera_1a" * object.path = "libcamera:/base/soc@0/cci@ac4a000/i2c-bus@0/camera@1a"
S
ыwpctl inspect 56 | grep -iE "node.name|device.name|object.path|api\." api.libcamera.location = "back" api.libcamera.path = "/base/soc@0/cci@ac4a000/i2c-bus@1/camera@36" api.libcamera.rotation = "180" device.name = "libcamera_device./base/soc@0/cci@ac4a000/i2c-bus@1/camera@36" fac
Как и думал: 56 — телевик (camera@36), 58 — широкая (camera@1a), а по умолчанию стоит именно телевик. Переключаем: wpctl set-default 58 wpctl status | grep -A4 "Sources" Звёздочка должна переехать на 58. И запускай приложение. Если оно всё равно упрётся (некоторые программы сами перебирают устройства и берут первое, игнорируя умолчание) — тогда убираем телевик совсем: echo 13-0036 | sudo tee /sys/bus/i2c/drivers/ov8856/unbind systemctl --user restart pipewire wireplumber 💰 7.01₽ · ⬇️ 266.7k / ⬆️ 339 · opus-5 · max · 8с
Ы
S
ывсе ещо такая же ошибка
Тогда добьём телевик и посмотрим, какие форматы вообще предлагает широкая — подозреваю, что приложение просит YUV, а программный ISP отдаёт только RGB, и переговоры о формате рушатся. echo 13-0036 | sudo tee /sys/bus/i2c/drivers/ov8856/unbind systemctl --user restart pipewire wireplumber sleep 2 wpctl status | grep -A4 "Sources" И список форматов узла (номер возьми из свежего wpctl status, он мог поменяться): pw-cli enum-params 58 EnumFormat 2>/dev/null | grep -E "format|Video|size|framerate" | head -30 Если там окажутся только RGB/BGR/ARGB, а привычных NV12/YUY2 нет — вот и причина. Тогда варианта два: включить в pipewire промежуточное преобразование или добавить вывод в NV12 в сам программный ISP (он это умеет в свежих версиях, вопрос сборки). 💰 7.46₽ · ⬇️ 267.1k / ⬆️ 1.1k · opus-5 · max · 19с
Ы
S
ыecho 13-0036 | sudo tee /sys/bus/i2c/drivers/ov8856/unbind 13-0036 tee: /sys/bus/i2c/drivers/ov8856/unbind: I/O error
Занят — pipewire держит камеру открытой. Останови его и повтори: systemctl --user stop pipewire wireplumber pipewire.socket 2>/dev/null pkill -f wireplumber; pkill -f pipewire; sleep 1 echo 13-0036 | sudo tee /sys/bus/i2c/drivers/ov8856/unbind systemctl --user start pipewire wireplumber Но это второстепенно. Гораздо важнее список форматов — без него мы гадаем. Номер узла возьми свежий: wpctl status | grep -A4 Sources pw-cli enum-params <номер> EnumFormat 2>&1 | grep -E "format:|size:|Video" | head -30 💰 7.38₽ · ⬇️ 268.3k / ⬆️ 721 · opus-5 · max · 13с
S
ычот оно на stop висит пару минут
Так и есть — pipewire завис, скорее всего именно на телевике: он открыл камеру, ждёт кадры, а их нет. Это, кстати, объясняет и ошибку приложения: оно спрашивает у зависшего сервиса. Бей жёстко: sudo pkill -9 -f pipewire; sudo pkill -9 -f wireplumber; sleep 1 echo 13-0036 | sudo tee /sys/bus/i2c/drivers/ov8856/unbind systemctl --user start pipewire wireplumber 2>/dev/null || (pipewire & wireplumber &) sleep 2; wpctl status | grep -A4 Sources Должна остаться одна камера. И сразу запускай приложение — подозреваю, что теперь оно заработает без всяких форматных плясок. 💰 7.11₽ · ⬇️ 269.1k / ⬆️ 646 · opus-5 · max · 13с
Ы
S
ыKilled Killed 13-0036 tee: /sys/bus/i2c/drivers/ov8856/unbind: I/O error
Ошибка не «занято», а именно ввод-вывод — значит дело не в pipewire. Проверим, как оно вообще привязано, и попробуем через модуль: ls -l /sys/bus/i2c/devices/13-0036/driver 2>/dev/null ls /sys/bus/i2c/drivers/ | grep -i ov lsmod | grep -i ov8856 Если это модуль — выгружаем целиком, так надёжнее: sudo rmmod ov8856 && dmesg | tail -5 А если он вкомпилирован в ядро, останется путь через дерево: дописать телевику status = "disabled", пересобрать dtb и перезагрузиться. Тогда он исчезнет и из libcamera, и из pipewire до тех пор, пока мы им не займёмся всерьёз. 💰 7.67₽ · ⬇️ 269.8k / ⬆️ 1.1k · opus-5 · max · 23с
Ы
S
ыsudo rmmod ov8856 && dmesg | tail -5 [sudo: authenticate] Password: rmmod: ERROR: Module ov8856 is in use
Ясно: модуль держит camss, потому что телевик прописан в его графе. Выгрузить camss тоже нельзя — тогда он будет ждать пропавший сенсор и не поднимет вообще ни одной камеры. Значит убираем телевик из дерева. Это одна пересборка dtb и перезагрузка, зато уходит и зависание pipewire, и ошибка приложения: cat >> $F <<'EOF' /* временно, пока телевик не отдаёт кадры: он вешает pipewire и приложения */ &cci0_i2c1 { camera@36 { status = "disabled"; }; }; EOF cd $K && make dtbs -j8 && sudo make dtbs_install INSTALL_DTBS_PATH=/boot/dtbs && sync Отключённый узел v4l2 пропускает молча, так что camss спокойно поднимется с одной камерой. После перезагрузки проверь: cam -l | grep -E "^[0-9]:" Должна остаться одна строка. Дальше приложение — думаю, заведётся сразу. Когда займёмся телевиком, вернём одной строкой: заменить disabled на okay и пересобрать dtb. 💰 8.56₽ · ⬇️ 271.1k / ⬆️ 1.7k · opus-5 · max · 30с
Ы
S
ы$F нету
Переменные потерялись — восстановим: F=$(find / -name "sm7150-xiaomi-davinci.dtsi" -not -path "/proc/*" 2>/dev/null | head -1) K=${F%/arch/*} echo "$K"; echo "$F" И дальше как было: cat >> $F <<'EOF' /* временно, пока телевик не отдаёт кадры: он вешает pipewire и приложения */ &cci0_i2c1 { camera@36 { status = "disabled"; }; }; EOF cd $K && make dtbs -j8 && sudo make dtbs_install INSTALL_DTBS_PATH=/boot/dtbs && sync 💰 7.40₽ · ⬇️ 272.8k / ⬆️ 456 · opus-5 · max · 10с
S
ы/ask
Тогда просто прямыми путями: K=/home/user/linux-7.2 F=$K/arch/arm64/boot/dts/qcom/sm7150-xiaomi-davinci.dtsi ls -l $F && tail -5 $F Если файл на месте — дописываем и собираем: cat >> $F <<'EOF' /* временно, пока телевик не отдаёт кадры: он вешает pipewire и приложения */ &cci0_i2c1 { camera@36 { status = "disabled"; }; }; EOF cd $K && make dtbs -j8 && sudo make dtbs_install INSTALL_DTBS_PATH=/boot/dtbs && sync 💰 7.02₽ · ⬇️ 273.4k / ⬆️ 566 · opus-5 · max · 10с
S
ыа sync он ваще чо делает
Сбрасывает на диск всё, что ядро ещё держит в памяти. Запись файла на самом деле сначала попадает в кеш страниц, а на флеш уезжает потом, когда ядру удобно — обычно в пределах секунд. Нам это важно ровно перед перезагрузкой: если выключить телефон сразу после dtbs_install, есть шанс, что новый dtb физически не долетел, и на диске останется обрезанный файл. Загрузчик такой прочитает и не запустится — а чинить это придётся уже из рекавери. Пара секунд на команду против такого сценария — выгодный обмен. По той же причине я его пишу и после установки ядра. 💰 6.80₽ · ⬇️ 274.0k / ⬆️ 328 · opus-5 · max · 10с
Ы
S
ыв приложении plasma-camera той ошибки терь нед. есть ток Camera not available
Хороший сдвиг — значит формат больше не спотыкается, теперь просто не находит устройство. Проверим, что видно на трёх уровнях: cam -l | grep -E "^[0-9]:" wpctl status | grep -A5 Sources systemctl --user status pipewire wireplumber --no-pager 2>/dev/null | grep -E "Active|Loaded" | head -4 Если cam камеру видит, а pipewire нет — просто перезапусти сеанс медиасервера: systemctl --user restart pipewire wireplumber sleep 2; wpctl status | grep -A5 Sources Подозреваю, что после перезагрузки wireplumber успел прочитать граф раньше, чем camss закончил регистрацию, и остался ни с чем. 💰 7.04₽ · ⬇️ 274.5k / ⬆️ 552 · opus-5 · max · 11с
Ы
S
ыcam -l | grep -E "^[0-9]:" [0:01:45.770689921] [2486] INFO Camera camera_manager.cpp:340 libcamera v0.0.0+1-244572db-dirty (2026-08-02T09:37:10GMT) [0:01:45.775351599] [2488] INFO SimplePipeline simple.cpp:1911 No sensor found for /dev/media0
Хуже — теперь camss вообще не видит ни одного сенсора. Значит зацепило и широкую. Смотрим, что происходило при загрузке: dmesg | grep -iE "imx586|dw976|ov8856|camss|cci" | tail -30 Заодно проверим, что в собранном дереве получилось на самом деле: dtc -I fs -O dts /proc/device-tree/soc@0/cci@ac4a000 2>/dev/null | grep -A3 -E "camera@1a|camera@36" | head -20 Подозреваю одно из двух: либо мой блок приписался не туда и отключил не тот узел, либо сенсор в этот раз не поднялся по другой причине — например, объектив снова не успел, а он у нас в зависимостях. 💰 7.45₽ · ⬇️ 275.3k / ⬆️ 844 · opus-5 · max · 16с
Ы
stdvectorclaudebotХуже — теперь camss вообще не видит ни одного сенсора. Значит зацепило и широкую. Смотрим, что происходило при загрузке: dmesg | grep -iE "imx586|dw976|ov8856|camss|cci" | tail -30 Заодно проверим, что в собранном дереве получилось на самом деле: dtc -I fs -O dts /proc/device-tree/soc@0/cci@ac4a0
sudo dmesg | grep -iE "imx586|dw976|ov8856|camss|cci" | tail -30 [ 0.643109] platform ace0000.camss: Adding to iommu group 8 [ 12.161971] calling qcom_cci_driver_init+0x0/0xff8 [i2c_qcom_cci] @ 683 [ 12.218138] /soc@0/camss@ace0000: Fixed dependency cycle(s) with /soc@0/cci@ac4a000/i2c-bus@0/camera@1a [ 12.218239] /soc@0/cci@ac4a000/i2c-bus@0/camera@1a: Fixed dependency cycle(s) with /soc@0/camss@ace0000 [ 12.245726] probe of ac4a000.cci returned 0 after 79230 usecs [ 12.261155] probe of ac4b000.cci returned 0 after 15397 usecs [ 12.277401] initcall qcom_cci_driver_init+0x0/0xff8 [i2c_qcom_cci] returned 0 after 2585 usecs [ 12.451174] calling qcom_camss_driver_init+0x0/0xff8 [qcom_camss] @ 663 [ 12.467864] qcom-camss ace0000.camss: parsed endpoint /soc@0/camss@ace0000/ports/port@0/endpoint of port 0: 4 lanes, first 0 [ 12.472200] qcom-camss ace0000.camss: parsed endpoint /soc@0/camss@ace0000/ports/port@3/endpoint of port 3: 2 lanes, first 0 [ 12.498440] probe of ace0000.camss returned 0 after 45022 usecs [ 12.502731] initcall qcom_camss_driver_init+0x0/0xff8 [qcom_camss] returned 0 after 34539 usecs [ 12.676818] calling dw9768_i2c_driver_init+0x0/0xff8 [dw9768] @ 665 [ 12.705469] initcall dw9768_i2c_driver_init+0x0/0xff8 [dw9768] returned 0 after 2480 usecs [ 12.724098] calling imx586_i2c_driver_init+0x0/0xff8 [imx586] @ 681 [ 12.737141] imx586 12-001a: IMX582 detected [ 12.742400] imx586 12-001a: signalling mode default 0x02 [ 12.762162] imx586 12-001a: lane mode default 0x03 [ 12.790466] initcall imx586_i2c_driver_init+0x0/0xff8 [imx586] returned 0 after 61465 usecs
S
ыsudo dmesg | grep -iE "imx586|dw976|ov8856|camss|cci" | tail -30 [ 0.643109] platform ace0000.camss: Adding to iommu group 8 [ 12.161971] calling qcom_cci_driver_init+0x0/0xff8 [i2c_qcom_cci] @ 683 [ 12.218138] /soc@0/camss@ace0000: Fixed dependency cycle(s) with /soc@0/cci@ac4a000/i2c-bus@0
Вот и объяснение: сенсор поднялся нормально («IMX582 detected»), но camss всё равно ждёт обе камеры — в логе видно, что он разобрал и порт 0, и порт 3. Отключённый сенсор к порту 3 больше не привязывается, ожидание не завершается никогда, и граф так и не публикуется. Отсюда «No sensor found». Значит убирать надо не только сенсор, но и вход, к которому он подключён: cat >> $F <<'EOF' /* вместе с отключённым телевиком убираем и его вход в camss, иначе приёмник ждёт сенсор, которого нет, и граф не публикуется */ &camss { ports { port@3 { /delete-node/ endpoint; }; }; }; EOF cd $K && make dtbs -j8 && sudo make dtbs_install INSTALL_DTBS_PATH=/boot/dtbs && sync После перезагрузки в логе должна остаться одна строка parsed endpoint ... port 0, а cam -l показать одну камеру. Если предпочитаешь наоборот — вернуть телевик и не трогать дерево, скажи, тогда просто уберём оба добавленных блока и спрячем лишний узел правилом wireplumber, без перезагрузки. 💰 9.01₽ · ⬇️ 277.0k / ⬆️ 1.8k · opus-5 · max · 31с
Ы
S
ыда пиши полные пути заепал
Понял, больше без переменных. cat >> /home/user/linux-7.2/arch/arm64/boot/dts/qcom/sm7150-xiaomi-davinci.dtsi <<'EOF' /* вместе с отключённым телевиком убираем и его вход в camss, иначе приёмник ждёт сенсор, которого нет, и граф не публикуется */ &camss { ports { port@3 { /delete-node/ endpoint; }; }; }; EOF cd /home/user/linux-7.2 && make dtbs -j8 && sudo make dtbs_install INSTALL_DTBS_PATH=/boot/dtbs && sync После перезагрузки: sudo dmesg | grep "parsed endpoint" cam -l | grep -E "^[0-9]:" Ждём одну строку про порт 0 и одну камеру в списке. 💰 7.54₽ · ⬇️ 278.9k / ⬆️ 425 · opus-5 · max · 7с
Ы
stdvectorclaudebotПонял, больше без переменных. cat >> /home/user/linux-7.2/arch/arm64/boot/dts/qcom/sm7150-xiaomi-davinci.dtsi <<'EOF' /* вместе с отключённым телевиком убираем и его вход в camss, иначе приёмник ждёт сенсор, которого нет, и граф не публикуется */ &camss { ports { port@3 { /delete-node/ en
arch/arm64/boot/dts/qcom/sm7150-xiaomi-davinci.dtsi:195.24-201.6: ERROR (phandle_references): /soc@0/cci@ac4a000/i2c-bus@1/camera@36/port/endpoint: Reference to non-existent node or label "csiphy3_ep" arch/arm64/boot/dts/qcom/sm7150-xiaomi-davinci.dtsi:195.24-201.6: ERROR (phandle_references): /soc@0/cci@ac4a000/i2c-bus@1/camera@36/port/endpoint: Reference to non-existent node or label "csiphy3_ep" ERROR: Input tree has errors, aborting (use -f to force output) ERROR: Input tree has errors, aborting (use -f to force output) make[3]: *** [scripts/Makefile.dtbs:140: arch/arm64/boot/dts/qcom/sm7150-xiaomi-davinci-visionox.dtb] Error 2 make[3]: *** Waiting for unfinished jobs.... make[3]: *** [scripts/Makefile.dtbs:140: arch/arm64/boot/dts/qcom/sm7150-xiaomi-davinci-samsung.dtb] Error 2 make[2]: *** [scripts/Makefile.build:549: arch/arm64/boot/dts/qcom] Error 2 make[1]: *** [/home/user/linux-7.2/Makefile:1629: dtbs] Error 2 make: *** [Makefile:248: __sub-make] Error 2
S
ыarch/arm64/boot/dts/qcom/sm7150-xiaomi-davinci.dtsi:195.24-201.6: ERROR (phandle_references): /soc@0/cci@ac4a000/i2c-bus@1/camera@36/port/endpoint: Reference to non-existent node or label "csiphy3_ep" arch/arm64/boot/dts/qcom/sm7150-xiaomi-davinci.dtsi:195.24-201.6: ERROR (phandle_references): /soc
Логично: я удалил вход, а сенсор телевика на него ссылается. Раз он нам сейчас не нужен — удалим его целиком, тогда и ссылка исчезнет: cat >> /home/user/linux-7.2/arch/arm64/boot/dts/qcom/sm7150-xiaomi-davinci.dtsi <<'EOF' /* сенсор телевика ссылается на удалённый вход, поэтому убираем и его */ &cci0_i2c1 { /delete-node/ camera@36; }; EOF cd /home/user/linux-7.2 && make dtbs -j8 && sudo make dtbs_install INSTALL_DTBS_PATH=/boot/dtbs && sync Когда вернёмся к телевику, просто снесём эти три добавленных блока в конце файла — они идут подряд и помечены комментариями. 💰 7.75₽ · ⬇️ 279.9k / ⬆️ 911 · opus-5 · max · 15с
Ы
S
ыпосле перезагрузки вернулось "The configuration is not valid"
Значит телевик был ни при чём — ошибка от самой широкой. Надо понять, каким путём приложение вообще ходит в камеру: ldd /usr/bin/plasma-camera | grep -iE "camera|pipewire|gstreamer|multimedia|Qt6Multimedia" ls /usr/lib/qt6/plugins/multimedia/ 2>/dev/null Подозрение такое: plasma-camera построен на QtMultimedia, а у неё на Linux по умолчанию бэкенд ffmpeg, который умеет только сырой V4L2. Он видит наши узлы camss (/dev/video0 и компанию), пытается открыть их как обычную веб-камеру — и получает отказ, потому что там нужен предварительно настроенный граф и упакованный raw10, а не готовый YUV. Если так, то приложение к нашей камере просто не подходит, и лечится это не настройкой, а другим потребителем: qcam из нашей сборки, Megapixels, или Qt с бэкендом gstreamer плюс libcamerasrc. Но сначала посмотрим на вывод — гадать не будем. 💰 8.17₽ · ⬇️ 280.8k / ⬆️ 1.3k · opus-5 · max · 22с
Ы
stdvectorclaudebotЗначит телевик был ни при чём — ошибка от самой широкой. Надо понять, каким путём приложение вообще ходит в камеру: ldd /usr/bin/plasma-camera | grep -iE "camera|pipewire|gstreamer|multimedia|Qt6Multimedia" ls /usr/lib/qt6/plugins/multimedia/ 2>/dev/null Подозрение такое: plasma-camera построен на
ldd /usr/bin/plasma-camera | grep -iE "camera|pipewire|gstreamer|multimedia|Qt6Multimedia" libQt6Multimedia.so.6 => /lib/libQt6Multimedia.so.6 (0xffff9ff38000) libcamera.so.0.7 => /lib/libcamera.so.0.7 (0xffff9d82a000) libcamera-base.so.0.7 => /lib/libcamera-base.so.0.7 (0xffff9fc71000) ls /usr/lib/qt6/plugins/multimedia/ 2>/dev/null libffmpegmediaplugin.so libgstreamermediaplugin.so в /lib/ если чо наша libcamera
S
ыldd /usr/bin/plasma-camera | grep -iE "camera|pipewire|gstreamer|multimedia|Qt6Multimedia" libQt6Multimedia.so.6 => /lib/libQt6Multimedia.so.6 (0xffff9ff38000) libcamera.so.0.7 => /lib/libcamera.so.0.7 (0xffff9d82a000) libcamera-base.so.0.7 => /lib/libcamera-base.so.0.7 (0xffff9fc71000) ls /us
Тогда смотрим, что именно оно просит. Включим логи QtMultimedia: export XDG_RUNTIME_DIR=/run/user/$(id -u) WAYLAND_DISPLAY=wayland-0 QT_LOGGING_RULES="qt.multimedia*=true" plasma-camera 2>&1 | tail -30 И заодно проверим, кто там тянет libcamera — сама Qt или приложение: ldd /lib/libQt6Multimedia.so.6 | grep -i camera ldd /usr/lib/qt6/plugins/multimedia/libffmpegmediaplugin.so | grep -i camera Есть ещё второй бэкенд, gstreamer — его можно попробовать прямо так: QT_MEDIA_BACKEND=gstreamer plasma-camera 2>&1 | tail -20 Ключевой вопрос — открывает ли оно камеру через libcamera или лезет напрямую в /dev/video0. Во втором случае оно обречено: наши узлы отдают упакованный raw10 и требуют настроенного графа, обычная камера так себя не ведёт. 💰 9.36₽ · ⬇️ 282.4k / ⬆️ 2.1k · opus-5 · max · 32с
Ы
stdvectorclaudebotТогда смотрим, что именно оно просит. Включим логи QtMultimedia: export XDG_RUNTIME_DIR=/run/user/$(id -u) WAYLAND_DISPLAY=wayland-0 QT_LOGGING_RULES="qt.multimedia*=true" plasma-camera 2>&1 | tail -30 И заодно проверим, кто там тянет libcamera — сама Qt или приложение: ldd /lib/libQt6Multimedia.
в логах опять пусто qcom-sm7150:~$ ldd /lib/libQt6Multimedia.so.6 | grep -i camera qcom-sm7150:~$ qcom-sm7150:~$ ldd /usr/lib/qt6/plugins/multimedia/libffmpegmediaplugin.so | grep -i camera qcom-sm7150:~$ с другим бекендом та же ошибка
S
ыв логах опять пусто qcom-sm7150:~$ ldd /lib/libQt6Multimedia.so.6 | grep -i camera qcom-sm7150:~$ qcom-sm7150:~$ ldd /usr/lib/qt6/plugins/multimedia/libffmpegmediaplugin.so | grep -i camera qcom-sm7150:~$ с другим бекендом та же ошибка
Тогда спросим саму libcamera — она логирует независимо от Qt: export XDG_RUNTIME_DIR=/run/user/$(id -u) WAYLAND_DISPLAY=wayland-0 LIBCAMERA_LOG_LEVELS=*:DEBUG plasma-camera 2>&1 | grep -iE "validate|configur|adjust|pixelformat|stream" | tail -40 Там будет видно, какой формат и размер оно запрашивает и на чём проверка говорит «нет». И для сравнения — заведомо рабочий потребитель на Qt, если он собрался: ls -l /home/user/libcamera/build/src/apps/qcam/qcam 2>/dev/null && \ /home/user/libcamera/build/src/apps/qcam/qcam 2>&1 | tail -5 Если qcam покажет живую картинку — значит виновата логика запроса в plasma-camera, и чинить надо её, а не камеру. 💰 8.20₽ · ⬇️ 284.7k / ⬆️ 736 · opus-5 · max · 13с
S
ыпусто все равно
А, понял, в чём фокус: tail ничего не покажет, пока программа не завершится, а она висит с открытым окном. Пиши в файл: export XDG_RUNTIME_DIR=/run/user/$(id -u) WAYLAND_DISPLAY=wayland-0 LIBCAMERA_LOG_LEVELS=*:DEBUG plasma-camera > /tmp/pc.log 2>&1 & sleep 8 kill %1 wc -l /tmp/pc.log grep -iE "validate|configur|adjust|pixelformat|Invalid" /tmp/pc.log | tail -30 Если файл окажется пустым и после этого — значит приложение вообще не доходит до libcamera, и тогда смотрим просто первые строки: head -30 /tmp/pc.log 💰 7.49₽ · ⬇️ 285.4k / ⬆️ 650 · opus-5 · max · 10с
Ы
S
ыдержи лог с самого начала
Вот и причина, целиком видно в логе: Picked 8000x6000 ... for max processed stream size 7992x6000 Failed to open /dev/dma_heap/system: No such file or directory Using /dev/udmabuf Failed to create dma buf for frame-0: Invalid argument Приложение не задаёт размер, libcamera по умолчанию берёт максимум — 7992×6000 в ABGR8888, это 191 МБ на кадр. Куч dma-heap в ядре нет, поэтому libcamera выделяет через udmabuf, а у того по умолчанию стоит потолок в 64 МБ на буфер. Отсюда Invalid argument и «конфигурация недопустима». Потолок правится на лету: cat /sys/module/udmabuf/parameters/size_limit_mb echo 1024 | sudo tee /sys/module/udmabuf/parameters/size_limit_mb И запускай приложение снова. Оно должно завестись, но учти: полный кадр через программный демозаик — это порядка секунды на кадр, видоискатель будет ползти. Зато мы убедимся, что причина именно эта. А правильное лечение — включить в ядре кучи dma-buf, тогда libcamera возьмёт нормальный аллокатор: CONFIG_DMABUF_HEAPS=y CONFIG_DMABUF_HEAPS_SYSTEM=y CONFIG_DMABUF_HEAPS_CMA=y Это в следующую пересборку ядра, вместе с патчем get_selection для телевика. 💰 13.59₽ · ⬇️ 296.6k / ⬆️ 1.9k · opus-5 · max · 33с
Ы
S
ытеперь оно камеру видит но там задержка адовая и все зеленое и будто бы в точках но не совсем. будто специально фильтр такой
Всё сходится: это не фильтр, а квадро-байер. В полном разрешении сенсор отдаёт пиксели группами 2×2 одного цвета — вместо привычного шахматного узора получается «крупная клетка», и обычный демозаик libcamera раскладывает её в зелёное с точками. Мы это уже видели в своих кадрах: полный кадр надо разбирать шаблоном quad, а не rggb. Проще говоря, режим 8000×6000 годится только как сырьё для нашего инструмента, а для просмотра нужен любой другой — они все с бинингом и дают честный байер. Плюс задержка сразу упадёт: 1080p через программный демозаик это 24 мс на кадр против почти секунды сейчас. Загляни в настройки приложения — там должен быть выбор разрешения, судя по логу оно знает про все четыре режима (1920×1080, 4000×2250, 4000×3000, 8000×6000). Поставь 1920×1080. Если селектора там нет, сделаем иначе: добавлю в драйвер параметр модуля, скрывающий полноразмерный режим от перечисления, и тогда libcamera будет брать максимумом 4000×3000. Наши собственные скрипты полный кадр всё равно снимут, они ходят напрямую. 💰 9.31₽ · ⬇️ 298.8k / ⬆️ 1.5k · opus-5 · max · 28с
Ы
S
ычот в настройках нет параметра для предпросмотра. а телеф грееца так чо аж совсем
Понял — значит выбор разрешения у приложения не предусмотрен вообще, оно берёт умолчание libcamera, а умолчание там — «самый большой размер». В коде рядом с этим местом даже висит комментарий разработчиков «надо бы придумать способ выбирать по-умному». Придумаем. Правка на три десятка строк в нашей сборке: для видоискателя брать не максимум, а самый большой размер в пределах разумного. python3 - <<'PY' p = "/home/user/libcamera/src/libcamera/pipeline/simple/simple.cpp" s = open(p).read() anchor = """\t\tcfg.pixelFormat = formats.begin()->first; \t\tcfg.size = formats.begin()->second[0].max; """ add = """ \t\t/* \t\t * Taking the largest size is a poor default for a software ISP: \t\t * on this board it selects a 48 megapixel quad bayer mode that no \t\t * debayer can interpret and that costs about a second a frame. \t\t * Prefer the largest size that stays sane for the role. \t\t */ \t\tif (role != StreamRole::Raw) { \t\t\tconst Size limit = role == StreamRole::StillCapture \t\t\t\t\t ? Size(4096, 3072) : Size(1920, 1080); \t\t\tSize best; \t\t\tfor (const SizeRange &range : formats.begin()->second) { \t\t\t\tconst Size &sz = range.max; \t\t\t\tif (sz.width <= limit.width && sz.height <= limit.height && \t\t\t\t sz.width * sz.height > best.width * best.height) \t\t\t\t\tbest = sz; \t\t\t} \t\t\tif (!best.isNull()) \t\t\t\tcfg.size = best; \t\t} """ assert anchor in s, "не нашёл место вставки" open(p, "w").write(s.replace(anchor, anchor + add, 1)) print("вставлено") PY cd /home/user/libcamera && ninja -C build && sudo ninja -C build install Пересборка тут только одного файла, минуты две. После неё видоискатель пойдёт в 1920×1080 — это 24 мс на кадр вместо секунды, и телефон перестанет греться. Съёмка фото останется в 4000×3000, а полноразмерный квадро-байер будет доступен только нашим скриптам, которые умеют его разбирать правильно. 💰 28.10₽ · ⬇️ 905.8k / ⬆️ 5.2k · opus-5 · max · 81с
Ы
S
ыне эт костыль какой та. лучше потребителя пропатчить. или другого взять
Согласен, это лечение симптома в чужом коде. Тогда так. Сначала проверим, что вообще доступно как потребитель: ls /home/user/libcamera/build/src/apps/qcam/qcam 2>/dev/null && echo "qcam собран" apk search -q megapixels 2>/dev/null apk search -q snapshot 2>/dev/null | head -5 qcam — родной просмотрщик libcamera, он принимает те же ключи потока, что и cam, то есть разрешение задаётся явно: XDG_RUNTIME_DIR=/run/user/$(id -u) WAYLAND_DISPLAY=wayland-0 \ /home/user/libcamera/build/src/apps/qcam/qcam -c 1 -s width=1920,height=1080,pixelformat=RGB888 Это сразу даст живой видоискатель без всяких патчей — годится как проверка и как рабочий инструмент на сегодня. А правильный потребитель для телефона — Megapixels: он специально сделан под такие камеры, умеет выбирать режим для превью и отдельный для снимка, и настраивается файлом описания устройства. Как раз наш случай: превью в 1920×1080, снимок в 4000×3000, а полноразмерный квадро-байер вообще не трогаем. Если он есть в репозитории, поставим и напишем ему описание для давинчи — заодно это готовый кусок для порта в pmOS. plasma-camera в этой роли слабоват: он не даёт выбрать разрешение вообще, что для телефона с четырьмя режимами странно. Но если хочешь, потом заведём им запрос — правка там небольшая. 💰 9.94₽ · ⬇️ 307.0k / ⬆️ 1.3k · opus-5 · max · 23с
S
ы-ash: /home/user/libcamera/build/src/apps/qcam/qcam: not found
Значит qcam не собрался — для него нужны заголовки Qt6, которых при сборке не было. Покажи, что нашлось в репозитории: apk search -q megapixels; echo "---"; apk search -q camera | head -20 Если megapixels там есть — ставим его, это самый подходящий вариант. Если нет, вторым кандидатом идёт snapshot от GNOME (ходит через pipewire), а третьим — досборка qcam: пакеты qt6-qtbase-dev и qt6-qttools-dev, потом meson configure build -Dqcam=enabled и пересборка. 💰 7.89₽ · ⬇️ 308.3k / ⬆️ 333 · opus-5 · max · 9с
Ы
S
ыNo camera found в megapixels
Ему нужен файл описания устройства — сам он камеру не ищет, а берёт готовое описание по совместимости платы. Посмотрим, что за версия и куда класть: apk info -v megapixels apk info -L megapixels | grep -iE "config|\.ini|share" | head -20 tr '\0' '\n' < /proc/device-tree/compatible ls /usr/share/megapixels/config/ 2>/dev/null | head По этим четырём выводам я напишу описание для давинчи: превью 1920×1080, снимок 4000×3000, поворот 180, объектив через focus_absolute. Заодно это ровно тот файл, который потом уйдёт в pmOS вместе с портом. 💰 8.11₽ · ⬇️ 308.7k / ⬆️ 889 · opus-5 · max · 15с
Ы
stdvectorclaudebotЕму нужен файл описания устройства — сам он камеру не ищет, а берёт готовое описание по совместимости платы. Посмотрим, что за версия и куда класть: apk info -v megapixels apk info -L megapixels | grep -iE "config|\.ini|share" | head -20 tr '\0' '\n' < /proc/device-tree/compatible ls /usr/share/meg
Ссылка
нажмите — покажем
qcom-sm7150:~$ apk info -v megapixels megapixels: GTK+4 camera app for mobile devices megapixels: https://gitlab.com/megapixels-org/Megapixels megapixels: 2389 KiB qcom-sm7150:~$ apk info -L megapixels | grep -iE "config|\.ini|share" | head -20 usr/share/applications/me.gapixels.Megapixels.desktop usr/share/glib-2.0/schemas/me.gapixels.Megapixels.gschema.xml usr/share/icons/hicolor/scalable/apps/me.gapixels.Megapixels.svg usr/share/megapixels/movie.sh usr/share/megapixels/postprocess.sh usr/share/megapixels/config/pine64,pinephone,front.dcp usr/share/megapixels/config/pine64,pinephone,rear.dcp usr/share/metainfo/me.gapixels.Megapixels.metainfo.xml qcom-sm7150:~$ tr '\0' '\n' < /proc/device-tree/compatible xiaomi,davinci-samsung xiaomi,davinci qcom,sm7150 qcom-sm7150:~$ ls /usr/share/megapixels/config/ 2>/dev/null | head google,b4s4-sdm670.conf pine64,pinephone,front.dcp pine64,pinephone,rear.dcp pine64,pinephone-pro.conf pine64,pinephone.conf pine64,pinetab.conf purism,librem5.conf samsung,midas.conf xiaomi,daisy.conf xiaomi,markw.conf
S
ыqcom-sm7150:~$ apk info -v megapixels megapixels: GTK+4 camera app for mobile devices megapixels: https://gitlab.com/megapixels-org/Megapixels megapixels: 2389 KiB qcom-sm7150:~$ apk info -L megapixels | grep -iE "config|\.ini|share" | head -20 usr/share/applications/me.gapixels.Megapixels.desktop u
Формат .conf, ключ — совместимость платы, значит нам нужен /usr/share/megapixels/config/xiaomi,davinci.conf. Покажи готовый пример, чтобы я написал наш точно по формату: cat "/usr/share/megapixels/config/xiaomi,daisy.conf" echo "==========" head -40 "/usr/share/megapixels/config/pine64,pinephone.conf" Дальше я соберу описание для давинчи: превью 1920×1080, снимок 4000×3000, поворот 180, объектив на focus_absolute — и телевик впишем сразу, чтобы потом не возвращаться. 💰 8.18₽ · ⬇️ 310.2k / ⬆️ 494 · opus-5 · max · 11с
Ы
stdvectorclaudebotФормат .conf, ключ — совместимость платы, значит нам нужен /usr/share/megapixels/config/xiaomi,davinci.conf. Покажи готовый пример, чтобы я написал наш точно по формату: cat "/usr/share/megapixels/config/xiaomi,daisy.conf" echo "==========" head -40 "/usr/share/megapixels/config/pine64,pinephone.co
Version = 1; Make: "Xiaomi"; Model: "Mi A2 Lite"; Front: { SensorDriver: "ov5675"; BridgeDriver: "qcom-camss"; Modes: ( { Width: 2592; Height: 1944; Rate: 30; Format: "GRBG10p"; Rotate: 270; Mirror: true; Pipeline: ( {Type: "Link", From: "msm_csiphy2", FromPad: 1, To: "msm_csid0", ToPad: 0}, {Type: "Link", From: "msm_csid0", FromPad: 1, To: "msm_ispif0", ToPad: 0}, {Type: "Link", From: "msm_ispif0", FromPad: 1, To: "msm_vfe0_rdi0", ToPad: 0}, {Type: "Mode", Entity: "ov5675"}, {Type: "Mode", Entity: "msm_csiphy2"}, {Type: "Mode", Entity: "msm_csid0"}, {Type: "Mode", Entity: "msm_ispif0"}, {Type: "Mode", Entity: "msm_vfe0_rdi0"} ); }, { Width: 1296; Height: 972; Rate: 30; Format: "GRBG10p"; Rotate: 270; Mirror: true; Pipeline: ( {Type: "Link", From: "msm_csiphy2", FromPad: 1, To: "msm_csid0", ToPad: 0}, {Type: "Link", From: "msm_csid0", FromPad: 1, To: "msm_ispif0", ToPad: 0}, {Type: "Link", From: "msm_ispif0", FromPad: 1, To: "msm_vfe0_rdi0", ToPad: 0}, {Type: "Mode", Entity: "ov5675"}, {Type: "Mode", Entity: "msm_csiphy2"}, {Type: "Mode", Entity: "msm_csid0"}, {Type: "Mode", Entity: "msm_ispif0"}, {Type: "Mode", Entity: "msm_vfe0_rdi0"} ); } ); }; Version = 1; Make: "PINE64"; Model: "PinePhone"; Rear: { SensorDriver: "ov5640"; BridgeDriver: "sun6i-csi"; FlashPath: "/sys/class/leds/white:flash"; IsoMin: 100; IsoMax: 64000; Modes: ( { Width: 2592; Height: 1944; Rate: 15; Format: "BGGR8"; Rotate: 270; FocalLength: 3.33; FNumber: 3.0; Pipeline: ( {Type: "Link", From: "ov5640", FromPad: 0, To: "sun6i-csi-bridge", ToPad: 0}, {Type: "Mode", Entity: "ov5640"}, {Type: "Mode", Entity: "sun6i-csi-bridge"} ); }, { Width: 1280; Height: 720; Rate: 30; Format: "BGGR8"; Rotate: 270; FocalLength: 3.33; FNumber: 3.0; Pipeline: ( {Type: "Link", From: "ov5640", FromPad: 0, To: "sun6i-csi-bridge", ToPad: 0}, {Type: "Mode", Entity: "ov5640"}, {Type: "Mode", Entity: "sun6i-csi-bridge"}
S
ыVersion = 1; Make: "Xiaomi"; Model: "Mi A2 Lite"; Front: { SensorDriver: "ov5675"; BridgeDriver: "qcom-camss"; Modes: ( { Width: 2592; Height: 1944; Rate: 30; Format: "GRBG10p"; Rotate: 270; Mirror: true;
Формат понятен — Megapixels сам рулит графом через media-ctl, libcamera ему не нужна. Значит пишем описание нашей камеры: sudo tee "/usr/share/megapixels/config/xiaomi,davinci.conf" >/dev/null <<'EOF' Version = 1; Make: "Xiaomi"; Model: "Mi 9T"; Rear: { SensorDriver: "imx586"; BridgeDriver: "qcom-camss"; IsoMin: 100; IsoMax: 6400; Modes: ( { Width: 1920; Height: 1080; Rate: 30; Format: "RGGB10p"; Rotate: 180; FocalLength: 4.74; FNumber: 1.75; Pipeline: ( {Type: "Link", From: "msm_csiphy0", FromPad: 1, To: "msm_csid0", ToPad: 0}, {Type: "Link", From: "msm_csid0", FromPad: 1, To: "msm_vfe0_rdi0", ToPad: 0}, {Type: "Mode", Entity: "imx586"}, {Type: "Mode", Entity: "msm_csiphy0"}, {Type: "Mode", Entity: "msm_csid0"}, {Type: "Mode", Entity: "msm_vfe0_rdi0"} ); }, { Width: 4000; Height: 3000; Rate: 30; Format: "RGGB10p"; Rotate: 180; FocalLength: 4.74; FNumber: 1.75; Pipeline: ( {Type: "Link", From: "msm_csiphy0", FromPad: 1, To: "msm_csid0", ToPad: 0}, {Type: "Link", From: "msm_csid0", FromPad: 1, To: "msm_vfe0_rdi0", ToPad: 0}, {Type: "Mode", Entity: "imx586"}, {Type: "Mode", Entity: "msm_csiphy0"}, {Type: "Mode", Entity: "msm_csid0"}, {Type: "Mode", Entity: "msm_vfe0_rdi0"} ); } ); }; EOF Полноразмерный режим я сюда сознательно не вписал — он квадро-байерный, и обычным демозаиком из него получается та самая зелёная сетка. Запускай. Если снова скажет, что камеры нет, посмотрим, по какой строке совместимости он ищет: megapixels 2>&1 | head -20 💰 10.54₽ · ⬇️ 312.0k / ⬆️ 2.4k · opus-5 · max · 35с
S
ыон чот крашица ваще
Нужен его вывод — он при падении обычно пишет причину: export XDG_RUNTIME_DIR=/run/user/$(id -u) WAYLAND_DISPLAY=wayland-0 megapixels > /tmp/mp.log 2>&1; echo "код выхода: $?"; tail -30 /tmp/mp.log Скорее всего одно из трёх: не понравился формат RGGB10p (тогда он ждёт другое написание), не нашёл сущность imx586 по короткому имени, или споткнулся на моих ссылках в конвейере. В логе это будет прямым текстом. 💰 8.74₽ · ⬇️ 314.5k / ⬆️ 537 · opus-5 · max · 11с
Ы
stdvectorclaudebotНужен его вывод — он при падении обычно пишет причину: export XDG_RUNTIME_DIR=/run/user/$(id -u) WAYLAND_DISPLAY=wayland-0 megapixels > /tmp/mp.log 2>&1; echo "код выхода: $?"; tail -30 /tmp/mp.log Скорее всего одно из трёх: не понравился формат RGGB10p (тогда он ждёт другое написание), не нашёл с
megapixels Found postprocessor script at /usr/share/megapixels/movie.sh [libmegapixels] Driver rejected pixfmt try: 0x3007 MPCamera: VIDIOC_STREAMON error 32, Broken pipe Initialized OpenGL ES 3.2 Found calibration file at .config MPCamera: VIDIOC_DQBUF error 22, Invalid argument Segmentation fault (core dumped)
S
ыmegapixels Found postprocessor script at /usr/share/megapixels/movie.sh [libmegapixels] Driver rejected pixfmt try: 0x3007 MPCamera: VIDIOC_STREAMON error 32, Broken pipe Initialized OpenGL ES 3.2 Found calibration file at .config MPCamera: VIDIOC_DQBUF error 22, Invalid argument Segmentation fault
Ключевая строка — Driver rejected pixfmt try: 0x3007. Это код SBGGR10_1X10, то есть он просит у сенсора байер «синий первый», а драйвер сейчас отдаёт «красный первый» (0x300f). Дальше по цепочке всё рушится: поток не стартует, буфер не приходит, и на этом он падает уже своим багом. Скорее всего он сам разворачивает порядок из-за Rotate: 180 — поворот на 180 градусов действительно меняет RGGB на BGGR. Проверим и подстроимся. Сначала убедись, что флипы сброшены (их могла оставить libcamera): SD=$(media-ctl -d /dev/media0 -e "imx586 12-001a") v4l2-ctl -d $SD --get-ctrl horizontal_flip,vertical_flip Если оба нули — меняем строку формата на противоположную: sudo sed -i 's/"RGGB10p"/"BGGR10p"/g' "/usr/share/megapixels/config/xiaomi,davinci.conf" megapixels > /tmp/mp.log 2>&1; echo "код: $?"; grep -iE "pixfmt|STREAMON|DQBUF|error" /tmp/mp.log | head Если наоборот, флипы окажутся единицами — тогда порядок в конфиге правильный, а сбросить надо их: v4l2-ctl -d $SD --set-ctrl horizontal_flip=0,vertical_flip=0 💰 10.12₽ · ⬇️ 315.4k / ⬆️ 2.3k · opus-5 · max · 33с
Ы
S
ыv4l2-ctl -d $SD --get-ctrl horizontal_flip,vertical_flip horizontal_flip: 1 vertical_flip: 1
Вот и объяснение: флипы стоят в единицах, их оставила libcamera. С ними драйвер честно рапортует «синий первый», а всё остальное в конвейере ждёт «красный первый» — отсюда и отказ, и Broken pipe на старте потока. Сбрасываем флипы и возвращаем конфиг как был: SD=$(media-ctl -d /dev/media0 -e "imx586 12-001a") v4l2-ctl -d $SD --set-ctrl horizontal_flip=0,vertical_flip=0 sudo sed -i 's/"BGGR10p"/"RGGB10p"/g' "/usr/share/megapixels/config/xiaomi,davinci.conf" v4l2-ctl -d $SD --get-ctrl horizontal_flip,vertical_flip И запускай: export XDG_RUNTIME_DIR=/run/user/$(id -u) WAYLAND_DISPLAY=wayland-0 megapixels > /tmp/mp.log 2>&1; echo "код: $?"; grep -iE "pixfmt|STREAMON|DQBUF|error|calib" /tmp/mp.log | head Только учти: стоит запустить libcamera-приложение — и флипы вернутся, потому что она честно отрабатывает поворот модуля из дерева. Если megapixels взлетит, я допишу ему в конфиг постоянный сброс через правило udev, чтобы они не мешали друг другу. 💰 9.84₽ · ⬇️ 317.8k / ⬆️ 1.5k · opus-5 · max · 25с
Ы
S
ытеперь видит. ток почему то на 90 градусов повернутое
Так и должно быть: у вендора для задней широкой записан roll = 90, а в дереве у нас стоит rotation = <180> — это наследство форка, и оно неверно. Отсюда и расхождение. Сейчас подгони отображение: sudo sed -i 's/Rotate: 180;/Rotate: 270;/g' "/usr/share/megapixels/config/xiaomi,davinci.conf" megapixels Если перевернётся в другую сторону — поменяй на 90. А заодно это объясняет и конфликт с флипами. Сейчас в дереве написано «модуль повёрнут на 180», и libcamera честно пытается это исправить, включая оба флипа — из-за чего меняется порядок байера и ломается megapixels. Если поставить настоящие 90 градусов, libcamera флипами компенсировать уже не сможет (поворот на прямой угол так не исправляется) и просто сообщит ориентацию приложению. Флипы останутся нулевыми, и оба потребителя перестанут мешать друг другу. Правку в дерево внесу в следующий заход — она в одну строку, вместе с включением куч dma-buf в ядре. 💰 17.62₽ · ⬇️ 639.7k / ⬆️ 1.9k · opus-5 · max · 38с
Ы
S
ытерь правильно. ток все почему то слишком темное
Скорее всего он выставляет выдержку и усиление сам, по своим умолчаниям. Посмотри, что он реально ставит, пока окно открыто: SD=$(media-ctl -d /dev/media0 -e "imx586 12-001a") v4l2-ctl -d $SD --get-ctrl exposure,analogue_gain Для сравнения: на нормально освещённой комнате мы снимали с выдержкой около 3000 и усилением 960 в режиме 4000×3000, а в 1080p потолок выдержки примерно 1240. И загляни в интерфейс — у Megapixels есть панель с ISO и выдержкой, там же обычно переключатель автоматики. Если он стоит в ручном режиме с минимальными значениями, всё сходится. Если же окажется, что значения выставлены нормальные, а картинка всё равно тёмная — тогда дело в его собственной обработке: он берёт уровень чёрного и гамму из файла калибровки, а нашего у него нет, и он мог подставить чужой. 💰 8.67₽ · ⬇️ 321.7k / ⬆️ 764 · opus-5 · max · 16с
Ы
S
ыв ISO лимит 960 и EXP лимит 360
Покажи, что реально стоит в драйвере, пока окно открыто — из интерфейса не видно, в каких единицах он меряет: SD=$(media-ctl -d /dev/media0 -e "imx586 12-001a") v4l2-ctl -d $SD --get-ctrl exposure,analogue_gain,vertical_blanking media-ctl -d /dev/media0 -p | grep -A3 "imx586" | grep fmt Смысл вот в чём: у нашего сенсора потолок выдержки зависит от режима — в 1920×1080 это около 1240 строк, в 4000×3000 около 3030. Число 360 не совпадает ни с одним, значит либо Megapixels сам ограничивает выдержку кадровой частотой из конфига (мы написали 30, а режим умеет 60), либо он показывает не строки, а что-то своё. Если окажется первое — просто поднимем предел, увеличив вертикальный интервал через тот же конфиг или сняв ограничение частоты. 💰 8.95₽ · ⬇️ 322.6k / ⬆️ 1.2k · opus-5 · max · 22с
Ы
S
ыexposure: 1080 analogue_gain: 960 vertical_blanking: 182 это в auto режиме
Значит сенсор уже на пределе: выдержка 1080 строк при потолке 1240, усиление максимальное 960. Кстати, это и объясняет «EXP лимит 360» — он показывает десятые доли миллисекунды, 1240 строк это как раз 36 мс. То есть темнит не сенсор, а обработка самого Megapixels. У него превью — это быстрый демозаик на видеокарте с собственной тоновой кривой, и он часто заметно темнее итогового снимка. Проверь по-настоящему: нажми затвор и посмотри результат. ls -lt ~/Pictures/ 2>/dev/null | head Файл там появляется после отработки postprocess.sh — это уже полноценная обработка, с уровнем чёрного и балансом. И заодно посмотрим, что за калибровку он нашёл, а то в логе была подозрительная строка: grep -i calib /tmp/mp.log ls -la ~/.config/megapixels* ~/.local/share/megapixels 2>/dev/null | head Если он подобрал чужой профиль (там лежат только пайнфоновские), цвет и яркость будут считаться по не тем коэффициентам — тогда просто уберём его, и он вернётся к нейтральной обработке. 💰 9.49₽ · ⬇️ 323.8k / ⬆️ 1.5k · opus-5 · max · 27с
Ы
S
ыAssertion failed: bytesused == (libmegapixels_mode_width_to_bytes(format, width) + libmegapixels_mode_width_to_padding(format, width)) * height (../src/camera.c: mp_camera_capture_buffer: 400) Aborted (core dumped) это после нажатия кнопки фото
Ссылка
нажмите — покажем
Это известная бага, и её уже починили. В libmegapixels 0.2.1 есть ровно наш случай: библиотека стала брать длину строки из драйвера, потому что «не все драйверы используют минимальное дополнение для данной ширины и режима». Наш camss как раз такой — он выравнивает строку до 16 байт, и на 4000 пикселях получается 5008 вместо 5000. Отсюда и проверка, которая падает. Проверь версию: apk info -v libmegapixels megapixels 2>/dev/null Если меньше 0.2.1 — собери свежую, библиотека маленькая: cd ~ && git clone https://gitlab.com/megapixels-org/libmegapixels cd libmegapixels && meson setup build --prefix=/usr --libdir=lib --buildtype=release && ninja -C build && sudo ninja -C build install После этого снимок в 4000×3000 должен сохраниться нормально — а заодно и превью подтянется, потому что оно считает то же самое. Источники: заметки к выпуску 0.2.1, описание формата конфига, как добавлять железо в libmegapixels. 💰 32.41₽ · ⬇️ 654.1k / ⬆️ 1.8k · opus-5 · max · 54с
Ы

Все сообщения за 1 августа 2026 · Вся лента · Оригинал в Telegram

Открыть в Telegram Каталог площадок Искать в ChatCrawler

Слепок открытой публичной ленты из поискового индекса ChatCrawler — «Google по публичному Telegram»; обновляется по мере обхода площадки. Время — UTC.

Только публичный контент, официальный API Telegram. О проекте · Вопросы · Чего мы не делаем · Убрать страницу из выдачи · Каталог · Поиск · Как мы считаем