開源的 H.264/AVC 視頻編碼器庫-x264 的交叉編譯 和 程序測試

一、環境準備

  1. 安裝交叉編譯工具鏈
    根據目標ARM架構選擇對應工具鏈(如arm-linux-gnueabihf-):
    # Ubuntu/Debian系統
    sudo apt-get install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf# 驗證安裝
    arm-linux-gnueabihf-gcc --version
    

或者手動指定交叉工具鏈

export PATH=$PATH:/home/user/Desktop/output/host/bin

在這里插入圖片描述

  1. 創建工作目錄
    mkdir x264 && cd x264
    

二、下載x264源碼

cd x264
git clone https://code.videolan.org/videolan/x264.git

在這里插入圖片描述

三、配置編譯參數

通過./configure指定交叉編譯參數:

# 禁止生成共享動態庫
./configure --cross-prefix=arm-linux-  --host=arm-linux --enable-static --disable-shared --disable-asm --prefix=$(pwd)/output

在這里插入圖片描述

./configure \--cross-prefix=arm-linux-gnueabihf- \--host=arm-linux \--enable-static \--disable-shared \--disable-asm \--prefix=$(pwd)/output
# 允許生成共享動態庫
./configure \--cross-prefix=arm-linux-gnueabihf- \--host=arm-linux \--enable-static \--enable-shared \--disable-asm \--prefix=$(pwd)/output

參數說明

  • --cross-prefix:交叉編譯器前綴
  • --host:目標平臺
  • --disable-asm:禁用ARM匯編優化(部分架構可能不兼容)
  • --prefix:指定安裝路徑

四、編譯與安裝

make -j$(nproc)  # 并行編譯

在這里插入圖片描述

make install      # 安裝到output目錄

在這里插入圖片描述

五、驗證編譯結果

編譯成功后,在output目錄下生成:

  • bin/x264:可執行文件
  • lib/libx264.a:靜態庫
  • include/x264.h:頭文件

在這里插入圖片描述

六、編寫測試程序

在這里插入圖片描述

使用 x264 API 將 YUV 視頻幀編碼為 H.264 數據流。
創建test_x264.c測試代碼:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <x264.h>#define WIDTH  320//640
#define HEIGHT 240//480
#define FPS    30
#define TOTAL_FRAMES 10//100  // 編碼幀數int main() {// 1. 初始化參數結構體x264_param_t param;if (x264_param_default_preset(&param, "medium", NULL) < 0) {fprintf(stderr, "Failed to apply preset\n");return -1;}// 2. 設置編碼參數param.i_width = WIDTH;param.i_height = HEIGHT;param.i_fps_num = FPS;param.i_fps_den = 1;param.i_keyint_max = FPS * 2;  // 關鍵幀間隔(2秒)param.b_vfr_input = 0;param.b_repeat_headers = 1;    // 在每個關鍵幀前添加SPS/PPSparam.b_annexb = 1;            // 輸出annex-b格式// 3. 應用配置if (x264_param_apply_profile(&param, "high") < 0) {fprintf(stderr, "Failed to apply profile\n");return -1;}// 4. 打開編碼器x264_t *encoder = x264_encoder_open(&param);if (!encoder) {fprintf(stderr, "Failed to open encoder\n");return -1;}// 5. 創建輸入圖像x264_picture_t pic_in, pic_out;x264_picture_alloc(&pic_in, param.i_csp, param.i_width, param.i_height);x264_picture_init(&pic_out);// 6. 準備輸出文件FILE *outfile = fopen("test.264", "wb");if (!outfile) {perror("Failed to open output file");return -1;}printf("Start encoding %dx%d video at %d fps...\n", WIDTH, HEIGHT, FPS);// 7. 編碼循環for (int i = 0; i < TOTAL_FRAMES; i++) {// 生成測試圖像(漸變彩條)uint8_t *y = pic_in.img.plane[0];uint8_t *u = pic_in.img.plane[1];uint8_t *v = pic_in.img.plane[2];// Y分量(亮度)for (int h = 0; h < HEIGHT; h++) {for (int w = 0; w < WIDTH; w++) {y[h * pic_in.img.i_stride[0] + w] = w * 255 / WIDTH;}}// UV分量(色度)for (int h = 0; h < HEIGHT/2; h++) {for (int w = 0; w < WIDTH/2; w++) {u[h * pic_in.img.i_stride[1] + w] = 128 + (h * 128 / (HEIGHT/2));v[h * pic_in.img.i_stride[2] + w] = 128 + (w * 128 / (WIDTH/2));}}pic_in.i_pts = i;  // 設置時間戳// 執行編碼x264_nal_t *nals;int i_nal;int frame_size = x264_encoder_encode(encoder, &nals, &i_nal, &pic_in, &pic_out);if (frame_size < 0) {fprintf(stderr, "Encoding error at frame %d\n", i);break;}// 8. 寫入輸出文件for (int j = 0; j < i_nal; j++) {fwrite(nals[j].p_payload, 1, nals[j].i_payload, outfile);}if (frame_size > 0) {printf("Frame %4d: size=%6d bytes, type=%s, qp=%d\n", i, frame_size,(pic_out.i_type == X264_TYPE_IDR) ? "IDR" :(pic_out.i_type == X264_TYPE_I) ? "I" :(pic_out.i_type == X264_TYPE_P) ? "P" : "B",pic_out.i_qpplus1 - 1);}}// 9. 刷新編碼器(處理延遲幀)while (1) {x264_nal_t *nals;int i_nal;int frame_size = x264_encoder_encode(encoder, &nals, &i_nal, NULL, &pic_out);if (frame_size <= 0) break;for (int j = 0; j < i_nal; j++) {fwrite(nals[j].p_payload, 1, nals[j].i_payload, outfile);}printf("Flush frame: size=%d bytes\n", frame_size);}// 10. 清理資源x264_encoder_close(encoder);x264_picture_clean(&pic_in);fclose(outfile);printf("\nEncoding completed. Output saved to test.264\n");printf("You can verify with:\n");printf("  ffplay test.264\n");printf("  ffprobe test.264\n");return 0;
}
  1. 參數配置

    • x264_param_default_preset():應用預設配置(medium/fast/placebo等)
    • x264_param_apply_profile():設置編碼規格(baseline/main/high)
  2. 圖像處理

    • x264_picture_alloc():分配YUV420P圖像內存
    • 手動生成漸變彩條測試圖案(實際應用應從文件/攝像頭獲取)
  3. 編碼核心

    • x264_encoder_encode():執行幀編碼
    • 輸出NAL單元包含:SPS/PPS/IDR幀/P幀等
  4. 輸出處理

    • 寫入annex-b格式的原始H.264流
    • 最后刷新編碼器獲取延遲幀

