RTMPdump原始碼分析: 處理各種訊息(Message)(10)
函式呼叫結構圖
RTMPDump (libRTMP)的整體的函式呼叫結構圖如下圖所示。
詳細分析
已經連續寫了一系列的部落格了,其實大部分內容都是去年搞RTMP研究的時候積累的經驗,回顧一下過去的知識,其實RTMPdump(libRTMP)主要的功能也都分析的差不多了,現在感覺還需要一些查漏補缺。主要就是它是如何處理各種訊息(Message)的這方面還沒有研究的特明白,在此需要詳細研究一下。再來看一下RTMPdump(libRTMP)的“靈魂”函式RTMP_ClientPacket(),主要完成了各種訊息的處理。
-
//處理接收到的資料
- int
- RTMP_ClientPacket(RTMP *r, RTMPPacket *packet)
- {
- int bHasMediaPacket = 0;
- switch (packet->m_packetType)
- {
- //RTMP訊息型別ID=1,設定塊大小
- case 0x01:
- /* chunk size */
- //----------------
-
r->dlg->AppendCInfo("處理收到的資料。訊息 Set Chunk Size (typeID=1)。");
- //-----------------------------
- RTMP_LogPrintf("處理訊息 Set Chunk Size (typeID=1)\n");
- HandleChangeChunkSize(r, packet);
- break;
- //RTMP訊息型別ID=3,致謝
- case 0x03:
- /* bytes read report */
-
RTMP_Log(RTMP_LOGDEBUG, "%s, received: bytes read report", __FUNCTION__);
- break;
- //RTMP訊息型別ID=4,使用者控制
- case 0x04:
- /* ctrl */
- //----------------
- r->dlg->AppendCInfo("處理收到的資料。訊息 User Control (typeID=4)。");
- //-----------------------------
- RTMP_LogPrintf("處理訊息 User Control (typeID=4)\n");
- HandleCtrl(r, packet);
- break;
- //RTMP訊息型別ID=5
- case 0x05:
- /* server bw */
- //----------------
- r->dlg->AppendCInfo("處理收到的資料。訊息 Window Acknowledgement Size (typeID=5)。");
- //-----------------------------
- RTMP_LogPrintf("處理訊息 Window Acknowledgement Size (typeID=5)\n");
- HandleServerBW(r, packet);
- break;
- //RTMP訊息型別ID=6
- case 0x06:
- /* client bw */
- //----------------
- r->dlg->AppendCInfo("處理收到的資料。訊息 Set Peer Bandwidth (typeID=6)。");
- //-----------------------------
- RTMP_LogPrintf("處理訊息 Set Peer Bandwidth (typeID=6)\n");
- HandleClientBW(r, packet);
- break;
- //RTMP訊息型別ID=8,音訊資料
- case 0x08:
- /* audio data */
- /*RTMP_Log(RTMP_LOGDEBUG, "%s, received: audio %lu bytes", __FUNCTION__, packet.m_nBodySize); */
- HandleAudio(r, packet);
- bHasMediaPacket = 1;
- if (!r->m_mediaChannel)
- r->m_mediaChannel = packet->m_nChannel;
- if (!r->m_pausing)
- r->m_mediaStamp = packet->m_nTimeStamp;
- break;
- //RTMP訊息型別ID=9,視訊資料
- case 0x09:
- /* video data */
- /*RTMP_Log(RTMP_LOGDEBUG, "%s, received: video %lu bytes", __FUNCTION__, packet.m_nBodySize); */
- HandleVideo(r, packet);
- bHasMediaPacket = 1;
- if (!r->m_mediaChannel)
- r->m_mediaChannel = packet->m_nChannel;
- if (!r->m_pausing)
- r->m_mediaStamp = packet->m_nTimeStamp;
- break;
- //RTMP訊息型別ID=15,AMF3編碼,忽略
- case 0x0F: /* flex stream send */
- RTMP_Log(RTMP_LOGDEBUG,
- "%s, flex stream send, size %lu bytes, not supported, ignoring",
- __FUNCTION__, packet->m_nBodySize);
- break;
- //RTMP訊息型別ID=16,AMF3編碼,忽略
- case 0x10: /* flex shared object */
- RTMP_Log(RTMP_LOGDEBUG,
- "%s, flex shared object, size %lu bytes, not supported, ignoring",
- __FUNCTION__, packet->m_nBodySize);
- break;
- //RTMP訊息型別ID=17,AMF3編碼,忽略
- case 0x11: /* flex message */
- {
- RTMP_Log(RTMP_LOGDEBUG,
- "%s, flex message, size %lu bytes, not fully supported",
- __FUNCTION__, packet->m_nBodySize);
- /*RTMP_LogHex(packet.m_body, packet.m_nBodySize); */
- /* some DEBUG code */
- #if 0
- RTMP_LIB_AMFObject obj;
- int nRes = obj.Decode(packet.m_body+1, packet.m_nBodySize-1);
- if(nRes < 0) {
- RTMP_Log(RTMP_LOGERROR, "%s, error decoding AMF3 packet", __FUNCTION__);
- /*return; */
- }
- obj.Dump();
- #endif
- if (HandleInvoke(r, packet->m_body + 1, packet->m_nBodySize - 1) == 1)
- bHasMediaPacket = 2;
- break;
- }
- //RTMP訊息型別ID=18,AMF0編碼,資料訊息
- case 0x12:
- /* metadata (notify) */
- RTMP_Log(RTMP_LOGDEBUG, "%s, received: notify %lu bytes", __FUNCTION__,
- packet->m_nBodySize);
- //處理元資料,暫時註釋
- /*
- if (HandleMetadata(r, packet->m_body, packet->m_nBodySize))
- bHasMediaPacket = 1;
- break;
- */
- //RTMP訊息型別ID=19,AMF0編碼,忽略
- case 0x13:
- RTMP_Log(RTMP_LOGDEBUG, "%s, shared object, not supported, ignoring",
- __FUNCTION__);
-
相關推薦
RTMPdump原始碼分析: 處理各種訊息(Message)(10)
函式呼叫結構圖 RTMPDump (libRTMP)的整體的函式呼叫結構圖如下圖所示。 詳細分析 已經連續寫了一系列的部落格了,其實大部分內容都是去年搞RTMP研究的時候積累的經驗,回顧一下過去的知識,其實RTMPdump(libRT
RTMPdump(libRTMP) 原始碼分析 8: 傳送訊息(Message)
=====================================================RTMPdump(libRTMP) 原始碼分析系列文章:=====================================================函式呼叫
JUC原始碼分析-執行緒池篇(一):ThreadPoolExecutor
在多執行緒程式設計中,任務都是一些抽象且離散的工作單元,而執行緒是使任務非同步執行的基本機制。隨著應用的擴張,執行緒和任務管理也變得非常複雜,為了簡化這些複雜的執行緒管理模式,我們需要一個“管理者”來統一管理執行緒及任務分配,這就是執行緒池。本章開始,我們將逐個分析 JUC
JavaScript案例分析:圖片庫改進版(2)
1.優化 showPic函式中裡仍存在一些需要處理的假設 ①檢查title屬性是否存在,可以測試它是否為null var text=whichpic.getAttribute("title")?whichpic.get
嵌入式BootLoader分析:U-Boot簡介(二)
概述 ARM處理器的晶片商很多,所以每種晶片的開發板都有自己相應的BootLoader。其中,U-Boot(Universal BootLoader)稱為通用BootLoader,是目前開發嵌入式系統引導程式碼使用最廣泛的,如今已成為ARM平臺事實上額標準Boo
python資料分析:內容資料化運營(下)——基於多項式貝葉斯增量學習分類文字
案例背景及資料 見上一篇 案例實現 匯入模組 import re import tarfile import os import numpy as np from bs4 import BeautifulSoup from sklearn.feature_extracti
python資料分析:內容資料化運營(中)——基於潛在狄利克雷分配(LDA)的內容主體挖掘
案例背景 本案例是從一堆新聞檔案中建立相應的主題模型,然後得到不同模型的主題特點,並通過對新文字資料集的預測得到其可能的主題分類。 相關知識 TF-IDF TF-IDF(term frequency–inverse document frequency)是一種針對關鍵字的
python資料分析:內容資料化運營(上)——知識點
何為資料化運營 內容運營是指基於內容的策劃、編輯、釋出、優化、營銷等一系列工作,主要集中在網際網路、媒體等以內容為主的行業領域。內容運營根據內容生產方式的不同可分為UGC、PGC和OGC三種。 UGC(User-generated Content),使用者生產內容。這是論
python資料分析:流量資料化運營(下)——基於自動K值得KMeans廣告效果聚類分析
案例背景 某企業由於投放的廣告渠道比較多,需要對其做廣告效果分析以實現有針對性的廣告效果測量和優化工作。跟以應用為目的的案例不同的是,由於本案例是一個分析型案例,該過程的輸出其實是不固定的,因此需要跟業務運營方具體溝通需求。 以下是在開展研究之前的基本預設條件: 廣告渠道
python資料分析:流量資料化運營(中)——流量資料波動原因下探分析
從細分到多層下鑽資料分析 細分是網站分析的基本方法,也是資料分析的基本思路。細分分析的過程是對整體資料進行層層拆分,然後找到影響整體的區域性因素。 步驟1:全站流量按來源模組可細分為廣告、SEM、SEO和直接輸入(假設只有4個模組)。細分發現廣告是網站流量的主要來源(昨日訪問量佔比
python資料分析:流量資料化運營(上)——知識點
流量資料化運營 流量值從數字裝置上訪問企業的網站、app應用、智慧裝置的使用者行為,它主要包括使用者從哪裡來,在企業相關載體上有哪些行為、產生了哪些轉化等。 媒體資訊時代,使用者行為移動化、需求個性化的複雜背景下,企業想要獲得使用者關注愈發困難。並且隨著營銷成本的增加,企業流量能夠更
python資料分析:商品資料化運營(下)——基於投票組合模型的異常檢測
本案例用到的主要技術包括: 基本預處理:使用DictVectorizer將字串分類變數轉換為數值型變數、使用SMOTE對不均衡樣本做過抽樣處理。 資料建模:基於cross_val_score的交叉檢驗、基於LogisticRegression、RandomForest、
python資料分析:商品資料化運營(中)——基於引數優化的Gradient Boosting的銷售預測
本案例需要使用超引數交叉檢驗和優化方法GridSearchCV以及整合迴歸方法GradientBoostingRegressor GridSearchCV與GradientBoostingRegressor GridSearchCV GridSearchCV用於系統地遍歷多種
python資料分析:商品資料化運營(上)——知識點
商品資料運營指標 銷售類指標 訂單量/商品銷售量 訂單量指使用者提交訂單的數量,計算邏輯去重後的訂單ID的數量。 商品銷售量又稱銷售件數,指銷售商品的數量。 訂單金額/商品銷售金額 訂單金額為使用者提
python資料分析:會員資料執行(下)——基於AdaBoost的營銷響應預測
何為AdaBoost Adaboost是一種迭代演算法,其核心思想是針對同一個訓練集訓練不同的分類器(弱分類器),然後把這些弱分類器集合起來,構成一個更強的最終分類器(強分類器)。其演算法本身是通過改變資料分佈來實現的,它根據每次訓練集之中每個樣本的分類是否正確,以及上次的總體分類的
python資料分析:會員資料化運營(中)——RMF分析
何為RFM模型分析 RFM模型是衡量客戶價值和客戶創利能力的重要工具和手段。在眾多的客戶關係管理(CRM)的分析模式中,RFM模型是被廣泛提到的。該機械模型通過一個客戶的近期購買行為、購買的總體頻率以及花了多少錢3項指標來描述該客戶的價值狀況。 RFM的含義: R(R
python資料分析:會員資料化運營(上)——知識點
會員資料化運營解決問題: 會員的生命週期狀態是什麼; 會員的核心訴求是什麼; 會員的轉化習慣和路徑是什麼; 會員的價值如何; 如何擴大市場覆蓋、獲得更多的新會員; 如何更好地維繫老會員; 應該在什麼時間、採取何種措施、針對哪些會員做哪些運營
jQuery原始碼分析——常用正則表示式(RegExp)
常用的數字正則(嚴格匹配) 正則 含義 ^[1-9]\d*$ 匹配正整數 ^-[1-9]\d*$ 匹配負整數 ^-?[1-9]\d*$ 匹配整數 ^[1-9]\d*|0$ 匹配非負整數(正整數 +
原始碼分析篇--Java集合操作(2)
4、兩大集合介面 在Java集合中,有兩大集合,一個是Collection介面及其實現類,另一個是Map介面及其實現類。下面給出這兩種集合的框架圖。如下所示。 4.1Collection介面框架圖 4.2Map介面框架圖 從上面兩個框架圖可以看出,Cllection介面和Map介面是
原始碼分析篇--Java集合操作(1)
一、集合框架 1、集合框架體系圖 2、集合的概念 Java集合是使程式能夠儲存和操縱元素不固定的一組資料。 所有Java集合類都位於java.uti包中。與Java陣列不同,Java集合中不能存放基本資料型別,只能存放物件的引用。但是在JDK5.0以後的版本當中,JAVA增加了“自動裝箱