WebRTC基于TransportCC和Trendline Filter的發(fā)送端碼率估計(jì)(Sendside-BWE)

1引言

眾所周知萝玷,WebRTC的擁塞控制和碼率估計(jì)算法采用GCC算法[1]墨状。該算法充分考慮了網(wǎng)絡(luò)丟包和網(wǎng)絡(luò)延遲對(duì)碼率估計(jì)的不同影響豁陆,分別基于丟包率和網(wǎng)絡(luò)延遲進(jìn)行碼率估計(jì)篇裁,最后綜合這另種碼率得出最優(yōu)值沛慢。在算法實(shí)現(xiàn)上,基于丟包率的碼率估計(jì)在發(fā)送端進(jìn)行达布,基于網(wǎng)絡(luò)延遲的碼率估計(jì)在接收端進(jìn)行团甲。最后在發(fā)送端計(jì)算出最優(yōu)值,作用于Codec和PacedSender模塊黍聂。GCC算法能夠較好地基于網(wǎng)絡(luò)實(shí)時(shí)狀況估計(jì)網(wǎng)絡(luò)帶寬躺苦,為網(wǎng)絡(luò)實(shí)時(shí)通信應(yīng)用打下堅(jiān)實(shí)基礎(chǔ)[2][3][4]。

然而产还,隨著時(shí)間推移匹厘,在實(shí)際測(cè)試中發(fā)現(xiàn)GCC算法逐漸顯出一些弊端,比如不能適應(yīng)所有網(wǎng)絡(luò)模型脐区,應(yīng)對(duì)網(wǎng)絡(luò)峰值能力差愈诚,等等。為此,Google官方從M55版本引進(jìn)最新的擁塞控制算法Sendside-BWE炕柔,把所有碼率計(jì)算模塊都移到發(fā)送端進(jìn)行酌泰,并采用全新的Trendline濾波器取代之前的Kalman濾波器[5]。實(shí)測(cè)表明汗唱,新的算法實(shí)現(xiàn)能夠更好更快地進(jìn)行碼率估計(jì)和網(wǎng)絡(luò)過載恢復(fù)宫莱。

本文基于WebRTC的M66版本和相關(guān)RFC,深度分析學(xué)習(xí)最新Sendside-BWE算法的實(shí)現(xiàn)哩罪。

2 GCC算法回顧

關(guān)于GCC算法已經(jīng)有很多分析和論述[6][7]授霸,本文只回顧其算法框架,并分析其在實(shí)際應(yīng)用中存在的問題际插。

圖1 GCC算法整體結(jié)構(gòu)

GCC算法分兩部分:發(fā)送端基于丟包率的碼率控制和接收端基于延遲的碼率控制碘耳。基于丟包率的碼率控制運(yùn)行在發(fā)送端框弛,依靠RTCP RR報(bào)文進(jìn)行工作辛辨。WebRTC在發(fā)送端收到來自接收端的RTCP RR報(bào)文,根據(jù)其Report Block中攜帶的丟包率信息瑟枫,動(dòng)態(tài)調(diào)整發(fā)送端碼率As斗搞。基于延遲的碼率控制運(yùn)行在接收端慷妙,WebRTC根據(jù)數(shù)據(jù)包到達(dá)的時(shí)間延遲僻焚,通過到達(dá)時(shí)間濾波器,估算出網(wǎng)絡(luò)延遲m(t)膝擂,然后經(jīng)過過載檢測(cè)器判斷當(dāng)前網(wǎng)絡(luò)的擁塞狀況虑啤,最后在碼率控制器根據(jù)規(guī)則計(jì)算出遠(yuǎn)端估計(jì)最大碼率Ar。得到Ar之后架馋,通過RTCP REMB報(bào)文返回發(fā)送端狞山。發(fā)送端綜合As、Ar和預(yù)配置的上下限叉寂,計(jì)算出最終的目標(biāo)碼率A萍启,該碼率會(huì)作用到Encoder、RTP和PacedSender等模塊屏鳍,控制發(fā)送端的碼率勘纯。

發(fā)送端基于丟包率的碼率估計(jì)計(jì)算公式:

圖2 GCC發(fā)送端基于丟包率的碼率估計(jì)

