3 पॉइंट द्वारा GN⁺ 2023-08-21 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • वीडियो कॉन्फ्रेंस के दौरान reMarkable 2 स्केच शेयर करने वाला टूल अब लैपटॉप की local service के बिना खुलने लगा है, जिससे presenter सिर्फ browser से तुरंत streaming शुरू कर सकता है
  • नया architecture reMarkable के अंदरूनी HTTP server और browser के JavaScript client तक सरल हो गया है, जो raw image लेकर उसे canvas पर draw करता है
  • WebSocket वाला विकल्प काम करता था, लेकिन iOS की समस्याएं और server overhead बचे रहे, इसलिए इसे raw stream तरीके में व्यवस्थित किया गया: fixed-resolution images को http.ResponseWriter में लगातार लिखना और fetch stream से पढ़ना
  • 1872x1404 raw frame करीब 2.5MB का होता है, इसलिए firmware 3.3 के बाद 16 color values को uint4 में pack करके इसे 50% घटाया गया और RLE से average 200KB transfer तक कम किया गया
  • /dev/input/event* को monitor कर input न होने पर नए frames भेजना रोक दिया जाता है; connected clients होने पर भी CPU usage 0 तक गिर जाता है और लिखते समय करीब 10% CPU पर चलता है

पुराने टूल में असुविधा क्यों थी

  • 2021 में बनाया गया reMarkable streaming tool वीडियो कॉन्फ्रेंस के दौरान sketches शेयर करने के लिए इस्तेमाल होता था, और सिर्फ browser tab शेयर करना पड़ता था, इसलिए presentation content पर focus करना आसान था
  • पुराना implementation तीन components में बंटा था
    • Server: reMarkable device पर चलता है और current screen की raw image expose करता है
    • Client: laptop पर server की raw image लाता है और उसे browser द्वारा देखे जा सकने वाले format में process करता है
    • Renderer: browser या VLC की तरह HTTP MJPEG stream पढ़कर screen पर दिखाता है
  • device CPU usage घटाने के लिए server सिर्फ client connected होने पर image extract करता था, और communication के लिए gRPC इस्तेमाल होता था
  • laptop client बार-बार images लाता, उन्हें JPEG में encode करता, और MJPEG stream को HTTP service के रूप में provide करता था
  • presentation environment में reMarkable address, client execution permissions, और renderer को पता होना चाहिए ऐसा client IP जैसे network configuration बोझ बन जाते थे

सिर्फ browser से खुलने वाला नया architecture

  • नया लक्ष्य यह था कि किसी भी browser में केवल reMarkable address डालने पर stream access हो जाए
  • अलग laptop client हटाकर, reMarkable के server component के अंदर HTTP server डालने वाला structure अपनाया गया
  • browser में चलने वाले client के लिए JavaScript या WASM form चाहिए था
    • शुरुआत में Go experience का फायदा उठाने के लिए WASM compilation पर विचार किया गया, लेकिन काफी modifications मांगने वाली limitations के कारण उसे छोड़ दिया गया
    • client का दूसरा version आखिरकार JavaScript में लिखा गया
  • JavaScript code snippets और explanations पाने की प्रक्रिया में ChatGPT का इस्तेमाल किया गया, लेकिन desired solution की direction खुद तय की गई

canvas rendering तरीका

  • MJPEG stream से हटने के लिए browser की image manipulation primitive canvas का इस्तेमाल किया गया
  • reMarkable से मिली raw image को Uint8Array के रूप में पढ़ा जाता है, ImageData के RGBA pixel data में वही value R/G/B में डाली जाती है, और alpha value 255 set करके display किया जाता है
  • responsive display, rotation, और colorization की संभावना के लिए fixed size वाले fixedCanvas को hidden state में रखा जाता है
  • display canvas पर drawImage से hidden canvas की सामग्री copy की जाती है
  • browser window size बदलने पर container size और 1872/1404 ratio के आधार पर display canvas की width और height adjust की जाती है

WebSocket छोड़कर raw stream पर switch

  • gRPC web development में आम choice नहीं है, इसलिए पहले replacement implementation में communication और encapsulation के साधन के रूप में WebSocket का इस्तेमाल किया गया
  • WebSocket messages में raw image होती है, और browser client हर message मिलने पर canvas update करता है ताकि यह streaming जैसा दिखे
  • इस तरीके से server-side message भेजने की frequency control करके reMarkable की memory और CPU load manage की जा सकती थी
  • लेकिन iOS पर problems थीं, और server-side WebSocket implementation का overhead भी control करना मुश्किल था
  • final structure में encapsulation हटाकर fixed image size का उपयोग करते हुए raw image को सीधे network पर भेजा गया
    • Go server images को बार-बार http.ResponseWriter में Write करता है
    • browser client fetch('/stream') के ReadableStream को पढ़ता है और incoming chunks को canvas data में reflect करता है

transfer size optimization

  • reMarkable 2 की raw image 1872x1404 resolution पर करीब 2.5MB होती है, और यह data हर frame में transfer होना होता है
  • firmware 3.3 के बाद reMarkable की 16 color values को uint8 की जगह uint4 array के रूप में represent किया जा सकता है
    • Go और JavaScript में native uint4 type नहीं है
    • workaround के तौर पर दो pixel values को एक uint8 byte में store किया गया
    • Go में दो uint4 values को upper 4 bits और lower 4 bits में pack किया जाता है, और JavaScript में इन्हें फिर unpack किया जाता है
    • यह representation data size को 50% घटा सकता है
  • extra compression के लिए Run Length Encoding (RLE) इस्तेमाल किया गया
    • RLE एक simple algorithm है जो एक जैसे pixel values के लगातार आने की count और value साथ में भेजता है
    • example 0 0 0 0 0 0 1 1 1 0 0 0 0 को 6 0 3 1 4 0 के रूप में represent किया जाता है
  • count value अधिकतम 1872*1404 तक बढ़ सकती है, इसलिए uint64 जैसा type चाहिए हो सकता है, और कुछ मामलों में compressed result original से बड़ा होने का risk है
  • इससे बचने के लिए count length को 15 तक limit किया गया और count व pixel value को एक byte में रखने वाला balance point चुना गया
  • RLE implementation Go के io.Writer जैसा काम करता है, इसलिए reusable है; जरूरत हो तो RLE दो बार भी apply किया जा सकता है, लेकिन फिलहाल इसकी जरूरत नहीं थी
  • packing और RLE के बाद average transfer size करीब 200KB है

बदलाव होने पर ही frame भेजना

  • अंतिम optimization यह है कि नया frame सिर्फ screen बदलने पर भेजा जाए
  • change detection को checksum से compute करने पर CPU load बढ़ सकता है
  • reMarkable Linux-based है, इसलिए pen या touch input /dev/input/event* के माध्यम से deliver होता है
  • एक goroutine इन input events को monitor करता है और केवल जरूरत पड़ने पर image भेजता है
  • events न होने पर, client connected रहने पर भी CPU usage 0 तक गिर जाता है
  • writing के दौरान CPU usage करीब 10% स्तर पर रहता है

firmware changes और maintenance burden

  • यह application hacking पर आधारित है, और मुख्य challenge images लाने वाले interface तथा client/renderer को effectively अलग करना है
  • पिछले implementation में protobuf definitions के जरिए client और server पूरी तरह अलग थे
  • reMarkable 3.3 firmware ने tool को तोड़ दिया था, और संबंधित जानकारी GitHub issue 36 में है
    • उस समय fix ने केवल client component को प्रभावित किया
  • firmware 3.6 भी GitHub issue 58 के अनुसार breaking change ला सकता है
    • इस मामले में अधिक व्यापक modifications की जरूरत हो सकती है
    • हालांकि client server में integrated self-contained structure है, इसलिए device update ज्यादा simple हो सकता है
  • application और source code github.com/owulveryck/goMarkableStream पर उपलब्ध हैं

