FFMpeg rtmp 无压缩推送本地yuv文件 压缩推送本地yuv文件

可以借鉴的:C++使用FFmpeg实现YUV数据编码转视频文件_C 语言_脚本之家

yuv文件下载地址:YUV Sequences

无压缩的方式推送本地yuv文件 代码:

#include <stdio.h>
#include <unistd.h>
#include <iostream>
extern "C" {
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavcodec/avcodec.h"
#include "libswscale/swscale.h"
};
using namespace std;const char* input_file = "/mnt/hgfs/shareVM/BigBuckBunny_CIF_24fps.yuv";
const char* output_rtmp_url = "rtmp://10.10.18.94:1935/live/test";int main(int argc, char *argv[]) {AVFormatContext *pFormatCtx = nullptr;AVOutputFormat *fmt = nullptr;AVStream *video_st = nullptr;AVCodecContext *pCodecCtx = nullptr;AVCodec *pCodec = nullptr;uint8_t *picture_buf = nullptr;int size;//打开视频文件FILE *in_file = fopen(input_file, "rb");if (!in_file) {cout << "can not open file!" << endl;return -1;}//[1] --注册所有ffmpeg组件avcodec_register_all();av_register_all();//[2] --初始化AVFormatContext结构体,根据文件名获取到合适的封装格式avformat_alloc_output_context2(&pFormatCtx, NULL, "flv", output_rtmp_url);fmt = pFormatCtx->oformat;//[3] --打开文件if (avio_open(&pFormatCtx->pb, output_rtmp_url, AVIO_FLAG_READ_WRITE)) {cout << "output file open fail!";return -1;}//[3]//[4] --初始化视频码流video_st = avformat_new_stream(pFormatCtx, 0);if (video_st == NULL){printf("failed allocating output stram\n");return -1;}video_st->time_base.num = 1;video_st->time_base.den = 25;//[4]//[5] --编码器Context设置参数pCodecCtx = video_st->codec;pCodecCtx->codec_id = fmt->video_codec;pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;pCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;pCodecCtx->width = 352;pCodecCtx->height = 288;pCodecCtx->time_base = {1, 25};pCodecCtx->framerate = {25, 1};pCodecCtx->bit_rate = 400000;pCodecCtx->gop_size = 50;//[5]//[6] --寻找编码器并打开编码器pCodec = avcodec_find_encoder(AV_CODEC_ID_FLV1);if (!pCodec){cout << "no right encoder!" << endl;return -1;}if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0){cout << "open encoder fail!" << endl;return -1;}//[6]//输出格式信息av_dump_format(pFormatCtx, 0, output_rtmp_url, 1);//初始化帧AVFrame *picture = av_frame_alloc();picture->width = pCodecCtx->width;picture->height = pCodecCtx->height;picture->format = pCodecCtx->pix_fmt;av_frame_get_buffer(picture, 32);size = avpicture_get_size(pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);picture_buf = (uint8_t*)av_malloc(size);avpicture_fill((AVPicture*)picture, picture_buf, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);//[7] --写头文件avformat_write_header(pFormatCtx, NULL);//[7]//[8] --循环编码每一帧AVPacket pkt; //创建已编码帧int frame_count = 0;while (!feof(in_file)) {// 读取一帧 YUV 数据uint8_t yuv_buf[pCodecCtx->width * pCodecCtx->height * 3 / 2];size_t read_size = fread(yuv_buf, 1, pCodecCtx->width * pCodecCtx->height * 3 / 2, in_file);if (read_size <= 0) {break;}av_init_packet(&pkt);pkt.data = NULL;pkt.size = 0;// 将 YUV 数据编码为 H.264memcpy(picture->data[0], yuv_buf, pCodecCtx->width * pCodecCtx->height);memcpy(picture->data[1], yuv_buf + pCodecCtx->width * pCodecCtx->height, pCodecCtx->width * pCodecCtx->height / 4);memcpy(picture->data[2], yuv_buf + pCodecCtx->width * pCodecCtx->height * 5 / 4, pCodecCtx->width * pCodecCtx->height / 4);picture->pts = frame_count;int got_picture = 0;//编码int ret = avcodec_encode_video2(pCodecCtx, &pkt, picture, &got_picture);if (ret < 0){cout << "encoder fail!" << endl;return -1;}if (!got_picture){ret = 0;break;}cout << "encoder success! " <<picture->pts<< endl;// parpare packet for muxingpkt.stream_index = video_st->index;pkt.pts = frame_count * (pCodecCtx->time_base.den) / ((pCodecCtx->time_base.num) * 25);pkt.dts = pkt.pts;av_packet_rescale_ts(&pkt, pCodecCtx->time_base, video_st->time_base);pkt.pos = -1;ret = av_interleaved_write_frame(pFormatCtx, &pkt);if(ret < 0)break;av_free_packet(&pkt);frame_count++;usleep(30*1000);}//[8]//[9] --写文件尾av_write_trailer(pFormatCtx);//[9]//释放内存if (video_st){avcodec_close(video_st->codec);av_free(picture);av_free(picture_buf);}if (pFormatCtx){avio_close(pFormatCtx->pb);avformat_free_context(pFormatCtx);}fclose(in_file);return 0;
}

