mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-02-10 04:07:23 +00:00
Fix the broken timestamp management in the virtio decoder device. Timestamps are specified by the guest's user-space as a struct timeval, which is effectively a (seconds, microseconds) pair. This pair is turned into a u64 with nanoseconds units by V4L2, and passed to the virtio device in that form. This is fine so far, save for the fact that libvda works with 32-bit timestamps. To accomodate that, we divided the original timestamp by 1_000_000_000, passed that truncated timestamp to the decoder backend as a u32, and when the backend gives us decoded frames, multiplied their timestamp by 1_000_000_000 again and passed that value as the frame timestamp to the guest. For some reason, we also used the timestamp as the key for the `NotifyEndOfBistreamBuffer` event, which forced us to have a mapping table between an input buffer timestamp and its corresponding resource ID. This in turn required that each input buffer has a unique timestamp, lest they collide in the mapping table. Anyway, the timestamp division by 1_000_000_000 means that any sub-second timestamp information was lost during the decoding process. This is not a problem with the Android V4L2 decoder which increases the timestamp by one second for each frame and does not use sub-second information, but clients that use *actual* timestamp information (like ffmpeg) get pretty confused by that and abandon decoding with an error. Fix this by passing the original 64-bit timestamp to decoder backends, along with the 32-bit ID of the input resource. This allows backends to directly send the NotifyEndOfBitstreamBuffer with the currect resource ID, removing the need for the mapping table and unique timestamps for input buffers. More importantly, backends that can work with 64-bit timestamps (all of them but libvda) can just pass the original timestamp to their decoder logic and return it as-is in the PictureReady event. Libvda still requires 32-bit timestamps, so we reproduce the truncation and mapping table behavior inside the libvda backend (I also tried sending the 32-bit input resource ID as a timestamp to VDA, but it was not happy with it). At least now that behavior is local to the VDA backend. Thanks to this change clients other than the Android C2 decoder can get proper timestamp information. One can argue that the code is also simpler (except for libvda which adds a simple mapping table that we were using before anyway). BUG=b:161774071 TEST=cargo test --features "video-decoder,ffmpeg" -p devices video TEST=`ffmpeg -codec:v vp8_v4l2m2m -i test-25fps.vp8 test-25fps-%d.png` in the guest completes successfully with the ffmpeg backend. TEST=tast arc.VideoDecodeAccel*_vm passes on hatch. Change-Id: Idb21b4c536acafbdf5458e88cdbc33c9376a405e Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/3841480 Commit-Queue: Alexandre Courbot <acourbot@chromium.org> Tested-by: Alexandre Courbot <acourbot@chromium.org> Reviewed-by: Keiichi Watanabe <keiichiw@chromium.org> Reviewed-by: Tatsuyuki Ishi <ishitatsuyuki@google.com> |
||
---|---|---|
.. | ||
ffmpeg | ||
libva | ||
libvda | ||
vp8 |