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;
}
 


--------------------- 
作者:侵蚀昨天 
来源:CSDN 
原文:https://blog.csdn.net/q2519008/article/details/80044758 
版权声明:本文为博主原创文章,转载请附上博文链接!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值