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数据 的相关文章

  • Python 子进程中的 ffmpeg - 无法找到“管道:”的合适输出格式

    尝试通过 Python 使用 ffmpeg 将字幕刻录到视频中 在命令行中工作正常 但是当从 Python 子进程调用时 p subprocess Popen cd Downloads yt ffmpeg i video vf subtit
  • 来自 http 直播 m3u8 文件的 FFMPEG mp4? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 如何从 http 直播 m3u8 文件中提取 mp4 我尝试了下面这个命令 ffmpeg i input file f rawvideo
  • 使用 FFMPEG 的 HLS FLAC 流

    我使用以下命令从 FLAC 文件创建了一个 HLS 流 并输出 FLAC ffmpeg i 10 brass in pocket flac map 0 a c a 0 flac f hls hls playlist type vod mas
  • JavaScript 中的 FFMPEG 命令

    是否可以使用如下命令 ffmpeg i video 1920 mp4 vf 比例 640 360 video 640 mp4 hide banner在纯 JavaScript 中降低视频的分辨率 例如 我有一个下拉菜单 其中有标签 所以我想
  • 将 H.264 I 帧放入 AVSampleBufferDisplayLayer 但不显示视频图像

    在详细回顾了 WWDC2014 Session513 后 我尝试在 IOS8 0 上编写我的应用程序来解码和显示一个实时 H 264 流 首先 我成功构建了H264参数集 当我得到一个带有 4 位起始代码的帧时 就像 0x00 0x00 0
  • OpenCV 3.0.0 使用 FFMPEG 时出错

    我使用 OpenCV 一段时间了 但是 我最近将系统更改为没有任何管理员权限的集群 问题是这样的 在我的主文件夹中 我安装了 FFMPEG ffmpeg 网站上提供的最新稳定版本 我将它安装在 HOME 中 因此在 HOME lib 中安装
  • ffmpeg drawtext如何设置从右到左的方向

    i write arabic text to videos and it works fine but the issue is that the arabic language is written from right to left
  • 为 iOS6.0 ARMv7 处理器构建 FFMPEG 库

    WARNING 我刚刚被另一位用户告知 在 iOS 上使用 FFMPEG 存在一些法律问题 请在此处留下链接http multinc com 2009 08 24 compatibility Between the iphone app s
  • 将每分钟的 MP3 导出为单独的 WAV

    这绝对是一个奇怪的问题 但我正在寻找一种方法 将 60 分钟的 mp3 混合拆分为 60 个单独的 1 分钟长的 wav 文件 以便与 Echonest 等音频指纹识别 API 一起使用 这是否可以在单个 ffmpeg 命令中实现 或者我是
  • FFmpeg - H264 编码器找不到有效设备并且无法配置编码器

    我尝试使用 H264 编码器进行编码 但是当我这样做时 出现以下错误 h264 v4l2m2m 0x55682d2416c0 Could not find a valid device h264 v4l2m2m 0x55682d2416c0
  • 如何使用 ffmpeg 提取时间精确的视频片段?

    这并不是一个特别新的问题领域 但我已经尝试过那里建议的内容 但运气不佳 那么 我的故事 我有一大段 15 秒的直接来自camera mov 视频 我想从中提取特定的块 我可以通过开始时间和停止时间 以秒为单位 来识别该块 我首先尝试执行我称
  • C# - 捕获 RTP 流并发送到语音识别

    我正在努力实现的目标 在 C 中捕获 RTP 流 将该流转发到 System Speech SpeechRecognitionEngine 我正在创建一个基于 Linux 的机器人 它将接受麦克风输入 将其发送给 Windows 机器 Wi
  • 如何使用ffmpeg重叠和合并多个音频文件?

    我正在尝试将多个音频文件合并到一个文件中 但我可以使用以下命令来连接 而不是连接 ffmpeg v debug i file1 wav i file2 wav i file3 wav filter complex 0 0 concat n
  • 如何使用android ndk r9b为Android编译FFMPEG

    我想设计一个Android应用程序 可以通过FFMPEG命令播放和编辑视频 但我不知道如何在Android上使用FFMPEG 我尝试过从Google搜索到的许多方法 但它们太旧了 无法实现 现在 FFMPEG的最新版本是2 1 1 Andr
  • Python 用静态图像将 mp3 转换为 mp4

    我有x文件包含一个列表mp3我想转换的文件mp3文件至mp4文件带有static png photo 似乎这里唯一的方法是使用ffmpeg但我不知道如何实现它 我编写了脚本来接受输入mp3文件夹和一个 png photo 然后它将创建新文件
  • FFmpeg - 来自 NodeJS 的 RTMP 流,流比实时更快

    我的目标是在 Node 中渲染画布 并将该画布流式传输到 RTMP 服务器 最终是 Twitch 但现在我正在在本地 RTMP 服务器上测试 流式传输到 RTMP 的标准方式似乎是ffmpeg 所以我使用它 从 NodeJS 中作为子进程生
  • 在 macOS 上为 MoviePy 安装 ffmpeg 失败并出现 SSL 错误

    我正在尝试编写一个 Python 程序 在 Mac OS 10 11 16 上使用 MoviePy 将 MP4 文件转换为 GIF 我用 import moviepy editor as mp 我收到一条错误消息 说我需要打电话imagei
  • OpenCV VideoWriter 未写入 Output.avi

    我正在尝试编写一段简单的代码来获取视频 裁剪视频并写入输出文件 系统设置 OS Windows 10 Conda Environment Python Version 3 7 OpenCV Version 3 4 2 ffmpeg Vers
  • Windows 上的 ffmpeg-android ndk

    我正在尝试编译 bash 文件 带有 android ndk 的 ffmpeg 我收到如下错误 arm linux androideabi gcc 无法创建可执行文件 C 编译器测试失败 Makefile 2 config mak 没有这样
  • 使用FFMpeg确定视频类型,然后进行转换?

    我正在尝试以编程方式确定文件的真实类型 看来我必须使用 FFMPeg 来实现这一点 我想确定上传的文件实际上是否是 MP4 或 FLV 对于 Flash 视频 或 WebM 对于 HTML5 我知道 FFMPeg 中的 i 运算符 但我不知

随机推荐

  • 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