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

FFmpeg YUV编码为H264

使用FFmpeg库把YUV420P文件编码为H264文件,FFmpeg版本为4.4.2-0。

需要yuv测试文件的,可以从我上传的MP4文件中用ffmpeg提取,命令如下:

ffmpeg -i <input.mp4> -pix_fmt yuv420p <output.yuv>

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/opt.h>
#include <libavutil/mem.h>
#include <libavutil/imgutils.h>
#include <libswscale/swscale.h>int main(int argc, char *argv[])
{int ret = -1;int frame_index = 0;const char *input_file = argv[1];const char *output_file = argv[2];FILE *input_yuv = NULL;AVFormatContext *format_context = NULL;AVCodecContext *codec_context = NULL;AVStream *stream = NULL;AVCodec *codec = NULL;AVFrame *frame = NULL;AVPacket *packet = NULL;const AVOutputFormat *ofmt = NULL;int in_width = 1280;                                // 输入YUV文件的宽度int in_height = 720;                                // 输入YUV文件的高度enum AVPixelFormat in_pix_fmt = AV_PIX_FMT_YUV420P; // 输入YUV文件的像素格式int frame_rate = 24;                                // 输出视频帧率if (argc < 3){fprintf(stderr, "Usage: %s <input file> <output file>\n", argv[0]);return -1;}input_yuv = fopen(input_file, "rb");if (!input_yuv){fprintf(stderr, "open input file failed\n");goto end;}// 分配输出格式上下文avformat_alloc_output_context2(&format_context, NULL, NULL, output_file);if (!format_context){fprintf(stderr, "avformat_alloc_output_context2 failed\n");goto end;}ofmt = format_context->oformat;// 查找编码器codec = avcodec_find_encoder(AV_CODEC_ID_H264);if (!codec){fprintf(stderr, "Codec not found\n");goto end;}printf("codec name: %s\n", codec->name);// 创建新的视频流stream = avformat_new_stream(format_context, NULL);if (!stream){fprintf(stderr, "avformat_new_stream failed\n");goto end;}// 分配编码器上下文codec_context = avcodec_alloc_context3(codec);if (!codec_context){fprintf(stderr, "avcodec_alloc_context3 failed\n");goto end;}/* 设置编码器参数 */codec_context->codec_id = AV_CODEC_ID_H264;codec_context->codec_type = AVMEDIA_TYPE_VIDEO;codec_context->pix_fmt = AV_PIX_FMT_YUV420P;codec_context->width = in_width;codec_context->height = in_height;codec_context->time_base = (AVRational){1, frame_rate};     // 设置时间基codec_context->framerate = (AVRational){frame_rate, 1};     // 设置帧率codec_context->bit_rate = 1456 * 1000;                      // 设置比特率codec_context->gop_size = frame_rate;                       // 设置GOP大小codec_context->max_b_frames = 1;                            // 设置最大B帧数,不需要B帧时设置为0av_opt_set(codec_context->priv_data, "profile", "main", 0); // 设置h264画质级别// 打开编码器if (avcodec_open2(codec_context, codec, NULL) < 0){fprintf(stderr, "avcodec_open2 failed\n");goto end;}// 将编码器参数复制到流int result = avcodec_parameters_from_context(stream->codecpar, codec_context);if (result < 0){fprintf(stderr, "avcodec_parameters_from_context failed\n");goto end;}// 打开输出文件if (!(ofmt->flags & AVFMT_NOFILE)) // 检查输出格式是否需要文件存储{result = avio_open(&format_context->pb, output_file, AVIO_FLAG_WRITE);if (result < 0){fprintf(stderr, "open output file failed\n");goto end;}}// 写文件头result = avformat_write_header(format_context, NULL);if (result < 0){fprintf(stderr, "avformat_write_header failed\n");goto end;}frame = av_frame_alloc();packet = av_packet_alloc();if (!frame || !packet){fprintf(stderr, "allocate frame or packet failed\n");goto end;}// 设置帧参数frame->format = codec_context->pix_fmt;frame->width = codec_context->width;frame->height = codec_context->height;// 分配帧数据缓冲区result = av_frame_get_buffer(frame, 0);if (result < 0){fprintf(stderr, "av_frame_get_buffer failed\n");goto end;}// 计算输入缓冲区大小int input_buffer_size = av_image_get_buffer_size(in_pix_fmt, in_width, in_height, 1);uint8_t *input_buffer = (uint8_t *)av_malloc(input_buffer_size);if (!input_buffer){fprintf(stderr, "av_malloc failed\n");goto end;}// 编码循环while (1){// 读取YUV数据到缓冲区result = fread(input_buffer, 1, input_buffer_size, input_yuv);if (result <= 0){break;}// 填充帧数据av_image_fill_arrays(frame->data, frame->linesize, input_buffer, in_pix_fmt, in_width, in_height, 1);frame->pts = frame_index;frame_index++;// 发送帧到编码器result = avcodec_send_frame(codec_context, frame);if (result < 0){fprintf(stderr, "avcodec_send_frame error (errmsg '%s')\n", av_err2str(result));goto end;}// 接收编码后的数据包while (result >= 0){result = avcodec_receive_packet(codec_context, packet);if (result == AVERROR(EAGAIN) || result == AVERROR_EOF){break;}else if (result < 0){fprintf(stderr, "avcodec_receive_packet error (errmsg '%s')\n", av_err2str(result));goto end;}packet->stream_index = stream->index;// 将时间戳从编码器时间基转换到流时间基av_packet_rescale_ts(packet, codec_context->time_base, stream->time_base);// 写数据包到输出文件result = av_interleaved_write_frame(format_context, packet);if (result < 0){fprintf(stderr, "av_interleaved_write_frame failed\n");av_packet_unref(packet);goto end;}av_packet_unref(packet);}}av_free(input_buffer);// 发送NULL帧到编码器,刷新编码器内部缓冲区result = avcodec_send_frame(codec_context, NULL);while (result >= 0){result = avcodec_receive_packet(codec_context, packet);if (result == AVERROR_EOF){break;}else if (result < 0){fprintf(stderr, "avcodec_receive_packet error (errmsg '%s')\n", av_err2str(result));goto end;}packet->stream_index = stream->index;av_packet_rescale_ts(packet, codec_context->time_base, stream->time_base);result = av_interleaved_write_frame(format_context, packet);if (result < 0){fprintf(stderr, "av_interleaved_write_frame failed\n");av_packet_unref(packet);goto end;}av_packet_unref(packet);}// 写文件尾av_write_trailer(format_context);ret = 0;end:if (frame)av_frame_free(&frame);if (packet)av_packet_free(&packet);if (codec_context)avcodec_free_context(&codec_context);if (ofmt && !(ofmt->flags & AVFMT_NOFILE))avio_close(format_context->pb);if (format_context)avformat_free_context(format_context);if (input_yuv)fclose(input_yuv);return ret;
}