压缩一半的方式推送本地yuv文件 代码:

#include <stdio.h>
#include <unistd.h>
#include <iostream>
extern "C" {
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavcodec/avcodec.h"
#include "libswscale/swscale.h"
};
using namespace std;const char* input_file = "/mnt/hgfs/shareVM/BigBuckBunny_CIF_24fps.yuv";
const char* output_rtmp_url = "rtmp://10.10.18.94:1935/live/test";
const int fps = 25;int main(int argc, char *argv[]) {AVFormatContext *pFormatCtx = nullptr;AVCodecContext *pCodecCtx = nullptr;//打开视频文件FILE *in_file = fopen(input_file, "rb");if (!in_file) {cout << "can not open file!" << endl;return -1;}//[1] --注册所有ffmpeg组件avcodec_register_all();av_register_all();//[2] --初始化AVFormatContext结构体,根据文件名获取到合适的封装格式avformat_alloc_output_context2(&pFormatCtx, NULL, "flv", output_rtmp_url);AVOutputFormat *fmt = pFormatCtx->oformat;//[3] --打开文件if (avio_open(&pFormatCtx->pb, output_rtmp_url, AVIO_FLAG_READ_WRITE)) {cout << "output file open fail!";return -1;}//[3]//[4] --初始化视频码流AVStream *video_st = avformat_new_stream(pFormatCtx, 0);if (video_st == NULL){printf("failed allocating output stram\n");avio_close(pFormatCtx->pb);avformat_free_context(pFormatCtx);return -1;}video_st->time_base.num = 1;video_st->time_base.den = fps;//[4]struct SwsContext* swsContext = sws_getContext(352, 288, AV_PIX_FMT_YUV420P,352 / 2, 288 / 2, AV_PIX_FMT_YUV420P,SWS_BICUBIC, NULL, NULL, NULL);if(swsContext == NULL) {printf("failed sws_getContext\n");avio_close(pFormatCtx->pb);avformat_free_context(pFormatCtx);return -1;}//[5] --编码器Context设置参数pCodecCtx = video_st->codec;pCodecCtx->codec_id = fmt->video_codec;pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;pCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;pCodecCtx->width = 352 / 2;pCodecCtx->height = 288 / 2;pCodecCtx->time_base = {1, fps};pCodecCtx->framerate = {fps, 1};pCodecCtx->bit_rate = 400000;pCodecCtx->gop_size = 50;//[5]//[6] --寻找编码器并打开编码器AVCodec *pCodec = avcodec_find_encoder(AV_CODEC_ID_FLV1);if (!pCodec){cout << "no right encoder!" << endl;return -1;}if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0){cout << "open encoder fail!" << endl;avformat_free_context(pFormatCtx);return -1;}//[6]//输出格式信息av_dump_format(pFormatCtx, 0, output_rtmp_url, 1);//初始化帧AVFrame *originalFrame = av_frame_alloc();originalFrame->width = 352;originalFrame->height = 288;originalFrame->format = pCodecCtx->pix_fmt;av_frame_get_buffer(originalFrame, 32);int originalFrame_size = avpicture_get_size(pCodecCtx->pix_fmt, 352, 288);uint8_t* originalFrame_buf = (uint8_t*)av_malloc(originalFrame_size);avpicture_fill((AVPicture*)originalFrame, originalFrame_buf, pCodecCtx->pix_fmt, 352, 288);AVFrame *compressFrame = av_frame_alloc();compressFrame->width = pCodecCtx->width;compressFrame->height = pCodecCtx->height;compressFrame->format = pCodecCtx->pix_fmt;av_frame_get_buffer(compressFrame, 32);int compressFrame_size = avpicture_get_size((AVPixelFormat)compressFrame->format, compressFrame->width, compressFrame->height);uint8_t* compressFrame_buf = (uint8_t*)av_malloc(compressFrame_size);avpicture_fill((AVPicture*)compressFrame, compressFrame_buf, (AVPixelFormat)compressFrame->format, compressFrame->width, compressFrame->height);//[7] --写头文件avformat_write_header(pFormatCtx, NULL);//[7]   //[8] --循环编码每一帧AVPacket pkt; //创建已编码帧int frame_count = 0;while (!feof(in_file)) {// 读取一帧 YUV 数据uint8_t yuv_buf[352 * 288 * 3 / 2];size_t read_size = fread(yuv_buf, 1, 352 * 288 * 3 / 2, in_file);if (read_size <= 0) {break;}av_init_packet(&pkt);pkt.data = NULL;pkt.size = 0;// 将 YUV 数据编码为 H.264memcpy(originalFrame->data[0], yuv_buf, 352 * 288);memcpy(originalFrame->data[1], yuv_buf + 352 * 288, 352 * 288 / 4);memcpy(originalFrame->data[2], yuv_buf + 352 * 288 * 5 / 4, 352 * 288 / 4);originalFrame->pts = compressFrame->pts = frame_count;int got_picture = 0;sws_scale(swsContext, (const uint8_t* const*)originalFrame->data, originalFrame->linesize, 0,288, compressFrame->data, compressFrame->linesize);//编码int ret = avcodec_encode_video2(pCodecCtx, &pkt, compressFrame, &got_picture);if (ret < 0){cout << "encoder fail!" << endl;return -1;}if (got_picture){cout << "encoder success! " <<compressFrame->pts<< endl;// parpare packet for muxingpkt.stream_index = video_st->index;pkt.pts = frame_count * (pCodecCtx->time_base.den) / ((pCodecCtx->time_base.num) * fps);pkt.dts = pkt.pts;av_packet_rescale_ts(&pkt, pCodecCtx->time_base, video_st->time_base);pkt.pos = -1;ret = av_interleaved_write_frame(pFormatCtx, &pkt);if(ret < 0)break;}av_free_packet(&pkt);frame_count++;usleep(30 * 1000);}//[8]//[9] --写文件尾av_write_trailer(pFormatCtx);//[9]//释放内存if (video_st){avcodec_close(video_st->codec);av_free(originalFrame);av_free(originalFrame_buf);av_free(compressFrame);av_free(compressFrame_buf);}if (pFormatCtx){avio_close(pFormatCtx->pb);avformat_free_context(pFormatCtx);}fclose(in_file);return 0;
}

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

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

