在visual studio 2010中調用ffmpeg

來源:互聯網
上載者:User

標籤:

本文來自:http://blog.sina.com.cn/s/blog_4178f4bf01018wqh.html

  最近幾天一直在折騰ffmpeg,在網上也查了許多資料,費了不少勁,現在在這裡和大家分享一下。

一、準備工作    本來是想自己在windows下編譯ffmpeg產生lib、dll等庫檔案的,但是折騰好久總是出錯,於是果斷放棄。幸好網上已經有了編譯好的版本,可以拿過來直接用,網址為http://ffmpeg.zeranoe.com/builds/。我們需要的是32-bit Builds (Shared)和32-bit Builds (Dev),版本號碼要相對應。32-bit Builds (Shared)主要包含了所要用到的dll檔案,32-bit Builds (Dev)主要包含了所要用的標頭檔和lib檔案。其實這些lib並不是傳統的靜態庫檔案(真正的靜態庫檔案是在lib目錄下的*.a檔案),他們是dll的匯出檔案。dll檔案在32-bit Builds (Shared)的bin目錄下,lib檔案在32-bit Builds (Dev)的lib目錄下,標頭檔在32-bit Builds (Dev)的include目錄下。    另外,C99中添加了幾個新的標頭檔,Visual Studio中沒有,所以需要你自己下載。並放至相應目錄。對於VS2010來說通常是:C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include。二、Visual Studio配置    在準備好庫檔案之後,便可以進行Visual Studio簡單的編譯工作了,下面給出一份當前可以編譯啟動並執行代碼,並以此為樣本。// ffmpeg-example.cpp : Defines the entry point for the console application.////#include "stdafx.h" #define inline _inline#ifndef INT64_C#define INT64_C(c) (c ## LL)#define UINT64_C(c) (c ## ULL)#endif #ifdef __cplusplusextern "C" {#endif   #include <libavformat/avformat.h>#include <libavcodec/avcodec.h>#include <libswscale/swscale.h>#ifdef __cplusplus}#endif #include <stdio.h>  static void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame); int main (int argc, const char * argv[]){    AVFormatContext *pFormatCtx;    int             i, videoStream;    AVCodecContext  *pCodecCtx;    AVCodec         *pCodec;    AVFrame         *pFrame;     AVFrame         *pFrameRGB;    AVPacket        packet;    int             frameFinished;    int             numBytes;    uint8_t         *buffer;     // Register all formats and codecs    av_register_all();     // Open video file    //if(avformat_open_input(&pFormatCtx, argv[1], NULL, NULL)!=0)if(avformat_open_input(NULL, argv[1], NULL, NULL)!=0)        return -1; // Couldn‘t open file     // Retrieve stream information    if(av_find_stream_info(pFormatCtx)<0)        return -1; // Couldn‘t find stream information     // Dump information about file onto standard error    av_dump_format(pFormatCtx, 0, argv[1], false);     // Find the first video stream    videoStream=-1;    for(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; // Didn‘t find a video stream         // Get a pointer to the codec context for the video stream        pCodecCtx=pFormatCtx->streams[videoStream]->codec;         // Find the decoder for the video stream        pCodec=avcodec_find_decoder(pCodecCtx->codec_id);        if(pCodec==NULL)            return -1; // Codec not found         // Open codec        if(avcodec_open(pCodecCtx, pCodec)<0)            return -1; // Could not open codec         // Hack to correct wrong frame rates that seem to be generated by some codecs        if(pCodecCtx->time_base.num>1000 && pCodecCtx->time_base.den==1)            pCodecCtx->time_base.den=1000;         // Allocate video frame        pFrame=avcodec_alloc_frame();         // Allocate an AVFrame structure        pFrameRGB=avcodec_alloc_frame();        if(pFrameRGB==NULL)            return -1;         // Determine required buffer size and allocate buffer        numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width,            pCodecCtx->height);         //buffer=malloc(numBytes);        buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));         // Assign appropriate parts of buffer to image planes in pFrameRGB        avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,            pCodecCtx->width, pCodecCtx->height);         // Read frames and save first five frames to disk        i=0;        while(av_read_frame(pFormatCtx, &packet)>=0)        {            // Is this a packet from the video stream?            if(packet.stream_index==videoStream)            {                // Decode video frame                avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);                 // Did we get a video frame?                if(frameFinished)                {                    static struct SwsContext *img_convert_ctx; #if 0                    // Older removed code                    // Convert the image from its native format to RGB swscale                    img_convert((AVPicture *)pFrameRGB, PIX_FMT_RGB24,                         (AVPicture*)pFrame, pCodecCtx->pix_fmt, pCodecCtx->width,                         pCodecCtx->height);                     // function template, for reference                    int sws_scale(struct SwsContext *context, uint8_t* src[], int srcStride[], int srcSliceY,                        int srcSliceH, uint8_t* dst[], int dstStride[]);#endif                    // Convert the image into YUV format that SDL uses                    if(img_convert_ctx == NULL) {                        int w = pCodecCtx->width;                        int h = pCodecCtx->height;                         img_convert_ctx = sws_getContext(w, h,                             pCodecCtx->pix_fmt,                             w, h, PIX_FMT_RGB24, SWS_BICUBIC,                            NULL, NULL, NULL);                        if(img_convert_ctx == NULL) {                            fprintf(stderr, "Cannot initialize the conversion context!\n");                            exit(1);                        }                    }                    int ret = sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0,                         pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);#if 0                     // this use to be true, as of 1/2009, but apparently it is no longer true in 3/2009                    if(ret) {                        fprintf(stderr, "SWS_Scale failed [%d]!\n", ret);                        exit(-1);                    }#endif                    // Save the frame to disk                    if(i++<=5)                        SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height, i);                }            }             // Free the packet that was allocated by av_read_frame            av_free_packet(&packet);        }         // Free the RGB image        //free(buffer);        av_free(buffer);        av_free(pFrameRGB);         // Free the YUV frame        av_free(pFrame);         // Close the codec        avcodec_close(pCodecCtx);         // Close the video file        av_close_input_file(pFormatCtx);         return 0;} static void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame){    FILE *pFile;    char szFilename[32];    int  y;     // Open file    sprintf(szFilename, "frame%d.ppm", iFrame);    pFile=fopen(szFilename, "wb");    if(pFile==NULL)        return;     // Write header    fprintf(pFile, "P6\n%d %d\n255\n", width, height);     // Write pixel data    for(y=0; y<height; y++)        fwrite(pFrame->data[0]+y*pFrame->linesize[0], 1, width*3, pFile);     // Close file    fclose(pFile);}首先在Visual Studio中建立工程,並將代碼添加到工程的.cpp檔案中。其次,就要配置工程的庫檔案和連結器。1. 設定ffmpeg標頭檔位置滑鼠右鍵點擊工程名,選擇屬性