相关文章:

FFmpeg YUV编码为H264

使用FFmpeg库把YUV420P文件编码为H264文件&#xff0c;FFmpeg版本为4.4.2-0。 需要yuv测试文件的&#xff0c;可以从我上传的MP4文件中用ffmpeg提取&#xff0c;命令如下&#xff1a; ffmpeg -i <input.mp4> -pix_fmt yuv420p <output.yuv> 代码如下&#xff1a;…...

【C语言】顺序表(上卷)

什么是数据结构&#xff1f; 数据结构是由“数据”和“结构”两词组合而来的。 数据需要管理。数据结构就是计算机存储、组织数据的方式。比如一个班级就是一个结构&#xff0c;管理的就是班级里的学生。如果我们要找三年2班的同学李华&#xff0c;就可以直接去三年2班找而不…...

Luma AI如何注册:文生视频领域的新星

文章目录 Luma AI如何注册&#xff1a;文生视频领域的新星一、Luma 注册方式二、Luma 的效果三、Luma 的优势四、Luma 的功能总结 Luma AI如何注册&#xff1a;文生视频领域的新星 近年来&#xff0c;Luma AI 凭借其在文生视频领域的创新技术&#xff0c;逐渐成为行业的新星。…...

一站式实时数仓Hologres整体能力介绍