其它功能

  1. 從文件讀取YUV
FILE *yuv_file = fopen("input.yuv", "rb");
fread(pic_in.img.plane[0], 1, WIDTH*HEIGHT, yuv_file);        // Y
fread(pic_in.img.plane[1], 1, WIDTH*HEIGHT/4, yuv_file);     // U
fread(pic_in.img.plane[2], 1, WIDTH*HEIGHT/4, yuv_file);     // V
  1. 調整編碼參數
// 提高編碼質量
param.rc.i_rc_method = X264_RC_CRF;
param.rc.f_rf_constant = 22.0;  // 0-51, 值越小質量越好// 啟用B幀
param.i_bframe = 3;// 開啟心理視覺優化
param.analyse.b_psy = 1;
  1. 實時編碼統計
x264_stats_t stats;
param.b_stats = 1;
x264_encoder_encode(encoder, &nals, &i_nal, &pic_in, &pic_out);
x264_encoder_get_stats(encoder, &stats, 0);
printf("PSNR: Y=%.2f dB, U=%.2f dB, V=%.2f dB\n", stats.f_psnr_avg[0], stats.f_psnr_avg[1], stats.f_psnr_avg[2]);

七、交叉編譯測試程序

arm-linux-gnueabihf-gcc test_x264.c -o test_x264 \-I$(pwd)/output/include \-L$(pwd)/output/lib \-lx264 -lpthread -lm

在這里插入圖片描述
在這里插入圖片描述

八、部署與測試

  1. 復制文件到ARM設備
    scp test_x264 root@192.168.1.100:/tmp/  # 替換為實際IP
    scp output/lib/libx264.so.* root@192.168.1.100:/lib/
    

將輸出的/lib目錄下的庫文件拷貝到開發板的/lib/目錄下
將輸出的/bin目錄下的可執行文件拷貝到開發板的/bin/目錄下
文件需要賦權限
在這里插入圖片描述
測試指令
在這里插入圖片描述

  1. 在ARM設備上運行

    # 設置庫路徑
    export LD_LIBRARY_PATH=/lib:$LD_LIBRARY_PATH# 執行測試
    /tmp/test_x264
    
  2. 輸出

在這里插入圖片描述
在這里插入圖片描述

# 使用FFmpeg播放生成的視頻
ffplay test.264

在這里插入圖片描述


# 查看視頻信息
ffprobe test.264

在這里插入圖片描述

# 檢查編碼統計
ffmpeg -i test.264 -f null -

在這里插入圖片描述

