ffmpeg庫視頻硬編碼使用流程

?一、硬件編碼核心流程?

  1. ?硬件設備初始化

    // 創建CUDA硬件設備上下文?
    AVBufferRef *hw_device_ctx = NULL;
    av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_CUDA, NULL, NULL, 0);// 綁定硬件設備到編碼器上下文?
    codec_ctx->hw_device_ctx = av_buffer_ref(hw_device_ctx);
  2. ?編碼器選擇與參數配置

    // 查找NVIDIA H.264硬件編碼器?
    const AVCodec *encoder = avcodec_find_encoder_by_name("h264_nvenc");// 設置編碼參數(分辨率、碼率、GOP等)?
    codec_ctx->width = 1920;
    codec_ctx->height = 1080;
    codec_ctx->bit_rate = 5000000;
    codec_ctx->time_base = (AVRational){1, 30};
    codec_ctx->pix_fmt = AV_PIX_FMT_CUDA;  // 指定硬件像素格式?// 設置編碼預設參數(NVIDIA專用)?
    av_opt_set(codec_ctx->priv_data, "preset", "llhp", 0);  // 低延遲高性能
  3. 硬件幀內存分配

    // 創建硬件幀并綁定GPU內存?
    AVFrame *hw_frame = av_frame_alloc();
    hw_frame->format = codec_ctx->pix_fmt;
    hw_frame->width = codec_ctx->width;
    hw_frame->height = codec_ctx->height;
    av_hwframe_get_buffer(codec_ctx->hw_frames_ctx, hw_frame, 0);
  4. 編碼數據流處理

    // 送入硬件編碼器?
    avcodec_send_frame(codec_ctx, hw_frame);// 接收編碼后的數據包
    AVPacket *pkt = av_packet_alloc();
    while (avcodec_receive_packet(codec_ctx, pkt) >= 0) {av_interleaved_write_frame(output_ctx, pkt);  // 寫入輸出文件?av_packet_unref(pkt);
    }

?二、跨平臺適配示例?

?硬件平臺??編碼器名稱??像素格式??初始化函數?
NVIDIA GPUh264_nvencAV_PIX_FMT_CUDAav_hwdevice_ctx_create(..., AV_HWDEVICE_TYPE_CUDA)?
Intel QSVh264_qsvAV_PIX_FMT_QSVav_hwdevice_ctx_create(..., AV_HWDEVICE_TYPE_QSV)?
AMD AMFh264_amfAV_PIX_FMT_D3D11av_hwdevice_ctx_create(..., AV_HWDEVICE_TYPE_D3D11VA)?

?三、關鍵問題解決?

  1. ?編碼器初始化失敗?

    • 檢查FFmpeg編譯時是否啟用對應硬件加速選項(如--enable-nvenc--enable-libmfx)?
    • 確認硬件驅動版本與FFmpeg兼容性?
  2. ?CPU-GPU內存拷貝開銷優化

    // 使用hwupload濾鏡直接上傳數據至GPU?
    AVFilterContext *upload_filter;
    const AVFilter *hwupload = avfilter_get_by_name("hwupload");
    avfilter_graph_create_filter(&upload_filter, hwupload, "upload", NULL, NULL, filter_graph);

??四、資源釋放

av_buffer_unref(&hw_device_ctx);  // 釋放硬件設備上下文?
avcodec_free_context(&codec_ctx);  // 釋放編碼器上下文
av_frame_free(&hw_frame);          // 釋放硬件幀
av_packet_free(&pkt);              // 釋放數據包

?五、編譯依賴?

  • ?NVIDIA平臺?:需安裝CUDA Toolkit,編譯時添加--enable-cuda --enable-nvenc?
  • ?Intel平臺?:需安裝Intel Media SDK,編譯時添加--enable-libmfx?

六、硬件編碼示例代碼

支持從本地YUV文件讀取數據、GPU加速編碼并輸出H.264視頻流到MP4文件。

