#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");
}