相关文章

身边有填报志愿需求别错过!张雪峰透露今年志愿填报技巧:报专业,别报行业!(文末附稳定高薪专业推荐)

高考填报志愿是每个考生和家长都要面对的重大抉择。在当前就业形势日趋严峻、部分行业发展前景不明朗的大背景下,考生在填报志愿时更需要全面了解各个专业的就业前景,理性权衡自身兴趣特长与社会需求&#xff0c;而不是盲目跟风报考所谓的"热门专业"。 今天跟大家分…

期权开户零门槛怎么操作?期权不满50w的开户方式

今天带你了解期权开户零门槛怎么操作&#xff1f;期权不满50w的开户方式。在股票期权市场上&#xff0c;期权交易是一种非常受欢迎的投资方式。它不仅可以增加投资组合的多样性&#xff0c;还可以为投资者提供一定的保护和利润机会&#xff0c;比如通过买入认股期权做空对冲大盘…

如何选择视频号矩阵系统:打造高效短视频内容生态的指南

在短视频内容创作和分发的热潮中&#xff0c;视频号矩阵系统作为一种高效的管理工具&#xff0c;受到了越来越多创作者和品牌的青睐。它通过集中管理多个视频号&#xff0c;优化内容发布流程&#xff0c;帮助用户提升工作效率和内容影响力。本文将探讨如何选择一个合适的视频号…

