音视频从入门到精通——FFmpeg结构体:AVPacket分析

2023-10-28 13:20

本文主要是介绍音视频从入门到精通——FFmpeg结构体:AVPacket分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • FFmpeg结构体 AVPacket分析
  • AVPacket 相关函数介绍
  • FFmpeg AVPacket和AVFrame区别
  • 重要结构体之间的关系
    • 解协议(http, rtsp, rtmp, mms)
    • 解封装(flv, avi, rmvb, mp4)
    • 解码(h264, mpeg2, aac, mp3)
    • 存数据
  • 参考

FFmpeg结构体 AVPacket分析

FFmpeg结构体

AVPacket保存的是解码前的数据,也就是压缩后的数据。
该结构本身不直接包含数据,其有一个指向数据域的指针,FFmpeg中很多的数据结构都使用这种方法来管理数据。


/*** This structure stores compressed data. It is typically exported by demuxers* and then passed as input to decoders, or received as output from encoders and* then passed to muxers.** For video, it should typically contain one compressed frame. For audio it may* contain several compressed frames. Encoders are allowed to output empty* packets, with no compressed data, containing only side data* (e.g. to update some stream parameters at the end of encoding).** The semantics of data ownership depends on the buf field.* If it is set, the packet data is dynamically allocated and is* valid indefinitely until a call to av_packet_unref() reduces the* reference count to 0.** If the buf field is not set av_packet_ref() would make a copy instead* of increasing the reference count.** The side data is always allocated with av_malloc(), copied by* av_packet_ref() and freed by av_packet_unref().** sizeof(AVPacket) being a part of the public ABI is deprecated. once* av_init_packet() is removed, new packets will only be able to be allocated* with av_packet_alloc(), and new fields may be added to the end of the struct* with a minor bump.** @see av_packet_alloc* @see av_packet_ref* @see av_packet_unref*/
typedef struct AVPacket {/*** A reference to the reference-counted buffer where the packet data is* stored.* May be NULL, then the packet data is not reference-counted.*/AVBufferRef *buf;/*** Presentation timestamp in AVStream->time_base units; the time at which* the decompressed packet will be presented to the user.* Can be AV_NOPTS_VALUE if it is not stored in the file.* pts MUST be larger or equal to dts as presentation cannot happen before* decompression, unless one wants to view hex dumps. Some formats misuse* the terms dts and pts/cts to mean something different. Such timestamps* must be converted to true pts/dts before they are stored in AVPacket.*/int64_t pts;/*** Decompression timestamp in AVStream->time_base units; the time at which* the packet is decompressed.* Can be AV_NOPTS_VALUE if it is not stored in the file.*/int64_t dts;uint8_t *data;int   size;int   stream_index;/*** A combination of AV_PKT_FLAG values*/int   flags;/*** Additional packet data that can be provided by the container.* Packet can contain several types of side information.*/AVPacketSideData *side_data;int side_data_elems;/*** Duration of this packet in AVStream->time_base units, 0 if unknown.* Equals next_pts - this_pts in presentation order.*/int64_t duration;int64_t pos;                            ///< byte position in stream, -1 if unknown/*** for some private data of the user*/void *opaque;/*** AVBufferRef for free use by the API user. FFmpeg will never check the* contents of the buffer ref. FFmpeg calls av_buffer_unref() on it when* the packet is unreferenced. av_packet_copy_props() calls create a new* reference with av_buffer_ref() for the target packet's opaque_ref field.** This is unrelated to the opaque field, although it serves a similar* purpose.*/AVBufferRef *opaque_ref;/*** Time base of the packet's timestamps.* In the future, this field may be set on packets output by encoders or* demuxers, but its value will be by default ignored on input to decoders* or muxers.*/AVRational time_base;
} AVPacket;

部分字段说明

