Windows FFMPEG開發環境配置

來源:互聯網
上載者:User

標籤:dll   size   sample   輸入輸出   avd   空間   _id   erro   配置   

1.去FFMPEG網站上下載Dev版本的庫,裡面有我們需要的標頭檔和lib檔案,然後下載Shared版本的庫,裡面有我們需要的dll檔案http://ffmpeg.zeranoe.com/builds/記得區分32位和64位的庫,這裡碰到一個大坑,就是我下載的是64位的庫,但是建立工程的時候選的是32位的工程,導致連結的時候一直報無法解析的外部符號 _av_register_all。。。(這個因為以前在Linux上使用的都是自己編譯出來的庫,所以沒注意這個坑)
最後通過這個連結解決的https://stackoverflow.com/questions/20672777/linker-error-using-ffmpeg-with-visual-studio-2013-express 

2.把Dev庫裡解壓出來的東西拷貝到工程中,Shared庫中解壓出來的東西拷貝到產生的bin檔案目錄(如release)

G:\source\FFmpegDemo\FFmpegDemo\ffmpeg>├─inc│  ├─libavcodec│  ├─libavdevice│  ├─libavfilter│  ├─libavformat│  ├─libavutil│  ├─libpostproc│  ├─libswresample│  └─libswscale└─libs        avcodec.lib        avdevice.lib        avfilter.lib        avformat.lib        avutil.lib        postproc.lib        swresample.lib        swscale.lib

3.右擊工程“屬性”,“C/C++”——>“附加元件封裝含目錄”——>加入我們添加進來的標頭檔的路徑

4.在源碼中連結lib檔案

#pragma comment(lib,"ffmpeg\\libs\\avutil.lib")#pragma comment(lib,"ffmpeg\\libs\\avformat.lib")#pragma comment(lib,"ffmpeg\\libs\\avcodec.lib")#pragma comment(lib,"ffmpeg\\libs\\swscale.lib")

源碼如下:

//main.cpp#include <stdio.h>#include <stdlib.h>#pragma comment(lib,"ffmpeg\\libs\\avutil.lib")#pragma comment(lib,"ffmpeg\\libs\\avformat.lib")#pragma comment(lib,"ffmpeg\\libs\\avcodec.lib")#pragma comment(lib,"ffmpeg\\libs\\swscale.lib")extern "C" {//編碼#include "libavcodec/avcodec.h"//封裝格式處理#include "libavformat/avformat.h"//像素處理#include "libswscale/swscale.h"};int main(int argc, char* argv[]){    //擷取輸入輸出檔案名    const char *input = "test.mp4";    const char *output = "test.yuv";    //1.註冊所有組件    av_register_all();    //封裝格式上下文,統領全域的結構體,儲存了視頻檔案封裝格式的相關資訊    AVFormatContext *pFormatCtx = avformat_alloc_context();    //2.開啟輸入視頻檔案    if (avformat_open_input(&pFormatCtx, input, NULL, NULL) != 0)    {        printf("%s", "無法開啟輸入視頻檔案");        return -1;    }    //3.擷取視頻檔案資訊    if (avformat_find_stream_info(pFormatCtx, NULL) < 0)    {        printf("%s", "無法擷取視頻檔案資訊");        return -1;    }    //擷取視頻流的索引位置    //遍曆所有類型的流(音頻流、視頻流、字幕流),找到視頻流    int v_stream_idx = -1;    int i = 0;    //number of streams    for (; i < pFormatCtx->nb_streams; i++)    {        //流的類型        if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)        {            v_stream_idx = i;            break;        }    }    if (v_stream_idx == -1)    {        printf("%s", "找不到視頻流\n");        return -1;    }    //只有知道視頻的編碼方式,才能夠根據編碼方式去找到解碼器    //擷取視頻流中的編解碼上下文    AVCodecContext *pCodecCtx = pFormatCtx->streams[v_stream_idx]->codec;    //4.根據編解碼上下文中的編碼id尋找對應的解碼    AVCodec *pCodec = avcodec_find_decoder(pCodecCtx->codec_id);    if (pCodec == NULL)    {        printf("%s", "找不到解碼器\n");        return -1;    }    //5.開啟解碼器    if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0)    {        printf("%s", "解碼器無法開啟\n");        return -1;    }    //輸出視頻資訊    printf("視頻的檔案格式:%s", pFormatCtx->iformat->name);    printf("視頻時間長度:%d", (pFormatCtx->duration) / 1000000);    printf("視頻的寬高:%d,%d", pCodecCtx->width, pCodecCtx->height);    printf("解碼器的名稱:%s", pCodec->name);    //準備讀取    //AVPacket用於儲存一幀一幀的壓縮資料(H264)    //緩衝區,開闢空間    AVPacket *packet = (AVPacket*)av_malloc(sizeof(AVPacket));    //AVFrame用於儲存解碼後的像素資料(YUV)    //記憶體配置    AVFrame *pFrame = av_frame_alloc();    //YUV420    AVFrame *pFrameYUV = av_frame_alloc();    //只有指定了AVFrame的像素格式、畫面大小才能真正分配記憶體    //緩衝區分配記憶體    uint8_t *out_buffer = (uint8_t *)av_malloc(avpicture_get_size(AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height));    //初始化緩衝區    avpicture_fill((AVPicture *)pFrameYUV, out_buffer, AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);    //用於轉碼(縮放)的參數,轉之前的寬高,轉之後的寬高,格式等    struct SwsContext *sws_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt,        pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_YUV420P,        SWS_BICUBIC, NULL, NULL, NULL);    int got_picture, ret;    FILE *fp_yuv = fopen(output, "wb+");    int frame_count = 0;    //6.一幀一幀的讀取壓縮資料    while (av_read_frame(pFormatCtx, packet) >= 0)    {        //只要視頻壓縮資料(根據流的索引位置判斷)        if (packet->stream_index == v_stream_idx)        {            //7.解碼一幀視頻壓縮資料,得到視頻像素資料            ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);            if (ret < 0)            {                printf("%s", "解碼錯誤");                return -1;            }            //為0說明解碼完成,非0正在解碼            if (got_picture)            {                //AVFrame轉為像素格式YUV420,寬高                //2 6輸入、輸出資料                //3 7輸入、輸出畫面一行的資料的大小 AVFrame 轉換是一行一行轉換的                //4 輸入資料第一列要轉碼的位置 從0開始                //5 輸入畫面的高度                sws_scale(sws_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height,                    pFrameYUV->data, pFrameYUV->linesize);                //輸出到YUV檔案                //AVFrame像素幀寫入檔案                //data解碼後的映像像素資料(音頻採樣資料)                //Y 亮度 UV 色度(壓縮了) 人對亮度更加敏感                //U V 個數是Y的1/4                int y_size = pCodecCtx->width * pCodecCtx->height;                fwrite(pFrameYUV->data[0], 1, y_size, fp_yuv);                fwrite(pFrameYUV->data[1], 1, y_size / 4, fp_yuv);                fwrite(pFrameYUV->data[2], 1, y_size / 4, fp_yuv);                frame_count++;                printf("解碼第%d幀\n", frame_count);            }        }        //釋放資源        av_free_packet(packet);    }    fclose(fp_yuv);    av_frame_free(&pFrame);    avcodec_close(pCodecCtx);    avformat_free_context(pFormatCtx);    return 0;}

 

Windows 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.