然後選擇 配置屬性 -> C/C++ -> 常規 -> 附加元件封裝含目錄,添加目錄為你下載的32-bit Builds (Dev)中的標頭檔目錄。

 2. 設定ffmpeg的lib檔案位置 滑鼠右鍵點擊工程名,選擇屬性, 然後選擇 配置屬性 -> 連結器 -> 常規 -> 附加庫目錄,添加目錄為你下載的32-bit Builds (Dev)中的lib檔案目錄。 

3. 設定ffmpeg的所引用的lib檔案 
滑鼠右鍵點擊工程名,選擇屬性, 然後選擇 配置屬性 -> 連結器 -> 輸入 -> 附加依賴項,添加的檔案為你下載的32-bit Builds (Dev)中的lib檔案。 

如果一切正常,這時你便可以編譯成功。
三、可能出現的問題1. 雖然編譯通過,但是並不表示就可以運行,當你運行代碼時會出現以下錯誤

原因是,你雖然引用了LIB檔案,但這並不是真正的靜態庫檔案,而是對DLL的引用,所以當你調用ffmpeg庫函數時,需要DLL檔案在場。你可以用dumpbin(VS內建工具)來查看你產生的exe中引用了哪些DLL檔案。你在命令列輸入:>dumpbin D:\test\test.exe /imports然後根據顯示的檔案名稱,將下載的32-bit Builds (Shared)的bin檔案夾下的dll檔案拷貝到你建立的工程的源檔案目錄下。

2. 上段代碼中的變數argv[1],如果你沒有指定參數,則會報錯。所以如果不指定,則需要將其改為一個const char *的字串變數,字串內容為你想讀入的視頻的全路徑,例如const char* filename = "D:\\work\\code\\VideoConference\\test\\IMGP1816.AVI"; 上述都配置完畢就可以運行了,暫時先寫這麼多吧,後面我會繼續總結的。

在visual studio 2010中調用ffmpeg

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.