01-解码-H264转YUV

整体方案:
采集端:摄像头采集(YUV)->编码(YUV转H264)->RTMP推流
客户端:RTMP拉流->解码(H264转YUV)->YUV显示(SDL2)

H264码流转YUV是视频解码部分,具体的代码实现如下。

#include <stdio.h>
#include <stdlib.h>
#ifdef __cplusplus
extern "C"
{
#endif
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavutil/imgutils.h>
#include <libswscale/swscale.h>
#ifdef __cplusplus
}
#endifint main(int argc, char *argv[])
{char* in_file = NULL;char* out_file = NULL;av_log_set_level(AV_LOG_INFO);if(argc < 3){av_log(NULL, AV_LOG_ERROR, "缺少输入文件和输出文件参数");return -1;}in_file = argv[1];out_file = argv[2];AVFormatContext *fmt_ctx = NULL;AVCodecContext *cod_ctx = NULL;AVCodec *cod = NULL;struct SwsContext *img_convert_ctx = NULL;int ret = 0;AVPacket packet;//第一步创建输入文件AVFormatContextfmt_ctx = avformat_alloc_context();if (fmt_ctx == NULL){ret = -1;av_log(NULL, AV_LOG_ERROR,"alloc fail");goto __ERROR;}if (avformat_open_input(&fmt_ctx, in_file, NULL, NULL) != 0){ret = -1;av_log(NULL, AV_LOG_ERROR,"open fail");goto __ERROR;}//第二步 查找文件相关流,并初始化AVFormatContext中的流信息if (avformat_find_stream_info(fmt_ctx, NULL) < 0){ret = -1;av_log(NULL, AV_LOG_ERROR,"find stream fail");goto __ERROR;}av_dump_format(fmt_ctx, 0, in_file, 0);//第三步查找视频流索引和解码器int stream_index = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &cod, -1);//第四步设置解码器上下文并打开解码器AVCodecParameters *codecpar = fmt_ctx->streams[stream_index]->codecpar;if (!cod){ret = -1;av_log(NULL, AV_LOG_ERROR,"find codec fail");goto __ERROR;}cod_ctx = avcodec_alloc_context3(cod);avcodec_parameters_to_context(cod_ctx, codecpar);ret = avcodec_open2(cod_ctx, cod, NULL);if (ret < 0){av_log(NULL, AV_LOG_ERROR,"can't open codec");goto __ERROR;}//第五步打开输出文件FILE *out_fb = NULL;out_fb = fopen(out_file, "wb");if (!out_fb){av_log(NULL, AV_LOG_ERROR,"can't open file");goto __ERROR;}//创建packet,用于存储解码前的数据av_init_packet(&packet);//第六步创建Frame,用于存储解码后的数据AVFrame *frame = av_frame_alloc();frame->width = codecpar->width;frame->height = codecpar->height;frame->format = codecpar->format;av_frame_get_buffer(frame, 32);AVFrame *yuv_frame = av_frame_alloc();yuv_frame->width = codecpar->width;yuv_frame->height = codecpar->height;yuv_frame->format = AV_PIX_FMT_YUV420P;av_frame_get_buffer(yuv_frame, 32);// size_t writesize = av_image_get_buffer_size(frame->format, frame->width,frame->height, 32);//第七步重采样初始化与设置参数// uint8_t **data = (uint8_t **)av_calloc((size_t)out_channels, sizeof(*data))img_convert_ctx = sws_getContext(codecpar->width, codecpar->height, codecpar->format, codecpar->width, codecpar->height, AV_PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);//while循环,每次读取一帧,并转码//第八步 读取数据并解码,重采样进行保存int count = 0;while (av_read_frame(fmt_ctx, &packet) >= 0){if (packet.stream_index != stream_index){av_packet_unref(&packet);continue;}ret = avcodec_send_packet(cod_ctx, &packet);if (ret < 0){ret = -1;av_log(NULL, AV_LOG_ERROR,"decode error");goto __ERROR;}while (avcodec_receive_frame(cod_ctx, frame) >= 0){av_log(NULL, AV_LOG_INFO,"decode frame count = %d\n" , count++);sws_scale(img_convert_ctx,(const uint8_t **)frame->data, frame->linesize,0,codecpar->height, yuv_frame->data,yuv_frame->linesize);int y_size = cod_ctx->width * cod_ctx->height;fwrite(yuv_frame->data[0], 1, y_size, out_fb);fwrite(yuv_frame->data[1], 1, y_size/4, out_fb);fwrite(yuv_frame->data[2], 1, y_size/4, out_fb);}av_packet_unref(&packet);}while(1){av_log(NULL, AV_LOG_INFO,"flush decode \n");ret = avcodec_send_packet(cod_ctx, NULL);if (ret < 0){ret = -1;av_log(NULL, AV_LOG_ERROR,"flush decode error\n");goto __ERROR;}while (avcodec_receive_frame(cod_ctx, frame) >= 0){av_log(NULL, AV_LOG_INFO,"flush decode frame count = %d" , count++);sws_scale(img_convert_ctx,(const uint8_t **)frame->data, frame->linesize,0,codecpar->height, yuv_frame->data,yuv_frame->linesize);int y_size = cod_ctx->width * cod_ctx->height;fwrite(yuv_frame->data[0], 1, y_size, out_fb);fwrite(yuv_frame->data[1], 1, y_size/4, out_fb);fwrite(yuv_frame->data[2], 1, y_size/4, out_fb);}}__ERROR:if (fmt_ctx){avformat_close_input(&fmt_ctx);avformat_free_context(fmt_ctx);}if (cod_ctx){avcodec_close(cod_ctx);avcodec_free_context(&cod_ctx);}if (out_fb){fclose(out_fb);}if (frame){av_frame_free(&frame);}if (yuv_frame){av_frame_free(&yuv_frame);}if(img_convert_ctx){sws_freeContext(img_convert_ctx);}return ret;
}

