FFmpeg【SDK01】日志和字典的使用

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
日志服务 SLS,月写入数据量 50GB 1个月
简介: FFmpeg中日志功能的使用方法,包括日志级别的设置和AVDictionary的基本操作,同时展示了字符串解析函数如av_parse_video_size、av_parse_video_rate和av_parse_time的应用。
#include <iostream>
#define __STDC_CONSTANT_MACROS

extern "C"
{
    #include <libavutil\log.h>
    #include <libavformat\avformat.h>
    #include <libavutil\parseutils.h>
}
#pragma comment(lib, "avutil.lib")
#pragma comment(lib, "avformat.lib")

// No1. ffmpeg日志使用
void testLog()
{
    // av_register_all();    FFmpeg4.0 以前需要注册所有的输入输出设备
    AVFormatContext *pAVFmtCtx = NULL;
    pAVFmtCtx = avformat_alloc_context();        

    printf("====================================\n");
    /*
        1. av_log 第一个参数avcl, 在解码器中调用可以指向AVCodecContext结构体指针
                                 在格式化上下文中调用可以指向AVFormatContext结构体指针
                                 在FFmpeg内部调用可以设置为NULL
        2. 日志等级默认 >= AV_LOG_INFO
    */

    int avLogLevel = av_log_get_level();    // 获取日志等级
    av_log(pAVFmtCtx, AV_LOG_WARNING, "log default level: %d\n", avLogLevel);

    av_log_set_level(AV_LOG_DEBUG);    // 设置日志等级为Debug

    av_log(pAVFmtCtx, AV_LOG_PANIC, "灾难性的: Something went really wrong and we will crash now.\n");
    av_log(pAVFmtCtx, AV_LOG_FATAL, "失败: Something went wrong and recovery is not possible.\n");
    av_log(pAVFmtCtx, AV_LOG_ERROR, "错误: Something went wrong and cannot losslessly be recovered.\n");
    av_log(pAVFmtCtx, AV_LOG_WARNING, "警告: This may or may not lead to problems.\n");
    av_log(pAVFmtCtx, AV_LOG_INFO, "信息: Standard information.\n");
    av_log(pAVFmtCtx, AV_LOG_VERBOSE, "细节描述: Detailed information.\n");
    av_log(pAVFmtCtx, AV_LOG_DEBUG, "调试: Stuff which is only useful for libav* developers.\n");
    printf("====================================\n");

    avformat_free_context(pAVFmtCtx);
}

// No2. ffmpeg字典基本使用
void testDictionary()
{
    AVDictionary *dict = NULL;                        // 字典
    AVDictionaryEntry *dictEntry = NULL;            // 字典条目

    av_dict_set(&dict, "name", "zhangsan", 0);        // 第四个参数位置(0默认在头部插入)
    av_dict_set(&dict, "age", "22", 0);
    av_dict_set(&dict, "gender", "man", 0);
    av_dict_set(&dict, "email", "www@www.com", 0);

    // 第二种添加方式 av_strdup()
    char *k = av_strdup("location");    // duplication: 复制
    char *v = av_strdup("Beijing-China");
    av_dict_set(&dict, k, v, AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
    // AV_DICT_DONT_STRDUP_KEY 有重复的key不复制(但是在av_dict_free(&d)之前不能修改或释放key,可能会出现未定义)

    printf("====================================\n");
    int dict_cnt = av_dict_count(dict);            // 获取字典个数
    printf("dict_count:%d\n", dict_cnt);

    // 遍历dict            AV_DICT_IGNORE_SUFFIX(忽略后缀)
    printf("dict_element:\n");
    while (dictEntry = av_dict_get(dict, "", dictEntry, AV_DICT_IGNORE_SUFFIX)) {
        printf("key:%10s  |  value:%s\n", dictEntry->key, dictEntry->value);
    }

    // 根据key获取value
    dictEntry = av_dict_get(dict, "email", NULL, AV_DICT_IGNORE_SUFFIX);
    printf("email is %s\n", dictEntry->value);
    printf("====================================\n");
    av_dict_free(&dict);        // 传入二级指针释放内存
}

// No3.ffmpeg字符串解析基本使用
void testParseUtil()
{
    char input_str[100] = { 0 };
    printf("========= Parse Video Size =========\n");        // 根据字符串解析出 Video Size
    int output_w = 0;
    int output_h = 0;
    strcpy(input_str, "1920x1080");                            // 16 : 9
    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");        // 根据分数字符串解析出 num/den 的结构
    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");        // 根据时间字符串解析出 us 值
    int64_t output_timeval;                //单位:us, 1s=1000MilliSeconds, 1ms=1000MacroSeconds
    strcpy(input_str, "00:01:01");
    av_parse_time(&output_timeval, input_str, 1);
    printf("microseconds:%lld\n", output_timeval);
    printf("====================================\n");
}
相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
5月前
|
开发工具
使用FFmpeg4.3.1的SDK官方开发包编译ffmpeg.c(三)
使用FFmpeg4.3.1的SDK官方开发包编译ffmpeg.c(三)
84 0
|
2月前
|
Java Apache 开发工具
【Azure 事件中心】 org.slf4j.Logger 收集 Event Hub SDK(Java) 输出日志并以文件形式保存
【Azure 事件中心】 org.slf4j.Logger 收集 Event Hub SDK(Java) 输出日志并以文件形式保存
|
3天前
|
C++
FFmpeg【SDK02】关于AVIO的一些使用
在C++中使用FFmpeg库处理本地文件和网络流,包括使用AVFormatContext打开和解析文件,自定义AVIO进行读取和定位,以及处理自定义数据源获取视频文件信息。
13 1
|
2月前
|
Java 开发工具
【Azure 事件中心】关闭或开启Azure Event Hub SDK中的日志输出
【Azure 事件中心】关闭或开启Azure Event Hub SDK中的日志输出
|
3月前
|
存储 并行计算 开发工具
SLS Prometheus存储问题之相比客户端SDK聚合写入,SLS网关侧聚合写入有什么优势
SLS Prometheus存储问题之相比客户端SDK聚合写入,SLS网关侧聚合写入有什么优势
|
5月前
|
编解码 IDE 开发工具
使用FFmpeg4.3.1的SDK官方开发包编译ffmpeg.c(一)
使用FFmpeg4.3.1的SDK官方开发包编译ffmpeg.c(一)
46 1
|
5月前
|
开发工具
使用FFmpeg4.3.1的SDK官方开发包编译ffmpeg.c(二)
使用FFmpeg4.3.1的SDK官方开发包编译ffmpeg.c(二)
64 0
|
5月前
|
开发工具 Python
【SLS开源兼容系列】使用ES SDK 访问SLS
本文介绍如何用es sdk访问sls
158 0
|
5月前
|
数据可视化 API 开发工具
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK使用相机日志跟踪功能(C++)
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK使用相机日志跟踪功能(C++)
66 0