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:
Andreas Huber
2010-10-13 12:15:03 -07:00
parent 312644cdbb
commit cc5fb1d5e5
3 changed files with 62 additions and 4 deletions

View File

@@ -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

View File

@@ -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);

View File

@@ -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 {