FFmpeg学习(一)开篇
为什么要学习FFmpeg?本人希望深入研究音视频领域,源码阅读音视频领域内容丰富,源码阅读我计划从多个方面逐步学习:FFmpeg常用功能实践、源码阅读FFmpeg源码研究、源码阅读OpenGL、源码阅读OpenGLES、源码阅读linuxcn源码Metal、源码阅读AR、源码阅读WebRTC、源码阅读直播架构等。源码阅读
当前音视频有哪些应用场景?从众多应用场景可以看出,源码阅读音视频技术至关重要,源码阅读尤其在5G时代,源码阅读网络传输问题得到极大提升,源码阅读音视频需求将爆发式增长。源码阅读以下是一个简单播放器架构图:
音频解码和视频解码一般使用FFmpeg解码,iOS8之后提供了VideoToolBox框架支持硬解码。视频渲染通常使用OpenGL直接利用GPU渲染,还有GPUImage、SDL、VLC等第三方框架。
音视频播放中的音视频同步是一项复杂的技术。学习一项技术需要高效的方法,只有不断实践才能深刻理解。学习FFmpeg也需要好的文档,以下列举一些必备的学习文档地址:
以上都是英文文档,如果英文学习困难,可以参考以下中文资料:
此外,推荐两本非常好的书籍:
相关学习资料推荐,点击下方链接免费报名,先码住不迷路~
1. FFmpeg简介:FFmpeg是一套用于记录、转换数字音频、视频并将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多code都是从头开发的。FFmpeg在Linux平台下开发,但也可以在其他操作系统环境中编译运行,包括Windows、Mac OS X等。这个项目最早由Fabrice Bellard发起,年至年间由Michael Niedermayer主要负责维护。许多FFmpeg的开发人员都来自MPlayer项目,当前FFmpeg也是放在MPlayer项目组的服务器上。项目的名称来自MPEG视频编码标准,前面的"FF"代表"Fast Forward"。
2. FFmpeg能做什么
3. FFmpeg架构模块组成:我们先看一张FFmpeg的架构图:
下载好的源码,我们也可以看到大致的源码结构:
3.1 libavutil
3.2 libavformat
FFmpeg是否支持某种媒体封装格式,取决于编译时是卖卡密源码否包含了该格式的封装库。根据实际需求,可进行媒体封装格式的扩展,增加自己定制的封装格式,即在AVFormat中增加自己的封装处理模块。
3.3 libavcodec
AVCodec中实现了目前多媒体绝大多数的编解码格式,既支持编码,也支持解码。AVCodec除了支持MPEG4、AAC、MJPEG等自带的媒体编解码格式之外,还支持第三方的编解码器,如H.(AVC)编码,需要使用x编码器;H.(HEVC)编码,需要使用x编码器;MP3(mp3lame)编码,需要使用libmp3lame编码器。如果希望增加自己的编码格式或硬件编解码,则需要在AVCodec中增加相应的编解码模块。
3.4 libavfilter
3.5 libavdevice
3.6 libswscale
3.7 libpostproc
3.8 libswrressample
3.9 ffmpeg
3. ffsever
3. ffplay
4. FFmpeg安装:下载源码后,我们可以查看一下目录结构:
输入./configure --help命令查看配置信息
内容太多需要分页,输入./configure --help | more
从上面的帮助,我们可以尝试输入:./configure --list-decoders查看所有解码器
接下来我们可以尝试输入:./configure --list-encoders查看所有编码器
接下来我们可以尝试输入:./configure --list-filters查看所有滤镜器
接下来我们可以尝试输入:./configure --list-muxers查看FFmpeg的封装,封装Muxing是指将压缩后的编码封装到一个容器格式中,我们输入./configure --list-muxers来查看FFmpeg支持哪些容器格式:
从上面打印信息来看,FFmpeg支持生成裸流文件,如H.、AAC、PCM,也支持一些常见的格式,如MP3、MP4、FLV、M3U8、WEBM等。
从上面解封装又称为解复用格式的支持信息中可以看到,FFmpeg支持的demuxter非常多,包含image、MP3、FLV、MP4、MOV、AVI等。
从支持的协议列表中可以看到,FFmpeg支持的流媒体协议比较多,包括MMS、HTTP、HTTPS、HLS、RTMP、RTP,甚至支持TCP、UDP,怎样看delphi源码它还支持使用file协议的本地文件操作和使用concat协议支持的多个文件串流操作。
接下来我们可以尝试输入:./configure --list-parsers查看FFmpeg支持的解析器
接下来我们可以尝试输入:./configure --list-bsfs查看FFmpeg支持的字节流过滤器
接下来我们可以尝试输入:./configure --list-indevs查看有效的输入设备
接下来我们可以尝试输入:./configure --list-outdevs查看有效的输出设备
FFmpeg源码分析:视频滤镜介绍(上)
FFmpeg在libavfilter模块提供了丰富的音视频滤镜功能。本文主要介绍FFmpeg的视频滤镜,包括黑色检测、视频叠加、色彩均衡、去除水印、抗抖动、矩形标注、九宫格等。
黑色检测滤镜用于检测视频中的纯黑色间隔时间,输出日志和元数据。若检测到至少具有指定最小持续时间的黑色片段,则输出开始、结束时间戳与持续时间。该滤镜通过参数选项rs、gs、bs、rm、gm、bm、rh、gh、bh来调整红、绿、蓝阴影、基调与高亮区域的色彩平衡。
视频叠加滤镜将两个视频的所有帧混合在一起,称为视频叠加。顶层视频覆盖底层视频,输出时长为最长的视频。实现代码位于libavfilter/vf_blend.c,通过遍历像素矩阵计算顶层像素与底层像素的混合值。
色彩均衡滤镜调整视频帧的RGB分量占比,通过参数rs、gs、bs、rm、gm、bm、rh、gh、bh在阴影、基调与高亮区域进行色彩平衡调整。
去除水印滤镜通过简单插值抑制水印,仅需设置覆盖水印的矩形。代码位于libavfilter/vf_delogo.c,核心是基于矩形外像素值计算插值像素值。
矩形标注滤镜在视频画面中绘制矩形框,用于标注ROI兴趣区域。在人脸检测与人脸识别场景中,python程序隐藏源码检测到人脸时会用矩形框进行标注。
绘制x宫格滤镜用于绘制四宫格、九宫格,模拟画面拼接或分割。此滤镜通过参数x、y、width、height、color、thickness来定义宫格的位置、大小、颜色与边框厚度。
调整yuv或rgb滤镜通过计算查找表,绑定像素输入值到输出值,然后应用到输入视频,实现色彩、对比度等调整。相关代码位于vf_lut.c,支持四种类型:packed 8bits、packed bits、planar 8bits、planar bits。
将彩色视频转换为黑白视频的滤镜设置U和V分量为,实现效果如黑白视频所示。
图像格式--FFMPEG代码走读-TIFF格式编码
本文从FFMPEG源码角度解读TIFF编码内容,无需过多介绍,直接开启解读。TIFF编码涉及到的结构体TiffEncoderContext,用于存储与TIFF编码相关的上下文信息,包括编码上下文信息、长宽信息、压缩信息、yuv数据信息、缓冲区信息、Strip信息,以及编解码算法和级别信息等。
TIFF文件使用标签(Tags)存储图像的元数据和其他信息,每个标签存储特定类型的信息,如图像宽度、高度、颜色深度等。在FFMPEG中包含的所有tag相关数据可参照下图查看。
此外,还存在特定的补充标签,如DNG和CinemaDNG格式。DNG是由Adobe开发的一种开放的RAW图像格式,基于TIFF/EP标准,在TIFF基础上增加了存储更多摄影信息和元数据的特定标签。CinemaDNG是一个基于DNG的开放标准,专为**和视频制作中的RAW图像序列设计,包含与静态图像DNG类似的生鲜官网源码标签,同时增加了一些特定于视频和**制作的标签,用于管理处理高动态范围的RAW视频数据。
TIFF编码代码位于libavcodec\tiffenc.c文件中。ff_tiff_encoder描述了一个TIFF图像编码器,采用标准FFmpeg库的API封装,包含TIFF编码器的各种信息和函数指针,便于对接到FFMPEG框架。
encode_init函数用于初始化TIFF编码器上下文,并进行必要的检查和设置。encode_close函数在编码器关闭时进行资源清理,确保无内存泄漏。add_entry将一个条目添加到TIFF文件目录中。encode_strip用于将图像数据编码为TIFF文件的一个条带。pack_yuv将YUV图像数据打包成适合TIFF格式的条带。
encode_frame函数主要作用是将一帧图像编码为TIFF格式。具体步骤包括初始化上下文和变量、设置编码器上下文参数、处理不同像素格式、计算每行字节数和数据包大小、分配内存、处理图像数据、写入TIFF文件头、添加TIFF标签、写入目录偏移量并完成编码。
至此,TIFF编码过程解析完毕。源码编译与调试有助于深入理解,增进对TIFF编码的认识。
FFMPEG详解(完整版)
FFMPEG详解
FFMPEG是自由软件中最完备的多媒体支持库,几乎涵盖了所有常见数据封装格式、多媒体传输协议以及音视频编解码器。对于多媒体技术开发工程师来说,深入研究FFMPEG是必不可少的。它的重要性如同kernel之于嵌入式系统工程师。FFMPEG的大部分代码遵循LGPL许可证,少部分遵循GPL许可证,因此其被广泛应用于各种第三方播放器和商业软件中,但需要注意在商业应用中可能涉及专利风险。
FFMPEG功能分为多个模块,如核心工具、媒体格式、编解码、设备和后处理模块,分别提供公用功能函数、实现多媒体文件读写、音视频编解码、设备操作以及音视频后处理。
FFMPEG提供命令行工具ffmpeg,其使用方法包含三部分:全局参数、输入文件参数、输出文件参数,每组输入参数以‘-i’结束,每组输出参数以文件名结束。
在使用FFMPEG时,需要熟悉基本选项、流标识、音频选项、视频选项等,同时,FFMPEG支持多种滤镜和高级选项,实现特定用例。
编译FFMPEG时,通过configure脚本实现定制和裁剪,以适应不同系统和需求。configure脚本生成的config.mak和config.h文件在Makefile和源代码层次上控制编译过程。
深入FFMPEG示例程序包括解码功能,实现复杂多媒体播放器的基础解复用、解码、数据分析过程。用户接口涉及数据结构、编解码器、媒体流和容器等概念,通过FFMPEG提供的AVFormatContext、AVStream、AVCodecContext等结构进行抽象。
时间信息在FFMPEG中用于实现多媒体同步,包括流内和流间同步。FFMPEG通过AVPacket结构为每个数据包打上时间标签,支持上层应用的同步机制。时间信息的获取和操作对于多媒体应用至关重要。
FFMPEG的API分为读系列、编解码系列和写系列,实现媒体数据的获取、编码、解码和输出。关键函数包括avformat_open_input、avformat_find_stream_info、av_read_frame等,用于文件输入、流信息查找和数据读取。
FFMPEG支持过滤链,通过AVFilter、AVFilterPad和AVFilterLink实现视频帧和音频采样数据的后续处理,如图像缩放、增强和声音重采样。
综上所述,FFMPEG是多媒体开发工程师不可或缺的工具,其功能强大且适用范围广泛,深入理解FFMPEG对于开发高性能多媒体应用至关重要。
FFmpeg开发笔记(十二)Linux环境给FFmpeg集成libopus和libvpx
在FFmpeg开发中,为了支持WebM格式的视频,特别是其音频编码的Opus和视频编码的VP8/VP9,需要在Linux环境中集成libopus和libvpx库。以下是具体的操作步骤:
1. 安装libopus:首先,从ftp.osuosl.org下载libopus源码,如libopus-1.4。解压后,运行`./configure`进行配置,接着执行`make`和`make install`编译并安装。
2. 安装libvpx:访问github.com/webmproject获取libvpx-1..1源码。解压后,使用`./configure --enable-pic --disable-examples --disable-unit-tests`配置,然后编译并安装,即`make`和`make install`。
3. 重新编译FFmpeg:由于FFmpeg默认不支持opus和vpx,需要在FFmpeg源码目录下,通过`./configure`命令添加`--enable-libopus --enable-libvpx`选项。接着执行`make clean`清理,`make -j4`编译,最后使用`make install`安装并检查FFmpeg版本以确认成功启用。
按照以上步骤,你就能在Linux环境中成功集成libopus和libvpx到FFmpeg,从而支持WebM格式的视频编码。《FFmpeg开发实战:从零基础到短视频上线》一书中的详细说明提供了完整的指导。
FFmpeg编解码处理-转码全流程简介
本文基于 FFmpeg 4.1 版本,对转码全流程进行简要介绍。转码过程主要分为输入、输出、转码、播放四大环节,其中转码功能占据较大比重。转码的核心在于解码和编码两部分,尽管在实际示例程序中,编码、解码与输入、输出难以完全分割。具体流程如下:
1. **解复用**:从输入文件中读取编码帧,判断流类型,并将编码帧送入对应的解码器(视频或音频)。
2. **解码**:将编码帧解码,生成原始帧。
3. **滤镜**:FFmpeg 提供多种滤镜,用于处理原始帧数据。本例中使用空滤镜,以确保视频流输出的像素格式转换为编码器支持的格式,音频流输出的声道布局同样转换为编码器支持的布局。这一步为编码操作做好准备。
4. **编码**:原始视音频帧通过编码器转换为编码帧。
5. **复用**:编码帧按不同流类型交织写入输出文件。
**转码例程简介**:
转码功能复杂,示例程序难以简化。本例程支持指定视音频编码格式与输出文件封装格式。若指定格式为 "copy",输出流将采用与输入流相同的编码格式。与 FFmpeg 命令不同,此例程在 "copy" 时,会进行编码与解码操作,耗时较长。验证方法与命令行操作类似,源代码文件主要包括在 main. c 中的 transcode_video()、transcode_audio() 和 transcode_audio_with_afifo() 函数,这些函数展示了音视频转码的实现方法。
**视频与音频转码流程**:
- **视频转码**:主要在 transcode_video() 函数中实现,处理流程包含解复用、解码、滤镜处理和编码等步骤。
- **音频转码**:在 transcode_audio() 函数中实现,同样涉及解复用、解码、滤镜处理和编码。
**时间戳处理**:
在封装格式处理中,时间基的理解不是必需的,但在编解码过程中,正确的时间基转换至关重要。容器的时间基与编解码器上下文的时间基不同,解码编码过程中需要进行转换。对于视频,原始帧时间基为 1/framerate,编码前需将容器时间基转换为 1/framerate,编码后转换回输出容器的时间基。对于音频,原始帧时间为 1/sample_rate,同样需要进行相应的时间基转换,若使用音频 FIFO,需使用 1/sample_rate 时间基重新生成时间戳信息。
**编译与验证**:
下载示例代码,执行 make 命令生成可执行文件。使用测试文件进行验证,观察文件格式,并指定编码格式与封装格式生成输出文件。
零基础读懂视频播放器控制原理: ffplay 播放器源代码分析
视频播放器的工作原理基于对音视频帧序列的控制。不同播放器可能在音视频同步上采用更复杂的帧预测技术,以提升音频与视频的同步性。ffplay,作为FFmpeg自带的播放器,使用了FFmpeg解码库与用于视频渲染显示的SDL库。本文将详细分析ffplay源码,旨在用基础且系统的方法,解读音视频同步、播放/暂停、快进/后退等控制原理。
相较于在移动端查看音视频代码,使用PC端通过VS进行查看和调试,能更高效迅速地分析播放器原理。由于ffplay在命令行界面的使用体验不够直观,本文将分析在CSDN上移植到VC的ffplay代码(ffplay for MFC)。
文章将按照以下结构展开:
一、解析MP4文件结构,理解视频文件的构成与参数。
二、从最简单的播放器入手,分析FFmpeg解码与SDL显示流程。
三、提出并解答五个关键问题,涉及音视频组合、同步、时间与帧数控制等。
四、深入ffplay代码,从总体流程图入手,理解其代码结构。
五、详细分析视频播放器的操作控制机制,包括关键结构体VideoState的作用,PTS和DTS的原理与应用,以及如何实现音视频同步。
六、总结反思,强调基础概念、流程图与PC端调试的重要性。
通过本文,我们将深入解析ffplay播放器的音视频播放与控制原理,旨在提供更直观、基础的解读方式,帮助读者理解和掌握视频播放器的核心技术。
FFmpeg源码分析: AVStream码流
在AVCodecContext结构体中,AVStream数组存储着所有视频、音频和字幕流的信息。每个码流包含时间基、时长、索引数组、编解码器参数、dts和元数据。索引数组用于保存帧数据包的offset、size、timestamp和flag,方便进行seek定位。
让我们通过ffprobe查看mp4文件的码流信息。该文件包含5个码流,是双音轨双字幕文件。第一个是video,编码为h,帧率为.fps,分辨率为x,像素格式为yuvp。第二个和第三个都是audio,编码为aac,采样率为,立体声,语言分别为印地语和英语。第四个和第五个都是subtitle,语言为英语,编码器为mov_text和mov_text。
调试实时数据显示,stream数组包含以下信息:codec_type(媒体类型)、codec_id、bit_rate、profile、level、width、height、sample_rate、channels等编解码器参数。
我们关注AVCodecContext的编解码器参数,例如codec_type、codec_id、bit_rate、profile、level、width、height、sample_rate和channels。具体参数如下:codec_type - 视频/音频/字幕;codec_id - 编码器ID;bit_rate - 位率;profile - 编码器配置文件;level - 编码器级别;width - 宽度;height - 高度;sample_rate - 采样率;channels - 音道数。
AVStream内部的nb_index_entries(索引数组长度)和index_entries(索引数组)记录着offset、size、timestamp、flags和min_distance信息。在seek操作中,通过二分查找timestamp数组来定位指定时间戳对应的帧。seek模式有previous、next、nearest,通常使用previous模式向前查找。
时间基time_base在ffmpeg中用于计算时间戳。在rational.h中,AVRational结构体定义为一个有理数,用于时间计算。要将时间戳转换为真实时间,只需将num分子除以den分母。
2024-11-30 10:05
2024-11-30 09:34
2024-11-30 09:20
2024-11-30 08:47
2024-11-30 08:13