av_dict_get,av_dict_set,av_dict_set_int

/**

* Get a dictionary entry with matching key.

*

* The returned entry key or value must not be changed, or it will

* cause undefined behavior.

*

* To iterate through all the dictionary entries, you can set the matching key

* to the null string "" and set the AV_DICT_IGNORE_SUFFIX flag.

*

* @param prev Set to the previous matching element to find the next.

* If set to NULL the first matching element is returned.

* @param key matching key

* @param flags a collection of AV_DICT_* flags controlling how the entry is retrieved

* @return found entry or NULL in case no matching entry was found in the dictionary

*/

AVDictionaryEntry *av_dict_get(const AVDictionary *m, const char *key,const AVDictionaryEntry *prev, int flags);

复制代码
AVDictionaryEntry *av_dict_get(  
    const AVDictionary *m,         // 目标字典  
    const char *key,               // 查找的键  
    const AVDictionaryEntry *prev, // 前一个匹配项(用于遍历)  
    int flags                      // 匹配模式控制标志  
);  

参数详解

  1. ‌**const AVDictionary *m**‌

    • 作用‌:指向待查询的字典对象。
    • 特殊值 ‌:若传入 NULL,函数直接返回 NULL(空字典无条目可查)8。
  2. ‌**const char *key**‌

    • 作用‌:指定要查找的键名。
    • 特殊值 ‌:
      • NULL:按 flags 定义的规则遍历字典中所有条目,忽略具体键名8。
      • 非空字符串:精确匹配键名(受 flags 控制大小写敏感)28。
  3. ‌**const AVDictionaryEntry *prev**‌

    • 作用‌:指向已找到的上一条匹配项,用于遍历字典中的多个条目。
    • 初始调用 ‌:首次调用时传入 NULL,函数返回第一个匹配项。
    • 后续调用 ‌:传入前一次返回的 AVDictionaryEntry 指针,获取下一个匹配项8。
  4. ‌**int flags**‌

    • 作用‌:控制键名匹配规则,支持位掩码组合。
    • 常用标志 ‌:
      • ‌**AV_DICT_MATCH_CASE**‌:严格匹配大小写(默认不区分)。
      • ‌**AV_DICT_IGNORE_SUFFIX**‌:忽略键名后缀(特定场景使用)。
      • 其他标志 ‌:参考 FFmpeg 源码 libavutil/dict.h 中的定义8。

返回值

  • 成功匹配 ‌:返回指向 AVDictionaryEntry 的指针(包含 keyvalue 字段)。
  • 无匹配项 ‌:返回 NULL(遍历结束或无符合条件的条目)28。

使用示例

遍历字典中所有键值对:

复制代码
   AVDictionary *d = NULL;           // "create" an empty dictionary
   AVDictionaryEntry *t = NULL;

   av_dict_set(&d, "foo", "bar", 0); // add an entry

   char *k = av_strdup("key");       // if your strings are already allocated,
   char *v = av_strdup("value");     // you can avoid copying them like this
   av_dict_set(&d, k, v, AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);

   while (t = av_dict_get(d, "", t, AV_DICT_IGNORE_SUFFIX)) {
       <....>                             // iterate over all entries in d
   }
   av_dict_free(&d);

#define AV_DICT_MATCH_CASE 1 /**< Only get an entry with exact-case key match. Only relevant in av_dict_get(). */ 只获取大小写完全匹配的条目。仅在av_dict_get()中相关

#define AV_DICT_IGNORE_SUFFIX 2 /**< Return first entry in a dictionary whose first part corresponds to the search key, ignoring the suffix of the found key string. Only relevant in av_dict_get(). */ 返回字典中的第一个条目,其第一部分对应于搜索关键字,忽略找到的关键字字符串的后缀

#define AV_DICT_DONT_STRDUP_KEY 4 /**< Take ownership of a key that's been allocated with av_malloc() or another memory allocation function. */ 获取通过av_malloc()或其他内存分配函数分配的密钥的所有权

#define AV_DICT_DONT_STRDUP_VAL 8 /**< Take ownership of a value that's been

allocated with av_malloc() or another memory allocation function. */

#define AV_DICT_DONT_OVERWRITE 16 ///< Don't overwrite existing entries.

#define AV_DICT_APPEND 32 /**< If the entry already exists, append to it. Note that no

delimiter is added, the strings are simply concatenated. */

#define AV_DICT_MULTIKEY 64 /**< Allow to store several equal keys in the dictionary */

复制代码
Key: video_codec, Value: h264  
Key: audio_codec, Value: aac  

注意事项

  1. 字典遍历顺序‌:条目返回顺序与插入顺序无关,由内部链表结构决定8。
  2. 线程安全‌:非线程安全,需外部同步控制8。
  3. 指针管理 ‌:返回的 AVDictionaryEntry 指针生命周期与字典对象绑定,释放字典后不可再使用28。

