FFmpeg+SDL 学习笔记2,视频转封装代码

1,流程图

在这里插入图片描述

2,代码

#include <iostream>
using namespace std;

extern "C"
{
#include <libavformat/avformat.h>
}

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

int main()
{
	av_register_all();
	AVFormatContext *ic = nullptr;
	//封装格式的上下文(结构体)
	//AVIOContext *pb;	:IO上下文
	//AVStream **streams;	:视频音频字幕流
	const char* iPath = "./file/test.mp4";
	const char* oPath = "./file/testOut.wmv";
	
	avformat_open_input(&ic, iPath, NULL, NULL);
	//int avformat_open_input(AVFormatContext **ps, const char *url, ff_const59 AVInputFormat *fmt, AVDictionary **options);
	//1,整个封装格式的上下文
	//2,打开文件的路径(也可网页文件)
	//3,指定打开的格式。一般为NULL,让其自己判断
	//4,每个格式对应的参数
	if (!ic)
	{
		cout << "avformat_open_input" << endl;
		//getchar();
		return -1;
	}
	cout << "1,打开文件成功" << endl;

	//2,创建输出上下文
	AVFormatContext *oc = nullptr;
	avformat_alloc_output_context2(&oc, NULL, NULL,oPath);
	if (!oc)
	{
		cout << "avformat_alloc_output_context2" << endl;
		//getchar();
		return -1;
	}
	cout << "2,输出文件成功" << endl;
	

	//3,创建音视频流
	AVStream *videoStream = avformat_new_stream(oc, NULL);
	AVStream *audioStream = avformat_new_stream(oc, NULL);

	//4,设置参数
	avcodec_parameters_copy(videoStream->codecpar, ic->streams[0]->codecpar);
	avcodec_parameters_copy(audioStream->codecpar, ic->streams[1]->codecpar);

	videoStream->codecpar->codec_tag = 0;
	audioStream->codecpar->codec_tag = 0;

	cout << "-----------------------------------------------------------------------------" << endl;
	av_dump_format(ic, 0, iPath, 0);
	cout << "-------------------------------------------------------------------------------" << endl;
	av_dump_format(oc, 0, oPath, 1);

	//5,打开输出文件,写入文件头信息
	int ret = avio_open(&oc->pb, oPath, AVIO_FLAG_WRITE);
	if (ret)
	{
		cerr << "avio_open" << endl;
		getchar();
		return -1;
	}

	ret = avformat_write_header(oc,NULL);
	if (ret)
	{
		cerr << "avformat_write_header" << endl;
		getchar();
		return -1;
	}

	//读取一帧并写入
	AVPacket pkt;	//压缩的一帧数据帧
	for (;;)
	{
		int re = av_read_frame(ic, &pkt);
		if (re)
			break;
		pkt.pts = av_rescale_q_rnd(pkt.pts,
			ic->streams[pkt.stream_index]->time_base,
			oc->streams[pkt.stream_index]->time_base,
			(AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
		pkt.dts = av_rescale_q_rnd(pkt.dts,
			ic->streams[pkt.stream_index]->time_base,
			oc->streams[pkt.stream_index]->time_base,
			(AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
		pkt.pos = -1;
		pkt.duration = av_rescale_q_rnd(pkt.duration,
			ic->streams[pkt.stream_index]->time_base,
			oc->streams[pkt.stream_index]->time_base,
			(AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
		//将数据包写入输出文件
		av_write_frame(oc, &pkt);

		av_packet_unref(&pkt);

		int k = 0;
		cout << k++ << endl;
	}
	//尾部信息(每帧视频的索引)
	av_write_trailer(oc);


	avio_close(oc->pb);
	cout << "------------endl_________________" << endl;


	getchar();
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值