mirror of
https://github.com/pikvm/ustreamer.git
synced 2026-02-18 02:55:46 +00:00
h264 boost mode
This commit is contained in:
parent
9eb39bbfc3
commit
5204f00812
@ -43,7 +43,7 @@
|
|||||||
|
|
||||||
static us_m2m_encoder_s *_m2m_encoder_init(
|
static us_m2m_encoder_s *_m2m_encoder_init(
|
||||||
const char *name, const char *path, uint output_format,
|
const char *name, const char *path, uint output_format,
|
||||||
uint bitrate, uint gop, uint quality, bool allow_dma);
|
uint bitrate, uint gop, uint quality, bool allow_dma, bool boost);
|
||||||
|
|
||||||
static void _m2m_encoder_ensure(us_m2m_encoder_s *enc, const us_frame_s *frame);
|
static void _m2m_encoder_ensure(us_m2m_encoder_s *enc, const us_frame_s *frame);
|
||||||
|
|
||||||
@ -63,9 +63,9 @@ static int _m2m_encoder_compress_raw(us_m2m_encoder_s *enc, const us_frame_s *sr
|
|||||||
#define _LOG_DEBUG(x_msg, ...) US_LOG_DEBUG("%s: " x_msg, enc->name, ##__VA_ARGS__)
|
#define _LOG_DEBUG(x_msg, ...) US_LOG_DEBUG("%s: " x_msg, enc->name, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
|
||||||
us_m2m_encoder_s *us_m2m_h264_encoder_init(const char *name, const char *path, uint bitrate, uint gop) {
|
us_m2m_encoder_s *us_m2m_h264_encoder_init(const char *name, const char *path, uint bitrate, uint gop, bool boost) {
|
||||||
bitrate *= 1000; // From Kbps
|
bitrate *= 1000; // From Kbps
|
||||||
return _m2m_encoder_init(name, path, V4L2_PIX_FMT_H264, bitrate, gop, 0, true);
|
return _m2m_encoder_init(name, path, V4L2_PIX_FMT_H264, bitrate, gop, 0, true, boost);
|
||||||
}
|
}
|
||||||
|
|
||||||
us_m2m_encoder_s *us_m2m_mjpeg_encoder_init(const char *name, const char *path, uint quality) {
|
us_m2m_encoder_s *us_m2m_mjpeg_encoder_init(const char *name, const char *path, uint quality) {
|
||||||
@ -76,12 +76,12 @@ us_m2m_encoder_s *us_m2m_mjpeg_encoder_init(const char *name, const char *path,
|
|||||||
bitrate = step * round(bitrate / step);
|
bitrate = step * round(bitrate / step);
|
||||||
bitrate *= 1000; // From Kbps
|
bitrate *= 1000; // From Kbps
|
||||||
assert(bitrate > 0);
|
assert(bitrate > 0);
|
||||||
return _m2m_encoder_init(name, path, V4L2_PIX_FMT_MJPEG, bitrate, 0, 0, true);
|
return _m2m_encoder_init(name, path, V4L2_PIX_FMT_MJPEG, bitrate, 0, 0, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
us_m2m_encoder_s *us_m2m_jpeg_encoder_init(const char *name, const char *path, uint quality) {
|
us_m2m_encoder_s *us_m2m_jpeg_encoder_init(const char *name, const char *path, uint quality) {
|
||||||
// FIXME: DMA не работает
|
// FIXME: DMA не работает
|
||||||
return _m2m_encoder_init(name, path, V4L2_PIX_FMT_JPEG, 0, 0, quality, false);
|
return _m2m_encoder_init(name, path, V4L2_PIX_FMT_JPEG, 0, 0, quality, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void us_m2m_encoder_destroy(us_m2m_encoder_s *enc) {
|
void us_m2m_encoder_destroy(us_m2m_encoder_s *enc) {
|
||||||
@ -139,7 +139,7 @@ int us_m2m_encoder_compress(us_m2m_encoder_s *enc, const us_frame_s *src, us_fra
|
|||||||
|
|
||||||
static us_m2m_encoder_s *_m2m_encoder_init(
|
static us_m2m_encoder_s *_m2m_encoder_init(
|
||||||
const char *name, const char *path, uint output_format,
|
const char *name, const char *path, uint output_format,
|
||||||
uint bitrate, uint gop, uint quality, bool allow_dma) {
|
uint bitrate, uint gop, uint quality, bool allow_dma, bool boost) {
|
||||||
|
|
||||||
US_LOG_INFO("%s: Initializing encoder ...", name);
|
US_LOG_INFO("%s: Initializing encoder ...", name);
|
||||||
|
|
||||||
@ -161,6 +161,7 @@ static us_m2m_encoder_s *_m2m_encoder_init(
|
|||||||
enc->gop = gop;
|
enc->gop = gop;
|
||||||
enc->quality = quality;
|
enc->quality = quality;
|
||||||
enc->allow_dma = allow_dma;
|
enc->allow_dma = allow_dma;
|
||||||
|
enc->boost = boost;
|
||||||
enc->run = run;
|
enc->run = run;
|
||||||
return enc;
|
return enc;
|
||||||
}
|
}
|
||||||
@ -222,7 +223,11 @@ static void _m2m_encoder_ensure(us_m2m_encoder_s *enc, const us_frame_s *frame)
|
|||||||
SET_OPTION(V4L2_CID_MPEG_VIDEO_H264_I_PERIOD, enc->gop);
|
SET_OPTION(V4L2_CID_MPEG_VIDEO_H264_I_PERIOD, enc->gop);
|
||||||
SET_OPTION(V4L2_CID_MPEG_VIDEO_H264_PROFILE, V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE);
|
SET_OPTION(V4L2_CID_MPEG_VIDEO_H264_PROFILE, V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE);
|
||||||
if (run->p_width * run->p_height <= 1920 * 1080) { // https://forums.raspberrypi.com/viewtopic.php?t=291447#p1762296
|
if (run->p_width * run->p_height <= 1920 * 1080) { // https://forums.raspberrypi.com/viewtopic.php?t=291447#p1762296
|
||||||
SET_OPTION(V4L2_CID_MPEG_VIDEO_H264_LEVEL, V4L2_MPEG_VIDEO_H264_LEVEL_4_0);
|
if (enc->boost) {
|
||||||
|
SET_OPTION(V4L2_CID_MPEG_VIDEO_H264_LEVEL, V4L2_MPEG_VIDEO_H264_LEVEL_4_2);
|
||||||
|
} else {
|
||||||
|
SET_OPTION(V4L2_CID_MPEG_VIDEO_H264_LEVEL, V4L2_MPEG_VIDEO_H264_LEVEL_4_0);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
SET_OPTION(V4L2_CID_MPEG_VIDEO_H264_LEVEL, V4L2_MPEG_VIDEO_H264_LEVEL_5_1);
|
SET_OPTION(V4L2_CID_MPEG_VIDEO_H264_LEVEL, V4L2_MPEG_VIDEO_H264_LEVEL_5_1);
|
||||||
}
|
}
|
||||||
@ -276,10 +281,13 @@ static void _m2m_encoder_ensure(us_m2m_encoder_s *enc, const us_frame_s *frame)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (run->p_width * run->p_height <= 1280 * 720) {
|
if (
|
||||||
|
(run->p_width * run->p_height <= 1280 * 720)
|
||||||
|
|| ((enc->output_format == V4L2_PIX_FMT_H264) && enc->boost)
|
||||||
|
) {
|
||||||
// H264 требует каких-то лимитов. Больше 30 не поддерживается, а при 0
|
// H264 требует каких-то лимитов. Больше 30 не поддерживается, а при 0
|
||||||
// через какое-то время начинает производить некорректные фреймы.
|
// через какое-то время начинает производить некорректные фреймы.
|
||||||
// Если же привысить fps, то резко увеличивается время кодирования.
|
// Если же превысить fps, то резко увеличивается время кодирования.
|
||||||
run->fps_limit = 60;
|
run->fps_limit = 60;
|
||||||
} else {
|
} else {
|
||||||
run->fps_limit = 30;
|
run->fps_limit = 30;
|
||||||
|
|||||||
@ -58,12 +58,13 @@ typedef struct {
|
|||||||
uint gop;
|
uint gop;
|
||||||
uint quality;
|
uint quality;
|
||||||
bool allow_dma;
|
bool allow_dma;
|
||||||
|
bool boost;
|
||||||
|
|
||||||
us_m2m_encoder_runtime_s *run;
|
us_m2m_encoder_runtime_s *run;
|
||||||
} us_m2m_encoder_s;
|
} us_m2m_encoder_s;
|
||||||
|
|
||||||
|
|
||||||
us_m2m_encoder_s *us_m2m_h264_encoder_init(const char *name, const char *path, uint bitrate, uint gop);
|
us_m2m_encoder_s *us_m2m_h264_encoder_init(const char *name, const char *path, uint bitrate, uint gop, bool boost);
|
||||||
us_m2m_encoder_s *us_m2m_mjpeg_encoder_init(const char *name, const char *path, uint quality);
|
us_m2m_encoder_s *us_m2m_mjpeg_encoder_init(const char *name, const char *path, uint quality);
|
||||||
us_m2m_encoder_s *us_m2m_jpeg_encoder_init(const char *name, const char *path, uint quality);
|
us_m2m_encoder_s *us_m2m_jpeg_encoder_init(const char *name, const char *path, uint quality);
|
||||||
void us_m2m_encoder_destroy(us_m2m_encoder_s *enc);
|
void us_m2m_encoder_destroy(us_m2m_encoder_s *enc);
|
||||||
|
|||||||
@ -100,6 +100,7 @@ enum _US_OPT_VALUES {
|
|||||||
_O_H264_BITRATE,
|
_O_H264_BITRATE,
|
||||||
_O_H264_GOP,
|
_O_H264_GOP,
|
||||||
_O_H264_M2M_DEVICE,
|
_O_H264_M2M_DEVICE,
|
||||||
|
_O_H264_BOOST,
|
||||||
# undef ADD_SINK
|
# undef ADD_SINK
|
||||||
|
|
||||||
# ifdef WITH_V4P
|
# ifdef WITH_V4P
|
||||||
@ -206,6 +207,7 @@ static const struct option _LONG_OPTS[] = {
|
|||||||
{"h264-bitrate", required_argument, NULL, _O_H264_BITRATE},
|
{"h264-bitrate", required_argument, NULL, _O_H264_BITRATE},
|
||||||
{"h264-gop", required_argument, NULL, _O_H264_GOP},
|
{"h264-gop", required_argument, NULL, _O_H264_GOP},
|
||||||
{"h264-m2m-device", required_argument, NULL, _O_H264_M2M_DEVICE},
|
{"h264-m2m-device", required_argument, NULL, _O_H264_M2M_DEVICE},
|
||||||
|
{"h264-boost", no_argument, NULL, _O_H264_BOOST},
|
||||||
// Compatibility
|
// Compatibility
|
||||||
{"sink", required_argument, NULL, _O_JPEG_SINK},
|
{"sink", required_argument, NULL, _O_JPEG_SINK},
|
||||||
{"sink-mode", required_argument, NULL, _O_JPEG_SINK_MODE},
|
{"sink-mode", required_argument, NULL, _O_JPEG_SINK_MODE},
|
||||||
@ -469,6 +471,7 @@ int options_parse(us_options_s *options, us_capture_s *cap, us_encoder_s *enc, u
|
|||||||
case _O_H264_BITRATE: OPT_NUMBER("--h264-bitrate", stream->h264_bitrate, 25, 20000, 0);
|
case _O_H264_BITRATE: OPT_NUMBER("--h264-bitrate", stream->h264_bitrate, 25, 20000, 0);
|
||||||
case _O_H264_GOP: OPT_NUMBER("--h264-gop", stream->h264_gop, 0, 60, 0);
|
case _O_H264_GOP: OPT_NUMBER("--h264-gop", stream->h264_gop, 0, 60, 0);
|
||||||
case _O_H264_M2M_DEVICE: OPT_SET(stream->h264_m2m_path, optarg);
|
case _O_H264_M2M_DEVICE: OPT_SET(stream->h264_m2m_path, optarg);
|
||||||
|
case _O_H264_BOOST: OPT_SET(stream->h264_boost, true);
|
||||||
|
|
||||||
# ifdef WITH_V4P
|
# ifdef WITH_V4P
|
||||||
case _O_V4P:
|
case _O_V4P:
|
||||||
|
|||||||
@ -156,7 +156,13 @@ void us_stream_loop(us_stream_s *stream) {
|
|||||||
atomic_store(&run->http->last_request_ts, us_get_now_monotonic());
|
atomic_store(&run->http->last_request_ts, us_get_now_monotonic());
|
||||||
|
|
||||||
if (stream->h264_sink != NULL) {
|
if (stream->h264_sink != NULL) {
|
||||||
run->h264_enc = us_m2m_h264_encoder_init("H264", stream->h264_m2m_path, stream->h264_bitrate, stream->h264_gop);
|
run->h264_enc = us_m2m_h264_encoder_init(
|
||||||
|
"H264",
|
||||||
|
stream->h264_m2m_path,
|
||||||
|
stream->h264_bitrate,
|
||||||
|
stream->h264_gop,
|
||||||
|
stream->h264_boost);
|
||||||
|
|
||||||
run->h264_tmp_src = us_frame_init();
|
run->h264_tmp_src = us_frame_init();
|
||||||
run->h264_dest = us_frame_init();
|
run->h264_dest = us_frame_init();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -94,6 +94,7 @@ typedef struct {
|
|||||||
uint h264_bitrate;
|
uint h264_bitrate;
|
||||||
uint h264_gop;
|
uint h264_gop;
|
||||||
char *h264_m2m_path;
|
char *h264_m2m_path;
|
||||||
|
bool h264_boost;
|
||||||
|
|
||||||
# ifdef WITH_V4P
|
# ifdef WITH_V4P
|
||||||
us_drm_s *drm;
|
us_drm_s *drm;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user