VLC调试:增加messages.c日志函数,在无vlc_object_t下打印日志

来源:互联网 发布:椅子 孩子写作业 知乎 编辑:程序博客网 时间:2024/05/19 13:58
在调测VLC源码时经常需要借助日志打印其中核心变量、临时变量的值,方便学习和定位问题,但是遇到像src\input\clock.c中的函数,因缺少vlc_object_t *obj对象,无法打印日志。一般可以通过增加函数参数,从调用方传入,本文提供更简单的方法,可以将以下源码加入到工程里即可使用。本文基于vlc-2.2.1.32-2013工程修改,源码目录https://github.com/sunqueen/vlc-2.2.1.32-2013。

      • 修改源码
      • 效果

修改源码:

1、在include\vlc_messages.h函数中增加代码

// add by yagerfgcs:增加msg_Output打印方式VLC_API void vlc_Debug(vlc_object_t *, int,                       const char *, const char *, ...) VLC_FORMAT( 4, 5 );VLC_API void vlc_vaDebug(vlc_object_t *, int,                         const char *, const char *, va_list);#define msg_Output(p_this,...) \    vlc_Debug(VLC_OBJECT(p_this), VLC_MSG_DBG,  MODULE_STRING, __VA_ARGS__ )// end

2、在src\misc\messages.c中增加代码
a、定义静态变量,存放vlc_object_t对象

// add by yagerfgcsstatic libvlc_priv_t *s_priv = NULL;// end 

b、在vlc_LogSet被调用时,更新s_priv值

void vlc_LogSet (libvlc_int_t *vlc, vlc_log_cb cb, void *opaque){    libvlc_priv_t *priv = libvlc_priv (vlc);    if (cb == NULL)    {#ifdef __ANDROID__        cb = AndroidPrintMsg;#else#if defined (HAVE_ISATTY) && !defined (_WIN32)        if (isatty (STDERR_FILENO) && var_InheritBool (vlc, "color"))            cb = PrintColorMsg;        else#endif            cb = PrintMsg;#endif // __ANDROID__        opaque = (void *)(intptr_t)priv->log.verbose;    }    vlc_rwlock_wrlock (&priv->log.lock);    priv->log.cb = cb;    priv->log.opaque = opaque;    vlc_rwlock_unlock (&priv->log.lock);    // add by yagerfgcs for:增加在无vlc_object_t对象的情况下也能调用msg_Output打印debug调试日志    s_priv = priv;    // end    /* Announce who we are */    msg_Dbg (vlc, "VLC media player - %s", VERSION_MESSAGE);    msg_Dbg (vlc, "%s", COPYRIGHT_MESSAGE);    msg_Dbg (vlc, "revision %s", psz_vlc_changeset);    msg_Dbg (vlc, "configured with %s", CONFIGURE_LINE);}

c、在vlc_LogDeinit中清理s_priv

void vlc_LogDeinit (libvlc_int_t *vlc){    libvlc_priv_t *priv = libvlc_priv (vlc);    vlc_rwlock_destroy (&priv->log.lock);    // add by yagerfgcs    s_priv = NULL;    // end}

d、在messages.c文件末尾粘贴以下代码

// add by yagerfgcs:增加在无vlc_object_t对象的情况下也能调用msg_Output打印debug调试日志void vlc_Debug(vlc_object_t *obj, int type, const char *module,    const char *format, ...){    va_list args;    va_start(args, format);    vlc_vaDebug(obj, type, module, format, args);    va_end(args);}#ifdef _WIN32static void Win32DebugOutputMsgnoObj(int, const vlc_log_t *,    const char *, va_list);#endif/*** Emit a log message. This function is the variable argument list equivalent* to vlc_Log().*/void vlc_vaDebug(vlc_object_t *obj, int type, const char *module,    const char *format, va_list args){    /*if (obj != NULL && obj->i_flags & OBJECT_FLAGS_QUIET)        return;*/    /* Get basename from the module filename */    char *p = strrchr(module, '/');    if (p != NULL)        module = p;    p = strchr(module, '.');    size_t modlen = (p != NULL) ? (p - module) : 1;    //    char modulebuf[modlen + 1];    char *modulebuf = (char *)malloc(modlen + 1);           // sunqueen modify    if (p != NULL)    {        memcpy(modulebuf, module, modlen);        modulebuf[modlen] = '\0';        module = modulebuf;    }    /* Fill message information fields */    vlc_log_t msg;    msg.i_object_id = (uintptr_t)obj;    msg.psz_object_type = "generic";    msg.psz_module = module;    msg.psz_header = NULL;    for (vlc_object_t *o = obj; o != NULL; o = o->p_parent)        if (o->psz_header != NULL)        {            msg.psz_header = o->psz_header;            break;        }    /* Pass message to the callback */    // libvlc_priv_t *priv = obj ? libvlc_priv(obj->p_libvlc) : NULL;#ifdef _WIN32    va_list ap;    va_copy(ap, args);    Win32DebugOutputMsgnoObj(type, &msg, format, ap);    va_end(ap);#endif    if (s_priv)     {        vlc_rwlock_rdlock(&s_priv->log.lock);        s_priv->log.cb(s_priv->log.opaque, type, &msg, format, args);        vlc_rwlock_unlock(&s_priv->log.lock);    }    free(modulebuf);}#ifdef _WIN32static void Win32DebugOutputMsgnoObj(int type, const vlc_log_t *p_item,    const char *format, va_list dol){    VLC_UNUSED(p_item);    va_list dol2;    va_copy(dol2, dol);    int msg_len = vsnprintf(NULL, 0, format, dol2);    va_end(dol2);    if (msg_len <= 0)        return;    char *msg = malloc(msg_len + 1 + 1);    if (!msg)        return;    msg_len = vsnprintf(msg, msg_len + 1, format, dol);    if (msg_len > 0){        if (msg[msg_len - 1] != '\n'){            msg[msg_len] = '\n';            msg[msg_len + 1] = '\0';        }        char* psz_msg = NULL;        if (asprintf(&psz_msg, "%s %s%s: %s", p_item->psz_module,            p_item->psz_object_type, msg_type[type], msg) > 0) {            wchar_t* wmsg = ToWide(psz_msg);            OutputDebugStringW(wmsg);            free(wmsg);            free(psz_msg);        }    }    free(msg);}#endif// end by yagerfgcs

3、在需要打印日志的地方调用msg_Output方法即可,以下两种方式都可以。

vlc_object_t *debug = NULL;msg_Output(debug, "AvgInit average_t{i_value[%llu] i_residue[%d] i_count[%d] i_divider[%d]} i_divider[%d]", p_avg->i_value, p_avg->i_residue, p_avg->i_count, p_avg->i_divider, i_divider);
msg_Output(NULL, "ClockData i_ts_buffering[%llu] i_ts_delay[%llu]", i_ts_buffering, i_ts_delay);

效果:

日志效果

备注:如果是VS2010版本的老VLC源码,可以参考http://blog.csdn.net/c_m_deng/article/details/8209310

0 0
原创粉丝点击