自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(73)
  • 收藏
  • 关注

原创 【x265】码率控制模块的简单分析—块级码控工具(AQ和cuTree)

AQ模式的计算位于encoder/slicetype.cpp中,由calcAdaptiveQuantFrame()实现,主要的步骤为: 1. 如果使用hevcAq,则使用xPreanalyze()去分析当前帧 2. 如果使用常规AQ (1)如果使用X265_AQ_EDGE模式,则先进行滤波,检测边缘纹理(edgeFilter) (2)如果使用X265_AQ_AUTO_VARIANCE、X265_AQ_ATUO_VARIANCE_BIASED或X265_AQ_EDGE模式中的一种,则根据全局范围的纹

2024-09-13 14:08:37 335

原创 【x265】预测模块的简单分析—帧间预测

帧间预测是编码器中降低编码耗时的最有效工具之一,通过时域上的相邻参考,能够大幅度降低编码码率,从而节省网络带宽。在x265当中,帧间预测(Inter Prediction,下文简称Inter模式)是基于PU实现和操作的,它能够将一个CU划分成为若干个子区域,分别实现预测功能,与帧内预测(Intra Prediction,下文简称Intra模式)不同,Inter模式能够将CU分成不规则的PU尺寸,如下所示,一共8种

2024-09-06 10:56:38 882

原创 【x265】预测模块的简单分析—帧内预测

在h265标准中,CU的尺寸最大为64x64,最小为8x8,以四叉树(QuadTree,QT)向下逐层划分,同时引入了预测单元(Prediction Unit,PU)这一概念,用于预测编码。PU由CU划分成为多个预测区域而来,对于帧内预测而言,PU的尺寸可以分为两类:(1)2Nx2N2Nx2N表示当前PU和该PU所属的CU具有相同的大小,并且以这个大小的区域进行预测编码(2)NxNNxN表示当前CU会划分成4大小相同的子PU,分别进行预测编码/

2024-08-30 11:11:00 680

原创 【x265】x265编码器参数配置

在熟悉编码器过程中,一个比较有效的方法是了解其配置参数,根据其配置参数就可以知道编码器使用了哪些工具,从中筛选出重要的工具重点看看。本文记录一下x265编码器中的配置参数。

2024-08-21 16:15:59 395

原创 【流媒体】基于libRTMP的H264推流器

前面记录了RTMP协议相关的内容,本文记录如何使用libRTMP库进行推流,推流的内容是本地H264码流,向RTMP服务器(nginx)进行推流,并且在传输之后使用ffplay进行拉流播放,主要参考了雷博的实现方式,但根据自己的理解进行了代码简化,加上了自己的理解和注释。在修改过程中,直接使用了雷博提供的libRTMP库,没有自己编译,这一点可能得后续再看看。

2024-08-20 16:38:56 889

原创 【流媒体】RTMPDump—AMF编码

在看RTMPDump代码过程中,发现一个比较核心的地方还没有记录,即AMF编码。RTMP协议的数据很多都是以AMF格式进行编码的,也应该做重点记录。参考RTMPDump代码中的amf.c和amf.h两个文件。由于AMF编码会将数据转换成为大端存储,可以参考。

2024-08-19 09:52:30 728

原创 【流媒体】RTMPDump—Download(接收流媒体信息)

在进行流连接之后,还可以进行传输过来数据的下载,执行这一功能的函数是Download(),其中使用RTMP_Read()读取数据,随后使用fwrite写入文件。写入文件通常是FLV格式,如果没有指定这个file,则会默认写到stdout。

2024-08-16 14:16:19 344

原创 【流媒体】RTMPDump—RTMP_ConnectStream(创建流连接)

RTMP_ConnectStream()的作用是建立流连接,先回顾一下RTMP标准文档当中是如何进行流的连接的,以client向server发送play命令为例,流程图如下所示。现在假设状态为client向server发送了av_connect命令,server会给予一个反馈,client会根据这个反馈去进行下一步的操作,此时会调用RTMP_SendCreateStream()函数发送av_createStream命令,RTMP_SendCreateStream()函数定义如下。(2)解析packet。

