mirror of
https://github.com/pikvm/ustreamer.git
synced 2026-03-03 22:31:43 +00:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0d396e3f0a | ||
|
|
28daefc5ff | ||
|
|
895db6a8c9 | ||
|
|
73b894419a |
@@ -1,7 +1,7 @@
|
|||||||
[bumpversion]
|
[bumpversion]
|
||||||
commit = True
|
commit = True
|
||||||
tag = True
|
tag = True
|
||||||
current_version = 0.14
|
current_version = 0.15
|
||||||
parse = (?P<major>\d+)\.(?P<minor>\d+)(\.(?P<patch>\d+)(\-(?P<release>[a-z]+))?)?
|
parse = (?P<major>\d+)\.(?P<minor>\d+)(\.(?P<patch>\d+)(\-(?P<release>[a-z]+))?)?
|
||||||
serialize =
|
serialize =
|
||||||
{major}.{minor}
|
{major}.{minor}
|
||||||
|
|||||||
2
PKGBUILD
2
PKGBUILD
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
|
|
||||||
pkgname=ustreamer
|
pkgname=ustreamer
|
||||||
pkgver=0.14
|
pkgver=0.15
|
||||||
pkgrel=1
|
pkgrel=1
|
||||||
pkgdesc="Lightweight and fast MJPG-HTTP streamer"
|
pkgdesc="Lightweight and fast MJPG-HTTP streamer"
|
||||||
url="https://github.com/pi-kvm/ustreamer"
|
url="https://github.com/pi-kvm/ustreamer"
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
| Возможность сервить файлы встроенным<br>HTTP-сервером, настройки авторизации |  Нет <sup>4</sup> |  Есть |
|
| Возможность сервить файлы встроенным<br>HTTP-сервером, настройки авторизации |  Нет <sup>4</sup> |  Есть |
|
||||||
|
|
||||||
Сносочки:
|
Сносочки:
|
||||||
* ```1``` Для mjpg-streamer существует [мой патч](https://github.com/jacksonliam/mjpg-streamer/pull/164), предотвращающий зависание при отключении устройства и добавляющий поддержку DV-таймингов, однако трансляция при этом все равно прерывается. В данный момент этот патч не принят в апстрим, и я даже не гарантирую его стопроцентную работоспособность. Код mjpg-streamer очень плохо структурирован и чрезвычайно запутан, и я мог что-то упустить. Собственно, это одна из причин, почему µStreamer написан с нуля.
|
* ```1``` Для mjpg-streamer существует [мой патч](https://github.com/jacksonliam/mjpg-streamer/pull/164), предотвращающий зависание при отключении устройства и добавляющий поддержку DV-таймингов, однако трансляция при этом все равно прерывается. В данный момент этот патч не принят в апстрим, и я даже не гарантирую его стопроцентную работоспособность. Код mjpg-streamer очень плохо структурирован и чрезвычайно запутан, и я мог что-то упустить. Собственно, это одна из причин, почему µStreamer был написан с нуля.
|
||||||
|
|
||||||
* ```2``` Это фича позволяет в несколько раз снизить объем исходящего трафика при трансляции HDMI, однако увеличивает загрузку процессора и добавляет небольшую задержку. Суть в том, что HDMI - полностью цифровой интерфейс, и новый захваченный фрейм может быть идентичен предыдущему в точности до байта. В этом случае нет нужды передавать одну и ту же картинку по сети несколько раз в секунду. При использовании опции `--drop-same-frames=20`, µStreamer будет дропать все одинаковые фреймы, но не более 20. Новый фрейм сравнивается с предыдущим сначала по длине, а затем помощью ```memcmp()```.
|
* ```2``` Это фича позволяет в несколько раз снизить объем исходящего трафика при трансляции HDMI, однако увеличивает загрузку процессора и добавляет небольшую задержку. Суть в том, что HDMI - полностью цифровой интерфейс, и новый захваченный фрейм может быть идентичен предыдущему в точности до байта. В этом случае нет нужды передавать одну и ту же картинку по сети несколько раз в секунду. При использовании опции `--drop-same-frames=20`, µStreamer будет дропать все одинаковые фреймы, но не более 20. Новый фрейм сравнивается с предыдущим сначала по длине, а затем помощью ```memcmp()```.
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ $ ./ustreamer --help
|
|||||||
|
|
||||||
-----
|
-----
|
||||||
# Использование
|
# Использование
|
||||||
Будучи запущенным без аргументов, ```ustremaer``` попробует открыть устройство ```/dev/video0``` с разрешением 640x480 и начать трансляцию на ```http://localhost:8080```. Это поведение может быть изменено с помощью опций ```--device```, ```--host``` и ```--port```. Пример вещания на всю сеть по 80 порту:
|
Будучи запущенным без аргументов, ```ustreamer``` попробует открыть устройство ```/dev/video0``` с разрешением 640x480 и начать трансляцию на ```http://localhost:8080```. Это поведение может быть изменено с помощью опций ```--device```, ```--host``` и ```--port```. Пример вещания на всю сеть по 80 порту:
|
||||||
```
|
```
|
||||||
# ./ustreamer --device=/dev/video1 --host=0.0.0.0 --port=80
|
# ./ustreamer --device=/dev/video1 --host=0.0.0.0 --port=80
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -21,4 +21,4 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define VERSION "0.14"
|
#define VERSION "0.15"
|
||||||
|
|||||||
@@ -54,65 +54,72 @@ pthread_mutex_t log_mutex;
|
|||||||
#define LOGGING_UNLOCK assert(!pthread_mutex_unlock(&log_mutex))
|
#define LOGGING_UNLOCK assert(!pthread_mutex_unlock(&log_mutex))
|
||||||
|
|
||||||
|
|
||||||
#define SEP_INFO(_x_ch) { \
|
#define SEP_INFO(_ch) { \
|
||||||
LOGGING_LOCK; \
|
LOGGING_LOCK; \
|
||||||
for (int _i = 0; _i < 80; ++_i) { \
|
for (int _i = 0; _i < 80; ++_i) { \
|
||||||
putchar(_x_ch); \
|
putchar(_ch); \
|
||||||
} \
|
} \
|
||||||
putchar('\n'); \
|
putchar('\n'); \
|
||||||
|
fflush(stdout); \
|
||||||
LOGGING_UNLOCK; \
|
LOGGING_UNLOCK; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SEP_DEBUG(_x_ch) { \
|
#define SEP_DEBUG(_ch) { \
|
||||||
if (log_level >= LOG_LEVEL_DEBUG) { \
|
if (log_level >= LOG_LEVEL_DEBUG) { \
|
||||||
SEP_INFO(_x_ch); \
|
SEP_INFO(_ch); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LOG_ERROR(_x_msg, ...) { \
|
#define LOG_PRINTF_NOLOCK(_label, _msg, ...) { \
|
||||||
|
printf("-- " _label " [%.03Lf tid=%ld] -- " _msg "\n", now_monotonic_ms(), syscall(SYS_gettid), ##__VA_ARGS__); \
|
||||||
|
fflush(stdout); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LOG_ERROR(_msg, ...) { \
|
||||||
LOGGING_LOCK; \
|
LOGGING_LOCK; \
|
||||||
printf("-- ERROR [%.03Lf tid=%ld] -- " _x_msg "\n", now_monotonic_ms(), syscall(SYS_gettid), ##__VA_ARGS__); \
|
LOG_PRINTF_NOLOCK("ERROR", _msg, ##__VA_ARGS__); \
|
||||||
LOGGING_UNLOCK; \
|
LOGGING_UNLOCK; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LOG_PERROR(_x_msg, ...) { \
|
#define LOG_PERROR(_msg, ...) { \
|
||||||
char _buf[1024] = ""; \
|
char _buf[1024] = ""; \
|
||||||
strerror_r(errno, _buf, 1024); \
|
strerror_r(errno, _buf, 1024); \
|
||||||
LOGGING_LOCK; \
|
LOGGING_LOCK; \
|
||||||
printf("-- ERROR [%.03Lf tid=%ld] -- " _x_msg ": %s\n", now_monotonic_ms(), syscall(SYS_gettid), ##__VA_ARGS__, _buf); \
|
printf("-- ERROR [%.03Lf tid=%ld] -- " _msg ": %s\n", now_monotonic_ms(), syscall(SYS_gettid), ##__VA_ARGS__, _buf); \
|
||||||
|
fflush(stdout); \
|
||||||
LOGGING_UNLOCK; \
|
LOGGING_UNLOCK; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LOG_INFO(_x_msg, ...) { \
|
#define LOG_INFO(_msg, ...) { \
|
||||||
LOGGING_LOCK; \
|
LOGGING_LOCK; \
|
||||||
printf("-- INFO [%.03Lf tid=%ld] -- " _x_msg "\n", now_monotonic_ms(), syscall(SYS_gettid), ##__VA_ARGS__); \
|
LOG_PRINTF_NOLOCK("INFO ", _msg, ##__VA_ARGS__); \
|
||||||
LOGGING_UNLOCK; \
|
LOGGING_UNLOCK; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LOG_INFO_NOLOCK(_x_msg, ...) { \
|
#define LOG_INFO_NOLOCK(_msg, ...) { \
|
||||||
printf("-- INFO [%.03Lf tid=%ld] -- " _x_msg "\n", now_monotonic_ms(), syscall(SYS_gettid), ##__VA_ARGS__); \
|
LOG_PRINTF_NOLOCK("INFO ", _msg, ##__VA_ARGS__); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LOG_PERF(_x_msg, ...) { \
|
#define LOG_PERF(_msg, ...) { \
|
||||||
if (log_level >= LOG_LEVEL_PERF) { \
|
if (log_level >= LOG_LEVEL_PERF) { \
|
||||||
LOGGING_LOCK; \
|
LOGGING_LOCK; \
|
||||||
printf("-- PERF [%.03Lf tid=%ld] -- " _x_msg "\n", now_monotonic_ms(), syscall(SYS_gettid), ##__VA_ARGS__); \
|
LOG_PRINTF_NOLOCK("PERF ", _msg, ##__VA_ARGS__); \
|
||||||
LOGGING_UNLOCK; \
|
LOGGING_UNLOCK; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LOG_VERBOSE(_x_msg, ...) { \
|
#define LOG_VERBOSE(_msg, ...) { \
|
||||||
if (log_level >= LOG_LEVEL_VERBOSE) { \
|
if (log_level >= LOG_LEVEL_VERBOSE) { \
|
||||||
LOGGING_LOCK; \
|
LOGGING_LOCK; \
|
||||||
printf("-- VERB [%.03Lf tid=%ld] -- " _x_msg "\n", now_monotonic_ms(), syscall(SYS_gettid), ##__VA_ARGS__); \
|
LOG_PRINTF_NOLOCK("VERB ", _msg, ##__VA_ARGS__); \
|
||||||
LOGGING_UNLOCK; \
|
LOGGING_UNLOCK; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LOG_DEBUG(_x_msg, ...) { \
|
#define LOG_DEBUG(_msg, ...) { \
|
||||||
if (log_level >= LOG_LEVEL_DEBUG) { \
|
if (log_level >= LOG_LEVEL_DEBUG) { \
|
||||||
LOGGING_LOCK; \
|
LOGGING_LOCK; \
|
||||||
printf("-- DEBUG [%.03Lf tid=%ld] -- " _x_msg "\n", now_monotonic_ms(), syscall(SYS_gettid), ##__VA_ARGS__); \
|
LOG_PRINTF_NOLOCK("DEBUG", _msg, ##__VA_ARGS__); \
|
||||||
LOGGING_UNLOCK; \
|
LOGGING_UNLOCK; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,12 +29,12 @@
|
|||||||
#include "formatters.h"
|
#include "formatters.h"
|
||||||
|
|
||||||
|
|
||||||
#define CASE_TO_STRING(_val) \
|
#define CASE_TO_STRING(_value) \
|
||||||
case _val: { return #_val; }
|
case _value: { return #_value; }
|
||||||
|
|
||||||
#define CASE_ASSERT(_msg, _val) default: { \
|
#define CASE_ASSERT(_msg, _value) default: { \
|
||||||
char *_buf; A_CALLOC(_buf, 128); \
|
char *_buf; A_CALLOC(_buf, 128); \
|
||||||
sprintf(_buf, _msg ": 0x%08x", _val); \
|
sprintf(_buf, _msg ": 0x%08x", _value); \
|
||||||
assert(0 && _buf); \
|
assert(0 && _buf); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,8 +49,8 @@
|
|||||||
|
|
||||||
#define A_CALLOC(_dest, _nmemb) assert((_dest = calloc(_nmemb, sizeof(*(_dest)))))
|
#define A_CALLOC(_dest, _nmemb) assert((_dest = calloc(_nmemb, sizeof(*(_dest)))))
|
||||||
#define A_REALLOC(_dest, _nmemb) assert((_dest = realloc(_dest, _nmemb * sizeof(*(_dest)))))
|
#define A_REALLOC(_dest, _nmemb) assert((_dest = realloc(_dest, _nmemb * sizeof(*(_dest)))))
|
||||||
#define MEMSET_ZERO(_x_obj) memset(&(_x_obj), 0, sizeof(_x_obj))
|
#define MEMSET_ZERO(_obj) memset(&(_obj), 0, sizeof(_obj))
|
||||||
#define MEMSET_ZERO_PTR(_x_ptr) memset(_x_ptr, 0, sizeof(*(_x_ptr)))
|
#define MEMSET_ZERO_PTR(_ptr) memset(_ptr, 0, sizeof(*(_ptr)))
|
||||||
|
|
||||||
|
|
||||||
#define INLINE inline __attribute__((always_inline))
|
#define INLINE inline __attribute__((always_inline))
|
||||||
|
|||||||
Reference in New Issue
Block a user