【问题标题】:GpuMat to FFMPEG EncoderGpuMat 到 FFMPEG 编码器
【发布时间】:2020-11-13 11:31:49
【问题描述】:

我正在使用 opencv::cuda 进行一些图像处理,所以我最终得到的是 cv::cuda::GpuMat。我现在想使用 ffmpeg 对其进行编码(因此我可以选择编码器是否进行硬件加速)。现在我想知道我是否可以在不下载的情况下将数据保存在编码器的 GPU 上,因为这似乎是我的应用程序运行多个线程的瓶颈。

我正在使用 Opencv CUDA 调整图像大小,因此我可以下载的东西更少。 (用 sws_scale 调整大小没有区别)

cv::cuda::GpuMat currentFrame;
...
cv::cuda::GpuMat resized;
cv::cuda::resize(currentFrame,resized,cv::Size(width*0.75,height*0.75),0,0,cv::INTER_NEAREST);
cv::Mat frameEnc = cv::Mat(resized);
const int stride[] = { static_cast<int>(frameEnc.step[0]) };
sws_scale(swsctx, &frameEnc.data, stride, 0, frameEnc.rows, avframe->data, avframe->linesize);
ret = avcodec_send_frame(codec, avframe);
if(!ret) {
    /* rescale packet timestamp */
    pkt->duration = 1;
    av_packet_rescale_ts(pkt, codec->time_base, vstrm->time_base);
    /* write packet */
    av_write_frame(outctx, pkt);
}

现在这确实有效并且执行良好,但我真的希望我能做这样的事情:

cv::cuda::GpuMat currentFrame;
...
GpuMatToAvFrame(currentFrame,avframe);
ret = avcodec_send_frame(codec, avframe);
if(!ret) {
    /* rescale packet timestamp */
    pkt->duration = 1;
    av_packet_rescale_ts(pkt, codec->time_base, vstrm->time_base);
    /* write packet */
    av_write_frame(outctx, pkt);
}

avframe 数据也在 gpu 上,因此我不需要下载 GPU-CPU/CPU-GPU 之间的任何传输

【问题讨论】:

    标签: opencv ffmpeg


    【解决方案1】:

    我认为一旦 OpenCV 的问题得到解决,cv::cudacodec::VideoWriter 课程会有所帮助。该类允许您直接编写 GpuMat。但是我相信由于 OpenCV 中的a bug,您无法构建支持此类的 OpenCV。这意味着现在这不是一个很好的解决方案,但将来可能会。

    【讨论】:

      猜你喜欢
      • 2013-10-27
      • 2012-06-15
      • 2021-03-01
      • 2018-09-26
      • 2014-11-18
      • 2013-02-28
      • 2011-04-13
      • 1970-01-01
      • 2019-04-28
      相关资源
      最近更新 更多