Chrome 104 现支持 HEVC 硬解
刚刚发布的 Chrome 104 支持了 HEVC 硬解,但目前需要手动开启,在启动时添加
该功能由字节跳动开发,并提交给 Chromium,使用的是操作系统解码能力(Windows D3D11,macOS VideoToolbox),因此不需要交专利费。由于 Windows 7 以下系统仅支持 VDA Decoder,因此不支持 HEVC 硬解。
此外,部分网站通过浏览器 UA 检查是否支持 HEVC,如 Bilibili,因此除添加上述参数外,还需要修改 UA 为先前已经支持的其它浏览器,如 Safari。
ref:
https://v2ex.com/t/870362
https://github.com/StaZhu/enable-chromium-hevc-hardware-decoding
刚刚发布的 Chrome 104 支持了 HEVC 硬解,但目前需要手动开启,在启动时添加
--args --enable-features=PlatformHEVCDecoderSupport 参数。可以使用 https://h265.webmfiles.org/embed-h265-video.php 测试是否成功。该功能由字节跳动开发,并提交给 Chromium,使用的是操作系统解码能力(Windows D3D11,macOS VideoToolbox),因此不需要交专利费。由于 Windows 7 以下系统仅支持 VDA Decoder,因此不支持 HEVC 硬解。
此外,部分网站通过浏览器 UA 检查是否支持 HEVC,如 Bilibili,因此除添加上述参数外,还需要修改 UA 为先前已经支持的其它浏览器,如 Safari。
ref:
https://v2ex.com/t/870362
https://github.com/StaZhu/enable-chromium-hevc-hardware-decoding
👍1
在 Go 中复用一个 io.Reader
io.Reader 表示一个 stream,而 stream 只能被读一次。因此有两种复用方式:
一、边读边缓冲到 Buffer
二、使用 Pipe,本质是个 ReaderWriter
由于 Pipe 是无 internal buffering 的,因此需要使用两个 goroutine 并行读写。对于多个 Pipe 可以:
#experience
io.Reader 表示一个 stream,而 stream 只能被读一次。因此有两种复用方式:
一、边读边缓冲到 Buffer
var (
r = strings.NewReader("hello world")
buf = new(bytes.Buffer)
)
foo(io.TeeReader(r, buf))
bar(buf)
二、使用 Pipe,本质是个 ReaderWriter
var (
r = strings.NewReader("hello world")
pr, pw = io.Pipe()
)
go foo(io.TeeReader(r, pw))
go bar(pr)由于 Pipe 是无 internal buffering 的,因此需要使用两个 goroutine 并行读写。对于多个 Pipe 可以:
var (
r = strings.NewReader("hello world")
pr1, pw1 = io.Pipe()
pr2, pw2 = io.Pipe()
pr3, pw3 = io.Pipe()
)
go foo(pr1)
go bar(pr2)
go baz(pr3)
io.Copy(io.MultiWriter(pw1, pw2, pw3), r)#experience
Transferable objects in JavaScript
像 Buffer、Stream、Bitmap 这类对象,都做成了 Transferable,它们可以安全地在两个线程间转移,这是一种 zero-copy 操作。
一、在 Worker 之间转移
二、在 clone 时转移
#learning
像 Buffer、Stream、Bitmap 这类对象,都做成了 Transferable,它们可以安全地在两个线程间转移,这是一种 zero-copy 操作。
一、在 Worker 之间转移
const u8 = new Uint8Array(1<<10)
const worker = new Worker(URL.createObjectURL(new Blob()))
u8.byteLength // 1024
worker.postMessage(u8, [u8.buffer])
u8.byteLength // 0
二、在 clone 时转移
const u8 = new Uint8Array(1<<10)
u8.byteLength // 1024
const trans = structuredClone(u8, {transfer: [u8.buffer]});
u8.byteLength // 0
trans.byteLength // 1024#learning
HTTP/2 可能没 HTTP/1.1 快
HTTP/2 最大变化是引入单独的成帧层,支持了多路复用,允许交错接收多个资源。如
但这种交错对浏览器来说,不一定是好事,因为浏览器必须完整接收整个文件,才能开始执行它,
其它方式呢,如
将多个文件相互交错,还更容易受到丢包影响,而被阻塞。丢包由网络路径中的路由缓冲区暂时溢出导致,一般发生在相邻几个流之间,
结果就是,对浏览器而言,某些情况 HTTP/1.1 会更快,即使存在 HOL blocking 问题(HTTP/2 也仍存在 TCP 层的 HOL blocking),但 HTTP/1.1 将这些请求分摊到 6 个连接,可以很大程度避免它。
与 HTTP/2 的单一连接不同,HTTP/1.1 是真正意义上的并行请求,每个连接都有自己的拥塞控制,对于 HTTP/2 即使是单个数据包丢失,也会导致整体变慢,而 HTTP/1.1 其中一个连接丢包,只会减慢该连接的速度。同时 6 个连接的初始拥塞窗口也会更大 6*14K=84KB,而非单一连接的 14KB。
#learning
HTTP/2 最大变化是引入单独的成帧层,支持了多路复用,允许交错接收多个资源。如
a.js 与 b.css,HTTP/1.1 只能顺序的 aaaabbb 接收,而 HTTP/2 允许 abababa。但这种交错对浏览器来说,不一定是好事,因为浏览器必须完整接收整个文件,才能开始执行它,
abababa 意味着直到最后才能开始执行 a.js,直到最后第二个才能开始执行 b.css。其它方式呢,如
aaababb,确实可以,但面对一众突发请求,很难有效控制,HTTP/2 确实出现过流优先级系统,但在 HTTP/3 中被彻底删除,当然很大一部分归因于 QUIC 流之间无序。将多个文件相互交错,还更容易受到丢包影响,而被阻塞。丢包由网络路径中的路由缓冲区暂时溢出导致,一般发生在相邻几个流之间,
aXXXbbb 和 aXXXaba(X 表示丢失),当然前者更好,因为 b.css 未受到丢包影响。结果就是,对浏览器而言,某些情况 HTTP/1.1 会更快,即使存在 HOL blocking 问题(HTTP/2 也仍存在 TCP 层的 HOL blocking),但 HTTP/1.1 将这些请求分摊到 6 个连接,可以很大程度避免它。
与 HTTP/2 的单一连接不同,HTTP/1.1 是真正意义上的并行请求,每个连接都有自己的拥塞控制,对于 HTTP/2 即使是单个数据包丢失,也会导致整体变慢,而 HTTP/1.1 其中一个连接丢包,只会减慢该连接的速度。同时 6 个连接的初始拥塞窗口也会更大 6*14K=84KB,而非单一连接的 14KB。
#learning
👍5
Source map 原理
Source map 本身是一个 JSON,如
如对
首先
之后是
最后的
如果得到 5 个数,则在上面 4 个基础上,再追加一个 name index,对应于 JSON 中的
#learning
Source map 本身是一个 JSON,如
{"version":3, "mappings":";;;MADF,cAtBF;mBAAkB", "sources":["~/code/Cat.tsx"], ...}mappings 是 source map 关键,它记录了源码与转换后代码的映射关系。每个 ; 表示新的一行,因此其后的 MADF 在第 4 行,表示该行的列映射关系,多个使用 , 隔开,它的每个字符基于 Base64 编码,解码后正好是 6 bits。如对
cAtBF 解码,c:011100 A:000000 t:101101 B:000001 F:000101,解码后的数据以 VLQ(variable-length quantity) 形式表示,每组的最高位是 continuation(C),表示是否连续,最低位是 sign(S),1 为负。首先
c:011100,C、S 都是 0,表示“非连续正数”,因此可以直接拿中间的位 1110=14。其后 A:000000 按照同样方式,0000=0。之后是
t:101101,C、S 均为 1,表示“连续负数”,“连续”指其后的 B:000001 也是它的一部分,为了更加充分利用空间,后面每组都省去了 S,因此最终是 t:0110(除去 C、S),B:00001(除去 C),连起来 00001 0110=22,补上符号 -22。最后的
F:000101,C=0,S=1,表示“非连续负数”,因此 0010=2,补上符号后 -2。最终 cAtBF 得到 [14,0,-22,-2] 四个数,分别表示 output column、input filename index、input line、input column,所有数字都是相对于当前的偏移量,input filename index 对应于上面 JSON 中的 sources。如果得到 5 个数,则在上面 4 个基础上,再追加一个 name index,对应于 JSON 中的
names(未列出)。如果只有 1 个数,那么仅表示 output column,无其它更多信息。#learning
🌸
与 Tab 缩进和解 很长一段时间我都在坚持“2-spaces”缩进,但直到今天我才意识到,这种风格的要点,不在“Space”,因为即使是“Tab”,只要将 size 调整为 2 就行了。 这算是长久以来我对“Tab”的和解,纠结 Spaces or Tabs 是没意义的,现在看来,我只是在纠结缩进的宽度。 在下个项目,我将尝试使用 1-tab 缩进,并设置 tab 的 size 为 2。 这样做有 2 个显而易见的好处:更少的字符占更少的空间;其他人可以根据自身偏好设置 tab 的 size。 …
GitHub 的 Tab 支持真是差强人意
- GitHub Actions 的 yaml 只能用 Space
- Markdown 会把 Tab 渲染成 8-width,即使用户设置了 Tab size preference,也不会遵照
在看到 GitHub 改善之前,我决定 Markdown 先用 space 作为替代。
- GitHub Actions 的 yaml 只能用 Space
- Markdown 会把 Tab 渲染成 8-width,即使用户设置了 Tab size preference,也不会遵照
在看到 GitHub 改善之前,我决定 Markdown 先用 space 作为替代。
推荐一个 MS Edge theme
https://microsoftedge.microsoft.com/addons/detail/pride/gpahbdchbfofplfeaeipcphhbdhdpnae
非常漂亮!inspired by the many flags of the LGBTQI+ community
https://microsoftedge.microsoft.com/addons/detail/pride/gpahbdchbfofplfeaeipcphhbdhdpnae
非常漂亮!inspired by the many flags of the LGBTQI+ community