-
通俗理解 编码与解码
-
封装格式:
-
视频封装格式就是将已经编码处理的 视频数据 音频数据以及字幕数据按照一定的方式放到一个文件中.
-
容器--封装
-
严格意义上说,我们通常所说的是视频格式,指的就是视频封装格式
-
编码格式与封装格式的名称有时是一致的,例如MPEG、WMV、DivX、XviD、RM、RMVB等格式,既是编码格式,也是封装格式;有时却不一致,例如MKV是一种能容纳多种不同类型编码的视频、音频及字幕流的“万能”视频封装格式,同样以mkv为扩展名的视频文件,可能封装了不同编码格式的视频数据
-
-
官方说法: Demuxers read a media file and split it into chunks of data (packets).
-
首先我们已经知道 容器是一种文件格式,比图 Mp4等,会包含5种流【音频,视频,字幕,附件,数据】和文件头信息。
-
而packet包,在ffmpeg中代表已经编码好的一个单位的音频或者视频。
-
把不同的流按照某种容器的规则放入容器,这种行为叫做复用(mux)
-
大白话:把视频文件-解码成内存中的数据,用于后面处理。
-
中文翻译:https://blog.csdn.net/qq_18998145/article/details/108535188
-
NVDEC 解码引擎。 通过 NVDECODE API 来访问NVDEC的视频解码功能
-
NVDEC 从视频流中解码出YUV视频帧,这些帧可以直接用cuda来处理。
包括三个部分: Demuxer, Video Parser, and Video Decoder。这三个部分相互独立,可以单独使用。 NVDECODE API 提供了 NVIDIA video parser and NVIDIA video decoder. 另外Video Parser 可以替换其他的视频解析软件(FFMPEG)
使用NVDECODEAPI的步骤:
- Create a CUDA context.
- Query the decode capabilities of the hardware decoder. 查询硬件解码能力
- Create the decoder instance(s). 创建解码器实例
- De-Mux the content (like .mp4). This can be done using third party software like FFMPEG. 读取文件,使用第三方实现,得到视频流。
- Parse the video bitstream using parser provided by NVDECODE API or third-party parser such as FFmpeg 解析视频流
- Kick off the Decoding using NVDECODE API. 开始解码
- Obtain the decoded YUV for further processing 拿到YUV后,进一步处理
- Query the status of the decoded frame 查询解码帧的状态
- 根据8的状态,进一步后处理:inferencing, postprocessing
- If the application needs to display the output: 输出:
- Convert decoded YUV surface to RGBA.
- Map RGBA surface to DirectX or OpenGL texture.
- Draw texture to screen.
- Destroy the decoder instance(s) after the completion of decoding process 析构
- cuvidDestroyVideoParser
- cuvidDestroyDecoder
- Destroy the CUDA context.
/*代码为API中sample的AppDec*/
//1
CUcontext cuContext = NULL;
createCudaContext(&cuContext, iGpu, 0);
//3
FFmpegDemuxer demuxer(szInFilePath);
//3
/*
NvDecoder(CUcontext cuContext,
bool bUseDeviceFrame,
cudaVideoCodec eCodec,
bool bLowLatency = false,
bool bDeviceFramePitched = false,
const Rect *pCropRect = NULL,
const Dim *pResizeDim = NULL,
int maxWidth = 0,
int maxHeight = 0,
unsigned int clkRate = 1000);
注意第二个参数: bUseDeviceFrame 指示 解码后的数据是在cpu上还是在gpu上。
*/
NvDecoder dec(cuContext, false, FFmpeg2NvCodecId(demuxer.GetVideoCodec()), false, false, &cropRect, &resizeDim);
//4
int nVideoBytes = 0
demuxer.Demux(&pVideo, &nVideoBytes);
//5 6
nFrameReturned = dec.Decode(pVideo, nVideoBytes);
//7
uint8_t* pFrame = dec.GetFrame();
// 8 9
状态即为 4中的 nVideoBytes 是否为0。 不为0 正常。
//