AvFrame和AvPacket

news/2023/6/6 23:48:30

在FFmpeg中,未压缩的图像和压缩的视频码流分别使用AVFrame结构和AVPacket结构保存; 针对视频编码器,其流程为从数据源获取图像格式的输入数据,保存为AVFrame对象并传入编码器,从编码器输出AVPacket结构。

1. AVFrame结构体

typedef struct AVFrame {
#define AV_NUM_DATA_POINTERS 8 //表示一个AVFrame结构最多保存8个图像分量;//待编码的图像像素数据保存在其中,各图像分量的像素数据保存在AVframe::data[0]~data[7]uint8_t *data[AV_NUM_DATA_POINTERS];int linesize[AV_NUM_DATA_POINTERS]; //每个分量的存储区的宽度,称为步长;/*指向数据平面/通道的指针。对于视频,指向data[]对于planar音频,每个通道有分离的数据指针,且linesize[0]包含每个通道buffer的大小;对于packed音频,仅仅是一个数据指针,且linesize[0]包含所有通道buffer的总大小; */uint8_t **extended_data;//图像宽高int width, height;//本帧描述的音频采样数(每个频道) int nb_samples;//帧格式,常见的为AV_PIX_FMT_YUV420Pint format;int key_frame; //当前帧的关键帧标识位;1表该帧为关键帧;0表非关键帧;enum AVPictureType pict_type;//当前帧的类型,0,1,2分别表示I帧,P帧,B帧;//采样视频帧的长宽比,如果未知/未指定,则为0/1;AVRational sample_aspect_ratio;int64_t pts;//当前帧的显示时间戳;#if FF_API_PKT_PTS//PTS复制自AVPacket,被解码产生此帧。int64_t pkt_pts;
#endif//dts从触发返回帧的AVPacket中复制//这也是由AVPacket计算出的AVFrame的显示时间。 无PTS值的DTS值int64_t pkt_dts;//按位流顺序排列的图片编号int coded_picture_number;//图片编号按显示顺序排列int display_picture_number;//质量int quality;void *opaque; //用户私有数据//当解码时,这表示图像必须延迟多少int repeat_pict;//图片的内容是交错的int interlaced_frame;//如果内容是交错的,则首先显示顶部字段。 int top_field_first;//告诉用户应用程序调色板已从上一帧更改。 int palette_has_changed;int64_t reordered_opaque;//音频数据采样速率int sample_rate;//音频数据的通道布局。uint64_t channel_layout;//AVBuffer引用支持这个帧的数据AVBufferRef *buf[AV_NUM_DATA_POINTERS];AVBufferRef **extended_buf;//扩展buf中的元素数目int        nb_extended_buf;AVFrameSideData **side_data;int            nb_side_data;//帧标志int flags;enum AVColorRange color_range;enum AVColorPrimaries color_primaries;enum AVColorTransferCharacteristic color_trc;enum AVColorSpace colorspace;enum AVChromaLocation chroma_location;//帧时间戳估计使用各种启发式int64_t best_effort_timestamp;//从输入到解码器的最后一个AVPacket重新排序pos int64_t pkt_pos;//对应报文的持续时间,以AVStream->time_base units表示,如果未知则为0int64_t pkt_duration;AVDictionary *metadata;//音频通道数,仅用于音频int channels;//包含压缩帧的相应数据包的大小 int pkt_size;AVBufferRef *hw_frames_ctx;AVBufferRef *opaque_ref;size_t crop_top;size_t crop_bottom;size_t crop_left;size_t crop_right;AVBufferRef *private_ref;
} AVFrame;

在AVFrame结构中,它所包含的最重要的结构即数据的缓存区;待编码的数据的像素数据保存在AVFrame结构的data指针所保存的内存区中;
一个AVFrame结构最多可以保存8个图像分量,各图像分量的像素数据保存在AVFrame::data[0]~AVFrame::data[7]所指向的内存区中;

1.1 创建AVFrame结构的实例并初始化

AVFrame *av_frame_alloc(void);:仅仅创建AVFrame结构的实例,以及初始化内部各个字段的值,并没有分配用于存储其内部图像的内存空间;

1.2 给AVFrame结构体中的音视频数据分配内存空间

int av_frame_get_buffer(AVFrame *frame, int align);
作用:实际分配内存空间;
参数1:AVFrame指针;
参数2:对齐方式,<=0表示以32字节对齐;否则以align对齐;

示例:

//创建AVFrame结构的实例并初始化;
//仅仅创建AVFrame的实例,并没有分配用于存储其内部图像的内存空间;
frame = av_frame_alloc();
if (!frame) {fprintf(stderr, "Could not allocate video frame\n");exit(1);
}
frame->format = c->pix_fmt;
frame->width  = c->width;
frame->height = c->height;//给AVFrame结构中的音视频数据分配内存空间;
ret = av_frame_get_buffer(frame, 0);
if (ret < 0) {fprintf(stderr, "Could not allocate the video frame data\n");exit(1);
}

1.3 将保存了图像数据的AVFrame结构传入编码器

int avcodec_send_frame(AVCodecContext *avctx, const AVFrame *frame);
参数1:当前编码器的上下文结构l;
参数2:待编码的图像结构;当该参数为NULL时表示编码结束,此时应该刷新编码器缓存的码流;
返回值:0:正常执行; 负数表错误码;
AVERROR(EAGAIN):输入缓存已满,应该调用avcodec_receive_packet获取输出数据后在尝试输入;
AVERROR_EOF:编码器已收到刷新指令,不再接收的图像输入;
VERROR(EINVAL):编码器状态错误;
VERROR(ENOMEM):内存空间不足;

