Windows下搭建ffmpeg+VS2008开发环境详细教程

由于个人是从事音视频开发相关的工作,所以也把自己的一些过程写下来,方便大家以及自己查看,时间关系就不多瞎说了,具体过程,都是图文教程
在搭建开发环境之前,首先需要下载ffmpeg源码 (dev版本+share版本)
提醒下 ffmpeg 源码应该是 32bit, 因为当前新建工程也是32位
Windows下搭建ffmpeg+VS2008开发环境详细教程 - 阿浪 - 温先良--桂林理工大学
 
Windows下搭建ffmpeg+VS2008开发环境详细教程 - 阿浪 - 温先良--桂林理工大学
 
Windows下搭建ffmpeg+VS2008开发环境详细教程 - 阿浪 - 温先良--桂林理工大学
 
Windows下搭建ffmpeg+VS2008开发环境详细教程 - 阿浪 - 温先良--桂林理工大学
 
Windows下搭建ffmpeg+VS2008开发环境详细教程 - 阿浪 - 温先良--桂林理工大学
 
注意头文件的引用

Windows下搭建ffmpeg+VS2008开发环境详细教程 - 阿浪 - 温先良--桂林理工大学
 

main函数代码如下:
int main (int argc, char **argv)
{
    AVFormatContext *fmt_ctx = NULL;
    AVDictionaryEntry *tag = NULL;
    int ret;
av_register_all();
    if ((ret = avformat_open_input(&fmt_ctx, "love.mp4", NULL, NULL)))
        return ret;
    while ((tag = av_dict_get(fmt_ctx->metadata, "", tag, AV_DICT_IGNORE_SUFFIX)))
{
printf("%s=%s\n", tag->key, tag->value);
}
//运行结果为打印音视频媒体文件基本信息
    avformat_close_input(&fmt_ctx);
    return 0;
}

运行结果截图:
Windows下搭建ffmpeg+VS2008开发环境详细教程 - 阿浪 - 温先良--桂林理工大学
 

提醒:VS2008安装目录: E:\software_setup\VS2008\VC\include  需要添加两个头文件 stdint.h 和 inttypes.h


遇到问题:

1.编译失败,

Error 1 error LNK2019: unresolved external symbol _av_register_all referenced in function _wmain C:\Users\Andres\Documents\Visual Studio 2013\Projects\PruebaFFMPEG\PruebaFFMPEG\PruebaFFMPEG.obj PruebaFFMPEG

除了要查明c++引用C文件的文件名有变化失败,还要检查

0 down vote accepted

 

It seems that you are trying to link a 32-bit application with 64-bit libraries. Download 32-bit libraries from http://ffmpeg.zeranoe.com/builds/ or create x64 configuration for your solution

Open Project properties -> click Configuration Manager... -> Active Solution Platform -> New.. -> Select x64 (see screenshot goo.gl/54ND5t) –  pogorskiy

2.缺少的头文件

Ffmpeg使用的是C99,但是vs2008不支持c99VS2008编译ffmpeg时会用到的两个C99标准的头文件。,所以需要你自己下载。并放至相应目录。对于VS2010来说通常是:C:\ProgramFiles (x86)\Microsoft Visual Studio10.0\VC\include。下载地址:http://download.csdn.net/detail/mfcai_blog/9540995

cpp文件里调用ffmpeg函数要注意.externC”是使C++能够调用C写的库文件的一种方式。如果在c++代码中要使用C库中的函数的话,那么就要使用externC”来说明。

一个用C写成的库如果想被C/C++同时可以使用,那在头文件应该加上

#ifdef__cplusplus

extern "C"{

#endif

#ifdef__cplusplus

} // endof extern"C"

#endif

3.

VS2008下配置SDL开发环境:

