ffmpeg目录架构与基本框架机制
ffmpeg命令机制分析–参数如何被设置
ffmpeg-日志系统
这里的demo就是根据上面三个链接的内容来仿写的。
这个demo包含了简单的c面向对象的写法,参数的设置,和带颜色输出的日志信息
关键结构体的简单说明:
底层模块结构体,可以理解成子结构体
typedef struct myCodec{
/*模块名字*/
const char *name;
const char *longname;
/*函数指针,指向实际的函数接口*/
void (*myprintf)( struct PCodecContext *codectx);
int (*myadd)(int a,int b);
struct myCodec *next; //建立链表需要用到
int priv_data_size;
const TestClass *priv_class; //指向管理结构体TestClass
}myCodec;
上层结构体,可以理解成父结构体
typedef struct PCodecContext{
const char *name;
struct myCodec *codec; //指向具体的底层模块
void *priv_data;
}PCodecContext;
管理结构体TestClass
typedef struct TestClass{
const char *name; //class的名字
const struct TestOption *option; //指向参数选项结构体
}TestClass;
参数选项结构体
typedef struct TestOption{
const char *name;
const char *help;
int offset; //保存偏移量
enum OptionType type; //参数选项类型
union{
u_int64 i64;
double dle;
const char *str;
}default_val; //默认值
char *unit
}TestOption;
日志信息结构体
typedef struct _LOG_INFO
{
char name[30]; //模块信息
char log[512]; //用户自定义的日志信息
}LOG_INFO;
主程序流程
int main(int argc ,char *argv[])
{
PCodecContext *ctx;
myCodec *dec;
codec_register_all(); //注册,建立链表
ctx = (PCodecContext *)malloc(sizeof(PCodecContext));
ctx->name = "parent codec context";
/*指定模块名字,链表查找匹配,找到之后
*赋值给父结构体的成员ctx->codec
*这样就可以通过父结构体调用底层模块函数
*/
char *name = argv[1];
dec = choose_codec_by_name(name);
ctx->codec = dec;
ctx->priv_data = malloc(dec->priv_data_size);
char *opt = argv[2];
char *value = argv[3];
char *opt_2 = argv[4];
char *val_2 = argv[5];
/*与TestOption建立联系,设置参数*/
*(const TestClass**)ctx->priv_data = dec->priv_class;
opt_set(ctx->priv_data,opt,value,0);
opt_set(ctx->priv_data,opt_2,val_2,0);
/*通过父结构体来调用底层函数*/
ctx->codec->myprintf(ctx);
ctx->codec->myadd(10,20);
free(ctx->priv_data);
ctx->priv_data = NULL;
free(ctx);
ctx = NULL;
}
不同命令的执行效果
代码下载地址:
github:
git clone https://github.com/williamsand/c-Practice
代码目录:c-Practice/c_dmon/obj_c/
执行环境:linux