#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/imgutils.h>
#include <libavutil/hwcontext.h>
#include <libswscale/swscale.h>#define INPUT_FILE "input.yuv"
#define OUTPUT_FILE "output.mp4"
#define WIDTH      1280
#define HEIGHT     720
#define FRAME_RATE 30int main() {AVFormatContext *fmt_ctx = NULL;AVCodecContext *enc_ctx = NULL;AVBufferRef *hw_device_ctx = NULL;SwsContext *sws_ctx = NULL;int ret = 0;// 1. 初始化硬件設備上下文ret = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_CUDA, NULL, NULL, 0);  // ?:ml-citation{ref="1,3" data="citationList"}if (ret < 0) {fprintf(stderr, "Failed to create CUDA device\n");goto cleanup;}// 2. 打開輸出文件并配置封裝格式avformat_alloc_output_context2(&fmt_ctx, NULL, NULL, OUTPUT_FILE);  // ?:ml-citation{ref="8" data="citationList"}if (!fmt_ctx) {fprintf(stderr, "Failed to create output context\n");ret = -1;goto cleanup;}// 3. 查找并配置硬件編碼器const AVCodec *encoder = avcodec_find_encoder_by_name("h264_nvenc");  // ?:ml-citation{ref="1,4" data="citationList"}if (!encoder) {fprintf(stderr, "NVENC encoder not found\n");ret = -1;goto cleanup;}enc_ctx = avcodec_alloc_context3(encoder);enc_ctx->width = WIDTH;enc_ctx->height = HEIGHT;enc_ctx->time_base = (AVRational){1, FRAME_RATE};enc_ctx->pix_fmt = AV_PIX_FMT_CUDA;       // 硬件像素格式 ?:ml-citation{ref="3,5" data="citationList"}enc_ctx->bit_rate = 4000000;              // 4Mbps碼率 ?:ml-citation{ref="5,8" data="citationList"}enc_ctx->hw_device_ctx = av_buffer_ref(hw_device_ctx);  // 綁定設備 ?:ml-citation{ref="3,6" data="citationList"}// 4. 打開編碼器并添加視頻流if ((ret = avcodec_open2(enc_ctx, encoder, NULL)) < 0) {  // ?:ml-citation{ref="4" data="citationList"}fprintf(stderr, "Failed to open encoder\n");goto cleanup;}AVStream *stream = avformat_new_stream(fmt_ctx, NULL);avcodec_parameters_from_context(stream->codecpar, enc_ctx);// 5. 打開輸出文件并寫入頭信息if (!(fmt_ctx->oformat->flags & AVFMT_NOFILE)) {ret = avio_open(&fmt_ctx->pb, OUTPUT_FILE, AVIO_FLAG_WRITE);  // ?:ml-citation{ref="8" data="citationList"}if (ret < 0) {fprintf(stderr, "Failed to open output file\n");goto cleanup;}}avformat_write_header(fmt_ctx, NULL);  // ?:ml-citation{ref="8" data="citationList"}// 6. 初始化YUV到CUDA格式轉換器sws_ctx = sws_getContext(WIDTH, HEIGHT, AV_PIX_FMT_YUV420P,WIDTH, HEIGHT, AV_PIX_FMT_CUDA,SWS_BILINEAR, NULL, NULL, NULL);  // ?:ml-citation{ref="4,7" data="citationList"}// 7. 準備輸入幀和硬件幀AVFrame *yuv_frame = av_frame_alloc();yuv_frame->width = WIDTH;yuv_frame->height = HEIGHT;yuv_frame->format = AV_PIX_FMT_YUV420P;av_frame_get_buffer(yuv_frame, 0);AVFrame *hw_frame = av_frame_alloc();hw_frame->format = enc_ctx->pix_fmt;hw_frame->width = WIDTH;hw_frame->height = HEIGHT;av_hwframe_get_buffer(enc_ctx->hw_frames_ctx, hw_frame, 0);  // ?:ml-citation{ref="3,6" data="citationList"}// 8. 處理每一幀數據FILE *yuv_file = fopen(INPUT_FILE, "rb");AVPacket *pkt = av_packet_alloc();for (int i = 0; i < 100; i++) {  // 編碼100幀測試// 從YUV文件讀取數據fread(yuv_frame->data, 1, WIDTH*HEIGHT, yuv_file);          // Y分量fread(yuv_frame->data?:ml-citation{ref="1" data="citationList"}, 1, (WIDTH/2)*(HEIGHT/2), yuv_file); // U分量fread(yuv_frame->data?:ml-citation{ref="2" data="citationList"}, 1, (WIDTH/2)*(HEIGHT/2), yuv_file); // V分量// 轉換到硬件幀sws_scale(sws_ctx, (const uint8_t**)yuv_frame->data, yuv_frame->linesize,0, HEIGHT, hw_frame->data, hw_frame->linesize);  // ?:ml-citation{ref="4,7" data="citationList"}// 編碼并寫入文件avcodec_send_frame(enc_ctx, hw_frame);while (avcodec_receive_packet(enc_ctx, pkt) >= 0) {av_packet_rescale_ts(pkt, enc_ctx->time_base, stream->time_base);av_interleaved_write_frame(fmt_ctx, pkt);  // ?:ml-citation{ref="8" data="citationList"}av_packet_unref(pkt);}}cleanup:// 9. 釋放所有資源if (yuv_file) fclose(yuv_file);if (sws_ctx) sws_freeContext(sws_ctx);av_packet_free(&pkt);av_frame_free(&yuv_frame);av_frame_free(&hw_frame);if (fmt_ctx) avformat_free_context(fmt_ctx);avcodec_free_context(&enc_ctx);av_buffer_unref(&hw_device_ctx);return ret;
}

關鍵代碼說明:?

?組件??功能說明??依賴項?
hw_device_ctx管理CUDA設備上下文,用于GPU內存分配和硬件加速操作CUDA驅動和NVENC支持 ?
sws_ctx將CPU端的YUV420P數據轉換為GPU端的CUDA格式(如NV12)libswscale庫?
av_hwframe_get_buffer直接從GPU顯存分配幀內存,避免CPU-GPU內存拷貝FFmpeg硬件幀支持
avcodec_send_frame將硬件幀送入編碼器隊列,觸發異步編碼操作編碼器線程模型

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

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

相關文章

【設計模式】3W 學習法全面解析 7 大結構型模式:Java 實戰 + 開源框架應用

3W 學習法總結結構型模式&#xff08;附 Java 代碼實戰及開源框架應用&#xff09; 結構型模式 主要關注 類與對象的組合&#xff0c;確保不同組件之間能夠高效協作&#xff0c;提高系統的靈活性和可維護性。本文采用 3W 學習法&#xff08;What、Why、How&#xff09;&#x…

在大數據開發中ETL是指什么?

hello寶子們...我們是艾斯視覺擅長ui設計和前端數字孿生、大數據、三維建模、三維動畫10年經驗!希望我的分享能幫助到您!如需幫助可以評論關注私信我們一起探討!致敬感謝感恩! 在數字經濟時代&#xff0c;數據已成為企業最核心的資產。然而&#xff0c;分散在業務系統、日志文件…

前端面試項目拷打

Axios相關 1.在Axios二次封裝時&#xff0c;具體封裝了哪些內容&#xff0c;如何處理請求攔截和響應攔截&#xff1f; axios二次封裝的目的&#xff1a;為了統一處理請求和響應攔截器、錯誤處理、請求超時、請求頭配置等&#xff0c;提高代碼可維護性和復用性。 首先創建axios…

「JavaScript深入」Server-Sent Events (SSE):輕量級實時通信技術

Server-Sent Events&#xff08;SSE&#xff09; SSE 的特點1. 單向通信2. 簡單易用&#xff0c;瀏覽器原生支持3. 持久連接4. 純文本傳輸5. 自動重連機制6. 輕量級協議 SSE 的實現服務器端實現&#xff08;Node.js 示例&#xff09;1. HTTP 響應頭設置2. 數據推送模式3. 服務器…

藍橋杯2023年第十四屆省賽真題-階乘的和

藍橋杯2023年第十四屆省賽真題-階乘的和 時間限制: 2s 內存限制: 320MB 提交: 3519 解決: 697 題目描述 給定 n 個數 Ai&#xff0c;問能滿足 m! 為∑ni1(Ai!) 的因數的最大的 m 是多少。其中 m! 表示 m 的階乘&#xff0c;即 1 2 3 m。 輸入格式 輸入的第一行包含一個整…

影刀RPA拓展-Python變量類型轉換

1. Python變量類型轉換概述 1.1 類型轉換的必要性 Python作為一種動態類型語言&#xff0c;在編程過程中經常需要進行變量類型轉換。這主要是因為不同數據類型在存儲結構、運算規則和使用場景上存在差異&#xff0c;而在實際開發中&#xff0c;我們常常需要對不同類型的數據進…

Python pyqt+flask做一個簡單實用的自動排班系統

這是一個基于Flask和PyQt的排班系統&#xff0c;可以將Web界面嵌入到桌面應用程序中。 系統界面&#xff1a; 功能特點&#xff1a; - 讀取員工信息和現有排班表 - 自動生成排班表 - 美觀的Web界面 - 獨立的桌面應用程序 整體架構&#xff1a; 系統采用前后端分離的架構…

Pycharm接入DeepSeek,提升自動化腳本的寫作效率

一.效果展示&#xff1a; 二.實施步驟&#xff1a; 1.DeepSeek官網創建API key&#xff1a; 創建成功后&#xff0c;會生成一個API key&#xff1a; 2. PyCharm工具&#xff0c;打開文件->設置->插件&#xff0c;搜索“Continue”&#xff0c;點擊安裝 3.安裝完成后&…

Java:Arrays類:操作數組的工具類

文章目錄 Arrays類常見方法SetAll(); 代碼排序如果數組中存儲的是自定義對象 Arrays類 常見方法 SetAll(); 注意&#xff1a; 不能用新的數組接是因為修改的是原數組&#xff0c;所以完了要輸出原數組發現會產生變化參數是數組下標變成灰色是因為還能簡化&#xff08;Lambda…

