FFmpeg 头文件完美翻译之 libavdevice 模块

前言

众所周知,FFmpeg 的代码开发上手难度较高,源于官方提供的文档很少有包含代码教程相关的。要想熟练掌握 FFmpeg 的代码库开发,需要借助它的头文件,FFmpeg 把很多代码库教程都写在头文件里面。因此,熟读头文件的内容很重要,为此,我对 FFmpeg 6.x 版本的头文件进行了翻译,方便大家阅读理解。相信我,通读一遍头文件的注释后,你的 FFmpeg 的代码库开发技能将更上一层。

本文适用于有 FFmpeg 代码库开发基础,但想深入熟练使用的同学。

同时也可以参考我的Github 仓库,下载到本地慢慢品读~

libavdevice 模块主要用于处理各种输入输出设备,主要有如下头文件:

  • avdevice.h

avdevice.h

c 复制代码
#ifndef AVDEVICE_AVDEVICE_H
#define AVDEVICE_AVDEVICE_H

#include "version_major.h"
#ifndef HAVE_AV_CONFIG_H
/* 当作为ffmpeg构建的一部分包含时,仅包含主版本号
 * 以避免不必要的重建。当外部包含时,保持包含
 * 完整版本信息。 */
#include "version.h"
#endif

/**
 * @file
 * @ingroup lavd
 * libavdevice API主头文件
 */

/**
 * @defgroup lavd libavdevice
 * 特殊设备复用/解复用库。
 *
 * Libavdevice是@ref libavf "libavformat"的补充库。它
 * 提供各种"特殊"的平台特定复用器和解复用器,例如用于
 * 抓取设备、音频捕获和播放等。因此,libavdevice中的
 * (解)复用器属于AVFMT_NOFILE类型(它们使用自己的I/O函数)。
 * 传递给avformat_open_input()的文件名通常不是指向实际存在
 * 的文件,而是具有一些特殊的设备特定含义 - 例如对于xcbgrab
 * 它是显示名称。
 *
 * 要使用libavdevice,只需调用avdevice_register_all()来注册所有
 * 已编译的复用器和解复用器。它们都使用标准的libavformat API。
 *
 * @{
 */

#include "libavutil/log.h"
#include "libavutil/opt.h"
#include "libavutil/dict.h"
#include "libavformat/avformat.h"

/**
 * 返回LIBAVDEVICE_VERSION_INT常量。
 */
unsigned avdevice_version(void);

/**
 * 返回libavdevice的编译时配置。
 */
const char *avdevice_configuration(void);

/**
 * 返回libavdevice的许可证。
 */
const char *avdevice_license(void);

/**
 * 初始化libavdevice并注册所有输入和输出设备。
 */
void avdevice_register_all(void);

/**
 * 音频输入设备迭代器。
 *
 * 如果d为NULL,返回第一个注册的输入音频/视频设备,
 * 如果d不为NULL,返回d之后的下一个注册的输入音频/视频设备
 * 如果d是最后一个则返回NULL。
 */
const AVInputFormat *av_input_audio_device_next(const AVInputFormat  *d);

/**
 * 视频输入设备迭代器。
 *
 * 如果d为NULL,返回第一个注册的输入音频/视频设备,
 * 如果d不为NULL,返回d之后的下一个注册的输入音频/视频设备
 * 如果d是最后一个则返回NULL。
 */
const AVInputFormat *av_input_video_device_next(const AVInputFormat  *d);

/**
 * 音频输出设备迭代器。
 *
 * 如果d为NULL,返回第一个注册的输出音频/视频设备,
 * 如果d不为NULL,返回d之后的下一个注册的输出音频/视频设备
 * 如果d是最后一个则返回NULL。
 */
const AVOutputFormat *av_output_audio_device_next(const AVOutputFormat *d);

/**
 * 视频输出设备迭代器。
 *
 * 如果d为NULL,返回第一个注册的输出音频/视频设备,
 * 如果d不为NULL,返回d之后的下一个注册的输出音频/视频设备
 * 如果d是最后一个则返回NULL。
 */
