树莓派移植FFmepg记录(x264、硬件编码支持)
参考链接:
- 树莓派编译安装FFmpeg(添加H.264硬件编解码器支持)_唐传林的博客-CSDN博客
- ubuntu下交叉编译X264和FFMPEG到RK3399平台(编译器:aarch64-linux-gcc)-阿里云开发者社区 (aliyun.com)
- FFmpeg encode_video.c示例 - 简书 (jianshu.com)
本次移植为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目录下包含有omx、mmal相关的库文件、头文件以及相关的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
│ │ │ └

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

被折叠的 条评论
为什么被折叠?



