diff options
Diffstat (limited to 'media')
-rw-r--r-- | media/libstagefright/rtsp/ARTPConnection.cpp | 38 | ||||
-rw-r--r-- | media/libstagefright/rtsp/ARTPConnection.h | 4 | ||||
-rw-r--r-- | media/libstagefright/rtsp/MyHandler.h | 24 |
3 files changed, 62 insertions, 4 deletions
diff --git a/media/libstagefright/rtsp/ARTPConnection.cpp b/media/libstagefright/rtsp/ARTPConnection.cpp index ded3b24..5a1ea5c 100644 --- a/media/libstagefright/rtsp/ARTPConnection.cpp +++ b/media/libstagefright/rtsp/ARTPConnection.cpp @@ -59,7 +59,8 @@ struct ARTPConnection::StreamInfo { sp<AMessage> mNotifyMsg; KeyedVector<uint32_t, sp<ARTPSource> > mSources; - int32_t mNumRTCPPacketsReceived; + int64_t mNumRTCPPacketsReceived; + int64_t mNumRTPPacketsReceived; struct sockaddr_in mRemoteRTCPAddr; bool mIsInjected; @@ -168,6 +169,12 @@ void ARTPConnection::onMessageReceived(const sp<AMessage> &msg) { break; } + case kWhatFakeTimestamps: + { + onFakeTimestamps(); + break; + } + default: { TRESPASS(); @@ -199,6 +206,7 @@ void ARTPConnection::onAddStream(const sp<AMessage> &msg) { CHECK(msg->findMessage("notify", &info->mNotifyMsg)); info->mNumRTCPPacketsReceived = 0; + info->mNumRTPPacketsReceived = 0; memset(&info->mRemoteRTCPAddr, 0, sizeof(info->mRemoteRTCPAddr)); if (!injected) { @@ -373,6 +381,12 @@ status_t ARTPConnection::receive(StreamInfo *s, bool receiveRTP) { } status_t ARTPConnection::parseRTP(StreamInfo *s, const sp<ABuffer> &buffer) { + if (s->mNumRTPPacketsReceived++ == 0) { + sp<AMessage> notify = s->mNotifyMsg->dup(); + notify->setInt32("first-rtp", true); + notify->post(); + } + size_t size = buffer->size(); if (size < 12) { @@ -638,5 +652,27 @@ void ARTPConnection::onInjectPacket(const sp<AMessage> &msg) { } } +void ARTPConnection::fakeTimestamps() { + (new AMessage(kWhatFakeTimestamps, id()))->post(); +} + +void ARTPConnection::onFakeTimestamps() { + List<StreamInfo>::iterator it = mStreams.begin(); + while (it != mStreams.end()) { + StreamInfo &info = *it++; + + for (size_t j = 0; j < info.mSources.size(); ++j) { + sp<ARTPSource> source = info.mSources.valueAt(j); + + if (!source->timeEstablished()) { + source->timeUpdate(0, 0); + source->timeUpdate(0 + 90000, 0x100000000ll); + + mFlags |= kFakeTimestamps; + } + } + } +} + } // namespace android diff --git a/media/libstagefright/rtsp/ARTPConnection.h b/media/libstagefright/rtsp/ARTPConnection.h index 77f81fa..a17b382 100644 --- a/media/libstagefright/rtsp/ARTPConnection.h +++ b/media/libstagefright/rtsp/ARTPConnection.h @@ -51,6 +51,8 @@ struct ARTPConnection : public AHandler { static void MakePortPair( int *rtpSocket, int *rtcpSocket, unsigned *rtpPort); + void fakeTimestamps(); + protected: virtual ~ARTPConnection(); virtual void onMessageReceived(const sp<AMessage> &msg); @@ -61,6 +63,7 @@ private: kWhatRemoveStream, kWhatPollStreams, kWhatInjectPacket, + kWhatFakeTimestamps, }; static const int64_t kSelectTimeoutUs; @@ -78,6 +81,7 @@ private: void onPollStreams(); void onInjectPacket(const sp<AMessage> &msg); void onSendReceiverReports(); + void onFakeTimestamps(); status_t receive(StreamInfo *info, bool receiveRTP); diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h index 8399ddd..6943608 100644 --- a/media/libstagefright/rtsp/MyHandler.h +++ b/media/libstagefright/rtsp/MyHandler.h @@ -105,7 +105,9 @@ struct MyHandler : public AHandler { mCheckPending(false), mCheckGeneration(0), mTryTCPInterleaving(false), + mTryFakeRTCP(false), mReceivedFirstRTCPPacket(false), + mReceivedFirstRTPPacket(false), mSeekable(false) { mNetLooper->setName("rtsp net"); mNetLooper->start(false /* runOnCallingThread */, @@ -534,6 +536,7 @@ struct MyHandler : public AHandler { mFirstAccessUnitNTP = 0; mNumAccessUnitsReceived = 0; mReceivedFirstRTCPPacket = false; + mReceivedFirstRTPPacket = false; mSeekable = false; sp<AMessage> reply = new AMessage('tear', id()); @@ -611,12 +614,17 @@ struct MyHandler : public AHandler { case 'accu': { - int32_t firstRTCP; - if (msg->findInt32("first-rtcp", &firstRTCP)) { + int32_t first; + if (msg->findInt32("first-rtcp", &first)) { mReceivedFirstRTCPPacket = true; break; } + if (msg->findInt32("first-rtp", &first)) { + mReceivedFirstRTPPacket = true; + break; + } + ++mNumAccessUnitsReceived; postAccessUnitTimeoutCheck(); @@ -839,9 +847,17 @@ struct MyHandler : public AHandler { case 'tiou': { if (!mReceivedFirstRTCPPacket) { - if (mTryTCPInterleaving) { + if (mTryFakeRTCP) { LOGW("Never received any data, disconnecting."); (new AMessage('abor', id()))->post(); + } else if (mTryTCPInterleaving && mReceivedFirstRTPPacket) { + LOGW("We received RTP packets but no RTCP packets, " + "using fake timestamps."); + + mTryFakeRTCP = true; + + mReceivedFirstRTCPPacket = true; + mRTPConn->fakeTimestamps(); } else { LOGW("Never received any data, switching transports."); @@ -987,7 +1003,9 @@ private: bool mCheckPending; int32_t mCheckGeneration; bool mTryTCPInterleaving; + bool mTryFakeRTCP; bool mReceivedFirstRTCPPacket; + bool mReceivedFirstRTPPacket; bool mSeekable; struct TrackInfo { |