Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support reMarkable 2 #31

Merged
merged 16 commits into from
Jan 1, 2021
Merged

Support reMarkable 2 #31

merged 16 commits into from
Jan 1, 2021

Conversation

rien
Copy link
Owner

@rien rien commented Oct 29, 2020

TODO:

  • Confirm this doesn't break rM1 support
  • Confirm reading the framebuffer works for rM2
  • Confirm the correct orientation is used for rM2

Closes #28

@rien rien force-pushed the feature/support-reMarkable-2 branch from 5276a0e to 6072366 Compare October 29, 2020 11:08
@Stivanification
Copy link

Doesn't work for me with with reMarkable 2 v2.3.1.27. This is the output I get:

WARNING: unknown reMarkable 2 release version
consider updating if reStream doesn't work
awk: cmd. line:1: Unexpected token
ffplay version 4.2.4-1ubuntu0.1 Copyright (c) 2003-2020 the FFmpeg developers
  built with gcc 9 (Ubuntu 9.3.0-10ubuntu2)
  configuration: --prefix=/usr --extra-version=1ubuntu0.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-nvenc --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
  WARNING: library configuration mismatch
  avcodec     configuration: --prefix=/usr --extra-version=1ubuntu0.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-nvenc --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared --enable-version3 --disable-doc --disable-programs --enable-libaribb24 --enable-liblensfun --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libtesseract --enable-libvo_amrwbenc
  libavutil      56. 31.100 / 56. 31.100
  libavcodec     58. 54.100 / 58. 54.100
  libavformat    58. 29.100 / 58. 29.100
  libavdevice    58.  8.100 / 58.  8.100
  libavfilter     7. 57.100 /  7. 57.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  5.100 /  5.  5.100
  libswresample   3.  5.100 /  3.  5.100
  libpostproc    55.  5.100 / 55.  5.100
Input #0, rawvideo, from 'pipe:':  0KB vq=    0KB sq=    0B f=0/0   
  Duration: N/A, bitrate: 525657 kb/s
    Stream #0:0: Video: rawvideo (Y800 / 0x30303859), gray, 1404x1872, 525657 kb/s, 25 tbr, 25 tbn, 25 tbc
^C  nan M-V:    nan fd=   0 aq=    0KB vq=    0KB sq=    0B f=0/0   

reStream.sh Outdated Show resolved Hide resolved
reStream.sh Outdated
pixel_format="gray8"
pid="$(ssh_cmd pidof xochitl)"
pointer="$(rm2_getpointer)"
read_address="addr=\$(dd if=/proc/$pid/mem bs=1 count=4 skip=$pointer 2>/dev/null | hexdump | awk '{print \$3\$2\}') && printf '%d' \$((16#\$addr))"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

had to change that line to

        read_address="addr=\$(dd if=/proc/$pid/mem bs=1 count=4 skip=$pointer 2>/dev/null | hexdump | awk '{print \$3\$2}') && printf '%d' \$((16#\$addr))"

reStream.sh Outdated Show resolved Hide resolved
reStream.sh Outdated
rm2_getpointer() {
xochitl_version="$(ssh_cmd "sed -n 's/^REMARKABLE_RELEASE_VERSION=//p' /usr/share/remarkable/update.conf")"
case "$xochitl_version" in
"2.3.*")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't seem to match my 2.3.1.27 version.

reStream.sh Outdated
"2.3.*")
echo "4121024"
;;
"2.4.*")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"2.4.*")
"2.4."*)