typedef struct AVPacket {
AVBufferRef *buf; //用来管理data指针引用的数据缓存
int64_t pts; //显示时间,结合AVStream->time_base转换成时间戳
int64_t dts; //解码时间,结合AVStream->time_base转换成时间戳
uint8_t *data; //★指向保存压缩数据的指针,这就是AVPacket的实际数据
int size; //data的大小
int stream_index; //packet在stream的index位置
int flags; //标示,结合AV_PKT_FLAG使用,其中最低为1表示该数据是一个关键帧。 
/*
* flags 可选:
* #define AV_PKT_FLAG_KEY 0x0001 //关键帧
* #define AV_PKT_FLAG_CORRUPT 0x0002 //损坏的数据
* #define AV_PKT_FLAG_DISCARD 0x0004 /丢弃的数据 
*/
AVPacketSideData *side_data; //容器提供的一些附加数据
int side_data_elems; //边缘数据元数个数
int64_t duration; //数据的时长,以所属媒体流的时间基准为单位,未知则值为默认值0 int64_t pos; //数据在流媒体中的位置,未知则值为默认值-1#if FF_API_CONVERGENCE_DURATIONattribute_deprecatedint64_t convergence_duration; //该字段已deprecated,不在使用 #endif
} AVPacket;

解码时AVPacket典型的使用场景为:

AVPacket *packet = av_packet_alloc(); // 创建一个packet
while(av_read_frame(pFormatCtx,packet))
{if(packet->stream_index == audio_index){...}else if(packet->stream_index == video_index){...}av_packet_unref(packet); // 不要忘记减少引用技术
}av_packet_free(packet);

在这里插入图片描述

AVPacket 相关函数介绍

av_read_frame:从媒体流中读取帧填充到Packet的数据缓存空间。如果Packet->buf为空,则Packet的数据缓存空间会在下次调用av_read_frame的时候失效。这也就是为何在FFmpeg3:播放音频中,从流中读取到Packet的时,在将该Packet插入队列时,要调用av_dup_avpacket重新复制一份缓存数据。

av_packet_alloc: 创建一个AVPacket,将其字段设为默认值(data为空,没有数据缓存空间)

av_packet_free: 释放使用av_packet_alloc创建的AVPacket,如果该Packet有引用计数(packet->buf不为空),则先调用av_packet_unref(&packet)。

av_packet_clone: 其功能是 av_packet_alloc + av_packet_ref

av_init_packet: 初始化packet的值为默认值,该函数不会影响data引用的数据缓存空间和size,需要单独处理。

av_new_packet: av_init_packet的增强版,不但会初始化字段,还为data分配了存储空间。

av_copy_packet: 复制一个新的packet,包括数据缓存。

av_packet_from_data: 初始化一个引用计数的packet,并指定了其数据缓存。

av_grow_packet: 增大Packet->data指向的数据缓存。

av_shrink_packet :减小Packet->data指向的数据缓存。

av_dup_packet: 是复制src->data引用的数据缓存,赋值给dst,也就是创建两个独立packet。说是3的版本册除了该方法,但4.1的源码里面又出现了该方法。

已经废弃的两个函数:av_dup_packetav_free_packet
av_free_packet: 释放packet,包括其data引用的数据缓存,现在可以使用av_packet_freeav_packet_unref代替。

FFmpeg AVPacket和AVFrame区别

在这里插入图片描述

AVPacket:存储压缩数据(视频对应H.264等码流数据,音频对应AAC/MP3等码流数据)
AVFrame:存储非压缩的数据(视频对应RGB/YUV像素数据,音频对应PCM采样数据)

重要结构体之间的关系

在这里插入图片描述
FFmpeg 中结构体很多。最关键的结构体可以分成以下几类:

解协议(http, rtsp, rtmp, mms)

  • AVIOContext ,URLProtocol ,URLContext 主要存储视音频使用的协议的类型以及状态。URLProtocol 存 储输入视音频使用的封装格式。每种协议都对应一个 URLProtocol 结构(注意:FFmpeg 中文件也被当 做一种协议 “file” )。

解封装(flv, avi, rmvb, mp4)

  • AVFormatContext 主要存储视音频封装格式中包含的信息;AVInputFormat 存储输入视音频使用的封装格式。每种视音频封装格式都对应一个 AVInputFormat 结构。

解码(h264, mpeg2, aac, mp3)

  • 每个 AVStream 存储一个视频/音频流的相关数据;每个 AVStream 对应一个 AVCodecContext ,存储该视 频/音频流使用解码方式的相关数据;每个 AVCodecContext 中对应一个 AVCodec ,包含该视频/音频对应 的解码器。每种解码器都对应一个 AVCodec 结构。

存数据

视频的话,每个结构一般是存一帧;音频可能有好几帧

  • 解码前数据:AVPacket
  • 解码后数据:AVFrame

