树莓派移植FFmepg记录(x264、硬件编码支持)

本文详细介绍了如何在Ubuntu环境下交叉编译x264和FFmpeg,将其移植到树莓派,并添加硬件编码支持。首先,通过配置脚本交叉编译x264,然后配置并编译FFmpeg,添加x264和硬件编码器h264_omx的支持。最后,将树莓派的omx、mmal库文件添加到编译路径,完成FFmpeg的编译。文章还提供了一个简单的视频编码示例程序,展示了FFmpeg在树莓派上运行的效果。

树莓派移植FFmepg记录(x264、硬件编码支持)

参考链接:

本次移植为FFmpeg添加了x264软件编码器、Omx-rpi硬件编码的支持

1.x264交叉编译

进入源码目录,根据configure --help,编写一个脚本:

#!/bin/sh

./configure --prefix=./pi_install \
--enable-strip \
--disable-asm \
--host=arm-linux \
--cross-prefix=arm-linux-gnueabihf- \
--sysroot=/opt/rpi_tools/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/arm-linux-gnueabihf/sysroot \
--enable-shared \
# --disable-cli #配置该项不会生成可执行文件

执行后会生成makefile,执行编译命令:

make 或make -j8 #多线程编译,提高编译速度

编译完成后使用make install命令则会将生成的文件拷贝到安装目录:

boy@ubuntu:~/opensource/x264/pi_install$ tree .
.
├── bin
│   └── x264
├── include
│   ├── x264_config.h
│   └── x264.h
└── lib
    ├── libx264.so -> libx264.so.164
    ├── libx264.so.164
    └── pkgconfig
        └── x264.pc

4 directories, 6 files
boy@ubuntu:~/opensource/x264/pi_install$

可以看到已经根据我们的configure配置项,生成了so动态库、可执行文件等。

2.ffmpeg交叉编译

源码下载链接:Download FFmpeg

解压:

tar -jxvf ffmpeg-snapshot.tar.bz2

与配置x264类似,使用configure --help可以查看到有很多选项配置,这里使用参考前人的配置编写一个合适的脚本:

#!/bin/sh

./configure \
--enable-shared \
--enable-static \
--prefix=`pwd`/pi_install \
--extra-cflags=-I/home/boy/opensource/x264/pi_install/include \ #添加外部头文件路径
--extra-ldflags=-L/home/boy/opensource/x264/pi_install/lib \    #添加外部库文件路径
--enable-libx264 #使能x264编码器
--enable-cross-compile \
--cross-prefix=arm-linux-gnueabihf- \
--arch=arm \
--target-os=linux \
--enable-gpl \

**注:**这些选项貌似会有一定的先后顺序,刚开始–extra-cflags、–extra-ldflags放在后面一直编译不成功。。

生成makefile后执行make -j8进行编译,代码比较多,编译会比较慢,编译完成后make install安装到相应路径:

