视频编码流程详解

article/2025/10/15 20:33:36


1、视频编码整体流程

在这里插入图片描述


2、FFmpeg视频编码详细流程

从本地读取YUV数据编码为H264格式的数据,然后再存入到本地,编码后的数据有带startcode。
与FFmpeg示例音频编码的流程基本一致。

在这里插入图片描述

3、关键函数说明

(1)avcodec_find_encoder_by_name:根据指定的编码器名称查找注册的编码器。

(2)avcodec_alloc_context3:为AVCodecContext分配内存。

(3)avcodec_open2:打开编码器。

(4)avcodec_send_frame:将AVFrame非压缩数据给编码器。

(5)avcodec_receive_packet:获取到编码后的AVPacket数据,收到的packet需要自己释放内存。

(6)av_frame_get_buffer:为音频或视频帧分配新的buffer。在调用这个函数之前,必须在AVFame上设置好以下属性:format(视频为像素格式,音频为样本格式)、nb_samples(样本个数,针对音频)、channel_layout(通道类型,针对音频)、width/height(宽高,针对视频)。

(7)av_frame_make_writable:确保AVFrame是可写的,使用av_frame_make_writable()的问题是,在最坏的情况下,它会在您使用encode再次更改整个输入frame之前复制它. 如果frame不可写,av_frame_make_writable()将分配新的缓冲区,并复制这个输入input frame数据,避免和编码器需要缓存该帧时造成冲突。

(8)av_image_fill_arrays:存储一帧像素数据存储到AVFrame对应的data buffer。

(9)int av_image_get_buffer_size(enum AVPixelFormat pix_fmt, int width, int height, int align);

作用:通过指定像素格式、图像宽、图像用来计算所需的内存大小。

参数align:此参数是设定内存对齐的对齐数,也就是按多大的字节进行内存对齐:

  • 比如设置为1,表示按1字对齐,那么得到的结果就是与实际的内存大小一样。3
  • 再比如设置为4,表示按4字节对齐。也就是内存的起始地址必须是4的整倍数。

(10)int av_image_alloc(uint8_t *pointers[4], int linesizes[4], int w, int h, enum AVPixelFormat pix_fmt, int align);

  • pointers[4]:保存图像通道的地址。如果是RGB,则前三个指针分别指向R,G,B的内存地址。第四个指针保留不用 linesizes[4]:保存图像每个通道的内存对齐的步长,即一行的对齐内存的宽度,此值大小等于图像宽度。
  • w:要申请内存的图像宽度。
  • h:要申请内存的图像高度。
  • pix_fmt:要申请内存的图像高度。
  • align:用于内存对齐的值。
  • 返回值:所申请的内存空间的总大小。如果是负值,表示申请失败。

(11)int av_image_fill_arrays(uint8_t *dst_data[4], int dst_linesize[4], const uint8_t *src, enum AVPixelFormat pix_fmt, int width, int height, int align);
av_image_fill_arrays()函数本身不具备内存申请的功能,此函数类似于格式化已经申请的内存,即通av_malloc()函数申请的内存空间,或者av_frame_get_buffer()函数申请的内存空间。

  • dst_data[4]: [out]对申请的内存格式化为三个通道后,分别保存其地址;
  • dst_linesize[4]: [out]格式化的内存的步长(即内存对齐后的宽度);
  • *src: [in]av_alloc()函数申请的内存地址;
  • pix_fmt: [in] 申请 src内存时的像素格式;
  • width: [in]申请src内存时指定的宽度;
  • height: [in]申请scr内存时指定的高度;
  • align: [in]申请src内存时指定的对齐字节数。

编码出来的h264数据可以直接使用ffplay播放,也可以使用VLC播放。


4、H264的码率设置

(1)什么是视频码率?
视频码率是视频数据(包含视频色彩量、亮度量、像素量)每秒输出的位数。一般用的单位是kbps。


(2)设置码率的必要性
在网络视频应⽤中,视频质量和网络带宽占用是相矛盾的。通常情况下,视频流占用的带宽越高则视频质量也越高,需要的网络带宽也越大,解决这一矛盾的钥匙当然是视频编解码技术。评判一种视频编解码技术的优劣,是比较在相同的带宽条件下,哪个视频质量更好;在相同的视频质量条件下,哪个占用的网络带宽更少(文件体积小)。

是不是视频码率越高,质量越好呢?理论上是这样的。然而在肉眼分辨的范围内,当码率高到一定程度时,就没有什么差别了。所以码率设置有它的最优值,H.264(也叫AVC或x264)的文件中,视频的建议码率如下:
在这里插入图片描述

(2)手机设置码率建议
在这里插入图片描述

5、FFmpeg与H264编码指南

鉴于x264的参数众多,各种参数的配合复杂,为了使用者方便,x264建议如无特别需要可使用preset和tune设置。
这套开发者推荐的参数较为合理,可在此基础上在调整一些具体参数以符合实际需要,手动设定的参数会覆盖preset和tune的参数。

