FFmpeg 解码H264数据为BGR数据

2023-05-16

封装成一个类
ffmpeg 库是4.1

FFmpegDecodeH264.h

#pragma once
// 此类设计输入H264码流,输出BGR buffer 数据
#include <stdio.h>
extern "C"
{
#include <libavcodec/avcodec.h>
#include <libswscale/swscale.h>
}

class ImageMat
{
public:
	ImageMat()
	{

	}
	~ImageMat()
	{
		if (data)
		{
			delete data;
		}
	}
	int Create(int width, int height, int channel)
	{

		if (width * height * channel > this->width * this->height * this->channel)
		{
			if (this->data)
			{
				delete this->data;
				this->data = new unsigned char[width * height * channel];
			}
			else
			{
				this->data = new unsigned char[width * height * channel];
			}

		}

		this->width = width;
		this->height = height;
		this->channel = channel;

		return 0;
	}

	int width = 0;
	int height = 0;
	int channel = 0;
	unsigned char * data = NULL;

};
class FFmpegDecodeH264
{
public:
	FFmpegDecodeH264();
	~FFmpegDecodeH264();

// ImageMat 最后一个参数最好传入一个vector<ImageMat > 因为有时候传入一帧会输出多帧,此处如果输出多帧,只取最后一帧,可以自己改善
	int InputH264Data(unsigned char * inputData, int inputLen, ImageMat &mImageMat);  // 返回值0 有输出, 返回值<0 没有输出数据,刷新数据时候inputLen = 0;

private:
	int decode(AVPacket *mpkt, ImageMat &mImageMat);

	const AVCodec *codec;
	AVCodecParserContext *parser = NULL;
	AVCodecContext *c = NULL;
	AVFrame *frame;
	AVPacket *pkt;

	struct SwsContext * sws_ctx = NULL;
};

FFmpegDecodeH264.cpp

#include "FFmpegDecodeH264.h"
//#include "opencv2/opencv.hpp"


FFmpegDecodeH264::FFmpegDecodeH264()
{

	avcodec_register_all();

	pkt = av_packet_alloc();
	if (!pkt)
		exit(1);

	/* find the MPEG-1 video decoder */
	codec = avcodec_find_decoder(AV_CODEC_ID_H264);
	if (!codec) {
		fprintf(stderr, "Codec not found\n");
		exit(1);
	}

	c = avcodec_alloc_context3(codec);
	if (!c) {
		fprintf(stderr, "Could not allocate video codec context\n");
		exit(1);
	}


	parser = av_parser_init(codec->id);
	if (!parser) {
		fprintf(stderr, "parser not found\n");
		exit(1);
	}

	/* open it */
	if (avcodec_open2(c, codec, NULL) < 0) {
		fprintf(stderr, "Could not open codec\n");
		exit(1);
	}


	frame = av_frame_alloc();
	if (!frame) {
		fprintf(stderr, "Could not allocate video frame\n");
		exit(1);
	}


}


FFmpegDecodeH264::~FFmpegDecodeH264()
{
	av_parser_close(parser);
	avcodec_free_context(&c);
	av_frame_free(&frame);
	av_packet_free(&pkt);
}


int FFmpegDecodeH264::InputH264Data(unsigned char * inputData, int inputLen, ImageMat & mImageMat)
{
	int ret = 0;
	int error = -1;
	if (inputData == NULL)
	{
		decode(NULL, mImageMat);
	}
	while (inputLen >0) {
		ret = av_parser_parse2(parser, c, &pkt->data, &pkt->size,
			inputData, inputLen, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);
		if (ret < 0) {
			fprintf(stderr, "Error while parsing\n");
			exit(1);
		}
		inputData += ret;
		inputLen -= ret;

		if (pkt->size) {

			int t_w = 0;
			int t_h = 0;
			error = decode(pkt, mImageMat);

			printf("size = %d .....frame.width = %d frame.height = %d frame=%p frame.widthp=%d frame.heightp=%d \n",
				pkt->size, frame->width, frame->height, frame, &frame->width, &frame->height);
		}

	}

	return error;
}

