summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2010-10-13 12:15:03 -0700
committerAndreas Huber <andih@google.com>2010-10-13 12:15:03 -0700
commitf61551f4fc79e7da879802e3974afa9b03ffb5d0 (patch)
tree4feb3e5d3d1897681129d5f5c44ff16fe25cfa11 /media
parent5cb77e080ced5362b5f047e107327b3cb6ece6c9 (diff)
downloadframeworks_av-f61551f4fc79e7da879802e3974afa9b03ffb5d0.zip
frameworks_av-f61551f4fc79e7da879802e3974afa9b03ffb5d0.tar.gz
frameworks_av-f61551f4fc79e7da879802e3974afa9b03ffb5d0.tar.bz2
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
Diffstat (limited to 'media')
-rw-r--r--media/libstagefright/rtsp/ARTPConnection.cpp38
-rw-r--r--media/libstagefright/rtsp/ARTPConnection.h4
-rw-r--r--media/libstagefright/rtsp/MyHandler.h24
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 0f4c1f3..1bc9925 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 {