Merge "Better handling of rtsp connection and disconnection." into gingerbread

This commit is contained in:
Andreas Huber
2010-08-23 12:26:31 -07:00
committed by Android (Google) Code Review
3 changed files with 99 additions and 14 deletions

View File

@@ -19,6 +19,7 @@
#define A_RTSP_CONTROLLER_H_ #define A_RTSP_CONTROLLER_H_
#include <media/stagefright/foundation/ABase.h> #include <media/stagefright/foundation/ABase.h>
#include <media/stagefright/foundation/AHandlerReflector.h>
#include <media/stagefright/MediaExtractor.h> #include <media/stagefright/MediaExtractor.h>
namespace android { namespace android {
@@ -38,12 +39,32 @@ struct ARTSPController : public MediaExtractor {
virtual sp<MetaData> getTrackMetaData( virtual sp<MetaData> getTrackMetaData(
size_t index, uint32_t flags); size_t index, uint32_t flags);
void onMessageReceived(const sp<AMessage> &msg);
protected: protected:
virtual ~ARTSPController(); virtual ~ARTSPController();
private: private:
enum {
kWhatConnectDone = 'cdon',
kWhatDisconnectDone = 'ddon',
};
enum State {
DISCONNECTED,
CONNECTED,
CONNECTING,
};
Mutex mLock;
Condition mCondition;
State mState;
status_t mConnectionResult;
sp<ALooper> mLooper; sp<ALooper> mLooper;
sp<MyHandler> mHandler; sp<MyHandler> mHandler;
sp<AHandlerReflector<ARTSPController> > mReflector;
DISALLOW_EVIL_CONSTRUCTORS(ARTSPController); DISALLOW_EVIL_CONSTRUCTORS(ARTSPController);
}; };

View File

@@ -26,31 +26,57 @@
namespace android { namespace android {
ARTSPController::ARTSPController(const sp<ALooper> &looper) ARTSPController::ARTSPController(const sp<ALooper> &looper)
: mLooper(looper) { : mState(DISCONNECTED),
mLooper(looper) {
mReflector = new AHandlerReflector<ARTSPController>(this);
looper->registerHandler(mReflector);
} }
ARTSPController::~ARTSPController() { ARTSPController::~ARTSPController() {
disconnect();
mLooper->unregisterHandler(mReflector->id());
} }
status_t ARTSPController::connect(const char *url) { status_t ARTSPController::connect(const char *url) {
if (mHandler != NULL) { Mutex::Autolock autoLock(mLock);
if (mState != DISCONNECTED) {
return ERROR_ALREADY_CONNECTED; return ERROR_ALREADY_CONNECTED;
} }
sp<AMessage> msg = new AMessage(kWhatConnectDone, mReflector->id());
mHandler = new MyHandler(url, mLooper); mHandler = new MyHandler(url, mLooper);
mHandler->connect();
sleep(10); mState = CONNECTING;
return OK; mHandler->connect(msg);
while (mState == CONNECTING) {
mCondition.wait(mLock);
}
if (mState != CONNECTED) {
mHandler.clear();
}
return mConnectionResult;
} }
void ARTSPController::disconnect() { void ARTSPController::disconnect() {
if (mHandler == NULL) { Mutex::Autolock autoLock(mLock);
if (mState != CONNECTED) {
return; return;
} }
mHandler->disconnect(); sp<AMessage> msg = new AMessage(kWhatDisconnectDone, mReflector->id());
mHandler->disconnect(msg);
while (mState == CONNECTED) {
mCondition.wait(mLock);
}
mHandler.clear(); mHandler.clear();
} }
@@ -75,4 +101,31 @@ sp<MetaData> ARTSPController::getTrackMetaData(
return mHandler->getPacketSource(index)->getFormat(); return mHandler->getPacketSource(index)->getFormat();
} }
void ARTSPController::onMessageReceived(const sp<AMessage> &msg) {
switch (msg->what()) {
case kWhatConnectDone:
{
Mutex::Autolock autoLock(mLock);
CHECK(msg->findInt32("result", &mConnectionResult));
mState = (mConnectionResult == OK) ? CONNECTED : DISCONNECTED;
mCondition.signal();
break;
}
case kWhatDisconnectDone:
{
Mutex::Autolock autoLock(mLock);
mState = DISCONNECTED;
mCondition.signal();
break;
}
default:
TRESPASS();
break;
}
}
} // namespace android } // namespace android

View File

@@ -45,18 +45,21 @@ struct MyHandler : public AHandler {
PRIORITY_HIGHEST); PRIORITY_HIGHEST);
} }
void connect() { void connect(const sp<AMessage> &doneMsg) {
mDoneMsg = doneMsg;
mLooper->registerHandler(this); mLooper->registerHandler(this);
mLooper->registerHandler(mConn); mLooper->registerHandler(mConn);
(1 ? mNetLooper : mLooper)->registerHandler(mRTPConn); (1 ? mNetLooper : mLooper)->registerHandler(mRTPConn);
sp<AMessage> reply = new AMessage('conn', id());
sp<AMessage> reply = new AMessage('conn', id());
mConn->connect(mSessionURL.c_str(), reply); mConn->connect(mSessionURL.c_str(), reply);
} }
void disconnect() { void disconnect(const sp<AMessage> &doneMsg) {
sp<AMessage> reply = new AMessage('disc', id()); mDoneMsg = doneMsg;
mConn->disconnect(reply);
(new AMessage('abor', id()))->post();
} }
virtual void onMessageReceived(const sp<AMessage> &msg) { virtual void onMessageReceived(const sp<AMessage> &msg) {
@@ -250,8 +253,9 @@ struct MyHandler : public AHandler {
CHECK_EQ(response->mStatusCode, 200u); CHECK_EQ(response->mStatusCode, 200u);
sp<AMessage> msg = new AMessage('abor', id()); mDoneMsg->setInt32("result", OK);
msg->post(60000000ll); mDoneMsg->post();
mDoneMsg = NULL;
} else { } else {
sp<AMessage> reply = new AMessage('disc', id()); sp<AMessage> reply = new AMessage('disc', id());
mConn->disconnect(reply); mConn->disconnect(reply);
@@ -301,6 +305,11 @@ struct MyHandler : public AHandler {
case 'quit': case 'quit':
{ {
if (mDoneMsg != NULL) {
mDoneMsg->setInt32("result", UNKNOWN_ERROR);
mDoneMsg->post();
mDoneMsg = NULL;
}
break; break;
} }
@@ -380,6 +389,8 @@ private:
}; };
Vector<TrackInfo> mTracks; Vector<TrackInfo> mTracks;
sp<AMessage> mDoneMsg;
void setupTrack(size_t index) { void setupTrack(size_t index) {
sp<APacketSource> source = sp<APacketSource> source =
new APacketSource(mSessionDesc, index); new APacketSource(mSessionDesc, index);