FFmpeg API 之 AVDictionary

AVDictionary是FFmpeg中非常常见的类型,在代码中,通常使用它来传递参数或信息。

这里所谓的 “dictionary”,不是指普通的字典,而是指编程语言中,常见的一种 pair 结构,如C++中的map,Python中的字典,json中的键值对指的都是类似的意思。

FFmpeg中的 AVDictionary 是 AVDictionaryEntry 的集合,而 AVDictionaryEntry 则是包含两个字符串字段的结构体(entry:条目,项的意思):

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

当我们需要创建一个新的 AVDictionary 时,仅需要将一个值为 NULL 的 AVDictionary 指针地址传入 av_dict_set() 即可。当我们将 NULL 传递给一个 AVDictionary 类型的实参时,它表示一个空的 dictionary。

使用 av_dict_get() 可以获取 dictionary 中的条目,或者遍历其中所有的条目,然后需要使用 av_dict_free() 函数来释放 dictionary 以及其中的内容。

示例代码如下:

   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);

在操作AVDictionary时,常常需要用到相关的Flag(如示例中所示),其详情如下:

//仅在key完全匹配时才能获取entry,仅用于 av_dict_get()
#define AV_DICT_MATCH_CASE      1  
​
//仅需条目中key开始的部分和传入的 key 相同即可,忽略其后续的部分,仅用于 av_dict_get()
#define AV_DICT_IGNORE_SUFFIX   2  
​
//接管保存在已分配在内存中的 key 的所有权,在后续中负责释放该内存
#define AV_DICT_DONT_STRDUP_KEY 4  
​
//接管保存在已分配在内存中的 value 的所有权,在后续中负责释放该内存
#define AV_DICT_DONT_STRDUP_VAL 8   
​
//不要覆盖已存在的同名entry,即如果没有,则添加,如果有,则不作任何事
#define AV_DICT_DONT_OVERWRITE 16
​
//如果entry已经存在,追加 value,注意,不添加分隔符,仅仅是简单的追加而已
#define AV_DICT_APPEND         32   
​
//允许存储多个相同的 key
#define AV_DICT_MULTIKEY       64

知道了上述内容之后,那么对AVDictionary的操作也就好理解了,其API有:

AVDictionaryEntry *av_dict_get(const AVDictionary *m, const char *key,
                               const AVDictionaryEntry *prev, int flags);
​
/*
    获取符合指定 key 的 entry。
    
    注意:返回的 entry 中的 key 和 value,不能被修改,否则可能会导致错误。
     
    如果想要遍历所有的 entry,那么我们将 key 设置为 “”,然后将 flags 设置为 AV_DICT_IGNORE_SUFFIX。
    
    参数 prev:上一个符合条件的 entry,这样就不会重复返回这个以及之前的符合条件的 entry 了。
    如果传入NULL,则表示需要返回第一个符合条件的 entry。
*/




int av_dict_count(const AVDictionary *m);
​
/*
    返回 dict 中 entry 的数量。
*/



int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags);
​
/*
    添加一个 entry 到 dict,或者覆盖已存在的同名 entry。
    
    注意:如果指定了 AV_DICT_DONT_STRDUP_KEY 或 AV_DICT_DONT_STRDUP_VAL,本函数发生错误时,会对它们进行 free 操作。
    注意:对一个 dict 进行 add 操作,那么从该 dict 之前返回的所有 entry 都将作废,不能再使用。
    
    返回值:成功时大于等于0,失败时返回一个负的错误值。  
*/


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

/*
    针对 int 类型的 value,av_dict_set() 函数的方便版函数。
*/



int av_dict_parse_string(AVDictionary **pm, const char *str,
                         const char *key_val_sep, const char *pairs_sep,
                         int flags);
​
/*
    从 str 解析 key/value 对,然后将解析成功的 entry 加入到 pm。其中 pairs_sep 指定 pair 之间的分割符号,key_value_sep 指定 key 和 value 之间的分割符号。
    
    注意:即使解析失败,pm中仍然存有已经解析成功并加入的entry,此时需要我们手动free这个dict。
    
    注意:flags会忽略 AV_DICT_DONT_STRDUP_KEY 和 AV_DICT_DONT_STRDUP_VAL,因为在这个函数中,所有加入entry的key和value都是被分配空间然后拷贝的,会自动采用这两个flag。
*/




int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags);
​
/*
    将 src 中的entry拷贝到 dst中。
    
    对于 dst 来说,这个操作如同 add 操作,flags指定 add 操作时的行为。
*/




void av_dict_free(AVDictionary **m);
​
/*
    释放 dict。
*/

 

总结一下:AVDirctionary 是一个存储字符串键值对的数据结构,我们可以通过相关的接口来操作它。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值