工程链接:https://download.csdn.net/download/sishen4199/88522521?spm=1001.2014.3001.5503
查看YUV视频的工具:https://download.csdn.net/download/sishen4199/88522520?spm=1001.2014.3001.5503
查看H264码流的工具:https://download.csdn.net/download/sishen4199/88522519?spm=1001.2014.3001.5503

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

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

相关文章

设计模式之禅之设计模式-原型模式

设计模式之禅之设计模式-原型模式 一&#xff1a;原型模式的定义 ​ 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。 ​ 原型模式(Prototype Pattern)的简单程度仅次于单例模式和迭代器模式。正是由于简单,使用的场景才非常地多。 ​ 原型模式的核心是一…

SSM德庆县乡村教育图书管理系统-计算机毕设 附源码 24668

SSM德庆县乡村教育图书管理系统 摘 要 大数据时代下&#xff0c;数据呈爆炸式地增长。为了迎合信息化时代的潮流和信息化安全的要求&#xff0c;利用互联网服务于其他行业&#xff0c;促进生产&#xff0c;已经是成为一种势不可挡的趋势。在德庆县乡村教育图书管理的要求下&…

23种设计模式 - 模板方法模式

1. 认识模板方法模式 1.1 模式定义 定义一个操作算法中的框架&#xff0c;而将这些步骤延迟加载到子类中。 它的本质就是固定算法框架。 1.2 解决何种问题 让父类控制子类方法的调用顺序 模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 1.3…

发明专利申请费用是多少

一、申请发明专利的费用是多少 1、申请费&#xff1a; 申请费950元(含印刷费50元) 2、审查费 该项费用仅当申请发明专利时缴纳&#xff0c;申请实用新型及外观设计时不用缴纳。 发明申请审查费2500元 3、专利登记费 申请人在接到专利授权通知书和办理登记手续通知书后&a…

卡尔曼家族从零解剖-(06)一维卡尔曼滤波编程实践

讲解关于slam一系列文章汇总链接:史上最全slam从零开始&#xff0c;针对于本栏目讲解的 卡尔曼家族从零解剖 链接 :卡尔曼家族从零解剖-(00)目录最新无死角讲解&#xff1a;https://blog.csdn.net/weixin_43013761/article/details/133846882 文末正下方中心提供了本人 联系…

【工具】Java计算图片相似度

