diff --git a/src/control_socket.cpp b/src/control_socket.cpp index a511e705d..18df01213 100644 --- a/src/control_socket.cpp +++ b/src/control_socket.cpp @@ -618,6 +618,8 @@ static struct client *add_client(struct client *clients, fd_t fd) { return new_client; } +ADD_TO_PARAM_DOC(control_accept_global, "* control-accept-global\n" + " Open control socket to public network.\n"); static void * control_thread(void *args) { struct control_state *s = (struct control_state *) args; @@ -676,13 +678,6 @@ static void * control_thread(void *args) if (fd == INVALID_SOCKET) { socket_error("[control socket] accept"); } else { - /** - * @addtogroup cmdline_params - * @{ - * * control-accept-global - * Open control socket to public network. - * @} - */ if (get_commandline_param("control-accept-global") || is_addr_loopback(&client_addr)) { clients = add_client(clients, fd); diff --git a/src/host.cpp b/src/host.cpp index c2ac864b9..6273c5837 100644 --- a/src/host.cpp +++ b/src/host.cpp @@ -77,16 +77,12 @@ static void common_cleanup() #endif } +ADD_TO_PARAM_DOC(buffering, + "* stdout-buf={no|line|full}\n" + " Buffering for stdout\n" + "* stderr-buf={no|line|full}\n" + " Buffering for stderr\n"); bool set_output_buffering() { - /** - * @addtogroup cmdline_params - * @{ - * * stdout-buf - * Buffering for stdout (no, line or full) - * * stderr-buf - * Buffering for stdout (no, line or full) - * @} - */ const unordered_map outs = { { "stdout-buf", stdout }, { "stderr-buf", stderr } @@ -313,3 +309,26 @@ void set_audio_delay(int audio_delay) video_offset = audio_delay < 0 ? abs(audio_delay) : 0; } +static const char *param_doc_strings[100]; + +void register_param_doc(const char *doc) +{ + for (unsigned int i = 0; i < sizeof param_doc_strings / sizeof param_doc_strings[0]; ++i) { + if (param_doc_strings[i] == NULL) { + param_doc_strings[i] = doc; + break; + } + } +} + +void print_param_doc() +{ + for (unsigned int i = 0; i < sizeof param_doc_strings / sizeof param_doc_strings[0]; ++i) { + if (param_doc_strings[i] != NULL) { + puts(param_doc_strings[i]); + } else { + break; + } + } +} + diff --git a/src/host.h b/src/host.h index 23822034c..b86d6b29c 100644 --- a/src/host.h +++ b/src/host.h @@ -142,6 +142,8 @@ void print_version(void); const char *get_commandline_param(const char *key); bool set_output_buffering(); +void register_param_doc(const char *doc); +void print_param_doc(void); #ifdef __cplusplus } @@ -153,4 +155,12 @@ bool set_output_buffering(); extern std::unordered_map commandline_params; #endif +#define ADD_TO_PARAM_DOC(salt, string) static void add_to_param_doc##salt(void) __attribute__((constructor));\ +\ +static void add_to_param_doc##salt(void) \ +{\ + register_param_doc(string);\ +}\ +struct NOT_DEFINED_STRUCT_THAT_SWALLOWS_SEMICOLON + #endif diff --git a/src/main.cpp b/src/main.cpp index 08ef003ea..93f075d19 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -474,8 +474,13 @@ bool parse_audio_capture_format(const char *optarg) return true; } -static void parse_params(char *optarg) +static bool parse_params(char *optarg) { + if (optarg && strcmp(optarg, "help") == 0) { + puts("Params can be one or more (separated by comma) of following:"); + print_param_doc(); + return false; + } char *item, *save_ptr; while ((item = strtok_r(optarg, ",:", &save_ptr))) { char *key_cstr = item; @@ -488,6 +493,7 @@ static void parse_params(char *optarg) } optarg = NULL; } + return true; } int main(int argc, char *argv[]) @@ -886,7 +892,9 @@ int main(int argc, char *argv[]) start_paused = true; break; case OPT_PARAM: - parse_params(optarg); + if (!parse_params(optarg)) { + return EXIT_SUCCESS; + } break; case '?': default: diff --git a/src/rtp/net_udp.cpp b/src/rtp/net_udp.cpp index 23dcb2a08..34d1a4f50 100644 --- a/src/rtp/net_udp.cpp +++ b/src/rtp/net_udp.cpp @@ -655,6 +655,9 @@ static bool address_is_ipv6(const char *addr) return strchr(addr, ':') != NULL; } +ADD_TO_PARAM_DOC(udp_queue_len, + "* udp-queue-len=\n" + " Use different queue size than default DEFAULT_MAX_UDP_READER_QUEUE_LEN\n"); /** * udp_init_if: * Creates a session for sending and receiving UDP datagrams over IP @@ -816,13 +819,6 @@ socket_udp *udp_init_if(const char *addr, const char *iface, uint16_t rx_port, s->local->multithreaded = multithreaded; if (multithreaded) { - /** - * @addtogroup cmdline_params - * @{ - * * udp-queue-len - * Use different queue size than default @ref DEFAULT_MAX_UDP_READER_QUEUE_LEN - * @} - */ if (!get_commandline_param("udp-queue-len")) { s->local->max_packets = DEFAULT_MAX_UDP_READER_QUEUE_LEN; } else { diff --git a/src/video_compress/libavcodec.cpp b/src/video_compress/libavcodec.cpp index e5ef6cfef..3a29caf52 100644 --- a/src/video_compress/libavcodec.cpp +++ b/src/video_compress/libavcodec.cpp @@ -556,6 +556,14 @@ bool set_codec_ctx_params(struct state_video_compress_libav *s, AVPixelFormat pi return true; } +ADD_TO_PARAM_DOC(lavc_use_codec, + "* lavc-use-codec=\n" + " Restrict codec to use user specified pix fmt. Can be used eg. to enforce\n" + " AV_PIX_FMT_NV12 (nv12) since some time ago, other codecs were broken\n" + " for NVENC encoder.\n" + " Another possibility is to use yuv420p10le, yuv422p10le or yuv444p10le\n" + " to force 10-bit encoding.\n"); + static bool configure_with(struct state_video_compress_libav *s, struct video_desc desc) { int ret; @@ -683,17 +691,6 @@ static bool configure_with(struct state_video_compress_libav *s, struct video_de } } - /** - * @addtogroup cmdline_params - * @{ - * * lavc-use-codec - * Restrict codec to use user specified pix fmt. Can be used eg. to enforce - * AV_PIX_FMT_NV12 (nv12) since some time ago, other codecs were broken - * for NVENC encoder. - * Another possibility is to use yuv420p10le, yuv422p10le or yuv444p10le - * to force 10-bit encoding. - * @} - */ if (get_commandline_param("lavc-use-codec")) { const char *val = get_commandline_param("lavc-use-codec"); requested_pix_fmts[0] = av_get_pix_fmt(val); @@ -1315,6 +1312,8 @@ static void setparam_default(AVCodecContext *codec_ctx, struct setparam_param *p } } +ADD_TO_PARAM_DOC(lavc_h264_interlaced_dct, "* lavc-h264-interlaced-dct\n" + " Use interlaced DCT for H.264\n"); static void configure_x264_x265(AVCodecContext *codec_ctx, struct setparam_param *param) { const char *tune; @@ -1343,13 +1342,6 @@ static void configure_x264_x265(AVCodecContext *codec_ctx, struct setparam_param //codec_ctx->rc_qsquish = 0; //codec_ctx->scenechange_threshold = 100; - /** - * @addtogroup cmdline_params - * @{ - * * lavc-h264-interlaced-dct - * Use interlaced DCT for H.264 - * @} - */ if (get_commandline_param("lavc-h264-interlaced-dct")) { // this options increases variance in frame sizes quite a lot if (param->interlaced) { diff --git a/src/video_decompress/libavcodec.c b/src/video_decompress/libavcodec.c index 0655dda07..8d22338f1 100644 --- a/src/video_decompress/libavcodec.c +++ b/src/video_decompress/libavcodec.c @@ -187,6 +187,8 @@ static const struct decoder_info decoders[] = { { VP9, AV_CODEC_ID_VP9, NULL, { NULL } }, }; +ADD_TO_PARAM_DOC(force_lavd_decoder, "* force-lavd-decoder=\n" + " Forces specified Libavcodec decoder\n"); static bool configure_with(struct state_libavcodec_decompress *s, struct video_desc desc) { @@ -213,13 +215,6 @@ static bool configure_with(struct state_libavcodec_decompress *s, memset(codecs_available, 0, sizeof codecs_available); unsigned int codec_index = 0; // first try codec specified from cmdline if any - /** - * @addtogroup cmdline_params - * @{ - * * force-lavd-decoder - * Forces specified Libavcodec decoder - * @} - */ if (get_commandline_param("force-lavd-decoder")) { const char *val = get_commandline_param("force-lavd-decoder"); AVCodec *codec = avcodec_find_decoder_by_name(val); @@ -1065,6 +1060,13 @@ static void libavcodec_decompress_done(void *state) free(s); } +ADD_TO_PARAM_DOC(lavd_use_10bit, + "* lavd-use-10bit\n" + " Indicates that we are using decoding to v210 (currently only H.264/HEVC).\n" + " If so, can be decompressed to v210. With this flag, v210 (10-bit UYVY)\n" + " will be announced as a supported codec. Please note that if the\n" + " compressed content won't be actually in 10-bit format, decompression\n" + " will fail.\n"); static const struct decode_from_to *libavcodec_decompress_get_decoders() { const struct decode_from_to dec_static[] = { { H264, UYVY, 500 }, @@ -1082,17 +1084,6 @@ static const struct decode_from_to *libavcodec_decompress_get_decoders() { pthread_mutex_lock(&lock); // prevent concurent initialization if (ret[0].from == VIDEO_CODEC_NONE) { // not yet initialized memcpy(ret, dec_static, sizeof dec_static); - /** - * @addtogroup cmdline_params - * @{ - * * lavd-use-10bit - * Indicates that we are using decoding to v210 (currently only H.264/HEVC). - * If so, can be decompressed to v210. With this flag, v210 (10-bit UYVY) - * will be announced as a supported codec. Please note that if the - * compressed content won't be actually in 10-bit format, decompression - * will fail. - * @} - */ // add also decoder from H.264/HEVC to v210 if user explicitly indicated to do so if (get_commandline_param("lavd-use-10bit")) { ret[sizeof dec_static / sizeof dec_static[0]] =