Alan Hou的个人博客

FFmpeg音视频核心技术与实战

FF – Fast Forward

mpeg – Moving Picture Experts Group

音视频的广泛应用

音视视频基础知识

音视频封装和编码格式

像素格式

Y 表示明亮度,也即灰度值;U 和 V 表示色度

PCM音频参数

MP4格式分析

box 类型说明
ftypfile type,表明文件类型
moovmetadata container,存放媒体信息的地方
mvhdmovie header,文件的总体信息,如时长,创建时间等
traktrack or stream container,存放视频/音频流的容量
tkhdtrack header,track 的总体信息,如时长,宽高等
mdiatrak media information container
mdhdmedia header,定论 TimeScale,trak需要通过 TimeScale 换算成真实时间
hdlrhandler,表明本 trak 类型,指明是 video/audio 还是 hint
minfmedia information container,数据在子 box 中
stblsample table box,存放时间/偏移的映射关系表,数据在子 box中
stsdsample descriptions
stts(decoding) time-to-sample,“时戳-sample 序号”的映射表
stscsample-to-chunk,sample 和 chunk 的映射表,这里的算法比较巧妙
stszsample size,每个 sample 的大小
stz2sample size,另一种 sample size 的存储算法,更节省空间
stsssync sample table,可随机访问的 sample 列表(关键帧列表)
stcochunk offset,每个 chunk 的偏移,sample 的偏移可根据其它 box 推算出来
co6464-bit chunk offset
mdatmedia data container,具体的媒体数据

http://download.qt.io/

FFmpeg 日志系统

播放器架构 & 渲染流程

音视频解码由 FFmpeg 完成,播放、渲染由 SDL 实现

FFmpeg 从何而来?

FFmpeg 是一个非常优秀的多媒体框架,可运行在 Linux、Windows和 Mac 平台上,能够解码、编码、转码、复用、解复用、过滤音视频数据。

本文主要内容

安装

GitHub 地址:https://github.com/FFmpeg/FFmpeg

以上–enable-debug –disable-optimizations主要是便于开发调试,生产环境请勿使用

Windows 下安装 FFmpeg

FFmpeg常用命令实战

基本信息查询命令

录制命令

参照如上命令在使用内置摄像头(-i 0)录制时会出现报错:

修改命令如下:

分解/复用命令



处理原始数据命令

裁剪与合并命令

图片/视频互转命令

直播相关命令

测试流地址链接:https://blog.csdn.net/github_30662571/article/details/72466091

各种滤镜命令

FFmpeg 常用命令

FFmpeg开发必备C语言回顾

Vim 编辑器常用命令

演示代码: GitHub仓库

常用基本类型

整型:short、int、long
浮点型:float、double
Char 型:char
无符号型:void

指针与数组

指针就是内存地址:void*、char*,指针本身也可进行运算

数组(连续同一类型):char c[2]、int arr[10]

结构体、枚举类型

文件操作
文件类型 FILE* file;
打开文件 FILE* fopen(path, mode); // a+
关闭文件 fclose(FILE*);

操作系统管理内存:栈空间(4M, 8M,操作系统自动分配)、堆空间(4G)、内存映射
内存的分配和释放
分配内存 void* mem = malloc(size);
释放内存 free(mem);
内存泄漏和野指针
不断地向系统申请内存
申请的内存不用,也不释放
占用别人的内存称作野指针

C语言编译器


预编译→编译→链接(动态链接 /静态链接)

调试器(gdb/lldb)

调试信息包含:指令地址、对应源代码及行号

FFmpeg多媒体文件处理

演示代码:GitHub 仓库

FFmpeg 代码结构

  • libavcodec: 提供了一系列编解码器的实现
  • libavformat: 实现在流协议,容器格式及其本IO访问
  • libavutil: 包括了hash器,解码器和各利工具函数
  • libavfilter: 提供了各种音视频过滤器
  • libavdevice: 提供了访问捕获设备和回放设备的接口
  • libswresample: 实现了混音和重采样
  • libswscale: 实现了色彩转换和缩放工能

多媒体文件的基本概念

几个重要的结构体

FFmpeg 操作流数据的基本步骤

解复用➞获取流➞读数据包➞释放资源

打印音/视频信息

抽取音频数据

抽取视频数据

◆Start code
◆SPS/PPS
◆codec→extradata

格式互转

视频截取 

av_seek_frame()

FFmpeg编解码实战

演示代码:GitHub 仓库

FFmpeg H264解码

libavcodec/avcodec.h

常用数据结构

结构体内存的分配与释放

解码步骤

FFmpeg H264编码

H264编码流程

实战-视频转图片

FFmpeg AAC 编解码

FFmpeg SDL音视频渲染实战

演示代码:GitHub 仓库

SDL(Simple DirectMedia Layer),是由 C 语言实现的跨平台的媒体开源库,多用于开发游戏、模拟器、媒体播放器等多媒体应用领域。

http://www.libsdl.org/index.php

编译安装

使用 SDL基本步骤

SDL_CreateWindow()/SDL_DestroyWindow()

SDL_CreateRenderer()/SDL_DestroyRenderer()/SDL_RenderClear()/SDL_RenderPresent()

SDL将所有事件都存放在一个队列中;所有对事件的操作,其实就是对队列的操作。

SDL事件种类

事件处理:SDL_PollEvent(轮询), SDL_WaitEvent, SDL_WaitEventTimeout

SDL渲染基本原理

SDL纹理相关 API

YUV 视频播放器

创建线程

SDL 更新纹理

SDL音频处理

播放音频基本流程:打开音频设备->设置音频参数->向声卡喂数据->播放音频->关闭设备

播放音频的基本原则

SDL 音频 API

FFmpeg播放器核心功能开发

演示代码:GitHub 仓库

最简单的播放器一

最简单的播放器二

线程的互斥与同步:通过操作系统的锁与信号量

锁的种类:读写锁、自旋锁、可重入锁

SDL创建线程

SDL锁

SDL条件变量(信号量)

参考教程:http://dranger.com/ffmpeg/tutorial04.html

 

线程的退出机制

音视频同步

如何在Android下使用FFmpeg

JNI基本概念

安卓投屏至电脑:https://www.vysor.io/

JAVA 调用 C、C++的方法

Signature

原始类型的 Signature

Java 类型符号
booleanZ
byteB
charC
shortS
intI
longL
floatF
doubleD
voidV

类的 Signature

参考代码FirstJNI:GitHub仓库

C/C++调Java 方法

参考代码testc2j:GitHub仓库

安卓下使用 FFmpeg(需修改MainActivity中的videoPath):GitHub仓库

如何在iOS下使用FFmpeg

参考代码:GitHub 仓库

https://github.com/Bilibili/ijkplayer

音视频进阶

行业痛点

常见问题

1、nasm/yasm not found or too old. Use –disable-x86asm for a crippled build.

2、ERROR: libfdk_aac not found

3、warning: ‘av_register_all’ is deprecated

修改为:

4、MacOS Mojave ffplay 只播放声音不显示画面

解决办法:

退出移动版