2019年9月11日 星期三

vlc-android 筆記

1: 有關於vlc的設定開啟選項, 例如 --disable-x265 可以在compile-libvlc.sh 修改想要的部分


2: https://wiki.videolan.org/AndroidCompile/
    可以加入 sudo apt-get build-dep vlc 安裝所需的vlc source code, 但是得改在GUI下. software的code選項打開.
    此外cmake如果自己更新到最新版, 有可能造成找不到libavcodec, 因為cmake 提供    pkg_check_modules(AVCODEC REQUIRED libavcodec) , 原先是可以找到的, 但是我手動更新cmake版本後, 就找不到了.


3:當頭端為live555作為RTSP server時, 相對應的是在vlc下的live555.cpp 的connect()會新創一個rtsp client

p_sys->rtsp = new (std::nothrow) RTSPClientVlc( *p_sys->env, p_sys->psz_pl_url,
                                     var_InheritInteger( p_demux, "verbose" ) > 1 ? 1 : 0,
                                     "LibVLC/" VERSION, i_http_port, p_sys );

================================================================
#不分哪一層, 所以也許得回上幾層搜尋一下函數
Init(vlc\src\input\input.c,為介面,呼叫不同的註冊函數使用)->
InputSourceNew(input.c)->
InputDemuxNew(input.c)->
demux_NewAdvanced(demux.c)->
vlc_module_load(module掛載完成)

Open(live555.cpp,
          #以下的demux註冊, 會使用到
          p_demux->pf_demux  = Demux;
          p_demux->pf_control= Control;)->
Demux(註冊)->
Connect()->
RTSPClientVlc()->
RTSPClient(RTSPClient.cpp)->
SessionsSetup(可以看到有關於audio/video,h265的一些設定值,比較值得注意的是DEFAULT_FRAME_BUFFER_SIZE 250000,  這邊也判斷是否有得到資料
/* Check if we will receive data from this subsession for
             * this track */
            if( sub->readSource() == NULL ) continue; 

if( !strcmp( sub->mediumName(), "audio" ) ) <---判斷是audio資料
else if( !strcmp( sub->mediumName(), "video" ) )  <---判斷是video資料

   MediaSession::createNew()->MediaSubsessionIterator()->sub->initiate()->MediaSubsession::initiate()(MediaSession.cpp)
)

run(input.c)->MainLoop()->MainLoopDemux()->demux_Demux()->p_demux->pf_demux(live555.cpp的Demux())->getNextFrame(FramedSource.cpp)


open()->Demux()->getNextFrame(FramedSource.cpp,並且註冊StreamRead,並在FramedSource::afterGetting()使用StreamRead函數,
(*(source->fAfterGettingFunc))(source->fAfterGettingClientData,
   source->fFrameSize, source->fNumTruncatedBytes,
   source->fPresentationTime,
   source->fDurationInMicroseconds);

static void StreamRead( void *p_private, unsigned int i_size,
                        unsigned int i_truncated_bytes, struct timeval pts,
                        unsigned int duration )
可以比較一下兩者的參數部分.
)->
doGetNextFrame()->doGetNextFrame(MultiFramedRTPSource.cpp)->
networkReadHandler()(
TaskScheduler::BackgroundHandlerProc* handler
      = (TaskScheduler::BackgroundHandlerProc*)&networkReadHandler;
    fRTPInterface.startNetworkReading(handler);
    而在networkReadHandler()->fillInData(可以看到拿封包這個動作)
                                                 ->storePacket(MultiFramedRTPSource.cpp)
)->
startNetworkReading(RTPInterface.cpp)->
doGetNextFrame1()->
nextPacket->use()(處理可用的網路封包,並且copy一份給自己)->FramedSource::afterGetting(也就是使用StreamRead函數)
->StreamRead()->
es_out_Send()->
EsOutSend(es_out.c)->
input_DecoderDecode()->
vlc_fifo_QueueUnlocked(將block放入fifo)->


