学习FFmpeg简单Samples之视频编码

实例代码

int video_Encode()
{
	int width = 1920;
	int height = 1080;
	int FPS = 25;
	
	AVDictionary* enoptions = 0;
	av_dict_set(&enoptions, "preset", "superfast", 0);
	av_dict_set(&enoptions, "tune", "zerolatency", 0);
	///4 初始化编码器 AV_CODEC_ID_H264
	AVCodec* codec = avcodec_find_encoder(AV_CODEC_ID_H264);
	if (!codec)
	{
		std::cout << "avcodec_find_encoder  failed!" << endl;
		return NULL;
	}
	//视频编码器上下文
	AVCodecContext* vc = avcodec_alloc_context3(codec);
	if (!vc)
	{
		std::cout << "avcodec_alloc_context3  failed!" << endl;
		return NULL;
	}
	std::cout << "avcodec_alloc_context3 success!" << endl;

	vc->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
	vc->codec_id = AV_CODEC_ID_H264;
	vc->codec_type = AVMEDIA_TYPE_VIDEO;
	vc->pix_fmt = AV_PIX_FMT_YUV420P;
	vc->width = width;
	vc->height = height;
	vc->time_base.num = 1;
	vc->time_base.den = FPS;
	vc->framerate = { FPS,1 };
	vc->bit_rate = 400000;
	vc->gop_size = 50;
	vc->qmin = 30;
	vc->qmax = 35;
	vc->max_b_frames = 0;//NO B Frame

	//打开视频编码器
	int ret = avcodec_open2(vc, 0, &enoptions);
	if (ret != 0)
	{
		return XError(ret);
	}
	std::cout << "avcodec_open2 success!" << endl;

	av_dict_free(&enoptions);

	FILE* video_record_yuv = fopen("video_1920x1080_yuv420p.yuv", "rb+");

	FILE* video_record = fopen("video_1920x1080_yuv420p.h264", "wb");

	int pic_size = width * height * 3 / 2;

	int pic = width * height;

	int  EncodeIndex = 0;
	
	uint8_t* yuv = (uint8_t*)av_malloc(pic_size);

	///3 初始化输出的数据结构
	AVFrame* frame_yuv = av_frame_alloc();
	frame_yuv->format = AV_PIX_FMT_YUV420P;
	frame_yuv->width = width;
	frame_yuv->height = height;
	frame_yuv->pts = 0;
	//分配yuv空间
	ret = av_frame_get_buffer(frame_yuv, 32);
	if (ret != 0)
	{
		return XError(ret);
	}


	AVPacket* Encodepacket = av_packet_alloc();

	while (fread(yuv, 1, pic_size, video_record_yuv) >= pic_size)
	{
		frame_yuv->data[0] = yuv;
		frame_yuv->data[1] = yuv + pic;
		frame_yuv->data[2] = yuv + pic *5 / 4;
		
		frame_yuv->pts = EncodeIndex;

		ret = avcodec_send_frame(vc, frame_yuv);

		if (ret < 0) {
			std::cout << "send frame is fail" << endl;
			continue;
		}

		while (ret >= 0) {
			ret = avcodec_receive_packet(vc, Encodepacket);
			if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
				break;
			}

			if (ret < 0) {
				break;
			}

			//Encodepacket->pts = av_rescale_q(av_gettime() - starttime, m_fmt_ctx->streams[video_stream]->time_base, vc->time_base);
			//Encodepacket->dts = Encodepacket->pts;

			//ret = av_bitstream_filter_filter(h264bsfc, m_fmt_ctx->streams[video_stream]->codec, NULL, &Encodepacket->data, &Encodepacket->size, Encodepacket->data, Encodepacket->size, 0);

			std::fwrite(Encodepacket->data, 1, Encodepacket->size, video_record);
			std::cout << "frameindex  : " << EncodeIndex << " pts:" << Encodepacket->pts << " dts: " << Encodepacket->dts << "  encodeSize:" << Encodepacket->size << endl;

			EncodeIndex++;
		}

		av_packet_unref(Encodepacket);

	}

	av_free(yuv);

	std::fclose(video_record);

	std::fclose(video_record_yuv);

	av_packet_free(&Encodepacket);

	av_frame_free(&frame_yuv);

	return 0;
}

你可能感兴趣的:(c++,ffmpeg,ffmpeg)