windows 10 vs2017 x264的編譯和使用測試
阿新 • • 發佈:2019-02-15
x264這個sdk非常棒!
x264原始碼:
./configure --enable-shared --disable-asm
make
找到pexports原始檔
./configure
make
編譯出來的pexports.exe是i686平臺的。
拷貝pexports.exe放到
D:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.15.26726\bin\Hostx64\x86
開啟vs2017開始中的 “VS 2017的x64_x86交叉工具命令提示符
把libx264-157.dll拷貝到一個獨立的資料夾,然後執行:
pexports ./libx264-157.dll > libx264-157.def
再執行:
lib /def:libx264-157.def /machine:x86 /out:libx264-157.lib
把x264的include資料夾拷貝到安裝的位置,把其他的libx264-157.dll和libx264-157.lib放到 bin目錄和lib目錄中。
然後就可以在vs2017的vc專案的x86的release中使用了。
測試環境,下面這個經典的例子已經包含了編碼器的主要使用流程,只是引數設定上略顯單調,引數的使用需要慢慢掌握。
新建VC 2017的控制檯程式,設定為x86專案,配置屬性中的 包含目錄 和 庫目錄 以及 連結輸入libx264-157.lib:
#include <cassert> #include <iostream> #include <string> #include "stdint.h" extern "C" { #include "x264.h" }; unsigned int g_uiPTSFactor = 0; int iNal = 0; x264_nal_t* pNals = NULL; int encode(x264_t* p264, x264_picture_t* pIn, x264_picture_t* pOut); int main(int argc, char** argv) { int iResult = 0; x264_t* pX264Handle = NULL; x264_param_t* pX264Param = new x264_param_t; assert(pX264Param); //* 配置為預設引數 x264_param_default(pX264Param); //* cpuFlags pX264Param->i_threads = X264_SYNC_LOOKAHEAD_AUTO; //* video Properties pX264Param->i_width = 320; //* width pX264Param->i_height = 240; //* height pX264Param->i_frame_total = 0; //* 視訊總幀數,0表示任意 pX264Param->i_keyint_max = 10; //* bitstream parameters pX264Param->i_bframe = 5; pX264Param->b_open_gop = 0; pX264Param->i_bframe_pyramid = 0; pX264Param->i_bframe_adaptive = X264_B_ADAPT_TRELLIS; //* 位元流引數 //pX264Param->vui.i_sar_width = 1080; //pX264Param->vui.i_sar_height = 720; //* Log引數 pX264Param->i_log_level = X264_LOG_DEBUG; //* Rate control Parameters pX264Param->rc.i_bitrate = 1024 * 10;//* 位元速率(Kbps) //* muxing parameters pX264Param->i_fps_den = 1; //* 幀率分母 pX264Param->i_fps_num = 25;//* 幀率分子 pX264Param->i_timebase_den = pX264Param->i_fps_num; pX264Param->i_timebase_num = pX264Param->i_fps_den; //* 設定編碼等級profile : baseline、main、height ( 直播baseline:流暢 、Main:有停頓現象 、本地FLV檔案:main) x264_param_apply_profile(pX264Param, x264_profile_names[1]); //* 建立264編碼器。後面可以使用x264_encoder_parameters來編碼器引數,可以使用x264_encoder_reconfig更新設定引數 pX264Handle = x264_encoder_open(pX264Param); assert(pX264Handle); //* 獲取流的PPS和SPS iResult = x264_encoder_headers(pX264Handle, &pNals, &iNal); assert(iResult >= 0); //* PPS SPS 解析 for (int i = 0; i < iNal; ++i) { switch (pNals[i].i_type) { case NAL_SPS: break; case NAL_PPS: break; default: break; } } //* 編碼器快取的最大幀數 int iMaxFrames = x264_encoder_maximum_delayed_frames(pX264Handle); //* 編碼需要的臨時變數 iNal = 0; pNals = NULL; x264_picture_t* pPicIn = new x264_picture_t; x264_picture_t* pPicOut = new x264_picture_t; x264_picture_init(pPicOut); x264_picture_alloc(pPicIn, X264_CSP_I420, pX264Param->i_width, pX264Param->i_height); pPicIn->img.i_csp = X264_CSP_I420; pPicIn->img.i_plane = 3; //* 建立264本地視訊檔案 FILE* pFile; fopen_s(&pFile,"d:\\hellox264.264", "wb"); assert(pFile); //* 一幀中YUV420中Y的資料長度 int iDataLen = pX264Param->i_width * pX264Param->i_height; uint8_t* data = new uint8_t[iDataLen]; unsigned int uiComponent = 0; while (++uiComponent<1030) { //* 每一幀的資料構成YUV420 ::memset(data, uiComponent, iDataLen); ::memcpy(pPicIn->img.plane[0], data, iDataLen); ::memcpy(pPicIn->img.plane[1], data, iDataLen / 4); ::memcpy(pPicIn->img.plane[2], data, iDataLen / 4); if (uiComponent <= 1000) { pPicIn->i_pts = uiComponent + g_uiPTSFactor * 1000; encode(pX264Handle, pPicIn, pPicOut); } else { int iResult = encode(pX264Handle, NULL, pPicOut); if (0 == iResult) { //uiComponent = 0; ++g_uiPTSFactor; } } //* 編碼完成的多幀資料逐一寫入視訊檔案 for (int i = 0; i < iNal; ++i) { fwrite(pNals[i].p_payload, 1, pNals[i].i_payload, pFile); } } //* 釋放清除影象資料 x264_picture_clean(pPicIn); // x264_picture_clean(pPicOut); //* 利用控制代碼關閉解碼器 x264_encoder_close(pX264Handle); pX264Handle = NULL; delete pPicIn; pPicIn = NULL; delete pPicOut; pPicOut = NULL; delete pX264Param; pX264Param = NULL; delete[] data; data = NULL; return 0; } int encode(x264_t* pX264Handle, x264_picture_t* pPicIn, x264_picture_t* pPicOut) { int iResult = 0; iResult = x264_encoder_encode(pX264Handle, &pNals, &iNal, pPicIn, pPicOut); if (0 == iResult) { std::cout << "編碼成功,但是快取在編碼器中" << std::endl; } else if (iResult < 0) { std::cout << "編碼出錯" << std::endl; } else if (iResult > 0) { std::cout << "編碼成功,並需要寫入視訊檔案流" << std::endl; } int iFrames = x264_encoder_delayed_frames(pX264Handle); std::cout << "緩衝幀數:" << iFrames << "\n";//因為要進行編碼,所以編碼器需要快取很多幀才好生成I、P、B幀 return iFrames; }