【FFMPEG应用篇】yuv图片编码为h264文件

#include<iostream>

extern "C"
{
#include"libavutil\imgutils.h"
#include"libavutil\samplefmt.h"
#include"libavformat\avformat.h"
#include"libavutil\opt.h"
#include<libavformat/avformat.h>
#include<libswscale/swscale.h>
#include <libswresample/swresample.h>
}

char errorbuf[1024];

AVCodec *Encodec = NULL;  //编解码器1

AVCodecContext *Enc = NULL; //编码的

void SaveH264(AVPacket * packet)
{
	FILE *fpSave;
	if ((fpSave = fopen("BB.h264", "wb")) == NULL) //h264保存的文件名  
	{
		std::cout << "fopen  SaveH264 NO";
		return;
	}
	fwrite(packet->data, 1, packet->size, fpSave);//写数据到文件中  

	fclose(fpSave);
}

int  main()
{

	static int i = 0;


	av_register_all();

	avcodec_register_all();


	//fps每秒25帧
	int fps = 25;


	Encodec = avcodec_find_encoder(AV_CODEC_ID_H264);
	if (!Encodec)
	{

		printf("avcodec_find_encoder AV_CODEC_ID_H264 failed!\n");
		exit(0);
	}

	Enc = avcodec_alloc_context3(Encodec);
	if (!Enc)
	{

		printf("avcodec_alloc_context3  failed!\n");
		exit(0);
	}

	//设置编码器上下文参数
	Enc->width = 1920;
	Enc->height = 1080;
	Enc->bit_rate = 576000;
	AVRational r = { 1, 25 };//每秒25帧
	Enc->time_base = r;
	Enc->gop_size = 50;//GOP组
	Enc->max_b_frames = 1;
	Enc->pix_fmt = AV_PIX_FMT_YUV420P;//视频格式
	av_opt_set(Enc->priv_data, "preset", "ultrafast", 0);
	av_opt_set(Enc->priv_data, "tune", "stillimage,fastdecode,zerolatency", 0);
	av_opt_set(Enc->priv_data, "x264opts", "crf=26:vbv-maxrate=728:vbv-bufsize=364:keyint=25", 0);


	//Enc->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;

	int ret = avcodec_open2(Enc, Encodec, NULL);
	if (ret < 0)
	{

		printf("avcodec_open2  failed!\n");
		exit(0);
	}
	printf("avcodec_open2 success!\n");


	AVFrame *pict = av_frame_alloc();

	FILE * fyuv = fopen("Out_fileTT.yuv", "rb");
	int nfilelen = (1920 * 1080 * 3) / 2;
	uint8_t * pbuf = new uint8_t[nfilelen];
	fread(pbuf, 1, nfilelen, fyuv);
	fclose(fyuv);

	int size = 1920 * 1080;

	pict->data[0] = pbuf;
	pict->data[1] = pict->data[0] + size;
	pict->data[2] = pict->data[1] + size / 4;
	pict->linesize[0] = 1920;
	pict->linesize[1] = 1920 / 2;
	pict->linesize[2] = 1920 / 2;

	pict->format = AV_PIX_FMT_YUV420P;
	pict->width =  1920;
	pict->height = 1080;

	clock_t start_time = clock();

	int p = 0;
	int Top = 1;
	while (Top != 0)
	{
		//6 encode frame
		pict->pts = p;

		p = p + 3600;

		Top = avcodec_send_frame(Enc, pict);
		if (Top != 0)
		{
			continue;
		}
		AVPacket Packetpkt;
		av_init_packet(&Packetpkt);


		Top = avcodec_receive_packet(Enc, &Packetpkt);
		if (Top != 0)
		{
			av_strerror(Top, errorbuf, sizeof(errorbuf));
			std::cout << "avcodec_receive_packet  NO ->" << errorbuf << Top << std::endl;
			std::cout << " Number :" << i << Top << std::endl;
			i++;
			continue;
		}



		SaveH264(&Packetpkt);

		//*********  Encodec Packetpkt  start   ***************
		std::cout << " Packetpkt size : " << Packetpkt.size << " " << std::endl;
		std::cout << " Packetpkt KB size : " << Packetpkt.size / 1024 << std::endl;
		std::cout << " Packetpkt data : " << Packetpkt.data << std::endl ;
		std::cout << " Packetpkt pts  : " << Packetpkt.pts<< std::endl;
		std::cout << " Packetpkt dts  : " << Packetpkt.dts << std::endl;


		//*********  Encodec Packetpkt  End   ***************



		clock_t end_time = clock();
		std::cout << "Codec Time: " << static_cast<double>(end_time - start_time) / CLOCKS_PER_SEC * 1000 << "ms"<< std::endl;
		std::cout << " ********************* " << std::endl;



		av_packet_unref(&Packetpkt);
		std::cout << " ImageEnde  End "<< std::endl;
	}


	av_free(pict);

	avcodec_close(Enc);
	avcodec_free_context(&Enc);

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

༄yi笑奈何

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值