const AVOutputFormat *av_output_video_device_next(const AVOutputFormat *d);

typedef struct AVDeviceRect {
    int x;      /**< 左上角x坐标 */
    int y;      /**< 左上角y坐标 */
    int width;  /**< 宽度 */
    int height; /**< 高度 */
} AVDeviceRect;

/**
 * avdevice_app_to_dev_control_message()使用的消息类型。
 */
enum AVAppToDevMessageType {
    /**
     * 空消息。
     */
    AV_APP_TO_DEV_NONE = MKBETAG('N','O','N','E'),

    /**
     * 窗口大小改变消息。
     *
     * 每当应用程序改变设备渲染窗口的大小时,
     * 都会向设备发送消息。
     * 创建窗口后也应立即发送消息。
     *
     * data: AVDeviceRect: 新窗口大小。
     */
    AV_APP_TO_DEV_WINDOW_SIZE = MKBETAG('G','E','O','M'),

    /**
     * 重绘请求消息。
     *
     * 当窗口需要重绘时向设备发送消息。
     *
     * data: AVDeviceRect: 需要重绘的区域。
     *       NULL: 需要重绘整个区域。
     */
    AV_APP_TO_DEV_WINDOW_REPAINT = MKBETAG('R','E','P','A'),

    /**
     * 请求暂停/播放。
     *
     * 应用程序请求暂停/取消暂停播放。
     * 主要用于具有内部缓冲区的设备。
     * 默认情况下设备不会暂停。
     *
     * data: NULL
     */
    AV_APP_TO_DEV_PAUSE        = MKBETAG('P', 'A', 'U', ' '),
    AV_APP_TO_DEV_PLAY         = MKBETAG('P', 'L', 'A', 'Y'),
    AV_APP_TO_DEV_TOGGLE_PAUSE = MKBETAG('P', 'A', 'U', 'T'),

    /**
     * 音量控制消息。
     *
     * 设置音量级别。根据设备的不同,音量可能是按流
     * 或系统范围更改。如果可能,期望按流更改音量。
     *
     * data: double: 新音量范围为0.0 - 1.0。
     */
    AV_APP_TO_DEV_SET_VOLUME = MKBETAG('S', 'V', 'O', 'L'),

    /**
     * 静音控制消息。
     *
     * 更改静音状态。根据设备的不同,静音状态可能是按流
     * 或系统范围更改。如果可能,期望按流更改静音状态。
     *
     * data: NULL。
     */
    AV_APP_TO_DEV_MUTE        = MKBETAG(' ', 'M', 'U', 'T'),
    AV_APP_TO_DEV_UNMUTE      = MKBETAG('U', 'M', 'U', 'T'),
    AV_APP_TO_DEV_TOGGLE_MUTE = MKBETAG('T', 'M', 'U', 'T'),

    /**
     * 获取音量/静音消息。
     *
     * 强制设备分别发送AV_DEV_TO_APP_VOLUME_LEVEL_CHANGED或
     * AV_DEV_TO_APP_MUTE_STATE_CHANGED命令。
     *
     * data: NULL。
     */
    AV_APP_TO_DEV_GET_VOLUME = MKBETAG('G', 'V', 'O', 'L'),
    AV_APP_TO_DEV_GET_MUTE   = MKBETAG('G', 'M', 'U', 'T'),
};

/**
 * avdevice_dev_to_app_control_message()使用的消息类型。
 */
enum AVDevToAppMessageType {
    /**
     * 空消息。
     */
    AV_DEV_TO_APP_NONE = MKBETAG('N','O','N','E'),

    /**
     * 创建窗口缓冲区消息。
     *
     * 设备请求创建窗口缓冲区。具体含义取决于设备
     * 和应用程序。在渲染第一帧之前发送消息,所有一次性
     * 初始化都应在此处完成。
     * 应用程序可以忽略首选的窗口缓冲区大小。
     *
     * @note: 应用程序必须通过AV_APP_TO_DEV_WINDOW_SIZE消息
     *        通知窗口缓冲区大小。
     *
     * data: AVDeviceRect: 窗口缓冲区的首选大小。
     *       NULL: 窗口缓冲区没有首选大小。
     */
    AV_DEV_TO_APP_CREATE_WINDOW_BUFFER = MKBETAG('B','C','R','E'),

