diff options
Diffstat (limited to 'media')
-rw-r--r-- | media/libeffects/visualizer/EffectVisualizer.cpp | 28 | ||||
-rw-r--r-- | media/libstagefright/rtsp/ARTPConnection.cpp | 62 | ||||
-rw-r--r-- | media/libstagefright/rtsp/ARTSPConnection.cpp | 134 | ||||
-rw-r--r-- | media/libstagefright/rtsp/ARTSPConnection.h | 2 | ||||
-rw-r--r-- | media/libstagefright/rtsp/MyHandler.h | 17 |
5 files changed, 159 insertions, 84 deletions
diff --git a/media/libeffects/visualizer/EffectVisualizer.cpp b/media/libeffects/visualizer/EffectVisualizer.cpp index 3c3af8f..1a06cc6 100644 --- a/media/libeffects/visualizer/EffectVisualizer.cpp +++ b/media/libeffects/visualizer/EffectVisualizer.cpp @@ -47,17 +47,22 @@ enum visualizer_state_e { VISUALIZER_STATE_ACTIVE, }; +// maximum number of reads from same buffer before resetting capture buffer. This means +// that the framework has stopped playing audio and we must start returning silence +#define MAX_STALL_COUNT 10 + struct VisualizerContext { const struct effect_interface_s *mItfe; effect_config_t mConfig; - uint32_t mState; uint32_t mCaptureIdx; uint32_t mCaptureSize; - uint32_t mCurrentBuf; + uint8_t mState; + uint8_t mCurrentBuf; + uint8_t mLastBuf; + uint8_t mStallCount; uint8_t mCaptureBuf[2][VISUALIZER_CAPTURE_SIZE_MAX]; }; - // //--- Local functions // @@ -66,6 +71,8 @@ void Visualizer_reset(VisualizerContext *pContext) { pContext->mCaptureIdx = 0; pContext->mCurrentBuf = 0; + pContext->mLastBuf = 1; + pContext->mStallCount = 0; memset(pContext->mCaptureBuf[0], 0x80, VISUALIZER_CAPTURE_SIZE_MAX); memset(pContext->mCaptureBuf[1], 0x80, VISUALIZER_CAPTURE_SIZE_MAX); } @@ -417,9 +424,24 @@ int Visualizer_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize, memcpy(pReplyData, pContext->mCaptureBuf[pContext->mCurrentBuf ^ 1], pContext->mCaptureSize); + // if audio framework has stopped playing audio although the effect is still + // active we must clear the capture buffer to return silence + if (pContext->mLastBuf == pContext->mCurrentBuf) { + if (pContext->mStallCount < MAX_STALL_COUNT) { + if (++pContext->mStallCount == MAX_STALL_COUNT) { + memset(pContext->mCaptureBuf[pContext->mCurrentBuf ^ 1], + 0x80, + pContext->mCaptureSize); + } + } + } else { + pContext->mStallCount = 0; + } + pContext->mLastBuf = pContext->mCurrentBuf; } else { memset(pReplyData, 0x80, pContext->mCaptureSize); } + break; default: diff --git a/media/libstagefright/rtsp/ARTPConnection.cpp b/media/libstagefright/rtsp/ARTPConnection.cpp index 47de4e0..cd374e2 100644 --- a/media/libstagefright/rtsp/ARTPConnection.cpp +++ b/media/libstagefright/rtsp/ARTPConnection.cpp @@ -220,7 +220,7 @@ void ARTPConnection::onRemoveStream(const sp<AMessage> &msg) { } if (it == mStreams.end()) { - TRESPASS(); + return; } mStreams.erase(it); @@ -274,41 +274,52 @@ void ARTPConnection::onPollStreams() { } int res = select(maxSocket + 1, &rs, NULL, NULL, &tv); - CHECK_GE(res, 0); if (res > 0) { - for (List<StreamInfo>::iterator it = mStreams.begin(); - it != mStreams.end(); ++it) { + List<StreamInfo>::iterator it = mStreams.begin(); + while (it != mStreams.end()) { if ((*it).mIsInjected) { + ++it; continue; } + status_t err = OK; if (FD_ISSET(it->mRTPSocket, &rs)) { - receive(&*it, true); + err = receive(&*it, true); } - if (FD_ISSET(it->mRTCPSocket, &rs)) { - receive(&*it, false); + if (err == OK && FD_ISSET(it->mRTCPSocket, &rs)) { + err = receive(&*it, false); } + + if (err == -ECONNRESET) { + // socket failure, this stream is dead, Jim. + + LOGW("failed to receive RTP/RTCP datagram."); + it = mStreams.erase(it); + continue; + } + + ++it; } } - postPollEvent(); - int64_t nowUs = ALooper::GetNowUs(); if (mLastReceiverReportTimeUs <= 0 || mLastReceiverReportTimeUs + 5000000ll <= nowUs) { sp<ABuffer> buffer = new ABuffer(kMaxUDPSize); - for (List<StreamInfo>::iterator it = mStreams.begin(); - it != mStreams.end(); ++it) { + List<StreamInfo>::iterator it = mStreams.begin(); + while (it != mStreams.end()) { StreamInfo *s = &*it; if (s->mIsInjected) { + ++it; continue; } if (s->mNumRTCPPacketsReceived == 0) { // We have never received any RTCP packets on this stream, // we don't even know where to send a report. + ++it; continue; } @@ -327,16 +338,34 @@ void ARTPConnection::onPollStreams() { if (buffer->size() > 0) { LOGV("Sending RR..."); - ssize_t n = sendto( + ssize_t n; + do { + n = sendto( s->mRTCPSocket, buffer->data(), buffer->size(), 0, (const struct sockaddr *)&s->mRemoteRTCPAddr, sizeof(s->mRemoteRTCPAddr)); + } while (n < 0 && errno == EINTR); + + if (n <= 0) { + LOGW("failed to send RTCP receiver report (%s).", + n == 0 ? "connection gone" : strerror(errno)); + + it = mStreams.erase(it); + continue; + } + CHECK_EQ(n, (ssize_t)buffer->size()); mLastReceiverReportTimeUs = nowUs; } + + ++it; } } + + if (!mStreams.empty()) { + postPollEvent(); + } } status_t ARTPConnection::receive(StreamInfo *s, bool receiveRTP) { @@ -350,16 +379,19 @@ status_t ARTPConnection::receive(StreamInfo *s, bool receiveRTP) { (!receiveRTP && s->mNumRTCPPacketsReceived == 0) ? sizeof(s->mRemoteRTCPAddr) : 0; - ssize_t nbytes = recvfrom( + ssize_t nbytes; + do { + nbytes = recvfrom( receiveRTP ? s->mRTPSocket : s->mRTCPSocket, buffer->data(), buffer->capacity(), 0, remoteAddrLen > 0 ? (struct sockaddr *)&s->mRemoteRTCPAddr : NULL, remoteAddrLen > 0 ? &remoteAddrLen : NULL); + } while (nbytes < 0 && errno == EINTR); - if (nbytes < 0) { - return -1; + if (nbytes <= 0) { + return -ECONNRESET; } buffer->setRange(0, nbytes); diff --git a/media/libstagefright/rtsp/ARTSPConnection.cpp b/media/libstagefright/rtsp/ARTSPConnection.cpp index bd0e491..4f0363b 100644 --- a/media/libstagefright/rtsp/ARTSPConnection.cpp +++ b/media/libstagefright/rtsp/ARTSPConnection.cpp @@ -187,10 +187,13 @@ bool ARTSPConnection::ParseURL( return true; } -static void MakeSocketBlocking(int s, bool blocking) { +static status_t MakeSocketBlocking(int s, bool blocking) { // Make socket non-blocking. int flags = fcntl(s, F_GETFL, 0); - CHECK_NE(flags, -1); + + if (flags == -1) { + return UNKNOWN_ERROR; + } if (blocking) { flags &= ~O_NONBLOCK; @@ -198,7 +201,9 @@ static void MakeSocketBlocking(int s, bool blocking) { flags |= O_NONBLOCK; } - CHECK_NE(fcntl(s, F_SETFL, flags), -1); + flags = fcntl(s, F_SETFL, flags); + + return flags == -1 ? UNKNOWN_ERROR : OK; } void ARTSPConnection::onConnect(const sp<AMessage> &msg) { @@ -302,27 +307,32 @@ void ARTSPConnection::onConnect(const sp<AMessage> &msg) { reply->post(); } +void ARTSPConnection::performDisconnect() { + if (mUIDValid) { + HTTPBase::UnRegisterSocketUserTag(mSocket); + } + close(mSocket); + mSocket = -1; + + flushPendingRequests(); + + mUser.clear(); + mPass.clear(); + mAuthType = NONE; + mNonce.clear(); + + mState = DISCONNECTED; +} + void ARTSPConnection::onDisconnect(const sp<AMessage> &msg) { if (mState == CONNECTED || mState == CONNECTING) { - if (mUIDValid) { - HTTPBase::UnRegisterSocketUserTag(mSocket); - } - close(mSocket); - mSocket = -1; - - flushPendingRequests(); + performDisconnect(); } sp<AMessage> reply; CHECK(msg->findMessage("reply", &reply)); reply->setInt32("result", OK); - mState = DISCONNECTED; - - mUser.clear(); - mPass.clear(); - mAuthType = NONE; - mNonce.clear(); reply->post(); } @@ -427,21 +437,25 @@ void ARTSPConnection::onSendRequest(const sp<AMessage> &msg) { send(mSocket, request.c_str() + numBytesSent, request.size() - numBytesSent, 0); - if (n == 0) { - // Server closed the connection. - LOGE("Server unexpectedly closed the connection."); + if (n < 0 && errno == EINTR) { + continue; + } - reply->setInt32("result", ERROR_IO); - reply->post(); - return; - } else if (n < 0) { - if (errno == EINTR) { - continue; + if (n <= 0) { + performDisconnect(); + + if (n == 0) { + // Server closed the connection. + LOGE("Server unexpectedly closed the connection."); + + reply->setInt32("result", ERROR_IO); + reply->post(); + } else { + LOGE("Error sending rtsp request. (%s)", strerror(errno)); + reply->setInt32("result", -errno); + reply->post(); } - LOGE("Error sending rtsp request."); - reply->setInt32("result", -errno); - reply->post(); return; } @@ -512,17 +526,22 @@ status_t ARTSPConnection::receive(void *data, size_t size) { size_t offset = 0; while (offset < size) { ssize_t n = recv(mSocket, (uint8_t *)data + offset, size - offset, 0); - if (n == 0) { - // Server closed the connection. - LOGE("Server unexpectedly closed the connection."); - return ERROR_IO; - } else if (n < 0) { - if (errno == EINTR) { - continue; - } - LOGE("Error reading rtsp response."); - return -errno; + if (n < 0 && errno == EINTR) { + continue; + } + + if (n <= 0) { + performDisconnect(); + + if (n == 0) { + // Server closed the connection. + LOGE("Server unexpectedly closed the connection."); + return ERROR_IO; + } else { + LOGE("Error reading rtsp response. (%s)", strerror(errno)); + return -errno; + } } offset += (size_t)n; @@ -681,24 +700,8 @@ bool ARTSPConnection::receiveRTSPReponse() { if (contentLength > 0) { response->mContent = new ABuffer(contentLength); - size_t numBytesRead = 0; - while (numBytesRead < contentLength) { - ssize_t n = recv( - mSocket, response->mContent->data() + numBytesRead, - contentLength - numBytesRead, 0); - - if (n == 0) { - // Server closed the connection. - TRESPASS(); - } else if (n < 0) { - if (errno == EINTR) { - continue; - } - - TRESPASS(); - } - - numBytesRead += (size_t)n; + if (receive(response->mContent->data(), contentLength) != OK) { + return false; } } @@ -765,17 +768,20 @@ bool ARTSPConnection::handleServerRequest(const sp<ARTSPResponse> &request) { send(mSocket, response.c_str() + numBytesSent, response.size() - numBytesSent, 0); - if (n == 0) { - // Server closed the connection. - LOGE("Server unexpectedly closed the connection."); + if (n < 0 && errno == EINTR) { + continue; + } - return false; - } else if (n < 0) { - if (errno == EINTR) { - continue; + if (n <= 0) { + if (n == 0) { + // Server closed the connection. + LOGE("Server unexpectedly closed the connection."); + } else { + LOGE("Error sending rtsp response (%s).", strerror(errno)); } - LOGE("Error sending rtsp response."); + performDisconnect(); + return false; } diff --git a/media/libstagefright/rtsp/ARTSPConnection.h b/media/libstagefright/rtsp/ARTSPConnection.h index 5cb84fd..68f2d59 100644 --- a/media/libstagefright/rtsp/ARTSPConnection.h +++ b/media/libstagefright/rtsp/ARTSPConnection.h @@ -91,6 +91,8 @@ private: AString mUserAgent; + void performDisconnect(); + void onConnect(const sp<AMessage> &msg); void onDisconnect(const sp<AMessage> &msg); void onCompleteConnection(const sp<AMessage> &msg); diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h index 6a5efa4..794c60b 100644 --- a/media/libstagefright/rtsp/MyHandler.h +++ b/media/libstagefright/rtsp/MyHandler.h @@ -463,8 +463,17 @@ struct MyHandler : public AHandler { mBaseURL = tmp; } - CHECK_GT(mSessionDesc->countTracks(), 1u); - setupTrack(1); + if (mSessionDesc->countTracks() < 2) { + // There's no actual tracks in this session. + // The first "track" is merely session meta + // data. + + LOGW("Session doesn't contain any playable " + "tracks. Aborting."); + result = ERROR_UNSUPPORTED; + } else { + setupTrack(1); + } } } } @@ -783,9 +792,13 @@ struct MyHandler : public AHandler { } if (mNumAccessUnitsReceived == 0) { +#if 1 LOGI("stream ended? aborting."); (new AMessage('abor', id()))->post(); break; +#else + LOGI("haven't seen an AU in a looong time."); +#endif } mNumAccessUnitsReceived = 0; |