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;
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的一些概念
沒有留言:
張貼留言