VS2013中使用ffmpeg解码视频

本文详细介绍如何在Visual Studio 2013环境下使用编译好的FFmpeg进行视频解码,包括配置步骤、代码示例及常见错误解决方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在前一篇文章中讲了如何编译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中会出现编译错误:
这里写图片描述
解决方法:
这里写图片描述
代码分析其他博文已经有所叙述,这里不再累述。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值