常見問題及解決方案

  1. 編譯報錯:undefined reference to 'sqrt'
    解決:在鏈接命令中添加-lm(數學庫)。

  2. 運行報錯:libx264.so.x: cannot open shared object file
    解決:確保庫文件已復制到ARM設備的/lib目錄,并執行ldconfig刷新緩存。

  3. 性能優化

    • 若ARM設備支持NEON指令集,可啟用匯編優化:

      ./configure --enable-neon  # 根據架構選擇--enable-*選項
      
      ./configure --enable-shared --prefix=/home/ubuntu/x264_install/ --host=arm-linux-gnueabihf --disable-asm--prefix=/home/ubuntu//x264_install/ :指定編譯后存放路徑--host=arm-linux-gnueabihf :指定交叉編譯鏈,用戶需要修改為自己的交叉編譯器--enable-shared :允許共享--disable-asm:跳過匯編
      

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/89130.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/89130.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/89130.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

自由學習記錄(69)

RectToPolar() 是 將直角坐標系 (笛卡爾坐標系) 的 uv 坐標&#xff0c;轉化為極坐標系&#xff08;θ&#xff0c;r&#xff09; uv - centerUV&#xff1a;將坐標原點平移&#xff0c;使 (0.5, 0.5) 變成原點。 r length(uv)&#xff1a;距離中心點的半徑&#xff08;從中…

Spring Boot 敏感信息入庫加密全面解決方案

Spring Boot 敏感信息入庫加密全面解決方案 在當今數據驅動的時代,保護用戶隱私數據已成為系統設計的必備要求。本文將詳細介紹 Spring Boot 應用中敏感數據加密存儲的完整方案,涵蓋從基礎實現到生產級落地的全流程。 一、加密方案選型 1.1 常見加密類型對比 加密類型特點…

docker0網卡沒有ip一步解決

