Skip to content

Instantly share code, notes, and snippets.

@NickHu
Last active April 8, 2020 16:26
Show Gist options
  • Save NickHu/8eb7ead78a5489d6a95ad5c7473994f5 to your computer and use it in GitHub Desktop.
Save NickHu/8eb7ead78a5489d6a95ad5c7473994f5 to your computer and use it in GitHub Desktop.
reStream frame deltas with xor
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <string.h>
#include <signal.h>
#include <assert.h>
#include "lz4frame.h"
enum {
HEIGHT = 1872,
WIDTH = 1408,
BYTES_PER_PIXEL = 2,
WINDOW_BYTES = WIDTH*HEIGHT*BYTES_PER_PIXEL
};
volatile sig_atomic_t stop = 0;
void sigINThandle(int signum) {
stop = 1;
};
inline _Bool xor(char *diff, char *x, char *y, size_t size) {
_Bool changed = 0;
for (size_t i = 0; i < size; i++) {
diff[i] = x[i] ^ y[i];
changed |= diff[i];
}
return changed;
}
int main(int argc, char const* argv[]) {
const int max_compressed_size = LZ4F_compressFrameBound(WINDOW_BYTES, NULL);
int fb0 = open("/dev/fb0", O_RDONLY);
// handle failed to open
char diff[WINDOW_BYTES];
_Bool a = 1;
uint8_t *fbp = mmap(NULL, WINDOW_BYTES, PROT_READ, MAP_SHARED, fb0, 0);
assert(fbp != MAP_FAILED);
uint8_t *buf_a = malloc(WINDOW_BYTES);
assert(buf_a != NULL);
uint8_t *buf_b = malloc(WINDOW_BYTES);
assert(buf_b != NULL);
char *compressed = malloc(max_compressed_size);
assert(compressed != NULL);
// grab the initial frame, compress and send
memcpy(buf_a, fbp, WINDOW_BYTES);
int compressed_size = LZ4F_compressFrame(compressed, max_compressed_size, buf_a, WINDOW_BYTES, NULL);
assert(compressed_size >= 0);
fwrite(compressed, 1, compressed_size, stdout);
signal(SIGINT, sigINThandle);
// now we watch for changes
while (!stop) {
// get a new framegrab
a = !a;
memcpy((a ? buf_a : buf_b), fbp, WINDOW_BYTES);
// xor it with the last one
_Bool changed = 0;
for (int i = 0; i < WINDOW_BYTES; i++) {
diff[i] = buf_a[i] ^ buf_b[i];
changed |= diff[i];
}
if (!changed) // if nothing changed, don't do anything else
continue;
// compress the result
compressed_size = LZ4F_compressFrame(compressed, max_compressed_size, diff, WINDOW_BYTES, NULL);
assert(compressed_size >= 0);
// write the compressed result to stdout
fwrite(compressed, 1, compressed_size, stdout);
// int changed = 0;
// for (int i = 0; i < WINDOW_BYTES; i++) {
// if (diff[i] != 0x00)
// changed++;
// }
// printf("Bytes changed: %d\n", changed);
}
free(buf_a);
free(buf_b);
free(compressed);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>
int main(int argc, char const* argv[]) {
const int height = 1872;
const int width = 1408;
const int bytes_per_pixel = 2;
const int window_bytes = width*height*bytes_per_pixel;
char diff[window_bytes];
_Bool a = 1;
uint8_t *buf_a = malloc(window_bytes);
assert(buf_a != NULL);
uint8_t *buf_b = malloc(window_bytes);
assert(buf_b != NULL);
// grab the initial frame, and dump to stdout
fread(buf_a, 1, window_bytes, stdin);
fwrite(buf_a, 1, window_bytes, stdout);
// now we watch for changes
while (1) {
// get a new framegrab
uint8_t *cur = (a ? buf_a : buf_b);
uint8_t *next = (a ? buf_b : buf_a);
// read the xor diff from the stream
fread(diff, 1, window_bytes, stdin);
// compute the next frame
for (int i = 0; i < window_bytes; i++) {
next[i] = cur[i] ^ diff[i];
}
// write the result to stdout
fwrite(next, 1, window_bytes, stdout);
a = !a;
}
free(buf_a);
free(buf_b);
return 0;
}
@NickHu
Copy link
Author

NickHu commented Apr 8, 2020

Usage:

ssh root@192.168.0.25 -- /tmp/framedelta | lz4 -d - | ./receiver | ffplay -vcodec rawvideo -loglevel info -f rawvideo -pixel_format gray16le -video_size "1408,1872" -i -

Or over nc instead (slightly less latency compared to ssh):

On computer:

nc -l 1234 | lz -d - | ./receiver | ffplay -vcodec rawvideo -loglevel info -f rawvideo -pixel_format gray16le -video_size "1408,1872" -i -

On reMarkable:

/tmp/framedelta | nc computer.lan 1234

@NickHu
Copy link
Author

NickHu commented Apr 8, 2020

Precompiled reMarkable binary:
http://ix.io/2hf5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment