FFmpeg之AVHWAccel

这也是ffmpeg解码器中比较重要的一个模块,很多人认识它应该是通过一条命令

ffmpeg -hwaccel cuda -hwaccel_output_format cuda -i input.mp4 -c:v h264_nvenc -b:v 5M output.mp4

命令地址:英伟达ffmpeg

大家可能觉得这就是nvcodec了,后来发现专门还有一个cuvid呢?瞬间不开心了,不知道这两个倒地时什么关系?如果你时看这个问题的,恭喜你来对了。
下面我们就说道说道。
ffmpeg是通过解码起家,所以它内部有很多自己写的软解码器,在这些软解码器的解码过程当中,比如说对于码流中的某些反量化,反变换等操作,把这些操作挪到一块硬件上,这块硬件就是加速设备。
我们可以看看ffmpeg的h264解码器,红框内部的都是h264解码器的加速插件,NVDEC只是其中之一。
在这里插入图片描述
再来看看代码


static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size)
{
    AVCodecContext *const avctx = h->avctx;
  ...
        switch (nal->type) {
        case H264_NAL_IDR_SLICE:
          ...
                if (h->avctx->hwaccel &&
                //这里就进入了加速解码的分支
                    (ret = h->avctx->hwaccel->start_frame(h->avctx, buf, buf_size)) < 0)
                    goto end;
            }
			...
            max_slice_ctx = avctx->hwaccel ? 1 : h->nb_slice_ctx;
            if (h->nb_slice_ctx_queued == max_slice_ctx) {
            //这里进入加速解码的分支中
                if (h->avctx->hwaccel) {
                    ret = avctx->hwaccel->decode_slice(avctx, nal->raw_data, nal->raw_size);
                    h->nb_slice_ctx_queued = 0;
                } else
                    ret = ff_h264_execute_decode_slices(h);
                if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))
                    goto end;
            }
            break;
            ...

这就是hwaccel加速解码的原理,它是在ffmpeg软解码的基础上将一些特定算法加载到硬件上去做。而cuvid是通过ffmpeg第三方插件库的方式去实现的。

可以看看AVHWAccel结构体定义,发现有几个关键的函数指针,这些指针就是你需要去实现的。
可能你又要问了,为什么英伟达解码器要实现两套?
这个问题留给你吧。或者在我博客里面找,一定有的。


/**
 * @defgroup lavc_hwaccel AVHWAccel
 *
 * @note  Nothing in this structure should be accessed by the user.  At some
 *        point in future it will not be externally visible at all.
 *
 * @{
 */
