亚洲国产日韩人妖另类,久久只有这里有精品热久久,依依成人精品视频在线观看,免费国产午夜视频在线

      
      

        ffmpeg + cuda(cuvid) 硬解碼+像素格式轉換(cpu主導)實戰(zhàn)

        ffmpeg + cuda(cuvid) 硬解碼+像素格式轉換(cpu主導)實戰(zhàn)

        注意:

        VAAPI 是inter gpu 提供的硬編解碼接口VDPAU 是 video decode present api for unixnvdec / ncvid 都是nivida產(chǎn)出的硬解接口,區(qū)別在于解碼方式,和數(shù)據(jù)傳輸方式不同nvenc nivida 硬編接口

        編譯 & 運行

        linux: gcc -g video_decode_gpu.c `pkg-config –libs libavformat libavcodec libswresample libswscale libavutil` -o video_decode_gpurun cmd: ./video_decode_gpu data/left.mp4 ./bmp

        gpu解碼原理

        問題1? gpu 解碼 是把內存中AVPacket 拷貝到gp顯存中進行處理的嗎? 看來是的,代碼中通過 av_read_frame(input_ctx, &packet) 讀取數(shù)據(jù)包,其數(shù)據(jù)操作流向應該是 video file -> memory問題2? gpu 解碼 的 數(shù)據(jù)流向? videofile-> avpacket ->decoding frame’s in gpu-> transfer rame in gpu into host memory問題3? gpu 解碼數(shù)據(jù) cuvid 解碼器,也是api,對應的數(shù)據(jù)操作流向? videofile-> avpacket ->decoding frame’s in gpu-> transfer rame in gpu into host memory

        VDPAU 簡介

        Developed by NVIDIA for Unix/Linux systems. To enable this you typically need the libvdpau development package in your distribution, and a compatible graphics card. Note that VDPAU cannot be used to decode frames in memory, the compressed frames are sent by libavcodec to the GPU device supported by VDPAU and then the decoded image can be accessed using the VDPAU API. This is not done automatically by FFmpeg, but must be done at the application level (check for example the ffmpeg_vdpau.c file used by ffmpeg.c). Also, note that with this API it is not possible to move the decoded frame back to RAM, for example in case you need to encode again the decoded frame (e.g. when doing transcoding on a server). Several decoders are currently supported through VDPAU in libavcodec, in particular H.264, MPEG-1/2/4, and VC-1. 翻譯: 由NVIDIA開發(fā)的Unix / Linux系統(tǒng)。 要啟用此功能,您通常需要分發(fā)中的libvdpau開發(fā)包和兼容的圖形卡。 注意,VDPAU不能用于解碼內存中的幀,壓縮幀由libavcodec發(fā)送到VDPAU支持的GPU設備,然后可以使用VDPAU API訪問解碼圖像。 這不是由FFmpeg自動完成的,但必須在應用程序級別完成(例如檢查ffmpeg.c使用的ffmpeg_vdpau.c文件)。此外,請注意,使用此API時,無法將解碼后的幀移回RAM,例如,如果您需要再次對解碼幀進行編碼(例如,在服務器上進行轉碼時)。 目前通過libavcodec中的VDPAU支持幾個解碼器,特別是H.264,MPEG-1/2/4和VC-1。

        VDPAU 學習:

        VdpDecoder -> 解碼 壓縮包數(shù)據(jù)VdpVideoSurface -> 解碼完數(shù)據(jù)放置的空間VdpVideoMixer -> 對解碼完的數(shù)據(jù)做后置處理VdpOutputSurface -> 處理完數(shù)據(jù)放置的位置

        cuvid 與 VDPAU 是平級的東西,不能拿來直接使用,使用成本太大

        cuvid 學習

        cuvid nvidia 提供的gpu 視頻硬解碼庫,底層依賴cuda并行計算框架 將cpu 解碼轉化到gpu 解碼上,減少cpu壓力,提升解碼速度

        CUVID 硬解碼

        note:

        cuvid nvdec 兩者都是解碼api,不同點在于解碼方式 & 數(shù)據(jù)傳輸nvenc vaapi cdpau 都是硬件編解碼api

        CUVID解碼rtsp視頻流

        note

        OpenCV中VideoReader_GPU可以方便地利用GPU讀取視頻文件,加速解碼過程,但OpenCV中VideoReader_GPU無法讀取rtsp視頻流數(shù)據(jù)。

        這是因為CUVID中CuvideoSource不支持rtsp視頻流數(shù)據(jù),不能由rtsp地址創(chuàng)建VideoSource。

        但是videoSource 支持 視頻文件

        查看nvidia 驅動 & nvcc 版本

        cat /proc/driver/nvidia/version nvcc編譯器的版本nvcc -V

        Note: For Video Codec SDK 7.0 and later, NVCUVID has been renamed to NVDECODE API.

        編譯 & 運行

        領取C++音視頻開發(fā)學習資料:點擊 音視頻開發(fā)(資料文檔+視頻教程+面試題)(FFmpeg+WebRTC+RTMP+RTSP+HLS+RTP)

        編譯

        linux: gcc -g hw_decode_cuvid.c `pkg-config –libs libavformat libavcodec libswresample libswscale libavutil` -o hw_decode_cuvid

        運行

        ./hw_decode_cuvid cuda input_data/left.mp4 ./output_data/raw.out

        運行結果

        raw.out 文件生成

        raw.out 文件生成

        cpu 軟解碼 cpu 占用率

        cpu 軟解碼 cpu使用率g

        gpu cuvid 硬解碼 cpu 占用率

        gpu 硬解碼 cpu使用率

        gpu 硬解碼 gpu 使用情況

        gpu 硬解碼 gpu 使用情況

        問題:

        1、為什么 gpu 硬解碼顯卡使用率那么低?需要排查下問題。

        2、將 gpu 中frame 直接做 AV_PIX_FMT_CUDA-> AV_PIX_FMT_BGR24 轉化 不能直接用 sws_getContext ,如何才能實現(xiàn)

        3、ffmpeg 將 gpu解碼 數(shù)據(jù)的像素格式進行 yuv-rgb 格式轉換 ,是否直接支持,是否需要自己寫函數(shù)

        4、將 gpu 中數(shù)據(jù)直接存儲在磁盤上? 如果不可以的話 ,則進行 device data ->host memory data ->file

        5、數(shù)據(jù)拷貝方式 transfer_data_from 源碼

        gpu decoded frame pix format AV_PIX_FMT_CUDA 直接在顯存中 轉化為 AV_PIX_FMT_BGR24

        可行路徑,試了三種:

        兩種cpu層面轉換像素格式 的方法(1種失敗,1種成功);直接使用ffmpeg api 在gpu層面進行像素格式轉換(失敗)

        CPU 主導像素轉換

        1. 使用 sws_scale 實現(xiàn) AV_PIX_FMT_CUDA-> AV_PIX_FMT_BGR24 的直接轉換(cpu 層面)

        這是我第一次使用的方式,模仿 cpu 上軟解碼(獲取視頻幀,并存儲為bmp格式,經(jīng)驗原則,這種方式最容易想到)運行結果:失敗,bad src img pointers運行結果如下圖所示:

        問題原因:

        如代碼 hw_decode_cuvid_origin.c 中所示, 直接通過transfer_data 將gpu 中解碼后的frame download到系統(tǒng)內存,則系統(tǒng)內存中的frames piex->format 仍為 AV_PIX_FMT_CUDA ,而 AV_PIX_FMT_CUDA 是gpu 顯存中存儲的解碼后的幀像素格式所以通過 sws_scale 是不能直接change的

        GPU 主導像素轉換

        gpu 不支持 sws_scale + AV_PIX_FMT_CUDA-> AV_PIX_FMT_BGR24 的直接像素轉換方式,那么 能否直接在gpu中直接轉化 AV_PIX_FMT_CUDA 為 AV_PIX_FMT_BGR24呢?如果可以直接實現(xiàn),性能會有很大提升,因為減少了device->host 的數(shù)據(jù)傳輸,且gpu多核心并行處理,肯定比cpu處理性能要強悍。

        av_hwframe_transfer_data() 執(zhí)行操作前 設置 內存中目標frame的像素格式為 AV_PIX_FMT_BGR24,gpu 黑盒操作實現(xiàn)在gpu上直接將像素格式轉化為目標bgr24格式

        運行結果:失敗,像素沒對齊,只有亮度運行結果如下圖所示:![預先設置內存中frame目標像素格式為 AV_PIX_FMT_BGR24]

        問題原因:如下圖所示:

        問題原因-transfer_data_pix_format_limit

        紅框表示的意思為:src->frame->format 轉換為 dst->frame->format 是受限制的,主要是受av_hwframe_transfer_get_formats() 函數(shù)返回的formats 列表限制

        所以gdb了下源碼,發(fā)現(xiàn)src->frame->format 轉換為 dst->frame->format 的受限范圍很小,然后找出了 av_hwframe_transfer_get_formats 支持的formats,調試過程如下所示:gdb -tui hw_decode_cuvid (-tui 支持查看源碼)

        gdb_tui.png

        在調用 av_hwframe_transfer_data() 函數(shù)處打上斷點,且設置程序運行所需參數(shù)

        enter_break_point.png

        run 程序,step 進入函數(shù)調用棧

        run & step-run_enter_func_call_stack

        n 單步運行,函數(shù)調用至 transfer_data_alloc()

        enter_transfer_data_alloc.png

        領取C++音視頻開發(fā)學習資料:點擊 音視頻開發(fā)(資料文檔+視頻教程+面試題)(FFmpeg+WebRTC+RTMP+RTSP+HLS+RTP)

        發(fā)現(xiàn) av_hwframe_transfer_get_formats()函數(shù)

        find_func_call_av_hwframe_transfer_get_formats.png

        更改 dst->format 的值為<0的值,并打印支持的像素轉換列表

        get_can_changed_pix_formats.png

        可以看到只支持 gpu 硬件像素編碼格式->AV_PIX_FMT_NV12 的轉換

        CPU 主導像素轉換

        經(jīng)過前兩次的試驗,可以明確當前最新版本的ffmpeg還不支持硬解完成之后直接將像素格式轉換為目標rgb24數(shù)據(jù),還是回歸到 cpu + sws_scale 上,經(jīng)過第二步,可以知道AV_PIX_FMT_CUDA->AV_PIX_FMT_NV12這條路行的通,AV_PIX_FMT_NV12 其實是 YUV 格式的數(shù)據(jù),yuv 數(shù)據(jù)到 rgb 的像素轉換是完全支持的,所以就自然編寫了 AV_PIX_FMT_CUDA->AV_PIX_FMT_NV12->AV_PIX_FMT_BGR24 的代碼,經(jīng)測試沒問題。當然,不可否認:實現(xiàn) AV_PIX_FMT_CUDA-> AV_PIX_FMT_NV12->AV_PIX_FMT_BGR24 格式轉換 (cpu 實現(xiàn) pix format 轉換,這種cpu層面上的像素格式轉換方式比較弱)

        運行結果:成功,如下圖所示:

        鄭重聲明:本文內容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場,版權歸原作者所有,如有侵權請聯(lián)系管理員(admin#wlmqw.com)刪除。
        上一篇 2022年6月23日 06:13
        下一篇 2022年6月23日 06:13

        相關推薦

        聯(lián)系我們

        聯(lián)系郵箱:admin#wlmqw.com
        工作時間:周一至周五,10:30-18:30,節(jié)假日休息