mirror of
https://github.com/pikvm/ustreamer.git
synced 2025-12-24 03:00:01 +00:00
bunch of fixes for m2m
This commit is contained in:
parent
222b9a0309
commit
630ad66cc8
15
README.md
15
README.md
@ -12,7 +12,7 @@
|
||||
| **Feature** | **µStreamer** | **mjpg-streamer** |
|
||||
|----------|---------------|-------------------|
|
||||
| Multithreaded JPEG encoding | ✔ | ✘ |
|
||||
| [OpenMAX IL](https://www.khronos.org/openmaxil) hardware acceleration<br>on Raspberry Pi | ✔ | ✘ |
|
||||
| Hardware image encoding<br>on Raspberry Pi | ✔ | ✘ |
|
||||
| Behavior when the device<br>is disconnected while streaming | ✔ Shows a black screen<br>with ```NO SIGNAL``` on it<br>until reconnected | ✘ Stops the streaming <sup>1</sup> |
|
||||
| [DV-timings](https://linuxtv.org/downloads/v4l-dvb-apis-new/userspace-api/v4l/dv-timings.html) support -<br>the ability to change resolution<br>on the fly by source signal | ✔ | ☹ Partially yes <sup>1</sup> |
|
||||
| Option to skip frames when streaming<br>static images by HTTP to save the traffic | ✔ <sup>2</sup> | ✘ |
|
||||
@ -35,13 +35,13 @@ If you're going to live-stream from your backyard webcam and need to control it,
|
||||
|
||||
-----
|
||||
# Building
|
||||
You'll need ```make```, ```gcc```, ```libevent``` with ```pthreads``` support, ```libjpeg8```/```libjpeg-turbo``` and ```libbsd``` (only for Linux).
|
||||
You'll need ```make```, ```gcc```, ```libevent``` with ```pthreads``` support, ```libjpeg9```/```libjpeg-turbo``` and ```libbsd``` (only for Linux).
|
||||
|
||||
* Arch: `sudo pacman -S libevent libjpeg-turbo libutil-linux libbsd`.
|
||||
* Raspbian: `sudo apt install libevent-dev libjpeg8-dev libbsd-dev`. Add `libraspberrypi-dev` for `WITH_OMX=1`, `libgpiod-dev` for `WITH_GPIO=1` and `libsystemd-dev` for `WITH_SYSTEMD=1`.
|
||||
* Raspbian: `sudo apt install libevent-dev libjpeg8-dev libbsd-dev`. Add `libgpiod-dev` for `WITH_GPIO=1` and `libsystemd-dev` for `WITH_SYSTEMD=1`.
|
||||
* Debian/Ubuntu: `sudo apt install build-essential libevent-dev libjpeg-dev libbsd-dev`.
|
||||
|
||||
On Raspberry Pi you can build the program with OpenMAX IL. To do this pass option ```WITH_OMX=1``` to ```make```. To enable GPIO support install [libgpiod](https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/about) and pass option ```WITH_GPIO=1```. If the compiler reports about a missing function ```pthread_get_name_np()``` (or similar), add option ```WITH_PTHREAD_NP=0``` (it's enabled by default). For the similar error with ```setproctitle()``` add option ```WITH_SETPROCTITLE=0```.
|
||||
To enable GPIO support install [libgpiod](https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/about) and pass option ```WITH_GPIO=1```. If the compiler reports about a missing function ```pthread_get_name_np()``` (or similar), add option ```WITH_PTHREAD_NP=0``` (it's enabled by default). For the similar error with ```setproctitle()``` add option ```WITH_SETPROCTITLE=0```.
|
||||
|
||||
```
|
||||
$ git clone --depth=1 https://github.com/pikvm/ustreamer
|
||||
@ -50,7 +50,8 @@ $ make
|
||||
$ ./ustreamer --help
|
||||
```
|
||||
|
||||
AUR has a package for Arch Linux: https://aur.archlinux.org/packages/ustreamer. It should compile automatically with OpenMAX IL on Raspberry Pi, if the corresponding headers are present in ```/opt/vc/include```.
|
||||
AUR has a package for Arch Linux: https://aur.archlinux.org/packages/ustreamer.
|
||||
|
||||
FreeBSD port: https://www.freshports.org/multimedia/ustreamer.
|
||||
|
||||
-----
|
||||
@ -67,8 +68,8 @@ The recommended way of running µStreamer with [Auvidea B101](https://www.raspbe
|
||||
$ export LD_LIBRARY_PATH=/opt/vc/lib/ # on bullseye
|
||||
$ ./ustreamer \
|
||||
--format=uyvy \ # Device input format
|
||||
--encoder=omx \ # Hardware encoding with OpenMAX
|
||||
--workers=3 \ # Maximum workers for OpenMAX
|
||||
--encoder=v4l2 \ # Hardware encoding on V4L2 M2M driver
|
||||
--workers=3 \ # Workers number
|
||||
--persistent \ # Don't re-initialize device on timeout (for example when HDMI cable was disconnected)
|
||||
--dv-timings \ # Use DV-timings
|
||||
--drop-same-frames=30 # Save the traffic
|
||||
|
||||
13
README.ru.md
13
README.ru.md
@ -12,7 +12,7 @@
|
||||
| **Фича** | **µStreamer** | **mjpg-streamer** |
|
||||
|----------|---------------|-------------------|
|
||||
| Многопоточное кодирование JPEG | ✔ | ✘ |
|
||||
| Аппаратное кодирование с помощью [OpenMAX IL](https://www.khronos.org/openmaxil) на Raspberry Pi | ✔ | ✘ |
|
||||
| Аппаратное кодирование на Raspberry Pi | ✔ | ✘ |
|
||||
| Поведение при физическом отключении<br>устройства от сервера во время работы | ✔ Транслирует черный экран<br>с надписью ```NO SIGNAL```,<br>пока устройство не будет подключено снова | ✘ Прерывает трансляцию <sup>1</sup> |
|
||||
| Поддержка [DV-таймингов](https://linuxtv.org/downloads/v4l-dvb-apis-new/userspace-api/v4l/dv-timings.html) - возможности<br>изменения параметров разрешения<br>трансляции на лету по сигналу<br>источника (устройства видеозахвата) | ✔ | ☹ Условно есть <sup>1</sup> |
|
||||
| Возможность пропуска фреймов при передаче<br>статического изображения по HTTP<br>для экономии трафика | ✔ <sup>2</sup> | ✘ |
|
||||
@ -38,10 +38,10 @@
|
||||
Для сборки вам понадобятся ```make```, ```gcc```, ```libevent``` с поддержкой ```pthreads```, ```libjpeg8```/```libjpeg-turbo``` и ```libbsd``` (только для Linux).
|
||||
|
||||
* Arch: `sudo pacman -S libevent libjpeg-turbo libutil-linux libbsd`.
|
||||
* Raspbian: `sudo apt install libevent-dev libjpeg8-dev libbsd-dev`. Добавьте `libraspberrypi-dev` для сборки с `WITH_OMX=1`, `libgpiod` для `WITH_GPIO=1` и `libsystemd-dev` для `WITH_SYSTEMD=1`.
|
||||
* Raspbian: `sudo apt install libevent-dev libjpeg8-dev libbsd-dev`. Добавьте `libgpiod` для `WITH_GPIO=1` и `libsystemd-dev` для `WITH_SYSTEMD=1`.
|
||||
* Debian/Ubuntu: `sudo apt install build-essential libevent-dev libjpeg-dev libbsd-dev`.
|
||||
|
||||
На Raspberry Pi программу можно собрать с поддержкой OpenMAX IL. Для этого передайте ```make``` параметр ```WITH_OMX=1```. Для включения сборки с поддержкой GPIO установите [libgpiod](https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/about) и добавьте параметр ```WITH_GPIO=1```. Если при сборке компилятор ругается на отсутствие функции ```pthread_get_name_np()``` или другой подобной, добавьте параметр ```WITH_PTHREAD_NP=0``` (по умолчанию он включен). При аналогичной ошибке с функцией ```setproctitle()``` добавьте параметр ```WITH_SETPROCTITLE=0```.
|
||||
Для включения сборки с поддержкой GPIO установите [libgpiod](https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/about) и добавьте параметр ```WITH_GPIO=1```. Если при сборке компилятор ругается на отсутствие функции ```pthread_get_name_np()``` или другой подобной, добавьте параметр ```WITH_PTHREAD_NP=0``` (по умолчанию он включен). При аналогичной ошибке с функцией ```setproctitle()``` добавьте параметр ```WITH_SETPROCTITLE=0```.
|
||||
|
||||
```
|
||||
$ git clone --depth=1 https://github.com/pikvm/ustreamer
|
||||
@ -50,7 +50,8 @@ $ make
|
||||
$ ./ustreamer --help
|
||||
```
|
||||
|
||||
Для Arch Linux в AUR есть готовый пакет: https://aur.archlinux.org/packages/ustreamer. На Raspberry Pi програма автоматически собирается с поддержкой OpenMAX IL, если обнаружит нужные хедеры в ```/opt/vc/include```.
|
||||
Для Arch Linux в AUR есть готовый пакет: https://aur.archlinux.org/packages/ustreamer.
|
||||
|
||||
Порт для FreeBSD: https://www.freshports.org/multimedia/ustreamer.
|
||||
|
||||
-----
|
||||
@ -66,8 +67,8 @@ $ ./ustreamer --help
|
||||
```bash
|
||||
$ ./ustreamer \
|
||||
--format=uyvy \ # Настройка входного формата устройства
|
||||
--encoder=omx \ # Использование аппаратного кодирования с помощью OpenMAX
|
||||
--workers=3 \ # Максимум воркеров для OpenMAX
|
||||
--encoder=v4l2 \ # Аппаратное кодирование с помощью драйвер V4L2 M2M
|
||||
--workers=3 \ # Максимум воркеров
|
||||
--persistent \ # Не переинициализировать устройство при таймауте (например, когда был отключен HDMI-кабель)
|
||||
--dv-timings \ # Включение DV-таймингов
|
||||
--drop-same-frames=30 # Экономим трафик
|
||||
|
||||
@ -23,7 +23,6 @@ _USTR_SRCS = $(shell ls \
|
||||
ustreamer/data/*.c \
|
||||
ustreamer/encoders/cpu/*.c \
|
||||
ustreamer/encoders/hw/*.c \
|
||||
ustreamer/encoders/v4l2/*.c \
|
||||
ustreamer/h264/*.c \
|
||||
)
|
||||
|
||||
|
||||
@ -122,7 +122,10 @@ workers_pool_s *encoder_workers_pool_init(encoder_s *enc, device_s *dev) {
|
||||
for (; ER(n_m2ms) < n_workers; ++ER(n_m2ms)) {
|
||||
char name[32];
|
||||
snprintf(name, 32, "JPEG-%u", ER(n_m2ms));
|
||||
m2m_option_s options[] = {{NULL, false, 0, 0}};
|
||||
m2m_option_s options[] = {
|
||||
{"COMPRESSION_QUALITY", false, V4L2_CID_JPEG_COMPRESSION_QUALITY, quality},
|
||||
{NULL, false, 0, 0},
|
||||
};
|
||||
ER(m2ms[ER(n_m2ms)]) = m2m_encoder_init(name, "/dev/video11", V4L2_PIX_FMT_MJPEG, 0, options);
|
||||
}
|
||||
|
||||
@ -219,10 +222,11 @@ static bool _worker_run_job(worker_s *wr) {
|
||||
|
||||
} else if (ER(type) == ENCODER_TYPE_V4L2) {
|
||||
LOG_VERBOSE("Compressing buffer using V4L2");
|
||||
if (!m2m_encoder_ensure_ready(ER(m2ms[wr->number]), src)) {
|
||||
if (m2m_encoder_compress(ER(m2ms[wr->number]), src, dest, false) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (m2m_encoder_ensure_ready(ER(m2ms[wr->number]), src) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (m2m_encoder_compress(ER(m2ms[wr->number]), src, dest, false) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
} else if (ER(type) == ENCODER_TYPE_NOOP) {
|
||||
|
||||
@ -35,6 +35,7 @@ h264_stream_s *h264_stream_init(memsink_s *sink, const char *path, unsigned bitr
|
||||
|
||||
m2m_option_s options[] = {
|
||||
OPTION(true, BITRATE, bitrate * 1000),
|
||||
OPTION(false, BITRATE_PEAK, bitrate * 1000),
|
||||
OPTION(true, H264_I_PERIOD, gop),
|
||||
OPTION(true, H264_PROFILE, V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE),
|
||||
OPTION(true, H264_LEVEL, V4L2_MPEG_VIDEO_H264_LEVEL_4_0),
|
||||
|
||||
@ -157,6 +157,13 @@ static int _m2m_encoder_prepare(m2m_encoder_s *enc, const frame_s *frame) {
|
||||
fmt.fmt.pix_mp.plane_fmt[0].sizeimage = 512 << 10;
|
||||
E_LOG_DEBUG("Configuring OUTPUT format ...");
|
||||
E_XIOCTL(VIDIOC_S_FMT, &fmt, "Can't set OUTPUT format");
|
||||
if (fmt.fmt.pix_mp.pixelformat != enc->output_format) {
|
||||
char fourcc_str[8];
|
||||
E_LOG_ERROR("The OUTPUT format can't be configured as %s",
|
||||
fourcc_to_string(enc->output_format, fourcc_str, 8));
|
||||
E_LOG_ERROR("In case of Raspberry Pi, try to append 'start_x=1' to /boot/config.txt");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if (enc->fps > 0) { // TODO: Check this for MJPEG
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user