Saturday 28 November 2020

视频用 N 倍速看对 fps 的影响

如果播放视频时加速,对 fps 有何影响?如何预测会 dropped 多少 frames?

mpv 确实可以 speed up 后如果仍可以满足 monitor 的 refresh rate Hz 就可以不 drop frames。

不过 165 Hz 要求 gpu+cpu 很高否则也是有问题(不然 multitasking 容易 drop frame)。

而且 144 Hz 或 120 Hz 都能被常见的 24 fps 完整除 (120 Hz 能被 youtube 常见的 30 fps 除)

,只有 165 Hz 怪怪的不能整除 (https://www.svp-team.com/forum/viewtopic.php?pid=63214#p63214)。



做个小实验验证一下:






(纠正: mpv 的新选项用法是 -x=value 和 --y 两种, 不再是上面的 --x=value)

如截图,mpv 播放不同 fps 不同速度的小实验,我 Monitor 59.99 Hz:


[1] 30 fps x 2 倍速 = 60 fps,由于我 Monitor 59.99 Hz,不会 drop 任何 frame, ( ( (30 video fps * 30 秒) / (30 秒 / 2.0 speed) ) - 60 Hz) * (30 秒 / 2.0 speed) = ~0 frame。

[2] 120 fps 普通速,由于 120 超出 Monitor 能力 一倍,30 秒后会 dropped ( ( (120 video fps * 30 秒) / (30 秒 / 1.0 speed) ) - 60 Hz) * (30 秒 / 1.0 speed) = ~1800 frames (即总数的一半)

[3] 60 fps x 2 倍速 = 120 fps,由于 120 超出 Monitor 能力 一倍,30 秒后会 dropped (( (60 video fps * 30 秒) / (30 秒 / 2.0 speed) ) - 60 Hz) * (30 秒 / 2.0 speed) = ~900 frames (即总数的一半)

[4] 60 fps x 1.5 倍速,30 秒后会 dropped ( ( (60*30) / (30 /1.5) ) - 60 ) * (30 /1.5)  = ~600 frames (即总数的三分之一)

预测 dropped 多少 frame 只能大概 ~,因为一: Hz 并非整数。二:时间和速度不担保 round 得精准,也因此我使用 --speed=1.99 而不是 2。 三:其它因素譬如 cpu/gpu/multitasking 可以随机 drop。 四:不清楚囧除非研究 mpv 源码 🌚

至于 YouTube player 我觉得 "Stats for Nerds" 的 frame dropped 信不过 🌚 (https://bugzilla.mozilla.org/show_bug.cgi?id=1578042)。我手机 app 60 Hz play 60 fps x 2 speed 却几乎没有任何 drop。

相关问题: https://video.stackexchange.com/questions/15857/what-happens-to-frames-when-you-speed-up-a-video-clip


Thursday 12 November 2020

MySejahtera bug

MySejahtera 的隐私 bug,可以查看其它店的人流, 甚至更新资料。

有些非 Master branch 而看不到更新资料的页面,能通过 email 得知 `Hi contact_name`(有些填手机号)。

由于 bug 会被滥用,我就不公开方法了。(更新: 已被修复)




MySejahtera 没网络 check-in

 实验:

MySejahtera app 在没网络下,扫描二维码后, 政府还能不能收到该 check-in?
 
实验结果:
 
每次点击 "close" 按钮后的十秒, 都会调用 js 的 checkAndSync() 函数, 检查 checkInQue 数据库表之前有没有失败的请求 queue,有的话就(等多一秒)一个个调用 syncCheckIn() 函数尝试 "/clockin" API 终点请求上传。"Clear storage" 会清除该 queue,"Clear Cache" 则不会。
 
实验总结:
 
请确保点击 "close" 按钮后的十一秒后有网络,才能上传之前没网络的 check-in 给政府。即使你扫描新的二维码, 是不会包括之前没网络所累积的 check-in, 必须点击 "close" 按钮等十一秒。十一秒是开始上传的时间,上传全部需时十一秒以上。










我也花了很长时间在 smali 在 enable remote debugging 函数附近加 Log.d()。

实验目标反而是次要,主要目标是顺便学习 smali, 否则要直接在 smali 加 (或删 if/else) enable remote debugging 有何难度?

加 Log.d 原本并不难,可是 `smali/org/apache/cordova/engine/SystemWebViewEngine.smali` 的 `initWebViewSettings()` 恰好是 `.locals 15`。

纯粹改成 16 而不去考虑改其它东西是不大行的,常遇到 error 却不理解为什么不 work。

着手找了 .locals 15 的 java 代码再加大量的代码,终于了解原理和 .locals 的规则。

我之前读的是这个教程,这个教程没提 .locals 15 和 { vx .. vy} 的情况:

首先, .registers 是真的跟 .locals 一样,比 .locals 纯粹多了函数 params 数目, 所以不需要奢望 .registers 可以做到 .locals 做不到的东西。

然后,v17 (.locals v16 + this p0) 意思是可以使用新的 v16, v16 可以想象为 temporary/virtual-variable(我这么形容的), 不实际存在, 但是想象它存在 非-registers 的地方。

要用 v16?  大于 v15 不能直接使用,但有两种使用方式:
【方法一】 先 move-object/from16 v4, v16 复制去小于 v16 的 v4,然后才用 v4。
【方法二】用 { v7 .. v16} ,能写 v16,前提是那些 registers 必须 v7, v8, v9 .. v16 准备好数值。

这样就完了?很可惜,我开头也以为这么容易, 可是其实要考虑 p。

你改成 .locals 16 后,之前的 p0 怎么办?

本来 p1 -> p0 占用 .locals vMax 倒数的目的就是为了方便加 vN 不会影响到现成的 pN, 可以轻松加 smali,对不?

很可惜,.locals 15 加成  16, smali 这特殊情况下帮不到你,需要手动改代码。

假设只有 this p0, p0 之前是 v15,然后你改成 .locals 16,那么你现在用 v15 是没问题的,p0 就升级成 v16。

So far so good, 很可惜,上面说了,大于 v15 的 registers 都是 temporary/virtual registers, 使用的方法不同。

因此你必须改所有涉及 p0 的代码, 先 move-object 才使用抑或更多工的 { pX .. pY}。

我上面强调 .locals 15 加成  16 是 “特殊情况”,是真的很 “特殊”, 即使你 .locals 21 加成 22 是不会有问题的,因为 .locals 21 + 1 existing 的 p0 并没有更改 “使用方法”(已经是 move/{..}了)。 只有 v15 去 v16 才导致 existing 的 p0 从普通方法 “突变” 成 move/{..} 的方法。

这个问题不出所料,网上也常提起

这还没完,v15 还没考虑 params 的数目。譬如 .locals 12 + params 6, 纯粹改成 .locals 13 也是有问题的。因此还要考虑之前 params 有没有属于 v15 的。可以 15 - .locals 12 = p3 要改。如果 .locals 加 2, 那么 p3 和 p2 得连续改。

如果是小数目的 p0 还好,可是 MySejahtera 的 `initWebViewSettings()` 用了大量的 p0,谁这么得空改完?不是不可能,而是很花时间而已。

最后我检查到 v13 少用到(要不然就是用了不再需要, 可以 override)。所以比较快的方式是只 assign v13, 然后重复用在 Log.d 即可达到我的加 Log.d 小目标。


然后 `<application android:debuggable="true"` 也很好用,改了后,不需要 root 也能通过

`adb exec-out run-as my.gov.onegovappstore.mysejahtera cat /data/user/0/my.gov.onegovappstore.mysejaht
era/databases/__ionicstorage > __ionicstorag
e`

的方式从手机复制数据库到电脑 (现在的 Android 的 run-as 不能直接 cp /sdcard/, 所以才比较折腾)。

其实 `android:debuggable="true"` 也能影响上面 `initWebViewSettings()`  的 `if ApplicationInfo flags == true` 而 enable remote debugging。

Saturday 7 November 2020

Facebook 鏈接對下載質量的影響

用 youtube-dl 和 you-get 下載 4 種視頻鏈接格式:
[1] 'https://www.facebook.com/<username>/videos/123/'
[2] 'https://www.facebook.com/<username>/posts/123'
[3] 'https://www.facebook.com/permalink.php?story_fbid=123&id=123'
[4] 'https://www.facebook.com/watch/?v=123'
[5] 手動下載。

實驗結果:
video detail page 的 'https://www.facebook.com/<username>/videos/123/'  或 /watch/ 或手動才能下載最高清視頻。
其餘兩個不僅僅有時下載不了,而是比較低清。

實驗總結:
選什麼鏈接下載並非 optional, 而是必須選 video detail page 的鏈接才能確保下載最高清視頻。