Skip to content

Commit

Permalink
Support for ffmpeg (#967)
Browse files Browse the repository at this point in the history
Add support for gpu_direct in ffmepg ffmpeg plugin
Introduces suport for experimental MTL_GPU_DIRECT
feature to enhance the performance of the FFmpeg
ST20p plugin by enabling direct GPU memory access.

Update ffmpeg README.md
-- include build instructions and description of
the feature

Modify build_ffmpeg_plugin.sh
-- Add support for building with GPU_DIRECT
  • Loading branch information
DawidWesierski4 authored Sep 10, 2024
1 parent 3127c88 commit 858fbc2
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 12 deletions.
43 changes: 43 additions & 0 deletions ecosystem/ffmpeg_plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,3 +172,46 @@ ffmpeg -stream_loop -1 -i test.wav -p_port 0000:af:01.1 -p_sip 192.168.96.3 -p_t

ffmpeg -p_port 0000:af:01.0 -p_sip 192.168.96.2 -p_rx_ip 239.168.85.20 -udp_port 30000 -payload_type 111 -pcm_fmt pcm16 -at 1ms -ac 2 -f mtl_st30p -i "0" dump_pcm16.wav -y
```

### Enabling experimental MTL_GPU_DIRECT in FFmpeg with ST20p Support

The MTL_GPU_DIRECT experimental feature aims at enhancing FFmpeg's performance by allowing direct access to GPU memory, which can be particularly beneficial when working with high-throughput video streams such as those handled by the MTL ST20 codec plugin.

#### Building FFmpeg with MTL_GPU_DIRECT Enabled
To take advantage of the MTL_GPU_DIRECT feature FFmpeg has to be built with this option enabled. Here’s how to do it:

```bash
./configure --enable-shared --disable-static --enable-nonfree --enable-pic --enable-gpl --enable-libopenh264 --enable-encoder=libopenh264 --enable-mtl --extra-cflags="-DMTL_GPU_DIRECT_ENABLED"
```
or use
```bash
./build_ffmpeg_plugin.sh -g
```

Reading a ST2110-20 10bit YUV422 stream on "239.168.85.20:20000" with payload_type 112 and
enabled gpu_direct:

```bash
./ffmpeg -p_port 0000:af:01.0 -p_sip 192.168.96.2 -p_rx_ip 239.168.85.20 -udp_port 20000 -payload_type 112 -fps 59.94 -pix_fmt yuv422p10le -video_size 1920x1080 -gpu_direct 1 -gpu_driver 0 -gpu_device 0 -f mtl_st20p -i "k" -f rawvideo /dev/null -y
```

#### Additional Notes
**GPU Direct Flag:** When compiling FFmpeg with the MTL_GPU_DIRECT feature enabled, ensure that your system's GPU drivers and hardware support direct GPU memory access.
GPU device IDs and GPU driver IDs are printed during initialization.

**Options:**
1. `-gpu_device`
1. `-gpu_driver`

Both default to 0, but if your device doesn't initialize, adjust it using the information printed during initialization.

**Example:**
```plaintext
Drivers count: 1
Driver: 0: Device: 0: Name: Intel(R) Data Center GPU Flex 170, Type: 1, VendorID: 8086, DeviceID: 22208
```


[GPU Documentation](../../doc/gpu.md)

By following these steps, you can effectively build and utilize FFmpeg with the MTL_GPU_DIRECT feature enabled.
64 changes: 52 additions & 12 deletions ecosystem/ffmpeg_plugin/build_ffmpeg_plugin.sh
Original file line number Diff line number Diff line change
@@ -1,19 +1,51 @@
#!/bin/bash

# SPDX-License-Identifier: BSD-3-Clause
# Copyright 2024 Intel Corporation
# SPDX-FileCopyrightText: Copyright (c) 2024 Intel Corporation

set -e

if [ -n "$1" ]; then
ffmpeg_ver=$1
else
# default to latest 7.0
ffmpeg_ver=7.0
fi
# Default values
ffmpeg_ver="7.0"
enable_gpu=false
script_path="$(dirname "$(readlink -f "$0")")"

# Help message function
usage() {
echo "Usage: $0 [options]"
echo "Options:"
echo " -v <version> Specify the FFmpeg version to build (default is $ffmpeg_ver)"
echo " -g Enable GPU direct mode during compilation"
echo " -h Display this help and exit"
}

# Parse command-line options
while getopts ":v:hg" opt; do
case "${opt}" in
v)
ffmpeg_ver=${OPTARG}
;;
g)
enable_gpu=true
;;
h)
usage
exit 0
;;
\?)
echo "Invalid option: -$OPTARG" >&2
usage
exit 1
;;
:)
echo "Option -$OPTARG requires an argument." >&2
exit 1
;;
esac
done

build_openh264() {
rm openh264 -rf
rm -rf openh264
git clone https://github.com/cisco/openh264.git
cd openh264
git checkout openh264v2.4.0
Expand All @@ -24,13 +56,21 @@ build_openh264() {
}

build_ffmpeg() {
rm FFmpeg -rf
rm -rf FFmpeg
git clone https://github.com/FFmpeg/FFmpeg.git
cd FFmpeg
git checkout release/"$ffmpeg_ver"
cp -f ../mtl_* ./libavdevice/
git am ../"$ffmpeg_ver"/*.patch
./configure --enable-shared --disable-static --enable-nonfree --enable-pic --enable-gpl --enable-libopenh264 --enable-encoder=libopenh264 --enable-mtl
cp -f "$script_path"/mtl_* ./libavdevice/
git am "$script_path"/"$ffmpeg_ver"/*.patch

if [ "$enable_gpu" = true ]; then
echo "Building with MTL_GPU_DIRECT_ENABLED"
extra_config_flags="--extra-cflags=-DMTL_GPU_DIRECT_ENABLED"
else
extra_config_flags=""
fi

./configure --enable-shared --disable-static --enable-nonfree --enable-pic --enable-gpl --enable-libopenh264 --enable-encoder=libopenh264 --enable-mtl $extra_config_flags
make -j "$(nproc)"
sudo make install
sudo ldconfig
Expand Down
60 changes: 60 additions & 0 deletions ecosystem/ffmpeg_plugin/mtl_st20p_rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
*/

#include "mtl_common.h"
#ifdef MTL_GPU_DIRECT_ENABLED
#include <mtl_gpu_direct/gpu.h>
#endif /* MTL_GPU_DIRECT_ENABLED */

typedef struct MtlSt20pDemuxerContext {
const AVClass* class; /**< Class for private options. */
Expand All @@ -39,6 +42,13 @@ typedef struct MtlSt20pDemuxerContext {
st20p_rx_handle rx_handle;

int64_t frame_counter;

#ifdef MTL_GPU_DIRECT_ENABLED
bool gpu_direct_enabled;
int gpu_driver_index;
int gpu_device_index;
void* gpu_context;
#endif /* MTL_GPU_DIRECT_ENABLED */
} MtlSt20pDemuxerContext;

static int mtl_st20p_read_close(AVFormatContext* ctx) {
Expand All @@ -58,6 +68,12 @@ static int mtl_st20p_read_close(AVFormatContext* ctx) {
s->dev_handle = NULL;
}

#ifdef MTL_GPU_DIRECT_ENABLED
if (s->gpu_direct_enabled) {
free_gpu_context(s->gpu_context);
}
#endif /* MTL_GPU_DIRECT_ENABLED */

info(ctx, "%s(%d), frame_counter %" PRId64 "\n", __func__, s->idx, s->frame_counter);
return 0;
}
Expand Down Expand Up @@ -148,6 +164,24 @@ static int mtl_st20p_read_header(AVFormatContext* ctx) {
dbg(ctx, "%s, fb_cnt: %d\n", __func__, s->fb_cnt);
ops_rx.framebuff_cnt = s->fb_cnt;

#ifdef MTL_GPU_DIRECT_ENABLED
if (s->gpu_direct_enabled) {
/* create context for one gpu device */
GpuContext gpu_ctx = {0};

/* print GPU device and driver IDs */
print_gpu_drivers_and_devices();

ret = init_gpu_device(&gpu_ctx, s->gpu_driver_index, s->gpu_device_index);
if (ret < 0) {
err(ctx, "%s, app gpu initialization failed %d\n", __func__, ret);
return -ENXIO;
}
ops_rx.gpu_context = (void*)(&gpu_ctx);
ops_rx.flags |= ST20P_RX_FLAG_USE_GPU_DIRECT_FRAMEBUFFERS;
}
#endif /* MTL_GPU_DIRECT_ENABLED */

// get mtl dev
s->dev_handle = mtl_dev_get(ctx, &s->devArgs, &s->idx);
if (!s->dev_handle) {
Expand Down Expand Up @@ -296,6 +330,32 @@ static const AVOption mtl_st20p_rx_options[] = {
3,
8,
DEC},
#ifdef MTL_GPU_DIRECT_ENABLED
{"gpu_direct",
"Store frames in framebuffer directly on GPU",
OFFSET(gpu_direct_enabled),
AV_OPT_TYPE_BOOL,
{.i64 = 0},
0,
1,
DEC},
{"gpu_driver",
"Index of the GPU driver",
OFFSET(gpu_driver_index),
AV_OPT_TYPE_INT,
{.i64 = 0},
0,
60,
DEC},
{"gpu_device",
"Index of the GPU device",
OFFSET(gpu_device_index),
AV_OPT_TYPE_INT,
{.i64 = 0},
0,
60,
DEC},
#endif /* MTL_GPU_DIRECT_ENABLED */
{NULL},
};

Expand Down

0 comments on commit 858fbc2

Please sign in to comment.