    /**
     * 准备窗口缓冲区消息。
     *
     * 设备请求准备用于渲染的窗口缓冲区。
     * 具体含义取决于设备和应用程序。
     * 在渲染每一帧之前发送消息。
     *
     * data: NULL。
     */
    AV_DEV_TO_APP_PREPARE_WINDOW_BUFFER = MKBETAG('B','P','R','E'),

    /**
     * 显示窗口缓冲区消息。
     *
     * 设备请求显示窗口缓冲区。
     * 当新帧准备好显示时发送消息。
     * 通常需要在此消息的处理程序中交换缓冲区。
     *
     * data: NULL。
     */
    AV_DEV_TO_APP_DISPLAY_WINDOW_BUFFER = MKBETAG('B','D','I','S'),

    /**
     * 销毁窗口缓冲区消息。
     *
     * 设备请求销毁窗口缓冲区。
     * 当设备即将被销毁且不再需要窗口缓冲区时
     * 发送消息。
     *
     * data: NULL。
     */
    AV_DEV_TO_APP_DESTROY_WINDOW_BUFFER = MKBETAG('B','D','E','S'),

    /**
     * 缓冲区满状态消息。
     *
     * 设备发出缓冲区溢出/下溢信号。
     *
     * data: NULL。
     */
    AV_DEV_TO_APP_BUFFER_OVERFLOW = MKBETAG('B','O','F','L'),
    AV_DEV_TO_APP_BUFFER_UNDERFLOW = MKBETAG('B','U','F','L'),

    /**
     * 缓冲区可读/可写。
     *
     * 设备通知缓冲区可读/可写。
     * 如果可能,设备会通知可以读/写多少字节。
     *
     * @warning 当可读/写字节数发生变化时,设备可能不会通知。
     *
     * data: int64_t: 可读/写的字节数。
     *       NULL: 可读/写的字节数未知。
     */
    AV_DEV_TO_APP_BUFFER_READABLE = MKBETAG('B','R','D',' '),
    AV_DEV_TO_APP_BUFFER_WRITABLE = MKBETAG('B','W','R',' '),

    /**
     * 静音状态改变消息。
     *
     * 设备通知静音状态已改变。
     *
     * data: int: 0表示非静音状态,非零表示静音状态。
     */
    AV_DEV_TO_APP_MUTE_STATE_CHANGED = MKBETAG('C','M','U','T'),

    /**
     * 音量级别改变消息。
     *
     * 设备通知音量级别已改变。
     *
     * data: double: 新音量范围为0.0 - 1.0。
     */
    AV_DEV_TO_APP_VOLUME_LEVEL_CHANGED = MKBETAG('C','V','O','L'),
};

/**
 * 从应用程序向设备发送控制消息。
 *
 * @param s         设备上下文。
 * @param type      消息类型。
 * @param data      消息数据。具体类型取决于消息类型。
 * @param data_size 消息数据大小。
 * @return >= 0表示成功,负值表示错误。
 *         AVERROR(ENOSYS)表示设备未实现消息处理程序。
 */
int avdevice_app_to_dev_control_message(struct AVFormatContext *s,
                                        enum AVAppToDevMessageType type,
                                        void *data, size_t data_size);

/**
 * 从设备向应用程序发送控制消息。
 *
 * @param s         设备上下文。
 * @param type      消息类型。
 * @param data      消息数据。可以为NULL。
 * @param data_size 消息数据大小。
 * @return >= 0表示成功,负值表示错误。
 *         AVERROR(ENOSYS)表示应用程序未实现消息处理程序。
 */
int avdevice_dev_to_app_control_message(struct AVFormatContext *s,
                                        enum AVDevToAppMessageType type,
                                        void *data, size_t data_size);

/**
 * 描述设备基本参数的结构。
 */