使用ffmpeg -h encoder=libx264 查询相关支持的参数。


(1)preset
预设是一系列参数的集合,这个集合能够在编码速度和压缩率之间做出权衡。
一个编码速度稍慢的预设会提供更高的压缩效率(压缩效率是以文件大小来衡量的)。这就是说,假如你想得到一个指定大小的文件或者采用恒定比特率编码模式,你可以采用一个较慢的预设来获得更好的质量。同样的,对于恒定质量编码模式,你可以通过选择一个较慢的预设轻松地节省比特率。如果你很有耐心,通常的建议是使用最慢的预设。目前所有的预设按照编码速度降序排列为:
ultrafast > superfast > veryfast > faster > fast > medium – default preset > slow > slower > veryslow > placebo - ignore this as it is not useful (see FAQ)

默认为medium级别。


(2)tune
une是x264中重要性仅次于preset的选项,它是视觉优化的参数,tune可以理解为视频偏好(或者视频类型),tune不是一个单一的参数,而是由一组参数构成-tune来改变参数设置。

当前的 tune包括:

  • film:电影类型,对视频的质量非常严格时使用该选项;
  • animation:动画片,压缩的视频是动画片时使用该选项;
  • grain:颗粒物很重,该选项适用于颗粒感很重的视频;
  • stillimage:静态图像,该选项主要用于静止画面比较多的视频;
  • psnr:提高psnr,该选项编码出来的视频psnr比较高;
  • ssim:提高ssim,该选项编码出来的视频ssim比较高;
  • fastdecode:快速解码,该选项有利于快速解码;
  • zerolatency:零延迟,该选项主要用于视频直播。

如果你不确定使用哪个选项或者说你的输入与所有的tune皆不匹配,你可以忽略–tune 选项。


(3)profile
另外一个可选的参数是**-profile:v**,它可以将你的输出限制到一个特定的 H.264 profile。一些非常老的或者要被淘汰的设备仅支持有限的选项,比如只支持baseline或者main。

所有的profile 包括:
1)baseline profile:基本画质。支持I/P 帧,只支持无交错(Progressive)和CAVLC;

2)extended profile:进阶画质。支持I/P/B/SP/SI 帧,只支持无交错(Progressive)和CAVLC;

3)main profile:主流画质。提供I/P/B 帧,支持无交错(Progressive)和交错(Interlaced),也支持CAVLC 和CABAC 的支持;

4)high profile:高级画质。在main Profile 的基础上增加了8x8内部预测、自定义量化、 无损视频编码和更多的YUV 格式;

在相同配置情况下,High profile(HP)可以比Main profile(MP)节省10%的码流量,比MPEG-2MP节省60%的码流量,具有更好的编码性能。根据应用领域的不同:
1)baseline profile多应用于实时通信领域;
2)main profile多应用于流媒体领域;
3)high profile则多应用于广电和存储领域。


http://chatgpt.dhexx.cn/article/bLv0qG1t.shtml

相关文章

视频编码知识

记录一下学习视频编码的过程和自己的理解 视频 数字图像在计算机中的表示:二维矩阵,或三维矩阵(彩色)。 矩阵中的每个点为像素,数值的大小反应色彩的强度,颜色深度需要使用一定数据空间存储,每…

视频的专业基础知识(一)常用的编码格式和参数

1. 常用的编码格式 编码格式:一个视频文件本身,通常由音频和视频两部分组成。例如视频文件,就是由avc视频编码AAC音频编码组成的,常见的视频编码格式有Xvid,AVC/H.264,MPEG1,MPEG2 等&#xff…

常见视频编码格式解析

常见视频编码格式解析 文章目录 常见视频编码格式解析1、MPEG2-TS编码技术1.1. MPEG-TS简介1.2. 基本概念及TS流概述1.3. 基本流程1.4. TS流传输包(简称TS包)结构分析1.4.1. TS包包头1.4.2. TS包净荷部分1.5. PS节目流2、MPEG-4编码技术2.1. MPEG-4概述2.2. MPEG-4各部分2.3.…

视频编码全流程

视频编解码用到的一些算法: 正反傅里叶变换、fft算法 dct变换、快速dct变换 如何自己实现一个视频编解码器: (1)取一帧作为I帧,类似jpeg压缩编码,也就是 rgb转yuv,然后dct去除高频信息。因为这种压缩会造成边界bloc…

视频编码技术详解

1、引言 如今我们所处的时代,是移动互联网时代,也可以说是视频时代。从快播到抖音,从“三生三世”到“延禧攻略”,我们的生活,被越来越多的视频元素所影响。 而这一切,离不开视频拍摄技术的不断升级&#x…

FIO源码解读测试

