Merge "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..." into gingerbread
This commit is contained in:
committed by
Android (Google) Code Review
commit
646e0d5ab3
@@ -59,7 +59,8 @@ struct ARTPConnection::StreamInfo {
|
|||||||
sp<AMessage> mNotifyMsg;
|
sp<AMessage> mNotifyMsg;
|
||||||
KeyedVector<uint32_t, sp<ARTPSource> > mSources;
|
KeyedVector<uint32_t, sp<ARTPSource> > mSources;
|
||||||
|
|
||||||
int32_t mNumRTCPPacketsReceived;
|
int64_t mNumRTCPPacketsReceived;
|
||||||
|
int64_t mNumRTPPacketsReceived;
|
||||||
struct sockaddr_in mRemoteRTCPAddr;
|
struct sockaddr_in mRemoteRTCPAddr;
|
||||||
|
|
||||||
bool mIsInjected;
|
bool mIsInjected;
|
||||||
@@ -168,6 +169,12 @@ void ARTPConnection::onMessageReceived(const sp<AMessage> &msg) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case kWhatFakeTimestamps:
|
||||||
|
{
|
||||||
|
onFakeTimestamps();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
TRESPASS();
|
TRESPASS();
|
||||||
@@ -199,6 +206,7 @@ void ARTPConnection::onAddStream(const sp<AMessage> &msg) {
|
|||||||
CHECK(msg->findMessage("notify", &info->mNotifyMsg));
|
CHECK(msg->findMessage("notify", &info->mNotifyMsg));
|
||||||
|
|
||||||
info->mNumRTCPPacketsReceived = 0;
|
info->mNumRTCPPacketsReceived = 0;
|
||||||
|
info->mNumRTPPacketsReceived = 0;
|
||||||
memset(&info->mRemoteRTCPAddr, 0, sizeof(info->mRemoteRTCPAddr));
|
memset(&info->mRemoteRTCPAddr, 0, sizeof(info->mRemoteRTCPAddr));
|
||||||
|
|
||||||
if (!injected) {
|
if (!injected) {
|
||||||
@@ -373,6 +381,12 @@ status_t ARTPConnection::receive(StreamInfo *s, bool receiveRTP) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
status_t ARTPConnection::parseRTP(StreamInfo *s, const sp<ABuffer> &buffer) {
|
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();
|
size_t size = buffer->size();
|
||||||
|
|
||||||
if (size < 12) {
|
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
|
} // namespace android
|
||||||
|
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ struct ARTPConnection : public AHandler {
|
|||||||
static void MakePortPair(
|
static void MakePortPair(
|
||||||
int *rtpSocket, int *rtcpSocket, unsigned *rtpPort);
|
int *rtpSocket, int *rtcpSocket, unsigned *rtpPort);
|
||||||
|
|
||||||
|
void fakeTimestamps();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~ARTPConnection();
|
virtual ~ARTPConnection();
|
||||||
virtual void onMessageReceived(const sp<AMessage> &msg);
|
virtual void onMessageReceived(const sp<AMessage> &msg);
|
||||||
@@ -61,6 +63,7 @@ private:
|
|||||||
kWhatRemoveStream,
|
kWhatRemoveStream,
|
||||||
kWhatPollStreams,
|
kWhatPollStreams,
|
||||||
kWhatInjectPacket,
|
kWhatInjectPacket,
|
||||||
|
kWhatFakeTimestamps,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int64_t kSelectTimeoutUs;
|
static const int64_t kSelectTimeoutUs;
|
||||||
@@ -78,6 +81,7 @@ private:
|
|||||||
void onPollStreams();
|
void onPollStreams();
|
||||||
void onInjectPacket(const sp<AMessage> &msg);
|
void onInjectPacket(const sp<AMessage> &msg);
|
||||||
void onSendReceiverReports();
|
void onSendReceiverReports();
|
||||||
|
void onFakeTimestamps();
|
||||||
|
|
||||||
status_t receive(StreamInfo *info, bool receiveRTP);
|
status_t receive(StreamInfo *info, bool receiveRTP);
|
||||||
|
|
||||||
|
|||||||
@@ -105,7 +105,9 @@ struct MyHandler : public AHandler {
|
|||||||
mCheckPending(false),
|
mCheckPending(false),
|
||||||
mCheckGeneration(0),
|
mCheckGeneration(0),
|
||||||
mTryTCPInterleaving(false),
|
mTryTCPInterleaving(false),
|
||||||
|
mTryFakeRTCP(false),
|
||||||
mReceivedFirstRTCPPacket(false),
|
mReceivedFirstRTCPPacket(false),
|
||||||
|
mReceivedFirstRTPPacket(false),
|
||||||
mSeekable(false) {
|
mSeekable(false) {
|
||||||
mNetLooper->setName("rtsp net");
|
mNetLooper->setName("rtsp net");
|
||||||
mNetLooper->start(false /* runOnCallingThread */,
|
mNetLooper->start(false /* runOnCallingThread */,
|
||||||
@@ -534,6 +536,7 @@ struct MyHandler : public AHandler {
|
|||||||
mFirstAccessUnitNTP = 0;
|
mFirstAccessUnitNTP = 0;
|
||||||
mNumAccessUnitsReceived = 0;
|
mNumAccessUnitsReceived = 0;
|
||||||
mReceivedFirstRTCPPacket = false;
|
mReceivedFirstRTCPPacket = false;
|
||||||
|
mReceivedFirstRTPPacket = false;
|
||||||
mSeekable = false;
|
mSeekable = false;
|
||||||
|
|
||||||
sp<AMessage> reply = new AMessage('tear', id());
|
sp<AMessage> reply = new AMessage('tear', id());
|
||||||
@@ -611,12 +614,17 @@ struct MyHandler : public AHandler {
|
|||||||
|
|
||||||
case 'accu':
|
case 'accu':
|
||||||
{
|
{
|
||||||
int32_t firstRTCP;
|
int32_t first;
|
||||||
if (msg->findInt32("first-rtcp", &firstRTCP)) {
|
if (msg->findInt32("first-rtcp", &first)) {
|
||||||
mReceivedFirstRTCPPacket = true;
|
mReceivedFirstRTCPPacket = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (msg->findInt32("first-rtp", &first)) {
|
||||||
|
mReceivedFirstRTPPacket = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
++mNumAccessUnitsReceived;
|
++mNumAccessUnitsReceived;
|
||||||
postAccessUnitTimeoutCheck();
|
postAccessUnitTimeoutCheck();
|
||||||
|
|
||||||
@@ -839,9 +847,17 @@ struct MyHandler : public AHandler {
|
|||||||
case 'tiou':
|
case 'tiou':
|
||||||
{
|
{
|
||||||
if (!mReceivedFirstRTCPPacket) {
|
if (!mReceivedFirstRTCPPacket) {
|
||||||
if (mTryTCPInterleaving) {
|
if (mTryFakeRTCP) {
|
||||||
LOGW("Never received any data, disconnecting.");
|
LOGW("Never received any data, disconnecting.");
|
||||||
(new AMessage('abor', id()))->post();
|
(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 {
|
} else {
|
||||||
LOGW("Never received any data, switching transports.");
|
LOGW("Never received any data, switching transports.");
|
||||||
|
|
||||||
@@ -987,7 +1003,9 @@ private:
|
|||||||
bool mCheckPending;
|
bool mCheckPending;
|
||||||
int32_t mCheckGeneration;
|
int32_t mCheckGeneration;
|
||||||
bool mTryTCPInterleaving;
|
bool mTryTCPInterleaving;
|
||||||
|
bool mTryFakeRTCP;
|
||||||
bool mReceivedFirstRTCPPacket;
|
bool mReceivedFirstRTCPPacket;
|
||||||
|
bool mReceivedFirstRTPPacket;
|
||||||
bool mSeekable;
|
bool mSeekable;
|
||||||
|
|
||||||
struct TrackInfo {
|
struct TrackInfo {
|
||||||
|
|||||||
Reference in New Issue
Block a user