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嗎?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM