2.把Dev庫裏解壓出來的東西拷貝到工程中,Shared庫中解壓出來的東西拷貝到生成的bin文件目錄(如release)express
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++」——>「附加包含目錄」——>加入咱們添加進來的頭文件的路徑ide
4.在源碼中連接lib文件post
#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")
源碼以下:visual-studio
//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; }