典型应用场景

  • 参数解析‌:从字典中提取 FFmpeg 组件的配置参数(如编解码器参数)。
  • 元数据读取‌:获取媒体文件的元信息(如视频分辨率、音频采样率)。

/**

* Set the given entry in *pm, overwriting an existing entry.

*

* Note: If AV_DICT_DONT_STRDUP_KEY or AV_DICT_DONT_STRDUP_VAL is set,

* these arguments will be freed on error.

*

* Warning: Adding a new entry to a dictionary invalidates all existing entries

* previously returned with av_dict_get.

*

* @param pm pointer to a pointer to a dictionary struct. If *pm is NULL

* a dictionary struct is allocated and put in *pm.

* @param key entry key to add to *pm (will either be av_strduped or added as a new key depending on flags)

* @param value entry value to add to *pm (will be av_strduped or added as a new key depending on flags).

* Passing a NULL value will cause an existing entry to be deleted.

* @return >= 0 on success otherwise an error code <0

*/

int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags);

int av_dict_set(

AVDictionary **pm, // 字典指针的地址

const char *key, // 键名(不可为 NULL)

const char *value, // 值(可为 NULL,用于删除键)

int flags // 操作标志位

);

核心功能

AVDictionary 字典中插入、修改或删除键值对,支持动态内存管理和多种操作模式14。


参数详解

  1. ‌**AVDictionary **pm**

    • 作用 ‌:指向字典指针的地址。若 *pmNULL,函数会自动创建新字典并更新指针。

    • 示例 ‌:

      复制代码

      AVDictionary *dict = NULL;

      av_dict_set(&dict, "key", "value", 0); // 自动创建字典

  2. ‌**const char *key**‌

    • 要求‌:必须为非空字符串,否则函数直接返回错误6。
  3. ‌**const char *value**‌

    • 删除操作 ‌:若设为 NULL,则会删除字典中对应的键值对。
    • 特殊值 ‌:支持 av_dict_set_int 设置整数值
      (如 av_dict_set_int(&dict, "timeout", 6000000, 0))。
  4. ‌**int flags**‌

    • 标志位组合 ‌:
      • ‌**0**‌(默认):覆盖已有键值对。
      • ‌**AV_DICT_MATCH_CASE**‌:键名匹配时区分大小写(默认不区分)。
      • ‌**AV_DICT_APPEND**‌:若键已存在,将新值追加到原值末尾(需确保值为字符串)。
      • ‌**AV_DICT_DONT_OVERWRITE**‌:仅当键不存在时才插入新值。

使用场景

  1. 配置编解码器参数

    AVDictionary *codec_opts = NULL;
    av_dict_set(&codec_opts, "preset", "slow", 0); // 编码预设 av_dict_set(&codec_opts, "crf", "23", 0); // 质量参数

  2. 设置网络协议超时

    AVDictionary *io_opts = NULL;
    av_dict_set_int(&io_opts, "timeout", 6000000, 0); // 6秒超时(单位:微秒)
    avformat_open_input(&fmt_ctx, url, NULL, &io_opts);

  3. 动态调整参数

    av_dict_set(&dict, "threads", "auto", 0); // 自动选择线程数(需协议支持)


内存管理

  • 自动创建与释放 ‌:
    • 首次调用时若 *pmNULL,函数自动分配内存4。
    • 必须通过 av_dict_free() 释放字典内存,避免泄漏5。

常见问题

  1. 参数不生效

    • 单位错误 ‌:如超时参数 timeout 需以微秒为单位(6秒应设为 6000000)78。
    • 未传递字典 ‌:确保将字典指针传递给相关函数(如 avformat_open_input)7。
    • 协议限制‌:部分协议不支持某些参数,需查阅协议文档8。
  2. 特殊值处理

    • 类似 "threads", "auto" 的字符串参数,需依赖 FFmpeg 内部解析逻辑(如 AV_OPT_TYPE_CONST 类型选项)2。

示例代码

复制代码
AVDictionary *dict = NULL;  
av_dict_set(&dict, "video_bitrate", "2000k", 0);  
av_dict_set(&dict, "audio_channels", "2", AV_DICT_DONT_OVERWRITE);  

// 遍历字典(调试用)  
AVDictionaryEntry *entry = NULL;  
while ((entry = av_dict_get(dict, "", entry, AV_DICT_IGNORE_SUFFIX))) {  
    printf("%s: %s\n", entry->key, entry->value);  
}  

av_dict_free(&dict);  // 必须手动释放  

总结

av_dict_set 是 FFmpeg 中管理键值对的核心接口,广泛应用于参数配置与协议控制。使用时需注意内存生命周期、参数单位及标志位语义,避免常见陷阱。

/**

* Convenience wrapper for av_dict_set that converts the value to a string

* and stores it.

*

* Note: If AV_DICT_DONT_STRDUP_KEY is set, key will be freed on error.

*/