参考

FFmpeg AVPacket 剖析以及使用
FFmpeg 中AVPacket的使用
ffmpeg中AVPacket与AVFrame中数据的传递与释放
AVPacket 详细说明

FFMPEG结构体分析:AVFrame
FFMPEG结构体分析:AVFormatContext
FFMPEG结构体分析:AVCodecContext
FFMPEG结构体分析:AVIOContext
FFMPEG结构体分析:AVCodec
FFMPEG结构体分析:AVStream
FFMPEG结构体分析:AVPacket

这篇关于音视频从入门到精通——FFmpeg结构体:AVPacket分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/293512

相关文章

从入门到精通MySQL联合查询

《从入门到精通MySQL联合查询》:本文主要介绍从入门到精通MySQL联合查询,本文通过实例代码给大家介绍的非常详细,需要的朋友可以参考下... 目录摘要1. 多表联合查询时mysql内部原理2. 内连接3. 外连接4. 自连接5. 子查询6. 合并查询7. 插入查询结果摘要前面我们学习了数据库设计时要满

怎样通过分析GC日志来定位Java进程的内存问题

《怎样通过分析GC日志来定位Java进程的内存问题》:本文主要介绍怎样通过分析GC日志来定位Java进程的内存问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、GC 日志基础配置1. 启用详细 GC 日志2. 不同收集器的日志格式二、关键指标与分析维度1.

从入门到精通C++11 <chrono> 库特性

《从入门到精通C++11<chrono>库特性》chrono库是C++11中一个非常强大和实用的库,它为时间处理提供了丰富的功能和类型安全的接口,通过本文的介绍,我们了解了chrono库的基本概念... 目录一、引言1.1 为什么需要<chrono>库1.2<chrono>库的基本概念二、时间段(Durat

MySQL中的表连接原理分析

《MySQL中的表连接原理分析》:本文主要介绍MySQL中的表连接原理分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、环境3、表连接原理【1】驱动表和被驱动表【2】内连接【3】外连接【4编程】嵌套循环连接【5】join buffer4、总结1、背景

解析C++11 static_assert及与Boost库的关联从入门到精通

《解析C++11static_assert及与Boost库的关联从入门到精通》static_assert是C++中强大的编译时验证工具,它能够在编译阶段拦截不符合预期的类型或值,增强代码的健壮性,通... 目录一、背景知识:传统断言方法的局限性1.1 assert宏1.2 #error指令1.3 第三方解决

python中Hash使用场景分析

《python中Hash使用场景分析》Python的hash()函数用于获取对象哈希值,常用于字典和集合,不可变类型可哈希,可变类型不可,常见算法包括除法、乘法、平方取中和随机数哈希,各有优缺点,需根... 目录python中的 Hash除法哈希算法乘法哈希算法平方取中法随机数哈希算法小结在Python中,

MySQL中的索引结构和分类实战案例详解

《MySQL中的索引结构和分类实战案例详解》本文详解MySQL索引结构与分类,涵盖B树、B+树、哈希及全文索引,分析其原理与优劣势,并结合实战案例探讨创建、管理及优化技巧,助力提升查询性能,感兴趣的朋... 目录一、索引概述1.1 索引的定义与作用1.2 索引的基本原理二、索引结构详解2.1 B树索引2.2

Java Stream的distinct去重原理分析

《JavaStream的distinct去重原理分析》Javastream中的distinct方法用于去除流中的重复元素,它返回一个包含过滤后唯一元素的新流,该方法会根据元素的hashcode和eq... 目录一、distinct 的基础用法与核心特性二、distinct 的底层实现原理1. 顺序流中的去重

从入门到精通MySQL 数据库索引(实战案例)

《从入门到精通MySQL数据库索引(实战案例)》索引是数据库的目录,提升查询速度,主要类型包括BTree、Hash、全文、空间索引,需根据场景选择,建议用于高频查询、关联字段、排序等,避免重复率高或... 目录一、索引是什么?能干嘛?核心作用:二、索引的 4 种主要类型(附通俗例子)1. BTree 索引(

如何使用Maven创建web目录结构

《如何使用Maven创建web目录结构》:本文主要介绍如何使用Maven创建web目录结构的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录创建web工程第一步第二步第三步第四步第五步第六步第七步总结创建web工程第一步js通过Maven骨架创pytho