typedef struct AVHWAccel {
    /**
     * Name of the hardware accelerated codec.
     * The name is globally unique among encoders and among decoders (but an
     * encoder and a decoder can share the same name).
     */
    const char *name;

    /**
     * Type of codec implemented by the hardware accelerator.
     *
     * See AVMEDIA_TYPE_xxx
     */
    enum AVMediaType type;

    /**
     * Codec implemented by the hardware accelerator.
     *
     * See AV_CODEC_ID_xxx
     */
    enum AVCodecID id;

    /**
     * Supported pixel format.
     *
     * Only hardware accelerated formats are supported here.
     */
    enum AVPixelFormat pix_fmt;

    /**
     * Hardware accelerated codec capabilities.
     * see AV_HWACCEL_CODEC_CAP_*
     */
    int capabilities;

    /*****************************************************************
     * No fields below this line are part of the public API. They
     * may not be used outside of libavcodec and can be changed and
     * removed at will.
     * New public fields should be added right above.
     *****************************************************************
     */

    /**
     * Allocate a custom buffer
     */
    int (*alloc_frame)(AVCodecContext *avctx, AVFrame *frame);

    /**
     * Called at the beginning of each frame or field picture.
     *
     * Meaningful frame information (codec specific) is guaranteed to
     * be parsed at this point. This function is mandatory.
     *
     * Note that buf can be NULL along with buf_size set to 0.
     * Otherwise, this means the whole frame is available at this point.
     *
     * @param avctx the codec context
     * @param buf the frame data buffer base
     * @param buf_size the size of the frame in bytes
     * @return zero if successful, a negative value otherwise
     */
    int (*start_frame)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size);

    /**
     * Callback for parameter data (SPS/PPS/VPS etc).
     *
     * Useful for hardware decoders which keep persistent state about the
     * video parameters, and need to receive any changes to update that state.
     *
     * @param avctx the codec context
     * @param type the nal unit type
     * @param buf the nal unit data buffer
     * @param buf_size the size of the nal unit in bytes
     * @return zero if successful, a negative value otherwise
     */
    int (*decode_params)(AVCodecContext *avctx, int type, const uint8_t *buf, uint32_t buf_size);

    /**
     * Callback for each slice.
     *
     * Meaningful slice information (codec specific) is guaranteed to
     * be parsed at this point. This function is mandatory.
     * The only exception is XvMC, that works on MB level.
     *
     * @param avctx the codec context
     * @param buf the slice data buffer base
     * @param buf_size the size of the slice in bytes
     * @return zero if successful, a negative value otherwise
     */
    int (*decode_slice)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size);

    /**
     * Called at the end of each frame or field picture.
     *
     * The whole picture is parsed at this point and can now be sent
     * to the hardware accelerator. This function is mandatory.
     *
     * @param avctx the codec context
     * @return zero if successful, a negative value otherwise
     */
    int (*end_frame)(AVCodecContext *avctx);

    /**
     * Size of per-frame hardware accelerator private data.
     *
     * Private data is allocated with av_mallocz() before
     * AVCodecContext.get_buffer() and deallocated after
     * AVCodecContext.release_buffer().
     */
    int frame_priv_data_size;

    /**
     * Called for every Macroblock in a slice.
     *
     * XvMC uses it to replace the ff_mpv_reconstruct_mb().
     * Instead of decoding to raw picture, MB parameters are
     * stored in an array provided by the video driver.
     *
     * @param s the mpeg context
     */
    void (*decode_mb)(struct MpegEncContext *s);

    /**
     * Initialize the hwaccel private data.
     *
     * This will be called from ff_get_format(), after hwaccel and
     * hwaccel_context are set and the hwaccel private data in AVCodecInternal
     * is allocated.
     */
    int (*init)(AVCodecContext *avctx);

    /**
     * Uninitialize the hwaccel private data.
     *
     * This will be called from get_format() or avcodec_close(), after hwaccel
     * and hwaccel_context are already uninitialized.
     */
    int (*uninit)(AVCodecContext *avctx);

    /**
     * Size of the private data to allocate in
     * AVCodecInternal.hwaccel_priv_data.
     */
    int priv_data_size;

    /**
     * Internal hwaccel capabilities.
     */
    int caps_internal;

    /**
     * Fill the given hw_frames context with current codec parameters. Called
     * from get_format. Refer to avcodec_get_hw_frames_parameters() for
     * details.
     *
     * This CAN be called before AVHWAccel.init is called, and you must assume
     * that avctx->hwaccel_priv_data is invalid.
     */
    int (*frame_params)(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx);
} AVHWAccel;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/238416.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

域渗透之Exchange

域内部署Exchange 首先这里环境的话是&#xff1a; DC: win2012 exchange服务器: win2012 exchange 2016首先我们去装win2012虚拟机的时候需要给两个网卡&#xff0c;一个是内网&#xff0c;一个是外网的网卡。 内网的dns设置为域控的IP。 外网就不需要指定ip了。 首先需要…

《码农的噩梦与修电脑的奇幻之旅》

故事从一个充满梦想的码农学习计算机编程开始。他对编写程序充满了热情&#xff0c;认为自己就像是一位能够编织魔法的巫师&#xff0c;能够创造出炫酷的虚拟世界。 然而&#xff0c;这个充满幻想的故事在码农入门的第一天就遭遇了突如其来的挫折。电脑故障了&#xff01;所有…

