博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于CUDA的硬编解码
阅读量:4226 次
发布时间:2019-05-26

本文共 2489 字,大约阅读时间需要 8 分钟。

1.硬解码软编码方法:大体流程,先用ffmpeg来读取视频文件的包,接着开启两个线程,一个用于硬解码,一个用于软编码,然后将读取的包传给解码器,编码出的frame download到内存,然后做scale处理,将scale后的帧和编码参数一起传给编码函数,最终生成pkt包,将其写入文件。由于CUVID中CuvideoSource不支持rtsp视频流数据,不能由rtsp地址创建VideoSource,所以用ffmpeg来解析rtsp视频流。
解码与编码之间维护一个队列,队列长度定为20(因为解码速度快于编码速度,数据被覆盖,丢帧)。

2.软解码软编码方法:目前只是用ffmpeg自带的sample功能,没有经过设计,暂时应用sample进行测试。

3.编解码结构
硬解软编:   read(ffmpeg) ---> decoder(NVIDIA) ---> |  Queue(20)  | ---> encoder(ffmpeg)
软解软编:   read(ffmpeg) ---> decoder(ffmpeg) ---> encoder(ffmpeg)

硬解软编基本步骤:
a.利用FFmpeg解析rtsp视频流
b.创建VideoParser
c.利用FFmpeg读取数据包(AVpacket)
d.将数据包传输到VideoParser(AVpacket ---> CUVIDSOURCEDATAPACKET)
e.VideoParser解码数据包

伪代码如下图所示
#include <nvcuvid.h>
#include <cuviddec.h>

//Called when the decoder encounters a video format change or initial sequence header
int CUDAAPI HandleVideoSequence(void * UserData, CUVIDEOFORMAT* pFormat)
{


    cuvidCreateDecoder();
}
//Called by the video parser to decode a single picture
int CUDAAPI HandlePictureDecode(void *UserData, CUVIDPICPARAMS* pPicParams)
{

    cuvidDecodePicture();
}
//Called by the video parser to display a video frame
int CUDAAPI HandlePicutureDisplay(void *UserData, CUVIDPARSERDISPINFO *pPicParams)
{

    cuvidMapVideoFrame();
    cuvidUnmapVideoFrame();
    download_frame(frame);
    queue.enqueue(frame);
}
// new thread read loop, read all frame
void read_loop()
{

    while(av_read_frame(ifmt_ctx,pkt) > 0)
    {

        CUVIDSOURCEDATAPACKET pkt;
        pkt.flags = 0;
        pkt.payload_size = pkt.size;
        pkt.payload = pkt.data;
        cuvidParseVideoData(cuParser, &pkt);
    }
}
//encode thread
void encode_frame()
{

    queue.dequeue(temp_frame);
    scale_frame(temp_frame);
    encode(temp_frame);
    write_to_file();
}
int main()
{

    //set video parser paramters. create video parser
    //decode frame packet
    cuvidCreateVideoParser();
    //FFmpeg open rstp strea, read packet data
    ...
    thread(read_loop);
    thread(encode_frame);
    //destroy resources
    cuvidDestroyDecoder();
    cuvidDestroyVideoParser();
}

4.目前测试的多路是通过开启多个线程来进行的,下面是测试结果:
               
 路数            硬解软编                          软解软编 
          Fps   CPU(%) MEM(%)    Fps  CPU(%) MEM(%)
  1      362      80.8         1.3         344   86.1             0.7
  5        81      92.5     1.3*5            72   92.5         0.7*5
 10    40.5     92.5   1.3*10            36   92.5       0.7*10
 20    20.6     92.5   1.3*20            18   92.5       0.7*20
注释:上面CPU占用率92.5%,CPU空闲都是0,基本CPU在满负荷运行。
需要说明的是,现在测试视频是电影的一个片段10000帧数据,可能运动比较多,如果变成直播可能运动较少,编码会更快。
当硬解码软编码时,如果帧率25fps的时候支持16路,当软解码软编码时,如果帧率25fps的时候支持14路。

5.测试环境以及参数
CPU:  Intel(R) Core(TM) i5-3470 CPU @ 3.20GHz 
MEM:  8G
OS:   ubuntu 12.04
Video:tears640x480p24_1000.y4m(10000frames,rate=1000)
Param:Fps:25,gop:10,bframe:1,rate:40,level 3.1

链接:http://blog.csdn.net/u010264950/article/details/40888517

你可能感兴趣的文章
游戏设计的艺术:一本透镜的书——第十章 某些元素是游戏机制
查看>>
游戏设计的艺术:一本透镜的书——第十一章 游戏机制必须平衡
查看>>
游戏设计的艺术:一本透镜的书——第十二章 游戏机制支撑谜题
查看>>
游戏设计的艺术:一本透镜的书——第十三章 玩家通过界面玩游戏
查看>>
编写苹果游戏中心应用程序(翻译 1.6 获取本地玩家的信息)
查看>>
编写苹果游戏中心应用程序(翻译 1.8 获取本地玩家的好友信息)
查看>>
WebGL自学教程《OpenGL ES 2.0编程指南》翻译——勘误表
查看>>
WebGL自学教程——WebGL示例:13.0 代码整理
查看>>
WebGL自学教程——WebGL示例:14.0 代码整理
查看>>
恶心的社会
查看>>
展现自己的人生智慧
查看>>
osg中使用MatrixTransform来实现模型的平移/旋转/缩放
查看>>
(一) Qt Model/View 的简单说明
查看>>
(二)使用预定义模型 QStringListModel例子
查看>>
UVM:7.4.5 加入存储器
查看>>
UVM:7.5.1 期望值与镜像值
查看>>
UVM:7.5.2 常用操作及其对期望值和镜像值的影响
查看>>
UVM:7.6.1 检查后门访问中hdl 路径的sequence
查看>>
UVM:7.6.2 检查默认值的sequence
查看>>
UVM:7.7.1 使用reg_predictor
查看>>