分享
 
 
 

DirectShow学习(八): CBaseRender类及相应Pin类的源代码分析

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

DirectShow学习(八): CBaseRender类及相应Pin类的源代码分析

1. CRendererInputPin类[renbase.h/renbase.cpp]

派生自CBaseInputPin。

a) 成员变量:

CBaseRenderer *m_pRenderer;

b) IPin接口和继承的函数

HRESULT

BreakConnect();

{

HRESULT hr = m_pRenderer->

BreakConnect();

return CBaseInputPin::

BreakConnect();

}

HRESULT CompleteConnect(IPin *pReceivePin);

{

HRESULT hr = m_pRenderer->CompleteConnect(pReceivePin);

return CBaseInputPin::CompleteConnect(pReceivePin);

}

HRESULT SetMediaType(const CMediaType *pmt);

{

HRESULT hr = CBaseInputPin::SetMediaType(pmt);

return m_pRenderer->SetMediaType(pmt);

}

HRESULT CheckMediaType(const CMediaType *pmt);

{ return m_pRenderer->CheckMediaType(pmt); }

HRESULT Active();{ return m_pRenderer->Active();}

HRESULT Inactive();

{

ASSERT(CritCheckIn(&m_pRenderer->m_InterfaceLock));

m_bRunTimeError = FALSE;

return m_pRenderer->Inactive();

}

STDMETHODIMP QueryId(LPWSTR *Id);

{

*Id = (LPWSTR)CoTaskMemAlloc(8);

lstrcpyW(*Id, L"In");

}

STDMETHODIMP EndOfStream();

{

CAutoLock cRendererLock(&m_pRenderer->m_InterfaceLock);

CAutoLock cSampleLock(&m_pRenderer->m_RendererLock);

HRESULT hr = CheckStreaming();

hr = m_pRenderer->EndOfStream();

hr = CBaseInputPin::EndOfStream();

}

STDMETHODIMP BeginFlush();

{

HRESULT hr = m_pRenderer->EndFlush();

hr = CBaseInputPin::EndFlush();

}

STDMETHODIMP EndFlush();

{

CAutoLock cRendererLock(&m_pRenderer->m_InterfaceLock);

CAutoLock cSampleLock(&m_pRenderer->m_RendererLock);

CBaseInputPin::BeginFlush();

m_pRenderer->BeginFlush();

return m_pRenderer->ResetEndOfStream();

}

STDMETHODIMP Receive(IMediaSample *pMediaSample);

{

HRESULT hr = m_pRenderer->Receive(pSample);

if (FAILED(hr)) {

ASSERT(CritCheckOut(&m_pRenderer->m_RendererLock));

CAutoLock cRendererLock(&m_pRenderer->m_InterfaceLock);

if (!IsStopped() && !IsFlushing() && !m_pRenderer->m_bAbort && !m_bRunTimeError)

{

m_pRenderer->NotifyEvent(EC_ERRORABORT,hr,0);

CAutoLock alRendererLock(&m_pRenderer->m_RendererLock);

if (m_pRenderer->IsStreaming() && !m_pRenderer->IsEndOfStreamDelivered())

{ m_pRenderer->NotifyEndOfStream();}

m_bRunTimeError = TRUE;

}

}

}

2. CBaseRender类[renbase.h/renbase.cpp]

派生自CBaseFilter。

a) 成员变量

CRendererPosPassThru *m_pPosition; // Media seeking pass by object

类CRendererPosPassThru派生自CPosPassThru,后者继承自接口IMediaSeeking和类CMediaPosition。而类CMediaPosition实现了接口IMediaPosition。具体实现见ctlutil.h

CAMEvent m_RenderEvent; // Used to signal timer events

CAMEvent m_ThreadSignal; // Signalled to release worker thread

CAMEvent m_evComplete; // Signalled when state complete

BOOL m_bAbort; // Stop us from rendering more data

BOOL m_bStreaming; // Are we currently streaming

DWORD_PTR m_dwAdvise; // Timer advise cookie

IMediaSample *m_pMediaSample; // Current image media sample

BOOL m_bEOS; // Any more samples in the stream

BOOL m_bEOSDelivered; // Have we delivered an EC_COMPLETE

CRendererInputPin *m_pInputPin; // Our renderer input pin object

CCritSec m_InterfaceLock; // Critical section for interfaces

CCritSec m_RendererLock; // Controls access to internals

IQualityControl * m_pQSink; // QualityControl sink

BOOL m_bRepaintStatus; // Can we signal an EC_REPAINT

// Avoid some deadlocks by tracking filter during stop

volatile BOOL m_bInReceive; // Inside Receive between PrepareReceive

// And actually processing the sample

REFERENCE_TIME m_SignalTime; // Time when we signal EC_COMPLETE

UINT m_EndOfStreamTimer; // Used to signal end of stream

CCritSec m_ObjectCreationLock; // This lock protects the creation and

// of m_pPosition and m_pInputPin. It ensures that two threads cannot create

// either object simultaneously.

构造函数中,对各成员初始化,m_evComplete(TRUE), m_bAbort(FALSE), m_pPosition(NULL), m_ThreadSignal(TRUE), m_bStreaming(FALSE), m_bEOS(FALSE), m_bEOSDelivered(FALSE), m_pMediaSample(NULL), m_dwAdvise(0), m_pQSink(NULL), m_pInputPin(NULL), m_bRepaintStatus(TRUE), m_SignalTime(0), m_bInReceive(FALSE), m_EndOfStreamTimer(0);析构函数中调用StopStreaming和ClearPendingSample;并删除m_pPosition和m_pInputPin。

b) 新增加的virtual函数

// Overriden to say what interfaces we support and where

virtual HRESULT GetMediaPositionInterface(REFIID riid,void **ppv);

{

CAutoLock cObjectCreationLock(&m_ObjectCreationLock);

if (m_pPosition) {

return m_pPosition->NonDelegatingQueryInterface(riid,ppv);

}

m_pPosition = new CRendererPosPassThru(NAME("Renderer CPosPassThru"),

CBaseFilter::GetOwner(),(HRESULT *) &hr, GetPin(0));

return GetMediaPositionInterface(riid,ppv);

}

virtual HRESULT SourceThreadCanWait(BOOL bCanWait);

{

if (bCanWait == TRUE) m_ThreadSignal.Reset();

else m_ThreadSignal.Set();

}

virtual HRESULT WaitForRenderTime();

{

HANDLE WaitObjects[] = { m_ThreadSignal, m_RenderEvent };

OnWaitStart();

while (Result == WAIT_TIMEOUT) {

Result = WaitForMultipleObjects(2,WaitObjects,FALSE,RENDER_TIMEOUT);}

OnWaitEnd();

if (Result == WAIT_OBJECT_0) {return VFW_E_STATE_CHANGED;}

SignalTimerFired();

}

virtual HRESULT CompleteStateChange(FILTER_STATE OldState);

{

if (m_pInputPin->IsConnected() == FALSE) {Ready();return S_OK;}

if (IsEndOfStream() == TRUE) {Ready();return S_OK;}

if (HaveCurrentSample() == TRUE) {

if (OldState != State_Stopped) { Ready();return S_OK;}

}

NotReady();

}

virtual void OnReceiveFirstSample(IMediaSample *pMediaSample) {};

virtual void OnRenderStart(IMediaSample *pMediaSample){}

virtual void OnRenderEnd(IMediaSample *pMediaSample){}

virtual HRESULT OnStartStreaming() { return NOERROR; };

virtual HRESULT OnStopStreaming() { return NOERROR; };

virtual void OnWaitStart() {};

virtual void OnWaitEnd() {};

virtual void PrepareRender() {};

// Quality management implementation for scheduling rendering

virtual BOOL ScheduleSample(IMediaSample *pMediaSample);

{

REFERENCE_TIME StartSample, EndSample;

if (pMediaSample == NULL) {return FALSE;}

HRESULT hr = GetSampleTimes(pMediaSample, &StartSample, &EndSample);

if (FAILED(hr)) {return FALSE;}

if (hr == S_OK) {EXECUTE_ASSERT(SetEvent((HANDLE) m_RenderEvent));

return TRUE;}

ASSERT(WAIT_TIMEOUT == WaitForSingleObject((HANDLE)m_RenderEvent,0));

hr = m_pClock->AdviseTime(

(REFERENCE_TIME) m_tStart, // Start run time

StartSample, // Stream time

(HEVENT)(HANDLE) m_RenderEvent, // Render notification

&m_dwAdvise); // Advise cookie

if (SUCCEEDED(hr)) {return TRUE;}

return FALSE;

}