讲师&#xff1a;阿里云Hologres PD丁烨 一、产品定位 随着技术的进步&#xff0c;大数据正从规模化转向实时化处理。用户对传统的T1分析已不满足&#xff0c;期望获得更高时效性的计算和分析能力。例如实时大屏&#xff0c;城市大脑的交通监控、风控和实时的个性化推荐&…...

如何在 Windows 上安装 Docker Desktop

如何在 Windows 上安装 Docker Desktop Docker 是一个开放平台&#xff0c;用于开发、部署和运行应用程序。Docker Desktop 是 Docker 在 Windows 和 macOS 上的官方客户端&#xff0c;它使得开发者能够轻松地在本地环境中构建、运行和共享容器化应用程序。本文将详细介绍如何…...

WPF由文本框输入的内容动态渲染下拉框

在做项目过程中&#xff0c;需要扫码枪扫描快递单号或者手动输入快递单号时&#xff0c;自动检索该单号是哪个快递公司的&#xff0c;下拉框中自动带出该单号的快递公司。当输入的快递单号不存在时&#xff0c;将数据库中所有快递公司都带出 效果&#xff1a; 通过输入的快递单…...

RPCMon:一款基于ETW的RPC监控工具

关于RPCMon RPCMon是一款基于事件跟踪的WindowsRPC监控工具&#xff0c;该工具是一款GUI工具&#xff0c;可以帮助广大研究人员通过ETW&#xff08;Event Tracing for Windows&#xff09;扫描RPC通信。 RPCMon能够为广大研究人员提供进程之间RPC通信的高级视图&#xff0c;该…...

【odoo】常用的字符转义:“>“,“<“,““,“/“等

概要 字符转义是指在编写代码或处理文本数据时&#xff0c;将特殊字符转换为另一种形式&#xff0c;以便在特定的上下文中正确解析和处理这些字符。 内容 特殊字符描述XML转义表示法&和符号&amp;<小于符号<>大于符号>"双引号&quot;单引号&ap…...

李宏毅深度学习项目——HW1个人笔记

视频链接 PDF链接 googleColab链接 GoogleColab是一个免费的jupyter notebook&#xff0c;可以用上面的gpu资源进行训练 题目 通过前两天的数据&#xff0c;预测第三天某个人感染新冠的概率 范例 导包 # Numerical Operations import math import numpy as np# Reading/Wr…...

3D Gaussian Splatting Windows安装

0.安装C++ 编译器 https://aka.ms/vs/17/release/vs_buildtools.exe 1.下载源码 git clone https://github.com/graphdeco-inria/gaussian-splatting --recursive 2.安装cuda NVIDIA GPU Computing Toolkit CUDA Toolkit Archive | NVIDIA Developer 3.安装COLMAP...

人脸识别——可解释的人脸识别(XFR)人脸识别模型是根据什么来识别个人的

可解释性人脸识别&#xff08;XFR&#xff09;&#xff1f; 人脸识别有一个任务叫1:N&#xff08;识别&#xff09;。这个任务将一个人的照片与N张注册照片进行比较&#xff0c;找出相似度最高的人。 这项任务用于刑事调查和出入境点。在犯罪调查中&#xff0c;任务从监控摄像…...

仓库管理系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;公告管理&#xff0c;物资管理&#xff0c;基础数据管理&#xff0c;用户管理 用户账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;公告管理&#xff0c;物…...

最火AI角色扮演流量已达谷歌搜索20%!每秒处理2万推理请求,Transformer作者公开优化秘诀

卡奥斯智能交互引擎是卡奥斯基于海尔近40年工业生产经验积累和卡奥斯7年工业互联网平台建设的最佳实践&#xff0c;基于大语言模型和RAG技术&#xff0c;集合海量工业领域生态资源方优质产品和知识服务&#xff0c;旨在通过智能搜索、连续交互&#xff0c;实时生成个性化的内容…...