.
├── bin
│   ├── ffmpeg
│   └── ffprobe
├── include
│   ├── libavcodec
│   │   ├── ac3_parser.h
│   │   ├── adts_parser.h
│   │   ├── avcodec.h
│   │   ├── avdct.h
│   │   ├── avfft.h
│   │   ├── bsf.h
│   │   ├── codec_desc.h
│   │   ├── codec.h
│   │   ├── codec_id.h
│   │   ├── codec_par.h
│   │   ├── d3d11va.h
│   │   ├── defs.h
│   │   ├── dirac.h
│   │   ├── dv_profile.h
│   │   ├── dxva2.h
│   │   ├── jni.h
│   │   ├── mediacodec.h
│   │   ├── packet.h
│   │   ├── qsv.h
│   │   ├── vdpau.h
│   │   ├── version.h
│   │   ├── version_major.h
│   │   ├── videotoolbox.h
│   │   ├── vorbis_parser.h
│   │   └── xvmc.h
│   ├── libavdevice
│   │   ├── avdevice.h
│   │   ├── version.h
│   │   └── version_major.h
│   ├── libavfilter
│   │   ├── avfilter.h
│   │   ├── buffersink.h
│   │   ├── buffersrc.h
│   │   ├── version.h
│   │   └── version_major.h
│   ├── libavformat
│   │   ├── avformat.h
│   │   ├── avio.h
│   │   ├── version.h
│   │   └── version_major.h
│   ├── libavutil
│   │   ├── adler32.h
│   │   ├── aes_ctr.h
│   │   ├── aes.h
│   │   ├── attributes.h
│   │   ├── audio_fifo.h
│   │   ├── avassert.h
│   │   ├── avconfig.h
│   │   ├── avstring.h
│   │   ├── avutil.h
│   │   ├── base64.h
│   │   ├── blowfish.h
│   │   ├── bprint.h
│   │   ├── bswap.h
│   │   ├── buffer.h
│   │   ├── camellia.h
│   │   ├── cast5.h
│   │   ├── channel_layout.h
│   │   ├── common.h
│   │   ├── cpu.h
│   │   ├── crc.h
│   │   ├── des.h
│   │   ├── detection_bbox.h
│   │   ├── dict.h
│   │   ├── display.h
│   │   ├── dovi_meta.h
│   │   ├── downmix_info.h
│   │   ├── encryption_info.h
│   │   ├── error.h
│   │   ├── eval.h
│   │   ├── ffversion.h
│   │   ├── fifo.h
│   │   ├── file.h
│   │   ├── film_grain_params.h
│   │   ├── frame.h
│   │   ├── hash.h
│   │   ├── hdr_dynamic_metadata.h
│   │   ├── hdr_dynamic_vivid_metadata.h
│   │   ├── hmac.h
│   │   ├── hwcontext_cuda.h
│   │   ├── hwcontext_d3d11va.h
│   │   ├── hwcontext_drm.h
│   │   ├── hwcontext_dxva2.h
│   │   ├── hwcontext.h
│   │   ├── hwcontext_mediacodec.h
│   │   ├── hwcontext_opencl.h
│   │   ├── hwcontext_qsv.h
│   │   ├── hwcontext_vaapi.h
│   │   ├── hwcontext_vdpau.h
│   │   ├── hwcontext_videotoolbox.h
│   │   ├── hwcontext_vulkan.h
│   │   ├── imgutils.h
│   │   ├── intfloat.h
│   │   ├── intreadwrite.h
│   │   ├── lfg.h
│   │   ├── log.h
│   │   ├── lzo.h
│   │   ├── macros.h
│   │   ├── mastering_display_metadata.h
│   │   ├── mathematics.h
│   │   ├── md5.h
│   │   ├── mem.h
│   │   ├── motion_vector.h
│   │   ├── murmur3.h
│   │   ├── opt.h
│   │   ├── parseutils.h
│   │   ├── pixdesc.h
│   │   ├── pixelutils.h
│   │   ├── pixfmt.h
│   │   ├── random_seed.h
│   │   ├── rational.h
│   │   ├── rc4.h
│   │   ├── replaygain.h
│   │   ├── ripemd.h
│   │   ├── samplefmt.h
│   │   ├── sha512.h
│   │   ├── sha.h
│   │   ├── spherical.h
│   │   ├── stereo3d.h
│   │   ├── tea.h
│   │   ├── threadmessage.h
│   │   ├── timecode.h
│   │   ├── time.h
│   │   ├── timestamp.h
│   │   ├── tree.h
│   │   ├── twofish.h
│   │   ├── tx.h
│   │   ├── version.h
│   │   ├── video_enc_params.h
│   │   └── xtea.h
│   ├── libpostproc
│   │   ├── postprocess.h
│   │   ├── version.h
│   │   └── version_major.h
│   ├── libswresample
│   │   ├── swresample.h
│   │   ├── version.h
│   │   └── version_major.h
│   └── libswscale
│       ├── swscale.h
│       ├── version.h
│       └── version_major.h
├── lib
│   ├── libavcodec.a
│   ├── libavcodec.so -> libavcodec.so.59.25.100
│   ├── libavcodec.so.59 -> libavcodec.so.59.25.100
│   ├── libavcodec.so.59.25.100
│   ├── libavdevice.a
│   ├── libavdevice.so -> libavdevice.so.59.6.100
│   ├── libavdevice.so.59 -> libavdevice.so.59.6.100
│   ├── libavdevice.so.59.6.100
│   ├── libavfilter.a
│   ├── libavfilter.so -> libavfilter.so.8.29.100
│   ├── libavfilter.so.8 -> libavfilter.so.8.29.100
│   ├── libavfilter.so.8.29.100
│   ├── libavformat.a
│   ├── libavformat.so -> libavformat.so.59.20.101
│   ├── libavformat.so.59 -> libavformat.so.59.20.101
│   ├── libavformat.so.59.20.101
│   ├── libavutil.a
│   ├── libavutil.so -> libavutil.so.57.24.101
│   ├── libavutil.so.57 -> libavutil.so.57.24.101
│   ├── libavutil.so.57.24.101
│   ├── libpostproc.a
│   ├── libpostproc.so -> libpostproc.so.56.5.100
│   ├── libpostproc.so.56 -> libpostproc.so.56.5.100
│   ├── libpostproc.so.56.5.100
│   ├── libswresample.a
│   ├── libswresample.so -> libswresample.so.4.6.100
│   ├── libswresample.so.4 -> libswresample.so.4.6.100
│   ├── libswresample.so.4.6.100
│   ├── libswscale.a
│   ├── libswscale.so -> libswscale.so.6.6.100
│   ├── libswscale.so.6 -> libswscale.so.6.6.100
│   ├── libswscale.so.6.6.100
│   └── pkgconfig
│       ├── libavcodec.pc
│       ├── libavdevice.pc
│       ├── libavfilter.pc
│       ├── libavformat.pc
│       ├── libavutil.pc
│       ├── libpostproc.pc
│       ├── libswresample.pc
│       └── libswscale.pc
├── share
│   ├── ffmpeg
│   │   ├── examples
│   │   │   ├── avio_list_dir.c
│   │   │   ├── avio_reading.c
│   │   │   ├── decode_audio.c
│   │   │   ├── decode_video.c
│   │   │   ├── demuxing_decoding.c
│   │   │   ├── encode_audio.c
│   │   │   ├── encode_video.c
│   │   │   ├── extract_mvs.c
│   │   │   ├── filter_audio.c
│   │   │   ├── filtering_audio.c
│   │   │   ├── filtering_video.c
│   │   │   ├── http_multiclient.c
│   │   │   ├── hw_decode.c
│   │   │   ├── Makefile
│   │   │   ├── metadata.c
│   │   │   ├── muxing.c
│   │   │   ├── qsvdec.c
│   │   │   ├── README
│   │   │   ├── remuxing.c
│   │   │   ├── resampling_audio.c
│   │   │   ├── scaling_video.c
│   │   │   ├── transcode_aac.c
│   │   │   ├── transcoding.c
│   │   │   ├── vaapi_encode.c
│   │   │   └── vaapi_transcode.c
│   │   ├── ffprobe.xsd
│   │   ├── libvpx-1080p50_60.ffpreset
│   │   ├── libvpx-1080p.ffpreset
│   │   ├── libvpx-360p.ffpreset
│   │   ├── libvpx-720p50_60.ffpreset
│   │   └── libvpx-720p.ffpreset
│   └── man
│       ├── man1
│       │   ├── ffmpeg.1
│       │   ├── ffmpeg-all.1
│       │   ├── ffmpeg-bitstream-filters.1
│       │   ├── ffmpeg-codecs.1
│       │   ├── ffmpeg-devices.1
│       │   ├── ffmpeg-filters.1
│       │   ├── ffmpeg-formats.1
│       │   ├── ffmpeg-protocols.1
│       │   ├── ffmpeg-resampler.1
│       │   ├── ffmpeg-scaler.1
│       │   ├── ffmpeg-utils.1
│       │   ├── ffprobe.1
│       │   └── ffprobe-all.1
│       └── man3
│           ├── libavcodec.3
│           ├── libavdevice.3
│           ├── libavfilter.3
│           ├── libavformat.3
│           ├── libavutil.3
│           ├── libswresample.3
│           └── libswscale.3
└── tree.txt