virtual HRESULT GetSampleTimes(IMediaSample *pMediaSample,

REFERENCE_TIME *pStartTime,

REFERENCE_TIME *pEndTime);

{

if (SUCCEEDED(pMediaSample->GetTime(pStartTime, pEndTime))) {

if (*pEndTime < *pStartTime) {return VFW_E_START_TIME_AFTER_END;}

} else {return S_OK;}

if (m_pClock == NULL) {return S_OK;}

return ShouldDrawSampleNow(pMediaSample,pStartTime,pEndTime);

}

virtual HRESULT ShouldDrawSampleNow(IMediaSample *pMediaSample,

REFERENCE_TIME *ptrStart,

REFERENCE_TIME *ptrEnd);{ return S_FALSE;}

virtual HRESULT SendEndOfStream();

{

ASSERT(CritCheckIn(&m_RendererLock));

if (m_bEOS == FALSE || m_bEOSDelivered || m_EndOfStreamTimer) {

return NOERROR;}

if (m_pClock == NULL) {return NotifyEndOfStream();}

REFERENCE_TIME Signal = m_tStart + m_SignalTime;

REFERENCE_TIME CurrentTime;

m_pClock->GetTime(&CurrentTime);

LONG Delay = LONG((Signal - CurrentTime) / 10000);

if (Delay < TIMEOUT_DELIVERYWAIT) {return NotifyEndOfStream();}

m_EndOfStreamTimer = CompatibleTimeSetEvent((UINT) Delay, // Period of timer

TIMEOUT_RESOLUTION, // Timer resolution

EndOfStreamTimer, // Callback function

DWORD_PTR(this), // Used information

TIME_ONESHOT); // Type of callback

if (m_EndOfStreamTimer == 0) {return NotifyEndOfStream();}

}

virtual HRESULT ResetEndOfStream();

{

ResetEndOfStreamTimer();

CAutoLock cRendererLock(&m_RendererLock);

m_bEOS = FALSE;

m_bEOSDelivered = FALSE;

m_SignalTime = 0;

}

virtual HRESULT EndOfStream();

{

m_bEOS = TRUE;

Ready();

if (m_pMediaSample) { return NOERROR;}

if (m_bStreaming) { SendEndOfStream();}

}

virtual HRESULT CancelNotification();

{

ASSERT(m_dwAdvise == 0 || m_pClock);

DWORD_PTR dwAdvise = m_dwAdvise;

if (m_dwAdvise) {

m_pClock->Unadvise(m_dwAdvise);

SignalTimerFired();}

m_RenderEvent.Reset();

return (dwAdvise ? S_OK : S_FALSE);

}

virtual HRESULT ClearPendingSample();

{

CAutoLock cRendererLock(&m_RendererLock);

if (m_pMediaSample) {

m_pMediaSample->Release();

m_pMediaSample = NULL;}

}

virtual HRESULT PrepareReceive(IMediaSample *pMediaSample);

{

CAutoLock cInterfaceLock(&m_InterfaceLock);

m_bInReceive = TRUE;

HRESULT hr = m_pInputPin->CBaseInputPin::Receive(pMediaSample);

if (hr != NOERROR) {m_bInReceive = FALSE; return E_FAIL;}

if (m_pInputPin->SampleProps()->pMediaType) {

hr = m_pInputPin->SetMediaType(

(CMediaType *)m_pInputPin->SampleProps()->pMediaType);

if (FAILED(hr)) {

m_bInReceive = FALSE;

return hr;

}

}

CAutoLock cSampleLock(&m_RendererLock);

if (m_pMediaSample || m_bEOS || m_bAbort) {

Ready();m_bInReceive = FALSE; return E_UNEXPECTED;}

if (m_pPosition) m_pPosition->RegisterMediaTime(pMediaSample);

if ((m_bStreaming == TRUE) && (ScheduleSample(pMediaSample) == FALSE)) {

ASSERT(WAIT_TIMEOUT == WaitForSingleObject((HANDLE)m_RenderEvent,0));

ASSERT(CancelNotification() == S_FALSE);

m_bInReceive = FALSE;

return VFW_E_SAMPLE_REJECTED;

}

m_SignalTime = m_pInputPin->SampleProps()->tStop;

m_pMediaSample = pMediaSample;

m_pMediaSample->AddRef();

if (m_bStreaming == FALSE) {SetRepaintStatus(TRUE);}

}

