文档章节

Nvidia硬解码总结

张旭0512
 张旭0512
发布于 2016/07/14 11:00
字数 1322
阅读 1341
收藏 3
点赞 1
评论 0

Nvidia硬解码总结

1.前言

  本文的主要目的是对近期进行的nvidia硬件解码工作的记录和总结。至于为什么研究nvidia硬件解码的具体内容,其实主要是为了在项目中能够利用nvidia的硬件解码和编码能力,提高单机的编解码并行能力。截止当前,nvidia的硬件编码官方提供了nvenc的方法,且在ffmpeg中已经增加了对nvenc的编码库。对于硬件解码,官方提供了基于cuda的解码方法,但是ffmpeg中还没有相应的解码库。所以,我的目的就是调研一下这个硬解方案,并将其自定义增加到ffmpeg中。

  官方提供的资料比较少,只包括一页的视频解码器介绍示例代码

  吐槽一下:官网那个一页的介绍参考量真不大,主要还是参考例程代码。

2.例程介绍

  官网提供的例程代码解压后如下图所示,因为是调用解码,所以主要参考了"NvDecodeD3D9"和"NvTranscoder"的代码。

  总的来说,nvidia提供了source, parser, decoder三个基本模块。其中source是用来解析视频文件(例如:纯h.264文件),parser是用来解析视频并得到一帧帧的数据,decoder就是解码了。

流程图

  这三个模块相辅相成,其主要操作流程如上图所示。source模块输出h264数据,parser解析这些h264数据,并通过3个重要的回调函数(pfnSequenceCallback, pfnDecodePicture, pfnDisplayPicture)完成解码及输出功能。其中,pfnSequenceCallback是parser解析到序列及图像参数信息时的回调函数,其传入的参数是parser解析好的视频参数,可以用于初始化解码器或重置解码器。pfnDecodePicture是parser解析到视频编码数据后的回调函数,其传入的参数parser处理好待解码的视频编码数据,需要在该函数中调用decoder的接口进行解码操作。pfnDisplayPicture是parser对解码后的数据处理的回调函数,可以在该回调中对已解码的数据进行获取(从显存到系统内存)并处理。

3.主要接口说明

  cuvidCreateVideoSource : 该接口的作用是创建source,主要参数是设置视频文件路径和回调函数。source会去解析指定视频文件,并通过回调函数实现对视频数据的自定义处理。源码中在视频数据回调函数中,调用了cuvidParseVideoData,即向parser中传递数据。

    //init video source
    CUVIDSOURCEPARAMS oVideoSourceParameters;
    memset(&oVideoSourceParameters, 0, sizeof(CUVIDSOURCEPARAMS));
    oVideoSourceParameters.pUserData = this;
    oVideoSourceParameters.pfnVideoDataHandler = HandleVideoData;
    oVideoSourceParameters.pfnAudioDataHandler = NULL;

    oResult = cuvidCreateVideoSource(&m_videoSource, videoPath, &oVideoSourceParameters);
    if (oResult != CUDA_SUCCESS) {
        fprintf(stderr, "cuvidCreateVideoSource failed\n");
        fprintf(stderr, "Please check if the path exists, or the video is a valid H264 file\n");
        exit(-1);
    }

  cuvidCreateVideoParser : 该接口是用来创建video parser,主要参数是设置三个回调函数,实现对解析出来的数据的处理。

    //init video parser
    CUVIDPARSERPARAMS oVideoParserParameters;
    memset(&oVideoParserParameters, 0, sizeof(CUVIDPARSERPARAMS));
    oVideoParserParameters.CodecType = oVideoDecodeCreateInfo.CodecType;
    oVideoParserParameters.ulMaxNumDecodeSurfaces = oVideoDecodeCreateInfo.ulNumDecodeSurfaces;
    oVideoParserParameters.ulMaxDisplayDelay = 1;
    oVideoParserParameters.pUserData = this;
    oVideoParserParameters.pfnSequenceCallback = HandleVideoSequence;
    oVideoParserParameters.pfnDecodePicture = HandlePictureDecode;
    oVideoParserParameters.pfnDisplayPicture = HandlePictureDisplay;

    oResult = cuvidCreateVideoParser(&m_videoParser, &oVideoParserParameters);
    if (oResult != CUDA_SUCCESS) {
        fprintf(stderr, "cuvidCreateVideoParser failed, error code: %d\n", oResult);
        exit(-1);
    }

  cuvidParseVideoData : 该接口是用来向parser塞数据,通过不断地塞h.264数据,parser会通过回调接口对解析出来的数据进行处理。在例程中,cuvidParseVideoData是在source的pfnVideoDataHandler回调中被使用的,即source获取到视频数据,就将其传递给parser。

    // the callback of source pfnVideoDataHandler
    static int CUDAAPI HandleVideoData(void* pUserData, CUVIDSOURCEDATAPACKET* pPacket)
    {
        assert(pUserData);
        CudaDecoder* pDecoder = (CudaDecoder*)pUserData;

        CUresult oResult = cuvidParseVideoData(pDecoder->m_videoParser, pPacket);
        if(oResult != CUDA_SUCCESS) {
            printf("error!\n");
        }

        return 1;
    }

  cuvidCreateDecoder : 该接口是用来创建decoder,通过设置一些解码参数,会返回一个decoder的句柄。这个句柄会在之后的解码接口中被使用。该接口的具体使用方法在例程中有详细的参数设置,这里就繁琐地描述了。

  cuvidDecodePicture : 该接口就是向解码器传递待解码的数据。需要说明一下,该接口是异步解码,不能通过该接口得到解码后的视频数据,它只是向解码器传数据而已。解码后的数据,是通过parser的pfnDisplayPicture回调得到。