@@ -69,13 +69,6 @@ while [ $# -gt 0 ]; do
esac
done

# technical parameters
width=1408

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • width, height are switched on the RM2.
  • bytes per pixel is 1 on the RM2
  • i'm wondering if loop_wait might benefit from having a small sleep? Still yet to experiment

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have experimented with sleeps, but it ended up not being beneficial I think. Anyway, we should speed up reading the framebuffer before changing loop_wait.

reStream.sh Outdated
# address of the pointer to the framebuffer for some reMarkable 2 versions.
# This will need to be changed each time xochitl updates.
rm2_getpointer() {
xochitl_version="$(ssh_cmd "sed -n 's/^REMARKABLE_RELEASE_VERSION=//p' /usr/share/remarkable/update.conf")"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/sys/devices/soc0/machine might be a better indicator, possibly

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on Eeems-Org/oxide#48 (comment) I would agree

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is is not to find out if we're running rM1 or 2, but to find the correct pointer between xochitl versions. That information is not included in /sys/devices/soc0/machine?

@@ -131,9 +183,6 @@ video_filters=""
# store extra ffmpeg arguments in $@
set --

# calculate how much bytes the window is
window_bytes="$((width * height * bytes_per_pixel))"

# rotate 90 degrees if landscape=true
$landscape && video_filters="$video_filters,transpose=1"
Copy link

@harrylepotter harrylepotter Oct 29, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think transpose might=2 on the RM2

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you confirm this? transpose=2 will flip it completely upside down?

Copy link

@gcotone gcotone Nov 3, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@harrylepotter indeed, I'm on 2.3.1.27 and this was required to make orientation work properly:

! $landscape && video_filters="$video_filters,transpose=2"

reStream.sh Outdated
# calculate how much bytes the window is
window_bytes="$((width * height * bytes_per_pixel))"
# carve the framebuffer out of the process memory
head_fb0="dd if=/proc/$pid/mem bs=1 count=$window_bytes skip=$skipbytes 2>/dev/null"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a better solution to this that i'm trying to figure out.. Unfortantely i'm not great at bash. Basically you want to get the highest factor to 4096 that divides skip_bytes without a remainder. it'd be something like:

for((c=1;c<=4096;c++))
do
    if[ (($skip_bytes % c)) -eq 0 ] then
        div=$c
    fi
done

then bs=$div, skip=(($skipbytes/$div)), count=(($window_bytes/$div))

Copy link

@Stivanification Stivanification Oct 29, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Am I missing something or do you want the biggest integer x such that x divides both 4096 and skip_bytes? In that case you're simply looking for the greatest common divisor of 4096 and skip_bytes. You can implement the gcd in bash like so (I took this from StackOverflow):

gcd() (
    if (( $1 % $2 == 0)); then
        echo $2
     else
        gcd $2 $(( $1 % $2 ))
    fi
)

This is an implementation of the Euclidean algorithm. The number you're looking for then is
gcd 4096 $skip_bytes

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

believe you're looking for the closest integer to 4096 (the page block limit) that $skipbytes is divisible by... You're also going to round-up count so that it captures more data than necessary (this gets filtered out by the 2nd dd command)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the fastest, though not pretty is simply to do:

num=1925402632

for i in {4096..1};
do
    if [ $(($num % $i)) == 0 ]; then
       echo "Largest divisor: $i"
       break
    fi
done

In my case, I'm getting 3284, which seems to work when updating @harrylepotter's gist.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@piada i think busybox's implementation of dd doesn't do iflag

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@harrylepotter @piada, yup, reading the implementation it doesn't seem like Busybox's implementation supports it: https://git.busybox.net/busybox/tree/coreutils/dd.c

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you guys for your input. The problem with the gcd approach is that we will be way to dependent of the specific address for performance. I've added a memread_instr function to read the pages containing the buffer and then slice it to the desired bytes.

@rien rien force-pushed the feature/support-reMarkable-2 branch from 0c34c0d to c7ed9c1 Compare October 31, 2020 17:54
@rien rien marked this pull request as ready for review October 31, 2020 17:57
@rien
Copy link
Owner Author

rien commented Oct 31, 2020

If someone with an rM2 and version 2.3.1.17 could test this PR out it that would be awesome! If someone can find the right skills to find the framebuffer pointer in 2.4.* then we can support the most recent update.

@Stivanification
Copy link

I'm getting the following

./reStream.sh: 113: dd if=/proc/238/mem bs=4096 skip=1006 count=1 2>/dev/null | dd if=/dev/stdin skip=448 bs=4 count=1 2>/dev/null: not found
sh: command substitution: line 1: syntax error near unexpected token `|'
sh: command substitution: line 1: ` | hexdump | awk '{print $3$2}')'
./reStream.sh: 113: dd if=/proc/238/mem bs=4096 skip=0 count=642 2>/dev/null | dd if=/dev/stdin skip=0 bs=2628288 count=1 2>/dev/null: not found
ffplay version 4.2.4-1ubuntu0.1 Copyright (c) 2003-2020 the FFmpeg developers
  built with gcc 9 (Ubuntu 9.3.0-10ubuntu2)
  configuration: --prefix=/usr --extra-version=1ubuntu0.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-nvenc --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
  WARNING: library configuration mismatch
  avcodec     configuration: --prefix=/usr --extra-version=1ubuntu0.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-nvenc --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared --enable-version3 --disable-doc --disable-programs --enable-libaribb24 --enable-liblensfun --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libtesseract --enable-libvo_amrwbenc
  libavutil      56. 31.100 / 56. 31.100
  libavcodec     58. 54.100 / 58. 54.100
  libavformat    58. 29.100 / 58. 29.100
  libavdevice    58.  8.100 / 58.  8.100
  libavfilter     7. 57.100 /  7. 57.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  5.100 /  5.  5.100
  libswresample   3.  5.100 /  3.  5.100
  libpostproc    55.  5.100 / 55.  5.100
sh: -c: line 0: syntax error near unexpected token `;'   0B f=0/0   
sh: -c: line 0: `whil./reStream.sh: 113: dd if=/proc/238/mem bs=4096 skip=1006 count=1 2>/dev/null | dd if=/dev/stdin skip=448 bs=4 count=1 2>/dev/null: not found
sh: command substitution: line 1: syntax error near unexpected token `|'
sh: command substitution: line 1: ` | hexdump | awk '{print $3$2}')'
./reStream.sh: 113: dd if=/proc/238/mem bs=4096 skip=0 count=642 2>/dev/null | dd if=/dev/stdin skip=0 bs=2628288 count=1 2>/dev/null: not found
ffplay version 4.2.4-1ubuntu0.1 Copyright (c) 2003-2020 the FFmpeg developers
  built with gcc 9 (Ubuntu 9.3.0-10ubuntu2)
  configuration: --prefix=/usr --extra-version=1ubuntu0.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-nvenc --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
  WARNING: library configuration mismatch
  avcodec     configuration: --prefix=/usr --extra-version=1ubuntu0.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-nvenc --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared --enable-version3 --disable-doc --disable-programs --enable-libaribb24 --enable-liblensfun --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libtesseract --enable-libvo_amrwbenc
  libavutil      56. 31.100 / 56. 31.100
  libavcodec     58. 54.100 / 58. 54.100
  libavformat    58. 29.100 / 58. 29.100
  libavdevice    58.  8.100 / 58.  8.100
  libavfilter     7. 57.100 /  7. 57.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  5.100 /  5.  5.100
  libswresample   3.  5.100 /  3.  5.100
  libpostproc    55.  5.100 / 55.  5.100