virtual BOOL HaveCurrentSample();

{

// Checks if there is a sample waiting at the renderer

CAutoLock cRendererLock(&m_RendererLock);

return (m_pMediaSample == NULL ? FALSE : TRUE);

}

virtual IMediaSample *GetCurrentSample();

{

CAutoLock cRendererLock(&m_RendererLock);

if (m_pMediaSample) {m_pMediaSample->AddRef();}

return m_pMediaSample;

}

virtual HRESULT Render(IMediaSample *pMediaSample);

{

if (pMediaSample == NULL) {return S_FALSE;}

if (m_bStreaming == FALSE) {return S_FALSE;}

OnRenderStart(pMediaSample);

DoRenderSample(pMediaSample);

OnRenderEnd(pMediaSample);

}

virtual HRESULT DoRenderSample(IMediaSample *pMediaSample) PURE;

c) IBaseFilter接口函数以及继承函数

virtual int GetPinCount();{1}

virtual CBasePin *GetPin(int n);

{

CAutoLock cObjectCreationLock(&m_ObjectCreationLock);

if (m_pInputPin == NULL) {

m_pInputPin = new CRendererInputPin(this,&hr,L"In");}

return m_pInputPin;

}

STDMETHODIMP Stop();

{

CAutoLock cRendererLock(&m_InterfaceLock);

if (m_State == State_Stopped) { return NOERROR;}

if (m_pInputPin->IsConnected() == FALSE) {

m_State = State_Stopped;

return NOERROR;}

CBaseFilter::Stop();

if (m_pInputPin->Allocator()) { m_pInputPin->Allocator()->Decommit();}

SetRepaintStatus(TRUE);

StopStreaming();

SourceThreadCanWait(FALSE);

ResetEndOfStream();

CancelNotification();

Ready();

WaitForReceiveToComplete();

m_bAbort = FALSE;

}

STDMETHODIMP Pause();

{

CAutoLock cRendererLock(&m_InterfaceLock);

FILTER_STATE OldState = m_State;

if (m_State == State_Paused) { return CompleteStateChange(State_Paused);}

if (m_pInputPin->IsConnected() == FALSE) {

m_State = State_Paused;

return CompleteStateChange(State_Paused);

}

HRESULT hr = CBaseFilter::Pause();

SetRepaintStatus(TRUE);

StopStreaming();

SourceThreadCanWait(TRUE);

CancelNotification();

ResetEndOfStreamTimer();

if (m_pInputPin->Allocator()) { m_pInputPin->Allocator()->Commit();}

if (OldState == State_Stopped) {

m_bAbort = FALSE;

ClearPendingSample();}

return CompleteStateChange(OldState);

}

STDMETHODIMP Run(REFERENCE_TIME StartTime);

{

CAutoLock cRendererLock(&m_InterfaceLock);

FILTER_STATE OldState = m_State;

if (m_pInputPin->IsConnected() == FALSE) {

NotifyEvent(EC_COMPLETE,S_OK,(LONG_PTR)(IBaseFilter *)this);

m_State = State_Running;

return NOERROR;}

Ready();

HRESULT hr = CBaseFilter::Run(StartTime);

SourceThreadCanWait(TRUE);

SetRepaintStatus(FALSE);

if (m_pInputPin->Allocator()) { m_pInputPin->Allocator()->Commit();}

if (OldState == State_Stopped) {

m_bAbort = FALSE;

ClearPendingSample();}

return StartStreaming ();

}

STDMETHODIMP GetState(DWORD dwMSecs,FILTER_STATE *State);

{

CheckPointer(State,E_POINTER);

if (WaitDispatchingMessages(m_evComplete, dwMSecs) == WAIT_TIMEOUT) {

*State = m_State;

return VFW_S_STATE_INTERMEDIATE;}

*State = m_State;

}

STDMETHODIMP FindPin(LPCWSTR Id, IPin **ppPin);

{

if (0==lstrcmpW(Id,L"In")) { *ppPin = GetPin(0); (*ppPin)->AddRef();}

}

virtual HRESULT Active();{return NOERROR;}

virtual HRESULT Inactive();

{

if (m_pPosition) { m_pPosition->ResetMediaTime();}

ClearPendingSample();

}

virtual HRESULT StartStreaming();

{

CAutoLock cRendererLock(&m_RendererLock);

if (m_bStreaming == TRUE) {return NOERROR;}

m_bStreaming = TRUE;

timeBeginPeriod(1);

OnStartStreaming();

ASSERT(WAIT_TIMEOUT == WaitForSingleObject((HANDLE)m_RenderEvent,0));

ASSERT(CancelNotification() == S_FALSE);

if (m_pMediaSample == NULL) {return SendEndOfStream();}

if (!ScheduleSample(m_pMediaSample)) m_RenderEvent.Set();

}

virtual HRESULT StopStreaming();

{

CAutoLock cRendererLock(&m_RendererLock);

m_bEOSDelivered = FALSE;

if (m_bStreaming == TRUE) {

m_bStreaming = FALSE;

OnStopStreaming();

timeEndPeriod(1);}

}

virtual HRESULT BeginFlush();

{

if (m_State == State_Paused) { NotReady();}

SourceThreadCanWait(FALSE);

CancelNotification();

ClearPendingSample();

WaitForReceiveToComplete();

}

virtual HRESULT EndFlush();

{

if (m_pPosition) m_pPosition->ResetMediaTime();

SourceThreadCanWait(TRUE);

}

virtual HRESULT

BreakConnect();

{

if (m_pQSink) {m_pQSink->Release();m_pQSink = NULL;}

if (m_pInputPin->IsConnected() == FALSE) {return S_FALSE;}

if (m_State != State_Stopped && !m_pInputPin->CanReconnectWhenActive()) {

return VFW_E_NOT_STOPPED;}

SetRepaintStatus(FALSE);

ResetEndOfStream();

ClearPendingSample();

m_bAbort = FALSE;

if (State_Running == m_State) {StopStreaming();}

}

virtual HRESULT SetMediaType(const CMediaType *pmt);{ return NOERROR;}

virtual HRESULT CompleteConnect(IPin *pReceivePin);

{

ASSERT(CritCheckIn(&m_InterfaceLock));

m_bAbort = FALSE;

if (State_Running == GetRealState()) {

HRESULT hr = StartStreaming();

SetRepaintStatus(FALSE);

} else { SetRepaintStatus(TRUE);}

}

virtual HRESULT Receive(IMediaSample *pMediaSample);

{

HRESULT hr = PrepareReceive(pSample);

if (m_State == State_Paused) {

PrepareRender();

m_bInReceive = FALSE;

{

// We must hold both these locks

CAutoLock cRendererLock(&m_InterfaceLock);

if (m_State == State_Stopped) return NOERROR;

m_bInReceive = TRUE;

CAutoLock cSampleLock(&m_RendererLock);

OnReceiveFirstSample(pSample);

}

Ready();

}

hr = WaitForRenderTime();

if (FAILED(hr)) {m_bInReceive = FALSE; return NOERROR;}

PrepareRender();

m_bInReceive = FALSE;

CAutoLock cRendererLock(&m_InterfaceLock);

if (m_State == State_Stopped) return NOERROR;

CAutoLock cSampleLock(&m_RendererLock);

Render(m_pMediaSample);

ClearPendingSample();

SendEndOfStream();

CancelNotification();

}

virtual HRESULT CheckMediaType(const CMediaType *) PURE;

d) 其他函数

BOOL IsEndOfStream() { return m_bEOS; };

BOOL IsEndOfStreamDelivered() { return m_bEOSDelivered; };

BOOL IsStreaming() { return m_bStreaming; };

void SetAbortSignal(BOOL bAbort) { m_bAbort = bAbort; };

CAMEvent *GetRenderEvent() { return &m_RenderEvent; };

