大家好,关于电影网站源码分享采集AV很多朋友都还不太明白,不过没关系,因为今天小编就来为大家分享关于最好的电影网站源代码的知识点,相信应该可以解决大家的一些困惑和问题,如果碰巧可以解决您的问题,还望关注下本站哦,希望对各位有所帮助!
注意:
VAAPI是intergpu提供的硬编解码接口\nVDPAU是videodecodepresentapiforunix\nnvdec/ncvid都是nivida产出的硬解接口,区别在于解码方式,和数据传输方式不同\nnvencnivida硬编接口
编译&运行
linux:\ngcc-gvideo_decode_gpu.c`pkg-config–libslibavformatlibavcodeclibswresamplelibswscalelibavutil`-ovideo_decode_gpu\nruncmd:\n./video_decode_gpudata/left.mp4./bmp
gpu解码原理
问题1?gpu解码是把内存中AVPacket拷贝到gp显存中进行处理的吗?\n看来是的,代码中通过av_read_frame(input_ctx,&packet)读取数据包,其数据操作流向应该是videofile->memory\n问题2?gpu解码的数据流向?\nvideofile->avpacket->decodingframe&39;singpu->transferrameingpuintohostmemory
VDPAU简介
DevelopedbyNVIDIAforUnix/Linuxsystems.Toenablethisyoutypicallyneedthelibvdpaudevelopmentpackageinyourdistribution,andacompatiblegraphicscard.\n\nNotethatVDPAUcannotbeusedtodecodeframesinmemory,thecompressedframesaresentbylibavcodectotheGPUdevicesupportedbyVDPAUandthenthedecodedimagecanbeaccessedusingtheVDPAUAPI.ThisisnotdoneautomaticallybyFFmpeg,butmustbedoneattheapplicationlevel(checkforexampletheffmpeg_vdpau.cfileusedbyffmpeg.c).Also,notethatwiththisAPIitisnotpossibletomovethedecodedframebacktoRAM,forexampleincaseyouneedtoencodeagainthedecodedframe(e.g.whendoingtranscodingonaserver).\n\nSeveraldecodersarecurrentlysupportedthroughVDPAUinlibavcodec,inparticularH.264,MPEG-1/2/4,andVC-1.\n\n翻译:\n\n由NVIDIA开发的Unix/Linux系统。要启用此功能,您通常需要分发中的libvdpau开发包和兼容的图形卡。\n\n注意,VDPAU不能用于解码内存中的帧,压缩帧由libavcodec发送到VDPAU支持的GPU设备,然后可以使用VDPAUAPI访问解码图像。\n这不是由FFmpeg自动完成的,但必须在应用程序级别完成(例如检查ffmpeg.c使用的ffmpeg_vdpau.c文件)。\n此外,请注意,使用此API时,无法将解码后的帧移回RAM,例如,如果您需要再次对解码帧进行编码(例如,在服务器上进行转码时)。\n\n目前通过libavcodec中的VDPAU支持几个解码器,特别是H.264,MPEG-1/2/4和VC-1。
VDPAU学习:
VdpDecoder->解码压缩包数据\nVdpVideoSurface->解码完数据放置的空间\nVdpVideoMixer->对解码完的数据做后置处理\nVdpOutputSurface->处理完数据放置的位置
cuvid与VDPAU是平级的东西,不能拿来直接使用,使用成本太大
cuvid学习
cuvidnvidia提供的gpu视频硬解码库,底层依赖cuda并行计算框架\n将cpu解码转化到gpu解码上,减少cpu压力,提升解码速度
CUVID硬解码
note:
cuvidnvdec两者都是解码api,不同点在于解码方式&数据传输\nnvencvaapicdpau都是硬件编解码api
CUVID解码rtsp视频流
note
OpenCV中VideoReader_GPU可以方便地利用GPU读取视频文件,加速解码过程,但OpenCV中VideoReader_GPU无法读取rtsp视频流数据。
这是因为CUVID中CuvideoSource不支持rtsp视频流数据,不能由rtsp地址创建VideoSource。
但是videoSource支持视频文件
查看nvidia驱动&nvcc版本
cat/proc/driver/nvidia/version\n\nnvcc编译器的版本\nnvcc-V
Note:ForVideoCodecSDK7.0andlater,NVCUVIDhasbeenrenamedtoNVDECODEAPI.
编译&运行
领取C++音视频开发学习资料:点击→音视频开发(资料文档+视频教程+面试题)(FFmpeg+WebRTC+RTMP+RTSP+HLS+RTP)
编译
linux:\ngcc-ghw_decode_cuvid.c`pkg-config–libslibavformatlibavcodeclibswresamplelibswscalelibavutil`-ohw_decode_cuvid
运行
./hw_decode_cuvidcudainput_data/left.mp4./output_data/raw.out
运行结果
raw.out文件生成
raw.out文件生成
cpu软解码cpu占用率
cpu软解码cpu使用率g
gpucuvid硬解码cpu占用率
gpu硬解码cpu使用率
gpu硬解码gpu使用情况
gpu硬解码gpu使用情况
问题:
1、为什么gpu硬解码显卡使用率那么低?需要排查下问题。
2、将gpu中frame直接做AV_PIX_FMT_CUDA->AV_PIX_FMT_BGR24转化不能直接用sws_getContext,如何才能实现
3、ffmpeg将gpu解码数据的像素格式进行yuv-rgb格式转换,是否直接支持,是否需要自己写函数
4、将gpu中数据直接存储在磁盘上?如果不可以的话,则进行devicedata->hostmemorydata->file
5、数据拷贝方式transfer_data_from源码
gpudecodedframepixformatAV_PIX_FMT_CUDA直接在显存中转化为AV_PIX_FMT_BGR24
可行路径,试了三种:
两种cpu层面转换像素格式的方法(1种失败,1种成功);\n直接使用ffmpegapi在gpu层面进行像素格式转换(失败)
CPU主导像素转换
1.使用sws_scale实现AV_PIX_FMT_CUDA->AV_PIX_FMT_BGR24的直接转换(cpu层面)
这是我第一次使用的方式,模仿cpu上软解码(获取视频帧,并存储为bmp格式,经验原则,这种方式最容易想到)运行结果:失败,badsrcimgpointers运行结果如下图所示:
问题原因:
如代码hw_decode_cuvid_origin.c中所示,直接通过transfer_data将gpu中解码后的framedownload到系统内存,则系统内存中的framespiex->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呢?如果可以直接实现,性能会有很大提升,因为减少了device->host的数据传输,且gpu多核心并行处理,肯定比cpu处理性能要强悍。
av_hwframe_transfer_data()执行操作前设置内存中目标frame的像素格式为AV_PIX_FMT_BGR24,gpu黑盒操作实现在gpu上直接将像素格式转化为目标bgr24格式
运行结果:失败,像素没对齐,只有亮度运行结果如下图所示:![预先设置内存中frame目标像素格式为AV_PIX_FMT_BGR24]
问题原因:如下图所示:
问题原因-transfer_data_pix_format_limit
红框表示的意思为:src->frame->format转换为dst->frame->format是受限制的,主要是受av_hwframe_transfer_get_formats()函数返回的formats列表限制
所以gdb了下源码,发现src->frame->format转换为dst->frame->format的受限范围很小,然后找出了av_hwframe_transfer_get_formats支持的formats,调试过程如下所示:gdb-tuihw_decode_cuvid(-tui支持查看源码)
gdb_tui.png
在调用av_hwframe_transfer_data()函数处打上断点,且设置程序运行所需参数
enter_break_point.png
run程序,step进入函数调用栈
run&step-run_enter_func_call_stack
n单步运行,函数调用至transfer_data_alloc()
enter_transfer_data_alloc.png
领取C++音视频开发学习资料:点击→音视频开发(资料文档+视频教程+面试题)(FFmpeg+WebRTC+RTMP+RTSP+HLS+RTP)
发现av_hwframe_transfer_get_formats()函数
find_func_call_av_hwframe_transfer_get_formats.png
更改dst->format的值为<0的值,并打印支持的像素转换列表
get_can_changed_pix_formats.png
可以看到只支持gpu硬件像素编码格式->AV_PIX_FMT_NV12的转换
CPU主导像素转换
经过前两次的试验,可以明确当前最新版本的ffmpeg还不支持硬解完成之后直接将像素格式转换为目标rgb24数据,还是回归到cpu+sws_scale上,经过第二步,可以知道AV_PIX_FMT_CUDA->AV_PIX_FMT_NV12这条路行的通,AV_PIX_FMT_NV12其实是YUV格式的数据,yuv数据到rgb的像素转换是完全支持的,所以就自然编写了AV_PIX_FMT_CUDA->AV_PIX_FMT_NV12->AV_PIX_FMT_BGR24的代码,经测试没问题。当然,不可否认:实现AV_PIX_FMT_CUDA->AV_PIX_FMT_NV12->AV_PIX_FMT_BGR24格式转换(cpu实现pixformat转换,这种cpu层面上的像素格式转换方式比较弱)
运行结果:成功,如下图所示:
END,本文到此结束,如果可以帮助到大家,还望关注本站哦!
