1. 主页 > vs安装问题 > VS2017安装问题 >

ffmpeg+vs2017配置及代码示例


准备环境:1、https://ffmpeg.zeranoe.com/builds/ 下载Shared及Dev两个开发包2、vs2017
步骤:1、创建工程2、dev中include及lib到工程,Shared中dll到工程3、将include及lib添加到工程配置中注意:按照网上的方法添加dll编译会失败:1、好像报什么找不到dll的错还是什么错2、FFmpeg被声明为已否决的解决方案
1解决方法网上方法是链接 ->输入 -> 附件依赖项这一步不要了,换成在代码中声明链接,如下:
#pragma comment(lib , "avcodec.lib")
#pragma comment(lib , "avdevice.lib")
#pragma comment(lib , "avfilter.lib")
#pragma comment(lib , "avformat.lib")
#pragma comment(lib , "avutil.lib")
#pragma comment(lib , "postproc.lib")
#pragma comment(lib , "swresample.lib")
#pragma comment(lib , "swscale.lib")

2、解决办法雷神博客中有一个ffmpeg的例子,使用的ffmpeg比较新,api有更新了,例子中国的api未来可能会删除,此处有两个解决办法1)c/c++中 sdl检查勾选否 有风险,不建议2)更换调用接口:

avcodec_decode_video2 换成 avcodec_send_packet

示例如下(从雷神版修改)

// ffmpeg_test.cpp: 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <stdio.h>

#define __STDC_CONSTANT_MACROS

#pragma comment(lib , "avcodec.lib")
#pragma comment(lib , "avdevice.lib")
#pragma comment(lib , "avfilter.lib")
#pragma comment(lib , "avformat.lib")
#pragma comment(lib , "avutil.lib")
#pragma comment(lib , "postproc.lib")
#pragma comment(lib , "swresample.lib")
#pragma comment(lib , "swscale.lib")


extern "C"
{
#include "libavcodec/avcodec.h"
};

#define TEST_H264  1
#define TEST_HEVC  0