接收端基于延遲的碼率估計(jì)計(jì)算公式:

圖3 GCC接收端基于延遲的碼率估計(jì)

GCC算法充分考慮丟包率和延遲對(duì)碼率的影響,在實(shí)時(shí)通訊應(yīng)用(如視頻會(huì)議)中能夠發(fā)揮良好效果孕蝉。然而,在某些特定應(yīng)用場(chǎng)景下(比如實(shí)時(shí)在線編輯)腌逢,GCC算法的表現(xiàn)不太讓人滿意降淮,主要體現(xiàn)在它應(yīng)對(duì)峰值流量的能力上,具體表現(xiàn)在:1)算法一開始基于Increase狀態(tài)增加碼率,當(dāng)檢測(cè)到Decrease狀態(tài)時(shí)調(diào)用Ar[t(i)] = Alpha * Rr[t(i)]佳鳖,這個(gè)時(shí)候?qū)崟r(shí)碼率Rr(ti)可能遠(yuǎn)小于Ar[t(i-1)]霍殴,這樣在后續(xù)過程中Ar處于較低水平;此時(shí)若有視頻關(guān)鍵幀沖擊系吩,則數(shù)據(jù)包大量在PacedSender的隊(duì)列中排隊(duì)来庭,造成較大排隊(duì)延遲。2)基于1)中論述的情況穿挨,碼率估計(jì)模塊反饋給Codec的編碼碼率很低月弛,但編碼器需要編碼關(guān)鍵幀時(shí),內(nèi)部的碼率控制模塊控制出的最小碼率仍然大于反饋碼率科盛。這兩種情況都會(huì)造成較大的發(fā)送端排隊(duì)延遲帽衙,進(jìn)而在接收端造成較大的JitterBuffer延遲,最終導(dǎo)致端到端延遲到達(dá)500ms的水平贞绵,這在實(shí)時(shí)在線編輯應(yīng)用中是無法容忍的厉萝。

基于此,Google官方從WebRTC M55開始引入新的碼率估計(jì)算法榨崩,把所有碼率計(jì)算模塊都移動(dòng)到發(fā)送端谴垫,并采用全新的Trendline濾波器,基于碼率探測(cè)機(jī)制快速準(zhǔn)確地估計(jì)出實(shí)時(shí)碼率母蛛。

3 Sendside-BWE算法框架

從本節(jié)開始系統(tǒng)分析Sendside-BWE算法的框架和實(shí)現(xiàn)翩剪,圖4顯示該算法的基本實(shí)現(xiàn)框架,以及和GCC算法的對(duì)比溯祸。

圖4 Sendside-BWE算法和GCC算法的實(shí)現(xiàn)和對(duì)比[8]

圖4中棕色線是Sendside-BWE算法的數(shù)據(jù)控制流回路:發(fā)送端在發(fā)送RTP數(shù)據(jù)包時(shí)肢专,在RTP頭部擴(kuò)展中設(shè)置傳輸層序列號(hào)TransportSequenceNumber;數(shù)據(jù)包到達(dá)接收端后記錄該序列號(hào)和包到達(dá)時(shí)間焦辅,然后接收端基于此構(gòu)造TransportCC報(bào)文返回到發(fā)送端博杖;發(fā)送端解析該報(bào)文,并執(zhí)行Sendside-BWE算法筷登,計(jì)算得到基于延遲的碼率Ar剃根;最終Ar和基于丟包率的碼率As進(jìn)行比較得到最終目標(biāo)碼率,作用到PacedSender和Codec模塊前方,形成一個(gè)完整的反饋回路狈醉。圖4中紅色線是GCC算法的數(shù)據(jù)控制流回路:發(fā)送端在發(fā)送RTP數(shù)據(jù)包時(shí),在RTP頭部擴(kuò)展中設(shè)置絕對(duì)發(fā)送時(shí)間AbsSendTime惠险;數(shù)據(jù)包到達(dá)接收端后記錄該絕對(duì)到達(dá)時(shí)間苗傅,然后基于此執(zhí)行GCC算法得到Ar,最后構(gòu)造REMB報(bào)文把Ar發(fā)送回發(fā)送端班巩;發(fā)送端基于Ar和As得到最終目標(biāo)碼率渣慕,作用到PacedSender和Codec模塊,形成一個(gè)完整的反饋回路。

