am 3e22ef1e: Merge "Better handling of rtsp connection and disconnection." into gingerbread

Merge commit '3e22ef1e111966df6ad527632fdc35d105c73916' into gingerbread-plus-aosp

* commit '3e22ef1e111966df6ad527632fdc35d105c73916':
  Better handling of rtsp connection and disconnection.
This commit is contained in:
Andreas Huber
2010-08-23 12:28:26 -07:00
committed by Android Git Automerger
3 changed files with 99 additions and 14 deletions

View File

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

View File

@@ -26,31 +26,57 @@
namespace android {
ARTSPController::ARTSPController(const sp<ALooper> &looper)
: mLooper(looper) {
: mState(DISCONNECTED),
mLooper(looper) {
mReflector = new AHandlerReflector<ARTSPController>(this);
looper->registerHandler(mReflector);
}
ARTSPController::~ARTSPController() {
disconnect();
mLooper->unregisterHandler(mReflector->id());
}
status_t ARTSPController::connect(const char *url) {
if (mHandler != NULL) {
Mutex::Autolock autoLock(mLock);
if (mState != DISCONNECTED) {
return ERROR_ALREADY_CONNECTED;
}
sp<AMessage> msg = new AMessage(kWhatConnectDone, mReflector->id());
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() {
if (mHandler == NULL) {
Mutex::Autolock autoLock(mLock);
if (mState != CONNECTED) {
return;
}
mHandler->disconnect();
sp<AMessage> msg = new AMessage(kWhatDisconnectDone, mReflector->id());
mHandler->disconnect(msg);
while (mState == CONNECTED) {
mCondition.wait(mLock);
}
mHandler.clear();
}
@@ -75,4 +101,31 @@ sp<MetaData> ARTSPController::getTrackMetaData(
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

View File

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