sh: -c: line 0: syntax error near unexpected token `;'   0B f=0/0   
sh: -c: line 0: `while ; do true; done | $HOME/lz4'
Input #0, rawvideo, from 'pipe:':
  Duration: N/A, bitrate: 525657 kb/s
    Stream #0:0: Video: rawvideo (Y800 / 0x30303859), gray, 1872x1404, 525657 kb/s, 25 tbr, 25 tbn, 25 tbc
^C  nan M-V:    nan fd=   0 aq=    0KB vq=    0KB sq=    0B f=0/0e ; do true; done | $HOME/lz4'
Input #0, rawvideo, from 'pipe:':

unfortunately I'm a beginner with bash so I'm afraid I can't help with the debugging.

reStream.sh Outdated
pixel_format="gray8"
pid="$(ssh_cmd pidof xochitl)"
pointer="$(rm2_getpointer)"
read_address="addr=\$($(memread_instr "/proc/$pid/mem" "$pointer" 4) | hexdump | awk '{print \$3\$2}') && printf '%d' \$((16#\$addr))"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not a bash expert, but I suspect we may want to add "echo" before the second dollar sign?

@thomsten
Copy link
Contributor

thomsten commented Nov 2, 2020

Using head doesn't seem to work on 2.4.1.30 at least. It's running Busybox v1.3, apparently without ENABLE_FANCY_HEAD :( https://git.busybox.net/busybox/tree/coreutils/head.c?h=1_3_stable#n72

@levincoolxyz
Copy link

After bypassing the lack of "head -c" issue using "dd bs=$window_bytes", I was able to get still frames out perfectly (e.g. using convert). But with ffplay it still have significant drifting artifacts during the stream. Not able to comprehend the inconsistency between these two outcomes... (on version 2.3.1.27)

Copy link

@gcotone gcotone left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check my comments. It works with a normal head binary and changing the rotation for portrait mode.
I don't have a rm1 to compare with, but IMHO latency is good enough with this aproach

@@ -131,9 +183,6 @@ video_filters=""
# store extra ffmpeg arguments in $@
set --

# calculate how much bytes the window is
window_bytes="$((width * height * bytes_per_pixel))"

# rotate 90 degrees if landscape=true
$landscape && video_filters="$video_filters,transpose=1"
Copy link

@gcotone gcotone Nov 3, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@harrylepotter indeed, I'm on 2.3.1.27 and this was required to make orientation work properly:

! $landscape && video_filters="$video_filters,transpose=2"

reStream.sh Outdated

# Using dd with bs=1 is too slow, so we first carve out the pages our desired
# bytes are located in, and then we trim the resulting data with what we need.
head_fb0="dd if=/proc/$pid/mem bs=$page_size skip=$window_start_blocks count=$window_length_blocks 2>/dev/null | tail -c+$window_offset | head -c $window_bytes"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

head -c not supported by head from busybox, requires armhf compiled binary, and can be replace by e.g. /usr/local/bin/head

Copy link

@levincoolxyz levincoolxyz Nov 3, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cool I just grabbed the latest stable busybox version from https://www.busybox.net/downloads/binaries/1.31.0-defconfig-multiarch-musl/busybox-armv7l and replaced/linked to /bin/busybox.nosuid on rm2 and it works!

but speed is still a bit of an issue though, but it's good enough

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest testing with the version of busybox (or better yet coreutils-head) in entware since it'll make more sense to keep within the established ecosystem: https:/Evidlo/remarkable_entware

Copy link

@levincoolxyz levincoolxyz Nov 3, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"opkg install head" was the first (dumb) thing I tried. Figured out the correct lines now with entware (update, upgrade than install coreutils-head) but actually the castrated stock busybox bothers a noob like me more anyways. (frequently needs reminders and the stock busybox does not have proper help info)... waiting for someone more familiar with bash/shell to chime in, maybe a proper dd command is enough? (still don't understand the difference between head -c $bytes vs dd bs=$bytes count=1 ...)

Copy link

@gcotone gcotone Nov 3, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kept the stock busybox and just installed debian's head from coreutils package (armhf)

it can be scripted as well:

wget http://ftp.de.debian.org/debian/pool/main/c/coreutils/coreutils_8.30-3_armhf.deb
dpkg --fsys-tarfile coreutils_8.30-3_armhf.deb | tar xOf - ./usr/bin/head > head
chmod +x head
scp head root@remarkable:/usr/local/bin/.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While it can be scripted to use debian's coreutils, the existing ecosystem on the remarkable (https:/toltec-dev/toltec) uses entware, so it would make more sense to continue using it.

Copy link

@benneti benneti Nov 4, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can confirm that it works with coreutils-head from entware.
Additionally as already mentioned for portrait mode such that the transpose should be set case dependent:

# landscape filter
video_filters="transpose=1"
# portrait mode
$landscape && video_filters="$video_filters,transpose=2"

Copy link

@adamm adamm Nov 5, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To get Portrait and Landscape working 100% after installing debian's head(), I had to do additional video settings:

# rotate 90˚ counter-clockwise for portrait mode
! $landscape && video_filters="$video_filters,transpose=2"

So if landscape==true, don't transpose the video on rM2.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

head -c not supported by head from busybox, requires armhf compiled binary, and can be replace by e.g. /usr/local/bin/head

About the head head -c, I would suggest to replace head -c $window_bytes" with dd count=$window_bytes bs=1 2>/dev/null which I tested and works on my up to date reMarkable2 without any additional binaries copied.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dd with bs=1 and non-zero count is very slow.
OTOH you can just call dd twice, I use the following snippet here to do everything in a single ssh invocation (not for reStream, but you can use the dd commands):

width=1872
height=1404
bytes_per_pixel=1
window_bytes="$((width * height * bytes_per_pixel))"

echo "
pid=\$(pidof xochitl)
offset=\$(awk -F- '/\/dev\/fb0/ { getline; print \"0x\" \$1; } ' < /proc/\$pid/maps)
{ dd bs=1 skip=\$((offset)) count=0; dd bs=$window_bytes count=1; } < /proc/\$pid/mem 2>/dev/null
" | ssh $REMARKABLE

@sdatko
Copy link

sdatko commented Nov 19, 2020

Software version 2.4.1.30 here, works properly after applying the following changes mentioned by others in comments:

diff --git a/reStream.sh b/reStream.sh
index 39a50e7..1f5d589 100755
--- a/reStream.sh
+++ b/reStream.sh
@@ -121,7 +121,7 @@ case "$rm_version" in

         # Using dd with bs=1 is too slow, so we first carve out the pages our desired
         # bytes are located in, and then we trim the resulting data with what we need.
-        head_fb0="dd if=/proc/$pid/mem bs=$page_size skip=$window_start_blocks count=$window_length_blocks 2>/dev/null | tail -c+$window_offset | head -c $window_bytes"
+        head_fb0="dd if=/proc/$pid/mem bs=$page_size skip=$window_start_blocks count=$window_length_blocks 2>/dev/null | tail -c+$window_offset | dd count=$window_bytes bs=1 2>/dev/null"
         ;;
     *)
         echo "Unsupported reMarkable version: $rm_version."
@@ -180,7 +180,7 @@ video_filters=""
 set --

 # rotate 90 degrees if landscape=true
-$landscape && video_filters="$video_filters,transpose=1"
+$landscape && video_filters="$video_filters,transpose=2"

 # Scale and add padding if we are targeting a webcam because a lot of services
 # expect a size of exactly 1280x720 (tested in Firefox, MS Teams, and Skype for

Though, the latency is for me very big – it takes about 40-45 seconds after any change is made when used the lz4 binary provided in the repository, while it takes about 20-25 seconds without this binary.

Also I have doubts about the rotation at all – the variable suggests that the default mode is landscape and optionally it should be portrait orientation. If I read this correctly, then we actually have the opposite – by default the displayed stream is exactly as you hold reMarkable in your hands, which for me is portrait (taller than wider). If you then add -p mode, then the screen is rotated by 90 degrees, which would correspond with rotating the device on your desk to have it wider than taller. Was it different on reMarkable1 or we just have bad naming here?

@ladnir
Copy link

ladnir commented Dec 1, 2020

What is the status of this? I pulled this branch but get the following error. I'm on v2.4.1.30, also tried the change that @sdatko mentions above and scp'ed head to root@remarkable:/usr/local/bin/.

peter@DESKTOP-31JUF3C:~/reStream$ ./reStream.sh
[SSH] true
[SSH] cat /sys/devices/soc0/machine
[SSH] pidof xochitl
xochitl's PID: 247
[SSH] grep -C1 '/dev/fb0' /proc/247/maps | tail -n1 | sed 's/-.*$//'
framebuffer is at 0x72afa000
[SSH] [ -f /opt/bin/lz4 ]
[SSH] [ -f ~/lz4 ]
Your remarkable does not have lz4.
Falling back to gzip, your experience may not be optimal.
Go to https:/rien/reStream/#sub-second-latency for a better experience.
[SSH] while dd if=/proc/247/mem bs=4096 skip=469754 count=642 2>/dev/null | tail -c+8 | dd count=2628288 bs=1 2>/dev/null; do true; done | gzip
ffplay version 4.2.4-1ubuntu0.1 Copyright (c) 2003-2020 the FFmpeg developers
  built with gcc 9 (Ubuntu 9.3.0-10ubuntu2)
  configuration: --prefix=/usr --extra-version=1ubuntu0.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-nvenc --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
  libavutil      56. 31.100 / 56. 31.100
  libavcodec     58. 54.100 / 58. 54.100
  libavformat    58. 29.100 / 58. 29.100
  libavdevice    58.  8.100 / 58.  8.100
  libavfilter     7. 57.100 /  7. 57.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  5.100 /  5.  5.100
  libswresample   3.  5.100 /  3.  5.100
  libpostproc    55.  5.100 / 55.  5.100
error: XDG_RUNTIME_DIR not set in the environment.
Could not initialize SDL - No available video device
(Did you set the DISPLAY variable?)
^C

@sdatko
Copy link

sdatko commented Dec 1, 2020

What is the status of this? I pulled this branch but get the following error. I'm on v2.4.1.30, also tried the change that @sdatko mentions above and scp'ed head to root@remarkable:/usr/local/bin/.

peter@DESKTOP-31JUF3C:~/reStream$ ./reStream.sh
...
error: XDG_RUNTIME_DIR not set in the environment.
Could not initialize SDL - No available video device
(Did you set the DISPLAY variable?)

@ladnir What OS do you use? It seems like you have problem with your Desktop Environment... The problem is that ffmpeg does not know where to launch the video window. If you are on Windows, you may need Xming.

@ladnir
Copy link

ladnir commented Dec 1, 2020

aww, I was using WSL. Thanks!

@hirowatari
Copy link

Please ignore if this is not helpful. With the patch that sdatko mentioned, I was able to get this to work. Without lz4, latency was about 30 seconds. With the reMarkable 1, it was very fast.

I'm using version 2.4.1.30.

Thanks a lot for all the work on this.

@jkopanski
Copy link

With lz4 and using dd instead of head I am having a lot of latency. With head copied from coreutils I have smooth experience.

@mirodietiker
Copy link

Like jkopanski i was able to make this work with a 45sec delay with the adjustments from #31 (comment)

Adding / removing lz4 didn't make an improvement for me performance wise.

I copied head from debian armhf coreutils as well, but couldn't make it work at all. What did i miss here?

@murph
Copy link
Contributor

murph commented Dec 11, 2020

version 2.4.1.30
0) Have l4z

  1. Installed coreutils-head via remarkable_entware and opt install coreutils-head.
  2. Applied small patches to fix rotation and use correct 'head' binary:
