From ef7af7fec702db2fde72b16dedf9064585e6db77 Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Wed, 18 Aug 2010 10:17:18 -0700 Subject: Better support for rtsp streamed through VLC. Temporarily make the socket blocking to read all of the session description. Change-Id: Ibe71f5941485660510e24d714da3865b9c6f89a2 --- media/libstagefright/rtsp/APacketSource.cpp | 17 +++++++++++-- media/libstagefright/rtsp/ARTSPConnection.cpp | 29 ++++++++++++++++++----- media/libstagefright/rtsp/ASessionDescription.cpp | 11 +++++++-- media/libstagefright/rtsp/ASessionDescription.h | 2 +- media/libstagefright/rtsp/MyHandler.h | 10 ++++++++ 5 files changed, 58 insertions(+), 11 deletions(-) diff --git a/media/libstagefright/rtsp/APacketSource.cpp b/media/libstagefright/rtsp/APacketSource.cpp index 224b4bf..b2d697b 100644 --- a/media/libstagefright/rtsp/APacketSource.cpp +++ b/media/libstagefright/rtsp/APacketSource.cpp @@ -18,6 +18,8 @@ #include "ASessionDescription.h" +#include + #include #include #include @@ -37,6 +39,10 @@ static bool GetAttribute(const char *s, const char *key, AString *value) { size_t keyLen = strlen(key); for (;;) { + while (isspace(*s)) { + ++s; + } + const char *colonPos = strchr(s, ';'); size_t len = @@ -253,7 +259,11 @@ APacketSource::APacketSource( mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); int32_t width, height; - sessionDesc->getDimensions(index, PT, &width, &height); + if (!sessionDesc->getDimensions(index, PT, &width, &height)) { + // TODO: extract dimensions from sequence parameter set. + mInitCheck = ERROR_UNSUPPORTED; + return; + } mFormat->setInt32(kKeyWidth, width); mFormat->setInt32(kKeyHeight, height); @@ -271,7 +281,10 @@ APacketSource::APacketSource( mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); int32_t width, height; - sessionDesc->getDimensions(index, PT, &width, &height); + if (!sessionDesc->getDimensions(index, PT, &width, &height)) { + mInitCheck = ERROR_UNSUPPORTED; + return; + } mFormat->setInt32(kKeyWidth, width); mFormat->setInt32(kKeyHeight, height); diff --git a/media/libstagefright/rtsp/ARTSPConnection.cpp b/media/libstagefright/rtsp/ARTSPConnection.cpp index e9162c0..5f8f5fd 100644 --- a/media/libstagefright/rtsp/ARTSPConnection.cpp +++ b/media/libstagefright/rtsp/ARTSPConnection.cpp @@ -136,6 +136,20 @@ bool ARTSPConnection::ParseURL( return true; } +static void MakeSocketBlocking(int s, bool blocking) { + // Make socket non-blocking. + int flags = fcntl(s, F_GETFL, 0); + CHECK_NE(flags, -1); + + if (blocking) { + flags &= ~O_NONBLOCK; + } else { + flags |= O_NONBLOCK; + } + + CHECK_NE(fcntl(s, F_SETFL, flags), -1); +} + void ARTSPConnection::onConnect(const sp &msg) { ++mConnectionID; @@ -150,10 +164,7 @@ void ARTSPConnection::onConnect(const sp &msg) { mSocket = socket(AF_INET, SOCK_STREAM, 0); - // Make socket non-blocking. - int flags = fcntl(mSocket, F_GETFL, 0); - CHECK_NE(flags, -1); - CHECK_NE(fcntl(mSocket, F_SETFL, flags | O_NONBLOCK), -1); + MakeSocketBlocking(mSocket, false); AString url; CHECK(msg->findString("url", &url)); @@ -210,7 +221,7 @@ void ARTSPConnection::onDisconnect(const sp &msg) { mSocket = -1; flushPendingRequests(); - } + } sp reply; CHECK(msg->findMessage("reply", &reply)); @@ -347,7 +358,13 @@ void ARTSPConnection::onReceiveResponse() { CHECK_GE(res, 0); if (res == 1) { - if (!receiveRTSPReponse()) { + MakeSocketBlocking(mSocket, true); + + bool success = receiveRTSPReponse(); + + MakeSocketBlocking(mSocket, false); + + if (!success) { // Something horrible, irreparable has happened. flushPendingRequests(); return; diff --git a/media/libstagefright/rtsp/ASessionDescription.cpp b/media/libstagefright/rtsp/ASessionDescription.cpp index ad813cd..4ea7fda 100644 --- a/media/libstagefright/rtsp/ASessionDescription.cpp +++ b/media/libstagefright/rtsp/ASessionDescription.cpp @@ -203,13 +203,18 @@ void ASessionDescription::getFormatType( } } -void ASessionDescription::getDimensions( +bool ASessionDescription::getDimensions( size_t index, unsigned long PT, int32_t *width, int32_t *height) const { + *width = 0; + *height = 0; + char key[20]; sprintf(key, "a=framesize:%lu", PT); AString value; - CHECK(findAttribute(index, key, &value)); + if (!findAttribute(index, key, &value)) { + return false; + } const char *s = value.c_str(); char *end; @@ -221,6 +226,8 @@ void ASessionDescription::getDimensions( *height = strtoul(s, &end, 10); CHECK_GT(end, s); CHECK_EQ(*end, '\0'); + + return true; } bool ASessionDescription::getDurationUs(int64_t *durationUs) const { diff --git a/media/libstagefright/rtsp/ASessionDescription.h b/media/libstagefright/rtsp/ASessionDescription.h index b26980f..a3fa79e 100644 --- a/media/libstagefright/rtsp/ASessionDescription.h +++ b/media/libstagefright/rtsp/ASessionDescription.h @@ -44,7 +44,7 @@ struct ASessionDescription : public RefBase { size_t index, unsigned long *PT, AString *desc, AString *params) const; - void getDimensions( + bool getDimensions( size_t index, unsigned long PT, int32_t *width, int32_t *height) const; diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h index f21c8dc..b19ad48 100644 --- a/media/libstagefright/rtsp/MyHandler.h +++ b/media/libstagefright/rtsp/MyHandler.h @@ -309,6 +309,16 @@ struct MyHandler : public AHandler { size_t trackIndex; CHECK(msg->findSize("track-index", &trackIndex)); + int32_t eos; + if (msg->findInt32("eos", &eos)) { + LOG(INFO) << "received BYE on track index " << trackIndex; +#if 0 + TrackInfo *track = &mTracks.editItemAt(trackIndex); + track->mPacketSource->signalEOS(ERROR_END_OF_STREAM); +#endif + return; + } + sp obj; CHECK(msg->findObject("access-unit", &obj)); -- cgit v1.1