1
0
James P. Ketrenos 6285d1ea75 Improved entry point scripts (sort of)
Signed-off-by: James P. Ketrenos <james.p.ketrenos@intel.com>
2019-09-19 14:17:44 -07:00
2019-09-17 16:03:32 -07:00
2019-09-19 14:17:26 -07:00
2019-09-18 10:28:43 -07:00

Intel Media FFMPEG Transcode Container

This project hosts a container demonstrating the use of ffmpeg using GPU offload for transcode operations.

Using

Build the container:

docker build . -t intel-media-ffmpeg

Run the container:

docker run \
  --rm \
  --device=/dev/dri \
  -it \
  intel-media-ffmpeg

Usage examples

Download stream:

mkdir media
cd media
wget https://fate-suite.libav.org/h264-conformance/AUD_MW_E.264
cd ..

NOTE: In each of the following, if you have a multi-card host system you may need to change the qsv_device used by changing QSV_DEVICE to whichever node is connected to your hardware.

You can find out the paths via:

ls -l /dev/dri/by-path/pci-*$(lspci | grep Intel.*Graphics | cut -d " " -f1)*

On my system, my Intel graphics adapter is /dev/dri/renderD129, so I use:

export QSV_DEVICE=/dev/dri/renderD129

Decode

H264 video decode and save as raw file:

Connect to container

QSV_DEVICE=${QSV_DEVICE:-/dev/dri/renderD128}
docker run \
  --rm \
  --device=/dev/dri \
  --volume $(pwd)/media:/media \
  -it \
  intel-media-ffmpeg \
  ffmpeg -hwaccel qsv -qsv_device ${QSV_DEVICE} \
    -c:v h264_qsv -i /media/AUD_MW_E.264        \
    -vf hwdownload,format=nv12 -pix_fmt yuv420p \
    /media/AUD_MW.yuv

Encode

Encode a 10 frames of 720p raw input as H264 with 5Mbps using VBR mode:

QSV_DEVICE=${QSV_DEVICE:-/dev/dri/renderD128}
docker run \
  --rm \
  --device=/dev/dri \
  --volume $(pwd)/media:/media \
  -it \
  intel-media-ffmpeg \
  ffmpeg -loglevel debug -init_hw_device qsv=hw      \
       -filter_hw_device hw -f rawvideo -pix_fmt     \
       yuv420p -s:v 176x144 -i /media/AUD_MW.yuv -vf \
       hwupload=extra_hw_frames=64,format=qsv        \
       -c:v h264_qsv -b:v 5M -frames:v 10            \
       -y /media/AUD_MW_E.h264

Transcode

H264 decode && H265 encode with 5Mbps using VBR

QSV_DEVICE=${QSV_DEVICE:-/dev/dri/renderD128}
docker run \
  --rm \
  --device=/dev/dri \
  --volume $(pwd)/media:/media \
  -it \
  intel-media-ffmpeg \
  ffmpeg -hwaccel qsv -qsv_device ${QSV_DEVICE} \
    -c:v h264_qsv -i /media/AUD_MW_E.264        \
    -c:v hevc_qsv -b:v 5M AUD_MW_E.hevc

1:N transcoding

QSV_DEVICE=${QSV_DEVICE:-/dev/dri/renderD128}
docker run \
  --rm \
  --device=/dev/dri \
  --volume $(pwd)/media:/media \
  -it \
  intel-media-ffmpeg \
  ffmpeg -hwaccel qsv -qsv_device ${QSV_DEVICE}        \
    -c:v h264_qsv -i /media/AUD_MW_E.264               \
    -filter_complex "split=2[s1][s2];                  \
                     [s1]scale_qsv=1280:720[o1];       \
                     [s2]vpp_qsv=framerate=60[o2]"     \
    -map [o1] -c:v h264_qsv -b:v 5M /media/5M.mp4      \
    -map [o2] -c:v h264_qsv -b:v 4M /media/4M60FPS.h264

Developing

The Dockerfile itself is constructed from re-usable snippets, located in the templates/ directory, and can be regenerated by running:

scripts/build-dockerfile

The above script uses environment substitution to stamp version information within the created Dockerfile. The files which declare the environment variables are in SOLUTION and MANIFEST.

After joining the template/* pieces together, the file Dockerfile.solution is then added to the Dockerfile with environment substitution.

SOLUTION

Solution specific definitions:

CONTAINER_IMAGE is used as the container tag name
OS_DISTRO       is used as the base OS distribution. Possible values: ubuntu
OS_RELEASE      is used as the OS version. Possible values: disco, eoan

MANIFEST

The version of MANIFEST is created by the set of Agama packages from the Agama repository and name-mangling them to be a VERSION declaration:

For example:

libgl1-mesa-glx_19.0.1-agama-109_amd64.deb

is changed to:

LIBGL1_MESA_GLX_VERSION=19.0.1-agama-109

The script you can use to recreate the OS_RELEASE defined in SOLUTION is:

NOTE: This only works on the Ubuntu releases.

AGAMA_VERSION=169
. SOLUTION
echo "AGAMA_VERSION=${AGAMA_VERSION}" > MANIFEST
wget -q -O - \
  https://osgc.jf.intel.com/packages/agama/ubuntu/dists/${OS_RELEASE}/main/binary-amd64/Packages.bz2 | 
    bunzip2 | 
    sed -nE 's/^(Package|Version): (.*)/\2/p' |
    paste -s -d' \n' |
    while read package version rest; do 
      package=$(echo $package | sed -E -e s#-#_#g -e 's#(.*)#\U\1#g')_VERSION
      echo $package=$version
    done | grep ${AGAMA_VERSION}\$ >> MANIFEST

This allows the Dockerfile templates to then version pin Agama packages:

  RUN apt-get install -y libgl1-mesa-glx=$LIBGL1_MESA_GLX_VERSION

The scripts/build-dockerfile loads MANIFEST, which defines LIBGL1_MESA_GLX_VERSION. That is then subsituted for the version in the above Dockerfile snippet when being placed into the main Dockerfile.

Tagging

If the build succeeds, we want to be able to tag the git project as well as corresponding Docker images with the appropriate Agama tag:

. MANIFEST ; git tag -f agama-${AGAMA_VERSION}
Description
Intel graphics driver hardware accelerated FFMPEG
Readme 447 KiB