GPT-4V 在机器人领域的应用

在科技的浩渺宇宙中&#xff0c;OpenAI如一颗璀璨的星辰&#xff0c;于2023年9月25日&#xff0c;以一种全新的方式&#xff0c;向世界揭示了其最新的人工智能力作——GPT-4V模型。这次升级&#xff0c;为其旗下的聊天机器人ChatGPT装配了语音和图像的新功能&#xff0c;使得用…

zabbix6入门到精通(2)宏定义

zabbix6入门到精通&#xff08;2&#xff09;宏定义 https://www.yuque.com/fenghuo-tbnd9/ffmkvs/sipmmw https://www.zabbix.com/documentation/6.0/zh/manual/appendix/macros/supported_by_location 配置— 主机 — 主机名称 — {$CPU.INTERVAL.TIME} CPU评估间隔时间…

Qt Desktop Widgets 控件绘图原理逐步分析拆解

Qt 是目前C语言首选的框架库。之所以称为框架库而不单单是GUI库&#xff0c;是因为Qt提供了远远超过GUI的功能封装&#xff0c;即使不使用GUI的后台服务&#xff0c;也可以用Qt大大提高跨平台的能力。 仅就界面来说&#xff0c;Qt 保持各个平台绘图等效果的统一&#xff0c;并…

Linux常用命令---- test 命令

文章目录 基本语法文件测试检查文件是否存在检查文件是否是目录检查文件是否为空检查文件是否可读、可写或可执行 字符串测试检查字符串是否为空检查字符串是否相等检查字符串是否不相等 数字测试检查数字是否相等检查数字是否大于或小于 在Linux操作系统中&#xff0c;test命令…

Oracle 透明网关安装

Oracle 11g透明网关连接Sqlserver oracle 透明网关是oracle连接异构数据库提供的一种技术。通过Gateway&#xff0c;可以在Oracle里透明的访问其他不同的数据库&#xff0c;如SQL Server, DB2, Sybase等等&#xff0c;就像远程Oracle数据库一样。配置后的sql查询的处理流程&…

数据库中常用的锁

目录 1、数据库中常用的锁类型 2、常见的数据库 3、以MySQL为例 3.1 MySQL的事务 3.2 MySQL事务的四大特性 1. 原子性&#xff08;Atomicity&#xff09; 2. 一致性&#xff08;Consistency&#xff09; 3. 隔离性&#xff08;Isolation&#xff09; ⭐mysql中的事务隔…

容器化升级对服务有哪些影响?

容器技术是近几年计算机领域的热门技术&#xff0c;特别是随着各种云服务的发展&#xff0c;越来越多的服务运行在以 Docker 为代表的容器之内。 本文我们就来分享一下容器化技术相关的知识。 容器化技术简介 相比传统虚拟化技术&#xff0c;容器技术是一种更加轻量级的操作…

程序员考公笔记之逻辑判断(图形推理)

文章目录 写在前面1、逻辑判断1.1、图形推理1.1.1、位置类1.1.2、样式类1.1.3、数量类1.1.4、属性类1.1.5、六面体 写在前面 1、逻辑判断 1.1、图形推理 观察&#xff1a;先宏观&#xff0c;再微观 图形推理的命题形式&#xff1a; 一组式 观察路径&#xff1a;顺序看(考最…

数据结构之优先级队列(堆)及top-k问题讲解

&#x1f495;"哪里会有人喜欢孤独&#xff0c;不过是不喜欢失望。"&#x1f495; 作者&#xff1a;Mylvzi 文章主要内容&#xff1a;数据结构之优先级队列(堆) 一.优先级队列 1.概念 我们已经学习过队列&#xff0c;队列是一种先进先出(FIFO)的数据结构&#xff…

单线圈无刷直流电机驱动芯片选型分析,可应用于笔记本,显卡风散热风扇,变频冷却风扇,打印机风扇等产品上

