准备环境: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