vlc-android 二次开发>>>>>1.如何解决vlc-android 在线播放视频(TCP协议)不流畅的问题

研究VLC-android有一段时间了,昨天在测试vlc-android播放在线视频时,发现特别不流畅,根据播放表现,我觉得是读取网络数据的缓冲(buffer size)过小的原因,但是vlc-android播放视频在android层就一个readmedia接口,并没有设置参数的函数,所以第一反应是通过修改vlc的源代码,然后重新编译库文件,达到修改buffer size的目的。

第一步。。上网查找,遇到有一个人跟我有相似的问题,但是并没有解决方案(事实证明这个人在某种程度上误导了我),于是去google用英文搜 vlc stream buffer ,搜到的都是 PC端的解决办法( TOOLS->preference->ALL->stream_out_put),于是在linux下用grep命令找这个字段(楼主水平有限。。欢迎各位指教更好的方法),最后找到和这个值对应的变量sout-mux-caching,这个变量是在vlc源代码中src/stream_output/stream_output.c中被函数sout_MuxSendBuffer调用的,根据函数名字也可以看出这个是把分离器得到的buffer传送给解码器解码并输出的,sout-mux-caching的大小也就是决定了最后一次性输出画面和声音的时间长度等等(如果有问题欢迎指出)。

于是找到这个变量的默认值,在modules.c中,默认值1500,改成15000后,编译并运行库后发现没有改变,跟没改一样,google直接搜sout-mux-caching,发现有人跟我一样的问题。

随后我想到,可能不是输出buffer的问题,而是缓存buffer的问题,网速太慢导致上一个缓冲区被解码播放后下一个缓冲区还没读满,导致播放不流畅。。

于是我在google里找了一下,发现有一个神奇的东西叫 vlc network caching,这个应该才是我们要找的东西,在tools->preferences->input/codecs里,往下拉,会看到(NM的隐藏这么深)。

用老办法,linux下grep 关键字(windows下可以在搜索栏打content: 加上搜索的内容,效果差不多),用到network-caching的模块就多了,搜索可以发现基本和network input有关的模块都用到这个参数,udp,tcp,ftp,live555等等。。。

然后更狗血的东西出现了

在vlc-android的/jni/libvlcjni中有这么一句话

libvlc_media_add_option(p_md,":network-caching=1500")

这句话是在libvlcjni.c中的newmedia包含的

贴上完整的一段

libvlc_media_t *new_media(jlong instance, JNIEnv *env, jobject thiz, jstring fileLocation, bool noOmx, bool noVideo)
{
    libvlc_instance_t *libvlc = (libvlc_instance_t*)(intptr_t)instance;
    jboolean isCopy;
    const char *psz_location = (*env)->GetStringUTFChars(env, fileLocation, &isCopy);
    libvlc_media_t *p_md = libvlc_media_new_location(libvlc, psz_location);
    (*env)->ReleaseStringUTFChars(env, fileLocation, psz_location);
    if (!p_md)
        return NULL;

    if (!noOmx) {
        jclass cls = (*env)->GetObjectClass(env, thiz);
        jmethodID methodId = (*env)->GetMethodID(env, cls, "useIOMX", "()Z");
        if ((*env)->CallBooleanMethod(env, thiz, methodId)) {
            /*
             * Set higher caching values if using iomx decoding, since some omx
             * decoders have a very high latency, and if the preroll data isn't
             * enough to make the decoder output a frame, the playback timing gets
             * started too soon, and every decoded frame appears to be too late.
             * On Nexus One, the decoder latency seems to be 25 input packets
             * for 320x170 H.264, a few packets less on higher resolutions.
             * On Nexus S, the decoder latency seems to be about 7 packets.
             */
            libvlc_media_add_option(p_md, ":file-caching=4500");
            libvlc_media_add_option(p_md, ":network-caching=1500");
            libvlc_media_add_option(p_md, ":codec=mediacodec,iomx,all");
        }
        if (noVideo)
            libvlc_media_add_option(p_md, ":no-video");
    }
    return p_md;
}

看过源代码都知道readmedia会首先扫描传入地址mLocation,然后用new_media()将传入的多媒体地址映射为一个vlc_media_t实例,最后传到playlist里去播放

于是,修改代码就变得异常简单,不用改源文件了,直接改network-caching为自己想要的值,然后重新编译一遍即可。

改完测试,还是不太尽如人意,不过比以前的好多了。。最后,最好让network-caching和sout-mux-caching的值一致。

啰嗦一句, libvlc_media_add_option(p_md, ":codec=mediacodec,iomx,all");

这句话的意思是把解码方式强制变为iomx吗?

原文地址:https://www.cnblogs.com/Xiegg/p/3312408.html