1 टिप्पणियां

 
GN⁺ 2023-08-21
Hacker News की राय
  • 2021 के उस टूल को फिर से सुधारा और जारी किया गया, जो reMarkable टैबलेट की स्क्रीन को लैपटॉप पर स्ट्रीम करता था, और नए लेख में architecture, components और user experience को बेहतर बनाने की प्रक्रिया को गहराई से कवर किया गया
    Product manager के नज़रिए से देखा गया कि यूज़र कैसा महसूस करता है, activation process को सरल बनाया गया, इसे local service के बिना चलने लायक बनाया गया और network usage भी optimize किया गया

    • शानदार project जैसा लगता है। Ctrl-C के बाद ./goMarkableStream से restart करने पर कुछ हद तक चला, लेकिन अब भी waiting for reMarkable screen अक्सर दिखता है और service unstable है
      reMarkable2 को 3.5.2.1807 पर update करने के बाद install किया, लेकिन laptop, sheet और book पर drawing करने पर भी कोई response नहीं था, और कभी-कभी read /dev/input/event2: file already closed, read /dev/input/event1: file already closed जैसे logs दिखे
      https://192.168.8.143:2001/ और https://10.11.99.1:2001/ दोनों HTML और canvas serve करते हैं, और Chrome, Firefox, Brave में भी कोशिश की
      हर stream पर एक browser, एक IP की limit जैसी लगती है, लेकिन कोई भी address और browser इस्तेमाल करने पर भी कभी-कभी waiting for reMarkable screen दिखता है। nohup ./goMarkableStream & के बाद PuTTY बंद करके client restart किया तो सभी browsers उसी state में आ गए, और https://10.11.99.1:2001/stream देखने पर too many requests return होता है। जानना चाहता हूँ कि stream को कैसे restart करना चाहिए
    • सोच रहा हूँ कि क्या इसे USB connection से भी implement किया जा सकता है
  • विकल्प के तौर पर SuperNote को बहुत संतुष्टि के साथ इस्तेमाल कर रहा हूँ। Screen mirroring संभव है, इसलिए meetings के दौरान जल्दी diagram बनाना बहुत अच्छा रहता है
    कमी यह है कि SuperNote एक छोटा web server चलाता है और Firefox से connect करने का तरीका अपनाता है, इसलिए laptop और SuperNote को same network पर होना पड़ता है। Home office में समस्या नहीं है, लेकिन company policy के कारण block हो सकता है
    RM2 हो या SuperNote, pen और paper पर ideas लिखना पसंद करने वालों के लिए ये बेहतरीन tools हैं, apps या text documents से इनका feel काफी अलग है, और notes में doodle भी कर सकते हैं
    [0]: https://supernote.com/

    • Onyx Boox Note भी अच्छी तरह काम करता है, और 5 साल से अधिक बीतने के बाद भी updates दे रहा है
      हालांकि खरीदते समय GPL violation को स्वीकार करना पड़ेगा। पूरी तरह Android-based होने के बावजूद operating system source release नहीं करता
    • e-book reader और note-taking के लिए e-ink tablet ढूँढ रहा था, recommendation मददगार रही। Remarkable 2 और Boox के बीच सोच रहा था, और SuperNote का software update experience कैसा है यह जानना चाहता हूँ
      चिंता है कि कहीं ऐसा device न खरीद बैठूँ जिसे अगले 3–5 सालों तक feature updates या कम-से-कम security updates भी न मिलें
    • याद के मुताबिक SuperNote अपने साथ distribute किए जाने वाले software के GPL का पालन नहीं करता था, जानना चाहता हूँ कि क्या उसका stance बदला है
    • अभी तक “same network पर होना पड़े” वाली समस्या नहीं झेली है, लेकिन native Ngrok feature जोड़ना कुछ मिनटों का आसान काम लगता है। तब internet के जरिए streaming हो सकेगी
    • SuperNote का writing feel RM2 की तुलना में कैसा है, यह जानना चाहता हूँ
  • HTML canvas rendering यहाँ बताए गए तरीके की तरह typed arrays इस्तेमाल करने पर तेज़ हो सकती है: https://hacks.mozilla.org/2011/12/faster-canvas-pixel-manipu...

    • धन्यवाद, एक बार देखूँगा
  • ऐसी पोस्ट ही वह content है जिसे मैं यहाँ देखना चाहता हूँ। अच्छा लगा कि ChatGPT ने ऐसे domain की समस्या सीखने और हल करने में कैसे मदद की, जिसके बारे में वह ज्यादा नहीं जानता था, और “मैं developer था और ChatGPT coder था” वाली बात से सहमत हूँ
    यह बात भी सही है कि simplicity असल में complex होती है

  • JPEG चुनने की वजह शायद यह रही होगी कि MJPEG में बदलना आसान है, और supporting side को दे दें तो decoding लगभग मुफ्त में handle हो जाती है। हालांकि यह reMarkable CPU पर बड़ा बोझ डालने वाला factor हो सकता है
    JPEG photos के लिए ज्यादा suitable है, लेकिन reMarkable screen illustration जैसी है, ऊपर से black-and-white range में है। PNG जैसे दूसरे सामान्य image format या सिर्फ simple RLE compression इस्तेमाल करने पर भी CPU load कम हो सकता है

    • कड़ाई से कहें तो reMarkable monochrome नहीं बल्कि grayscale है, और याद के मुताबिक 16 levels of gray support करता है। companion app में pen नीला/लाल और highlighter पीला/हरा दिखने जैसी color ink भी है
      और proprietary file format bitmap नहीं, बल्कि handwriting input based है
    • शुरुआत में JPEG चुनने की वजह सही है। हालांकि इसी वजह से client/server architecture चुना, और encoding tablet पर नहीं बल्कि client यानी laptop पर की गई
      Profiling करने पर पता चला कि CPU का ज्यादातर हिस्सा wire के जरिए data transfer में लग रहा था, इसलिए compression जोड़ा। अब CPU usage कम है
  • क्या आपने सिर्फ framebuffer के बदले हुए areas भेजने का तरीका consider किया है? इससे data transfer rate काफी घट सकता है: https://github.com/pl-semiotics/mxc_epdc_fb_damage
    rM VNC project भी ऐसा करता है, लेकिन मुझे इस app का user experience ज्यादा पसंद है क्योंकि client-side software की जरूरत नहीं होती

    • उस approach की समस्या यह है कि device पर कुछ हद तक analysis चाहिए, और मैं code को जितना हो सके less invasive रखना चाहता हूँ। देखूँगा कि इसे सस्ते में करने का कोई तरीका है या नहीं
  • वाकई शानदार है और मैं ReMarkable 2 को पसंद करना चाहता हूँ, लेकिन इसे असुरक्षित device मानने की वजह से यह आसान नहीं है: https://support.remarkable.com/s/article/Does-reMarkable-off...

    • लिंक का मतलब है कि इस device में केवल उतनी ही physical security है जितनी उस कागज में होती है जिसे यह replace करना चाहता है। यानी अगर कोई device तक पहुँच जाए, तो वह पढ़ सकता है
      यह उन known software vulnerabilities की बात नहीं है जो आमतौर पर network से जुड़े insecure device के बारे में सोचते समय दिमाग में आती हैं
    • अनौपचारिक रूप से gocryptfs-based home directory encryption संभव है: https://github.com/RedTeamPentesting/remarkable-encryption
    • software भी फिलहाल काफी सीमित है। अफसोस है कि officially device पर marketplace या extensions इस्तेमाल करने की सुविधा नहीं दी जाती
    • क्या कोई e-book reader है जो full-disk encryption देता हो?
  • “शुरुआत में client को WASM में compile करने की कोशिश की थी। Go development experience का फायदा उठा सकते थे, इसलिए यह promising लग रहा था, लेकिन कई limitations सामने आईं जिनमें काफी बदलावों की जरूरत थी” — इस हिस्से के बारे में और पढ़ना चाहूँगा

    • मुख्य समस्या gRPC library थी, और मौजूदा support बहुत सीमित था। साथ ही Go में JPEG compression धीमा है और CPU बहुत ज्यादा इस्तेमाल करता है
      भले ही MJPEG stream बना भी लेते, उसे display कैसे करना है यह भी समस्या थी। canvas तरीका सोचा था, लेकिन WASM और JS के बीच बड़े copies किए बिना canvas backend तक पहुँचना मुश्किल था, और size भी 2.5MB था
      आखिरकार लगा कि WASM पर निर्भर रहने से image rotation जैसे कई basic image operations खुद implement करने पड़ेंगे, जो JS में native रूप से accessible हैं
  • जानना चाहता हूँ कि यह tool built-in streaming, यानी screen sharing feature से कैसे अलग है

    • built-in feature इस्तेमाल करने के लिए desktop app install करनी पड़ती है, और जहाँ तक पता है Linux version नहीं है
      https://support.remarkable.com/s/article/Screen-Share
      लेख का solution सिर्फ एक सक्षम browser होने पर Linux पर भी काम करता दिखता है
    • सबसे बड़ा फर्क यह है कि अब client installation की जरूरत नहीं है। browser में बस reMarkable address डालें और content देख सकते हैं
    • मुझे लगा था यह feature पहले से ही उपलब्ध है। screen sharing काफी ठीक है, और मैं इसे live streaming के लिए भी इस्तेमाल कर रहा हूँ
  • मुझे reMarkable पसंद है, लेकिन काश वे उस subscription के बजाय, जिसके लिए मैं आगे भी पैसे देने का इरादा नहीं रखता, ऐसी streaming features पर ध्यान दें