從中可以看出逊桦,Sendside-BWE算法充分復(fù)用GCC算法的框架和實(shí)現(xiàn)眨猎,整個(gè)反饋回路基本類似:發(fā)送端在RTP頭部擴(kuò)展中記錄碼率估計(jì)元數(shù)據(jù),碼率估計(jì)模塊基于此元數(shù)據(jù)估計(jì)出碼率As强经,在發(fā)送端基于丟包率計(jì)算Ar睡陪,發(fā)送端綜合As和Ar得到最終目標(biāo)碼率,并作用于Codec和PacedSender模塊匿情。所不同的是:對(duì)于GCC算法兰迫,RTP報(bào)文頭部添加AbsSendTime擴(kuò)展,在接收端執(zhí)行基于延遲的碼率估計(jì)码秉,網(wǎng)絡(luò)延遲濾波器采用Kalman Filter逮矛,返回給發(fā)送端的是REMB報(bào)文;對(duì)于Sendside-BWE算法转砖,RTP報(bào)文頭部添加TransportSequenceNumber擴(kuò)展须鼎,在發(fā)送端執(zhí)行基于延遲的碼率估計(jì),網(wǎng)絡(luò)延遲濾波器采用Trandline府蔗,返回給發(fā)送端的是TransportCC報(bào)文晋控。表5總結(jié)出GCC算法和Sendside-BWE算法的異同。

表5 GCC和Sendside-BWE關(guān)鍵模塊異同

需要注意的是姓赤,從WebRTC M55開始啟用Sendside-BWE后赡译,其GCC算法就只做前向兼容而沒有進(jìn)一步的功能開發(fā)、性能優(yōu)化和bug修正不铆。因此蝌焚,GCC是過去,Sendside-BWE是未來誓斥。

4 Sendside-BWE算法實(shí)現(xiàn)

本節(jié)論述Sendside-BWE算法的實(shí)現(xiàn)細(xì)節(jié)只洒,在論述上力求不過度注釋代碼,以免陷入細(xì)節(jié)無法自拔劳坑。本節(jié)按照如下順序論述Sendside-BWE的實(shí)現(xiàn)細(xì)節(jié):SDP協(xié)商毕谴,發(fā)送端發(fā)送RTP報(bào)文,接收端接受RTP報(bào)文及信息存儲(chǔ)距芬,接收端構(gòu)造TransportCC報(bào)文涝开,發(fā)送端解析TransportCC報(bào)文,發(fā)送端碼率估計(jì)框仔。

4.1 Sendside-BWE在SDP層協(xié)商

TransportCC和remb一樣都是Codec的feedback params的一部分舀武。為支持TransportCC,Codec在收集feedback params時(shí)需添加額外一條:

codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamTransportCc, kParamValueEmpty));

其中离斩,TransportCC在最終生成的SDP中體現(xiàn)為如下一條attribute:

a=extmap:5 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01

然后银舱,SDP協(xié)商過程按照常規(guī)操作進(jìn)行衷旅。

4.2 發(fā)送端發(fā)送RTP報(bào)文

發(fā)送端在發(fā)送RTP報(bào)文時(shí),需要在RTP頭部添加新的擴(kuò)展TransportSequenceNumber纵朋,該擴(kuò)展格式如圖6所示。

圖6 TransportSequenceNumber擴(kuò)展格式

注意這里的傳輸層序列號(hào)茄袖,和RTP報(bào)文格式中的媒體層序列號(hào)不是同一個(gè)東西操软。傳輸層序列號(hào)關(guān)注數(shù)據(jù)的傳輸特性,主要作用是碼率估計(jì)宪祥;媒體曾序列號(hào)關(guān)注數(shù)據(jù)的媒體特性聂薪,主要作用是組幀和抗丟包。它們的初始值不一樣蝗羊,賦值點(diǎn)也不一樣藏澳,其中媒體層序列號(hào)在RTPSender::AssignSequenceNumber()處賦值,而傳輸層序列號(hào)在RTPSender::UpdateTransportSequenceNumber()處賦值耀找。RTP報(bào)文在發(fā)送時(shí)構(gòu)造該頭部擴(kuò)展的函數(shù)調(diào)用棧如下:

