Private
Public Access
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fcdfc4b431 | ||
|
|
ef03258e22 | ||
|
|
2f6efd9864 |
No files matched your search
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"id": "org.webosbrew.histogramhyperion",
|
||||
"version": "0.13.1",
|
||||
"version": "0.13.4",
|
||||
"type": "web",
|
||||
"title": "HyperDRM",
|
||||
"appDescription": "Ambient lighting for webOS, Hyperion and HyperHDR",
|
||||
"iconUri": "https://gitea.adnau.de/matze19999/HyperDRM/raw/branch/main/app/icon.png",
|
||||
"sourceUrl": "https://gitea.adnau.de/matze19999/HyperDRM",
|
||||
"rootRequired": true,
|
||||
"ipkUrl": "https://gitea.adnau.de/matze19999/HyperDRM/raw/branch/main/HyperDRM_0.13.1_arm.ipk",
|
||||
"ipkUrl": "https://gitea.adnau.de/matze19999/HyperDRM/raw/branch/main/HyperDRM_0.13.4_arm.ipk",
|
||||
"ipkHash": {
|
||||
"sha256": "7ee27c6c8c0f7649690f1eb6e055b0add5ba2e57461cec58cbc8e144316af1d6"
|
||||
"sha256": "3028ea164e05ff6b9c601aa7f3ff0f05b17781ba603eaebe3395abae503f7bb7"
|
||||
},
|
||||
"ipkSize": 1207854
|
||||
"ipkSize": 1208554
|
||||
}
|
||||
Binary file not shown.
@@ -27,7 +27,7 @@ Only the own service is modified. Optional Auto PicCap can configure its receive
|
||||
|
||||
## Installation
|
||||
|
||||
The current package is [HyperDRM_0.13.1_arm.ipk](HyperDRM_0.13.1_arm.ipk). Install it using the TV's webOS/Homebrew package installation workflow.
|
||||
The current package is [HyperDRM_0.13.4_arm.ipk](HyperDRM_0.13.4_arm.ipk). Install it using the TV's webOS/Homebrew package installation workflow.
|
||||
|
||||
Elevate the installed own service through Homebrew Channel:
|
||||
|
||||
@@ -234,4 +234,8 @@ and briefly interrupts ambient lighting; it never runs automatically.
|
||||
receiver-output and simulated service-lifecycle tests with ASan/UBSan. These host
|
||||
tests do not replace real LG capture and remote-control validation on a TV.
|
||||
|
||||
Histogram near-black handling suppresses colors with a maximum RGB channel of 12 or less, gradually restores brightness between 12 and 24, and preserves brighter colors. This applies only to histogram output; PicCap, receiver calibration and raw calibration samples are unchanged.
|
||||
Histogram near-black handling suppresses colors with a maximum RGB channel of 16 or less, gradually restores brightness between 16 and 32, and preserves brighter colors. This applies only to histogram output; PicCap, receiver calibration and raw calibration samples are unchanged.
|
||||
|
||||
Thin letterbox detection compares both edges against lit interior histogram samples and requires a consistently dark upper edge for at least two seconds. Histogram probes cannot determine the exact bar height or guarantee detection on every scene.
|
||||
|
||||
Histogram capture defaults to 50 ms. The Receiver panel provides a saved Capture interval (ms) setting from 25 to 1000 in steps of 25. Existing settings without this field use 50 ms. PicCap capture timing is unchanged.
|
||||
+9
-2
@@ -125,6 +125,7 @@ function display(result) {
|
||||
document.getElementById('host').value = result.host;
|
||||
document.getElementById('port').value = result.port;
|
||||
document.getElementById('piccapPort').value = result.piccapPort || 19400;
|
||||
document.getElementById('captureInterval').value = result.captureIntervalMs || 50;
|
||||
receiver = result.receiver;
|
||||
document.getElementById('receiver').textContent = 'Receiver: ' + receiver;
|
||||
}
|
||||
@@ -298,7 +299,7 @@ document.getElementById('handover').onclick = function() {
|
||||
enabled: button.getAttribute('aria-checked') !== 'true'
|
||||
});
|
||||
};
|
||||
['host', 'port', 'piccapPort', 'token', 'clearToken'].forEach(function(id) {
|
||||
['host', 'port', 'piccapPort', 'captureInterval', 'token', 'clearToken'].forEach(function(id) {
|
||||
document.getElementById(id).addEventListener('input', function() {
|
||||
targetDirty = true;
|
||||
});
|
||||
@@ -320,7 +321,13 @@ document.getElementById('saveTarget').onclick = function() {
|
||||
showActionError('PicCap FlatBuffer port must be an integer from 1 to 65535.');
|
||||
return;
|
||||
}
|
||||
var interval = Number(document.getElementById('captureInterval').value);
|
||||
if (!Number.isInteger(interval) || interval < 25 || interval > 1000 || interval % 25) {
|
||||
showActionError('Capture interval must be 25–1000 ms in steps of 25.');
|
||||
return;
|
||||
}
|
||||
var settings = {
|
||||
captureIntervalMs: interval,
|
||||
piccapPort: flatPort,
|
||||
host: document.getElementById('host').value.trim(),
|
||||
port: port,
|
||||
@@ -393,6 +400,6 @@ document.getElementById('editProfile').onclick = function() {
|
||||
showProfile();
|
||||
if (advancedProfile) document.getElementById('customProfileField').focus();
|
||||
};
|
||||
setupRemoteNavigation(['overviewTab', 'receiverTab', 'calibrationTab', 'reloadService', 'grantRoot', 'start', 'stop', 'refresh', 'autostart', 'handover', 'calibrationShortcut', 'receiver', 'hostField', 'portField', 'piccapPortField', 'tokenField', 'clearToken', 'saveTarget', 'testConnection', 'calibrate', 'validateCalibration', 'profile', 'saveProfile', 'editProfile', 'customProfileField', 'cancelCalibration'].map(function(id) {
|
||||
setupRemoteNavigation(['overviewTab', 'receiverTab', 'calibrationTab', 'reloadService', 'grantRoot', 'start', 'stop', 'refresh', 'autostart', 'handover', 'calibrationShortcut', 'receiver', 'hostField', 'portField', 'piccapPortField', 'captureIntervalField', 'tokenField', 'clearToken', 'saveTarget', 'testConnection', 'calibrate', 'validateCalibration', 'profile', 'saveProfile', 'editProfile', 'customProfileField', 'cancelCalibration'].map(function(id) {
|
||||
return document.getElementById(id);
|
||||
}), document, window);
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"id": "org.webosbrew.histogramhyperion",
|
||||
"version": "0.13.1",
|
||||
"version": "0.13.4",
|
||||
"vendor": "Local development",
|
||||
"type": "web",
|
||||
"main": "index.html",
|
||||
|
||||
+2
-1
@@ -38,11 +38,12 @@ nav{border-bottom:1px solid #456185;padding-bottom:10px;margin-bottom:18px}nav b
|
||||
<div id="hostField" class="field" tabindex="0" role="button" aria-label="IP address, press OK to edit"><label>IP address<input id="host" tabindex="-1" readonly type="text" maxlength="45" value="127.0.0.1" spellcheck="false"></label></div>
|
||||
<div id="portField" class="field narrow" tabindex="0" role="button" aria-label="JSON port, press OK to edit"><label>JSON port<input id="port" tabindex="-1" readonly type="number" min="1" max="65535" value="19444"></label></div>
|
||||
<div id="piccapPortField" class="field narrow" tabindex="0" role="button" aria-label="FlatBuffer port, press OK to edit"><label>PicCap FlatBuffer port<input id="piccapPort" tabindex="-1" readonly type="number" min="1" max="65535" value="19400"></label></div>
|
||||
<div id="captureIntervalField" class="field narrow" tabindex="0" role="button" aria-label="Capture interval in milliseconds, press OK to edit"><label>Capture interval (ms)<input id="captureInterval" tabindex="-1" readonly type="number" min="25" max="1000" step="25" value="50"></label></div>
|
||||
<div id="tokenField" class="field" tabindex="0" role="button" aria-label="API token, press OK to edit"><label>API token (optional)<input id="token" tabindex="-1" readonly type="password" maxlength="256" autocomplete="off"></label></div>
|
||||
</div>
|
||||
<label><input id="clearToken" type="checkbox"> Remove saved token</label>
|
||||
<div><button id="saveTarget" class="primary">Save receiver</button><button id="testConnection">Test connection</button></div><p id="testResult" role="status">Connection test: Not tested</p>
|
||||
<p><small>The JSON TCP port is usually 19444. Leave the token blank to keep the saved token. Saving updates the current session.</small></p>
|
||||
<p><small>The JSON TCP port is usually 19444. Leave the token blank to keep the saved token. Saving updates the current session. Histogram capture defaults to 50 ms; choose 25–1000 ms in steps of 25. Lower values reduce latency and increase TV load. PicCap uses its own capture rate.</small></p>
|
||||
<p id="piccapTargetHint"><small>Auto PicCap uses the same IP and its FlatBuffer port, usually 19400. Enable the receiver's FlatBuffer server. Remote IPv6 uses HyperDRM.</small></p></fieldset>
|
||||
</section>
|
||||
<section id="calibrationPanel" aria-label="TV calibration" style="display:none">
|
||||
|
||||
+1
-1
@@ -64,4 +64,4 @@ function setupFormEditors(ids, doc, win) {
|
||||
}
|
||||
});
|
||||
}
|
||||
setupFormEditors(['host', 'port', 'piccapPort', 'token', 'customProfile'], document, window);
|
||||
setupFormEditors(['host', 'port', 'piccapPort', 'captureInterval', 'token', 'customProfile'], document, window);
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
'use strict';
|
||||
var HYPERDRM_APP_VERSION = '0.13.1';
|
||||
var HYPERDRM_APP_VERSION = '0.13.4';
|
||||
@@ -0,0 +1,3 @@
|
||||
# HyperDRM 0.13.2
|
||||
|
||||
Raise the histogram black cutoff to 16 and extend the proportional transition to 32. Live measurements showed raw [13,14,7] causing residual [1,1,0] to [2,2,1] at the bottom-right LEDs with the previous cutoff. Regression coverage now includes this sample. Brighter colors, PicCap and saved settings remain unchanged; very dark detail is suppressed more strongly.
|
||||
@@ -0,0 +1,3 @@
|
||||
# HyperDRM 0.13.3
|
||||
|
||||
Detect thinner horizontal black bars using edge-versus-interior contrast, distributed upper-edge support and lower-edge support. Preserve the existing dark-scene rejection, wide-bar rule and two-second stability gate. Regression tests include live G4 measurements, one-sided and isolated dark edges, dim frames and insufficient contrast. This is a histogram heuristic; it does not measure exact bar heights.
|
||||
@@ -0,0 +1,3 @@
|
||||
# HyperDRM 0.13.4
|
||||
|
||||
Default histogram capture to 50 ms and expose a persisted Capture interval (ms) in the Receiver panel (25–1000, steps of 25). Remote highlighting leaves the keyboard closed; OK opens editing. A 25 ms scheduler keeps network processing responsive independently of slower capture settings. Missing legacy values default to 50 ms. PicCap timing is unchanged. Native tests check persistence, legacy defaults and invalid values.
|
||||
+25
-2
@@ -4,14 +4,17 @@
|
||||
* or dark frame so darkness alone cannot switch the active capture mode. */
|
||||
static inline int letterbox_candidate(const unsigned black[16], const unsigned char color[16][3]) {
|
||||
const unsigned interior[] = {2, 6, 10, 15};
|
||||
unsigned lit = 0;
|
||||
unsigned lit = 0, interior_black = 0, interior_peak = 0;
|
||||
for (unsigned i = 0; i < 4; i++) {
|
||||
unsigned r = interior[i], peak = color[r][0];
|
||||
for (unsigned c = 1; c < 3; c++)
|
||||
if (color[r][c] > peak)
|
||||
peak = color[r][c];
|
||||
if (black[r] < 20 && peak > 35)
|
||||
if (black[r] < 20 && peak > 35) {
|
||||
lit++;
|
||||
interior_black += black[r];
|
||||
interior_peak += peak;
|
||||
}
|
||||
}
|
||||
if (lit < 2)
|
||||
return -1;
|
||||
@@ -19,6 +22,26 @@ static inline int letterbox_candidate(const unsigned black[16], const unsigned c
|
||||
unsigned bottom = (black[1] + black[5] + black[9]) / 3;
|
||||
if (top >= 55 && bottom >= 25)
|
||||
return 1;
|
||||
/* Thin bars occupy only part of an edge probe. Require a broad upper
|
||||
* dark edge, lower-edge support and contrast against lit interior probes.
|
||||
* This remains a histogram heuristic, not a pixel-accurate crop. */
|
||||
const unsigned top_regions[] = {3, 11, 12};
|
||||
const unsigned bottom_regions[] = {1, 5, 9};
|
||||
unsigned top_support = 0, bottom_support = 0, top_peak = 0;
|
||||
for (unsigned i = 0; i < 3; i++) {
|
||||
unsigned r = top_regions[i], peak = color[r][0];
|
||||
for (unsigned c = 1; c < 3; c++)
|
||||
if (color[r][c] > peak)
|
||||
peak = color[r][c];
|
||||
top_peak += peak;
|
||||
top_support += black[r] >= 12;
|
||||
bottom_support += black[bottom_regions[i]] >= 8;
|
||||
}
|
||||
unsigned baseline = interior_black / lit;
|
||||
if (top_support == 3 && bottom_support >= 2 && top >= 12 && bottom >= 10 &&
|
||||
top >= baseline + 8 && bottom >= baseline + 8 &&
|
||||
(unsigned long)top_peak * lit * 100 <= (unsigned long)interior_peak * 3 * 60)
|
||||
return 1;
|
||||
if (top < 20 && bottom < 20)
|
||||
return 0;
|
||||
return -1;
|
||||
|
||||
@@ -83,6 +83,8 @@ static int tick(void *unused) {
|
||||
capture_ctx.settling = 2;
|
||||
return 1;
|
||||
}
|
||||
if (capture_ctx.sample_at && now - capture_ctx.sample_at < target_capture_interval(&target))
|
||||
return 1;
|
||||
Histogram hist[16] = {0};
|
||||
int rc = vt_get(capture_ctx.handle, hist);
|
||||
bool populated = !rc && histogram_populated(hist);
|
||||
|
||||
+3
-3
@@ -7,10 +7,10 @@ static inline void dark_color_filter(unsigned char color[3]) {
|
||||
for (unsigned c = 1; c < 3; c++)
|
||||
if (color[c] > peak)
|
||||
peak = color[c];
|
||||
if (peak >= 24)
|
||||
if (peak >= 32)
|
||||
return;
|
||||
unsigned gain = peak > 12 ? peak - 12 : 0;
|
||||
unsigned gain = peak > 16 ? peak - 16 : 0;
|
||||
for (unsigned c = 0; c < 3; c++)
|
||||
color[c] = (unsigned char)((color[c] * gain + 6) / 12);
|
||||
color[c] = (unsigned char)((color[c] * gain + 8) / 16);
|
||||
}
|
||||
#endif
|
||||
+1
-1
@@ -270,7 +270,7 @@ int main(void) {
|
||||
service_handle = handle;
|
||||
if (!boot_enabled())
|
||||
retry_pause(&retries);
|
||||
timer(100, tick, NULL);
|
||||
timer(25, tick, NULL);
|
||||
while (!quitting) {
|
||||
iterate(NULL, 0);
|
||||
usleep(10000);
|
||||
|
||||
@@ -61,10 +61,10 @@ static bool status(void *h, void *m, void *ctx) {
|
||||
CALIBRATION_ACTIVE ? "true" : "false");
|
||||
used +=
|
||||
snprintf(json + used, sizeof(json) - used,
|
||||
"\"returnValue\":true,\"piccapPort\":%u,\"connectionTest\":{\"state\":\"%s\","
|
||||
"\"returnValue\":true,\"captureIntervalMs\":%u,\"piccapPort\":%u,\"connectionTest\":{\"state\":\"%s\","
|
||||
"\"ledCount\":%u,\"elapsedMs\":%llu,\"error\":\"%s\"},\"lastOutputAgeMs\":%"
|
||||
"lld,\"retryInMs\":%llu,\"captureState\":\"%s\",\"piccapError\":\"%s\",",
|
||||
target.piccap_port, test_stage_name(), connection_test.leds,
|
||||
target_capture_interval(&target), target.piccap_port, test_stage_name(), connection_test.leds,
|
||||
(unsigned long long)connection_test.elapsed, connection_test.error,
|
||||
capture_ctx.last_output_at ? (long long)(now - capture_ctx.last_output_at) : -1,
|
||||
(unsigned long long)(retries.due > now ? retries.due - now : 0),
|
||||
|
||||
+25
-4
@@ -15,10 +15,14 @@
|
||||
"/media/developer/apps/usr/palm/services/org.webosbrew.histogramhyperion.service/target.json"
|
||||
typedef struct {
|
||||
char host[46], receiver[16], token[257];
|
||||
unsigned port, piccap_port;
|
||||
unsigned port, piccap_port, capture_interval;
|
||||
} TargetConfig;
|
||||
static TargetConfig target = {
|
||||
.host = "127.0.0.1", .receiver = "Hyperion", .port = 19444, .piccap_port = 19400};
|
||||
.host = "127.0.0.1", .receiver = "Hyperion", .port = 19444, .piccap_port = 19400,
|
||||
.capture_interval = 50};
|
||||
static inline unsigned target_capture_interval(const TargetConfig *t) {
|
||||
return t->capture_interval ? t->capture_interval : 50;
|
||||
}
|
||||
static inline bool target_piccap_local(const TargetConfig *t) {
|
||||
return t->port == 19444 && (!strcmp(t->host, "127.0.0.1") || !strcmp(t->host, "::1"));
|
||||
}
|
||||
@@ -31,6 +35,9 @@ static inline const char *target_piccap_host(const TargetConfig *t) {
|
||||
}
|
||||
static bool target_valid(const TargetConfig *t) {
|
||||
unsigned char address[16];
|
||||
unsigned interval = target_capture_interval(t);
|
||||
if (interval < 25 || interval > 1000 || interval % 25)
|
||||
return false;
|
||||
if (inet_pton(AF_INET, t->host, address) != 1 && inet_pton(AF_INET6, t->host, address) != 1)
|
||||
return false;
|
||||
if (!t->piccap_port || t->piccap_port > 65535)
|
||||
@@ -97,6 +104,20 @@ static bool target_parse(PlaybackJson *j, const char *text, TargetConfig *out) {
|
||||
next.piccap_port = (unsigned)n;
|
||||
}
|
||||
}
|
||||
void *interval = NULL;
|
||||
if (j->type(root) == 4 && j->get(root, "captureIntervalMs", &interval)) {
|
||||
if (j->type(interval) != 3)
|
||||
valid = false;
|
||||
else {
|
||||
char *end = NULL;
|
||||
errno = 0;
|
||||
long n = strtol(j->string(interval), &end, 10);
|
||||
if (errno || !end || *end || n < 25 || n > 1000 || n % 25)
|
||||
valid = false;
|
||||
else
|
||||
next.capture_interval = (unsigned)n;
|
||||
}
|
||||
}
|
||||
void *clear = playback_field(j, root, "clearToken");
|
||||
if (clear) {
|
||||
if (j->type(clear) != 1)
|
||||
@@ -116,8 +137,8 @@ static bool target_save(const char *path, const TargetConfig *t) {
|
||||
char data[512];
|
||||
int n = snprintf(
|
||||
data, sizeof(data),
|
||||
"{\"host\":\"%s\",\"port\":%u,\"piccapPort\":%u,\"receiver\":\"%s\",\"token\":\"%s\"}\n",
|
||||
t->host, t->port, t->piccap_port, t->receiver, t->token);
|
||||
"{\"host\":\"%s\",\"port\":%u,\"piccapPort\":%u,\"receiver\":\"%s\",\"token\":\"%s\",\"captureIntervalMs\":%u}\n",
|
||||
t->host, t->port, t->piccap_port, t->receiver, t->token, target_capture_interval(t));
|
||||
return n > 0 && (size_t)n < sizeof(data) &&
|
||||
atomic_replace(path, data, (size_t)n) != SAVE_UNCHANGED;
|
||||
}
|
||||
|
||||
+18
-1
@@ -11,5 +11,22 @@ int main(void){
|
||||
for(unsigned i=0;i<16;i++)black[i]=100;
|
||||
memset(color,0,sizeof(color));assert(letterbox_candidate(black,color)==-1);
|
||||
memset(black,0,sizeof(black));assert(letterbox_candidate(black,color)==-1);
|
||||
puts("PASS: full frame, measured letterbox, one edge only, black frame, dark frame");
|
||||
unsigned thin_black[16]={12,23,1,21,9,6,6,16,18,12,26,23,23,22,37,8};
|
||||
unsigned char thin_color[16][3]={{57,52,48},{97,94,92},{51,42,35},{25,24,21},
|
||||
{71,65,60},{128,122,118},{84,74,67},{34,32,27},{47,41,36},{59,47,43},
|
||||
{37,29,25},{19,18,15},{22,20,16},{22,19,15},{14,13,11},{78,75,72}};
|
||||
assert(letterbox_candidate(thin_black,thin_color)==1);
|
||||
thin_black[1]=thin_black[5]=thin_black[9]=0;
|
||||
assert(letterbox_candidate(thin_black,thin_color)!=1);
|
||||
thin_black[1]=23;thin_black[5]=6;thin_black[9]=12;
|
||||
thin_black[11]=0;
|
||||
assert(letterbox_candidate(thin_black,thin_color)!=1);
|
||||
thin_black[11]=23;
|
||||
memset(thin_color,10,sizeof(thin_color));
|
||||
assert(letterbox_candidate(thin_black,thin_color)==-1);
|
||||
memset(thin_color,100,sizeof(thin_color));
|
||||
assert(letterbox_candidate(thin_black,thin_color)!=1);
|
||||
for(unsigned i=0;i<16;i++)thin_black[i]=15;
|
||||
assert(letterbox_candidate(thin_black,thin_color)!=1);
|
||||
puts("PASS: measured wide/thin bars, full frame, one-sided/isolated edges, dark frame and low contrast");
|
||||
}
|
||||
@@ -5,17 +5,20 @@ int main(void) {
|
||||
for (unsigned v = 0; v <= 255; v++) {
|
||||
unsigned char gray[3] = {v, v, v};
|
||||
dark_color_filter(gray);
|
||||
unsigned expected = v <= 12 ? 0 : v >= 24 ? v : (v * (v - 12) + 6) / 12;
|
||||
unsigned expected = v <= 16 ? 0 : v >= 32 ? v : (v * (v - 16) + 8) / 16;
|
||||
for (unsigned c = 0; c < 3; c++) assert(gray[c] == expected);
|
||||
}
|
||||
unsigned char residual[3] = {4, 8, 2};
|
||||
dark_color_filter(residual);
|
||||
assert(!residual[0] && !residual[1] && !residual[2]);
|
||||
unsigned char transition[3] = {9, 18, 6};
|
||||
unsigned char measured[3] = {13, 14, 7};
|
||||
dark_color_filter(measured);
|
||||
assert(!measured[0] && !measured[1] && !measured[2]);
|
||||
unsigned char transition[3] = {12, 24, 8};
|
||||
dark_color_filter(transition);
|
||||
assert(transition[0] == 5 && transition[1] == 9 && transition[2] == 3);
|
||||
unsigned char saturated[3] = {0, 24, 0};
|
||||
assert(transition[0] == 6 && transition[1] == 12 && transition[2] == 4);
|
||||
unsigned char saturated[3] = {0, 32, 0};
|
||||
dark_color_filter(saturated);
|
||||
assert(saturated[0] == 0 && saturated[1] == 24 && saturated[2] == 0);
|
||||
assert(saturated[0] == 0 && saturated[1] == 32 && saturated[2] == 0);
|
||||
puts("PASS: near-black suppression, gradual transition, unchanged brighter colors");
|
||||
}
|
||||
@@ -24,8 +24,16 @@ int main(void){
|
||||
assert(!target_parse(&j,"{\"host\":\"127.0.0.1\",\"port\":19444,\"piccapPort\":null,\"receiver\":\"HyperHDR\"}",&t));
|
||||
TargetConfig v6=t;strcpy(v6.host,"2001:db8::1");assert(!target_piccap_compatible(&v6));strcpy(v6.host,"::1");assert(target_piccap_compatible(&v6) && !strcmp(target_piccap_host(&v6),"127.0.0.1"));
|
||||
const char *file="/tmp/hyperdrm-target-test.json";assert(access(file,F_OK)!=0);assert(access("/tmp/hyperdrm-target-test.json.tmp",F_OK)!=0);
|
||||
assert(target_capture_interval(&t)==50);
|
||||
assert(target_parse(&j,"{\"host\":\"::1\",\"port\":65535,\"receiver\":\"HyperHDR\",\"captureIntervalMs\":100}",&t));
|
||||
assert(t.capture_interval==100);
|
||||
const char *invalid_intervals[]={"0","24","26","1001","50.5","null","\"50\""};
|
||||
for(unsigned i=0;i<sizeof(invalid_intervals)/sizeof(*invalid_intervals);i++){
|
||||
char request[256];snprintf(request,sizeof(request),"{\"host\":\"::1\",\"port\":65535,\"receiver\":\"HyperHDR\",\"captureIntervalMs\":%s}",invalid_intervals[i]);
|
||||
TargetConfig before=t;assert(!target_parse(&j,request,&t));assert(!memcmp(&before,&t,sizeof(t)));
|
||||
}
|
||||
assert(target_save(file,&t));struct stat st;assert(stat(file,&st)==0 && (st.st_mode&0777)==0600);
|
||||
TargetConfig restored=target;assert(target_load(&j,file,&restored));assert(!strcmp(restored.host,"::1") && restored.port==65535 && !strcmp(restored.token,"test-token"));
|
||||
TargetConfig restored=target;assert(target_load(&j,file,&restored));assert(restored.capture_interval==100);assert(!strcmp(restored.host,"::1") && restored.port==65535 && !strcmp(restored.token,"test-token"));
|
||||
assert(target_parse(&j,"{\"host\":\"127.0.0.1\",\"port\":19444,\"receiver\":\"HyperHDR\",\"clearToken\":true}",&t));assert(!t.token[0]);assert(target_piccap_local(&t));unlink(file);
|
||||
int server=socket(AF_INET,SOCK_STREAM,0);assert(server>=0);struct sockaddr_in a={.sin_family=AF_INET,.sin_addr={htonl(INADDR_LOOPBACK)}};
|
||||
assert(bind(server,(void*)&a,sizeof(a))==0 && listen(server,1)==0);socklen_t length=sizeof(a);assert(getsockname(server,(void*)&a,&length)==0);t.port=ntohs(a.sin_port);
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#ifndef HYPERDRM_VERSION_H
|
||||
#define HYPERDRM_VERSION_H
|
||||
#define HYPERDRM_VERSION "0.13.1"
|
||||
#define HYPERDRM_VERSION "0.13.4"
|
||||
#endif
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"id": "org.webosbrew.histogramhyperion",
|
||||
"version": "0.13.1",
|
||||
"version": "0.13.4",
|
||||
"vendor": "Local development",
|
||||
"app": "org.webosbrew.histogramhyperion",
|
||||
"services": [
|
||||
|
||||
Binary file not shown.
@@ -7,7 +7,7 @@ function element(id,input){return {id,tagName:input?'INPUT':'DIV',type:'text',re
|
||||
focus(){if(doc.activeElement && doc.activeElement!==this)doc.activeElement.blur();doc.activeElement=this;if(input)inputFocuses++;},
|
||||
blur(){if(this.handlers.blur)this.handlers.blur();if(doc.activeElement===this)doc.activeElement=null;}
|
||||
};}
|
||||
['host','port','piccapPort','token','customProfile'].forEach(id=>{elements[id]=element(id,true);elements[id+'Field']=element(id+'Field',false);});
|
||||
['host','port','piccapPort','captureInterval','token','customProfile'].forEach(id=>{elements[id]=element(id,true);elements[id+'Field']=element(id+'Field',false);});
|
||||
['overview','receiver','calibration'].forEach(key=>{elements[key+'Panel']=element(key+'Panel');elements[key+'Tab']=element(key+'Tab');});
|
||||
['start','receiver','calibrate','calibrationShortcut'].forEach(id=>elements[id]=element(id));
|
||||
const win={addEventListener(k,f){windowEvents[k]=f;}};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use strict';
|
||||
const assert=require('assert'),fs=require('fs'),vm=require('vm');
|
||||
const ids=['reloadService','versionWarning','host','port','piccapPort','receiver','token','clearToken','endpoint','handover','autostart','error','status','regions','start','stop','refresh','saveTarget','testConnection','testResult','diagnostics','profile','customEditor','customProfile','saveProfile','profileStatus','calibrate','validateCalibration','cancelCalibration','editProfile','customProfileField','overviewTab','receiverTab','calibrationTab','calibrationShortcut','hostField','portField','piccapPortField','tokenField','grantRoot','rootHint'];
|
||||
const ids=['reloadService','versionWarning','host','port','piccapPort','captureInterval','receiver','token','clearToken','endpoint','handover','autostart','error','status','regions','start','stop','refresh','saveTarget','testConnection','testResult','diagnostics','profile','customEditor','customProfile','saveProfile','profileStatus','calibrate','validateCalibration','cancelCalibration','editProfile','customProfileField','overviewTab','receiverTab','calibrationTab','calibrationShortcut','hostField','portField','piccapPortField','captureIntervalField','tokenField','grantRoot','rootHint'];
|
||||
const elements={};
|
||||
ids.forEach(id=>elements[id]={value:'',textContent:'',disabled:false,checked:false,attributes:{},style:{},addEventListener(){},focus(){},appendChild(){},setAttribute(k,v){this.attributes[k]=v;},getAttribute(k){return this.attributes[k];}});
|
||||
const requests=[];
|
||||
@@ -17,8 +17,8 @@ assert(elements.diagnostics.textContent.includes('Root service'));
|
||||
assert(controls.includes(elements.piccapPortField)&&controls.includes(elements.testConnection));
|
||||
context.targetDirty=true;elements.testConnection.onclick();assert(elements.error.textContent.includes('Save receiver'));
|
||||
elements.piccapPort.value='0';elements.saveTarget.onclick();assert(elements.error.textContent.includes('FlatBuffer port'));
|
||||
elements.piccapPort.value='19446';elements.host.value='10.1.0.100';elements.token.value='';elements.saveTarget.onclick();
|
||||
const saved=requests.find(r=>r.uri.endsWith('/settings'));assert.strictEqual(saved.data.piccapPort,19446);assert.strictEqual(saved.data.host,'10.1.0.100');assert(!('token' in saved.data));
|
||||
elements.piccapPort.value='19446';elements.captureInterval.value='26';elements.saveTarget.onclick();assert(elements.error.textContent.includes('Capture interval'));elements.captureInterval.value='100';elements.piccapPort.value='19446';elements.host.value='10.1.0.100';elements.token.value='';elements.saveTarget.onclick();
|
||||
const saved=requests.find(r=>r.uri.endsWith('/settings'));assert.strictEqual(saved.data.piccapPort,19446);assert.strictEqual(saved.data.captureIntervalMs,100);assert.strictEqual(saved.data.host,'10.1.0.100');assert(!('token' in saved.data));
|
||||
elements.testConnection.onclick();assert(requests.some(r=>r.uri.endsWith('/testConnection')));
|
||||
assert.strictEqual(elements.token.value,'');assert(!elements.diagnostics.textContent.includes('fixture-token'));
|
||||
elements.profile.onclick();assert(elements.profile.textContent.includes('LG G4'));elements.saveProfile.onclick();assert(requests.some(r=>r.uri.endsWith('/calibration')&&r.data.profile==='g4'));
|
||||
|
||||
Reference in new issue
Block a user