4.技术点说明

库的使用

  nvidia解码需要使用cuda和nvcuvid两个库(在linux中是libcuda.so和libnvcuvid.so),使用的时候要加载它们,并使用其中一些接口。主要使用到的接口主要有:

    cuInit
    cuDeviceGetCount
    cuDeviceGet
    cuDeviceGetName
    cuDeviceComputeCapability
    cuCtxCreate
    cuCtxPushCurrent
    cuCtxPopCurrent
    cuCtxDestroy
    cuMemAllocHost
    cuMemFreeHost
    cuStreamCreate
    cuStreamDestroy
    cuMemcpyDtoHAsync
    cuvidCreateDecoder
    cuvidDestroyDecoder
    cuvidDecodePicture
    cuvidCtxLockCreate
    cuvidCtxLockDestroy
    cuvidCtxLock
    cuvidCtxUnlock
    cuvidMapVideoFrame
    cuvidUnmapVideoFrame
    cuvidCreateVideoParser
    cuvidParseVideoData
    cuvidDestroyVideoParser

注意:根据库的版本不同,接口有的需要使用v2版本。例如:cuCtxCreate和cuCtxCreate_v2。

device内存和system内存

  使用nvidia进行硬件解码需要了解一下device内存(可以叫显存或设备内存)和系统内存的数据处理方法。在解码完成后,视频YUV数据是在device内存中的,所以需要使用nvidia提供的接口把数据弄出来。涉及的接口主要有:cuMemAllocHost, cuMemFreeHost, cuvidMapVideoFrame, cuvidUnmapVideoFrame, cuMemcpyDtoHAsync。其中,cuMemAllocHost是用来创建系统及显卡都可访问的系统内存。cuvidMapVideoFrame可以获取到设备内存中指定的YUV数据地址。最后通过cuMemcpyDtoHAsync将设备内存中指定的数据copy到系统内存中。

© 著作权归作者所有

共有 人打赏支持
张旭0512
粉丝 40
博文 136
码字总数 30203
作品 0
朝阳
程序员
QtAV 1.8.0 发布,跨平台高性能音视频框架

QtAV 1.8.0 发布,此版本更新内容如下: - 支持XAudio2。XAudio2是windows的一个音频接口,支持几乎所有windows版本,从xp到10,还有xbox、windows phone。其中win7及更老的系统需要安装dir...

LucasWang
2015/09/01
2.3K
7
H.265/HEVC视频编码:FPGA GPU QSV实现对比

1. 背景 随着视频采集及传输技术的发展,视频素材的分辨率和帧率在不断提升。分辨率从2K到4K到8K;帧率从30到60到120;新的标准及技术,比如HDR,也不断出现。 素材质量的增长,图像码流量也...

大锤强
04/27
0
0
H.265/HEVC视频编码: FPGA GPU QSV实现对比

1. 背景 随着视频采集及传输技术的发展,视频素材的分辨率和帧率在不断提升。分辨率从2K到4K到8K;帧率从30到60到120;新的标准及技术,比如HDR,也不断出现。 素材质量的增长,图像码流量也...

大锤强
04/27
0
0
AMD 下一代 GPU 架构代号 Polaris

AMD正式透露了代号为Polaris的下一代GPU架构。Polaris是 Graphics Core Next (GCN)架构的第四代,目前AMD显卡如Radeon R9 285和R9 Fury 使用的是 GCN1.2架构。新架构显卡最引入瞩目之处是使用...

oschina
2016/01/06
2.2K
8
Ubuntu 17.10 惬意看片,支持 Intel/AMD 等硬解码

Linux系统在普通消费者中无法流行起来,一大原因就是日常娱乐功能不足,但这一点也在逐渐完善。Canonical近日就透露,即将发布的Ubuntu 17.10将会全面支持GPU视频硬件解码加速。 Ubuntu 17....

