diff --git a/src/json_rpc_client.c b/src/json_rpc_client.c index 039dd6d..d2a38d2 100644 --- a/src/json_rpc_client.c +++ b/src/json_rpc_client.c @@ -159,7 +159,7 @@ int get_daemon_flavor(char* host, ushort rpc_port, AmbientLightingDaemon* flavor return ret; } -int set_hdr_state(char* host, ushort rpc_port, bool hdr_active) +int set_hdr_state(char* host, ushort rpc_port, const char* dynamic_range, bool sdr_tone_mapping) { int ret = 0; @@ -180,16 +180,18 @@ int set_hdr_state(char* host, ushort rpc_port, bool hdr_active) jvalue_ref response_body_jval; jvalue_ref post_body = jobject_create(); - jvalue_ref component_state_jobj = jobject_create(); - - // Assemble nested object first - // See: https://docs.hyperion-project.org/en/json/Control.html#control-components - jobject_set(component_state_jobj, j_cstr_to_buffer("component"), jstring_create("HDR")); - jobject_set(component_state_jobj, j_cstr_to_buffer("state"), jboolean_create(hdr_active)); // Assemble top-level json - jobject_set(post_body, j_cstr_to_buffer("command"), jstring_create("componentstate")); - jobject_set(post_body, j_cstr_to_buffer("componentstate"), component_state_jobj); + // Using HDR command that was added in: https://github.com/awawa-dev/HyperHDR/pull/334 + bool enable_tone_mapping = sdr_tone_mapping || !strcmp(dynamic_range, "sdr"); + jobject_set(post_body, j_cstr_to_buffer("command"), jstring_create("videomodehdr")); + jobject_set(post_body, j_cstr_to_buffer("HDR"), jnumber_create_i32(enable_tone_mapping ? 1 : 0)); + if (enable_tone_mapping) { + char* lut_filename = malloc(strlen(dynamic_range) + 20); + strcpy(lut_filename, dynamic_range); + strcat(lut_filename, "_lut_lin_tables.3d"); + jobject_set(post_body, j_cstr_to_buffer("flatbuffers_user_lut_filename"), jstring_create(lut_filename)); + } if ((ret = send_rpc_message(host, rpc_port, post_body, &response_body_jval)) != 0) { WARN("set_hdr_state: Failed to send RPC message, code: %d", ret); @@ -197,6 +199,5 @@ int set_hdr_state(char* host, ushort rpc_port, bool hdr_active) } j_release(&post_body); - j_release(&component_state_jobj); return ret; } \ No newline at end of file diff --git a/src/json_rpc_client.h b/src/json_rpc_client.h index 8fbfe6d..0eda99c 100644 --- a/src/json_rpc_client.h +++ b/src/json_rpc_client.h @@ -16,4 +16,4 @@ const char* daemon_to_string(AmbientLightingDaemon flavor); int do_http_post(char* url, const char* post_body, char** response_body, int out_buf_sz); int send_rpc_message(char* host, ushort rpc_port, jvalue_ref post_body_jval, jvalue_ref* response_body_jval); int get_daemon_flavor(char* host, ushort rpc_port, AmbientLightingDaemon* flavor); -int set_hdr_state(char* host, ushort rpc_port, bool hdr_active); \ No newline at end of file +int set_hdr_state(char* host, ushort rpc_port, const char* dynamic_range, bool sdr_tone_mapping); \ No newline at end of file diff --git a/src/service.c b/src/service.c index eb0d68d..35891e7 100644 --- a/src/service.c +++ b/src/service.c @@ -35,6 +35,14 @@ void* connection_loop(void* data) } else { INFO("hyperion-client connected!"); service->connected = true; + + if (service->settings->sdr_on_start) { + int ret = set_hdr_state(service->settings->unix_socket ? "127.0.0.1" : service->settings->address, RPC_PORT, "sdr", service->settings->sdr_tone_mapping); + if (ret != 0) { + ERR("startup: set_hdr_state failed, ret: %d", ret); + } + } + while (service->connection_loop_running) { if (hyperion_read() < 0) { ERR("Error! Connection timeout."); @@ -439,19 +447,20 @@ static bool videooutput_callback(LSHandle* sh __attribute__((unused)), LSMessage return false; } - bool hdr_enabled; raw_buffer hdr_type_buf = jstring_get(hdr_type_ref); const char* hdr_type_str = hdr_type_buf.m_str; + const char* dynamic_range; + // hdr_type_str: for DynamicRange or Dolby Vision it's 'dolbyHdr', for HDR it's 'hdr and for SDR it's 'none' if (strcmp(hdr_type_str, "none") == 0) { INFO("videooutput_callback: hdrType: %s --> SDR mode", hdr_type_str); - hdr_enabled = false; + dynamic_range = "sdr"; } else { INFO("videooutput_callback: hdrType: %s --> HDR mode", hdr_type_str); - hdr_enabled = true; + dynamic_range = hdr_type_str; } - int ret = set_hdr_state(service->settings->unix_socket ? "127.0.0.1" : service->settings->address, RPC_PORT, hdr_enabled); + int ret = set_hdr_state(service->settings->unix_socket ? "127.0.0.1" : service->settings->address, RPC_PORT, dynamic_range, service->settings->sdr_tone_mapping); if (ret != 0) { ERR("videooutput_callback: set_hdr_state failed, ret: %d", ret); } @@ -495,19 +504,17 @@ static bool picture_callback(LSHandle* sh __attribute__((unused)), LSMessage* ms return false; } - bool hdr_enabled; raw_buffer dynamic_range_buf = jstring_get(dynamic_range_ref); const char* dynamic_range_str = dynamic_range_buf.m_str; + // dynamic_range_str is "sdr" for SDR, dolbyHDR for dolbyVision and "hdr" for HDR? if (strcmp(dynamic_range_str, "sdr") == 0) { INFO("picture_callback: dynamicRange: %s --> SDR mode", dynamic_range_str); - hdr_enabled = false; } else { INFO("picture_callback: dynamicRange: %s --> HDR mode", dynamic_range_str); - hdr_enabled = true; } - int ret = set_hdr_state(service->settings->unix_socket ? "127.0.0.1" : service->settings->address, RPC_PORT, hdr_enabled); + int ret = set_hdr_state(service->settings->unix_socket ? "127.0.0.1" : service->settings->address, RPC_PORT, dynamic_range_str, service->settings->sdr_tone_mapping); if (ret != 0) { ERR("videooutput_callback: set_hdr_state failed, ret: %d", ret); } diff --git a/src/settings.c b/src/settings.c index 1a14904..3f72840 100644 --- a/src/settings.c +++ b/src/settings.c @@ -22,6 +22,8 @@ void settings_init(settings_t* settings) settings->vsync = true; settings->no_hdr = false; + settings->sdr_tone_mapping = false; + settings->sdr_on_start = false; settings->no_powerstate = false; settings->dump_frames = false; @@ -78,6 +80,10 @@ int settings_load_json(settings_t* settings, jvalue_ref source) if ((value = jobject_get(source, j_cstr_to_buffer("nohdr"))) && jis_boolean(value)) jboolean_get(value, &settings->no_hdr); + if ((value = jobject_get(source, j_cstr_to_buffer("sdrtonemapping"))) && jis_boolean(value)) + jboolean_get(value, &settings->sdr_tone_mapping); + if ((value = jobject_get(source, j_cstr_to_buffer("sdronstart"))) && jis_boolean(value)) + jboolean_get(value, &settings->sdr_on_start); if ((value = jobject_get(source, j_cstr_to_buffer("nopowerstate"))) && jis_boolean(value)) jboolean_get(value, &settings->no_powerstate); @@ -105,6 +111,8 @@ int settings_save_json(settings_t* settings, jvalue_ref target) jobject_set(target, j_cstr_to_buffer("autostart"), jboolean_create(settings->autostart)); jobject_set(target, j_cstr_to_buffer("nohdr"), jboolean_create(settings->no_hdr)); + jobject_set(target, j_cstr_to_buffer("sdrtonemapping"), jboolean_create(settings->sdr_tone_mapping)); + jobject_set(target, j_cstr_to_buffer("sdronstart"), jboolean_create(settings->sdr_on_start)); jobject_set(target, j_cstr_to_buffer("nopowerstate"), jboolean_create(settings->no_powerstate)); return 0; @@ -169,4 +177,4 @@ int settings_save_file(settings_t* settings, char* target) j_release(&jobj); return 0; -} +} \ No newline at end of file diff --git a/src/settings.h b/src/settings.h index 44918ee..246464d 100644 --- a/src/settings.h +++ b/src/settings.h @@ -30,6 +30,8 @@ typedef struct _settings_t { bool dump_frames; bool no_hdr; + bool sdr_tone_mapping; + bool sdr_on_start; bool no_powerstate; } settings_t;