瑞芯微Rockchip开发者社区
直播中

陈秀英

7年用户 1231经验值
私信 关注
[经验]

RK3399 rkmpp解码移植步骤分享

一、编译指令:

--enable-cross-compile --cross-prefix=/home/cks/fireFlyLinuxSdk/firefly/linux_sdk/buildroot/output/rockchip_rk3399pro/host/bin/aarch64-buildroot-linux-gnu- --sysroot=/home/cks/fireFlyLinuxSdk/firefly/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);

原作者:////M////

更多回帖

发帖
×
20
完善资料,
赚取积分