达尔文
2017/07/09
3.7K
20
英伟达开源数据增强和数据解码库,解决计算机视觉性能瓶颈

     新智元编译   来源:NVIDIA   编辑:肖琴   【新智元导读】在CVPR 2018大会上,英伟达开源了数据增强库DALI和数据解码库nvJPEG。   在CVPR 2018大会上,英伟达开源了数据增...

深度学习
06/25
0
0
[FFMPEG硬件加速]nvidia方案

<2>方案可行性; H.264 (AVCHD) YUV 4:4:4 H.264 (AVCHD) Lossless H.265 (HEVC) YUV 4:2:0 H.265 (HEVC) YUV 4:4:4 H.265 (HEVC) Lossless H.265 (HEVC) 8k VC-1 H.264(AVCHD) H.265(HEVC)......

weixin_40592935
05/29
0
0
支持电视的 Linux 发行--OpenPCTV

OpenPCTV 是一款支持 DVB-S2 卫星、DVB-C 有线、DVB-T 地面波电脑接收设备(PCI/PCIE/USB)的接收及播放的 Linux 发行版。 功能介绍: 完美支持原汁原味的 CHC HD、CCTV 3/5/6/8 HD 及多个省...

红薯
2013/09/10
3.5K
0
gstreamer 概述以及TX1 硬解码多路RTSP流

以NVIDIA TX1为例硬解码就是利用硬件芯片来解码的,TX1有单独的解码模块,NVDEC. 软解码是用软件程序来解码,比较占用CPU资源 查看cpu gpu 以及编解码模块的使用: sudo ./tegrastats 1.gstr...

csdnhuaong
04/21
0
0
Pandaboard Android硬解码相关问题?

最近一直在搞Pandaboard的硬解码相关的问题,因为我的系统不能硬解码!都是使用的google软解码!而我用Android4.0.4又是硬解码!用Android4.1就软解解闷了!希望得到知道的大牛指点!期待! ...

朱一心
2013/06/05
661
1

没有更多内容

加载失败,请刷新页面

加载更多

下一页

shell中的函数、shell中的数组、告警系统需求分析

shell中的函数 格式: 格式: function f_name() { command } 函数必须要放在最前面 示例1(用来打印参数) 示例2(用于定义加法) 示例3(用于显示IP) shell中的数组 shell中的数组1 定义数...

Zhouliang6
26分钟前
1
0
用 Scikit-Learn 和 Pandas 学习线性回归

      对于想深入了解线性回归的童鞋,这里给出一个完整的例子,详细学完这个例子,对用scikit-learn来运行线性回归,评估模型不会有什么问题了。 1. 获取数据,定义问题     没有...

wangxuwei
48分钟前
0
0
MAC安装MAVEN

一:下载maven压缩包(Zip或tar可选),解压压缩包 二:打开终端输入:vim ~/.bash_profile(如果找不到该文件新建一个:touch ./bash_profile) 三:输入i 四:输入maven环境变量配置 MAVEN_HO...

WALK_MAN
今天
0
0
33.iptables备份与恢复 firewalld的9个zone以及操作 service的操作

10.19 iptables规则备份和恢复 10.20 firewalld的9个zone 10.21 firewalld关于zone的操作 10.22 firewalld关于service的操作 10.19 iptables规则备份和恢复: ~1. 保存和备份iptables规则 ~2...

王鑫linux
今天
1
0
大数据教程(2.11):keeperalived+nginx高可用集群搭建教程

上一章节博主为大家介绍了目前大型互联网项目的系统架构体系,相信大家应该注意到其中很重要的一块知识nginx技术,在本节博主将为大家分享nginx的相关技术以及配置过程。 一、nginx相关概念 ...

em_aaron
今天
0
0
Apache Directory Studio连接Weblogic内置LDAP

OBIEE默认使用Weblogic内置LDAP管理用户及组。 要整理已存在的用户及组,此前办法是导出安全数据,文本编辑器打开认证文件,使用正则表达式获取用户及组的信息。 后来想到直接用Apache Dire...

wffger
今天
2
0
HFS

FS,它是一种上传文件的软件。 专为个人用户所设计的 HTTP 档案系统 - Http File Server,如果您觉得架设 FTP Server 太麻烦,那么这个软件可以提供您更方便的档案传输系统,下载后无须安装,...

garkey
今天
1
0
Java IO类库之BufferedInputStream

一、BufferedInputStream介绍 /** * A <code>BufferedInputStream</code> adds * functionality to another input stream-namely, * the ability to buffer the input and to * sup......

老韭菜
今天
0
0
STM 32 窗口看门狗

http://bbs.elecfans.com/jishu_805708_1_1.html https://blog.csdn.net/a1985831055/article/details/77404131...

whoisliang
昨天
0
0
Dubbo解析(六)-服务调用

当dubbo消费方和提供方都发布和引用完成后,第四步就是消费方调用提供方。 还是以dubbo的DemoService举例 -- 提供方<dubbo:application name="demo-provider"/><dubbo:registry address="z...

青离
昨天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部