2024-08-16 14:15:04 1138

原创 【流媒体】RTMPDump—RTMP_Connect函数(握手、网络连接)

前面进行了RTMPDump主流程的分析,包括初始化和一些解析过程,现在分析RTMPDump是如何进行握手和网络连接,这是进行RTMP通信的第一步。

2024-08-16 14:12:56 1181

原创 【流媒体】RTMPDump—主流程简单分析

main函数的流程如下所示,代码还是比较长的,主要可以分为8个步骤:(1)初始化socket(InitSockets)(2)初始化RTMP(RTMP_Init)(3)解析URL(RTMP_ParseURL)(4)配置流信息(RTMP_SetupStream)(5)建立网络连接(RTMP_Connect)(6)建立流连接(RTMP_ConnectStream)(7)流媒体下载(Download)(8)清理和释放(free、RTMP_Close和CleanupSockets)

2024-08-16 14:07:23 1474

原创 【流媒体】RTMP协议的消息类型

不得不说RTMP协议比之前看到的RTP协议要复杂很多,其中涉及到的数据格式和控制方式要更多。前面记录了RTMP协议的主要流程和数据格式,本文记录RTMP中的消息类型,不同的消息类型决定当前的数据包完成不同的任务,因此是极其重要的内容。

2024-08-14 16:38:25 1061

原创 【流媒体】RTMP协议的数据格式

在RTMP协议中,定义的数据格式称为消息(Message),消息是网络传输的数据载体,其中会携带RTMP协议命令、用户控制命令和传输的数据等等,是client和server之间进行交流通信的核心RTMP消息分为2个部分:RTMP Message Header和RTMP Message Payload

2024-08-13 15:50:25 746

原创 【流媒体】RTMP协议概述

