目录

  • 1、确定解码器类型
  • 2、获取解码器
  • 3、打开解码器
  • 4、进行解码

1、确定解码器类型

单解封装后得到视频流信息,我们可以从第一帧视频(音频)流信息中获取编码格式,从而确定解码器类型。

(1)定位第一帧音视频流信息
使用循环的方式查找,找到后break退出,代码如下:

    int videoStream = -1;int audioStream = -1;for (int i = 0; i < pFormatCtx->nb_streams; i++)    //循环查找视频中包含的流信息,{if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) //视频流{videoStream = i;break;}if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO  && audioStream < 0)    //音频流{audioStream = i;break;}}

pFormatCtx:描述一个媒体文件或媒体流的构成和基本信息结构,代码中解封装得到的变量。
(2)得到音视频流编码信息

    if (videoStream >= 0)pCodecCtx = pFormatCtx->streams[videoStream]->codec;      //查找视频解码器类型if (audioStream >= 0)aCodecCtx = pFormatCtx->streams[audioStream]->codec; ///查找音频解码器类型

2、获取解码器

使用AVCodecID枚举(代码中使用codec_id变量) 获取码流对应的标准,进而选择对应的解码器。

(1)软件解码器 ,使用函数:avcodec_find_decoder,代码如下:

codec_id = pCodecCtx->codec_id;
pCodec = avcodec_find_decoder(codec_id);

(2)硬件解码器(英伟达、英特尔),使用函数:avcodec_find_decoder_by_name,代码如下:

-------- 英伟达 --------:

 codec_id = pCodecCtx->codec_id;char hardWareDecoderName[32] = {0};if (AV_CODEC_ID_H264 == codec_id)sprintf(hardWareDecoderName, "h264_cuvid");else if (AV_CODEC_ID_HEVC == codec_id)sprintf(hardWareDecoderName, "hevc_cuvid");else if (AV_CODEC_ID_MPEG1VIDEO == codec_id)sprintf(hardWareDecoderName, "mpeg1_cuvid");else if (AV_CODEC_ID_MPEG2VIDEO == codec_id)sprintf(hardWareDecoderName, "mpeg2_cuvid");else if (AV_CODEC_ID_MPEG4 == codec_id)sprintf(hardWareDecoderName, "mpeg4_cuvid");

-------- 英特尔 --------:

 codec_id = pCodecCtx->codec_id;char hardWareDecoderName[32] = {0};if (AV_CODEC_ID_H264 == codec_id)sprintf(hardWareDecoderName, "h264_qsv");else if (AV_CODEC_ID_HEVC == codec_id)sprintf(hardWareDecoderName, "hevc_qsv");else if (AV_CODEC_ID_MPEG1VIDEO == codec_id)sprintf(hardWareDecoderName, "mpeg1_qsv");else if (AV_CODEC_ID_MPEG2VIDEO == codec_id)sprintf(hardWareDecoderName, "mpeg2_qsv");else if (AV_CODEC_ID_MPEG4 == codec_id)sprintf(hardWareDecoderName, "mpeg4_qsv");if (strlen(hardWareDecoderName) > 0)pCodec = avcodec_find_decoder_by_name(hardWareDecoderName);

3、打开解码器

使用avcodec_alloc_context3函数创建编码器,avcodec_open2函数打开编码器,代码如下:

     // 配置解码器pCodecCtx = avcodec_alloc_context3(pCodec);          //得到的解码器pCodecCtx->thread_count = 8;      //只有软件解码需要配置,解码线程数pCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;    //指明像素格式//打开解码器if (avcodec_open2(pCodecCtx, pCodec, nullptr) < 0){//返回参数小于0表示编码器打开失败avcodec_close(pCodecCtx);avcodec_free_context(&pCodecCtx);pCodecCtx = nullptr;}

4、进行解码

解码函数如下,参数输入解码前的码流数据,输出为解码后视频帧pFrame(格式为yuv420p,之前解码器配置的类型),以及放回解码结果。

bool decode(uint8_t *inputbuf, int frame_size)
{AVPacket pkt;av_init_packet(&pkt);pkt.data = inputbuf;pkt.size = frame_size;if (avcodec_send_packet(pCodecCtx, &pkt) != 0){av_packet_unref(&pkt);return false;}while (0 == avcodec_receive_frame(pCodecCtx, pFrame));av_packet_unref(&pkt);return true;
}

补充:
前面初始化配置解码器的时候,并没有设置视频的宽高信息。因为h264的每一帧数据都带有编码的信息,当然也包括这些宽高信息了,因此解码完之后,使用pCodecCtx->width, pCodecCtx->height便可以知道视频的宽高是多少。

