FFmpeg解码的软解及硬解(cuda和qsv)使用方法

本文介绍了使用FFmpeg 4.2版本进行视频解码的方法,包括软解码和硬解码(CUDA、QSV)。软解码时,重点讲解了多线程解码的设置和自定义内存管理。对于硬解码,文章详细阐述了CUDA和QSV解码器的创建过程,以及如何处理解码后的硬件加速帧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本次使用的ffmpeg版本是4.2,解码的调用方式为:

int32_t iRet = -1;

// 最后一个包解码完成后,需要取完解码器中剩余的缓存帧;

// 调用avcodec_send_packet时塞空包进去,;

// 解码器就会知道所有包解码完成,再调用avcodec_receive_frame时,将会取出缓存帧;

// AVPacket packet;

// av_init_packet(&packet);

// pkt.data = NULL;

// pkt.size = 0;

// avcodec_send_packet(ctx, pkt);

iRet = avcodec_send_packet(ctx, pkt);

if (iRet != 0 && iRet != AVERROR(EAGAIN)) {

get_ffmepg_err_str(iRet);

if (iRet == AVERROR_EOF)

iRet = 0;

return iRet;

}

while (true) {

// 每解出来一帧,丢到队列中;

iRet = avcodec_receive_frame(ctx, frame);

if (iRet != 0) {

if (iRet == AVERROR(EAGAIN)) {

return 0;

} else

return iRet;

}

PushRenderBuffer();

// 音频解码后,如果需要重采样,也可以在此处进行resample;

}

以前的版本解码方式为:

int32_t iRet = -1;

iRet = avcodec_send_packet(ctx, pkt);

if (iRet != 0 && iRet != AVERROR(EAGAIN)) {

get_ffmepg_err_str(iRet);

if (iRet == AVERROR_EOF)

iRet = 0;

return iRet;

}

avcodec_decode_video2(pCodecCtx, frame, iGotPicture, pkt);

新旧版本更新时,注意接口的使用方法,新版本avcodec_send_packet一次,需要循环调用avcodec_receive_frame多次,返回EAGAIN后,结束当前这次的解码,音频解码也是一样

一、软件解码:

先上一段代码,再做下说明,这是解码视频文件,以AVStream的方式获取文件信息,再创建解码器

int32_t ret = avformat_open_input(&m_pAVFormatIC, pPath, NULL, NULL);

if (avformat_find_stream_info(m_pAVFormatIC, NULL) < 0) {

return;

}

for (uint32_t i = 0; i < m_pAVFormatIC->nb_streams; i++) {

switch (m_pAVFormatIC->streams[i]->codec->codec_type) {

case AVMEDIA_TYPE_VIDEO:

// 视频流;

AVCodec *find_codec = avcodec_find_decoder(m_pAVFormatIC->streams[i]->codec->codec_id);

AVCodecContext *codec_ctx = avcodec_alloc_context3(find_codec);

avcodec_parameters_to_context(codec_ctx, m_pAVFormatIC->streams[i]->codecpar);

codec_ctx->opaque = this;

codec_ctx->thread_count = 5;

codec_ctx->thread_safe_callbacks = 1;

// avcodec_receive_frame的frame数据内存交由自己申请,自己释放,减少内存申请及拷贝;

codec_ctx->get_buffer2 = DemuxStream::CustomFrameAllocBuffer;

avcodec_open2(codec_ctx, find_codec, NULL);

continue;

case AVMEDIA_TYPE_AUDIO:

// 音频流;

// 同上;

continue;

}

}

1、m_pAVFormatIC->streams[i]->codec->codec_type 来判断是否包含音频和视频数据,如果是mp3文件,codec_type有Video是表示MP3的封面图片帧;

2、avcodec_find_decoder和avcodec_alloc_context3创建的指针,不需要覆盖stream中的指针,这是错误的用法,stream只是记录当前文件的流信息,不要用来保存context,创建的context由自己来保管;

3、avcodec_parameters_to_context,一定要做,这是把解析到的留信息设置到context,不需要在自己一个参数一个参数的设置;

4、多线程软解,thread_count不修改的话默认值是1,使用单个线程进行解码,遇到一些大文件,比如4K,30帧以上的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值