RTMP(Real-Time Message Protocol)协议是由Adobe公司提出的一种专为实时音视频数据传输设计的专用网络协议,主要用于流媒体传输领域,如直播、在线视频播放等等。RTMP协议基于TCP,是一种有数据传输保障的协议,默认使用1935号端口,支持多种数据格式和传输方式,从而适用于不同的应用场景。RTMP能够应用于Windows、macOS、Linux、Android和iOS等不同的操作系统,进行高效的音视频数据传输。熟悉RTMP协议,可以阅读官方的文档,这里我参考的是中文翻译:[R

2024-08-13 09:36:52 967

原创 【视频编码】调用x264库文件实现编码

整理前面记录的文章时发现还没有记录过如何实际操作x264编码器实现编码的功能,过去是通过FFmpeg调用libx264的接口来实现编码功能,这里记录一下直接调用x264的接口来实现编码的功能,同时存储编码之后的码流和重建的yuv。代码整体的框架参考example.c文件,文件的存储参考encoder.c中的frame_dump函数。在进行文件存储时需要注意uv分量的存储是按照interleave的方式进行的

2024-08-07 10:13:27 346

原创 【流媒体】基于RTP协议的H264播放器

前面记录了一篇基于RTP协议的H264的推流器、接收器的实现过程,但是没有加上解码播放,这里记录一下如何实现解码和播放,也是在前面的基础之上实现的。前一篇的记录为【开源项目】基于RTP协议的H264码流发送器和接收器在前文中,接收器将接收到的一系列数据包进行解析,并分成了一个个完整的帧,存储在内存之中。下面要将这些完整的帧进行解码成为yuv,并且播放。因此,需要添加解码和播放部分的代码。

2024-08-02 17:20:05 734

原创 【流媒体】基于RTP协议的H264码流发送器和接收器

RTP(Real-time Transport Protocol,实时传输协议)是一种网络协议,用于在IP网络上传输实时数据,如音频、视频等。它的主要目的是提供一种可靠的、面向数据包的传输机制,以支持实时多媒体应用。无连接RTP协议本身不保证数据的可靠传输,它只是负责将数据包从发送端发送到接收端,而不关心数据包是否按顺序到达或者是丢失面向数据包RTP协议适用于传输数据包,而不是连续的数据流。这意味着它可以处理任意大小的数据包,而不需要预先建立连接时间戳。

2024-08-01 15:39:42 730

原创 【FFmpeg】avcodec_receive_packet函数

这里的av_packet_move_ref的作用是取出avci这个内部(internal)结构体中缓冲区的数据,并且赋值给到avpkt中,随后将avci->buffer_pkt中的信息设置为默认值。如果缓冲区中没有数据,则需要重新进行编码操作,使用encode_receive_packet_internal函数,在其他文中记录过,不再多记录av_packet_move_ref的定义如下,先进行内容的拷贝,随后将src设置为初始值

2024-07-23 20:47:20 690

原创 【FFmpeg】avcodec_receive_frame函数

函数的主要功能是返回解码的帧,定义位于libavcodec\avcodec.c中。如果代码需要从已编码的缓冲区中取出数据,会调用这个函数。这个函数的主要流程是检查缓冲区是否有数据,如果有则直接取出,否则尝试进行解码,随后会进行一些其他的检查和处理

2024-07-23 20:40:04 849

原创 【视频编码】H265码流格式解析

H265码流格式相对而言比较复杂,其中涉及到的语法元素更多,其中互相依赖的关系也更加复杂,可能在实际应用中更多的关注H264标准是比较合适的(对于实时性要求比较高的场景)

2024-07-22 14:07:48 288

原创 【Linux】Windows平台使用gdb调试FFmpeg源码

在windows平台使用linux环境来调试FFmpeg源码,需要编译生成一个后缀有_g的exe文件,参考[ffmpeg编译](https://blog.csdn.net/u012559967/article/details/134035253)。在windows平台下,如果想要使用vs调试,需要在编译FFmepg时添加--toolchain=msvc来生成pdb文件

2024-07-11 15:00:43 293

原创 【视频编码】H264码流格式解析

码流解析可以深入的剖析视频流当中语法元素存储的方式,这对于理解码流有很大的帮助作用,本文参考雷博和李迟的开源代码,结合2021年8月份新的H264视频编码标准,做了一些微调和注释,尽管有些地方还有待改进,但实现了主要功能。这个开源项目提出的另一个作用是替代那些昂贵的视频码流分析软件如VQA,目前只有打印输出分析的内容,但未来会改成可操作性界面。下面对代码进行定义和解释

2024-07-10 11:50:47 922

原创 【FFmpeg】av_write_trailer函数

函数的主要功能是向输出的媒体文件中写入流的尾部信息,同时释放文件的私有数据。从注释上看,这个函数只能在成功调用了avformat_write_header之后进行调用

2024-07-05 09:48:24 1056

原创 【FFmpeg】内存分配和释放(av_malloc、av_realloc等)

av_malloc在FFmpeg中用于分配内存地址,先检查输入的size是否大于了内存分配的最大限制,如果不大于,则调用_aligned_malloc按照对齐的方式分配内存。使用内存对齐的方式进行内存分配,有利于CPU的读取

2024-07-04 16:27:15 1206

原创 【FFmpeg】avcodec_send_packet函数

函数的定义位于libavcodec\decode.c中,如下所示。这里最重要的地方在于检查cb_type,如果使用硬件解码器,则使用receive_frame,否则使用decode_simple_receive_frame执行软解过程

2024-07-04 14:58:24 1337

原创 【FFmpeg】avcodec_send_frame函数

avcodec_send_frame函数的主要功能是将外部输入的frame送入到编码器中实现编码,函数的实现位于libavcodec\encode.c中,从代码看,主要进行的流程为:(1)输入信息avctx的检查(2)如果输入的帧frame不存在,设置draining为1,随后将输入的frame存入avctx的buffer中,存入的过程使用encode_send_frame_internal实现(3)将frame送入编码器进行编码,使用encode_receive_packet_internal实现

2024-07-03 16:03:39 1635

原创 【FFmpeg】avcodec_open2函数

函数的定义位于libavcodec\avcodec.c中,从注释上看,主要的功能是使用给定的AVCodec情况下,来初始化AVCodecContext。在使用此函数之前,必须使用avcodec_alloc_context3来分配上下文,可以在外面配置options,作为codec初始化的参数

2024-07-03 09:04:23 1308

原创 【FFmpeg】关键结构体的初始化和释放(AVFormatContext、AVIOContext等)

在记录了一些主要函数的执行流程之后,可以看看几个关键结构体的初始化函数和释放函数,这样对整个FFmpeg更加熟悉一些。需要说明的是,在FFmpeg当中,很多函数都能够实现关键结构体的初始化,举例来说,对于AVFormatContext,可以使用avformat_alloc_output_context2初始化,这个函数会根据输出的format来初始化AVFormatContext,这样的操作避免了先进行malloc,然后手动赋值的流程。不过本文记录的函数是最基本的函数,尽量避免与其他结构体交织在一起

2024-07-02 14:43:33 1001

原创 【FFmpeg】avcodec_find_encoder和avcodec_find_decoder

函数的功能是用于查找一个编码器,定义位于libavcodec\allcodecs.c,函数调用了find_codec查找一个编码器。find_codec的定义如下,其中先调用了remap_deprecated_codec_id进行id的重映射,随后调用av_codec_iterate从codec_list当中取出一个codec,随后判断这个codec的id是否与输入的id匹配,如果匹配再检查这个codec的编码能力(capabilities)是否是experimental,如果不是experimental则

2024-07-01 16:48:43 1075

原创 【FFmpeg】av_write_frame函数

在参考雷博的文章时,发现他在进行函数分析时,分析了av_write_frame但是在实际工程之中应用了av_interleaved_write_frame,为什么有这个区别?这两个函数有什么异同,对于不同的格式而言,应该使用什么函数来实现frame写入比较好?本文先记录av_write_frame是如何实现的,在FFmpeg7.0中,av_write_frame和老版本的av_write_frame有一些改动,av_write_frame函数的内部调用关系如下,其中最核心的部分是调用的write_pack

2024-07-01 16:04:24 909

原创 【FFmpeg】av_read_frame函数

返回流的下一帧1.此函数返回存储在文件中的内容,而不验证是否存在用于解码器的有效帧。它将把存储在文件中的内容分割成帧,并为每次调用返回一个帧。它不会省略有效帧之间的无效数据,以便为解码器提供可能用于解码的最大信息2.如果成功,返回的数据包将被引用计数(pkt->但已设置)并无限期有效。当不再需要该数据包时,必须使用av_packet_unref()释放该数据包。对于视频,数据包只包含一帧。对于音频,如果每帧有一个已知的固定大小(例如PCM或ADPCM数据),它包

2024-07-01 10:37:04 1717

原创 【FFmpeg】avformat_write_header函数

函数的功能:分配流私有数据并将流标头写入输出媒体文件;函数的定义位于libavformat\mux.c中,主要的工作流程为:(1)如果没有进行初始化,则进行初始化输出(avformat_init_output)(2)进行头信息的写入(write_header)(3)如果流还没有被初始化,则写入pts(init_pts)

2024-06-28 11:28:57 1266

原创 【FFmpeg】avio_open2函数

avio_open2函数的定义位于libavformat\avio.c中,功能是打开URL,之后方便进行读写操作。这里的URL是广义的地址,对于文件而言,就是文件的路径,如"C:\xxx\test.flv",也可以是地址例如"rtmp://127.0.0.1:1935/live/stream",flag表示控制如何打开url所指示的资源的标志,如AVIO_FLAG_READ和AVIO_FLAG_WRITE

2024-06-27 16:55:12 1019

原创 【FFmpeg】avformat_alloc_output_context2函数

avformat_alloc_output_context2内函数调用关系如下。函数的主要功能是分配一个输出的context,利用输入的format和filename来确定output format,主要工作流程为:(1)初始化AVFormatContext(avformat_alloc_context)(2)如果没有指定输出format,需要根据输入信息来猜测一个format(av_guess_format)(3)根据输出的format,来对AVFormatContext中的priv_data初始

2024-06-27 12:20:46 1113

原创 【FFmpeg】avformat_find_stream_info函数

FFmpeg版本为7.0,函数的主要功能是根据前面获取的AVFormatContext,结合输入的options,分析每个流(AVStream)的信息,主要内容包括:(1)确定分析的最大时长(2)对每个流当中的codec信息的获取(2.1)初始化解析器(av_parser_init)(2.2)查找探测解码器(find_probe_decoder)(2.3)尝试打开解码器(avcodec_open2)(3)frame信息的获取(3.1)编解码器的检

2024-06-27 10:43:32 1231

原创 【FFmpeg】avformat_open_input函数

函数的定义位于libavformat\demux.c中,定义如下,主要的工作流程为:(1)为avformat分配空间(avformat_alloc_context)(2)初始化输入格式(init_input)(3)黑白名单的检查(4)其他信息的检查(5)读取头信息(read_header)(6)更新流的音频/视频上下文(update_stream_avctx)在函数执行的过程中,最核心的函数为初始化输入格式(init_input)

2024-06-25 16:25:08 1387

原创 【FFmpeg】AVFrame结构体

AVFrame结构体中记录的比较关键的信息包括:(1)uint8_t *data[AV_NUM_DATA_POINTERS]:存储frame数据(2)int linesize[AV_NUM_DATA_POINTERS]:帧当中一行有多少像素(3)int width, height:视频的宽高(4)int format:frame的格式(5)int key_frame:是否是关键帧(6)enum AVPictureType pict_type:帧的类型(7)int64_t pts:present

2024-06-24 11:55:15 956

原创 【FFmpeg】AVPacket结构体

AVPacket结构体的定义与老版本相似,基本没有大的改动,其中比较关键的内容包括:(1)uint8_t *data:存储压缩数据的变量(2)int size:数据大小(3)int stream_index:流的索引号(4)int flags:描述当前pkt的使用情况(5)int64_t pts:解压后的数据包呈现给用户的时间(6)int64_t dts:数据包被解压的时间

2024-06-24 09:15:35 468

原创 【FFmpeg】AVIOContext结构体

AVIOContext当中比较重要的信息包括:(1)unsigned char *buffer:buffer的起始地址(2)int buffer_size:buffer的大小(3)unsigned char *buf_ptr:buffer当前的指针(4)unsigned char *buf_end:buffer末尾的地址(5)void *opaque:URLContext(6)int (*read_packet)(void *opaque, uint8_t *buf, int buf_size)

2024-06-21 17:51:59 1178

原创 【FFmpeg】AVFormatContext结构体

从AVFormatContext的定义来看,除了定义了AVInputFormat和AVOutputFormat两种format结构体之外,还定义了输入输出上下文结构体AVIOContext、文件中流的list结构体AVStream、黑白名单list和流的打开关闭函数,这里与老版本的FFmpeg不同的地方包括:(1)将以前的char filename[1024]改成了现在的char* url,不再限制长度;(2)将AVCodec存放在AVFormatContext之中而不是AVStream之中,这里有一点将A

2024-06-21 12:08:46 766

原创 【FFmpeg】AVStream结构体

粗略来看,AVCodecParameters之中存储的信息和AVCodecContext之间的关系更像是子集关系,AVCodecParameters只包含部分的变量,例如长宽、格式和帧率等等,AVCodecContext既包含了这些变量,还包含了如qp控制、bitrate控制、硬件编解码等等一系列变量,此外AVCodecContext之中还定义了一些函数指针,如get_format和get_buffer等。在新版本中将编解码器参数和上下文信息隔离开来,应该是不希望在stream这个级别去改变codec的一些

2024-06-20 18:23:00 880

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除