本文主要是介绍音视频从入门到精通——FFmpeg结构体:AVPacket分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- FFmpeg结构体 AVPacket分析
- AVPacket 相关函数介绍
- FFmpeg AVPacket和AVFrame区别
- 重要结构体之间的关系
- 解协议(http, rtsp, rtmp, mms)
- 解封装(flv, avi, rmvb, mp4)
- 解码(h264, mpeg2, aac, mp3)
- 存数据
- 参考
FFmpeg结构体 AVPacket分析
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_packet
和av_free_packet
av_free_packet
: 释放packet,包括其data引用的数据缓存,现在可以使用av_packet_free
或av_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分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!