=> RTPSender::TimeToSendPacket();
?=> RTPSender::PrepareAndSendPacket();
??=> RTPSender::UpdateTransportSequenceNumber();
???=> RTPSender::AddPacketToTransportFeedback();s
????=> SendSideCongestionController::AddPacket();

然后RTP報(bào)文走正常的構(gòu)造發(fā)送路徑發(fā)送到網(wǎng)絡(luò)翔悠。

4.3 接收端接收RTP并構(gòu)造TransportCC報(bào)文

接收端worker線程在收到RTP報(bào)文后,解析并檢查其頭部擴(kuò)展野芒,根據(jù)其是否有TransportSN擴(kuò)展蓄愁,決定采用Sendside-BWE還是GCC,注意這兩種擁塞控制器是互斥的狞悲。對(duì)于Sendside-BWE撮抓,接收端代理解析擴(kuò)展拿到傳輸層序列號(hào),并記錄RTP報(bào)文的到達(dá)時(shí)間摇锋,構(gòu)造(transport-sn丹拯,arrival_time_ms)鍵值對(duì),存儲(chǔ)在隊(duì)列中荸恕。整個(gè)過程的函數(shù)調(diào)用棧如下:

=> Call::DeliverRtp();
?=> NotifyBweOfReceivedPacket();
?=> RtpPacketReceived::GetHeader();
?=> ReceiveSideCongestionController::OnReceivedPacket();
??=> RemoteEstimatorProxy::IncomingPacket();
???=> OnPacketArrival(transport-sn, arrival_time_ms):
??????Packet_arrival_times_[seq] = arrival_time;

RemoteEstimatorProxy作為Sendside-BWE在接收端的代理乖酬,其實(shí)現(xiàn)遵從WebRTC的模塊機(jī)制,在Process線程以100ms為發(fā)送周期發(fā)送TransportCC報(bào)文[9]戚炫,發(fā)送周期會(huì)根據(jù)當(dāng)前碼率動(dòng)態(tài)調(diào)整剑刑,其取值范圍在[50ms, 250ms]之間,其本身可用的發(fā)送碼率為當(dāng)前可用碼率的5%双肤。TransportFeedback報(bào)文是一種RTP 傳輸層feedback報(bào)文(pt=205)施掏,F(xiàn)MT為15。其格式如圖7所示:

圖7 TransportCC報(bào)文格式

TransportCC報(bào)文采用base + bitmap的思想茅糜,其各個(gè)字段的具體解釋請(qǐng)參考文獻(xiàn)[9]七芭,一個(gè)TransportCC報(bào)文能最多攜帶16個(gè)RTP報(bào)文的有效信息,每個(gè)RTP報(bào)文信息包括其傳輸層序列號(hào)和包到達(dá)時(shí)間蔑赘。TransportCC報(bào)文在發(fā)送端構(gòu)造和發(fā)送的函數(shù)調(diào)用棧如下:

=> RemoteEstimatorProxy::Process();
?=> RemoteEstimatorProxy::BuildFeedbackPacket();
??=> TransportFeedback::AddReceivedPacket()
???=> PacketRouter::SendTransportFeedback(fbpacket);
????=> RTCPSender::SendFeedbackPacket(fbpacket);

然后按照常規(guī)RTCP報(bào)文流程發(fā)送到發(fā)送端狸驳。

4.4 發(fā)送端接收TransportCC報(bào)文并解析

接收端接收操作就是常規(guī)的RTCP接收预明、解析并回調(diào)的流程,在worker線程中:

=> WebRtcVideoChannel::OnRtcpReceived();
?=> Call::DeliverRtcp();
??=> RTCPReceiver::HandleTransportFeedback();
???=> RTCPReceiver::TriggerCallbacksFromRtcpPacket();
????=> TransportFeedbackObserver::OnTransportFeedback();
?????=> SendSideCongestionController::OnTransportFeedback();