int FFmpegDecodeH264::decode(AVPacket *mpkt, ImageMat & mImageMat)
{

	int ret;
	ret = avcodec_send_packet(c, mpkt);
	if (ret < 0) {
		fprintf(stderr, "Error sending a packet for decoding\n");
		exit(1);
	}


	while (ret >= 0) {
		ret = avcodec_receive_frame(c, frame);
		if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
			return 0;
		else if (ret < 0) {
			fprintf(stderr, "Error during decoding\n");
			exit(1);
		}

		printf("saving frame %3d\n", c->frame_number);
		fflush(stdout);

		/* the picture is allocated by the decoder. no need to
		free it */
		//snprintf(buf, sizeof(buf), "%s-%d", filename, c->frame_number);
		//pgm_save(frame->data[0], frame->linesize[0],
		//	frame->width, frame->height, buf);

		printf("frame->width = %d frame->height = %d frame=%p frame->width_p = %d frame->height_p = %d \n", frame->width, frame->height, frame, &frame->width, &frame->height);




		AVPixelFormat src_pix_fmt = AV_PIX_FMT_YUV420P;
		AVPixelFormat dst_pix_fmt = AV_PIX_FMT_BGR24;
		sws_ctx = sws_getCachedContext(sws_ctx, frame->width, frame->height, src_pix_fmt,
			frame->width, frame->height, dst_pix_fmt,
			SWS_BILINEAR, NULL, NULL, NULL);

		if (frame->height > 0)
		{
			mImageMat.Create(frame->width, frame->height, 3);
			//cv::Mat mBGR = cv::Mat(frame->height, frame->width, CV_8UC3);

			uint8_t *datas[2] = { 0 };
			datas[0] = mImageMat.data;
			int lines[2] = { 0 };
			//lines[0] = frame->width * 3;
			lines[0] = frame->width * 3;
			int ret = sws_scale(sws_ctx,
				frame->data,		//输入数据
				frame->linesize,	//输入行大小
				0,
				frame->height,		//输入高度
				datas,				//输出数据和大小
				lines
			);
#if 0
			if (ret == frame->height)
			{
				cv::Mat mBGR = cv::Mat(frame->height, frame->width, CV_8UC3);
				memcpy(mBGR.data, datas[0], frame->width * frame->height * 3);
				cv::imshow("xxxx", mBGR);

				cv::waitKey(40);

			}
#endif
		}
	}
	return 0;
}

main.cpp


#pragma comment(lib, "opencv_world300.lib")
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "opencv2/opencv.hpp"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern "C"
{
#include <libavcodec/avcodec.h>
#include <libswscale/swscale.h>
}


#include "FFmpegDecodeH264.h"