diff --git a/reStream.sh b/reStream.sh
index 39a50e7..9227f91 100755
--- a/reStream.sh
+++ b/reStream.sh
@@ -121,7 +121,7 @@ case "$rm_version" in
 
         # Using dd with bs=1 is too slow, so we first carve out the pages our desired
         # bytes are located in, and then we trim the resulting data with what we need.
-        head_fb0="dd if=/proc/$pid/mem bs=$page_size skip=$window_start_blocks count=$window_length_blocks 2>/dev/null | tail -c+$window_offset | head -c $window_bytes"
+        head_fb0="dd if=/proc/$pid/mem bs=$page_size skip=$window_start_blocks count=$window_length_blocks 2>/dev/null | tail -c+$window_offset | /opt/bin/head -c $window_bytes"
         ;;
     *)
         echo "Unsupported reMarkable version: $rm_version."
@@ -179,8 +179,8 @@ video_filters=""
 # store extra ffmpeg arguments in $@
 set --
 
-# rotate 90 degrees if landscape=true
-$landscape && video_filters="$video_filters,transpose=1"
+# rotate 90˚ counter-clockwise for portrait mode
+! $landscape && video_filters="$video_filters,transpose=2"
  1. It works great, sub-second latency.

Is this sufficient for this project?

Some options for the binary:

  1. We could add a head binary to the repo
  2. We could have people use entware.
  3. We could build our own tiny binary that just does the dd and cut and head stuff. Would be a trivial program.

