Libavutil详解:理论与实战

文章目录


前言

libavutil 是一个实用库,用于辅助多媒体编程,本文记录 libavutil 库学习及 demo 例程展示。


一、Libavutil 简介

libavutil 是一个实用库,用于辅助多媒体编程。此库包含安全的可移植字符串函数、随机数生成器、数据结构、附加数学函数、加密和多媒体相关功能(如像素和样本格式的枚举)。

libavcodec 和 libavformat 并不依赖此库。

从 FFmpeg 官网的文档 -libavutil 来看, avutil 主要有以下几种功能:

  • 数学函数
  • 字符串操作
  • 内存管理相关
  • 数据结构相关
  • 错误码及错误处理
  • 日志输出
  • 其他辅助信息,比如密钥、哈希值、宏、库版本、常量等

FFmpeg 中 libavutil 的示例,目前包含:

  • AVLog
  • AVOption (AVClass)
  • AVDictionary
  • ParseUtil

二、AVLog 测试

AVLog 是 FFmpeg(音视频处理库)中的一个日志系统,用于记录和输出日志信息。它提供了一种可配置的方式,使开发者能够根据自己的需求控制日志输出的详细程度和目标。

AVLog 的设计目标是提供一个灵活和可扩展的日志系统,以便在音视频处理过程中记录各种事件、错误和调试信息。它可以用于调试和分析应用程序或库的运行时行为,特别是在处理音视频数据时。

AVLog 提供了多个日志级别,包括:

  • QUIET(静默):最低日志级别,不输出任何日志信息。
  • PANIC(紧急):当发生严重错误时触发,可能导致程序崩溃或不可恢复的错误。
  • FATAL(致命):当发生严重错误时触发,但程序可能还能继续执行。
  • ERROR(错误):记录错误信息,表示发生了一些操作失败或异常情况,但程序仍然可以继续执行。
  • WARNING(警告):记录警告信息,表示发生了一些潜在问题或不符合预期的情况。
  • INFO(信息):记录一般的信息,用于追踪应用程序的运行状态。
  • VERBOSE(详细):记录更详细的信息,用于调试和排查问题。
  • DEBUG(调试):记录详细的调试信息,包括函数调用、变量值等。

1、示例源码

cpp 复制代码
#include <stdio.h>

extern "C" {
    #include "libavcodec/avcodec.h"
    #include "libavformat/avformat.h"
    #include "libavutil/opt.h"
    #include "libavutil/parseutils.h"
    #include "libavutil/avutil.h"
};

void test_log(){
    / av_register_all();
    AVFormatContext *pAVFmtCtx = NULL;
    pAVFmtCtx = avformat_alloc_context();

	printf("====================================\n");
    av_log(pAVFmtCtx,AV_LOG_PANIC, "Panic: Something went really wrong and we will crash now.\n");
    av_log(pAVFmtCtx,AV_LOG_FATAL, "Fatal: Something went wrong and recovery is not possible.\n");
    av_log(pAVFmtCtx,AV_LOG_ERROR, "Error: Something went wrong and cannot losslessly be recovered.\n");
    av_log(pAVFmtCtx,AV_LOG_WARNING, "Warning: This may or may not lead to problems.\n");
    av_log(pAVFmtCtx,AV_LOG_INFO, "Info: Standard information.\n");
    av_log(pAVFmtCtx,AV_LOG_VERBOSE, "Verbose: Detailed information.\n");
    av_log(pAVFmtCtx,AV_LOG_DEBUG, "Debug: Stuff which is only useful for libav* developers.\n");
	printf("====================================\n");

    avformat_free_context(pAVFmtCtx);
}

int main(int argc, char* argv[])
{
    av_log_set_level(AV_LOG_DEBUG);
    test_log();

	return 0;
}
  • avformat_alloc_context():分配一个 AVFormatContext;
  • avformat_free_context():可用于释放上下文以及其中由框架分配的所有内容;
  • av_log():如果 level 小于或等于当前 av_log_level,则将指定的消息发送到日志。默认情况下,所有日志消息都发送到 stderr。可以通过设置不同的日志回调函数来更改此行为。

2、运行结果