【工具】Java图片相似度匹配工具 方案一 通过像素点去匹配 /*** * param file1Url 图片url* param file2Url 图片url* return*/public static double img相似度Url(String file1Url, String file2Url){InputStream inputStream1 HttpUtil.createGet(file1Url).execute().…

Unity中Shader光照探针的支持

文章目录 前言一、光照探针用在哪怎么用1、光照探针的应用场景2、我们按照以上条件&#xff0c;在Unity中搭建一个相同的环境3、创建光照探针 二、在我们自己的Shader中&#xff0c;实现支持光照探针1、使用常用的 cginc2、在 v2f 中&#xff0c;准备如下变量3、在顶点着色器中…

macOS文本编辑器 BBEdit 最新 for mac

BBEdit是一款功能强大的文本编辑器&#xff0c;适用于Mac操作系统。它由Bare Bones Software开发&#xff0c;旨在为开发者和写作人员提供专业级的文本编辑工具。 以下是BBEdit的一些主要特点和功能&#xff1a; 多语言支持&#xff1a;BBEdit支持多种编程语言和标记语言&…

ZYNQ PS端的Cache问题

Zynq Cache问题的解决方法 - Kevin_HeYongyuan - 博客园 (cnblogs.com) zynq双核AMP实验之cpu1唤醒代码_xil_settlbattributes-CSDN博客 内存与cache一致性问题_ddr cache一致性-CSDN博客 使用Xil_SetTlbAttributes(0xFFFF0000,0x14de2);可以禁用掉0x1F00 0000区域的Cache&…

负债1320万美元的【思宏集团/Neo-Concep】申请900万美元纳斯达克IPO上市

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 猛兽财经获悉&#xff0c;总部位于香港的思宏集团Neo-Concept International Group Holdings Limited(简称&#xff1a;思宏集团&#xff09;近期已向美国证券交易委员会&#xff08;SEC&#xff09;提交招股书&#xff0c…

【解刊】IEEE(trans),中科院2区,顶刊,CCF-A类,圈外人别想投?

计算机类 • 好刊解读 今天小编带来IEEE旗下计算机领域好刊的解读&#xff0c;如有相关领域作者有意向投稿&#xff0c;可作为重点关注&#xff01;后文有真实发表案例&#xff0c;供您投稿参考~ 01 期刊简介 IEEE Transactions on Computers ☑️出版社&#xff1a;IEEE …

layui 表格(table)合计 取整数

第一步 开启合计行 是否开启合计行区域 table.render({elem: #myTable, url: ../baidui/, page: true, cellMinWidth: 100,totalRow:true,cols: [[ //表头//{ type: checkbox },{ type: checkbox,totalRowText: "合计" },//合计行区域{ field: id, align: center,…

devops步骤 -- jenkins安装

安装的docker-compose ##安装步骤参考&#xff1a; https://editor.csdn.net/md/?articleId133070011 编写docker-compose.yml version: 3 services: # 集合docker_jenkins:user: root # 为了避免一些…

Zookeeper篇---第八篇

系列文章目录 文章目录 系列文章目录一、描述一下 ZAB 协议二、ZAB 和 Paxos 算法的联系与区别?三、ZooKeeper 宕机如何处理?一、描述一下 ZAB 协议 ZAB 协议是 ZooKeeper 自己定义的协议,全名 ZooKeeper 原子广播协议。 ZAB 协议有两种模式:Leader 节点崩溃了如何恢复和消…

稀疏数组如何帮助我们节省内存,提升性能

本文由葡萄城技术团队发布。转载请注明出处&#xff1a;葡萄城官网&#xff0c;葡萄城为开发者提供专业的开发工具、解决方案和服务&#xff0c;赋能开发者。 什么是稀疏矩阵 稀疏矩阵是指矩阵中大部分元素为零的矩阵。在实际应用中&#xff0c;很多矩阵都是稀疏的&#xff0c…

RocketMQ 如何保证消息正常【投递】和【消费】

消息整体处理过程&#xff0c;这里我们将消息的整体处理阶段分为3个阶段进行分析&#xff1a;1、Producer发送消息阶段。 2、Broker处理消息阶段。 3、Consumer消费消息阶段。一、Producer发送消息阶段 1、安全机制保障1&#xff0c;发送方式。 1、同步发送 2、异步发送 3、O…

JPA Buddy快速创建update、find、count、delete、exists方法

JPA Buddy快速创建update、find、count、delete、exists方法&#xff0c;JPA默认提供的CrudRepository\JpaRepository提供的方法比较少&#xff0c;一般我们会手写一些方法&#xff0c;这里我们选择通过JPA Buddy快速生成&#xff0c;之前文章中讲到了JPA Buddy原本是IDEA收费插…

《QT从基础到进阶·二十一》QGraphicsView、QGraphicsScene和QGraphicsItem坐标关系和应用

前言&#xff1a; 我们需要先由一个 QGraphicsView&#xff0c;这个是UI显示的地方&#xff0c;也就是装满可见原色的Scene&#xff0c;然后需要一个QGraphicsScene 用来管理所有可见的界面元素&#xff0c;要实现UI功能&#xff0c;我们需要用各种从QGraphicsItem拼装成UI控件…

scDrug:从scRNA-seq到药物反应预测

scRNA-seq技术允许在转录组水平上对数千个细胞进行测量。scRNA-seq正在成为研究肿瘤微环境中细胞成分及其相互作用的重要工具。scRNA-seq也被用于揭示肿瘤微环境模式与临床结果之间的关联&#xff0c;并在复杂组织中剖析药物治疗的细胞特异性效应。scRNA-seq的最新进展推动了疾…

广告业展示服务预约小程序的效果如何

虽然不少人不会与广告业直接接触&#xff0c;但各种形式的广告却是充斥在人们生活中&#xff0c;线下的传单展板、线上的视频、音频、图文等都是广告很好的传播通道&#xff0c;同时广告业能扩展的客户属性也非常广&#xff0c;下到超市小摊&#xff0c;上到企业公司都有大小相…