[ffmpeg] 解码

c 复制代码
#include<iostream>
#include <fstream>
#include <string>
using namespace std;
extern "C"
{
#include <libavcodec/avcodec.h>
#include <libavutil/opt.h>
}

#pragma comment(lib, "avcodec.lib")
#pragma comment(lib, "avutil.lib")

int main(int argc, char* argv[])
{
	// 分割 h264 存入 AVPacket
	string filename = "test.h264";
	ifstream ifs(filename, ios::binary);
	if (!ifs) return -1;
	unsigned char inbuf[4096] = { 0 };

	AVCodecID codec_id = AV_CODEC_ID_H264;

	// 1. 找解码器
	auto codec = avcodec_find_decoder(codec_id);
	// 2. 创建上下文
	auto c = avcodec_alloc_context3(codec);
	// 3. 打开上下文
	avcodec_open2(c, NULL, NULL);

	// 分割上下文
	auto parser = av_parser_init(codec_id);

	auto pkt = av_packet_alloc();
	auto frame = av_frame_alloc();
	while (!ifs.eof())
	{
		ifs.read((char*)inbuf, sizeof(inbuf));
		int data_size = ifs.gcount(); // 读取的字节数
		if (data_size <= 0) break;
		// 通过 0001截断
		auto data = inbuf;
		while (data_size > 0)
		{
			// 通过 0001 截取输出到 AVPacket 返回帧大小
			int ret = av_parser_parse2(parser, c,
				&pkt->data, &pkt->size, // 输出
				data, data_size, // 输入
				AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);
			data += ret;
			data_size -= ret; // 已处理
			if (pkt->size)
			{
				//cout << pkt->size << " " << flush;
				// 发送 packet 到解码线程
				ret = avcodec_send_packet(c, pkt);
				if (ret < 0)
				{
					break;
				}
				// 获取多帧解码数据
				while (ret >= 0)
				{
					// 每次会调用 av_frame_unref
					ret = avcodec_receive_frame(c, frame);
					if (ret < 0)
						break;
					cout << frame->format << " " << flush;
				}
			}
		}
	}
	av_packet_free(&pkt);

	// 取出缓存数据
	int ret = avcodec_send_packet(c, NULL);
	while (ret >= 0)
	{
		ret = avcodec_receive_frame(c, frame);
		if (ret < 0)
			break;
		cout << frame->format << "-" << flush;
	}

	av_parser_close(parser);
	avcodec_free_context(&c);
	av_frame_free(&frame);
	av_packet_free(&pkt);
	return 0;
}
相关推荐
追光天使1 天前
Mac M1 源码安装FFmpeg,开启enable-gpl 和 lib x264
macos·ffmpeg
cuijiecheng20182 天前
FFmpeg源码:av_base64_decode函数分析
ffmpeg
2035去旅行2 天前
FFmpeg(7.1版本)编译:Ubuntu18.04交叉编译到ARM
arm开发·ffmpeg
我码玄黄2 天前
FFmpeg:多媒体处理的瑞士军刀
后端·ffmpeg·开源
yerennuo2 天前
FFmpeg rtmp推流直播
ffmpeg
2035去旅行2 天前
FFmpeg(7.1版本)的基本组成
ffmpeg
学习嵌入式的小羊~4 天前
RV1126画面质量三:QP调节
ffmpeg·音视频
daqinzl4 天前
Ubuntu x64下交叉编译ffmpeg、sdl2到目标架构为aarch64架构的系统(生成ffmpeg、ffprobe、ffplay)
ubuntu·ffmpeg·ffplay·sdl2·交叉编译 aarch64
yerennuo5 天前
FFmpeg 自定义IO和格式转换
ffmpeg
daqinzl6 天前
ubuntu x64下交叉编译ffmpeg到目标架构为aarch架构的系统
ubuntu·ffmpeg·交叉编译·arm64 aarch64