diff options
author | Andreas Huber <andih@google.com> | 2012-09-28 10:23:51 -0700 |
---|---|---|
committer | Andreas Huber <andih@google.com> | 2012-09-28 10:23:51 -0700 |
commit | 96fc6cc65ca93009a759a3a874b82a35771b9714 (patch) | |
tree | 8084454da63f974ef6ccfe29e5e3760184ec185b | |
parent | de799a74064a363d26f4c1bbc5a59d1b7127f49f (diff) | |
download | frameworks_av-96fc6cc65ca93009a759a3a874b82a35771b9714.zip frameworks_av-96fc6cc65ca93009a759a3a874b82a35771b9714.tar.gz frameworks_av-96fc6cc65ca93009a759a3a874b82a35771b9714.tar.bz2 |
Various improvements to a cleaner shutdown of the wifi display connection.
Change-Id: Id029a89939e53c2bd1d20e572d3975ec2795c239
related-to-bug: 7247918
13 files changed, 326 insertions, 172 deletions
diff --git a/include/media/stagefright/SurfaceMediaSource.h b/include/media/stagefright/SurfaceMediaSource.h index 9e07ea4..f60a535 100644 --- a/include/media/stagefright/SurfaceMediaSource.h +++ b/include/media/stagefright/SurfaceMediaSource.h @@ -52,6 +52,8 @@ class GraphicBuffer; // may be dropped. It is possible to wait for the buffers to be // returned (but not implemented) +#define DEBUG_PENDING_BUFFERS 0 + class SurfaceMediaSource : public MediaSource, public MediaBufferObserver, protected BufferQueue::ConsumerListener { @@ -169,6 +171,10 @@ private: size_t mNumPendingBuffers; +#if DEBUG_PENDING_BUFFERS + Vector<MediaBuffer *> mPendingBuffers; +#endif + // mCurrentTimestamp is the timestamp for the current texture. It // gets set to mLastQueuedTimestamp each time updateTexImage is called. int64_t mCurrentTimestamp; diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index 8190498..af7a459 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -2471,6 +2471,9 @@ bool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) { // by this "mediaBuffer" object. Now that the OMX component has // told us that it's done with the input buffer, we can decrement // the mediaBuffer's reference count. + + ALOGV("releasing mbuf %p", mediaBuffer); + ((MediaBuffer *)mediaBuffer)->release(); mediaBuffer = NULL; diff --git a/media/libstagefright/SurfaceMediaSource.cpp b/media/libstagefright/SurfaceMediaSource.cpp index 3d3f421..9d39d0e 100644 --- a/media/libstagefright/SurfaceMediaSource.cpp +++ b/media/libstagefright/SurfaceMediaSource.cpp @@ -191,6 +191,23 @@ status_t SurfaceMediaSource::stop() ALOGV("stop"); Mutex::Autolock lock(mMutex); + if (mStopped) { + return OK; + } + + while (mNumPendingBuffers > 0) { + ALOGI("Still waiting for %d buffers to be returned.", + mNumPendingBuffers); + +#if DEBUG_PENDING_BUFFERS + for (size_t i = 0; i < mPendingBuffers.size(); ++i) { + ALOGI("%d: %p", i, mPendingBuffers.itemAt(i)); + } +#endif + + mMediaBuffersAvailableCondition.wait(mMutex); + } + mStopped = true; mFrameAvailableCondition.signal(); mMediaBuffersAvailableCondition.signal(); @@ -335,6 +352,12 @@ status_t SurfaceMediaSource::read( MediaBuffer **buffer, ++mNumPendingBuffers; +#if DEBUG_PENDING_BUFFERS + mPendingBuffers.push_back(*buffer); +#endif + + ALOGV("returning mbuf %p", *buffer); + return OK; } @@ -391,6 +414,15 @@ void SurfaceMediaSource::signalBufferReturned(MediaBuffer *buffer) { CHECK(!"signalBufferReturned: bogus buffer"); } +#if DEBUG_PENDING_BUFFERS + for (size_t i = 0; i < mPendingBuffers.size(); ++i) { + if (mPendingBuffers.itemAt(i) == buffer) { + mPendingBuffers.removeAt(i); + break; + } + } +#endif + --mNumPendingBuffers; mMediaBuffersAvailableCondition.broadcast(); } diff --git a/media/libstagefright/wifi-display/ANetworkSession.cpp b/media/libstagefright/wifi-display/ANetworkSession.cpp index 90db758..0279c34 100644 --- a/media/libstagefright/wifi-display/ANetworkSession.cpp +++ b/media/libstagefright/wifi-display/ANetworkSession.cpp @@ -176,7 +176,7 @@ ANetworkSession::Session::Session( } ANetworkSession::Session::~Session() { - ALOGI("Session %d gone", mSessionID); + ALOGV("Session %d gone", mSessionID); close(mSocket); mSocket = -1; @@ -1084,7 +1084,7 @@ void ANetworkSession::threadLoop() { } else { status_t err = session->readMore(); if (err != OK) { - ALOGI("readMore on socket %d failed w/ error %d (%s)", + ALOGE("readMore on socket %d failed w/ error %d (%s)", s, err, strerror(-err)); } } @@ -1093,7 +1093,7 @@ void ANetworkSession::threadLoop() { if (FD_ISSET(s, &ws)) { status_t err = session->writeMore(); if (err != OK) { - ALOGI("writeMore on socket %d failed w/ error %d (%s)", + ALOGE("writeMore on socket %d failed w/ error %d (%s)", s, err, strerror(-err)); } } diff --git a/media/libstagefright/wifi-display/source/Converter.cpp b/media/libstagefright/wifi-display/source/Converter.cpp index c6118d4..0cdff6b 100644 --- a/media/libstagefright/wifi-display/source/Converter.cpp +++ b/media/libstagefright/wifi-display/source/Converter.cpp @@ -20,12 +20,15 @@ #include "Converter.h" +#include "MediaPuller.h" + #include <cutils/properties.h> #include <gui/SurfaceTextureClient.h> #include <media/ICrypto.h> #include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/AMessage.h> +#include <media/stagefright/MediaBuffer.h> #include <media/stagefright/MediaCodec.h> #include <media/stagefright/MediaDefs.h> #include <media/stagefright/MediaErrors.h> @@ -53,14 +56,12 @@ Converter::Converter( } Converter::~Converter() { - if (mEncoder != NULL) { - mEncoder->release(); - mEncoder.clear(); - } + CHECK(mEncoder == NULL); +} - AString mime; - CHECK(mInputFormat->findString("mime", &mime)); - ALOGI("encoder (%s) shut down.", mime.c_str()); +void Converter::shutdownAsync() { + ALOGV("shutdown"); + (new AMessage(kWhatShutdown, id()))->post(); } status_t Converter::initCheck() const { @@ -155,16 +156,6 @@ status_t Converter::initEncoder() { return mEncoder->getOutputBuffers(&mEncoderOutputBuffers); } -void Converter::feedAccessUnit(const sp<ABuffer> &accessUnit) { - sp<AMessage> msg = new AMessage(kWhatFeedAccessUnit, id()); - msg->setBuffer("accessUnit", accessUnit); - msg->post(); -} - -void Converter::signalEOS() { - (new AMessage(kWhatInputEOS, id()))->post(); -} - void Converter::notifyError(status_t err) { sp<AMessage> notify = mNotify->dup(); notify->setInt32("what", kWhatError); @@ -174,32 +165,70 @@ void Converter::notifyError(status_t err) { void Converter::onMessageReceived(const sp<AMessage> &msg) { switch (msg->what()) { - case kWhatFeedAccessUnit: + case kWhatMediaPullerNotify: { - sp<ABuffer> accessUnit; - CHECK(msg->findBuffer("accessUnit", &accessUnit)); + int32_t what; + CHECK(msg->findInt32("what", &what)); - mInputBufferQueue.push_back(accessUnit); + if (mEncoder == NULL) { + ALOGV("got msg '%s' after encoder shutdown.", + msg->debugString().c_str()); - feedEncoderInputBuffers(); + if (what == MediaPuller::kWhatAccessUnit) { + sp<ABuffer> accessUnit; + CHECK(msg->findBuffer("accessUnit", &accessUnit)); - scheduleDoMoreWork(); - break; - } + void *mbuf; + if (accessUnit->meta()->findPointer("mediaBuffer", &mbuf) + && mbuf != NULL) { + ALOGV("releasing mbuf %p", mbuf); - case kWhatInputEOS: - { - mInputBufferQueue.push_back(NULL); + accessUnit->meta()->setPointer("mediaBuffer", NULL); + + static_cast<MediaBuffer *>(mbuf)->release(); + mbuf = NULL; + } + } + break; + } + + if (what == MediaPuller::kWhatEOS) { + mInputBufferQueue.push_back(NULL); + + feedEncoderInputBuffers(); + + scheduleDoMoreWork(); + } else { + CHECK_EQ(what, MediaPuller::kWhatAccessUnit); + + sp<ABuffer> accessUnit; + CHECK(msg->findBuffer("accessUnit", &accessUnit)); + +#if 0 + void *mbuf; + if (accessUnit->meta()->findPointer("mediaBuffer", &mbuf) + && mbuf != NULL) { + ALOGI("queueing mbuf %p", mbuf); + } +#endif + + mInputBufferQueue.push_back(accessUnit); - feedEncoderInputBuffers(); + feedEncoderInputBuffers(); - scheduleDoMoreWork(); + scheduleDoMoreWork(); + } break; } case kWhatDoMoreWork: { mDoMoreWorkPending = false; + + if (mEncoder == NULL) { + break; + } + status_t err = doMoreWork(); if (err != OK) { @@ -212,6 +241,10 @@ void Converter::onMessageReceived(const sp<AMessage> &msg) { case kWhatRequestIDRFrame: { + if (mEncoder == NULL) { + break; + } + if (mIsVideo) { ALOGI("requesting IDR frame"); mEncoder->requestIDRFrame(); @@ -219,6 +252,18 @@ void Converter::onMessageReceived(const sp<AMessage> &msg) { break; } + case kWhatShutdown: + { + ALOGI("shutting down encoder"); + mEncoder->release(); + mEncoder.clear(); + + AString mime; + CHECK(mInputFormat->findString("mime", &mime)); + ALOGI("encoder (%s) shut down.", mime.c_str()); + break; + } + default: TRESPASS(); } diff --git a/media/libstagefright/wifi-display/source/Converter.h b/media/libstagefright/wifi-display/source/Converter.h index 901ae2e..9f54523 100644 --- a/media/libstagefright/wifi-display/source/Converter.h +++ b/media/libstagefright/wifi-display/source/Converter.h @@ -51,18 +51,20 @@ struct Converter : public AHandler { kWhatError, }; -protected: - virtual ~Converter(); - virtual void onMessageReceived(const sp<AMessage> &msg); - -private: enum { - kWhatFeedAccessUnit, - kWhatInputEOS, kWhatDoMoreWork, kWhatRequestIDRFrame, + kWhatShutdown, + kWhatMediaPullerNotify, }; + void shutdownAsync(); + +protected: + virtual ~Converter(); + virtual void onMessageReceived(const sp<AMessage> &msg); + +private: status_t mInitCheck; sp<AMessage> mNotify; sp<ALooper> mCodecLooper; diff --git a/media/libstagefright/wifi-display/source/MediaPuller.cpp b/media/libstagefright/wifi-display/source/MediaPuller.cpp index 35ae539..82ae001 100644 --- a/media/libstagefright/wifi-display/source/MediaPuller.cpp +++ b/media/libstagefright/wifi-display/source/MediaPuller.cpp @@ -65,33 +65,20 @@ status_t MediaPuller::start() { return postSynchronouslyAndReturnError(new AMessage(kWhatStart, id())); } -status_t MediaPuller::stop() { - return postSynchronouslyAndReturnError(new AMessage(kWhatStop, id())); +void MediaPuller::stopAsync(const sp<AMessage> ¬ify) { + sp<AMessage> msg = new AMessage(kWhatStop, id()); + msg->setMessage("notify", notify); + msg->post(); } void MediaPuller::onMessageReceived(const sp<AMessage> &msg) { switch (msg->what()) { case kWhatStart: - case kWhatStop: { - status_t err; + status_t err = mSource->start(); - if (msg->what() == kWhatStart) { - err = mSource->start(); - - if (err == OK) { - schedulePull(); - } - } else { - sp<MetaData> meta = mSource->getFormat(); - const char *tmp; - CHECK(meta->findCString(kKeyMIMEType, &tmp)); - AString mime = tmp; - - ALOGI("MediaPuller(%s) stopping.", mime.c_str()); - err = mSource->stop(); - ALOGI("MediaPuller(%s) stopped.", mime.c_str()); - ++mPullGeneration; + if (err == OK) { + schedulePull(); } sp<AMessage> response = new AMessage; @@ -104,6 +91,24 @@ void MediaPuller::onMessageReceived(const sp<AMessage> &msg) { break; } + case kWhatStop: + { + sp<MetaData> meta = mSource->getFormat(); + const char *tmp; + CHECK(meta->findCString(kKeyMIMEType, &tmp)); + AString mime = tmp; + + ALOGI("MediaPuller(%s) stopping.", mime.c_str()); + mSource->stop(); + ALOGI("MediaPuller(%s) stopped.", mime.c_str()); + ++mPullGeneration; + + sp<AMessage> notify; + CHECK(msg->findMessage("notify", ¬ify)); + notify->post(); + break; + } + case kWhatPull: { int32_t generation; @@ -153,6 +158,10 @@ void MediaPuller::onMessageReceived(const sp<AMessage> &msg) { notify->setBuffer("accessUnit", accessUnit); notify->post(); + if (mbuf != NULL) { + ALOGV("posted mbuf %p", mbuf); + } + schedulePull(); } break; diff --git a/media/libstagefright/wifi-display/source/MediaPuller.h b/media/libstagefright/wifi-display/source/MediaPuller.h index 134e1c0..728da7b 100644 --- a/media/libstagefright/wifi-display/source/MediaPuller.h +++ b/media/libstagefright/wifi-display/source/MediaPuller.h @@ -33,7 +33,7 @@ struct MediaPuller : public AHandler { MediaPuller(const sp<MediaSource> &source, const sp<AMessage> ¬ify); status_t start(); - status_t stop(); + void stopAsync(const sp<AMessage> ¬ify); protected: virtual void onMessageReceived(const sp<AMessage> &msg); diff --git a/media/libstagefright/wifi-display/source/PlaybackSession.cpp b/media/libstagefright/wifi-display/source/PlaybackSession.cpp index 0facafe..9b729fc 100644 --- a/media/libstagefright/wifi-display/source/PlaybackSession.cpp +++ b/media/libstagefright/wifi-display/source/PlaybackSession.cpp @@ -53,14 +53,17 @@ namespace android { static size_t kMaxRTPPacketSize = 1500; static size_t kMaxNumTSPacketsPerRTPPacket = (kMaxRTPPacketSize - 12) / 188; -struct WifiDisplaySource::PlaybackSession::Track : public RefBase { - Track(const sp<ALooper> &pullLooper, +struct WifiDisplaySource::PlaybackSession::Track : public AHandler { + enum { + kWhatStopped, + }; + + Track(const sp<AMessage> ¬ify, + const sp<ALooper> &pullLooper, const sp<ALooper> &codecLooper, const sp<MediaPuller> &mediaPuller, const sp<Converter> &converter); - Track(const sp<AMessage> &format); - sp<AMessage> getFormat(); bool isAudio() const; @@ -70,20 +73,27 @@ struct WifiDisplaySource::PlaybackSession::Track : public RefBase { void setPacketizerTrackIndex(size_t index); status_t start(); - status_t stop(); + void stopAsync(); + + bool isStopped() const { return !mStarted; } void queueAccessUnit(const sp<ABuffer> &accessUnit); sp<ABuffer> dequeueAccessUnit(); protected: + virtual void onMessageReceived(const sp<AMessage> &msg); virtual ~Track(); private: + enum { + kWhatMediaPullerStopped, + }; + + sp<AMessage> mNotify; sp<ALooper> mPullLooper; sp<ALooper> mCodecLooper; sp<MediaPuller> mMediaPuller; sp<Converter> mConverter; - sp<AMessage> mFormat; bool mStarted; ssize_t mPacketizerTrackIndex; bool mIsAudio; @@ -95,11 +105,13 @@ private: }; WifiDisplaySource::PlaybackSession::Track::Track( + const sp<AMessage> ¬ify, const sp<ALooper> &pullLooper, const sp<ALooper> &codecLooper, const sp<MediaPuller> &mediaPuller, const sp<Converter> &converter) - : mPullLooper(pullLooper), + : mNotify(notify), + mPullLooper(pullLooper), mCodecLooper(codecLooper), mMediaPuller(mediaPuller), mConverter(converter), @@ -108,14 +120,8 @@ WifiDisplaySource::PlaybackSession::Track::Track( mIsAudio(IsAudioFormat(mConverter->getOutputFormat())) { } -WifiDisplaySource::PlaybackSession::Track::Track(const sp<AMessage> &format) - : mFormat(format), - mPacketizerTrackIndex(-1), - mIsAudio(IsAudioFormat(mFormat)) { -} - WifiDisplaySource::PlaybackSession::Track::~Track() { - stop(); + CHECK(!mStarted); } // static @@ -128,10 +134,6 @@ bool WifiDisplaySource::PlaybackSession::Track::IsAudioFormat( } sp<AMessage> WifiDisplaySource::PlaybackSession::Track::getFormat() { - if (mFormat != NULL) { - return mFormat; - } - return mConverter->getOutputFormat(); } @@ -155,9 +157,7 @@ void WifiDisplaySource::PlaybackSession::Track::setPacketizerTrackIndex(size_t i status_t WifiDisplaySource::PlaybackSession::Track::start() { ALOGV("Track::start isAudio=%d", mIsAudio); - if (mStarted) { - return INVALID_OPERATION; - } + CHECK(!mStarted); status_t err = OK; @@ -172,24 +172,40 @@ status_t WifiDisplaySource::PlaybackSession::Track::start() { return err; } -status_t WifiDisplaySource::PlaybackSession::Track::stop() { - ALOGV("Track::stop isAudio=%d", mIsAudio); +void WifiDisplaySource::PlaybackSession::Track::stopAsync() { + ALOGV("Track::stopAsync isAudio=%d", mIsAudio); - if (!mStarted) { - return INVALID_OPERATION; - } + CHECK(mStarted); - status_t err = OK; + mConverter->shutdownAsync(); + + sp<AMessage> msg = new AMessage(kWhatMediaPullerStopped, id()); if (mMediaPuller != NULL) { - err = mMediaPuller->stop(); + mMediaPuller->stopAsync(msg); + } else { + msg->post(); } +} - mConverter.clear(); +void WifiDisplaySource::PlaybackSession::Track::onMessageReceived( + const sp<AMessage> &msg) { + switch (msg->what()) { + case kWhatMediaPullerStopped: + { + mConverter.clear(); - mStarted = false; + mStarted = false; - return err; + sp<AMessage> notify = mNotify->dup(); + notify->setInt32("what", kWhatStopped); + notify->post(); + break; + } + + default: + TRESPASS(); + } } void WifiDisplaySource::PlaybackSession::Track::queueAccessUnit( @@ -482,15 +498,7 @@ status_t WifiDisplaySource::PlaybackSession::onFinishPlay2() { } for (size_t i = 0; i < mTracks.size(); ++i) { - status_t err = mTracks.editValueAt(i)->start(); - - if (err != OK) { - for (size_t j = 0; j < i; ++j) { - mTracks.editValueAt(j)->stop(); - } - - return err; - } + CHECK_EQ((status_t)OK, mTracks.editValueAt(i)->start()); } sp<AMessage> notify = mNotify->dup(); @@ -506,32 +514,12 @@ status_t WifiDisplaySource::PlaybackSession::pause() { return OK; } -status_t WifiDisplaySource::PlaybackSession::destroy() { - mTracks.clear(); - - mPacketizer.clear(); - - mTracks.clear(); - -#if ENABLE_RETRANSMISSION - if (mRTCPRetransmissionSessionID != 0) { - mNetSession->destroySession(mRTCPRetransmissionSessionID); - } - - if (mRTPRetransmissionSessionID != 0) { - mNetSession->destroySession(mRTPRetransmissionSessionID); - } -#endif +void WifiDisplaySource::PlaybackSession::destroyAsync() { + ALOGI("destroyAsync"); - if (mRTCPSessionID != 0) { - mNetSession->destroySession(mRTCPSessionID); - } - - if (mRTPSessionID != 0) { - mNetSession->destroySession(mRTPSessionID); + for (size_t i = 0; i < mTracks.size(); ++i) { + mTracks.valueAt(i)->stopAsync(); } - - return OK; } void WifiDisplaySource::PlaybackSession::onMessageReceived( @@ -669,32 +657,6 @@ void WifiDisplaySource::PlaybackSession::onMessageReceived( break; } - case kWhatMediaPullerNotify: - { - int32_t what; - CHECK(msg->findInt32("what", &what)); - - if (what == MediaPuller::kWhatEOS) { - ALOGI("input eos"); - - for (size_t i = 0; i < mTracks.size(); ++i) { - mTracks.valueAt(i)->converter()->signalEOS(); - } - } else { - CHECK_EQ(what, MediaPuller::kWhatAccessUnit); - - size_t trackIndex; - CHECK(msg->findSize("trackIndex", &trackIndex)); - - sp<ABuffer> accessUnit; - CHECK(msg->findBuffer("accessUnit", &accessUnit)); - - mTracks.valueFor(trackIndex)->converter() - ->feedAccessUnit(accessUnit); - } - break; - } - case kWhatConverterNotify: { int32_t what; @@ -776,6 +738,57 @@ void WifiDisplaySource::PlaybackSession::onMessageReceived( break; } + case kWhatTrackNotify: + { + int32_t what; + CHECK(msg->findInt32("what", &what)); + + size_t trackIndex; + CHECK(msg->findSize("trackIndex", &trackIndex)); + + if (what == Track::kWhatStopped) { + bool allTracksAreStopped = true; + for (size_t i = 0; i < mTracks.size(); ++i) { + const sp<Track> &track = mTracks.valueAt(i); + if (!track->isStopped()) { + allTracksAreStopped = false; + break; + } + } + + if (!allTracksAreStopped) { + break; + } + + mTracks.clear(); + + mPacketizer.clear(); + +#if ENABLE_RETRANSMISSION + if (mRTCPRetransmissionSessionID != 0) { + mNetSession->destroySession(mRTCPRetransmissionSessionID); + } + + if (mRTPRetransmissionSessionID != 0) { + mNetSession->destroySession(mRTPRetransmissionSessionID); + } +#endif + + if (mRTCPSessionID != 0) { + mNetSession->destroySession(mRTCPSessionID); + } + + if (mRTPSessionID != 0) { + mNetSession->destroySession(mRTPSessionID); + } + + sp<AMessage> notify = mNotify->dup(); + notify->setInt32("what", kWhatSessionDestroyed); + notify->post(); + } + break; + } + default: TRESPASS(); } @@ -817,11 +830,6 @@ status_t WifiDisplaySource::PlaybackSession::addSource( trackIndex = mTracks.size(); - notify = new AMessage(kWhatMediaPullerNotify, id()); - notify->setSize("trackIndex", trackIndex); - sp<MediaPuller> puller = new MediaPuller(source, notify); - pullLooper->registerHandler(puller); - sp<AMessage> format; status_t err = convertMetaDataToMessage(source->getFormat(), &format); CHECK_EQ(err, (status_t)OK); @@ -842,11 +850,25 @@ status_t WifiDisplaySource::PlaybackSession::addSource( looper()->registerHandler(converter); + notify = new AMessage(Converter::kWhatMediaPullerNotify, converter->id()); + notify->setSize("trackIndex", trackIndex); + + sp<MediaPuller> puller = new MediaPuller(source, notify); + pullLooper->registerHandler(puller); + if (numInputBuffers != NULL) { *numInputBuffers = converter->getInputBufferCount(); } - mTracks.add(trackIndex, new Track(pullLooper, codecLooper, puller, converter)); + notify = new AMessage(kWhatTrackNotify, id()); + notify->setSize("trackIndex", trackIndex); + + sp<Track> track = new Track( + notify, pullLooper, codecLooper, puller, converter); + + looper()->registerHandler(track); + + mTracks.add(trackIndex, track); if (isVideo) { mVideoTrackIndex = trackIndex; diff --git a/media/libstagefright/wifi-display/source/PlaybackSession.h b/media/libstagefright/wifi-display/source/PlaybackSession.h index 342fc85..9237a72 100644 --- a/media/libstagefright/wifi-display/source/PlaybackSession.h +++ b/media/libstagefright/wifi-display/source/PlaybackSession.h @@ -51,7 +51,7 @@ struct WifiDisplaySource::PlaybackSession : public AHandler { const char *clientIP, int32_t clientRtp, int32_t clientRtcp, TransportMode transportMode); - status_t destroy(); + void destroyAsync(); int32_t getRTPPort() const; @@ -72,6 +72,7 @@ struct WifiDisplaySource::PlaybackSession : public AHandler { kWhatSessionDead, kWhatBinaryData, kWhatSessionEstablished, + kWhatSessionDestroyed, }; protected: @@ -91,6 +92,7 @@ private: #endif kWhatMediaPullerNotify, kWhatConverterNotify, + kWhatTrackNotify, kWhatUpdateSurface, kWhatFinishPlay, }; diff --git a/media/libstagefright/wifi-display/source/RepeaterSource.cpp b/media/libstagefright/wifi-display/source/RepeaterSource.cpp index 56e8860..483d29c 100644 --- a/media/libstagefright/wifi-display/source/RepeaterSource.cpp +++ b/media/libstagefright/wifi-display/source/RepeaterSource.cpp @@ -50,6 +50,8 @@ status_t RepeaterSource::start(MetaData *params) { } status_t RepeaterSource::stop() { + ALOGV("stopping"); + if (mLooper != NULL) { mLooper->stop(); mLooper.clear(); @@ -57,7 +59,17 @@ status_t RepeaterSource::stop() { mReflector.clear(); } - return mSource->stop(); + if (mBuffer != NULL) { + ALOGV("releasing mbuf %p", mBuffer); + mBuffer->release(); + mBuffer = NULL; + } + + status_t err = mSource->stop(); + + ALOGV("stopped"); + + return err; } sp<MetaData> RepeaterSource::getFormat() { @@ -117,6 +129,8 @@ void RepeaterSource::onMessageReceived(const sp<AMessage> &msg) { MediaBuffer *buffer; status_t err = mSource->read(&buffer); + ALOGV("read mbuf %p", buffer); + Mutex::Autolock autoLock(mLock); if (mBuffer != NULL) { mBuffer->release(); diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp index 16c0f35..8091cc4 100644 --- a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp +++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp @@ -293,6 +293,8 @@ void WifiDisplaySource::onMessageReceived(const sp<AMessage> &msg) { mClientInfo.mPlaybackSession->height(), 0 /* flags */); } + } else if (what == PlaybackSession::kWhatSessionDestroyed) { + disconnectClient2(); } else { CHECK_EQ(what, PlaybackSession::kWhatBinaryData); @@ -1117,6 +1119,12 @@ status_t WifiDisplaySource::onTeardownRequest( void WifiDisplaySource::finishStop() { ALOGV("finishStop"); + disconnectClientAsync(); +} + +void WifiDisplaySource::finishStopAfterDisconnectingClient() { + ALOGV("finishStopAfterDisconnectingClient"); + #if REQUIRE_HDCP if (mHDCP != NULL) { ALOGI("Initiating HDCP shutdown."); @@ -1137,14 +1145,12 @@ void WifiDisplaySource::finishStop2() { mHDCP.clear(); #endif - disconnectClient(); - if (mSessionID != 0) { mNetSession->destroySession(mSessionID); mSessionID = 0; } - ALOGV("finishStop2 completed."); + ALOGI("We're stopped."); status_t err = OK; @@ -1264,14 +1270,26 @@ sp<WifiDisplaySource::PlaybackSession> WifiDisplaySource::findPlaybackSession( return mClientInfo.mPlaybackSession; } -void WifiDisplaySource::disconnectClient() { +void WifiDisplaySource::disconnectClientAsync() { + ALOGV("disconnectClient"); + + if (mClientInfo.mPlaybackSession == NULL) { + disconnectClient2(); + return; + } + + if (mClientInfo.mPlaybackSession != NULL) { + ALOGV("Destroying PlaybackSession"); + mClientInfo.mPlaybackSession->destroyAsync(); + } +} + +void WifiDisplaySource::disconnectClient2() { + ALOGV("disconnectClient2"); + if (mClientInfo.mPlaybackSession != NULL) { - sp<PlaybackSession> playbackSession = mClientInfo.mPlaybackSession; + looper()->unregisterHandler(mClientInfo.mPlaybackSession->id()); mClientInfo.mPlaybackSession.clear(); - - ALOGI("Destroying PlaybackSession"); - playbackSession->destroy(); - looper()->unregisterHandler(playbackSession->id()); } if (mClientSessionID != 0) { @@ -1280,6 +1298,8 @@ void WifiDisplaySource::disconnectClient() { } mClient->onDisplayDisconnected(); + + finishStopAfterDisconnectingClient(); } #if REQUIRE_HDCP diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.h b/media/libstagefright/wifi-display/source/WifiDisplaySource.h index 77b15f8..ade623a 100644 --- a/media/libstagefright/wifi-display/source/WifiDisplaySource.h +++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.h @@ -200,11 +200,10 @@ private: sp<PlaybackSession> findPlaybackSession( const sp<ParsedMessage> &data, int32_t *playbackSessionID) const; - // Disconnects the current client and shuts down its playback session - // (if any). - void disconnectClient(); - void finishStop(); + void disconnectClientAsync(); + void disconnectClient2(); + void finishStopAfterDisconnectingClient(); void finishStop2(); DISALLOW_EVIL_CONSTRUCTORS(WifiDisplaySource); |