单线圈无刷直流电机的电机驱动器。 GC1298R/S&#xff0c;GC1262E/S&#xff0c;GC1298R/S&#xff0c;GC1262R/S具有高效的直接PWM控制方式&#xff0c;它可以控制无刷直流电机转速。它集成了最低速度限制模式、可调速度斜率控制模式、软启动模式、风扇转速计、锁保护、自动重…

PGSQL 设置autovacuum

VACUUM和ANALYZE是PostgreSQL 数据库维护最重要的两个操作。 vacuum用于恢复表中“死元组”占用的空间。删除或更新&#xff08;删除后插入&#xff09;记录时&#xff0c;将产生死元组。PostgreSQL不会从表中物理删除旧行&#xff0c;而是在其上放置一个“标记”&#xff0c;以…

java定位系统源码,UWB技术的无线定位系统源码

UWB技术是一种传输速率高&#xff0c;发射功率较低&#xff0c;穿透能力较强并且是基于极窄脉冲的无线技术。UWB最优的应用环境是室内或者相对密闭的空间&#xff0c;有着厘米级的定位精度&#xff0c;不仅可以非常精准地进行位置跟踪&#xff0c;还可以快速地进行数据传输。 智…

DNF 单机联网 搭建教程(附视频)

更多游戏搭建&pvf修改教程请见: DNF教程 注意&#xff1a;请不要将游戏进行商业化&#xff0c;一切后果概不负责。仅供单机&#xff0c;好友之间进行娱乐&#xff01;&#xff01; 注意&#xff1a;请不要将游戏进行商业化&#xff0c;一切后果概不负责。仅供单机&#…

Vue笔记-在axios中的than函数中使用this需要注意的地方

在Vue中&#xff0c;可以使用this关键字来访问到组件中定义的变量。然而&#xff0c;在axios的then函数中&#xff0c;this关键字的作用域会改变&#xff0c;会指向axios对象本身而不是Vue组件实例。因此&#xff0c;不能直接访问到Vue组件中定义的变量。 解决这个问题的一种方…

git入门教程+常用命令

Git入门教程 本文章主要参照视频教程&#xff1a;https://www.bilibili.com/video/BV1FE411P7B3/?spm_id_from333.337.search-card.all.click&vd_source06caf161b187fb3f4c039bc15e238fea 为什么要使用GIT 版本控制是项目、文档迭代的必然要求&#xff0c;所以需要使用…

如何在 IDEA 中设置远程连接服务器开发环境并实现固定地址远程 Linux 环境

文章目录 1. 检查Linux SSH服务2. 本地连接测试3. Linux 安装Cpolar4. 创建远程连接公网地址5. 公网远程连接测试6. 固定连接公网地址7. 固定地址连接测试 本文主要介绍如何在IDEA中设置远程连接服务器开发环境&#xff0c;并结合Cpolar内网穿透工具实现无公网远程连接&#xf…

肥猫游戏报价器|计价器|王者荣耀代练陪练等游戏报价器软件介绍说明

目录 1. 前言2. 软件著作权3. 软件使用说明3.1 进入软件3.2 用户登录3.3 首页3.4 报价器3.4.1 总体介绍3.4.2 王者报价器3.4.3 LOL手游报价器3.4.4 英雄联盟报价器3.4.5 云顶之弈报价器3.4.7 王者水晶报价器3.4.8 和平精英报价器3.4.9 蛋仔派对报价器3.4.10 穿越火线报价器3.4.…

西工大网络空间安全学院计算机系统基础实验二(phase_2下——漫漫深夜过后的黎明!!!)

内存地址内存地址中的数注释指向这块内存的寄存器0xffffd0e8函数phase_2的栈帧0xffffd0e40xffffd0f4函数phase_2的栈帧0xffffd0e00x5655b7b0函数phase_2的栈帧0xffffd0dc0x565566ca函数read_six_numbers的返回地址&#xff0c;函数phase_2的栈帧0xffffd0d80x5655af64旧%ebx的值…