当前位置: 首页 > news >正文

FFMpeg的AVFrame数据格式解析

一、什么是AVFrame

只要使用FFmpeg做解码,必然会使用到AVFrame结构体,AVFrame主要用于存放音频/视频未压缩的数据。

二、AVFrame结构体内部

typedef struct AVFrame {
#define AV_NUM_DATA_POINTERS 8
uint8_t *data[AV_NUM_DATA_POINTERS]; // 存放媒体数据的指针数组
int linesize[AV_NUM_DATA_POINTERS]; // 视频或音频帧数据的行宽
uint8_t **extended_data; // 音频或视频数据的指针数组
int width, height; // 视频帧的宽和高
int nb_samples; // 当前帧的音频采样数(每个通道)
int format; // 视频帧的像素格式或音频的采样格式
int key_frame; // 当前帧是否为关键帧,1表示是,0表示不是
AVRational sample_aspect_ratio; // 视频帧的样本宽高比
int64_t pts; // 以time_base为单位的呈现时间戳
int64_t pkt_dts; // 从AVPacket复制而来的dts时间
int coded_picture_number; // 按解码先后排序的解码图像数
int display_picture_number; // 按显示前后排序的显示图像数
int quality; // 帧质量,从1到FF_LAMBDA_MAX之间取值
void *opaque; // 用户的私有数据
int interlaced_frame; // 图片的内容是否为隔行扫描
int top_field_first; // 如果内容是隔行扫描的,是否首先显示顶部字段
int sample_rate; // 音频数据的采样率
uint64_t channel_layout; // 音频数据的通道布局
AVBufferRef *buf[AV_NUM_DATA_POINTERS]; // AVBuffer引用,当前帧数据
AVBufferRef **extended_buf; // AVBufferRef的指针
int nb_extended_buf; // extended_buf的数量
enum AVColorSpace colorspace; // YUV颜色空间类型
int64_t best_effort_timestamp; // 算法预测的timestamp
int64_t pkt_pos; // 记录上一个AVPacket输入解码器的位置
int64_t pkt_duration; // packet的duration
AVDictionary *metadata; // 元数据
int channels; // 音频的通道数
int pkt_size; // 包含压缩帧的相应数据包的大小
} AVFrame;

三、AVFrame接口函数

  • AVFrame *av_frame_alloc(void);

构造一个AVFrame, 对象成员被设为默认值.

此函数只分配AVFrame对象本身, 而不分配AVFrame中的数据缓存区.

  • void av_frame_free(AVFrame **frame);

释放AVFrame.

  • int av_frame_ref(AVFrame *dst, const AVFrame *src);

为src中的数据建立一个新的引用.

将src中帧的各属性拷到dst中, 并且为src中每个AVBufferRef创建一个新的引用.

如果src未使用引用计数, 则dst中会分配新的数据缓存区, 将src中缓存区的数据拷贝到dst中的缓存区.

  • void av_frame_unref(AVFrame *frame);

解除本AVFrame对AVFrame中所有缓存区的引用, 并复位AVFrame中的各成员.

  • int av_frame_get_buffer(AVFrame *frame, int align); 

为音频或视频数据分配新的缓冲区.

调用本函数前, 帧中的以下成员必须先设置好:

    • format
    • width, height
    • nb_samples, channel_layout

本函数会填充AVFrame.data和AVFrame.buf数组, 如果有需要, 还会分配和填充AVFrame.extended_data和AVFrame.extended_buf.

四、实例

#include <iostream>
using namespace std;
extern "C"{ //指定函数是c语言函数,函数名不包含重载标注
//引用ffmpeg头文件
#include <libavcodec/avcodec.h>
}
//预处理指令导入库
#pragma comment(lib,"avcodec.lib")
#pragma comment(lib,"avutil.lib")
int main(int argc, char* argv[])
{cout << "first ffmpeg" << endl;cout << avcodec_configuration() << endl;//创建frame对象auto frame1 = av_frame_alloc();//图像参数frame1->width = 401;frame1->height = 300;frame1->format = AV_PIX_FMT_ARGB;//分配空间 16字节对齐int re = av_frame_get_buffer(frame1, 16);if (re != 0){char buf[1024] = { 0 };av_strerror(re, buf, sizeof(buf));cout << buf << endl;}cout <<"frame1 linesize[0]="<< frame1->linesize[0] << endl;if (frame1->buf[0]){cout << "frame1 ref count = " <<av_buffer_get_ref_count(frame1->buf[0]); // 线程安全cout << endl;}auto frame2 = av_frame_alloc();av_frame_ref(frame2, frame1);cout << "frame1 ref count = " <<av_buffer_get_ref_count(frame1->buf[0]) << endl;cout << "frame2 ref count = " <<av_buffer_get_ref_count(frame2->buf[0]) << endl;//引用计数-1 并将buf清零av_frame_unref(frame2);cout << "av_frame_unref(frame2)" << endl;cout << "frame1 ref count = " <<av_buffer_get_ref_count(frame1->buf[0]) << endl;//引用计数为1 直接删除buf空间 引用计数变为0av_frame_unref(frame1);//释放frame对象空间,buf的引用计数减一//buf已经为空,只删除frame对象空间av_frame_free(&frame1);av_frame_free(&frame2);return 0;
}

http://www.lqws.cn/news/538615.html

相关文章:

  • C++(模板与容器)
  • 重定向攻击与防御
  • AI+时代已至|AI人才到底该如何培育?
  • AI编程工具深度对比:腾讯云代码助手CodeBuddy、Cursor与通义灵码
  • vscode ssh远程连接到Linux并实现免密码登录
  • 爬虫简单实操2——以贴吧为例爬取“某吧”前10页的网页代码
  • Spring Cloud Feign 整合 Sentinel 实现服务降级与熔断保护
  • [AI]从0到1通过神经网络训练模型
  • 每日算法刷题Day38 6.25:leetcode前缀和3道题,用时1h40min
  • 第七章:总结
  • 【RabbitMQ】多系统下的安装配置与编码使用(python)
  • Spring Task定时任务详解与实战应用
  • java中的anyMatch和allMatch方法
  • OSEK/VDX OS ISO17356-3,【1】规范概述
  • SpringBoot项目快速开发框架JeecgBoot——Web处理!
  • linux cp与mv那个更可靠
  • MySQL5.7和8.0 破解root密码
  • 快速傅里叶变换(FFT)是什么?
  • python中学物理实验模拟:斜面受力分析
  • 圆周期性显示和消失——瞬态实现(CAD c#二次开发、插件定制)
  • Nordic nRF54L15 SoC对包含电池监测、中断处理和电源轨控制的定制 nPM1300 示例
  • springcloud 尚硅谷 看到9开头
  • 华为云鸿蒙应用入门级开发者认证 实验(HCCDA-HarmonyOS Cloud Apps)
  • 玄机抽奖Spring Web项目
  • Maven Javadoc 插件使用详解
  • [论文阅读]RaFe: Ranking Feedback Improves Query Rewriting for RAG
  • 解决uniapp vue3版本封装组件后:deep()样式穿透不生效的问题
  • react-嵌套路由 二级路由
  • 事件循环(Event Loop)机制对比:Node.js vs 浏览器​
  • python+requests接口自动化测试