一文读懂 Android FFmpeg 视频解码过程与实战分析

本文首先以 FFmpeg 视频解码为主题,主要介绍了 FFmpeg 进行解码视频时的主要流程、基本原理;其次,文章还讲述了与 FFmpeg 视频解码有关的简单应用,包括如何在原有的 FFmpeg 视频解码的基础上按照一定时间轴顺序播放视频、如何在播放视频时加入 seek 的逻辑;除此之外,文章重点介绍了解码视频时可能容易遗漏的细节,最后是简单地阐述了下如何封装一个具有基本的视频解码功能的 VideoDecoder。

前言

FFmpeg

FFmpeg 是一套可以用来录制、转换数字音频、视频,并能将其转化为流的开源计算机程序,它可生成用于处理和操作多媒体数据的库,其中包含了先进的音视频解码库 libavcodec 和音视频格式转换库 libavformat

FFmpeg 六大常用功能模块

  • libavformat:多媒体文件或协议的封装和解封装库,如 mp4、flv 等文件封装格式,rtmp、rtsp 等网络协议封装格式;

  • libavcodec:音视频解码核心库;

  • libavfilter:音视频、字幕滤镜库;

  • libswscale:图像格式转换库;

  • libswresample:音频重采样库;

  • libavutil:工具库

视频解码基础入门

  1. 解复用(Demux):解复用也可叫解封装。这里有一个概念叫封装格式,封装格式指的是音视频的组合格式,常见的有 mp4、flv、mkv 等。通俗来讲,封装是将音频流、视频流、字幕流以及其他附件按一定规则组合成一个封装的产物。而解封装起着与封装相反的作用,将一个流媒体文件拆解成音频数据和视频数据等。此时拆分后数据是经过压缩编码的,常见的视频压缩数据格式有 h264。

一文读懂 Android FFmpeg 视频解码过程与实战分析_第1张图片

  1. 解码(Decode):简单来说,就是对压缩的编码数据解压成原始的视频像素数据,常用的原始视频像素数据格式有 yuv。

一文读懂 Android FFmpeg 视频解码过程与实战分析_第2张图片

  1. 色彩空间转换(Color Space Convert):通常对于图像显示器来说,它是通过 RGB 模型来显示图像的,但在传输图像数据时使用 YUV 模型可以节省带宽。因此在显示图像时就需要将 yuv 像素格式的数据转换成 rgb 的像素格式后再进行渲染。

  2. 渲染(Render):将前面已经解码和进行色彩空间转换的每一个视频帧的数据发送给显卡以绘制在屏幕画面上。

一、 引入 FFmpeg 前的准备工作


1.1 FFmpeg so 库编译

  • 在 FFmpeg 官网下载源码库并解压;

  • 下载 NDK 库并解压;

  • 配置解压后的 FFmpeg 源码库目录中的 configure,修改高亮部分几个参数为以下的内容,主要目的是生成 Android 可使用的 名称-版本.so 文件的格式;

# ······

# build settings

SHFLAGS=‘-shared -Wl,-soname,$$(@F)’

LIBPREF=“lib”

LIBSUF=“.a”

FULLNAME=‘(NAME)(NAME)(NAME)(BUILDSUF)’

LIBNAME=‘(LIBPREF)(LIBPREF)(LIBPREF)(FULLNAME)$(LIBSUF)’

SLIBPREF=“lib”

SLIBSUF=“.so”

SLIBNAME=‘(SLIBPREF)(SLIBPREF)(SLIBPREF)(FULLNAME)$(SLIBSUF)’

SLIBNAME_WITH_VERSION=‘(SLIBNAME).(SLIBNAME).(SLIBNAME).(LIBVERSION)’

# 已修改配置

SLIBNAME_WITH_MAJOR=‘(SLIBNAME)(SLIBNAME)(SLIBNAME)(FULLNAME)-(LIBMAJOR)(LIBMAJOR)(LIBMAJOR)(SLIBSUF)’

LIB_INSTALL_EXTRA_CMD=‘$(RANLIB)"(RANLIB)"(RANLIB)"(LIBDIR)/$(LIBNAME)"’

SLIB_INSTALL_NAME=‘$(SLIBNAME_WITH_MAJOR)’

SLIB_INSTALL_LINKS=‘$(SLIBNAME)’

# ······

  • 在 FFmpeg 源码库目录下新建脚本文件 build_android_arm_v8a.sh,在文件中配置 NDK 的路径,并输入下面其他的内容;

# 清空上次的编译

make clean

# 这里先配置你的 NDK 路径

export NDK=/Users/bytedance/Library/Android/sdk/ndk/21.4.7075529

TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/darwin-x86_64

function build_android

{

./configure \

–prefix=$PREFIX \

–disable-postproc \

–disable-debug \

–disable-doc \

–enable-FFmpeg \

–disable-doc \

–disable-symver \

–disable-static \

–enable-shared \

–cross-prefix=$CROSS_PREFIX \

–target-os=android \

–arch=$ARCH \

–cpu=$CPU \

–cc=$CC \

–cxx=$CXX \

–enable-cross-compile \

–sysroot=$SYSROOT \

–extra-cflags=“-Os -fpic $OPTIMIZE_CFLAGS” \

–extra-ldflags=“$ADDI_LDFLAGS”

make clean

make -j16

make install

echo “============================ build android arm64-v8a success ==========================”

}

# arm64-v8a

ARCH=arm64

CPU=armv8-a

API=21

CC=TOOLCHAIN/bin/aarch64−linux−androidTOOLCHAIN/bin/aarch64-linux-androidTOOLCHAIN/bin/aarch64linuxandroidAPI-clang

CXX=TOOLCHAIN/bin/aarch64−linux−androidTOOLCHAIN/bin/aarch64-linux-androidTOOLCHAIN/bin/aarch64

你可能感兴趣的:(android,ffmpeg,音视频)