es_out_timeshift.c  input_EsOutTimeshiftNew()
    p_out->pf_add     = Add;
    p_out->pf_send    = Send;
    p_out->pf_del     = Del;
    p_out->pf_control = Control;
    p_out->pf_destroy = Destroy;
    p_out->p_sys      = p_sys;

es_out.c   input_EsOutNew()
    out->pf_add     = EsOutAdd;
    out->pf_send    = EsOutSend;
    out->pf_del     = EsOutDel;
    out->pf_control = EsOutControl;
    out->pf_destroy = EsOutDelete;
    out->p_sys      = p_sys;


4:更新live555版本
vim vlc-3.0/contrib/src/live555/rules.mak 修改這裡.
rm -rf vlc/contrib/contrib-android-arm-linux-androideabi/.live555


5: 從上層的
args.add("--network-caching=0");
new LibVLC(this, args); -> nativeNew() -> Java_org_videolan_libvlc_LibVLC_nativeNew(libvlcjni.c) -> libvlc_new(core.c)-> libvlc_InternalInit(libvlc.c)->config_LoadCmdLine(cmdline.c)->vlc_getopt_long(getopt.c)
->


6:處理rtp封包格式
https://tools.ietf.org/html/rfc3550
session.c rtp_seq() rtp_timestamp() 可以拿到rtp協議中的參數

input.c  rtp_stream_thread()可以看到處理stream socket.


7:
share方式:
將finstrument-functions定義時做到test.c
並且用
gcc -g -fPIC -shared test.c -o libtest.so -ldl
然後在vlc下
./configure --prefix=/home/zinwell/samba/vlc_bin --enable-gprof --libdir=/home/zinwell/samba/test/ CFLAGS="-g -ldl -export-dynamic" CXXFLAGS="-g -ldl -export-dynamic"
然後執行
LD_PRELOAD=/home/zinwell/samba/test/libtest.so ./vlc rtsp://192.168.70.25:8554/test2.ts

https://drive.google.com/file/d/1cNq_7sUVxhT8mG_zg6b0vSf-asn7Vn9V/view?usp=sharing



8:
vlc-android的live555.cpp(vlc-android\vlc\modules\access)是使用到
vlc-android\vlc\contrib\contrib-android-arm-linux-androideabi\live555\liveMedia
下的source code.


9:
h265 video處理函數:
mediacodec.c  OutThread()  decoder_QueueVideo(p_dec, p_pic); ->
decoder.c  DecoderQueueVideo() 


10:
vlc-android\vlc\modules\access\live555.cpp 透過
class RTSPClientVlc : public RTSPClient 繼承的方式取得
vlc\contrib\contrib-android-arm-linux-androideabi\live555\liveMedia\RTSPClient.cpp的code使用
並且也可以參考
vlc\contrib\contrib-android-arm-linux-androideabi\live555\testProgs\testRTSPClient.cpp
學習如何使用RTSPClient
這裡可以看到vlc是如何使用到live555 source code.


11:
mediacodec_ndk.c 這裡處理了codec相關的東西, 直接呼叫到android-ndk-r18b裡面的libmediandk.so


12:
mediacodec.c
decoder_QueueVideo(p_dec, p_pic);
可以看出將pic放入videoqueue

vlc-android\vlc\src\input\decoder.c  DecoderPlayVideo()  vout_PutPicture() 將pic放入buffer.
vlc\src\video_output\video_output.c  ThreadDisplayPreparePicture()  picture_fifo_Pop() 將pic取出


13:參考文件
https://wiki.videolan.org/Hacker_Guide/Video_Output/
說明了ㄧ些有關於video output的相關函數.

https://wiki.videolan.org/Hacker_Guide/Audio_Output/
audio 的相關函數

https://wiki.videolan.org/Documentation:VLC_Modules_Loading/
vlc load modules的一些所需的參數,概念

https://wiki.videolan.org/Hacker_Guide/
開發者必須看過一遍, 基本概念.

https://wiki.videolan.org/Hacker_Guide/How_To_Write_a_Module/
有關於module開發的一些觀念

https://www.kshuang.xyz/doku.php/programming:c:socket
有關於socket的一些概念

沒有留言:

張貼留言