振弦采集仪的工程安全监测实践与案例分析

振弦采集仪的工程安全监测实践与案例分析 振弦采集仪是一种常用的工程安全监测仪器&#xff0c;通过测量被监测结构的振动频率与振型&#xff0c;可以实时监测结构的安全状况。本文将结合实践经验和案例分析&#xff0c;探讨振弦采集仪在工程安全监测中的应用。 一&#xff0c…

欢乐钓鱼大师游戏攻略:在什么地方掉称号鱼?云手机游戏辅助!

《欢乐钓鱼大师》是一款融合了休闲娱乐和策略挑战的钓鱼游戏。游戏中的各种鱼类不仅各具特色&#xff0c;而且钓鱼过程充满了挑战和乐趣。下面将为大家详细介绍如何在游戏中钓鱼&#xff0c;以及一些有效的钓鱼技巧&#xff0c;帮助你成为一个出色的钓鱼大师。 实用工具推荐 为…

io_contextttttttttttt

创建上下文——io_context_t 它是一个上下文结构&#xff0c;在内部它包含一个完成队列&#xff0c;在线程之间是可以共享的。 提交请求——iocb io回调数据结构&#xff0c;和io_submit配合使用。 处理结果 通过io_event处理结果&#xff0c; struct io_event {void *data…

【刷题汇总--Fibonacci数列、单词搜索、杨辉三角】

C日常刷题积累 今日刷题汇总 - day0041、Fibonacci数列1.1、题目1.2、思路1.3、程序实现 2、单词搜索2.1、题目2.2、思路2.3、程序实现 3、杨辉三角3.1、题目3.2、思路3.3、程序实现 - 蛮力法3.4、程序实现 - vector3.5、程序实现 - dp 4、题目链接 今日刷题汇总 - day004 1、…

【CUDA】 矩阵乘向量 matVecMul

Matrix - Vector Multiplication 矩阵-向量乘法是线性代数中的基本操作。它用于将一个矩阵与一个向量相乘。乘法的结果是与输入向量大小相同的向量。 矩阵和向量的乘法如图1所示。 图1 基础kernel与共享内存kernel 执行矩阵-向量乘法的基础kernel是使用单个线程执行输出向量…

【SOLID原则前端中的应用】开闭原则(Open/Closed Principle)- vue3示例

开闭原则&#xff08;Open/Closed Principle&#xff09;在Vue 3中的应用 开闭原则&#xff08;Open/Closed Principle&#xff0c;OCP&#xff09;规定&#xff0c;软件实体&#xff08;类、模块、函数等&#xff09;应该对扩展开放&#xff0c;对修改关闭。 也就是说&#xf…

大型网站软件系统架构演进过程

在我们的生活中,通常会使用大型网站系统,比如购物网站淘宝,京东,阿里1688;大型搜索引擎网站百度,社交类的如腾讯旗下的微信,QQ及新浪旗下的微博等,他们通常都有一下特点: 高并发、大流量&#xff1a;这些系统必须能够处理成千上万甚至数百万的并发用户请求&#xff0c;以及持续…

Dubbo内部通信流程

我当时在学习的过程中搭建过demo&#xff0c;具体流程就是&#xff0c;我先定义了一个api接口模块&#xff0c;还定义一个服务提供者模块&#xff0c;然后服务提供方实现该接口&#xff0c;定义该方法具体的实现impl类&#xff0c;服务提供方启动时&#xff0c;将要暴露的服务和…