然后就是Send-side BWE算法在發(fā)送端的核心實(shí)現(xiàn)耙箍。

4.5 SendSideCongestionController碼率估計(jì)

SendSideCongestionController是Sendside-BWE算法在發(fā)送端的核心實(shí)現(xiàn)撰糠,關(guān)于其的分析全部是細(xì)節(jié)描述。本節(jié)限于篇幅辩昆,僅勾勒出其大致的函數(shù)調(diào)用棧和流程說明阅酪。

?=> SendSideCongestionController::OnTransportFeedback();
?=> AcknowledBitrateEstimator::IncomingPacketFeedbackVector();
?=> DelayBasedBwe::IncomingPacketFeedbackVector();
?=> BitrateControllerImpl::OnDelayBasedBweResult();
?=> SendSideCongestionController::MaybeTriggerOnNetworkChanged();
?=> ProbeController::RequestProbe();

在SendSideCongestionController的OnTransportFeedback()函數(shù)中,首先調(diào)用ALR碼率估計(jì)器得到一個(gè)實(shí)時(shí)碼率汁针,然后以此為參數(shù)調(diào)用DelayBasedBwe計(jì)算得到最新的估計(jì)碼率Ar术辐,把Ar經(jīng)過BitrateController對(duì)象和As綜合,得到最新的目標(biāo)碼率施无。最后通過函數(shù)MaybeTriggerOnNetworkChanged()把最新目標(biāo)碼率作用到Codec和PacedSender模塊辉词。如果本次碼率估計(jì)從網(wǎng)絡(luò)過載中恢復(fù),則調(diào)用ProbeController對(duì)象發(fā)起下一次碼率探測(cè)猾骡。

DelayBasedBwe對(duì)象是真正實(shí)現(xiàn)碼率估計(jì)的地方瑞躺,其內(nèi)部調(diào)用函數(shù)棧如下:

=> DelayBasedBwe::IncomingPacketFeedbackVector();
=> DelayBasedBwe::IncomingPacketFeedback();
?=> InterArrival::ComputeDeltas();
?=> TrendlineEstimator::Update();
=> DelayBasedBwe::MaybeUpdateEstimate();
?=> ProbeBitrateEstimator::FetchAndResetLastEstimatedBitrateBps();
?=> AimdRateControl::SetEstimator();

DelayBasedBwe首先調(diào)用IncomingPacketFeedback針對(duì)每個(gè)RTP報(bào)文信息進(jìn)行碼率估計(jì),其內(nèi)部邏輯和GCC算法的相關(guān)步驟一致兴想,在此不再贅述隘蝎。需要注意的是,其內(nèi)部網(wǎng)絡(luò)延遲濾波器采用TrendlineEstimator襟企。然后DelayBasedBwe調(diào)用MaybeUpdateEstimate()根據(jù)本次判定的網(wǎng)絡(luò)狀態(tài)計(jì)算得到最終的Ar嘱么,如GCC算法一樣。

Trendline濾波器的原理就是最小二乘法線性回歸求得網(wǎng)絡(luò)延遲波動(dòng)的斜率顽悼,每個(gè)散列點(diǎn)表示為(arrival_time, smoothed_delay)曼振,其中arrival_time為RTP包到達(dá)時(shí)間,smoothed_delay為平滑后的發(fā)送接收相對(duì)延遲蔚龙。最后根據(jù)當(dāng)前散列點(diǎn)集合冰评,采用最小二乘法線性回歸計(jì)算得到本次估計(jì)的網(wǎng)絡(luò)延遲m(i)。其計(jì)算過程調(diào)用如下:

=> TrendlineEstimator::Update();
?=> LinearFitSlope();
?=> TrendlineEstimator::Detect();
??=> TrendlineEstimator::UpdateThreshold();

至此木羹,關(guān)于Sendside-BWE算法的實(shí)現(xiàn)初步分析完畢甲雅。

5 Sendside-BWE實(shí)測(cè)數(shù)據(jù)

實(shí)際測(cè)試表明,和GCC算法相比坑填,Sendside-BWE算法在快速碼率估計(jì)抛人、碼率估計(jì)準(zhǔn)確性、抗網(wǎng)絡(luò)抖動(dòng)等方面都具有非常大改善脐瑰。由于保密原因妖枚,此處不能發(fā)布內(nèi)部測(cè)試數(shù)據(jù),僅貼出一組公開渠道獲得的快速碼率估計(jì)比較圖[10]苍在。