正常查看ip的時候一直顯示沒有ip這里先刪除docker0網卡ip link delete docker0然后重啟服務systemctl restart docker再次查看顯示有ip了并且查看配置文件也是正常的cat /etc/docker/daemon.json {"registry-mirrors": ["https://docker.m.daocloud.io",&q…

MYSQL-索引篇

索引結構概述MySQL 的索引是在存儲引擎層實現的&#xff0c;不同的存儲引擎有不同的索引結構&#xff0c;主要包含以下幾種&#xff1a;索引結構描述BTree索引最常見的索引類型&#xff0c;大部分引擎都支持 B 樹索引Hash索引底層數據結構是用哈希表實現的&#xff0c;只有精確…

(純新手教程)HTML零基礎教學

&#xff08;下一章&#xff1a;python網絡爬蟲&#xff09;HTML 簡介HTML&#xff08;HyperText Markup Language&#xff0c;超文本標記語言&#xff09;是用于創建網頁的標準標記語言。什么是 HTML&#xff1f;HTML 不是編程語言&#xff0c;而是一種標記語言使用標簽來描述…

前端面試寶典---項目難點2-智能問答對話框采用虛擬列表動態渲染可視區域元素(10萬+條數據)

引言 在我參與智能問答項目中一個智能體回話并不會像豆包一樣&#xff0c;每次新建會話都是是從頭開始&#xff0c;而項目中你想創建新會話就像chatbox一樣&#xff0c;是點擊橡皮擦開啟新的聊天上下文&#xff0c;但是直接的聊天記錄依然存在&#xff0c;針對超過十萬&#xf…

Python元組:不可變數據的強大用法

文章目錄元組概念1.基本特性2.創建元組3.訪問元素4.元組的不可變性5.元組操作6.元組解包7.命名元組8.元組與列表的比較9.元組的優勢10.適用場景11.常用方法小結元組 概念 元組是 Python 中一個非常重要的內置數據結構&#xff0c;它與列表(list)相似但具有關鍵差異。下面我將…

若爾蓋濕地的花湖

花湖位于若爾蓋縣和甘肅的郎木寺之間的213國道旁&#xff0c;屬于若爾蓋濕地國家級自然保護區內。又名“梅朵湖”&#xff0c;因陽光照射下湖面色彩斑斕如絢麗的花瓣得名。花湖的大門是梯形高大石柱搭成&#xff0c;我們需要過天橋到對面檢票坐小交通。通過車窗看到一層一層的云…

50天50個小項目 (Vue3 + Tailwindcss V4) ? | DoubleClickHeart(雙擊愛心)

&#x1f4c5; 我們繼續 50 個小項目挑戰&#xff01;—— DoubleClickHeart組件 倉庫地址&#xff1a;https://github.com/SunACong/50-vue-projects 項目預覽地址&#xff1a;https://50-vue-projects.vercel.app/ 使用 Vue 3 的 Composition API&#xff08;<script se…

1-緒論-1-數據結構的基本概念

&#x1f389; 數據結構的魔法世界&#x1f4da;&#x1f468;?&#x1f393;“數據就像大海中的浪花&#xff0c;結構則是那神秘的洋流。掌握數據結構&#xff0c;就是掌握在信息海洋中自由航行的力量&#xff01;”引言&#xff1a;為什么要學數據結構&#xff1f;&#x1f…

linux網絡相關命令簡介

目錄 一、IP命令 1、Link或L:管理網絡接口(網卡) 2、Address或Addr,A:管理Ip地址 3、Route或R:管理路由表

教育培訓機構如何為課程視頻添加防盜錄的強水印?

在知識付費時代&#xff0c;教育培訓機構的課程視頻是核心資產&#xff0c;但盜錄、非法傳播等問題卻讓機構防不勝防。如何在不影響學員觀看體驗的前提下&#xff0c;為課程視頻添加“強效防盜水印”&#xff0c;精準追蹤泄露源頭&#xff1f;本文將為您揭秘高安全性水印的添加…

python的形成性考核管理系統

前端開發框架:vue.js 數據庫 mysql 版本不限 后端語言框架支持&#xff1a; 1 java(SSM/springboot)-idea/eclipse 2.NodejsVue.js -vscode 3.python(flask/django)–pycharm/vscode 4.php(thinkphp/laravel)-hbuilderx 數據庫工具&#xff1a;Navicat/SQLyog等都可以 摘要 隨著…

A*算法詳解

A*算法詳解一、A*算法基礎概念1.1 算法定位1.2 核心評估函數1.3 關鍵數據結構二、A*算法的核心步驟三、啟發函數設計3.1 網格地圖中的啟發函數3.2 啟發函數的選擇原則三、Java代碼實現四、啟發函數的設計與優化4.1 啟發函數的可采納性4.2 啟發函數的效率影響4.3 常見啟發函數對…

.net winfrom 獲取上傳的Excel文件 單元格的背景色

需求&#xff1a;根據Excel某行標注了黃色高亮顏色&#xff0c;說明該行數據已被用戶選中(Excel文件中并沒有“已選中”這一列&#xff0c;純粹用顏色表示)&#xff0c;導入數據到數據庫時標注此行已選中直接上代碼&#xff1a;//選擇Excel文件private void btnBrowse_Click(ob…

OpenAI GPT-4o技術詳解:全能多模態模型的架構革新與生態影響

本文由「大千AI助手」原創發布&#xff0c;專注用真話講AI&#xff0c;回歸技術本質。拒絕神話或妖魔化。搜索「大千AI助手」關注我&#xff0c;一起撕掉過度包裝&#xff0c;學習真實的AI技術&#xff01; ?? 一、核心定義與發布背景 官方定位 GPT-4o&#xff08;“o”代表“…

? 構建真正的高性能即時通訊服務:基于 Netty 集群的架構設計與實現

引子 在前面的文章中&#xff0c;我們基于 Netty 構建了一套單體架構的即時通訊服務。雖然單體架構在開發初期簡單高效&#xff0c;但隨著用戶量的增長和業務規模的擴大&#xff0c;其局限性逐漸顯現。當面對高并發場景時&#xff0c;單體 Netty 服務很容易觸及性能天花板&…

原來時間序列挖掘這么簡單

先搞懂&#xff1a;啥是時間序列&#xff1f;簡單說&#xff0c;時間序列就是按時間順序記下來的數據。比如&#xff1a;你每天早上 8 點測的體重&#xff0c;連起來就是 “體重時間序列”&#xff1b;超市每天的銷售額&#xff0c;連起來就是 “銷售時間序列”&#xff1b;城市…

基于Python的豆瓣圖書數據分析與可視化系統【自動采集、海量數據集、多維度分析、機器學習】

文章目錄有需要本項目的代碼或文檔以及全部資源&#xff0c;或者部署調試可以私信博主項目介紹每文一語有需要本項目的代碼或文檔以及全部資源&#xff0c;或者部署調試可以私信博主 項目介紹 豆瓣圖書數據智能分析系統是一個集數據采集、清洗、分析與可視化于一體的綜合性項…

2.3 數組與字符串

學習目標&#xff1a; 理解數組和字符串的概念&#xff08;存儲多個數據的“盒子”&#xff09;。掌握數組的聲明、初始化和遍歷方法。能用字符串處理簡單文本問題&#xff08;如字符計數、回文判斷&#xff09;。1 一維數組 基本概念 比喻&#xff1a; 數組就像“儲物柜”&…