VS2012中ffmpeg的使用配置及遇到的问题

开发环境:

VS2012 + ffmpeg + SDL

配置步骤:

  1. 将ffmpeg 中的.h文件、.lib文件、.dll文件拷贝到工程目录下,如下图所示:
    这里写图片描述
  2. 在_mingw.h文件的结尾处(在#endif 一行之前)添加了一行:#define restrict
    这里写图片描述
  3. 把所有long long改成了__int64。
  4. 源文件:
#include "stdafx.h"
#include <stdio.h>

extern "C"
{
#include "libavformat/avformat.h"
#include "libavcodec/avcodec.h"
#include "libswscale/swscale.h"

#include "sdl/SDL.h"
#include "sdl/SDL_thread.h"
};

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

int _tmain(int argc, _TCHAR* argv[])
{
    AVFormatContext * pFormatCtx;  //包含输入文件的很多信息,流个数,编解码器
    AVCodecContext * pCodecCtx;    //编解码器上下文
    AVCodec * pCodec;              //真正的编解码器
    AVFrame * pFrame;              //保存刚解码出来的原始数据帧
    AVFrame * pFrameYUV;           //保存真正解码出来的帧,要显示的帧
    char fileName[]="cuc_ieschool.flv";
    av_register_all();             //注册所有的编解码器和文件格式

    pFormatCtx=avformat_alloc_context();
    if(avformat_open_input(&pFormatCtx,fileName,NULL,NULL)!=0)
    {
        printf("打开输入流失败\n");
        return -1;
    }

    if(avformat_find_stream_info(pFormatCtx,NULL)<0)
    {
        printf("查找输入流失败\n");
        return -1;
    }

    //寻找视频流
    int videoStream=-1;
    for(int i=0;i<pFormatCtx->nb_streams;i++)
    {
        if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)
        {
            videoStream=i;
            break;
        }

    }
    if(videoStream==-1)
        return -1;

    pCodecCtx=pFormatCtx->streams[videoStream]->codec; //获得对应流的编解码器信息
    pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
    if(pCodec==NULL)
    {
        printf("没有找到对应流的解码器\n");
        return -1;
    }

    if(avcodec_open2(pCodecCtx,pCodec,NULL)<0)
    {
        printf("无法打开解码器\n");
        return -1;
    }

    pFrame=avcodec_alloc_frame();
    pFrameYUV=avcodec_alloc_frame();

    int numBytes;
    uint8_t * buffer;                        //这个buffer与pFrameYUV关联在一起,
    //用buffer的数据填充帧pFrameYUV
    AVPacket * pPacket;                      //存储视频数据包
    SwsContext * img_convert_ctx;            //源格式信息、宽高,目标格式、宽高
    SDL_Overlay * bmp;                       //相当于一幅图片
    SDL_Surface * screen;
    SDL_Rect myRect;
    SDL_Rect * rect=&myRect;

    screen=SDL_SetVideoMode(pCodecCtx->width,pCodecCtx->height,0,0);
    bmp=SDL_CreateYUVOverlay(pCodecCtx->width,pCodecCtx->height,
        SDL_YV12_OVERLAY,screen);            //显示格式信息

    img_convert_ctx=sws_getContext(pCodecCtx->width,pCodecCtx->height,
        pCodecCtx->pix_fmt,pCodecCtx->width,pCodecCtx->height,
        PIX_FMT_YUV420P,SWS_BICUBIC,NULL,NULL,NULL);

    numBytes=avpicture_get_size(PIX_FMT_YUV420P,pCodecCtx->width,
        pCodecCtx->height);
    buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));

    avpicture_fill((AVPicture *)pFrameYUV,buffer,PIX_FMT_YUV420P,
        pCodecCtx->width,pCodecCtx->height);
    pPacket=(AVPacket *)av_malloc(sizeof(AVPacket));

    rect->x=0;
    rect->y=0;
    rect->w=pCodecCtx->width;
    rect->h=pCodecCtx->height;

    //开始视频解码
    int frameFinished;
    while (av_read_frame(pFormatCtx,pPacket)>=0)
    {
        if(pPacket->stream_index==videoStream)
        {
            avcodec_decode_video2(pCodecCtx,pFrame,&frameFinished,pPacket);
            if(frameFinished)
            {
                sws_scale(img_convert_ctx,pFrame->data,pFrame->linesize,
                    0,pCodecCtx->height,pFrameYUV->data,pFrameYUV->linesize);
                SDL_LockYUVOverlay(bmp);
                bmp->pixels[0]=pFrameYUV->data[0];
                bmp->pixels[2]=pFrameYUV->data[1];
                bmp->pixels[1]=pFrameYUV->data[2];

                bmp->pitches[0]=pFrameYUV->linesize[0];
                bmp->pitches[2]=pFrameYUV->linesize[1];
                bmp->pitches[1]=pFrameYUV->linesize[2];
                SDL_UnlockYUVOverlay(bmp);
                SDL_DisplayYUVOverlay(bmp,rect);
            }
        }
        av_free_packet(pPacket);
    }

    sws_freeContext(img_convert_ctx);
    SDL_Quit();
    av_free(buffer);
    av_free(pFrameYUV);
    av_free(pFrame);
    avcodec_close(pCodecCtx);
    avformat_close_input(&pFormatCtx);

    return 0;
}

遇到的问题:

上述配置完成后,即可播放视频。但可能会出现如下现象:程序可以直接执行,但在程序中设置断点调试时,会出现如下问题:
这里写图片描述
解决方法:
将avcodec-56.dll、avdevice-56.dll、avfilter-5.dll、avformat-56.dll、avutil-54.dll、postproc-53.dll、SDL.dll、swresample-1.dll、swscale-3.dll拷贝到Debug目录下,如下图所示:
这里写图片描述
这样即可解决上述问题。

参考资料:

http://ffmpeg.zeranoe.com/builds/网站上
1.下载Dev版本,里面包含了ffmpeg的xxx.h头文件以及xxx.lib库文件。
2.下载Shared版本,里面包含了ffmpeg的dll文件。
注:可能会出现问题,参见:FFMPEG 库移植到 VC 需要的步骤
http://blog.csdn.net/leixiaohua1020/article/details/12747899

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值