@Eeems
Copy link

Eeems commented Dec 11, 2020

Likely using entware would be the better solution longer term.

@rien
Copy link
Owner Author

rien commented Dec 12, 2020

Thank you all for your input and my apologies for the radio silence lately. I've started working on a small executable to do all the reMarkable-sided stuff (reading the framebuffer, compressing with lz4). Initial results on my rM1 are promising. I will finish this PR soon and hopefully we'll have a working reStream for rM2!

@Foxei
Copy link

Foxei commented Dec 27, 2020

@rien How is you progress?
I have a working prototype that archives around 12-15fps. Currently the visualization is done by a tweak version of the rMview python script but the image data is extracted with a custom C++ executable running on my rM2.

Untitled.mov

@aenario
Copy link

aenario commented Dec 28, 2020

Tested #31 (comment)
on v2.5.0.27 and everything work fine with sub-second latency.

Thanks everyone, awesome project !

@Foxei
Copy link

Foxei commented Dec 29, 2020

I published the code of my framebuffer dumping tool called reDump and updated the Code of reStream to work with my tool. Pull request #35 is related to this. 😄

In the future it might be feasible to adapt reDump to work with the rM1 as well so that those users can enjoy 12-14 FPS as well. Unfortunately, I do not own an rM1. 😢

@rien
Copy link
Owner Author