bash 复制代码
====================================
====================================
[NULL @ 01e0fc40] Panic: Something went really wrong and we will crash now.
[NULL @ 01e0fc40] Fatal: Something went wrong and recovery is not possible.
[NULL @ 01e0fc40] Error: Something went wrong and cannot losslessly be recovered.
[NULL @ 01e0fc40] Warning: This may or may not lead to problems.
[NULL @ 01e0fc40] Info: Standard information.
[NULL @ 01e0fc40] Verbose: Detailed information.
[NULL @ 01e0fc40] Debug: Stuff which is only useful for libav* developers.

三、AVDictionary 测试

AVDictionary 是 FFmpeg(音视频处理库)中的一个字典结构,用于存储键值对的元数据信息。它提供了一种通用的方式来管理和操作多种类型的元数据,例如音视频流的元数据、编解码器的参数、封装格式的选项等。

AVDictionary 的设计目标是提供一种灵活和可扩展的数据结构,用于表示和传递各种元数据信息。它可以用于读取和写入多种音视频文件格式,并且支持动态添加、修改和查询字典中的元素。

AVDictionary 提供了一系列的函数来对字典进行操作,包括:

  • av_dict_set():向字典中添加或修改键值对。
  • av_dict_get():根据键查询字典中的值。
  • av_dict_count():获取字典中键值对的数量。
  • av_dict_copy():复制一个字典。
  • av_dict_free():释放字典及其内部分配的内存。

除了基本的操作函数外,AVDictionary 还支持迭代器遍历字典中的键值对,以及支持将字典转换为字符串格式进行打印或保存。

1、示例源码

cpp 复制代码
#include <stdio.h>

extern "C" {
    #include "libavcodec/avcodec.h"
    #include "libavformat/avformat.h"
    #include "libavutil/opt.h"
    #include "libavutil/parseutils.h"
    #include "libavutil/avutil.h"
};

void test_avdictionary(){

    AVDictionary *d = NULL;
    AVDictionaryEntry *t = NULL;

    av_dict_set(&d, "name", "zhangsan", 0);
    av_dict_set(&d, "age", "22", 0);
    av_dict_set(&d, "gender", "man", 0);
    av_dict_set(&d, "email", "www@www.com", 0);
    //av_strdup()
    char *k = av_strdup("location");
    char *v = av_strdup("Beijing-China");
    av_dict_set(&d, k, v, AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);

    printf("====================================\n");
    int dict_cnt = av_dict_count(d);
    printf("dict_count:%d\n",dict_cnt);

    printf("dict_element:\n");
    while (t = av_dict_get(d, "", t, AV_DICT_IGNORE_SUFFIX)) {
        printf("key:%10s  |  value:%s\n",t->key,t->value);
    }

    t = av_dict_get(d, "email", t, AV_DICT_IGNORE_SUFFIX);
    printf("email is %s\n",t->value);
    printf("====================================\n");
    av_dict_free(&d);
}

int main(int argc, char* argv[])
{
    test_avdictionary();

	return 0;
}

2、运行结果

bash 复制代码
====================================
dict_count:5
dict_element:
key:      name  |  value:zhangsan
key:       age  |  value:22
key:    gender  |  value:man
key:     email  |  value:www@www.com
key:  location  |  value:Beijing-China
email is www@www.com
====================================

四、ParseUtil 测试

ParseUtil 提供了一些实用的函数和方法,用于解析和转换编解码器参数字符串,以及处理编解码器参数的操作。它主要用于解析编解码器的选项和参数,并将它们转换为适当的数据结构供 FFmpeg 使用。

一些常见的功能和用途包括:

  • 解析编解码器参数:ParseUtil 可以解析编解码器参数字符串,将其拆分为键值对或特定格式的数据。
  • 转换参数数据类型:它可以将参数字符串中的数值或其他特定格式的数据转换为适当的数据类型,如整数、浮点数等。
  • 构建编解码器参数结构:ParseUtil 可以根据解析的结果构建编解码器参数的数据结构,以便在 FFmpeg 中使用。
  • 错误处理:它提供了一些错误处理机制,用于检测和处理无效的参数字符串或错误的参数格式。

