Call collect() on the iterator returned by map(... munmap() ...)

This CL fixes the Drop trait implementation for DmaMapping so that it
actually calls munmap(). Before this CL, a Map iterator was being
created using zip().map() in order to call munmap(). However, this
iterator was not being "consumed" so munmap() wasn't actually called.
This was causing a leak, crazy memory usage numbers, and subsequent
instability during playback on corsola (where frames must be mmap()ed in
order to do de-tiling).

This CL calls collect() on the Map iterator in order to consume it and
actually call munmap().

Unfortunately, this surfaced another bug: munmap() was getting called
multiple times for a single mmap(), and this was causing VTS failures.
To handle this, this CL tracks the mmap()ed addresses separately from
the offset (plane) addresses. As drive-by improvements, this CL also:

- Takes some things out of `unsafe` blocks that were not unsafe.

- Provides justification for an unsafe operation that did not have
  justification (the pointer arithmetic itself).

- Eliminates the use of `as *mut u8` and similar when casting from an
  mmap()ed address to the desired type.

Bug: 409389166
Test: https://crosvideo.appspot.com/?codec=h264&resolution=720&loop=true for a long time on corsola (until after the frame index goes past ~65000)
Test: top -d 0.5 and adb shell dumpsys meminfo <PID> (where <PID> is the process ID of android.hardware.media.c2-cros-codecs-service) while playing https://crosvideo.appspot.com/?codec=h264&resolution=720&loop=true on corsola
Flag: com.google.android.desktop.video.flags.cros_codecs_decoder_hal
Change-Id: I16c0ca6cfa0bf501b127e12448d1f0c5367ca7fb
2 files changed
tree: 613c21ea7a096df1d2cd808de50d533a81b63925
  1. .cargo/
  2. ci/
  3. examples/
  4. fuzz/
  5. src/
  6. test/
  7. .clippy.toml
  8. .gitignore
  9. Android.bp
  10. Cargo.toml
  11. cargo_embargo.json
  12. CONTRIBUTING.md
  13. DIR_METADATA
  14. LICENSE
  15. METADATA
  16. MODULE_LICENSE_BSD
  17. OWNERS
  18. README.md
  19. rustfmt.toml
  20. simple_test.py
README.md

Cros-codecs

A lightweight, simple, low-dependency, and hopefully safe crate for hardware-accelerated video decoding and encoding on Linux.

It is developed for use in ChromeOS (particularly crosvm), but has no dependency to ChromeOS and should be usable anywhere.

Current features

  • Simple decoder API,
  • VAAPI decoder support (using cros-libva) for H.264, H.265, VP8, VP9 and AV1,
  • VAAPI encoder support for H.264, VP9 and AV1,
  • Stateful V4L2 encoder support.

Planned features

  • Stateful V4L2 decoder support,
  • Stateless V4L2 decoder support,
  • Support for more encoder codecs,
  • C API to be used in non-Rust projects.

Non-goals

  • Support for systems other than Linux.

Example programs

The ccdec example program can decode an encoded stream and write the decoded frames to a file. As such it can be used for testing purposes.

$ cargo build --examples
$ ./target/debug/examples/ccdec --help
Usage: ccdec <input> [--output <output>] --input-format <input-format> [--output-format <output-format>] [--compute-md5 <compute-md5>]

Simple player using cros-codecs

Positional Arguments:
  input             input file

Options:
  --output          output file to write the decoded frames to
  --input-format    input format to decode from.
  --output-format   pixel format to decode into. Default: i420
  --compute-md5     whether to display the MD5 of the decoded stream, and at
                    which granularity (stream or frame)
  --help            display usage information

Testing

Fluster can be used for testing, using the ccdec example program described above. This branch contains support for cros-codecs testing. Just make sure the ccdec binary is in your PATH, and run Fluster using one of the ccdec decoders, e.g.

python fluster.py run -d ccdec-H.264 -ts JVT-AVC_V1

Credits

The majority of the code in the initial commit has been written by Daniel Almeida as a VAAPI backend for crosvm, before being split into this crate.