18 directories, 229 files

编译完成即可拷贝头文件、库文件到自己的工程目录,编写相关应用程序。

3.添加硬件编码支持

​ libx264是使用CPU进行编码转换的,即软件编码,运行起来CPU占用率非常高。为了降低CPU占用率,决定使用硬件加速编码。

首先,需要知道两个比较关键的东西:

  • omx-rpi 树莓派的硬编码加速
  • mmal 树莓派的硬解码加速

PS:博主只用到编码,因此只添加硬件编码支持,硬件解码的添加应该大同小异,有空再折腾。

​ 树莓派交叉编译添加硬件编码支持的资料非常少,折腾了非常久( ~ . ~痛苦面具),最后在某歌搜索到一个比较有用的博客:为树莓派交叉编译FFMPEG工具 | Sunrise 博客 (yjdwbj.github.io)

①.获取树莓派omx库、头文件

根据该博客的指导,在树莓派/opt/vc目录下包含有omxmmal相关的库文件、头文件以及相关的demo,如下所示,将这些拷贝到ubuntu宿主机。

boy@ubuntu:~/opensource/vc$ tree .
.
├── bin
│   ├── containers_check_frame_int
│   ├── containers_datagram_receiver
│   ├── containers_datagram_sender
│   ├── containers_dump_pktfile
│   ├── containers_rtp_decoder
│   ├── containers_stream_client
│   ├── containers_stream_server
│   ├── containers_test
│   ├── containers_test_bits
│   ├── containers_test_uri
│   ├── containers_uri_pipe
│   ├── dtmerge
│   ├── dtoverlay
│   ├── dtoverlay-post
│   ├── dtoverlay-pre
│   ├── dtparam -> dtoverlay
│   ├── edidparser
│   ├── mmal_vc_diag
│   ├── raspistill
│   ├── raspivid
│   ├── raspividyuv
│   ├── raspiyuv
│   ├── tvservice
│   ├── vcdbg
│   ├── vcgencmd
│   ├── vchiq_test
│   ├── vcmailbox
│   └── vcsmem
├── include
│   ├── bcm_host.h
│   ├── EGL
│   │   ├── eglext_android.h
│   │   ├── eglext_brcm.h
│   │   ├── eglext.h
│   │   ├── eglext_nvidia.h
│   │   ├── egl.h
│   │   └── eglplatform.h
│   ├── GLES
│   │   ├── glext.h
│   │   ├── gl.h
│   │   └── glplatform.h
│   ├── GLES2
│   │   ├── gl2ext.h
│   │   ├── gl2.h
│   │   └── gl2platform.h
│   ├── IL
│   │   ├── OMX_Audio.h
│   │   ├── OMX_Broadcom.h
│   │   ├── OMX_Component.h
│   │   ├── OMX_Core.h
│   │   ├── OMX_ILCS.h
│   │   ├── OMX_Image.h
│   │   ├── OMX_Index.h
│   │   ├── OMX_IVCommon.h
│   │   ├── OMX_Other.h
│   │   ├── OMX_Types.h
│   │   └── OMX_Video.h
│   ├── interface
│   │   ├── debug_sym
│   │   │   └── debug_sym.h
│   │   ├── mmal
│   │   │   ├── core
│   │   │   │   ├── mmal_buffer_private.h
│   │   │   │   ├── mmal_clock_private.h
│   │   │   │   ├── mmal_component_private.h
│   │   │   │   ├── mmal_core_private.h
│   │   │   │   ├── mmal_events_private.h
│   │   │   │   └── mmal_port_private.h
│   │   │   ├── mmal_buffer.h
│   │   │   ├── mmal_clock.h
│   │   │   ├── mmal_common.h
│   │   │   ├── mmal_component.h
│   │   │   ├── mmal_encodings.h
│   │   │   ├── mmal_events.h
│   │   │   ├── mmal_format.h
│   │   │   ├── mmal.h
│   │   │   ├── mmal_logging.h
│   │   │   ├── mmal_parameters_audio.h
│   │   │   ├── mmal_parameters_camera.h
│   │   │   ├── mmal_parameters_clock.h
│   │   │   ├── mmal_parameters_common.h
│   │   │   ├── mmal_parameters.h
│   │   │   ├── mmal_parameters_video.h
│   │   │   ├── mmal_pool.h
│   │   │   ├── mmal_port.h
│   │   │   ├── mmal_queue.h
│   │   │   ├── mmal_types.h
│   │   │   ├── util
│   │   │   │   ├── mmal_component_wrapper.h
│   │   │   │   ├── mmal_connection.h
│   │   │   │   ├── mmal_default_components.h
│   │   │   │   ├── mmal_graph.h
│   │   │   │   ├── mmal_il.h
│   │   │   │   ├── mmal_list.h
│   │   │   │   ├── mmal_param_convert.h
│   │   │   │   ├── mmal_util.h
│   │   │   │   ├── mmal_util_params.h
│   │   │   │   └── mmal_util_rational.h
│   │   │   └
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值