1.下载SDL-devel-1.2.15-VC.zip(在http://www.libsdl.org/download-1.2.php可见)

2.解压缩SDL-devel-1.2.13-VC8.zip,docs里面包含了官方文档,这将是你学习SDL的主要参考资料。找到你在硬盘上安装VC的位置,类似:C:\Program Files\Microsoft Visual Studio 9.0\VC,打开include文件夹,在里面建立一个新文件夹,取名为SDL,打开这个新的文件夹:C:\Program Files\Microsoft Visual Studio 9.0\VC\include\SDL,然后,将SDL Development Libraries中include文件夹里面的文件全部拷贝到刚才建立起来的那个新文件夹中。
  然后,回到VC的.\VC文件夹下,打开lib文件夹:C:\Program Files\Microsoft Visual Studio 9.0\VC\lib,将SDL Development Libraries中lib文件夹下的SDL.lib和SDLmain.lib两个文件拷贝到刚才的那个VC的lib文件夹下

(注意库可以这么取,但是位置不要这么放,要像上面放置ffmpeg库那样去配置)

4.代码示例

#include <stdafx.h>
#include <stdio.h>  
 
#define __STDC_CONSTANT_MACROS


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

#include "SDL_include/SDL.h"  

//Refresh Event  
#define SFM_REFRESH_EVENT  (SDL_USEREVENT + 1)  
 
#define SFM_BREAK_EVENT  (SDL_USEREVENT + 2)  
 
int thread_exit=0;  
int thread_pause=0;  
 
int sfp_refresh_thread(void *opaque){  
    thread_exit=0;  
    thread_pause=0;  
 
    while (!thread_exit) {  
        if(!thread_pause){  
            SDL_Event event;  
            event.type = SFM_REFRESH_EVENT;  
            SDL_PushEvent(&event);  
        }  
        SDL_Delay(40);  
    }  
    thread_exit=0;  
    thread_pause=0;  
    //Break  
    SDL_Event event;  
    event.type = SFM_BREAK_EVENT;  
    SDL_PushEvent(&event);  
 
    return 0;  
}  
 
 
int main(int argc, char* argv[])  
{  
 
    AVFormatContext *pFormatCtx;  
    int             i, videoindex;  
    AVCodecContext  *pCodecCtx;  
    AVCodec         *pCodec;  
    AVFrame *pFrame,*pFrameYUV;  
    unsigned char *out_buffer;  
    AVPacket *packet;  
    int ret, got_picture;  
 
    //------------SDL----------------  
    int screen_w,screen_h;  
    SDL_Window *screen;   
    SDL_Renderer* sdlRenderer;  
    SDL_Texture* sdlTexture;  
    SDL_Rect sdlRect;  
    SDL_Thread *video_tid;  
    SDL_Event event;  
 
    struct SwsContext *img_convert_ctx;  
 
    //char filepath[]="bigbuckbunny_480x272.h265";  
    char filepath[]="bigbuckbunny_480x272.h264";  
 
    av_register_all();  
    avformat_network_init();  
    pFormatCtx = avformat_alloc_context();  
 
    if(avformat_open_input(&pFormatCtx,filepath,NULL,NULL)!=0){  
        printf("Couldn't open input stream.\n");  
        return -1;  
    }  
    if(avformat_find_stream_info(pFormatCtx,NULL)<0){  
        printf("Couldn't find stream information.\n");  
        return -1;  
    }  
    videoindex=-1;  
    for(i=0; i<pFormatCtx->nb_streams; i++)   
        if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO){  
            videoindex=i;  
            break;  
        }  
    if(videoindex==-1){  
        printf("Didn't find a video stream.\n");  
        return -1;  
    }  
    pCodecCtx=pFormatCtx->streams[videoindex]->codec;  
    pCodec=avcodec_find_decoder(pCodecCtx->codec_id);  
    if(pCodec==NULL){  
        printf("Codec not found.\n");  
        return -1;  
    }  
    if(avcodec_open2(pCodecCtx, pCodec,NULL)<0){  
        printf("Could not open codec.\n");  
        return -1;  
    }  
    pFrame=av_frame_alloc();  
    pFrameYUV=av_frame_alloc();  
 
    out_buffer=(unsigned char *)av_malloc(av_image_get_buffer_size(AV_PIX_FMT_YUV420P,  pCodecCtx->width, pCodecCtx->height,1));  
    av_image_fill_arrays(pFrameYUV->data, pFrameYUV->linesize,out_buffer,  
        AV_PIX_FMT_YUV420P,pCodecCtx->width, pCodecCtx->height,1);  
 
    //Output Info-----------------------------  
    printf("---------------- File Information ---------------\n");  
    av_dump_format(pFormatCtx,0,filepath,0);  
    printf("-------------------------------------------------\n");  
      
    img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt,   
        pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);   
      
 
    if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {    
        printf( "Could not initialize SDL - %s\n", SDL_GetError());   
        return -1;  
    }   
    //SDL 2.0 Support for multiple windows  
    screen_w = pCodecCtx->width;  
    screen_h = pCodecCtx->height;  
    screen = SDL_CreateWindow("Simplest ffmpeg player's Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,  
        screen_w, screen_h,SDL_WINDOW_OPENGL);  
 
    if(!screen) {    
        printf("SDL: could not create window - exiting:%s\n",SDL_GetError());    
        return -1;  
    }  
    sdlRenderer = SDL_CreateRenderer(screen, -1, 0);    
    //IYUV: Y + U + V  (3 planes)  
    //YV12: Y + V + U  (3 planes)  
    sdlTexture = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING,pCodecCtx->width,pCodecCtx->height);    
 
    sdlRect.x=0;  
    sdlRect.y=0;  
    sdlRect.w=screen_w;  
    sdlRect.h=screen_h;  
 
    packet=(AVPacket *)av_malloc(sizeof(AVPacket));  
 
    video_tid = SDL_CreateThread(sfp_refresh_thread,NULL,NULL);  
    //------------SDL End------------  
    //Event Loop  
      
    for (;;) {  
        //Wait  
        SDL_WaitEvent(&event);  
        if(event.type==SFM_REFRESH_EVENT){  
            while(1){  
                if(av_read_frame(pFormatCtx, packet)<0)  
                    thread_exit=1;  
 
                if(packet->stream_index==videoindex)  
                    break;  
            }  
            ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);  
            if(ret < 0){  
                printf("Decode Error.\n");  
                return -1;  
            }  
            if(got_picture){  
                sws_scale(img_convert_ctx, (const unsigned char* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize);  
                //SDL---------------------------  
                SDL_UpdateTexture( sdlTexture, NULL, pFrameYUV->data[0], pFrameYUV->linesize[0] );    
                SDL_RenderClear( sdlRenderer );    
                //SDL_RenderCopy( sdlRenderer, sdlTexture, &sdlRect, &sdlRect );    
                SDL_RenderCopy( sdlRenderer, sdlTexture, NULL, NULL);    
                SDL_RenderPresent( sdlRenderer );    
                //SDL End-----------------------  
            }  
            av_free_packet(packet);  
        }else if(event.type==SDL_KEYDOWN){  
            //Pause  
            if(event.key.keysym.sym==SDLK_SPACE)  
                thread_pause=!thread_pause;  
        }else if(event.type==SDL_QUIT){  
            thread_exit=1;  
        }else if(event.type==SFM_BREAK_EVENT){  
            break;  
        }  
 
    }  
 
    sws_freeContext(img_convert_ctx);  
 
    SDL_Quit();  
    //--------------  
    av_frame_free(&pFrameYUV);  
    av_frame_free(&pFrame);  
    avcodec_close(pCodecCtx);  
    avformat_close_input(&pFormatCtx);  
 
    return 0;  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值