int main(int argc, char **argv)
{
	const char *filename, *outfilename;
	FILE *f;
	uint8_t inbuf[4096 + AV_INPUT_BUFFER_PADDING_SIZE];
	int ret;
	int data_size;

	if (argc <= 2) {
		fprintf(stderr, "Usage: %s <input file> <output file>\n", argv[0]);
		exit(0);
	}
	filename = "ds.264"; // 输入的264文件
	outfilename = "";

	

	/* set end of buffer to 0 (this ensures that no overreading happens for damaged MPEG streams) */
	memset(inbuf + 4096, 0, AV_INPUT_BUFFER_PADDING_SIZE);

	FFmpegDecodeH264 mFFmpegDecodeH264;
	ImageMat mImageMat;
	f = fopen(filename, "rb");
	if (!f) {
		fprintf(stderr, "Could not open %s\n", filename);
		exit(1);
	}

	while (!feof(f)) {
		/* read raw data from the input file */
		data_size = fread(inbuf, 1, 4096, f);
		if (!data_size)
			break;

		int retC = mFFmpegDecodeH264.InputH264Data(inbuf, data_size, mImageMat);

		printf("####################mImge.height = %d ........\n", mImageMat.height);
		if (mImageMat.height > 0)
		{
			cv::Mat imageShow = cv::Mat(mImageMat.height, mImageMat.width, CV_8UC3, mImageMat.data);

			cv::imshow("last.", imageShow);
			cv::waitKey(30);
		}
	}

	/* flush the decoder */
	int t_w = 0;
	int t_h = 0;
	//decode(c, frame, NULL, outfilename, mImageMat);

	mFFmpegDecodeH264.InputH264Data(NULL, 0, mImageMat);
	fclose(f);

	return 0;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

FFmpeg 解码H264数据为BGR数据 的相关文章

  • 在 MacOS 终端上运行 ffmpeg [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我对 MacOS 相当陌生 我发现使用终端来获取信息并不容易ffmpeg和我在 Window 上一样正常运行 我有 ffmpeg 二进制文件ffmpe
  • ffmpeg concat:“不安全的文件名”

    尝试将一堆 mts 文件转换为一个大 mp4 文件 stephan rechenmonster mnt backupsystem archive2 Videos 20151222 PRIVATE AVCHD BDMV bin ffmpeg
  • C# 中的 H.264(或类似)编码器?

    有谁知道 C 或任何其他托管语言 的开源 H 264 编码器 我也许也可以用 python 实现 我发现的库 例如 x264 是用相当低级的 c 带有大量宏的程序 和汇编语言编写的 调整它们比我想象的要复杂得多 我的项目不关心性能或兼容性
  • 两个图像之间的视频变形,FFMPEG/Minterpolate

    我正在尝试在 Ubuntu Linux 上的 bash 脚本中使用两个帧 png 图像 和 ffmpeg 的 minterpolate 过滤器制作一个快速且简单的变形视频 目的是稍后使用变形作为不同视频编辑器中相似视频之间的过渡 它适用于
  • Chromium 中的 MP4 编解码器支持

    我们已将 Chromium 嵌入式框架集成到我们的 Windows 游戏中 以允许我们从应用程序内渲染网页 并且一切正常 除了 MP4 视频 据我所知 由于许可问题 Chromium 不包含此编解码器 但任何人都可以提供有关我们如何添加支持
  • 如何使用AVAssetWriter将h264流写入视频?

    我想将 h 264 流从服务器传输到视频文件 但是当我使用assetwrite finishwrite XCode 报告 Video var mobile Applications DE4196F1 BB77 4B7D 8C20 7A5D6
  • 如何让 Python 找到 ffprobe?

    I have ffmpeg and ffprobe安装在我的 mac macOS Sierra 上 并且我已将它们的路径添加到 PATH 中 我可以从终端运行它们 我正在尝试使用ffprobe使用以下代码获取视频文件的宽度和高度 impor
  • 如何使用 ffmpeg 设置默认流

    我有一些 m4v 文件 我想用 ffmpeg 添加字幕 我知道我需要映射流以将它们放入输出文件中 但如何确保此字幕流将是默认流 字幕是 srt 人们似乎说它们与 mp4 容器不兼容 我需要先将字幕转换为什么 另外 各种流的顺序重要吗 视频流
  • 如何在 RTMP 流中嵌入 pic_timing SEI 挂钟时间码?

    我需要将我的桌面流式传输到 AWS MediaLive 服务 并且根据要求 我必须在流中包含挂钟时间码 AWS 支持人员善意地通知我 对于 h 264 编码流 我需要提供时间码作为 pic timing SEI 消息 我在 Windows
  • FFmpeg av_read_frame 无法正确读取帧?

    好吧 我已经下载了一些 yuv 格式的原始 UHD 序列 并在 mp4 容器中使用 ffmpeg 对其进行编码 h264 4 4 4 100 质量 25fps 当我使用 ffprobe 找出编码了多少帧时 我得到 600 所以这是 24 秒
  • 如何启用 FFMPEG 日志记录?

    我想调试 ffmpeg 我添加以下代码来打印日志 av log s AV LOG PANIC fmt or printf msg 但这行不通 没有任何调试信息 然后我启用调试构建选项 export COMMON FF CFG FLAGS C
  • FFMPEG 帧到 DirectX 表面

    给定一个指向 FFMPEG 的 AVFrame 的指针avcodec decode video 函数如何将图像复制到 DirectX 表面 假设我有一个指向适当大小的 DX X8R8G8B8 表面的指针 Thanks John 您可以使用
  • swscaler 警告:使用了已弃用的像素格式

    我想先对视频帧执行颜色空间转换 然后使用以下代码将其转换为 opengl 纹理 struct SwsContext pSwsCtx sws getCachedContext NULL width height codec gt pix fm
  • 以 Gif 形式在 Android 上以编程方式共享 WhatsApp 视频

    我如何将 mp4 视频文件转换为 WhatsApp gif 文件 在应用程序 UI 中简单显示为 gif 但内部是特定的 mp4 格式 以在 android 共享意图中使用 并被 Whatsapp 聊天应用程序识别为此类媒体 我搜索了很多
  • ffmpeg 将 m4s 转换为 mp4

    我正在研究 DASH 试图为最终用户优化 QoE 我有一个视频 并使用 ffmpeg 将其编码为不同的比特率 一切都很好 并且可以使用 dash 播放该视频 我想要的是将用户收到的片段合并为一个 m4 并将该 m4 转换为 mp4 我在 f
  • 视频文件转换/转码 Google App Engine

    我想启动一个云计算项目 其简单任务是 接收上传的视频文件 对它们进行一些转码 转换 允许用户下载 流式传输生成的文件 我刚在想ffmpeg作为集成在的外部命令行工具Java Google App engine Application 由于很
  • FFMPEG:尝试从图像和音频创建 facebook 流时出现转换失败错误?

    目标是从图像和音频文件创建 Facebook 流 这是我的命令 ffmpeg re y loop 1 f image2 i maxresdefault jpg i audio loop mp3 ar 44100 b a 128k vcode
  • ffmpeg 找不到 vcodec h264

    我是 ffmpeg 的新手 正在 Windows 上使用它 我尝试使用 H 264 vcodec h264 转换 avi 文件 收到此错误 未知编码器 h264 使用 acodec 的 mp3 也会出现 未知编码器 错误 有人可以帮我解决这
  • 将yuv420p原始数据转换为opencv图像

    我有来自 rtmp 服务器的原始数据 像素格式为 yuv420p 我使用管道来读取数据 但我不知道如何将原始数据解码为图像 command ffmpeg command extend loglevel fatal i rtmp localh
  • 使用 ImageMagick 有效地将线扫描图像拼接在一起

    我正在寻找线扫描相机的替代品 用于体育计时 或者更确切地说 用于需要确定位置的部分 我发现普通工业相机可以轻松与商业相机解决方案的速度相匹配 每秒 gt 1000 帧 对于我的需求来说 通常计时的准确性并不重要 重要的是运动员的相对位置 我

随机推荐

  • Questa-sim安装最后一步点了是之后,安装了hardlock.sys文件导致电脑无限蓝屏重启的解决方案

    学习FPGA xff0c 需要安装Questa sim仿真软件 xff0c 没有提前看安装教程 xff0c 在软件安装的最后一步 xff0c 本应该点击否 xff0c 我点了是以后电脑直接蓝屏无限重启 xff0c 真是反人类的设计 xff1
  • 用定时器计数器计算初值

    只需要输入晶振频率 定时时长和计时方式 一般选择方式1 即可 如晶振为12MHz 定时时长为50ms 方式1 xff0c 即可计算出初值为3CB0 xff0c 如下图所示 总结 xff1a 定时器在单片机有着极其重要的作用 xff0c 利用
  • Linux系统管理---xfs文件系统--centos7

    目录 一 XFS文件系统 xff1a 1 数据区 xff08 data section xff09 2 文件系统活动登录区 xff08 log section xff09 3 实时运行区 xff08 realtime section xff
  • 中文code:blocks安装(三分钟包安装成功,不成功你找我)

    目录 一 下载code bocks压缩包并解压 a 百度网盘下载压缩包 xff08 不需安装了 xff09 b 创键快捷方式并拉到桌面 二 一步完成汉化 xff0c 两步完成调试环境 a 打开上面创建在桌面上的快捷方式 b 一步汉化 c 两
  • 2021-2022年度第三届全国大学生算法设计与编程挑战赛(冬季赛)题解(7道题)

    只有 xff1a B xff0c D xff0c E xff0c G xff0c I xff0c K xff0c L 正文 B xff1a 题目链接 Error 题目 xff1a 思路 xff1a 二分 二分给出一个d xff0c 先考虑第
  • mysql jar包下载(直接链接下载)

    mysql connector java 8 0 23 jar的下载链接 xff1a mysql jar包下载 服务器一年后过期 xff0c 过期的话先用百度网盘下载吧 链接 xff1a https pan baidu com s 187w
  • Druid-1.1.12.jar下载 (链接下载+使用)

    链接下载 xff1a 下载链接 不行的话用网盘下载 网盘下载 xff1a 链接 xff1a https pan baidu com s 1VUvRj VuxCDd3fb uvA8Q pwd 61 1111 提取码 xff1a 1111 下载
  • 第十三届蓝桥杯c++b组2022年国赛决赛题解

    写的不是很好 xff0c 8000 43 浏览量后开的粉丝可见 xff0c 希望涨一点点粉 觉得还阔以的 xff0c 就不要取关了Fight xff4f 39 39 题目pdf下载 xff1a 第十三届蓝桥杯大赛软件赛决赛pdf下载 G题没
  • OpenWrt 设置IP地址

    注 本文是基于Ubuntu14 04 43 Openwrt17 01开发的教程 5 1在开发板上设置IP 由于我们在开发过程中 xff0c 可能会用到其他路由器 xff0c 而它们的IP一般都是192 168 1 1 xff0c 为了让开发
  • java打包成exe(带图片,不放大)

    目录 一 如何把java程序打包成exe文件 二 过程 二 1 如何将java程序打包成jar包 二 2 如何使用软件exe4j将jar包打包成exe文件 三 如何在打包的时候带上图片和音乐 四 如何打包后不放大 五 如何把exe文件发送给
  • 【华为OD机试真题java、python、c++、jsNode】匿名信(100%通过+复盘思路)

    nbsp nbsp 代码请进行一定修改后使用 本代码保证100 通过率 本文章提供java python c jsNode四种代码 复盘思路在文章的最后 题目描述 电视剧 分界线 里面有一个片段 男主为了向警察透露案件细节 且不暴露自己 于
  • 第十四届蓝桥杯javaA组2023年省赛初赛题解

    题目pdf下载 xff1a 第十四届蓝桥杯省赛pdf下载 目录 试题 A 特殊日期 试题 B 与或异或 试题 C 平均 试题 D 棋盘 试题 E 互质数的个数 试题 F 阶乘的和 试题 G 小蓝的旅行计划 试题 H 太阳 试题 I 高塔 试
  • JsNode算法题acm模式输入

    js分为jsNode和JsV8两种输入输出方式 xff0c 一般的执行代码还是一样的 牛客是两种都支持 华为的题目大多只支持jsNode 本文主要介绍jsNode的输入 JsNode 首先他是逐行输入的 xff0c 就和py差不多 xff0
  • c++11 将enum转为字符串,将字符串转为enum

    一般用enum有两种情况 xff0c 一种是string类型方便 人 读 一种是int类型 xff0c 方便机器识别 所以 xff0c 很多情况 xff0c 需要把int转为string类型 xff0c 或者将string转为int类型 x
  • 手把手教你阿里云服务器搭建网站(超详细图文)

    前文概述 出于好奇 xff0c 我用学生优惠租了一台阿里云服务器 xff0c 打算做一些Java web的开发 xff0c 但是毕竟是第一次接触这样的东西 xff0c 还是比较陌生 xff0c 在这个过程中遇到了一些问题 xff08 肯定会
  • arm64位处理器Ubuntu18.04系统安装libpcap-dev

    1 背景需求 编译项目文件时需要包含头文件 xff1a include lt pcap h gt xff0c 但缺少对应的库 正常情况下 xff0c 打开终端 xff0c 输入下面这行指令即可解决 xff1a sudo apt get in
  • 指定JDK运行Jar包

    指定JDK运行Jar包 找到JDK安装路径如下路径 E Java javaJDK bin java exe正常运行Jar包为 java jar xxx jar指定jdk运行 E Java javaJDK bin java exe jar x
  • Anaconda3安装教程---图文讲解

    Hello xff0c 大家好 xff0c 我是霜淮子 xff0c 今天分享一篇Anaconda3的安装教程 软件介绍 Anaconda xff0c 中文大蟒蛇 xff0c 是一个开源的python发行版本 xff0c 其包含了conda
  • C++课程设计——学生成绩管理系统

    今天清理电脑偶尔发现一个我刚学编程时用c 43 43 写的一份课程设计 xff0c 使用到简单的链表 xff0c 结构体 xff0c c 43 43 类与对象的知识 学生成绩管理系统 系统结构 xff1a 管理员模式教师模式学生模式 实现了
  • FFmpeg 解码H264数据为BGR数据

    封装成一个类 ffmpeg 库是4 1 FFmpegDecodeH264 h pragma once 此类设计输入H264码流 xff0c 输出BGR buffer 数据 include lt stdio h gt extern 34 C