您的位置:首页 > 其它

VS2013中使用ffmpeg解码视频

2018-03-28 21:11 1771 查看
在前一篇文章中讲了如何编译ffmpeg,现在介绍如何使用已经编译好的ffmpeg。

首先使用VS2013新建一个控制台工程,取消预编译头,然后将ffmpeg编译生成的include目录拷贝到此工程下,把include改为ffmpeg。加入到工程的包含路径之下,如下图:



拷贝lib到解决方案目录下,加入包含路径:



包含头文件:

extern "C"
{
#include "libavutil/adler32.h"
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavutil/imgutils.h"
}


C++中引用C编译的库,需要加extern “C”,否则会出现没有定义的链接错误。

加载库:

#ifdef _DEBUG
#pragma comment(lib, "libavcodecd.lib")
#pragma comment(lib, "libavformatd.lib")
#pragma comment(lib, "libavutild.lib")
#pragma comment(lib, "libswresampled.lib")
#else
#pragma comment(lib, "libavcodec.lib")
#pragma comment(lib, "libavformat.lib")
#pragma comment(lib, "libavutil.lib")
#pragma comment(lib, "libswresample.lib")
#endif


示例代码:

void video_decode(const char *input_filename, int id, wchar_t* name)
{
AVCodec *codec = NULL;
AVCodecContext *origin_ctx = NULL, *ctx = NULL;
AVFrame *fr = NULL;
uint8_t *byte_buffer = NULL;
AVPacket pkt;
AVFormatContext *fmt_ctx = NULL;
int number_of_written_bytes;
int video_stream;
int got_frame = 0;
int byte_buffer_size;
int i = 0;
int result;
int end_of_stream = 0;
result = avformat_open_input(&fmt_ctx, input_filename, NULL, NULL);
if (result < 0) {
//av_log(NULL, AV_LOG_ERROR, "Can't open file\n");
return;
}

result = avformat_find_stream_info(fmt_ctx, NULL);
if (result < 0) {
return;
}

video_stream = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
if (video_stream < 0)
{
return;
}

origin_ctx = fmt_ctx->streams[video_stream]->codec;
codec = avcodec_find_decoder(origin_ctx->codec_id);
if (!codec)
{
av_log(NULL, AV_LOG_ERROR, "Can't find decoder\n");
return;
}

ctx = avcodec_alloc_context3(codec);
if (!ctx) {
av_log(NULL, AV_LOG_ERROR, "Can't allocate decoder context\n");
return;
}

result = avcodec_copy_context(ctx, origin_ctx);
if (result) {
av_log(NULL, AV_LOG_ERROR, "Can't copy decoder context\n");
return;
}

result = avcodec_open2(ctx, codec, NULL);
if (result < 0) {
av_log(ctx, AV_LOG_ERROR, "Can't open decoder\n");
return;
}

fr = av_frame_alloc();
if (!fr) {
av_log(NULL, AV_LOG_ERROR, "Can't allocate frame\n");
return;
}

byte_buffer_size = av_image_get_buffer_size(ctx->pix_fmt, ctx->width, ctx->height, 16);
byte_buffer = (uint8_t*)av_malloc(byte_buffer_size);
if (!byte_buffer) {
av_log(NULL, AV_LOG_ERROR, "Can't allocate buffer\n");
return;
}

printf("#tb %d: %d/%d\n", video_stream, fmt_ctx->streams[video_stream]->time_base.num, fmt_ctx->streams[video_stream]->time_base.den);
i = 0;
int frame_count = 0;
av_init_packet(&pkt);
do {
if (!end_of_stream)
if (av_read_frame(fmt_ctx, &pkt) < 0)
end_of_stream = 1;
if (end_of_stream) {
pkt.data = NULL;
pkt.size = 0;
}
if (pkt.stream_index == video_stream || end_of_stream)
{
got_frame = 0;
if (pkt.pts == AV_NOPTS_VALUE)
pkt.pts = pkt.dts = i;
result = avcodec_decode_video2(ctx, fr, &got_frame, &pkt);
if (result < 0)
{
av_log(NULL, AV_LOG_ERROR, "Error decoding frame\n");
break;
}
if (got_frame)
{
//if (fr->pict_type == AV_PICTURE_TYPE_I)
{
number_of_written_bytes = av_image_copy_to_buffer(byte_buffer, byte_buffer_size,
(const uint8_t* const *)fr->data, (const int*)fr->linesize,
ctx->pix_fmt, ctx->width, ctx->height, 1);
if (number_of_written_bytes < 0)
{
break;
}
//printf("get a frame,%d, %10"PRId64", %10"PRId64", %8"PRId64", %8d, 0x%08lx\n", video_stream,
//  fr->pkt_pts, fr->pkt_dts, av_frame_get_pkt_duration(fr),
//  number_of_written_bytes, av_adler32_update(0, (const uint8_t*)byte_buffer, number_of_written_bytes));
printf("get a frame\n");
}
}
}
i++;
av_free_packet(&pkt);
av_init_packet(&pkt);
} while (!end_of_stream || got_frame);

av_free_packet(&pkt);
av_frame_free(&fr);
avcodec_close(ctx);
avformat_close_input(&fmt_ctx);
avcodec_free_context(&ctx);
av_freep(&byte_buffer);
return;
}


在VS2013中会出现
a1b6
编译错误:



解决方法:



代码分析其他博文已经有所叙述,这里不再累述。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ffmpeg vs2013