1.4 释放分配的图像帧结构

void av_frame_free(AVFrame **frame)

2. AVPacket结构体

typedef struct AVPacket {AVBufferRef *buf;int64_t pts;//当前packet的显示时间戳;必须大于等于dtsint64_t dts;//当前packet的解码时间戳,以AVStream的time_base为单位;uint8_t *data;//码流数据保存在data指针指向的内存;int   size;//数据长度为size字节;可通过data和size读取编码后的码流;int   stream_index;//当前packet所从属的stream序号;int   flags;AVPacketSideData *side_data;int side_data_elems;//当前packet的显示时长,即按照顺序显示下一帧pts与当前pts的差值;int64_t duration; //当前packet在数据流中的二进制位置; -1表示未知;int64_t pos;                      
} AVPacket;

2.1 创建AVPacket结构的实例并初始化

AVPacket *av_packet_alloc(void)

2.2 依照一个已存在的packet创建新的packet,新packet是对原packet的引用

AVPacket *av_packet_clone(const AVPacket *src);

2.3 释放一个packet,若该packet存在引用计数,则其引用计数减1

void av_packet_free(AVPacket **pkt);

2.4 按照指定大小分配一个packet的存储空间,并初始化该packet

int av_new_packet(AVPacket *pkt, int size);

2.5 根据传入的packet创建新的引用packet

int av_packet_ref(AVPacket *dst, const AVPacket *src);

2.6 回收该packet

void av_packet_unref(AVPacket *pkt);

2.7 从编码器中获取输出的码流,并保存在传入的AVPacket结构中

int avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt);
参数1:当前编码器上下文结构;
参数2:输出的码流包结构,包含编码器输出的视频码流;
返回值:0表正常,负数为错误码;
AVERROR(EAGAIN):编码器尚未完成对新一帧的编码,应继续通过函数avcodec_send_frame传入后续图像;
AVERROR_EOF:编码器已经完成输出内部缓存的码流,编码完成;
VERROR(EINVAL):编码器状态错误;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.exyb.cn/news/show-4557196.html

如若内容造成侵权/违法违规/事实不符,请联系郑州代理记账网进行投诉反馈,一经查实,立即删除!

相关文章

第30课时_电力MOSFET开关概述及工作原理

第30课时_电力MOSFET开关概述及工作原理 MOSFET的工作原理 正向阻断反向导电形成反型层导电沟道形成

第8讲+ MOSFET工作原理

以Ntype MOS晶体管为例&#xff0c;探讨MOS管的工作原理。 放大作用的实质是控制作用&#xff0c;为探究栅极电压对沟道的控制作用&#xff0c;先将源极(s)、漏极(d)、衬底连接起来&#xff0c;并在栅极(g)和源极之间加上电压&#xff0c;如图一所示。 在加了上述电压之后&…

MOSFET结构及工作原理

目录1. N沟道增强型(1) 结构(2) 工作原理2. N沟道耗尽型(1) 结构(2) 工作原理3. P沟道增强型(1) 结构(2) 工作原理4. P沟道耗尽型(1) 结构(2) 工作原理1. N沟道增强型 (1) 结构 (2) 工作原理 2. N沟道耗尽型 (1) 结构 (2) 工作原理 3. P沟道增强型 (1) 结构 (2) 工作原理…

MOSFET从原理到使用

0 引子 最近打算把项目中的继电器开关控制换成MOSFET开关控制&#xff0c;继电器虽然控制简单但是关断次数有限&#xff0c;不适合高频率的关断闭合&#xff0c;而MOSFET属于压控组件&#xff0c;只要通过改变栅源电压就可以实现快速开关动作&#xff0c;且MOS管阻抗极大相较于…

第三代电力电子半导体:SiC MOSFET学习笔记(三)SiC驱动方案

如何为SiC MOSFET选择合适的驱动芯片&#xff1f;&#xff08;英飞凌官方&#xff09; 由于SiC产品与传统硅IGBT或者MOSFET参数特性上有所不同&#xff0c;并且其通常工作在高频应用环境中&#xff0c; 为SiC MOSFET选择合适的栅极驱动芯片&#xff0c;需要考虑如下几个方面&a…

k8s在华为openeuler搭建

参考文献 Kubernetes1.26.0部署(Ubuntu/CentOS)未完待续https://blog.csdn.net/weixin_67405599/article/details/128466282 Kubeadm 快速搭建 k8s v1.24.1 集群&#xff08;openEuler 22.03 LTS&#xff09;https://huaweicloud.csdn.net/633119cbd3efff3090b52068.html op…

MOSFET原理学习

1、基本结构 小信号采用平面导电型&#xff0c;大功率采用垂直导电型。 对于平面型MOSFET,当栅极无电压时&#xff0c;两个PN结反偏&#xff0c;当S和D极无论接正还是负&#xff0c;总有一个PN结反偏&#xff0c;无法到SD无法导通。当s极和衬底B相连时&#xff0c;会导致BD之间…

数据结构与算法——第一章——绪论

1.2数据结构的概念 1.2.1基本概念和术语 1.数据 是信息的载体&#xff0c;是所有能够被计算机识别、存储和加工处理的符号的总称。 是计算机程序加工的原料。 可以是数值数据&#xff08;整数、实数、复数&#xff09;&#xff0c;也可以是非数值数据&#xff08;字符、文字…