Browser git · main
Minimal browser in C (mini and big variant)
C 96.1% Markdown 3.7%git clone https://git.christianimmanuel.de/web-tools/Browser.gitwget https://git.christianimmanuel.de/web-tools/Browser/archive/Browser.tar.gzAdd streaming debug option
Makefile | 2 +- README.md | 18 ++++++++++++++++-- browser-big.c | 34 ++++++++++++++++++++++++++++------ 3 files changed, 45 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 674ab6a..d48c593 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ CC ?= gcc CFLAGS ?= -O2 -Wall -Wextra -rdynamic PREFIX ?= /usr -VERSION := 4.39.0 +VERSION := 4.40.0 SOURCES := browser_core.c browser_core.h browser-mini.c browser-big.c Makefile BUILD_ID := $(shell cat $(SOURCES) 2>/dev/null | md5sum | cut -c1-7) diff --git a/README.md b/README.md index 659cc7e..6328076 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ make # build both make install # into /usr/bin (PREFIX=... to change) make uninstall make clean -make version # 4.39.0 (build …), md5 of the sources +make version # 4.40.0 (build …), md5 of the sources ``` ## Usage @@ -178,7 +178,8 @@ browser-big URL --rtc-trace 2>&1 | tee /tmp/bb.log | `sdp` | Each description, codecs as `payload-type name` | | `ssrc-real`, `ssrc-ws`, `pt-fixed` | The server got the real SSRC and payload type | | `rtc-stats` | Every 3 s: `out-*` sent, `far-*` server report, `in-*` received | -| `video-state` | Each `<video>`: size, frames shown | +| `video-state` | Each `<video>`: size, `frames` shown, `dframes` since last tick | +| `stuck: true` | On `rtc-stats` or `video-state`: counters stopped moving | | `video-audio-split` | A silent-audio stream shown video-only | | `codec-mismatch` | We encode something the far end did not agree to | @@ -186,6 +187,19 @@ browser-big URL --rtc-trace 2>&1 | tee /tmp/bb.log - `in-video.dec` climbing, `video-state.frames` at 0: decoded, never shown. - `in-video.fir` climbing, `keys` still: no keyframe arrives. +**A frozen picture, audio still playing.** Repeated samples are not +printed, so a freeze stops the log instead of filling it. One line is +let through when the counters stop and one when they move again: + +- `video-state` `stuck: true`, `dframes: 0`, `in-video.dec` climbing: + frames decode, the element never presents them. Our bug. +- `in-video.bytes` climbing, `dec` flat: packets arrive, the decoder + does not advance. Usually codec or keyframe. +- `rtc-stats` `stuck: true`: nothing arrives any more. The page or the + server stopped sending. + +The timestamp on the `stuck` line is when the picture froze. + **Without a server:** `browser-big https://webrtc.github.io/samples/src/content/peerconnection/pc1/ --rtc-trace`. If that works, WebKit's WebRTC is fine and the problem is site-specific. diff --git a/browser-big.c b/browser-big.c index 937e034..6e5c342 100644 --- a/browser-big.c +++ b/browser-big.c @@ -791,9 +791,21 @@ static const char *SHIM_JS = " box:Math.round(r.width)+'x'+Math.round(r.height)," " shown:st.display!=='none'&&st.visibility!=='hidden'&&+st.opacity>0," " track:vt.length?(vt[0].id.slice(0,8)+' '+vt[0].readyState+(vt[0].muted?'/muted':'')):'none'};" -" var k=JSON.stringify(o);" -" if(vlast.get(v)===k)continue;" -" vlast.set(v,k);post(o);" +/* + * The repeat filter is what makes a freeze invisible: when the picture + * stops, every counter stops with it, this sample is identical to the + * last one and nothing is printed at all - so silence means either + * frozen or page gone, and the two cannot be told apart. Compare the + * frame counter on its own and let one line through on the transition + * into stuck and one on the way out. A frozen element then says so + * once, with dframes:0, instead of going quiet. + */ +" var k=JSON.stringify(o),p=vlast.get(v)||{};" +" o.dframes=(o.frames>=0&&p.frames>=0)?o.frames-p.frames:-1;" +" o.stuck=(o.dframes===0&&o.ready>=2&&!o.paused);" +" var rep=(k!==p.k)||(!!o.stuck!==!!p.stuck);" +" vlast.set(v,{k:k,frames:o.frames,stuck:o.stuck});" +" if(rep)post(o);" " }" " },3000);" " try{var SD=Object.getOwnPropertyDescriptor(HTMLMediaElement.prototype,'srcObject');" @@ -859,9 +871,19 @@ static const char *SHIM_JS = " o['rtrack-'+rv.track.kind]={id:rv.track.id.slice(0,8),state:rv.track.readyState,muted:!!rv.track.muted};" " });}catch(e){}" " if(!any)return;" -" var key=JSON.stringify(o);" -" if(key===last[i])return;" /* nothing moved, do not repeat */ -" last[i]=key;post(o);" +/* + * Same on the receive side. Hold the three counters that have to move + * while video is arriving and being decoded, and report the tick they + * stop on: bytes still climbing with dec flat is "arriving, not + * decoding"; both flat is "nothing arriving". Without this the stats + * simply stop printing at the moment they get interesting. + */ +" var key=JSON.stringify(o),p=last[i]||{},iv=o['in-video'];" +" var rx=iv?(iv.bytes+'/'+iv.pkts+'/'+iv.dec):null;" +" o.stuck=(rx!==null&&rx===p.rx);" +" var rep=(key!==p.key)||(!!o.stuck!==!!p.stuck);" +" last[i]={key:key,rx:rx,stuck:o.stuck};" +" if(rep)post(o);" " }).catch(function(e){" " if(!pc.__bbStatsErr){pc.__bbStatsErr=1;" " post({ev:'rtc-stats-error',pc:i,message:String((e&&e.message)||e)});}"