MySQL:MySQL分组排序函数rank()、row_number()、dense_rank()与partition by结合使用

一、前言 在 MySQL 中&#xff0c;虽然标准的 SQL 函数 RANK(), ROW_NUMBER(), 和 DENSE_RANK() 是 SQL 标准的一部分&#xff0c;但早期的 MySQL 版本并不直接支持这些窗口函数。然而&#xff0c;从 MySQL 8.0 开始&#xff0c;这些函数被引入以支持窗口函数&#xff08;也称为…...

opencv c++ 检测图像尺寸大小,标注轮廓

1. 项目背景 本项目旨在开发一个图像处理程序&#xff0c;通过使用计算机视觉技术&#xff0c;能够自动检测图像中物体的尺寸并进行分类。项目利用了开源的计算机视觉库 OpenCV&#xff0c;实现了图像的灰度处理、二值化、轮廓检测、边界框绘制以及尺寸分类等功能。通过这些功…...

Python数据可视化基础:使用Matplotlib绘制图表

Python数据可视化基础&#xff1a;使用Matplotlib绘制图表 数据可视化是数据分析中的重要环节&#xff0c;它可以帮助我们更直观地理解数据。Python作为一门强大的编程语言&#xff0c;提供了多种库来支持数据可视化&#xff0c;其中Matplotlib是最为流行和功能丰富的库之一。…...

Java开发接口设计的原则

在现代软件开发实践中&#xff0c;接口设计扮演着至关重要的角色。它不仅关乎代码的结构和未来的可维护性&#xff0c;还直接影响到软件系统的灵活性和扩展性。本文将通过实例详解几个核心的接口设计原则&#xff0c;帮助开发者更好地编写和管理接口&#xff0c;从而提升软件的…...

[火灾警报系统]yolov5_7.0-pyside6火焰烟雾识别源码

国内每年都会发生大大小小的火灾&#xff0c;造成生命、财产的损失。但是很多火灾如果能够早期发现&#xff0c;并及时提供灭火措施&#xff0c;将会大大较小损失。本套源码采用yolov5-7.0目标检测算法结合pyside6可视化界面源码&#xff0c;当检测到火灾时&#xff0c;能否发出…...

机器学习和深度学习区别

定义和范围&#xff1a; 机器学习&#xff1a;是一门多领域交叉学科&#xff0c;涉及概率论、统计学、逼近论、凸分析、算法复杂度理论等多门学科。它专门研究计算机怎样模拟或实现人类的学习行为&#xff0c;以获取新的知识或技能&#xff0c;重新组织已有的知识结构使之不断改…...

【功能详解】银河麒麟操作系统“安全启动”是如何发挥作用的?

2023年12月&#xff0c;财政部、工信部发布了7项信息类产品《政府采购需求标准》&#xff0c;为包括操作系统在内多项产品的政府集中采购提供政策支撑。其中&#xff0c;安全、可信作为国产操作系统的基本要求备受关注。 安全体系的构建离不开操作系统本身的硬实力&#xff0c…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩

目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

页面渲染流程与性能优化

页面渲染流程与性能优化详解&#xff08;完整版&#xff09; 一、现代浏览器渲染流程&#xff08;详细说明&#xff09; 1. 构建DOM树 浏览器接收到HTML文档后&#xff0c;会逐步解析并构建DOM&#xff08;Document Object Model&#xff09;树。具体过程如下&#xff1a; (…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

拉力测试cuda pytorch 把 4070显卡拉满

import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试&#xff0c;通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小&#xff0c;增大可提高计算复杂度duration: 测试持续时间&#xff08;秒&…...

ArcGIS Pro制作水平横向图例+多级标注

今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作&#xff1a;ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等&#xff08;ArcGIS出图图例8大技巧&#xff09;&#xff0c;那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分&#xff1a; 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...

Golang——7、包与接口详解

包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...