从学龄前开始解读FFMPEG代码 之 AVDictionary结构体以及av_dict_set()相关函数

本文详细介绍了FFMPEG中AVDictionary结构体及其相关函数av_dict_set()的工作原理和使用场景。AVDictionary用于存储键值对,常用于设置视频处理参数。av_dict_set()函数负责插入键值对,其内部实现包括查找、内存管理等操作。文章还探讨了flag标记位的作用,以及AVDictionary在大量条目时的性能问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

开始AVDictionary以及相关函数学习前想说的一些话

首先声明源码是我在github上直接clone并checkout到了4.2的版本。关于这个结构体以及后续的相关函数的说明可能会进行多次添加修改(在阅读源码的整体学习过程中真的随时都有可能更新自己的认知)

从AVDictionary开始

AVDictionary结构体其实是FFmpeg提供的用于存储键值对的结构体,使用该结构体可以用于设置在打开视频文件/视频码流的时候所需要的各项参数,比如probesize(探测读入大小),max_delay(最大时延)等等参数。

该结构体的定义文件在libavutil/dict.h 以及dict.c中。

首先在dict.h中,头文件上来的备注中就指出了AVdictionary的缺点,主要作用以及相关的用法:

/**
 * @file
 * Public dictionary API.
 * @deprecated
 *  AVDictionary is provided for compatibility with libav. It is both in
 *  implementation as well as API inefficient. It does not scale and is
 *  extremely slow with large dictionaries.
 *  It is recommended that new code uses our tree container from tree.c/h
 *  where applicable, which uses AVL trees to achieve O(log n) performance.
 */

/*
* @{
 * Dictionaries are used for storing key:value pairs. To create
 * an AVDictionary, simply pass an address of a NULL pointer to
 * av_dict_set(). NULL can be used as an empty dictionary wherever
 * a pointer to an AVDictionary is required.
 * Use av_dict_get() to retrieve an entry or iterate over all
 * entries and finally av_dict_free() to free the dictionary
 * and all its contents.
 */

AVDictionary主要是为了服务libav相关文件的,在接口以及实现上来说AVDictionary其实效率很低,不提供缩放功能且在大型的字典存储中非常缓慢,所以建议新的代码使用tree.c/h中的存储方式,使用AVL(二叉查找树,一种高度平衡树,任意节点的子树高度差不会超过1)提供了logn级别的查找速度。(tree.c/h中确实提供了一种更好的存储方式AVTreeNode,对于大型字典存储非常好用。

不过对于普通应用场景,其实并不需要太多的参数,所以AVDictionary完全够用。

AVDictianary用于存储 key:value的键值对,创建键值对也可以直接用一个NULL指针传入。如果需要的时候,NULL也可以作为一个空的dictionary。*(用法类似于AVDictionary d = NULL 之后 直接 av_dict_set(&d, “aa”,“bb”,0) )

AVDictianary结构体由一个int类型和一个AVDictianaryEntry指针(数组)类型组成,定义代码在dict.c中:

struct AVDictionary {
   
	int count;
	AVDictionaryEntry *elems;
};

count是用于计数的变量,而AVDictionaryEntry定义则是在dict.h文件中,包含两个字符串(char*类型),这是真正用于存储键值对的结构体

typedef struct AVDictionaryEntry {
   
    char *key;
    char *value;
} AVDictionaryEntry;

从变量名就能看出来,key和value就是键值对的键名和键值,AVDictionary内就存放管理着AVDictionaryEntry

在需要创建并存储一个键值对时,就可以通过av_dict_set方法来将键值对写入到AVDictionary字典当中。

av_dict_set()是干啥的

av_dict_set函数定义在dict.c中,代码如下:

int av_dict_set(AVDictionary **pm, const char *key, const char *value,
                int flags)
{
   
    AVDictionary *m = *pm;
    AVDictionaryEntry *tag = NULL;
    char *oldval = NULL, *copy_key = NULL, *copy_value = NULL;

    if (!(flags & AV_DICT_MULTIKEY)) {
   
        tag = av_dict_get(m, key, NULL, flags);
    }
    if (flags & AV_DICT_DONT_STRDUP_KEY)
        copy_key = (void *)key;
    else
        copy_key = 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值