简体   繁体   English

使用C ++在ffmpeg中解码为特定像素格式

[英]Decoding to specific pixel format in ffmpeg with C++

I need to decode video but my video player only supports RGB8 pixel format. 我需要解码视频,但是我的视频播放器仅支持RGB8像素格式。 So I'm looking into how to do pixel format conversion in the GPU, preferably in the decoding process, but if not possible, after it. 因此,我正在研究如何在GPU中进行像素格式转换,最好是在解码过程中,但如果可能的话,在此之后。

I've found How to set decode pixel format in libavcodec? 我发现如何在libavcodec中设置解码像素格式? which explains how to decode video on ffmpeg to an specific pixel format, as long as it's suported by the codec. 解释了如何将ffmpeg上的视频解码为特定的像素格式,只要它受编解码器支持即可。

Basically, get_format() is a function which chooses, from a list of supported pixel formats from the codec, a pixel format for the decoded video. 基本上, get_format()是从编解码器支持的像素格式列表中选择解码视频的像素格式的函数。 My questions are: 我的问题是:

  1. Is this list of supported codec output formats the same for all computers? 所有计算机支持的编解码器输出格式的列表是否相同? For example, if my codec is for H264, then it will always give me the same list on all computers? 例如,如果我的编解码器适用于H264,那么它将在所有计算机上始终显示相同的列表吗? (assuming same ffmpeg version of all computers) (假设所有计算机的ffmpeg版本相同)
  2. If I choose any of these supported pixel formats, will the pixel format conversion always happen in the GPU? 如果我选择这些受支持的像素格式中的任何一种,像素格式转换是否总是在GPU中进行?
  3. If some of the pixel format conversions won't happen in the GPU, then my question is: does sws_scale() function converts in the GPU or CPU? 如果某些像素格式转换不会在GPU中发生,那么我的问题是: sws_scale()函数在GPU或CPU中转换吗?
  1. It depends. 这取决于。 First, H264 is just a Codec standard. 首先,H264只是编解码器标准。 While libx264 or openh264 are implementing this standard you can guess that each implementation supports different formats. 当libx264或openh264实现此标准时,您可以猜测每种实现都支持不同的格式。 But let's assume (as you did in your question) you are using the same implementation on different machines then yes there might be still cases where different machines support different formats. 但是,让我们假设(就像您在问题中所做的那样)您在不同的机器上使用相同的实现,那么是的,在某些情况下,不同的机器可能会支持不同的格式。 Take H264_AMF for example. 以H264_AMF为例。 You will need an AMD graphics card to use the codec and the supported formats will depend on your graphics card as well. 您将需要AMD显卡才能使用编解码器,支持的格式也将取决于您的显卡。
  2. Decoding will generally happen on your CPU unless you explicitly specify a hardware decoder. 除非您明确指定硬件解码器,否则解码通常会在CPU上进行。 See this example for Hardware decoding: https://github.com/FFmpeg/FFmpeg/blob/release/4.1/doc/examples/hw_decode.c 参见以下示例进行硬件解码: https : //github.com/FFmpeg/FFmpeg/blob/release/4.1/doc/examples/hw_decode.c
    When using Hardware decoding you are heavily relying on your machine. 使用硬件解码时,您严重依赖计算机。 And each Hardware encoder will output their own (proprietary) frame format eg NV12 for a Nvida Graphics Card. 每个硬件编码器都将输出自己的(专有)帧格式,例如用于Nvida图形卡的NV12。 Now comes the tricky part. 现在是棘手的部分。 The encoded frames will remain on your GPU memory which means you might be able to reuse the avframe buffer to do the pixel conversion using OpenCL/GL. 编码的帧将保留在您的GPU内存中,这意味着您可以重新使用avframe缓冲区来使用OpenCL / GL进行像素转换。 But achieving GPU zero-copy when working with different frameworks is not that easy and I don't have enough knowledge to help you there. 但是在使用不同框架时实现GPU零复制并不是那么容易,而且我没有足够的知识来帮助您。 So what I would do is to download the decoded frame from the GPU via av_hwframe_transfer_data like in the example. 因此,我要做的就是像示例中一样通过av_hwframe_transfer_data从GPU下载解码帧。 From this point on it doesn't make much of a difference if you used hardware or software decoding. 从这一点出发,如果您使用硬件或软件解码,它并没有多大区别。
  3. To my knowledge sws_scale isn't using hardware acceleration. 据我所知, sws_scale没有使用硬件加速。 Since it's not accepting "hwframes". 由于它不接受“ hwframe”。 If you want to do color conversion on Hardware Level you might wanna take a look at OpenCV you can use GPUMat there then upload your frame, call cvtColor and download it again. 如果您想在硬件级别上进行颜色转换,您可能GPUMat一下OpenCV,您可以在那里使用GPUMat ,然后上传您的框架,调用cvtColor并再次下载。

Some general remarks: 一些一般性的评论:
Almost any image operation scaling etc. is faster on your GPU, but uploading and downloading the data can take ages. 在您的GPU上,几乎任何图像操作缩放等操作都更快,但是上载和下载数据可能会花费一些时间。 For single operations, it's often not worth using your GPU. 对于单个操作,通常不值得使用GPU。
In your case, I would try to work with CPU decoding and CPU color conversion first. 在您的情况下,我将尝试首先使用CPU解码和CPU颜色转换。 Just make sure to use well threaded and vectorized algorithms like OpenCV or Intel IPP. 只需确保使用良好的线程化和矢量化算法,例如OpenCV或Intel IPP。 If you still lack performance then you can think about Hardware Acceleration. 如果仍然缺乏性能,则可以考虑硬件加速。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM