Tegra/Downstream SW/Linux4Tegra/WebBrowsers/Hardware Accelerated Video Decoding

The bundled Chromium and Firefox don't use the Video Decoding Hardware and therefore the playback of High bandwidth Full HD videos and 4K videos not only saturate all the 4 cores but also lag a lot to the extend that the video is not watchable. The browsers manage to play low bandwidth Full HD videos and lesser resolution videos with ease using the software codec. Linux4Tegra package has the necessary Gstreamer libraries and Firefox has Gstreamer support but I couldn't yet get firefox achieve H/W acceleration, however recompiling Chrome with certain options and a few hacks enable it to achieve H/W acceleration.

Motivation

 * Video Acceleration is disabled by default in Linux Builds of Chromium.
 * Nvidia provides Gstreamer libraries for the Tegra K1
 * Chromium doesn't support Gstreamer backend for media
 * Chromium supports VA-API and VDPAU libraries through the Hardware acceleration implementation called VAVDA.
 * Nvidia doesn't provide VDPAU libraries for the Tegra K1.
 * Notwithstanding all the above points, Acer 13 and HP 14 Chromebooks that shipped with the same SoC supported hardware accelerated video decoding.

V4L2

 * This Change List hinted at Chromium supporting Video Acceleration using V4L2, However this is enabled only for ChromeOS Builds for ARM.
 * This presentation from Samsung explains the V4L2 Implementation.

Build Setup

 * Ubuntu 14.04.2 LTS (64 BIT) (32 Bit version doesn't work as the scripts are customized for 64 bit system)

Building Chromium for ChromeOS/ARM

 * The Acer 13 is called the nyan_big within the ChromeOS however builders for non-generic boards are not yet available so make sure to use BOARD type as arm-generic wherever required.
 * Follow the Steps for Compiling Chromium for ChromeOS, however use the board type as arm-generic wherever required. The complete steps can be found in the previous link but I would just highlight the overall steps.
 * Setup depot tools
 * git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
 * export PATH=$PATH:`pwd`/depot_tools
 * Download Chromium source
 * fetch --nohooks --no-history chromium
 * Mind the --no-history otherwise it would take forever to download the source, the progress of download is displayed on the screen but it's going to be very long before all the required source is downloaded because at the time of my testing the source came up to 10 GB, Webkit download was the longest but never interrupt a download because it would start afresh all over again.
 * There should now be two directories depot_tool and src.
 * Install dependencies (May not be required)
 * ./src/build/install-build-deps.sh
 * ./src/build/install-build-deps.sh --arm
 * Install gsutil
 * Follow the instructions to setup gsutil.
 * Add gsutil to the PATH
 * Configure gsutil
 * follow the instructions to configure gsutil.
 * Enter 134157665460 as the project id.
 * I created API Keys but that may not be required.
 * Drop to the build environment
 * cros chrome-sdk --board=arm-generic --nogoma
 * First time the command would download the required packages for cross compiling.
 * Modify the GYP_DEFINES
 * export GYP_DEFINES="$GYP_DEFINES proprietary_codecs=1 ffmpeg_branding=ChromeOS" # To support H.264
 * export GYP_DEFINES="$GYP_DEFINES component=shared_library fastbuild=1" # For fast link times
 * export GYP_DEFINES=${GYP_DEFINES//release_extra_cflags=-g/} # To reduce binary size
 * Generate the ninja build files
 * gclient runhooks # from the src directory
 * Patching
 * Please apply the patch defined in the section below
 * Building
 * ninja -C out_arm-generic/Release -j500 chrome chrome_sandbox nacl_helper # From the src folder

Patching the code
In the file src/content/common/gpu/media/v4l2_video_decode_accelerator.cc, the function SetupFormats uses an IOCTL VIDIOC_ENUM_FMT which for some reason doesn't seem to work on my board. Until a proper fix is figured out I am hard coding the format type: output_format_fourcc_ = V4L2_PIX_FMT_NV12M;

Running the built binary

 * Create a symbolic link /usr/lib/libtegrav4l2.so pointing to /usr/lib/arm-linux-gnueabihf/tegra/libtegrav4l2.so
 * Create symbolic link /usr/lib/arm-linux-gnueabihf/libstdc++.so pointing to libstdc++.so.6.0.20 (Which can be extracted from the downloaded package in the build machine.)
 * Set the SUID on the sandbox binary from the build machine.
 * Export the src/out_arm-generic/Release folder from the build machine through nfs and mount it on the board.
 * Set CHROME_DEVEL_SANDBOX to the sandbox binary in the nfs path.
 * ./chrome --use-gl=egl --ignore-resolution-limits-for-accelerated-video-decode
 * Play a 4K video. If the video doesn't play, play another low resolution video and retry the original video - you should see debug messages from the Tegra V4L2 library with the media dimensions and a string stating "Capture stream ON" to confirm that the acceleration is working.