1、示例源码

matlab 复制代码
#include <stdio.h>

extern "C" {
    #include "libavcodec/avcodec.h"
    #include "libavformat/avformat.h"
    #include "libavutil/opt.h"
    #include "libavutil/parseutils.h"
    #include "libavutil/avutil.h"
};

void test_parseutil(){
    char input_str[100] = {0};
    printf("========= Parse Video Size =========\n");
    int output_w = 0;
    int output_h = 0;
    strcpy(input_str, "1920x1080");
    av_parse_video_size(&output_w,&output_h,input_str);
    printf("w:%4d | h:%4d\n",output_w,output_h);

    //strcpy(input_str,"vga");//640x480(4:3)
    //strcpy(input_str,"hd1080");//high definition
    strcpy(input_str,"pal");//ntsc(N制720x480), pal(啪制720x576)
    av_parse_video_size(&output_w, &output_h, input_str);
    printf("w:%4d | h:%4d\n",output_w,output_h);


    printf("========= Parse Frame Rate =========\n");
    AVRational output_rational = {0,0};
    strcpy(input_str,"15/1");
    av_parse_video_rate(&output_rational,input_str);
    printf("framerate:%d/%d\n",output_rational.num,output_rational.den);

    strcpy(input_str,"pal");//fps:25/1
    av_parse_video_rate(&output_rational,input_str);
    printf("framerate:%d/%d\n",output_rational.num,output_rational.den);


    printf("=========== Parse Time =============\n");
    int64_t output_timeval;//单位:微妙, 1S=1000MilliSeconds, 1MilliS=1000MacroSeconds
    strcpy(input_str,"00:01:01");
    av_parse_time(&output_timeval,input_str,1);
    printf("microseconds:%lld\n",output_timeval);
    printf("====================================\n");
}

int main(int argc, char* argv[])
{
    test_parseutil();

	return 0;
}
  • av_parse_video_size():用于解析视频大小字符串并将其转换为对应的宽度和高度;
  • av_parse_video_rate():用于解析视频帧率字符串并将其转换为对应的帧率值;
  • av_parse_time():用于解析时间字符串并将其转换为对应的时间值(以微秒为单位)

2、运行结果

bash 复制代码
========= Parse Video Size =========
w:1920 | h:1080
w: 720 | h: 576
========= Parse Frame Rate =========
framerate:15/1
framerate:25/1
=========== Parse Time =============
microseconds:61000000
====================================

我的qq:2442391036,欢迎交流!


相关推荐
OH_TPC1 天前
【鸿蒙优选三方库】@ohos/ffmpeg-kit:把 FFmpeg 的全部能量带进鸿蒙
华为·ffmpeg·harmonyos·鸿蒙
是jin奥1 天前
最新 FFmpeg 安装脚本:Linux x86_64
linux·运维·ffmpeg
骑着蜗牛撵大象3271 天前
用 Codex 批量做数字人商品口播视频:从分镜 JSON 到成片校验的流水线
java·ffmpeg·json·音视频·数字人·视频·codex
企业数字化笔记1 天前
视频加放大特写后音画不同步怎么办?OpenCV转场与FFmpeg音轨续接实战
opencv·ffmpeg·音视频
开开心心就好3 天前
课堂随机点名工具,绿色版免安装双击即用
java·服务器·前端·ffmpeg·音视频·perl·symfony
小鹿软件办公3 天前
不依赖 FFmpeg 也能录屏?ShareX 22 新增录屏等十余款新工具
ffmpeg·sharex·免费录屏工具
lll23526917793 天前
Android APP短视频音频提取,主流工具怎么选
ffmpeg·音视频
成都旺小宝科技4 天前
首访决策人没来,AI一客一策两天成交!
大数据·人工智能·机器学习·ffmpeg·语音识别
余槐i4 天前
加了Cookie yt-dlp仍报HTTP 403:3个容易漏的请求头差异
python·http·ffmpeg·开发工具·yt-dlp
余槐i4 天前
yt-dlp 线程开到 16 反而更慢:1000 个视频的实测与限速原因
性能优化·ffmpeg·自动化·开发工具·yt-dlp