在线快速制作二维码的技巧,支持生成多种内容二维码

现在用二维码来分享内容是很多场景下会使用的一种方式&#xff0c;常见的展示内容有图片、文件、文本、音频、视频等&#xff0c;都可以生成二维码之后。通过手机扫码来查看内容&#xff0c;有利于内容的快速传播&#xff0c;并且用户获取信息也更加的方便。 下面来教大家使用…

Web应用防火墙用在哪些场景?

WAF是Web Application Firewall的缩写&#xff0c;翻译为“Web应用防火墙”是一种网络安全设备或服务&#xff0c;用于保护Web应用程序免受各种网络攻击和漏洞的影响。 WAF特别设计用于识别和阻止特定于Web应用程序的攻击&#xff0c;例如SQL注入、跨站脚本(XSS)、跨站请求伪造…

力扣习题--哈沙德数

一、前言 本系列主要讲解和分析力扣习题&#xff0c;所以的习题均来自于力扣官网题库 - 力扣 (LeetCode) 全球极客挚爱的技术成长平台 二、哈沙德数 1. 哈沙德数 如果一个整数能够被其各个数位上的数字之和整除&#xff0c;则称之为 哈沙德数&#xff08;Harshad number&…

CTF常用sql注入(二)报错注入(普通以及双查询)

0x05 报错注入 适用于页面无正常回显&#xff0c;但是有报错&#xff0c;那么就可以使用报错注入 基础函数 floor() 向下取整函数 返回小于或等于传入参数的最大整数。换句话说&#xff0c;它将数字向下取整到最接近的整数值。 示例&#xff1a; floor(3.7) 返回 3 floor(-2…

5.基于SpringBoot的SSMP整合案例-数据层开发

目录 1.新建项目 2.实体类开发&#xff1a; 2.1在pom.xml中增加Lombok坐标&#xff1a; 2.2添加Book实体类 3.数据层开发&#xff1a; 3.1 配置MyBatisPlus与Druid 3.2创建数据层接口 3.3写测试类 3.4点击运行&#xff1a; 4.数据层快速开发&#xff1a; 4.1配置MyB…

C++视觉开发 四.手势识别

本章记录传统手势识别&#xff0c;在表示0-5六个数值时的识别问题。例如识别剪刀石头布&#xff0c;手势&#xff0c;以及其表示的动作。在识别时将手势中的凹陷区域称为凸缺陷&#xff0c;其个数作为识别的重要依据。 需要注意&#xff0c;在凸缺陷个数为0时&#xff0c;无法…

S272钡铼技术4G无线RTU支持多路DIN输入和模拟量转换至4G网络

钡铼第四代RTU S272是一款先进的工业级4G远程遥测终端&#xff0c;为各种远程工业数据采集和控制系统提供了高效解决方案。结合了现代通信技术和多功能的输入输出接口&#xff0c;S272不仅支持多路数字量和模拟量输入&#xff0c;还具备灵活的扩展性和强大的控制功能&#xff0…

WEB攻防-XSS跨站反射型存储型DOM型标签闭合输入输出JS代码解析

文章目录 XSS跨站-输入输出-原理&分类&闭合XSS跨站-分类测试-反射&存储&DOM反射型XSS存储型XSSDOM-base型XSS XSS跨站-输入输出-原理&分类&闭合 漏洞原理&#xff1a;接受输入数据&#xff0c;输出显示数据后解析执行 基础类型&#xff1a;反射(非持续…

典型案例 | 基于全数字实时仿真的嵌入式DevOps解决方案

为丰富浙江省信息技术应用创新&#xff08;以下简称“信创”&#xff09;产业生态&#xff0c;在全社会各领域形成示范效应&#xff0c;浙江省经信厅联合省密码管理局开展2023年浙江省深化信创典型案例评选工作。 经过征集申报、专家评选、名单公示等程序&#xff0c;确定36个…