rien commented Dec 31, 2020

Hi everyone! I've adjusted the README and added a compiled version of the dumping script to the repository. Can someone with a reMarkable 2 test if it works and test if the orientation is correct by default it should be in landscape mode, with -p it should be in portrait mode. If this doesn't work, please try changing the transpose=1 option here to something else ffmpeg accepts (documentation: https://ffmpeg.org/ffmpeg-filters.html#transpose-1).

@rien rien force-pushed the feature/support-reMarkable-2 branch 2 times, most recently from c691eaa to cf6b105 Compare December 31, 2020 17:17
@danielebruneo
Copy link

danielebruneo commented Dec 31, 2020

Hi everyone! I've adjusted the README and added a compiled version of the dumping script to the repository. Can someone with a reMarkable 2 test if it works and test if the orientation is correct by default it should be in landscape mode, with -p it should be in portrait mode. If this doesn't work, please try changing the transpose=1 option here to something else ffmpeg accepts (documentation: https://ffmpeg.org/ffmpeg-filters.html#transpose-1).

Confirmed as working in reMarkable 2, orientation behaves correctly as well.
Great job!

@axelson
Copy link

axelson commented Dec 31, 2020

I confirmed this as working on my reMarkable 2 also (and with correct orientation). Thanks for the software! ❤️

@rien rien force-pushed the feature/support-reMarkable-2 branch from cf6b105 to 38ff447 Compare January 1, 2021 13:52
@rien rien merged commit c41b877 into master Jan 1, 2021
@pascalw
Copy link

pascalw commented Jan 1, 2021

I tried this on my RM and while FPS seems to be pretty good, I noticed that quite often after about 20s the updates completely stop, the view my computer just doesn't update anymore. Has anyone else seen this?

I'm on macOS. Here's some output:

[SSH] true
[SSH] cat /sys/devices/soc0/machine
[SSH] [ ! -f ~/restream ]
[SSH] ./restream
ffplay version 4.3.1 Copyright (c) 2003-2020 the FFmpeg developers
  built with Apple clang version 11.0.3 (clang-1103.0.32.62)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/4.3.1_1 --enable-shared --enable-pthreads --enable-version3 --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librtmp --enable-libspeex --enable-libsoxr --enable-videotoolbox --disable-libjack --disable-indev=jack
  libavutil      56. 51.100 / 56. 51.100
  libavcodec     58. 91.100 / 58. 91.100
  libavformat    58. 45.100 / 58. 45.100
  libavdevice    58. 10.100 / 58. 10.100
  libavfilter     7. 85.100 /  7. 85.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  7.100 /  5.  7.100
  libswresample   3.  7.100 /  3.  7.100
  libpostproc    55.  7.100 / 55.  7.100
Input #0, rawvideo, from 'pipe:':
  Duration: N/A, start: 0.000000, bitrate: 525657 kb/s
    Stream #0:0: Video: rawvideo (Y800 / 0x30303859), gray, 1872x1404, 525657 kb/s, 25 tbr, 25 tbn, 25 tbc
  48.00 M-V:  0.001 fd= 319 aq=    0KB vq=15400KB sq=    0B f=0/0

@rien
Copy link
Owner Author

rien commented Jan 2, 2021

@pascalw I haven't encountered this. Can you please open a new issue with some additional information:

  • Do you use the rM1 or rM2?
  • What is the output if you us the -m flag? This measures the throughput of the connection to the reMarkable. What happens if the video freezes? Does it drop to 0?

I do know this can happen is the reMarkable goes to sleep, but that only happens after a period of inactivity on the reMarkable.

@rien rien deleted the feature/support-reMarkable-2 branch January 29, 2021 12:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Does not work on reMarkable 2