Commit 34c11333 authored by Michael Wootton's avatar Michael Wootton Committed by Luca Barbato

Add support for H.264 and HEVC hardware encoding for AMD GPUs based on AMF SDK

Requires AMF headers for at least version 1.4.4.1.
Signed-off-by: 's avatarMikhail Mironov <mikhail.mironov@amd.com>
Signed-off-by: 's avatarLuca Barbato <lu_zero@gentoo.org>
parent 7b0b5bc8
......@@ -231,6 +231,7 @@ External library support:
--enable-zlib compression [autodetect]
The following libraries provide various hardware acceleration features:
--enable-amf AMF video encoding code [auto]
--enable-cuda Nvidia CUDA (dynamically linked)
--enable-cuvid Nvidia CUVID video decode acceleration
--enable-d3d11va Microsoft Direct3D 11 video acceleration [auto]
......@@ -1255,6 +1256,7 @@ HWACCEL_LIBRARY_NONFREE_LIST="
"
HWACCEL_LIBRARY_LIST="
$HWACCEL_LIBRARY_NONFREE_LIST
amf
d3d11va
dxva2
libmfx
......@@ -2238,6 +2240,7 @@ wmv3_vaapi_hwaccel_select="vc1_vaapi_hwaccel"
wmv3_vdpau_hwaccel_select="vc1_vdpau_hwaccel"
# hardware-accelerated codecs
amf_deps_any="libdl LoadLibrary"
nvenc_deps_any="libdl LoadLibrary"
omx_deps="libdl pthreads"
omx_rpi_select="omx"
......@@ -2250,6 +2253,7 @@ vaapi_encode_deps="vaapi"
hwupload_cuda_filter_deps="cuda"
scale_npp_filter_deps="cuda libnpp"
h264_amf_encoder_deps="amf"
h264_mmal_decoder_deps="mmal"
h264_nvenc_encoder_deps="nvenc"
h264_omx_encoder_deps="omx"
......@@ -2257,6 +2261,7 @@ h264_qsv_decoder_select="h264_mp4toannexb_bsf h264_parser qsvdec"
h264_qsv_encoder_select="qsvenc"
h264_vaapi_encoder_deps="VAEncPictureParameterBufferH264"
h264_vaapi_encoder_select="cbs_h264 vaapi_encode"
hevc_amf_encoder_deps="amf"
hevc_nvenc_encoder_deps="nvenc"
hevc_qsv_decoder_select="hevc_mp4toannexb_bsf hevc_parser qsvdec"
hevc_qsv_encoder_select="hevcparse qsvenc"
......@@ -4573,6 +4578,11 @@ for func in $MATH_FUNCS; do
done
# these are off by default, so fail if requested and not available
enabled amf &&
check_cpp_condition "AMF/core/Version.h" \
"(AMF_VERSION_MAJOR << 48 | AMF_VERSION_MINOR << 32 | AMF_VERSION_RELEASE << 16 | AMF_VERSION_BUILD_NUM) >= 0x0001000400040001" ||
disable amf
enabled avisynth && require_header avisynth/avisynth_c.h
enabled avxsynth && require_header avxsynth/avxsynth_c.h
enabled cuda && require cuda cuda.h cuInit -lcuda
......
......@@ -237,6 +237,16 @@ The dispatcher is open source and can be downloaded from
with the @code{--enable-libmfx} option and @code{pkg-config} needs to be able to
locate the dispatcher's @code{.pc} files.
@section AMD VCE
Libav can use the AMD Advanced Media Framework library for accelerated H.264 and HEVC encoding on VCE enabled hardware under Windows.
To enable support you must obtain the AMF framework header files from @url{https://github.com/GPUOpen-LibrariesAndSDKs/AMF.git}.
Create an @code{AMF/} directory in the system include path.
Copy the contents of @code{AMF/amf/public/include/} into that directory.
Then Configure Libav with @code{--enable-amf}.
@chapter Supported File Formats and Codecs
You can use the @code{-formats} and @code{-codecs} options to have an exhaustive list.
......
......@@ -48,6 +48,7 @@ OBJS = ac3_parser.o \
OBJS-$(CONFIG_AANDCTTABLES) += aandcttab.o
OBJS-$(CONFIG_AC3DSP) += ac3dsp.o
OBJS-$(CONFIG_ADTS_HEADER) += adts_header.o mpeg4audio.o
OBJS-$(CONFIG_AMF) += amfenc.o
OBJS-$(CONFIG_AUDIO_FRAME_QUEUE) += audio_frame_queue.o
OBJS-$(CONFIG_AUDIODSP) += audiodsp.o
OBJS-$(CONFIG_BLOCKDSP) += blockdsp.o
......@@ -271,6 +272,7 @@ OBJS-$(CONFIG_H264_DECODER) += h264dec.o h264_cabac.o h264_cavlc.o \
h264_mb.o h264_picture.o \
h264_refs.o h264_sei.o \
h264_slice.o h264data.o
OBJS-$(CONFIG_H264_AMF_ENCODER) += amfenc_h264.o
OBJS-$(CONFIG_H264_MMAL_DECODER) += mmaldec.o
OBJS-$(CONFIG_H264_NVENC_ENCODER) += nvenc_h264.o
OBJS-$(CONFIG_H264_OMX_ENCODER) += omx.o
......@@ -282,6 +284,7 @@ OBJS-$(CONFIG_HAP_ENCODER) += hapenc.o hap.o
OBJS-$(CONFIG_HEVC_DECODER) += hevcdec.o hevc_mvs.o hevc_sei.o \
hevc_cabac.o hevc_refs.o hevcpred.o \
hevcdsp.o hevc_filter.o hevc_data.o
OBJS-$(CONFIG_HEVC_AMF_ENCODER) += amfenc_hevc.o
OBJS-$(CONFIG_HEVC_NVENC_ENCODER) += nvenc_hevc.o
OBJS-$(CONFIG_HEVC_QSV_DECODER) += qsvdec_h2645.o
OBJS-$(CONFIG_HEVC_QSV_ENCODER) += qsvenc_hevc.o hevc_ps_enc.o \
......@@ -808,6 +811,7 @@ SKIPHEADERS += %_tablegen.h \
$(ARCH)/vp56_arith.h \
SKIPHEADERS-$(CONFIG_CUVID) += cuvid.h
SKIPHEADERS-$(CONFIG_AMF) += amfenc.h
SKIPHEADERS-$(CONFIG_D3D11VA) += d3d11va.h dxva2_internal.h
SKIPHEADERS-$(CONFIG_DXVA2) += dxva2.h dxva2_internal.h
SKIPHEADERS-$(CONFIG_LIBSCHROEDINGER) += libschroedinger.h
......
......@@ -452,11 +452,13 @@ void avcodec_register_all(void)
/* external libraries, that shouldn't be used by default if one of the
* above is available */
REGISTER_ENCDEC (LIBOPENH264, libopenh264);
REGISTER_ENCODER(H264_AMF, h264_amf);
REGISTER_ENCODER(H264_NVENC, h264_nvenc);
REGISTER_ENCODER(H264_OMX, h264_omx);
REGISTER_ENCODER(H264_QSV, h264_qsv);
REGISTER_ENCODER(H264_VAAPI, h264_vaapi);
REGISTER_ENCODER(LIBKVAZAAR, libkvazaar);
REGISTER_ENCODER(HEVC_AMF, hevc_amf);
REGISTER_ENCODER(HEVC_NVENC, hevc_nvenc);
REGISTER_ENCODER(HEVC_QSV, hevc_qsv);
REGISTER_ENCODER(HEVC_VAAPI, hevc_vaapi);
......
This diff is collapsed.
/*
* AMD AMF support
* Copyright (C) 2017 Luca Barbato
* Copyright (C) 2017 Mikhail Mironov <mikhail.mironov@amd.com>
*
* This file is part of Libav.
*
* Libav is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* Libav is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_AMFENC_H
#define AVCODEC_AMFENC_H
#include <AMF/core/Factory.h>
#include <AMF/components/VideoEncoderVCE.h>
#include <AMF/components/VideoEncoderHEVC.h>
#include "libavutil/fifo.h"
#include "config.h"
#include "avcodec.h"
/**
* AMF trace writer callback class
* Used to capture all AMF logging
*/
typedef struct AmfTraceWriter {
AMFTraceWriterVtbl *vtbl;
AVCodecContext *avctx;
} AmfTraceWriter;
/**
* AMF encoder context
*/
typedef struct AmfContext {
AVClass *avclass;
// access to AMF runtime
amf_handle library; ///< handle to DLL library
AMFFactory *factory; ///< pointer to AMF factory
AMFDebug *debug; ///< pointer to AMF debug interface
AMFTrace *trace; ///< pointer to AMF trace interface
amf_uint64 version; ///< version of AMF runtime
AmfTraceWriter tracer; ///< AMF writer registered with AMF
AMFContext *context; ///< AMF context
//encoder
AMFComponent *encoder; ///< AMF encoder object
amf_bool eof; ///< flag indicating EOF happened
AMF_SURFACE_FORMAT format; ///< AMF surface format
AVBufferRef *hw_device_ctx; ///< pointer to HW accelerator (decoder)
AVBufferRef *hw_frames_ctx; ///< pointer to HW accelerator (frame allocator)
// helpers to handle async calls
int delayed_drain;
AMFSurface *delayed_surface;
AVFrame *delayed_frame;
// shift dts back by max_b_frames in timing
AVFifoBuffer *timestamp_list;
int64_t timestamp_last;
int64_t dts_delay;
// common encoder options
int log_to_dbg;
char *writer_id;
// Static options, have to be set before Init() call
int usage;
int profile;
int level;
int preanalysis;
int quality;
int b_frame_delta_qp;
int ref_b_frame_delta_qp;
// Dynamic options, can be set after Init() call
int rate_control_mode;
int enforce_hrd;
int filler_data;
int enable_vbaq;
int skip_frame;
int qp_i;
int qp_p;
int qp_b;
int max_au_size;
int header_spacing;
int b_frame_ref;
int intra_refresh_mb;
int coding_mode;
int me_half_pel;
int me_quarter_pel;
int aud;
// HEVC - specific options
int gops_per_idr;
int header_insertion_mode;
int min_qp_i;
int max_qp_i;
int min_qp_p;
int max_qp_p;
int tier;
} AmfContext;
/**
* Common encoder initization function
*/
int ff_amf_encode_init(AVCodecContext *avctx);
/**
* Common encoder termination function
*/
int ff_amf_encode_close(AVCodecContext *avctx);
/**
* Ecoding one frame - common function for all AMF encoders
*/
int ff_amf_send_frame(AVCodecContext *avctx, const AVFrame *frame);
int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt);
/**
* Supported formats
*/
extern const enum AVPixelFormat ff_amf_pix_fmts[];
/**
* Error handling helper
*/
#define AMF_RETURN_IF_FALSE(avctx, exp, ret_value, /*message,*/ ...) \
if (!(exp)) { \
av_log(avctx, AV_LOG_ERROR, __VA_ARGS__); \
return ret_value; \
}
#define AMF_COMMON_OPTIONS \
{ "log_to_dbg", "Enable AMF logging to debug output", OFFSET(log_to_dbg), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, \
{ "writer_id", "Enable AMF logging to writer id", OFFSET(writer_id), AV_OPT_TYPE_STRING, { .str = "libavcodec" }, 0, 1, VE } \
#endif //AVCODEC_AMFENC_H
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment