RKMPP 在FFmpeg上实现硬编解码
Posted Geek.Fan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RKMPP 在FFmpeg上实现硬编解码相关的知识,希望对你有一定的参考价值。
一、编译指令
--enable-cross-compile --cross- prefix=/home/cks/linux_sdk/buildroot/output/rockchip_rk3399pro/host/bin/aarch64-buildroot-linux-gnu- --sysroot=/home/cks/linux_sdk/buildroot/output/rockchip_rk3399pro/host/aarch64-buildroot-linux-gnu/sysroot --host-cc=/usr/bin/gcc --arch=aarch64 --target-os=linux --disable-stripping --pkg-config=/home/cks/fireFlyLinuxSdk/firefly/linux_sdk/buildroot/output/rockchip_rk3399pro/host/bin/pkg-config --disable-static --enable-shared --prefix=/usr --enable-avfilter --enable-version3 --enable-logging --enable-optimizations --disable-extra-warnings --enable-avdevice --enable-avcodec --enable-avformat --enable-network --disable-gray --enable-swscale-alpha --disable-small --enable-dct --enable-fft --enable-mdct --enable-rdft --disable-crystalhd --disable-dxva2 --enable-runtime-cpudetect --disable-hardcoded-tables --disable-mipsdsp --disable-mipsdspr2 --disable-msa --enable-hwaccels --disable-cuda --disable-cuvid --disable-nvenc --disable-avisynth --disable-frei0r --disable-libopencore-amrnb --disable-libopencore-amrwb --disable-libcdio --disable-libdc1394 --disable-libgsm --disable-libilbc --disable-libvo-amrwbenc --disable-symver --disable-doc --disable-gpl --disable-nonfree --enable-ffmpeg --disable-ffplay --disable-ffserver --disable-avresample --disable-ffprobe --disable-postproc --enable-swscale --enable-indevs --enable-alsa --enable-outdevs --enable-pthreads --enable-zlib --disable-bzlib --disable-libfdk-aac --disable-gnutls --enable-openssl --disable-libopenh264 --enable-libvorbis --enable-muxer=ogg --enable-encoder=libvorbis --disable-vaapi --disable-vdpau --enable-rkmpp --enable-libdrm --disable-decoder=h264_v4l2m2m --disable-decoder=vp8_v4l2m2m --disable-decoder=mpeg2_v4l2m2m --disable-decoder=mpeg4_v4l2m2m --disable-encoder=h264_v4l2m2m --disable-encoder=vp8_v4l2m2m --disable-encoder=mpeg2_v4l2m2m --disable-encoder=mpeg4_v4l2m2m --disable-mmal --disable-omx --disable-omx-rpi --disable-libopencv --disable-libopus --disable-libvpx --disable-libass --disable-libbluray --enable-librtmp --disable-libmp3lame --disable-libmodplug --disable-libspeex --enable-libtheora --disable-libwavpack --disable-iconv --enable-libfreetype --enable-fontconfig --disable-libopenjpeg --disable-libx264 --disable-libx265 --disable-x86asm --disable-mmx --disable-sse --disable-sse2 --disable-sse3 --disable-ssse3 --disable-sse4 --disable-sse42 --disable-avx --disable-avx2 --disable-armv6 --disable-armv6t2 --enable-vfp --enable-neon --disable-altivec --extra-libs=-latomic --enable-pic --cpu=cortex-a72.cortex-a53
特别留意 --enable-rkmpp --enable-libdrm 因为mpp依赖drm相关的framebuffer。
ffmpeg rkmpp依赖mpp库librockchip_mpp.so
故在configure中
enabled rkmpp && require_pkg_config rockchip_mpp rockchip_mpp rockchip/rk_mpi.h mpp_create ||
die "ERROR : Rockchip MPP was not found."; &&
enabled libdrm ||
die "ERROR: rkmpp requires --enable-libdrm";
依赖mpp 的 pkg lib/pkgconfig/rockchip_mpp.pc
内容如下:
prefix=/usr
exec_prefix=$prefix
libdir=$prefix/lib
includedir=$prefix/include
Name: rockchip_mpp
Description: Rockchip Media Process Platform
Requires.private:
Version: 1.3.8
Libs: -L$libdir -lrockchip_mpp
Libs.private:
Cflags: -I$includedir
二、rkmpp解码移植
libavcodec/Makefile:344:OBJS-$(CONFIG_H264_RKMPP_DECODER) += rkmppdec.o
libavcodec/Makefile:361:OBJS-$(CONFIG_HEVC_RKMPP_DECODER) += rkmppdec.o
libavcodec/Makefile:641:OBJS-$(CONFIG_VP8_RKMPP_DECODER) += rkmppdec.o
libavcodec/Makefile:650:OBJS-$(CONFIG_VP9_RKMPP_DECODER) += rkmppdec.o
libavcodec/rkmppdec.c
1、声明h264_rkmpp解码器
#define RKMPP_DEC_CLASS(NAME) \\
static const AVClass rkmpp_##NAME##_dec_class = \\
.class_name = "rkmpp_" #NAME "_dec", \\
.version = LIBAVUTIL_VERSION_INT, \\
;
#define RKMPP_DEC(NAME, ID, BSFS) \\
RKMPP_DEC_CLASS(NAME) \\
AVCodec ff_##NAME##_rkmpp_decoder = \\
.name = #NAME "_rkmpp", \\ //这里其实就是h264_rkmpp
.long_name = NULL_IF_CONFIG_SMALL(#NAME " (rkmpp)"), \\
.type = AVMEDIA_TYPE_VIDEO, \\
.id = ID, \\
.priv_data_size = sizeof(RKMPPDecodeContext), \\
.init = rkmpp_init_decoder, \\
.close = rkmpp_close_decoder, \\
.receive_frame = rkmpp_receive_frame, \\
.flush = rkmpp_flush, \\
.priv_class = &rkmpp_##NAME##_dec_class, \\
.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE, \\
.caps_internal = AV_CODEC_CAP_AVOID_PROBING, \\
.pix_fmts = (const enum AVPixelFormat[]) AV_PIX_FMT_DRM_PRIME, \\
AV_PIX_FMT_NONE, \\
.bsfs = BSFS, \\
;
RKMPP_DEC(h264, AV_CODEC_ID_H264, "h264_mp4toannexb")
RKMPP_DEC(hevc, AV_CODEC_ID_HEVC, "hevc_mp4toannexb")
RKMPP_DEC(vp8, AV_CODEC_ID_VP8, NULL)
RKMPP_DEC(vp9, AV_CODEC_ID_VP9, NULL)
2、注册解码器h264_rkmpp
libavcodec/allcodecs.c
static void register_all(void)
REGISTER_DECODER(H264_RKMPP, h264_rkmpp);
3、rkmpp实现ffmpeg相关解码(初始化送帧解码取解码后码流)
1)找到codec
codec = avcodec_find_decoder_by_name("h264_rkmpp");
打开codec到上下文avcodec_open2(acc, codec, NULL)
2)往codec送h264原始码流
avcodec_send_packet(acc, pkt);
这里实际上就调用到
libavcodec/rkmppdec.c
static int rkmpp_send_packet(AVCodecContext *avctx, const AVPacket *avpkt)
ret = ff_decode_get_packet(avctx, &pkt);
if (ret < 0 && ret != AVERROR_EOF)
return ret;
ret = rkmpp_send_packet(avctx, &pkt);
3)获取解码后数据
avcodec_receive_frame(acc, frame);
实际上调用到底层mpp接口
static int rkmpp_receive_frame(AVCodecContext *avctx, AVFrame *frame)
rkmpp_retrieve_frame(avctx, frame);
以上是关于RKMPP 在FFmpeg上实现硬编解码的主要内容,如果未能解决你的问题,请参考以下文章