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

ffmpeg视频解码

一、视频解码流程

使用ffmpeg解码视频帧主要可分为两大步骤:初始化解码器解码视频帧,以下代码以mjpeg为例

1. 初始化解码器

初始化解码器主要有以下步骤:

(1)查找解码器

// 查找MJPEG解码器pCodec = avcodec_find_decoder_by_name(videoCodecName);if (pCodec == nullptr) {release();return false;}// 分配解码器上下文pCodecCtx = avcodec_alloc_context3(pCodec);if (!pCodecCtx) {release();return false;}

(2)设置解码器参数

    pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;pCodecCtx->width = mVideoSrcWidth; // 视频宽度pCodecCtx->height = mVideoSrcHeight; // 视频高度pCodecCtx->pix_fmt = AV_PIX_FMT_YUVJ422P; // 或者其他适合的格式pCodecCtx->time_base = { 1, mVideoSrcFps }; // 帧率pCodecCtx->thread_count = 2;

(3)打开解码器

 // 打开解码器if (avcodec_open2(pCodecCtx, pCodec, nullptr) < 0) {release();return false;}

2. 解码视频帧数据

解码视频帧数据主要有以下步骤:

(1)将编码数据送往解码器

AVPacket* packet = av_packet_alloc();if (!packet) {release();return false;}packet->data = data; // 待解码数据地址packet->size = size; // 待解码数据大小// 发送数据到解码器int ret = avcodec_send_packet(pCodecCtx, packet);if (ret < 0) {release();return false;}

(2)接收解码数据

ret = avcodec_receive_frame(pCodecCtx, pFrame);

二、使用ffmpeg实现对内存中的视频帧数据解码

以下代码中InitDecoder为初始化解码器接口,DecodeVideoFrame为解码视频帧接口

需注意

(1)解码的色彩空间pCodecCtx->pix_fmt不可随意指定,调用avcodec_send_packet后可能会变化,这与视频帧的编码方式有关
(2)每次接收完解码数据要调用av_frame_unref进行释放,否则会有内存泄漏问题


extern "C" { // ffmpeg为使用C语言库,因此要声明为C语言的方式链接
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavutil/avutil.h>
#include <libavutil/opt.h>
#include <libavutil/mathematics.h>
#include <libavutil/timestamp.h>
#include <libswresample/swresample.h>
#include <libswscale/swscale.h>
#include <libavutil/imgutils.h>
#include <libavutil/error.h>
}char videoCodecName[] = "mjpeg";
FILE* out_file = nullptr;AVFormatContext* pFormatCtx = nullptr;AVCodecContext* pCodecCtx = nullptr;
const AVCodec* pCodec = nullptr;
AVFrame* pFrame = nullptr;
AVFrame* pFrameYUYV = nullptr;
int yuyv_size = 0;
uint8_t* buffer = nullptr;
SwsContext* sws_ctx = nullptr;int      mVideoSrcWidth = 1920;
int      mVideoSrcHeight = 1080;
int      mVideoSrcFps = 30;bool InitDecoder() {fopen_s(&out_file, "test_yuv.yuv", "wb");// 查找MJPEG解码器pCodec = avcodec_find_decoder_by_name(videoCodecName);if (pCodec == nullptr) {release();return false;}// 分配解码器上下文pCodecCtx = avcodec_alloc_context3(pCodec);if (!pCodecCtx) {release();return false;}pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;pCodecCtx->width = mVideoSrcWidth; // 视频宽度pCodecCtx->height = mVideoSrcHeight; // 视频高度pCodecCtx->pix_fmt = AV_PIX_FMT_YUVJ422P; // 或者其他适合的格式pCodecCtx->time_base = { 1, mVideoSrcFps }; // 帧率pCodecCtx->thread_count = 2;// 打开解码器if (avcodec_open2(pCodecCtx, pCodec, nullptr) < 0) {release();return false;}// 分配帧pFrame = av_frame_alloc();pFrameYUYV = av_frame_alloc();if (!pFrame || !pFrameYUYV) {release();return false;}// 分配YUYV帧的缓冲区yuyv_size = av_image_get_buffer_size(AV_PIX_FMT_YUYV422, pCodecCtx->width, pCodecCtx->height, 1);buffer = (uint8_t*)av_malloc(yuyv_size * sizeof(uint8_t));if (!buffer) {release();return false;}av_image_fill_arrays(pFrameYUYV->data, pFrameYUYV->linesize, buffer, AV_PIX_FMT_YUYV422, pCodecCtx->width, pCodecCtx->height, 1);// 创建图像转换上下文sws_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt,pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_YUYV422,SWS_BILINEAR, nullptr, nullptr, nullptr);if (!sws_ctx) {release();return false;}
}bool DecodeVideoFrame(uint8_t* data, int size)
{AVPacket* packet = av_packet_alloc();if (!packet) {release();return false;}packet->data = data;packet->size = size;// 发送数据到解码器int ret = avcodec_send_packet(pCodecCtx, packet);if (ret < 0) {release();return false;}// 循环接收解码后的帧while (ret >= 0) {ret = avcodec_receive_frame(pCodecCtx, pFrame);if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {break;}else if (ret < 0) {release();return false;}/******** 将解码后数据进行处理 ********/// 转换为YUYV格式if (sws_scale(sws_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameYUYV->data, pFrameYUYV->linesize) < 0) {return false;}fwrite(pFrameYUYV->data[0], 1, yuyv_size, out_file);/******** 将解码后数据进行处理 ********/av_frame_unref(pFrame); // 将每次接收的解码帧释放掉,否则会内存泄露}av_packet_unref(packet);av_packet_free(&packet);return true;
}void release()
{if (buffer) {av_free(buffer);buffer = nullptr;}if (pCodecCtx) {avcodec_free_context(&pCodecCtx);pCodecCtx = nullptr;}if (pFormatCtx) {avformat_close_input(&pFormatCtx);pFormatCtx = nullptr;}if (pFrame) {av_frame_free(&pFrame);pFrame = nullptr;}if (pFrameYUYV) {av_frame_free(&pFrameYUYV);pFrameYUYV = nullptr;}if (out_file) {fclose(out_file);}}

