Some webcams output rtp streams but never send any rtcp data in violation of
the specs. Attempt to use fake timestamps to be able to play these... Change-Id: Ia7a926616fb764e972955df4acdb59d85cdd93df related-to-bug: 3087310
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user