文档章节

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

yagerfgcs
 yagerfgcs
发布于 2016/06/26 17:48
字数 811
阅读 37
收藏 0
在调测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 yagerfgcs
static 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 _WIN32
static 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 _WIN32
static 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

© 著作权归作者所有

共有 人打赏支持
yagerfgcs
粉丝 5
博文 34
码字总数 13476
作品 0
南京
技术主管
私信 提问
VLC调试:增加messages.c日志函数,在无vlc_object_t下打印日志

修改源码: 1、在includevlc_messages.h函数中增加代码 2、在srcmiscmessages.c中增加代码 a、定义静态变量,存放vlcobjectt对象 b、在vlcLogSet被调用时,更新spriv值 c、在vlcLogDeinit中清...

筱骏
2016/04/13
0
0
VLC播放器调试经验总结

一、前言 在使用VS学习VLC源码时,可以打断点分析变量数据,跟踪代码流程,方便我们理解源码。但是在定位音视频卡顿、延时等疑难问题时,这一招就不管用了,因为打上断点就会导致实时计算的p...

筱骏
2016/04/12
0
0
EasyPlayer RTSP播放器:一个适用于安防行业的工具利器(EasyPlayer Windows v2.0.17.0709)

EasyPlayer-RTSP-Win播放器最新版本下载:https://github.com/EasyDSS/EasyPlayer-RTSP-Win/releases EasyPlayer项目Github地址:https://github.com/EasyDarwin/EasyPlayer 最近在跟一些做安......

xiejiashu
2017/07/09
0
0
基于VLC的一个播放器

VLC属于Video LAN开源项目组织中的一款全开源的流媒体服务器和多媒体播放器。作为流媒体服务器,VLC跨平台,支持多操作系统和计算机体系结构;作为多媒体播放器,VLC可以播放多种格式的媒体文...

种地瓜
2016/07/04
62
0
vlc相关学习资料汇总及零散技术总结

一、参考资料 官网的编译教程:http://wiki.videolan.org/Win32CompileMSYS 编译的各种问题:http://wiki.videolan.org/Win32CompileMSYSTroubleShooting 已经编译好的各种版本:http://nigh...

筱骏
2016/05/27
0
0

没有更多内容

加载失败,请刷新页面

加载更多

想问一下C++里queue要怎么遍历

如题,想知道怎么遍历<queue>对象的元素? 貌似不能遍历。要么全部pop push一遍,要么换个容器呗。 queue是先进后出的数据类型,只能不断读top()然后再pop()掉。故意把遍历操作隐藏掉了,...

shzwork
昨天
2
0
Ubuntu 18.04.2 LTS nvidia-docker2 : 依赖: docker-ce (= 5:18.09.0~3-0~ubuntu-bionic)

平台:Ubuntu 18.04.2 LTS nvidia-docker2 版本:2.0.3 错误描述:在安装nvidia-docker2的时候报dpkg依赖错误 nvidia-docker2 : 依赖: docker-ce (= 5:18.09.0~3-0~ubuntu-bionic) 先看一下依......

Pulsar-V
昨天
2
0
学习笔记1-goland结构体(struct)

写在前面:若有侵权,请发邮件by.su@qq.com告知。 转载者告知:如果本文被转载,但凡涉及到侵权相关事宜,转载者需负责。请知悉! 本文永久更新地址:https://my.oschina.net/bysu/blog/3036...

不最醉不龟归
昨天
3
0
【转】go get命令使用socket代理

由于某些不可描述的原因,国内使用go get命令安装某些包的时候会超时导致失败,比如net包、sys包、tools包等。第一种解决办法就是自己从git上下载后添加链接到GOPATH中,比如: 1234...

yiduwangkai
昨天
6
0
从上往下打印出二叉树的每个节点,同层节点从左至右打印。

//第一种做法 public class Solution { public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) { ArrayList <Integer> li=new ArrayList<Integer>(); ArrayList <TreeN......

南桥北木
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部