// Permit access to the transition state

void Ready() { m_evComplete.Set(); };

void NotReady() { m_evComplete.Reset(); };

BOOL CheckReady() { return m_evComplete.Check(); };

FILTER_STATE GetRealState(){ return m_State; };

void SendRepaint();

{

CAutoLock cSampleLock(&m_RendererLock);

if (m_bAbort == FALSE) {

if (m_pInputPin->IsConnected() == TRUE) {

if (m_pInputPin->IsFlushing() == FALSE) {

if (IsEndOfStream() == FALSE) {

if (m_bRepaintStatus == TRUE) {

IPin *pPin = (IPin *) m_pInputPin;

NotifyEvent(EC_REPAINT,(LONG_PTR) pPin,0);

SetRepaintStatus(FALSE);

}}}}}}

void SendNotifyWindow(IPin *pPin,HWND hwnd);

{

IMediaEventSink *pSink;

HRESULT hr = pPin->QueryInterface(IID_IMediaEventSink,(void **)&pSink);

if (SUCCEEDED(hr)) {

pSink->Notify(EC_NOTIFY_WINDOW,LONG_PTR(hwnd),0);

pSink->Release();}

NotifyEvent(EC_NOTIFY_WINDOW,LONG_PTR(hwnd),0);

}

BOOL OnDisplayChange();

{

CAutoLock cSampleLock(&m_RendererLock);

if (m_pInputPin->IsConnected() == FALSE) {return FALSE;}

IPin *pPin = (IPin *) m_pInputPin;

m_pInputPin->AddRef();

NotifyEvent(EC_DISPLAY_CHANGED,(LONG_PTR) pPin,0);

SetAbortSignal(TRUE);

ClearPendingSample();

m_pInputPin->Release();

}

void SetRepaintStatus(BOOL

bRepaint);

{

CAutoLock cSampleLock(&m_RendererLock);

m_bRepaintStatus =

bRepaint;

}

void TimerCallback();

{

CAutoLock cRendererLock(&m_RendererLock);

if (m_EndOfStreamTimer) {

m_EndOfStreamTimer = 0;

SendEndOfStream();}

}

void ResetEndOfStreamTimer();

{

ASSERT(CritCheckOut(&m_RendererLock));

if (m_EndOfStreamTimer) {

timeKillEvent(m_EndOfStreamTimer);

m_EndOfStreamTimer = 0;}

}

HRESULT NotifyEndOfStream();

{

CAutoLock cRendererLock(&m_RendererLock);

if (m_bStreaming == FALSE) {return NOERROR;}

m_EndOfStreamTimer = 0;

if (m_pPosition) m_pPosition->EOS();

m_bEOSDelivered = TRUE;

return NotifyEvent(EC_COMPLETE,S_OK,(LONG_PTR)(IBaseFilter *)this);

}

void SignalTimerFired();{m_dwAdvise = 0;}

void WaitForReceiveToComplete();

{

for (;;) {

if (!m_bInReceive) {

break;}

MSG msg;

// Receive all interthread sendmessages

PeekMessage(&msg, NULL, WM_NULL, WM_NULL, PM_NOREMOVE);

Sleep(1);

}

if (HIWORD(GetQueueStatus(QS_POSTMESSAGE)) & QS_POSTMESSAGE) {

PostThreadMessage(GetCurrentThreadId(), WM_NULL, 0, 0);

}

}

STDMETHODIMP NonDelegatingQueryInterface(REFIID riid,void **ppv)

{

if (riid == IID_IMediaPosition || riid == IID_IMediaSeeking) {

return GetMediaPositionInterface(riid,ppv);

} else { return CBaseFilter::NonDelegatingQueryInterface(riid,ppv); }

}

e) 友元函数

friend void CALLBACK EndOfStreamTimer(UINT uID, // Timer identifier

UINT uMsg, // Not currently used

DWORD_PTR dwUser, // User information

DWORD_PTR dw1, // Windows reserved

DWORD_PTR dw2); // Is also reserved

{

CBaseRenderer *pRenderer = (CBaseRenderer *) dwUser;

pRenderer->TimerCallback();

}

前一篇: (七) CTransInPlaceFilter及相关联Pin类的源代码解析

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有