1
0
intel-media-ffmpeg/README.md
James Ketrenos ac8d6a5cb5 Change --device to only provide the LHS
Signed-off-by: James Ketrenos <james.p.ketrenos@intel.com>
2019-09-18 10:28:43 -07:00

204 lines
5.0 KiB
Markdown

# 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:
```bash
docker build . -t intel-media-ffmpeg
```
Run the container:
```bash
docker run \
--rm \
--device=/dev/dri \
-it \
intel-media-ffmpeg
```
# Usage examples
Download stream:
```bash
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
```bash
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:
```bash
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
```bash
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
```bash
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:
```bash
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.
```bash
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:
```Dockerfile
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:
```bash
. MANIFEST ; git tag -f agama-${AGAMA_VERSION}
```