ffmpeg之yuv格式转h264

yuv转h264格式步骤

  1. 初始化FFmpeg库:通过 av_register_all() avcodec_register_all() 来初始化必要的组件。
  2. 查找编码器:使用 avcodec_find_encoder 查找H.264编码器。
  3. 配置编码上下文:使用avcodec_alloc_context3分配编码上下文,并设置必要的参数。
  4. 打开编码器:通过 avcodec_open2 打开编码器。
  5. 准备输入数据:从文件中读取YUV数据,并将其填充到 AVFrame 中。
  6. 编码帧:使用 avcodec_send_frame 发送帧到编码器,并通过 avcodec_receive_packet 获取编码后的数据包。
  7. 输出H.264数据:将编码后的数据包写入输出文件。
  8. 清理资源:释放所有分配的资源,确保没有内存泄漏。

详细代码如下:

#include "ffmpegs.h"
#include <QFile>
#include <QDebug>
extern "C"
{
#include <libavcodec/avcodec.h>
#include <libavutil/avutil.h>
#include <libavformat/avformat.h>
#include <libavutil/imgutils.h>
}#define ERROR_BUF(ret) \char errbuf[1024]; \av_strerror(ret,errbuf,sizeof(errbuf));
ffmpegs::ffmpegs()
{}//检查像素格式
static int check_pix_fmt(const AVCodec *codec,enum AVPixelFormat pixFmt)
{const enum AVPixelFormat *p = codec->pix_fmts;while(*p != AV_PIX_FMT_NONE){if(*p == pixFmt){return 1;}p++;}return 0;
}//音频编码,返回负数:中途出现了错误,返回0:编码操作正常完成
static int encode(AVCodecContext *ctx,AVFrame *frame,AVPacket *pkt,QFile &outFile)
{int ret = avcodec_send_frame(ctx,frame);if(ret < 0){ERROR_BUF(ret);qDebug() << "avcodec_send_frame error" << errbuf;return 0;}//不断从编码器中取出编码后的数据while(ret >= 0){ret = avcodec_receive_packet(ctx,pkt);if(ret == AVERROR(EAGAIN) || ret == AVERROR_EOF){//继续读取数据到frame,然后送到编码器return 0;}else if(ret < 0)//其他错误{return ret;}//成功从编码器拿到的数据outFile.write((char*)pkt->data,pkt->size);//释放pkt内部资源av_packet_unref(pkt);}
}void ffmpegs::h264Encode(VideoEncodeSpec &in,const char *outFileName,QString &str)
{//文件QFile inFile(in.filename);QFile outFile(outFileName);//一帧图片的大小int imgSize = av_image_get_buffer_size(in.pixFmt,in.width,in.height,1);int ret = 0;                            //返回结果const AVCodec *codec = nullptr;         //编码器AVCodecContext *ctx = nullptr;          //编码上下文AVFrame *frame = nullptr;               //存放编码前的数据(yuv)AVPacket *pkt = nullptr;                //存放编码后的数据(h264)//uint8_t *buf = nullptr;//获取编码器codec = avcodec_find_encoder_by_name("libx264");if(!codec){qDebug() << "encoder not found";return;}qDebug() << codec->name;//libfdk_aac对输入数据的要求:采样格式必须是16位整数//检查输入数据的采样格式if(!check_pix_fmt(codec,in.pixFmt)){qDebug() << "unsupported pixel format" << av_get_pix_fmt_name(in.pixFmt);return;}//创建编码器上下文ctx = avcodec_alloc_context3(codec);if(!ctx){qDebug() << "avcodec_alloc_context3 error";return;}//设置yuv参数ctx->width = in.width;ctx->height = in.height;ctx->pix_fmt = in.pixFmt;//设置帧率(1秒钟显示多少帧)ctx->time_base = {1,in.fps};//打开编码器ret = avcodec_open2(ctx,codec,nullptr);if(ret < 0){ERROR_BUF(ret);qDebug() << "avcodec_open2_error" << errbuf;goto end;}//创建AVFrame  -- AVFrame用来存放编码前的数据frame = av_frame_alloc();if(!frame){qDebug() << "av_frame_alloc error";goto end;}//创建AVFrameframe->width = ctx->width;frame->height = ctx->height;frame->format = ctx->pix_fmt;frame->pts = 0;//利用width、height、format创建缓冲区ret = av_image_alloc(frame->data,frame->linesize,in.width,in.height,in.pixFmt,1);if(ret < 0){ERROR_BUF(ret);qDebug() << "avcodec_open2_error" << errbuf;goto end;}//    //创建输入缓冲区(方法2)
//    buf = (uint8_t*)av_malloc(imgSize);//实际buf和frame->data[0]地址一样
//    ret = av_image_fill_arrays(frame->data,frame->linesize,
//                               buf,
//                               in.pixFmt,in.width,in.height,1);
//    if(ret < 0)
//    {
//        ERROR_BUF(ret);
//        qDebug() << "av_image_fill_arrays error" << errbuf;
//        goto end;
//    }//创建AVPacketpkt = av_packet_alloc();if(!pkt){qDebug() << "av_packet_alloc error";goto end;}//打开文件if(!inFile.open(QFile::ReadOnly)){qDebug() << "file open error" << in.filename;goto end;}if(!outFile.open(QFile::WriteOnly)){qDebug() << "file open error" << outFileName;goto end;}//读取数据到frame中while((ret = inFile.read((char*)frame->data[0],imgSize)) > 0){//进行编码if(encode(ctx,frame,pkt,outFile) < 0){goto end;}//设置帧的序号frame->pts++;}//刷新缓冲区encode(ctx,frame,pkt,outFile);end://关闭文件inFile.close();outFile.close();//av_freep(&buf);//释放资源if(frame){av_freep(&frame->data[0]);av_frame_free(&frame);}av_packet_free(&pkt);avcodec_free_context(&ctx);
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot中实现拦截器和过滤器

【SpringBoot中实现过滤器和拦截器】 1.过滤器和拦截器简述 过滤器Filter和拦截器Interceptor&#xff0c;在功能方面很类似&#xff0c;但在具体实现方面差距还是比较大的。 2.过滤器的配置 2.1 自定义过滤器&#xff0c;实现Filter接口(SpringBoot 3.0 开始&#xff0c;jak…

基于LightGBM的集成学习算法

目录 一、LightGBM基本原理1.1 基于直方图的决策树算法1.1.1 连续变量分箱 1.2 互斥特征捆绑1.2.1 互斥特征捆绑计算流程1.2.2 互斥特征捆绑算法基本原理1.2.2.1 冲突比例&#xff08;conflict_rate&#xff09;1.2.2.2 图着色1.2.2.3 特征捆绑 1.3 基于梯度的单边采样&#xf…

trendFinder - 利用 AI 掌握社交媒体上的热门话题

1600 Stars 177 Forks 7 Issues 2 贡献者 MIT License Javascript 语言 代码: https://github.com/ericciarla/trendFinder 更多AI开源软件&#xff1a;AI开源 - 小众AI Trend Finder 收集并分析来自关键影响者的帖子&#xff0c;然后在检测到新趋势或产品发布时发送 Slack 通知…

Level DB --- BloomFilterPolicy

BloomFilterPolicy是Level DB中重要的数据过滤模块&#xff0c;它主要用来先过滤在Block中不存在的key&#xff0c;减少Block的搜索计算量。 Bloom Filter 从原理上来讲Bloom FIlter相对来说原理还是比较简单的&#xff0c;将一个key经过一次&#xff08;组合&#xff09;ha…

ELK 使用教程采集系统日志 Elasticsearch、Logstash、Kibana

前言 你知道对于一个系统的上线考察&#xff0c;必备的几样东西是什么吗&#xff1f;其实这也是面试中考察求职者&#xff0c;是否真的做过系统开发和上线的必备问题。包括&#xff1a;服务治理(熔断/限流) (opens new window)、监控 (opens new window)和日志&#xff0c;如果…

【MySQL】九、表的内外连接

文章目录 前言Ⅰ. 内连接案例&#xff1a;显示SMITH的名字和部门名称 Ⅱ. 外连接1、左外连接案例&#xff1a;查询所有学生的成绩&#xff0c;如果这个学生没有成绩&#xff0c;也要将学生的个人信息显示出来 2、右外连接案例&#xff1a;对stu表和exam表联合查询&#xff0c;把…

机器学习周报-ModernTCN文献阅读

文章目录 摘要Abstract 0 提升有效感受野&#xff08;ERF&#xff09;1 相关知识1.1 标准卷积1.2 深度分离卷积&#xff08;Depthwise Convolution&#xff0c;DWConv&#xff09;1.3 逐点卷积&#xff08;Pointwise Convolution&#xff0c;PWConv&#xff09;1.4 组卷积(Grou…

计算机的错误计算(二百零二)

摘要 利用三个大模型化简计算 前面分式的分子为零&#xff0c;因此正确值是后面的数值300.09...321 . 让三个大模型计算&#xff0c;它们均没有看出分式的分子中被减数与减数是相等的。因此&#xff0c;均得出了错误结果。 例1. 化简计算摘要中算式的值。 下面是一个大模型的…

2025-01-04 Unity插件 YodaSheet1 —— 插件介绍

文章目录 1 介绍2 工作原理2.1 ScriptableObject -> YadeSheetData2.2 YadeDatabase 存储多个 YadeSheetData 3 用途4 缺点5 推荐 1 介绍 ​ Yade 提供类似于 Excel 或者 Google Sheets 的表格编辑器&#xff0c;可以轻松地在 Unity 编辑器中 编辑&#xff0c;搜索&#xf…

connect to host github.com port 22: Connection timed out 的解决方法

原因是 Github 被 GFW 屏蔽了。 Windows 系统&#xff0c;打开 C:\Windows\System32\drivers\etc&#xff0c;复制其中的 hosts 文件至桌面&#xff0c;用文本编辑器或者其他工具打开。 复制以下内容进去&#xff1a; 140.82.114.4 github.com 151.101.1.6 github.global.ss…

memcached的基本使用

memcached是一种基于键值对的内存数据库&#xff0c;一般应用于缓存数据&#xff0c;提高数据访问速度&#xff0c;减轻后端数据库压力。 安装 这里以Ubuntu为例&#xff0c;其他系统安装方法请看官方文档。 sudo apt-get update sudo apt-get install memcached启动 memca…

【操作系统不挂科】操作系统期末考试题库<2>(单选题&简答题&计算与分析题&程序分析题&应用题)

前言 大家好吖&#xff0c;欢迎来到 YY 滴 操作系统不挂科 系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C的老铁 目录 一、单项选择题&#xff08;每空2分&#xff0c;共40分&#xff09;1&#xff0e;以下选项中&#xff0c;&#xff08; &#xff09;不是操…

ip属地的信息准确吗?ip归属地不准确怎么办

在数字化时代&#xff0c;IP属地信息成为了我们日常生活中不可或缺的一部分。在各大社交媒体平台上&#xff0c;IP属地信息都扮演着重要的角色。然而&#xff0c;随着技术的不断进步和网络的复杂性增加&#xff0c;IP属地信息的准确性问题也日益凸显。那么&#xff0c;IP属地信…

【GUI-pyqt5】QWidget类

1. 描述 所有可视空间的基类是一个最简单的空白控件控件是用户界面的最小元素 接收各种事件&#xff08;鼠标、键盘&#xff09;绘制在桌面上&#xff0c;显示给用户看 每个控件都是矩形的&#xff0c;它们按z轴顺序排序控件由其父控件和前面的控件剪切没有父控件的控件&#…

Linux(Centos 7.6)命令详解:ls

1.命令作用 列出目录内容(list directory contents) 2.命令语法 Usage: ls [OPTION]... [FILE]... 3.参数详解 OPTION: -l&#xff0c;long list 使用长列表格式-a&#xff0c;all 不忽略.开头的条目&#xff08;打印所有条目&#xff0c;包括.开头的隐藏条目&#xff09…

unity学习6:unity的3D项目的基本界面和菜单

目录 1 unity界面的基本认识 1.1 file 文件 1.2 edit 编辑/操作 1.3 Assets 1.4 gameobject 游戏对象 1.5 组件 1.6 windows 2 这些部分之间的关系 2.1 关联1&#xff1a; Assets & Project 2.2 关联2&#xff1a;gameobject & component 2.3 关联3&#xf…

生成模型的现状2025年的新兴趋势

2024年对人工智能而言是极为出色的一年。在文本生成和图像生成这两方面&#xff0c;我们目睹了模型能力全方位出现了类似阶跃函数般的巨大提升。这一年起始时OpenAI占据主导地位&#xff0c;而到了年末&#xff0c;Anthropic的Claude成了我常用的大型语言模型&#xff0c;并且还…

PWN 的知识之如何利用栈溢出利用后门函数

PWN 的知识之如何利用栈溢出利用后门函数 利用栈溢出漏洞调用原本存在的后门函数&#xff08;例如 get_flag 或system("/bin/sh")&#xff09;是二进制漏洞利用中的一种常见技术,相信各位网安的师傅或多或少都听说过&#xff0c;那么如何利用栈溢出来利用后门函数呢…

基于YOLO11的道路缺陷检测系统

基于YOLO11的道路缺陷检测系统 (价格90) 包含 [cracks, potholes] [裂缝, 凹坑] 2个类 通过PYQT构建UI界面&#xff0c;包含图片检测&#xff0c;视频检测&#xff0c;摄像头实时检测。 &#xff08;该系统可以根据数据训练出的yolo11的权重文件&#xff0c;运用在其他…

JAVA:Spring Boot 集成 Quartz 实现分布式任务的技术指南

1、简述 Quartz 是一个强大的任务调度框架&#xff0c;允许开发者在应用程序中定义和执行定时任务。在 Spring Boot 中集成 Quartz&#xff0c;可以轻松实现任务的调度、管理、暂停和恢复等功能。在分布式系统中&#xff0c;Quartz 也支持集群化的任务调度&#xff0c;确保任务…