圖8 Sendside-BWE和GCC算法對(duì)比

該圖表明绝页,Sendside-BWE算法能夠在第一次TransportCC報(bào)文返回時(shí)即估計(jì)出實(shí)時(shí)網(wǎng)絡(luò)帶寬荠商,相比GCC算法更快速更準(zhǔn)確。

6 總結(jié)

本文在總結(jié)對(duì)比GCC和Sendside-BWE算法基礎(chǔ)上续誉,深入學(xué)習(xí)Sendside-BWE算法的框架和實(shí)現(xiàn)細(xì)節(jié)莱没,為進(jìn)一步學(xué)習(xí)WebRTC擁塞控制算法和優(yōu)化算法細(xì)節(jié)打下堅(jiān)實(shí)基礎(chǔ)。

參考文獻(xiàn)

[1] A Google Congestion Control Algorithm for Real-Time Communication. draft-alvestrand-rmcat-congestion-03
[2] Understanding the Dynamic Behaviour of the Google Congestion Control for RTCWeb.
[3] Experimental Investigation of the Google Congestion Control for Real-Time Flows.
[4] Analysis and Design of the Google Congestion Control for Web Real-time Communication (WebRTC). MMSys’16, May 10-13, 2016, Klagenfurt, Austria
[5] WebRTC視頻接收緩沖區(qū)基于KalmanFilter的延遲模型.http://www.reibang.com/p/bb34995c549a
[6] WebRTC基于GCC的擁塞控制(上) - 算法分析 http://www.reibang.com/p/0f7ee0e0b3be
[7] WebRTC基于GCC的擁塞控制(下) - 實(shí)現(xiàn)分析 http://www.reibang.com/p/5259a8659112
[8] WebRTC的擁塞控制和帶寬策略 https://mp.weixin.qq.com/s/Ej63-FTe5-2pkxyXoXBUTw
[9] RTP Extensions for Transport-wide Congestion Control
draft-holmer-rmcat-transport-wide-cc-extensions-01
[10] Bandwidth Estimation in WebRTC (and the new Sender Side BWE) http://www.rtcbits.com/2017/01/bandwidth-estimation-in-webrtc-and-new.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
禁止轉(zhuǎn)載酷鸦,如需轉(zhuǎn)載請(qǐng)通過簡信或評(píng)論聯(lián)系作者郊愧。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市井佑,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌眠寿,老刑警劉巖躬翁,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異盯拱,居然都是意外死亡盒发,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門狡逢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宁舰,“玉大人,你說我怎么就攤上這事奢浑÷瑁” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵雀彼,是天一觀的道長壤蚜。 經(jīng)常有香客問我,道長徊哑,這世上最難降的妖魔是什么袜刷? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮莺丑,結(jié)果婚禮上著蟹,老公的妹妹穿的比我還像新娘。我一直安慰自己梢莽,他們只是感情好萧豆,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著昏名,像睡著了一般炕横。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上葡粒,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天份殿,我揣著相機(jī)與錄音忽媒,去河邊找鬼。 笑死笤受,一個(gè)胖子當(dāng)著我的面吹牛淀弹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播拾枣,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼沃疮,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了梅肤?” 一聲冷哼從身側(cè)響起司蔬,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎姨蝴,沒想到半個(gè)月后俊啼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡左医,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年授帕,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片浮梢。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡跛十,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出秕硝,到底是詐尸還是另有隱情芥映,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布远豺,位于F島的核電站屏轰,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏憋飞。R本人自食惡果不足惜霎苗,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望榛做。 院中可真熱鬧唁盏,春花似錦、人聲如沸检眯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽锰瘸。三九已至刽严,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間避凝,已是汗流浹背舞萄。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來泰國打工眨补, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人倒脓。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓撑螺,卻偏偏與公主長得像,于是被迫代替她去往敵國和親崎弃。 傳聞我的和親對(duì)象是個(gè)殘疾皇子甘晤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容