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

本次使用的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帧以上的

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FFmpeg软解硬解是两种不同的解码方式。软解是指使用CPU计算进行解码的过程,而硬解则是利用GPU进行解码和渲染的过程。 对于FFmpeg软解,可以通过编译的库里面含有videotoolbox模块来实现硬解,例如在iOS平台上。软解的流程一般是先进行解码,然后将解码出来的数据进行格式转换,再通过软件来渲染显示出来。软解的优点是可以在多种平台上运行,但是当需要同时解码多个视频或者处理复杂的视频时,CPU资源的占用会增加,可能导致卡顿现象。 而FFmpeg硬解,则是利用硬件加速进行解码和渲染。例如,可以调用ffmpeg的dxva2硬解H264/H265图像帧,输入为一帧264/265数据帧,输出为YUV数据,264解码输出为YUV420P,265解码输出为NV12格式。硬解的优点是可以减轻CPU的负担,提高解码和渲染的效率,特别是在处理大量视频或者高分辨率视频时,能够更好地利用GPU的计算能力。 综上所述,FFmpeg软解硬解是两种不同的解码方式,软解使用CPU进行解码和渲染,硬解则利用GPU进行解码和渲染,具体选择哪种方式取决于实际需求和平台支持。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [FFmpeg软解硬解](https://blog.csdn.net/yinshipin007/article/details/131616862)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [ffmpeg+dxva2硬解](https://download.csdn.net/download/lishi_1991/13012092)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [FFmpeg的软、硬解码方式梳理](https://blog.csdn.net/T__zxt/article/details/125008548)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值