int av_dict_set_int(AVDictionary **pm, const char *key, int64_t value, int flags);

av_dict_set_int 函数详解

1. ‌核心功能

av_dict_set_int 是 FFmpeg 提供的便捷接口,用于向 AVDictionary 字典中插入或修改一个 ‌整数值的键值对‌。该函数将整数值自动转换为字符串格式后存储,简化数值型参数的设置流程8。


2. ‌函数定义

int av_dict_set_int( AVDictionary **pm, // 字典指针的地址
const char *key, // 键名(不可为 NULL)
int64_t value, // 需要设置的整数值(64 位)
int flags // 操作标志位 );


3. ‌参数解析
参数 作用
‌**pm**‌ 指向字典指针的地址。若 *pmNULL,函数会自动创建新字典并更新指针28。
‌**key**‌ 键名字符串,不可为 NULL,否则函数直接返回错误58。
‌**value**‌ 待设置的整数值(64 位),如超时时间、分辨率数值等16。
‌**flags**‌ 标志位组合,控制插入或覆盖逻辑(如 0 表示覆盖,AV_DICT_DONT_OVERWRITE 表示仅新增)58。

4. ‌使用场景
  1. 设置网络超时参数

    复制代码

    AVDictionary *options = NULL;
    av_dict_set_int(&options, "timeout", 6000000, 0); // 6 秒超时(单位:微秒) avformat_open_input(&format_ctx, input_url, NULL, &options); // 应用到协议连接

  2. 配置视频参数

    复制代码

    av_dict_set_int(&dict, "video_size", 1920 * 1080, 0); // 设置分辨率标识av_dict_set_int(&dict, "probesize", 100 * 1024, 0); // 设置媒体探测大小

  3. 动态调整编码参数

    复制代码

    av_dict_set_int(&codec_opts, "crf", 23, AV_DICT_DONT_OVERWRITE); // 仅当键不存在时设置


5. ‌注意事项
  • 数值单位 ‌:部分参数(如 timeout)需注意单位(例如微秒 vs 秒)16。
  • 协议兼容性 ‌:不同协议支持的参数可能不同(如 timeout 对 RTSP/HTTP 有效,但文件协议可能无效)1。
  • 字典指针初始化 ‌:首次调用时需确保 pm 指向的指针初始化为 NULL,避免野指针问题27。
  • 内存释放 ‌:必须通过 av_dict_free() 释放字典内存,防止泄漏27。

6. ‌av_dict_set 的区别
特性 av_dict_set_int av_dict_set
值类型 整数值(自动转字符串) 字符串值
适用场景 数值型参数(如超时、分辨率、帧率等)16 字符串型参数(如预设名、协议类型等)35
函数复杂度 底层调用 av_dict_set,封装转换逻辑8 直接操作字符串键值对5

7. ‌示例代码
复制代码

cCopy Code

AVDictionary *dict = NULL; // 设置视频比特率(单位:bps)
av_dict_set_int(&dict, "video_bitrate", 2000000, 0); // 设置音频采样率(单位:Hz) av_dict_set_int(&dict, "sample_rate", 44100, AV_DICT_DONT_OVERWRITE); // 遍历字典验证设置
AVDictionaryEntry *entry = NULL;
while ((entry = av_dict_get(dict, "", entry, 0)))
{
printf("Key: %s → Value: %s\n", entry->key, entry->value);
}

av_dict_free(&dict); // 必须释放内存

输出‌:

Key: video_bitrate → Value: 2000000 Key: sample_rate → Value: 44100


总结

av_dict_set_int 是 FFmpeg 中处理整型参数的高效工具,适用于超时、分辨率、编解码参数等场景。需注意协议兼容性、单位转换及内存管理规则15。

相关推荐
陈奕昆17 分钟前
【LLaMA-Factory实战】Web UI快速上手:可视化大模型微调全流程
前端·ui·llama·大模型微调实战
fhgfyrsg20 分钟前
【无标题】
java
佩奇的技术笔记34 分钟前
Java学习手册:关系型数据库基础
java·数据库·学习
forestsea41 分钟前
Maven 实现多模块项目依赖管理
java·maven
种时光的人1 小时前
【Java多线程】计时器Timer/ScheduledExecutorService的使用
java·开发语言
Jedi Hongbin1 小时前
echarts自定义图表--柱状图-横向
前端·javascript·echarts
会游泳的石头1 小时前
在Java项目中实现本地语音识别与热点检测,并集成阿里云智能语音服务
java·阿里云·语音识别
计算机毕设指导61 小时前
基于Springboot旅游网站系统【附源码】
java·开发语言·spring boot·后端·mysql·spring·旅游
fanTuanye2 小时前
Java 中的 设计模式详解
java·设计模式·工厂模式
3D虚拟工厂2 小时前
1️⃣7️⃣three.js_OrbitControls相机控制器
javascript·3d·vue·blender·three.js·uv