ffmpeg解码器使用相关推荐

  1. 基于Ffmpeg解码器的简单播放器(a simple audio player based on Ffmpeg)

    这是一个基于Ffmpeg解码器的简单播放器,怎么在Windows上编译Ffmpeg可以在网上找到很多,开发环境是Windows XP SP3+VS2008,其中DirectSound控制单元来自jdk ...

  2. ffmpeg解码器优化

    在以前的视频项目中,用到了几种商业版的H.264解码器.虽然性能稳定,支持DXVA或CUDA,在高清视频播放效果上不错,但是存在一个共同的缺陷-存在帧间延迟.经过我的测算,大概有3帧的缓冲延迟.当帧率 ...

  3. 简单的ffmpeg解码器

    ffmpeg解码过程 相关函数的介绍 该代码将解码前的h264码流和解码后的yuv数据都保存为文件 直接贴代码 /*** 最简单的基于FFmpeg的解码器* Simplest FFmpeg Decod ...

  4. XBMC源代码分析 4:视频播放器(dvdplayer)-解码器(以ffmpeg为例)

    XBMC分析系列文章: XBMC源代码分析 1:整体结构以及编译方法 XBMC源代码分析 2:Addons(皮肤Skin) XBMC源代码分析 3:核心部分(core)-综述 本文我们分析XBMC中视 ...

  5. FFMPEG学习【libavcodec】:编解码器:硬件加速器桥:VDPAU解码器和渲染器

    VDPAU硬件加速有两个模块. 1.VDPAU解码. 2.VDPAU演示. VDPAU解码模块使用FFmpeg解析机制解析所有头,并使用VDPAU进行实际解码. 根据当前的实现,实际的解码和渲染(AP ...

  6. Android NDK开发之旅29 云服务器Ubuntu下搭建NDK环境,并编译FFmpeg

    ###前言 因为在Linux环境下编译FFmpeg生成库和头文件下比较方便,所以接下来主要操作在Linux环境下进行.但是对于Android NDK 开发新手来说,自己电脑配置Ubuntu Linux ...

  7. 【Android FFMPEG 开发】FFMPEG 解码 AVPacket 数据到 AVFrame ( AVPacket-解码器 | 初始化 AVFrame | 解码为 AVFrame 数据 )

    文章目录 I . FFMPEG 解码 AVPacket 数据到 AVFrame 前置操作 II . FFMPEG 解码 AVPacket 数据到 AVFrame 流程 III . FFMPEG 发送 ...

  8. FFmpeg再学习 -- FFmpeg+SDL+MFC实现图形界面视频播放器

    继续看雷霄骅的 课程资料 - 基于FFmpeg+SDL的视频播放器的制作 最后一篇,主要是想学一下 MFC 创建和配置. 一.创建 MFC 工程 文件->新建->项目->Visual ...

  9. ffmpeg的内部Video Buffer管理和传送机制

    本文主要介绍ffmpeg解码器内部管理Video Buffer的原理和过程,ffmpeg的Videobuffer为内部管理,其流程大致为:注册处理函数->帧级释放->帧级申请->清空 ...

  10. GitHub 超 20000 Star,最火开源视频库 FFmpeg 这 20 年!

    [编者按]不知不觉,FFmpeg 已有 20 个年头了.这 20 年总体看来,FFmpeg 如今已非常成功,但期间也有一些波折. 项目发起人 Fabrice Bellard 曾带领部分开发团队脱离 F ...

最新文章

  1. 推荐一个工作流自动化工具
  2. codeforces数学1600day4[贪心数学公式推导CodeForces - 1151D ,思维CodeForces - 1085C,数论同余+组合计数 CodeForces - 1056B]
  3. Struts2的Action和Servlet有什么联系,区别?
  4. eclipse git插件配置
  5. CTFshow php特性 web112
  6. LESSON 9.4 集成算法的参数空间与网格优化
  7. Android开发之Java和Calendar日期上一年,上一个月,前一天,前一周的方法
  8. 树的常见概念,二叉树的性质
  9. SpringBoot和SpringCloud面试题
  10. [转]浅谈php web安全
  11. CSS 动画指南: 原理和实战 (一)
  12. 数据分析之数据预处理、分析建模、可视化
  13. 数字信号处理:时域采样定理与频域采样定理
  14. 理解算法中的时间复杂度,O(1),O(n),O(log2n),O(n^2)
  15. 肇事逃逸人会受到什么处罚
  16. MaskNet 这个CTR模型,有点意思
  17. .[转] 家里有娃娃的请注意,终于把儿歌凑齐了!! 儿歌大全
  18. SAS初学者笔记---001
  19. 中南大学电子信息 单片机_沙漠老师讲专业系列三:电子信息类相关专业解读(1)...
  20. 采购堡垒机时候,选择开源堡垒机还是云堡垒机?

热门文章

  1. 【C语言】游戏管理系统简单设计
  2. spyder python下载_Spyder Python软件-Spyder Python下载-最火软件站
  3. Win制作苹果IOS证书
  4. gaussian 和gaussview_谈谈Gaussian软件中的guess=mix
  5. Android 性能优化 (十一) 电量优化全解析 秒变大神
  6. 图书信息管理系统需求分析
  7. H3C AP当无线路由器静态IP上网配置
  8. 用Aria2加速下载数据集等
  9. dev分支clone时git报错:'origin/dev' is not a commit and a branch 'dev' cannot be created from it
  10. Orcad Capture CIS 绘制原理图库