int main(int argc, char* argv[])
{
#if 1
	AVCodec *pCodec;
	AVCodecContext *pCodecCtx = NULL;
	AVCodecParserContext *pCodecParserCtx = NULL;

	FILE *fp_in;
	FILE *fp_out;
	AVFrame	*pFrame;

	const int in_buffer_size = 4096;
	unsigned char in_buffer[in_buffer_size + FF_INPUT_BUFFER_PADDING_SIZE] = { 0 };
	unsigned char *cur_ptr;
	int cur_size;
	AVPacket packet;
	int ret, got_picture;


#if TEST_HEVC
	enum AVCodecID codec_id = AV_CODEC_ID_HEVC;
	char filepath_in[] = "bigbuckbunny_480x272.hevc";
#elif TEST_H264
	AVCodecID codec_id = AV_CODEC_ID_H264;
	char filepath_in[] = "bigbuckbunny_480x272.h264";
#else
	AVCodecID codec_id = AV_CODEC_ID_MPEG2VIDEO;
	char filepath_in[] = "bigbuckbunny_480x272.m2v";
#endif

	char filepath_out[] = "bigbuckbunny1_480x272.yuv";
	int first_time = 1;


	//av_log_set_level(AV_LOG_DEBUG);

	avcodec_register_all();

	pCodec = avcodec_find_decoder(codec_id);
	if (!pCodec) {
		printf("Codec not found\n");
		return -1;
	}
	pCodecCtx = avcodec_alloc_context3(pCodec);
	if (!pCodecCtx) {
		printf("Could not allocate video codec context\n");
		return -1;
	}

	pCodecParserCtx = av_parser_init(codec_id);
	if (!pCodecParserCtx) {
		printf("Could not allocate video parser context\n");
		return -1;
	}

	//if(pCodec->capabilities&CODEC_CAP_TRUNCATED)
	//    pCodecCtx->flags|= CODEC_FLAG_TRUNCATED; 

	if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {
		printf("Could not open codec\n");
		return -1;
	}
	//Input File
	fp_in = fopen(filepath_in, "rb");
	if (!fp_in) {
		printf("Could not open input stream\n");
		return -1;
	}
	//Output File
	fp_out = fopen(filepath_out, "wb");
	if (!fp_out) {
		printf("Could not open output YUV file\n");
		return -1;
	}

	pFrame = av_frame_alloc();
	av_init_packet(&packet);

	while (1) {
		cur_size = (int)fread(in_buffer, 1, in_buffer_size, fp_in);
		if (cur_size == 0)
			break;
		cur_ptr = in_buffer;

		while (cur_size>0) {

			int len = av_parser_parse2(
				pCodecParserCtx, pCodecCtx,
				&packet.data, &packet.size,
				cur_ptr, cur_size,
				AV_NOPTS_VALUE, AV_NOPTS_VALUE, AV_NOPTS_VALUE);

			cur_ptr += len;
			cur_size -= len;

			if (packet.size == 0)
				continue;

			//Some Info from AVCodecParserContext
			printf("[Packet]Size:%6d\t", packet.size);
			switch (pCodecParserCtx->pict_type) {
			case AV_PICTURE_TYPE_I: printf("Type:I\t"); break;
			case AV_PICTURE_TYPE_P: printf("Type:P\t"); break;
			case AV_PICTURE_TYPE_B: printf("Type:B\t"); break;
			default: printf("Type:Other\t"); break;
			}
			printf("Number:%4d\n", pCodecParserCtx->output_picture_number);

			//ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, &packet);
			ret = avcodec_send_packet(pCodecCtx, &packet);
			if (ret != 0)
			{
				printf("send pkt error.\n");
				return ret;
			}

                        ret = avcodec_receive_frame/(pCodecCtx, pFrame)
			if(ret == 0)
			{
				if (first_time) {
					printf("\nCodec Full Name:%s\n", pCodecCtx->codec->long_name);
					printf("width:%d\nheight:%d\n\n", pCodecCtx->width, pCodecCtx->height);
					first_time = 0;
				}
				//Y, U, V
				for (int i = 0; i<pFrame->height; i++) {
					fwrite(pFrame->data[0] + pFrame->linesize[0] * i, 1, pFrame->width, fp_out);
				}
				for (int i = 0; i<pFrame->height / 2; i++) {
					fwrite(pFrame->data[1] + pFrame->linesize[1] * i, 1, pFrame->width / 2, fp_out);
				}
				for (int i = 0; i<pFrame->height / 2; i++) {
					fwrite(pFrame->data[2] + pFrame->linesize[2] * i, 1, pFrame->width / 2, fp_out);
				}
				
				printf("Succeed to decode 1 frame!\n");
			}
                        else if (ret < 0)
                        {
                            //printf("%s\n",str2_to_string(ret));
                            //str2_to_string
                            //这里vs会报错,需要在error头文件中修改一个宏
                        }
                }
        }

	//Flush Decoder
	packet.data = NULL;
	packet.size = 0;
	while (1) {
		//ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, &packet);
		ret = avcodec_send_packet(pCodecCtx, &packet);
		if (ret != 0)
		{
			printf("send pkt error.\n");
			return ret;
		}

		while(avcodec_receive_frame(pCodecCtx, pFrame) == 0)
		{
			//Y, U, V
			for (int i = 0; i<pFrame->height; i++) {
				fwrite(pFrame->data[0] + pFrame->linesize[0] * i, 1, pFrame->width, fp_out);
			}
			for (int i = 0; i<pFrame->height / 2; i++) {
				fwrite(pFrame->data[1] + pFrame->linesize[1] * i, 1, pFrame->width / 2, fp_out);
			}
			for (int i = 0; i<pFrame->height / 2; i++) {
				fwrite(pFrame->data[2] + pFrame->linesize[2] * i, 1, pFrame->width / 2, fp_out);
			}

			printf("Flush Decoder: Succeed to decode 1 frame!\n");
		}
	}

	fclose(fp_in);
	fclose(fp_out);


	av_parser_close(pCodecParserCtx);

	av_frame_free(&pFrame);
	avcodec_close(pCodecCtx);
	av_free(pCodecCtx);
#else

	avcodec_register_all();
#endif

	return 0;
}



本文由VS软件圈(vssoft.net)发布,不代表VS软件圈立场,转载联系作者并注明出处:https://vssoft.net/vsazwt/VS2017anzhuangwenti/2020/0727/5850.html

联系我们

在线咨询:点击这里给我发消息

微信号:PREEE8

工作日:9:30-18:30,节假日休息