2025-gazebo配置on vmware,wsl

ros2安裝 # 安裝ros2, 推薦魚香ros一鍵式安裝 wget http://fishros.com/install -O fishros && . fishros安裝版本&#xff1a;ubuntu24.04 ros2 jazzy gazebo Getting Started with Gazebo? — Gazebo ionic documentation ros與gz的版本對應關系&#xff1a; ?…

格力地產更名“珠免集團“ 全面轉型免稅賽道

大灣區經濟網品牌觀察訊&#xff0c;3月18日&#xff0c;格力地產股份有限公司公告宣布&#xff0c;擬將公司名稱變更為"珠海珠免集團股份有限公司"&#xff0c;證券簡稱同步變更為"珠免集團"。此次更名并非簡單的品牌煥新&#xff0c;而是標志著這家曾以房…

網絡編程--服務器雙客戶端聊天

寫一個服務器和客戶端 運行服務器和2個客戶端&#xff0c;實現聊天功能 客戶端1和客戶端2進行聊天&#xff0c;客戶端1將聊天數據發送給服務器&#xff0c;服務器將聊天數據轉發給客戶端2 要求&#xff1a; 服務器使用 select 模型實現 &#xff0c;客戶端1使用 poll 模型實現…

k8s主要控制器簡述(一)ReplicaSet與Deployment

目錄 一、ReplicaSet 關鍵特性 示例 解釋 支持的 Operator 二、Deployment 1. 聲明式更新 示例 2. 滾動更新 示例 3. 回滾 示例 4. ReplicaSet 管理 示例 5. 自動恢復 示例 6. 擴展和縮容 示例 示例 一、ReplicaSet ReplicaSet 是 Kubernetes 中的一個核心控…

python中redis操作整理

下載redis命令 pip install redis 連接redis import redis # host是redis主機&#xff0c;需要redis服務端和客戶端都起著 redis默認端口是6379 pool redis.ConnectionPool(hostlocalhost, port6379,decode_responsesTrue) r redis.Redis(connection_poolpool)操作字符串 …

自然語言處理入門4——RNN

一般來說&#xff0c;提到自然語言處理&#xff0c;我們都會涉及到循環神經網絡&#xff08;RNN&#xff09;&#xff0c;這是因為自然語言可以被看作是一個時間序列&#xff0c;這個時間序列中的元素是一個個的token。傳統的前饋神經網絡結構簡單&#xff0c;但是不能很好的處…

數據結構之鏈表(雙鏈表)

目錄 一、雙向帶頭循環鏈表 概念 二、哨兵位的頭節點 優點&#xff1a; 頭節點的初始化 三、帶頭雙向鏈表的實現 1.雙鏈表的銷毀 2.雙鏈表的打印 3.雙鏈表的尾插和頭插 尾插&#xff1a; 頭插&#xff1a; 4.雙鏈表的尾刪和頭刪 尾刪&#xff1a; 頭刪&#xff1a; …

ASP3605同步降壓調節器——滿足汽車電子嚴苛要求的電源芯片方案

ASP3605高效同步降壓調節器&#xff0c;通過AEC-Q100 Grade1認證&#xff0c;輸入電壓4V至15V&#xff0c;輸出電流5A&#xff0c;峰值效率94%。車規級型號ASP3605A3U支持-40C至125C工作溫度&#xff0c;適用于ADAS、車載信息娛樂系統等場景。 面向汽車電子的核心功能設計 1. …

vue3+Ts+elementPlus二次封裝Table分頁表格,表格內展示圖片、switch開關、支持

目錄 一.項目文件結構 二.實現代碼 1.子組件&#xff08;表格組件&#xff09; 2.父組件&#xff08;使用表格&#xff09; 一.項目文件結構 1.表格組件&#xff08;子組件&#xff09;位置 2.使用表格組件的頁面文件&#xff08;父組件&#xff09;位置 3.演示圖片位置 ele…

[特殊字符]1.2.1 新型基礎設施建設

&#x1f680; 新型基礎設施建設全解析 &#x1f31f; 核心概念與定義 維度詳細內容定義以新發展理念為引領&#xff0c;以技術創新為驅動&#xff0c;以信息網絡為基礎&#xff0c;提供數字轉型、智能升級、融合創新服務的基礎設施體系。提出背景2018年中央經濟工作會議首次提…

SQL Server數據庫慢SQL調優

SQL Server中慢SQL會顯著降低系統性能并引發級聯效應。首先&#xff0c;用戶直接體驗響應時間延長&#xff0c;核心業務操作&#xff08;如交易處理、報表生成&#xff09;效率下降&#xff0c;導致客戶滿意度降低甚至業務中斷。其次&#xff0c;資源利用率失衡&#xff0c;CPU…