typedef struct AVDeviceInfo {
    char *device_name;                   /**< 设备名称,格式取决于设备 */
    char *device_description;            /**< 人类友好的名称 */
    enum AVMediaType *media_types;       /**< 数组指示设备可以提供哪些媒体类型(如果有)。如果为null,则不能提供任何类型 */
    int nb_media_types;                  /**< media_types数组的长度,如果设备不能提供任何媒体类型则为0 */
} AVDeviceInfo;

/**
 * 设备列表。
 */
typedef struct AVDeviceInfoList {
    AVDeviceInfo **devices;              /**< 自动检测设备列表 */
    int nb_devices;                      /**< 自动检测设备数量 */
    int default_device;                  /**< 默认设备的索引,如果没有默认设备则为-1 */
} AVDeviceInfoList;

/**
 * 列出设备。
 *
 * 返回可用设备名称及其参数。
 *
 * @note: 某些设备可能接受无法自动检测的系统相关设备名称。
 *        不能假定此函数返回的列表始终是完整的。
 *
 * @param s                设备上下文。
 * @param[out] device_list 自动检测设备列表。
 * @return 自动检测设备数量,负值表示错误。
 */
int avdevice_list_devices(struct AVFormatContext *s, AVDeviceInfoList **device_list);

/**
 * 释放avdevice_list_devices()结果的便捷函数。
 *
 * @param device_list 要释放的设备列表。
 */
void avdevice_free_list_devices(AVDeviceInfoList **device_list);

/**
 * 列出设备。
 *
 * 返回可用设备名称及其参数。
 * 这些是avdevice_list_devices()的便捷包装器。
 * 设备上下文在内部分配和释放。
 *
 * @param device           设备格式。如果设置了设备名称,可以为NULL。
 * @param device_name      设备名称。如果设置了设备格式,可以为NULL。
 * @param device_options   填充了设备私有选项的AVDictionary。可以为NULL。
 *                         对于输出设备,相同的选项必须稍后传递给avformat_write_header(),
 *                         对于输入设备,必须传递给avformat_open_input(),或在任何其他
 *                         影响设备私有选项的地方传递。
 * @param[out] device_list 自动检测设备列表
 * @return 自动检测设备数量,负值表示错误。
 * @note 当两者都设置时,device参数优先于device_name。
 */
int avdevice_list_input_sources(const AVInputFormat *device, const char *device_name,
                                AVDictionary *device_options, AVDeviceInfoList **device_list);
int avdevice_list_output_sinks(const AVOutputFormat *device, const char *device_name,
                               AVDictionary *device_options, AVDeviceInfoList **device_list);

/**
 * @}
 */

#endif /* AVDEVICE_AVDEVICE_H */
相关推荐
微帧Visionular1 小时前
AI视频单帧清晰,播放时却闪烁,原因是什么?
人工智能·深度学习·音视频
辰辰观影3 小时前
Windows网盘视频播放器推荐:无广告4K HDR怎么选
音视频
2601_966827455 小时前
电视端云盘在线播放怎么选?支持4K HDR的应用推荐
音视频
开开心心就好6 小时前
音频降噪剪辑工具,音量裁剪一键处理
运维·服务器·前端·spring·ocr·音视频·1024程序员节
zslefour9 小时前
使用ffmpeg遍历获取音频文件相关信息
ffmpeg
AI视频工具指南9 小时前
AI视频的声音和画面怎么配合?先分清谁在传递信息
人工智能·aigc·音视频
辰辰观影11 小时前
无广告播放器推荐来啦
音视频
TrueDei11 小时前
GStreamer 使用 valve 分别控制音视频流的暂停与恢复
音视频
Android系统攻城狮12 小时前
Linux FFmpeg深度解析之avcodec_parameters_from_context调用流程与实战(十六)
linux·运维·ffmpeg·音视频进阶·ffmpeg音视频·车载音视频进阶
一条破秋裤13 小时前
基于 Hi3516CV610 的立定跳远视频测量系统调研与实施方案
arm开发·音视频