在磁盘测试中,fio是最常用的测试的工具,其下载网址为https://github.com/axboe/fio; 对于fio,其测试命令有许多,这个大家很容易就可以查到,此处不讲解具体的测试命令, 而是讲一下大概的源码框架。 Fio的入口函数在fio.…

fio引发的一些问题

fio引发的一些问题 奇怪的255扇区在nvme驱动中插入打印语句直接编译模块加载源码编译内核 查找内核源码 奇怪的255扇区 由于块设备驱动项目需要测试读写速度,故使用fio工具,没想着深入了解,简单测个速就可以 使用tldr命令得到测试磁盘读写的…

【fio】关于磁盘性能测试

一、关于磁盘 磁盘是可以持久化存储的设备,根据存储介质的不同,常见磁盘可以分为两类:机械磁盘和固态磁盘。 第一类,机械磁盘,也称为硬盘驱动器(Hard Disk Driver),通常缩写为 HDD。…

【测试】 FIO:ceph/磁盘IO测试工具 fio(iodepth深度)

目录 随看随用 NAS文件系统测试 块系统测试 FIO用法 FIO介绍 FIO 工具常用参数: FIO结果说明 I/O 的重放(录下实际工况的IO,用fio重放) fio工作参数可以写入配置文件 fio的iodepth参数说明 IO状态监控: Ios…

FIO详解

fio - Flexible IO Tester 一、服务器配置: 由于我们想通过fio得到SSD真实的参数信息,因此我们需要服务器BIOS一些参数的配合,以便能更好的体现硬盘的性能。 以华为1288HV5为例: 二、fio 1.安装 a.下载地址:htt…

FIO 存储性能压测

一、 FIO简介 FIO 是一个多线程IO生成工具,可以生成多种IO模式(随机、顺序、读、写四大类),用来测试磁盘设备的性能。GFIO是FIO的图形监测工具,它提供了图形界面的参数配置,和性能监测图像。 在github上的…

磁盘性能测试工具-FIO的安装及使用

文章目录 FIO介绍FIO安装在线安装离线安装 磁盘测试命令行方式测试结果说明命令参数说明配置文件方式 dd命令介绍使用方法 FIO介绍 FIO是一款测试IOPS的工具,用于对磁盘进行压力测试和验证,磁盘I/O是检查磁盘性能的重要指标,可以按照负载情况…

NuGet学习笔记(1)——初识NuGet及快速安装使用

http://kb.cnblogs.com/page/143190/ 1. NuGet是什么? NuGet is a Visual Studio 2010 extension that makes it easy to add, remove, and update libraries and tools in Visual Studio projects that use the .NET Framework. This topic lists documentation t…

Nuget路径问题

VS NetGet包管理器 问题场景: 装了两遍VS2019,第一次装D盘卸载了,然后装C盘,结果生成 .netCore项目时就悲剧了,报错:error MSB4018: “ResolvePackageAssets”任务意外失败。Microsoft.PackageDependencyResolution.t…

使用nuget 打包并上传 nuget.org

使用nuget 打包并上传 nuget.org 一、准备工作二、打包你的项目三、上传 nug.org 服务器 前言:今天又玩了个新东西,那就是 使用nuget 打包并上传 nuget.org,在这里即时记录一下,废话不多说,直接上教程。 一、准备工作…

nuget 的生成、发布、使用和更新

nuget 的生成、发布、使用和更新 一、nuget 的生成1.生成.dll1.1创建.net项目(类库)1.2 打包生成 .dll 2.打包成.nupkg文件2.1安装 [NuGetPackageExplorer.exe](https://github.com/NuGetPackageExplorer/NuGetPackageExplorer)程序2.2打开软件,完成打包…

修改NuGet包默认存放位置

默认情况下,NuGet下载的包存放在系统盘(C盘中),这样一来,时间长了下载的包越多,C盘占用的空间也就越多。 1、问题描述 默认情况下,NuGet下载的包存放在系统盘(C盘中,一般在路径C:\Users\用户\.nuget\packag…

Nuget使用简介

1.什么是Nuget Nuget是 ASP .NET Gallery 的一员。NuGet 是免费、开源的包管理开发工具,专注于在 .NET 应用开发过程中,简单地合并第三方的组件库。 当需要分享开发的工具或是库,需要建立一个Nuget package,然后把这个package放到…

Nuget的使用说明

在做项目的时候,经常需要添加一些第三方引用,Visual Studio 2019环境下,最推荐的是Nuget安装方式,好处就是可以将所有依赖的包全部打包下载安装。 1.nuget.org,搜索需要的nuget包,复制相应的安装命令&…

NuGet的了解

目录 1..NuGet 的使用目的 2..Net 的工具 NuGet 1.NuGet 包的下载 2.NuGet 包的分析 3.NuGet 的使用 1.通过命令行使用 2.在 visual studio 里通过图形化界面进行添加。 3.在添加包的时候 4.特点 1..NuGet 的使用目的 在引入第三方程序集(dll)的…