一、编译指令:

--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);
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