相关文章:

ffmpeg视频解码

一、视频解码流程 使用ffmpeg解码视频帧主要可分为两大步骤&#xff1a;初始化解码器和解码视频帧&#xff0c;以下代码以mjpeg为例 1. 初始化解码器 初始化解码器主要有以下步骤&#xff1a; &#xff08;1&#xff09;查找解码器 // 查找MJPEG解码器pCodec avcodec_fin…...

前端入门一之CSS知识详解

前言 CSS是前端三件套之一&#xff0c;在MarkDown中也完美兼容这些语法&#xff1b;这篇文章是本人大一学习前端的笔记&#xff1b;欢迎点赞 收藏 关注&#xff0c;本人将会持续更新。 文章目录 Emmet语法&#xff1a;CSS基本语法&#xff1a;css语法结构只有3种&#xff1a…...

【JS学习】10. web API-BOM

文章目录 Web APIs - 第5天笔记js组成window对象定时器-延迟函数location对象navigator对象histroy对象本地存储&#xff08;今日重点&#xff09;localStorage&#xff08;重点&#xff09;sessionStorage&#xff08;了解&#xff09;localStorage 存储复杂数据类型 综合案例…...

C#实现递归获取所有父级的列表

条件&#xff1a; 父级的id是子级的父id形成递归条件 实现功能&#xff1a; 获取自己到最顶级父级的列表&#xff08;假如最顶级父级的父ID0&#xff09; 代码&#xff1a; 解释&#xff1a;CF_CODE是自己的ID&#xff0c;CF_PARENT_ID是父id /// <summary>/// 递归获…...

【深度学习】梯度累加和直接用大的batchsize有什么区别

梯度累加与使用较大的batchsize有类似的效果&#xff0c;但是也有区别 1.内存和计算资源要求 梯度累加&#xff1a; 通过在多个小的mini-batch上分别计算梯度并累积&#xff0c;梯度累积不需要一次加载所有数据&#xff0c;因此显著减少了内存需求。这对于显存有限的设别尤为重…...

【Linux】网络相关的命令

目录 ① ip addr show ② ip route show ③ iptables -nvL ④ ping -I enx00e04c6666c0 192.168.1.100 ⑤ ip route get 192.168.1.100 ⑥ sudo ip addr add dev enx00e04c6666c0 192.168.1.101/24 ⑦ ifconfig ⑧ netstat ⑨ traceroute ⑩ nslookup ① ip addr sho…...

leetcode哈希表(五)-四数相加II

题目 454.四数相加II 给你四个整数数组 nums1、nums2、nums3 和 nums4 &#xff0c;数组长度都是 n &#xff0c;请你计算有多少个元组 (i, j, k, l) 能满足&#xff1a; 0 < i, j, k, l < nnums1[i] nums2[j] nums3[k] nums4[l] 0 示例 1&#xff1a; 输入&…...

Java学习路线:Maven(一)认识Maven

目录 认识Maven 新建Maven文件 导入依赖 认识Maven Maven是一个Java的项目管理工具&#xff0c;通过Maven&#xff0c;我们可以实现&#xff1a; 项目自动构建&#xff0c;包括代码的编译、测试、打包、安装等依赖管理&#xff0c;快速完成依赖的导入 在学习Maven之前&…...

【深度学习】— 多输入多输出通道、多通道输入的卷积、多输出通道、1×1 卷积层、汇聚层、多通道汇聚层

【深度学习】— 多输入多输出通道、多通道输入的卷积、多输出通道、11 卷积层、汇聚层、多通道汇聚层 多输入多输出通道多通道输入的卷积示例&#xff1a;多通道的二维互相关运算 多输出通道实现多通道输出的互相关运算 11 卷积层11 卷积的作用 使用全连接层实现 11 卷积小结 …...

java mapper 的 xml讲解

<?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace"com.bnc.s12.mapper.GoodaCateDT…...

全面解析:区块链技术及其应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 全面解析&#xff1a;区块链技术及其应用 文章目录 全面解析&#xff1a;区块链技术及其应用什么是区块链区块链的工作原理1. 分…...

python基础学习笔记

本文类比c语言讲解python 一.变量和类型 前缀小知识&#xff1a; 注意&#xff1a;1.python写每一行代码时&#xff0c;结尾不需要 ; 这点是和c语言有很大区别的 2.代码的缩进&#xff08;就是每行代码前面的空格&#xff09;是非常重要的后文会提到 1.定义变量 注意: 和C/C …...

【dvwa靶场:XSS系列】XSS (DOM) 低-中-高级别,通关啦

一、低级low 拼接的url样式&#xff1a;​​​​​​​ http://127.0.0.1/dvwa/vulnerabilities/xss_d/?default 拼接的新内容 <script>alert("假客套")</script> 二、中级middle 拼接的url样式&#xff1a;​​​​​​​ http://127.0.0.1/dvwa/vuln…...

ONLYOFFICE 8.2深度体验:高效协作与卓越性能的完美融合

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀ONLYOFFICE 8.2 &#x1f50d;引言&#x1f4d2;1. ONLYOFFICE 产品简介&#x1f4da;2. 功能与特点&#x1f341;协作编辑 PDF&#x1f342;…...

Mac如何将多个pdf文件归并到一个

电脑&#xff1a;MacBook Pro M1 操作方式&#xff1a; very easy 选中想要归并的所有pdf文件&#xff0c;然后 右键 -> quick actions -> Create PDF 然后就可以看到将所选pdf文件归并为一个pdf的文件了...

LINUX下的Mysql:Mysql基础

目录 1.为什要有数据库 2.什么是数据库 3.LINUX下创建数据库的操作 4.LINUX创建表的操作 5.SQL语句的分类 6.Mysql的架构 1.为什要有数据库 直接用文件直接存储数据难道不行吗&#xff1f;非得搞个数据库呢&#xff1f; 首先用文件存储数据是没错&#xff0c;但是文件不方…...

自然语言处理方向学习建议

自然语言处理方向学习建议 自然语言处理&#xff08;NLP&#xff09;作为人工智能的一个重要分支&#xff0c;近年来在学术界和工业界都取得了显著的发展。作为即将或正在攻读博士学位的你&#xff0c;投身于NLP领域无疑是一个充满挑战与机遇的选择。以下是一些针对NLP方向学习…...

介绍一下如何生成随机数(c基础)

适合对象 c语言初学者 总结语言用色&#xff0c;个人强调用红色&#xff0c;注意为易错点&#xff0c;若有问题请告诉我谢谢。(建议通过目录观看)。一定要自己动手打代码。 rand函数 是生成随机数的函数&#xff0c;但实则是伪随机数。(即是同一个值) 格式 #include<st…...

24-11-1-读书笔记(三十一)-《契诃夫文集》(五)下([俄] 契诃夫 [译] 汝龙)生活乏味但不乏魅力。

文章目录 《契诃夫文集》&#xff08;五&#xff09;下&#xff08;[俄] 契诃夫 [译] 汝龙&#xff09;生活乏味但不乏魅力。目录阅读笔记总结 《契诃夫文集》&#xff08;五&#xff09;下&#xff08;[俄] 契诃夫 [译] 汝龙&#xff09;生活乏味但不乏魅力。 休息&#xff0c…...

从“点”到“面”,热成像防爆手机如何为安全织就“透视网”?

市场上测温产品让人眼花缭乱&#xff0c;通过调研分析&#xff0c;小编发现测温枪占很高比重。但是&#xff0c;测温枪局限于显示单一数值信息&#xff0c;无法直观地展示物体的整体温度分布情况&#xff0c;而且几乎没有功能拓展能力。以AORO A23为代表的热成像防爆手机改变了…...

智能CPU性能优化工具:释放处理器潜能的系统级解决方案

智能CPU性能优化工具&#xff1a;释放处理器潜能的系统级解决方案 【免费下载链接】CPUDoc 项目地址: https://gitcode.com/gh_mirrors/cp/CPUDoc 当你在游戏中遭遇帧率骤降、视频渲染耗时过长&#xff0c;或是多任务处理时系统响应迟滞&#xff0c;这些问题的根源往往…...

利用AI写教材,掌握低查重方法,让你的教材脱颖而出!

许多教材编写者常常会有一种失落感&#xff1a;在花费大量心血完成了主体内容后&#xff0c;配套资源的不足却影响了整体的教学效果。针对课后练习的题型设计&#xff0c;常常缺乏创新的思路&#xff1b;想要制作直观的教学课件&#xff0c;却没有相应的技术能力&#xff1b;对…...

写作压力小了!盘点2026年倾心之选的的降AIGC平台

轻松降低论文AI率在2026年已不再是天方夜谭。以下是2026年最炸裂、实测效果显著的降AIGC平台神器&#xff0c;覆盖AI痕迹消除、文本改写润色、降重优化、学术合规检测四大核心场景&#xff0c;帮你稳妥搞定毕业论文。 一、全流程王者&#xff1a;一站式搞定论文全链路 这类工具…...

二进制魔法:解密Windows平台消息防撤回的底层实现

二进制魔法&#xff1a;解密Windows平台消息防撤回的底层实现 【免费下载链接】RevokeMsgPatcher :trollface: A hex editor for WeChat/QQ/TIM - PC版微信/QQ/TIM防撤回补丁&#xff08;我已经看到了&#xff0c;撤回也没用了&#xff09; 项目地址: https://gitcode.com/Gi…...

基于springboot的论坛网站设计与实现.7z(源码+论文+开题报告)

[点击下载链接》》》] 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了论坛网站的开发全过程。通过分析论坛网站管理的不足&#xff0c;创建了一个计算机管理论坛网站的方案。文章介绍了论坛网站的系统分析部分&…...

轨道桥梁与列车这对CP,到底怎么互相伤害

车桥耦合动力学模型&#xff0c;轮轨耦合动力学模型&#xff0c;采用二自由度列车模型&#xff0c;可以改为FF梁SF梁&#xff0c;采用德国轨道谱&#xff0c;采用积分算法&#xff0c;可以输出桥梁任意位置的响应。玩轨道桥梁动力学的老铁们都知道&#xff0c;车桥耦合这玩意儿…...

从实例出发:宏平均、微平均与权重平均的计算与应用解析

1. 从混淆矩阵说起&#xff1a;理解评估指标的基础 在机器学习分类任务中&#xff0c;我们经常需要评估模型的性能。这时候就离不开混淆矩阵这个基础工具。假设我们有一个二分类问题&#xff0c;类别分别是"是"和"否"。混淆矩阵会告诉我们模型预测的正确和…...

告别Git命令行烦恼:Tig工具让版本控制效率提升3倍

告别Git命令行烦恼&#xff1a;Tig工具让版本控制效率提升3倍 【免费下载链接】tig Text-mode interface for git 项目地址: https://gitcode.com/gh_mirrors/ti/tig 作为开发者&#xff0c;你是否也曾面临这些Git操作痛点&#xff1a;记不住复杂的git log参数组合、在命…...

简单几步,让AI帮你画瑜伽女孩:雯雯的后宫-造相Z-Image-瑜伽女孩模型使用教程

简单几步&#xff0c;让AI帮你画瑜伽女孩&#xff1a;雯雯的后宫-造相Z-Image-瑜伽女孩模型使用教程 1. 模型介绍&#xff1a;你的专属AI瑜伽画师 想象一下&#xff0c;你只需要用文字描述&#xff0c;就能让AI为你创作出专业级的瑜伽女孩图片。这就是"雯雯的后宫-造相Z…...

OWL ADVENTURE应用场景解析:如何用AI助手提升工作效率

OWL ADVENTURE应用场景解析&#xff1a;如何用AI助手提升工作效率 1. 为什么选择OWL ADVENTURE作为AI助手 在当今快节奏的工作环境中&#xff0c;我们每天都要处理大量视觉信息——从产品图片到数据图表&#xff0c;从设计稿到文档扫描件。传统的工作流程往往需要人工逐一查看…...