Private
Public Access
Release 0.12.0
This commit is contained in:
1 parent
f74a658097
commit
7f6eeab39e
48 files changed
+3617
-1266
No files matched your search
+105
-40
@@ -1,47 +1,112 @@
|
||||
#ifndef HYPERDRM_SOURCE_BRIDGE_H
|
||||
#define HYPERDRM_SOURCE_BRIDGE_H
|
||||
static unsigned bridge_phase,bridge_sequence;
|
||||
static uint64_t bridge_started,bridge_clear_at,bridge_fade_at,bridge_last_sent;
|
||||
static unsigned char bridge_from[16][3],bridge_to[16][3];
|
||||
#include "runtime_states.h"
|
||||
static BridgePhase bridge_phase;
|
||||
static unsigned bridge_sequence;
|
||||
static uint64_t bridge_started, bridge_clear_at, bridge_fade_at, bridge_last_sent;
|
||||
static unsigned char bridge_from[16][3], bridge_to[16][3];
|
||||
static CaptureSource bridge_source;
|
||||
static char *region_command(const unsigned char colors[16][3],const LedBlend *mapping,unsigned count,unsigned duration){
|
||||
if(!count || !mapping)return NULL;
|
||||
if(!strcmp(target.receiver,"HyperHDR"))return spatial_image_command_duration(colors,PRIORITY,duration);
|
||||
size_t capacity=256+(size_t)count*12;char *line=malloc(capacity);if(!line)return NULL;
|
||||
size_t n=(size_t)snprintf(line,capacity,"{\"command\":\"color\",\"priority\":%d,\"duration\":%u,\"origin\":\"HyperDRM\",\"color\":[",PRIORITY,duration);
|
||||
for(unsigned i=0;i<count;i++){unsigned char value[3];LedBlend b=mapping[i];blend_color(colors[b.a],colors[b.b],b.weight,value);n+=(size_t)snprintf(line+n,capacity-n,"%s%u,%u,%u",i?",":"",value[0],value[1],value[2]);}
|
||||
snprintf(line+n,capacity-n,"]}\n");return line;
|
||||
static char *region_command(const unsigned char colors[16][3], const LedBlend *mapping,
|
||||
unsigned count, unsigned duration) {
|
||||
if (!count || !mapping)
|
||||
return NULL;
|
||||
if (!strcmp(target.receiver, "HyperHDR"))
|
||||
return spatial_image_command_duration(colors, PRIORITY, duration);
|
||||
size_t capacity = 256 + (size_t)count * 12;
|
||||
char *line = malloc(capacity);
|
||||
if (!line)
|
||||
return NULL;
|
||||
size_t n = (size_t)snprintf(line, capacity,
|
||||
"{\"command\":\"color\",\"priority\":%d,\"duration\":%u,\"origin\":"
|
||||
"\"HyperDRM\",\"color\":[",
|
||||
PRIORITY, duration);
|
||||
for (unsigned i = 0; i < count; i++) {
|
||||
unsigned char value[3];
|
||||
LedBlend b = mapping[i];
|
||||
blend_color(colors[b.a], colors[b.b], b.weight, value);
|
||||
n += (size_t)snprintf(line + n, capacity - n, "%s%u,%u,%u", i ? "," : "", value[0],
|
||||
value[1], value[2]);
|
||||
}
|
||||
snprintf(line + n, capacity - n, "]}\n");
|
||||
return line;
|
||||
}
|
||||
static bool bridge_clear(void){return stream.stage==4 && stream_queue("{\"command\":\"clear\",\"priority\":149}\n");}
|
||||
static bool bridge_send(const unsigned char colors[16][3]){
|
||||
if(stream.stage!=4)return false;
|
||||
char *line=region_command(colors,stream.mapping,stream.count,1500);if(!line)return false;
|
||||
bool ok=stream_queue(line);free(line);return ok;
|
||||
static bool bridge_clear(void) {
|
||||
return stream.stage == STREAM_SUBSCRIBED &&
|
||||
stream_queue("{\"command\":\"clear\",\"priority\":149}\n");
|
||||
}
|
||||
static void bridge_tick(uint64_t now){
|
||||
if(retries.paused || retries.blocked){if(bridge_phase)bridge_clear();bridge_phase=0;bridge_source=capture_source;return;}
|
||||
if(capture_source!=bridge_source){
|
||||
if(capture_source==SOURCE_PICCAP_STARTING){
|
||||
bridge_phase=continuity.available && now-continuity.valid_at<2000?1:0;bridge_started=now;memcpy(bridge_from,continuity.last,sizeof(bridge_from));
|
||||
}else if(capture_source==SOURCE_PICCAP_STOPPING || (bridge_source==SOURCE_PICCAP && capture_source==SOURCE_HISTOGRAM)){
|
||||
bridge_phase=0;
|
||||
if(stream.valid && now-stream.updated<1000){continuity_seed(&continuity,stream.colors,now);bridge_send(stream.colors);}
|
||||
}
|
||||
bridge_source=capture_source;
|
||||
}
|
||||
if(bridge_phase && now-bridge_started>=3000){if(bridge_clear())bridge_phase=0;return;}
|
||||
if(bridge_phase==1 && capture_source==SOURCE_PICCAP && piccap_connected && stream.stage==4){
|
||||
if(bridge_clear()){bridge_sequence=stream.sequence;bridge_clear_at=now;bridge_phase=2;}
|
||||
}else if(bridge_phase==1 && now-bridge_last_sent>=100 && stream.stage==4){
|
||||
if(bridge_send(bridge_from))bridge_last_sent=now;
|
||||
}else if(bridge_phase==2 && stream.valid && stream.sequence>bridge_sequence && stream.updated>=bridge_clear_at+150){
|
||||
memcpy(bridge_to,stream.colors,sizeof(bridge_to));bridge_fade_at=now;bridge_phase=3;
|
||||
bool black=true;for(unsigned r=0;r<16;r++)for(unsigned c=0;c<3;c++)if(bridge_to[r][c]>3)black=false;
|
||||
if(black)bridge_phase=0;
|
||||
}
|
||||
if(bridge_phase==3 && now-bridge_last_sent>=100){
|
||||
if(now-bridge_fade_at>=500){if(bridge_clear())bridge_phase=0;}
|
||||
else {unsigned char colors[16][3];continuity_mix(bridge_from,bridge_to,(unsigned)(now-bridge_fade_at),colors);if(bridge_send(colors))bridge_last_sent=now;}
|
||||
}
|
||||
static bool bridge_send(const unsigned char colors[16][3]) {
|
||||
if (stream.stage != STREAM_SUBSCRIBED)
|
||||
return false;
|
||||
char *line = region_command(colors, stream.mapping, stream.count, 1500);
|
||||
if (!line)
|
||||
return false;
|
||||
bool ok = stream_queue(line);
|
||||
free(line);
|
||||
return ok;
|
||||
}
|
||||
static void bridge_tick(uint64_t now) {
|
||||
if (retries.paused || retries.blocked) {
|
||||
if (bridge_phase)
|
||||
bridge_clear();
|
||||
bridge_phase = BRIDGE_IDLE;
|
||||
bridge_source = capture_source;
|
||||
return;
|
||||
}
|
||||
if (capture_source != bridge_source) {
|
||||
if (capture_source == SOURCE_PICCAP_STARTING) {
|
||||
bridge_phase = continuity.available && now - continuity.valid_at < 2000 ? BRIDGE_HOLDING
|
||||
: BRIDGE_IDLE;
|
||||
bridge_started = now;
|
||||
memcpy(bridge_from, continuity.last, sizeof(bridge_from));
|
||||
} else if (capture_source == SOURCE_PICCAP_STOPPING ||
|
||||
(bridge_source == SOURCE_PICCAP && capture_source == SOURCE_HISTOGRAM)) {
|
||||
bridge_phase = BRIDGE_IDLE;
|
||||
if (stream.valid && now - stream.updated < 1000) {
|
||||
continuity_seed(&continuity, stream.colors, now);
|
||||
bridge_send(stream.colors);
|
||||
}
|
||||
}
|
||||
bridge_source = capture_source;
|
||||
}
|
||||
if (bridge_phase && now - bridge_started >= 3000) {
|
||||
if (bridge_clear())
|
||||
bridge_phase = BRIDGE_IDLE;
|
||||
return;
|
||||
}
|
||||
if (bridge_phase == BRIDGE_HOLDING && capture_source == SOURCE_PICCAP && piccap_connected &&
|
||||
stream.stage == STREAM_SUBSCRIBED) {
|
||||
if (bridge_clear()) {
|
||||
bridge_sequence = stream.sequence;
|
||||
bridge_clear_at = now;
|
||||
bridge_phase = BRIDGE_WAITING_FRAME;
|
||||
}
|
||||
} else if (bridge_phase == BRIDGE_HOLDING && now - bridge_last_sent >= 100 &&
|
||||
stream.stage == STREAM_SUBSCRIBED) {
|
||||
if (bridge_send(bridge_from))
|
||||
bridge_last_sent = now;
|
||||
} else if (bridge_phase == BRIDGE_WAITING_FRAME && stream.valid &&
|
||||
stream.sequence > bridge_sequence && stream.updated >= bridge_clear_at + 150) {
|
||||
memcpy(bridge_to, stream.colors, sizeof(bridge_to));
|
||||
bridge_fade_at = now;
|
||||
bridge_phase = BRIDGE_FADING;
|
||||
bool black = true;
|
||||
for (unsigned r = 0; r < 16; r++)
|
||||
for (unsigned c = 0; c < 3; c++)
|
||||
if (bridge_to[r][c] > 3)
|
||||
black = false;
|
||||
if (black)
|
||||
bridge_phase = BRIDGE_IDLE;
|
||||
}
|
||||
if (bridge_phase == BRIDGE_FADING && now - bridge_last_sent >= 100) {
|
||||
if (now - bridge_fade_at >= 500) {
|
||||
if (bridge_clear())
|
||||
bridge_phase = BRIDGE_IDLE;
|
||||
} else {
|
||||
unsigned char colors[16][3];
|
||||
continuity_mix(bridge_from, bridge_to, (unsigned)(now - bridge_fade_at), colors);
|
||||
if (bridge_send(colors))
|
||||
bridge_last_sent = now;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in new issue
Block a user