summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/wifi-display/MediaReceiver.cpp
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2013-03-05 10:56:27 -0800
committerAndreas Huber <andih@google.com>2013-03-05 13:07:19 -0800
commita556c4822fc205db0d27834ba5b637c351d73ffa (patch)
tree814471eaca96e0c8e7237563ff3f303171ba8546 /media/libstagefright/wifi-display/MediaReceiver.cpp
parentd573622dc001c23223cb26b1f55fb75be189e77d (diff)
downloadframeworks_av-a556c4822fc205db0d27834ba5b637c351d73ffa.zip
frameworks_av-a556c4822fc205db0d27834ba5b637c351d73ffa.tar.gz
frameworks_av-a556c4822fc205db0d27834ba5b637c351d73ffa.tar.bz2
Squashed commit of the following:
commit e5919b1f57ea61fa1d380dfdb4e3e832ce73d79d Author: Andreas Huber <andih@google.com> Date: Wed Feb 27 16:38:48 2013 -0800 Configure TCP datagram sockets to be TCP_NODELAY. Change-Id: Ia724a81e6e27dccd00ac84603e712d69ca77a0cd commit 1b52b393183db8a6dc000a7c31baac544ccfc50c Author: Andreas Huber <andih@google.com> Date: Wed Feb 27 14:26:01 2013 -0800 Send IDR frame requests on packet loss. Change-Id: I53b7fb85cbd6923491113b93ec3e2175726d654a commit 68d76b4b3a0181b30abc57cd2915273210530a6d Author: Andreas Huber <andih@google.com> Date: Tue Feb 26 15:12:34 2013 -0800 Revive TunnelRenderer Change-Id: I8c5a9d982793b1c5b841c828227b354f1dab618c commit 3df28a8e9d8bcdc1430016bb088d097eca653b56 Author: Andreas Huber <andih@google.com> Date: Tue Feb 26 13:53:14 2013 -0800 Disable suspension of video updates. Change-Id: I7e3a16b8d7dd7a55d9f962a2236388931f664106 commit 2ec7a79de019a26ec415016c1478afd762f069cd Author: Andreas Huber <andih@google.com> Date: Tue Feb 26 08:54:40 2013 -0800 Adds an SNTP client to wfd. Change-Id: Icd7d6104e951e1443e4c1b81ccf6b3731d79d3ec commit c81c3bb5725bb4079a4d7fb02151ad0bb540632f Author: Andreas Huber <andih@google.com> Date: Mon Feb 25 10:00:58 2013 -0800 Squashed commit of the following: commit b83a4ec96659ef6f6b7c2090fdd866abe3ab78ba Author: Andreas Huber <andih@google.com> Date: Mon Feb 25 09:28:11 2013 -0800 Some reorganization of the rtp code, renamed StreamHub -> MediaSender Change-Id: I8cf67444960e60426bf74880af1acce41e8b2fef commit 7769cbd739f2a67c58e0c6a7b1a21a12210c7c4d Author: Andreas Huber <andih@google.com> Date: Fri Feb 22 16:12:18 2013 -0800 Choose a smaller MTU to avoid fragmented IPv4 packets, fix AVC assembler. Change-Id: I274b3cc1483c4e9f4d146dbf9f3d9f7557ef7ef9 commit 1f687ee80a88b56d614c2cf408ff729114ff86a0 Author: Andreas Huber <andih@google.com> Date: Fri Feb 22 11:38:31 2013 -0800 better reporting. Change-Id: I67f0bb51f106ea77f5cc75938b053c8e8e8f688e commit 7950c1cd59213eb5f281fcde44a772ecffae473d Author: Andreas Huber <andih@google.com> Date: Fri Feb 22 09:07:41 2013 -0800 stuff Change-Id: Ib99416366d3eec6e6ad69b4d791a8a9408410f3b commit 33c09045b0f86fcaa4619cbd679b47a074f71231 Author: Andreas Huber <andih@google.com> Date: Thu Feb 21 15:54:01 2013 -0800 Render frames according to their timestamps. Change-Id: I8143a95cffe775799d6a4bb093558bd7abb1f063 commit d8b6daae2160bf1c016d7c6251256b46bb89db42 Author: Andreas Huber <andih@google.com> Date: Thu Feb 21 15:01:27 2013 -0800 Better packet-lost logic. Change-Id: I611eee5a42bd089638cf45b0e16f628ff2a955ab commit 782c6b15717e2d062d96665a089d06c0577733d0 Author: Andreas Huber <andih@google.com> Date: Wed Feb 20 15:06:47 2013 -0800 Add a dedicated looper for the MediaReceiver Change-Id: I3b79cad367fb69c9a160a8d009af8c5f5142b98e commit 4c7b8b10861674b773270103bcabd1a99486a691 Author: Andreas Huber <andih@google.com> Date: Wed Feb 20 14:30:28 2013 -0800 Tweaks to RTPSender and RTPReceiver Change-Id: Ib535552f289a26cfead6df8c63e4c63d3987d4e9 commit 39226b28177a816cda5c67b321745d396b18277d Author: Andreas Huber <andih@google.com> Date: Tue Feb 19 08:48:25 2013 -0800 Playing around with non muxed delivery Change-Id: I845375f6938d04bc30502840c2ceb7688dc9b237 commit c16d21de75d8ecdbcd9abce14934afe484970061 Author: Andreas Huber <andih@google.com> Date: Wed Feb 13 14:43:35 2013 -0800 A more solid base for RTP communication. Change-Id: I52033eeb0feba0ff029d61553a821c82f2fa1c3f Change-Id: I57e3bcfc1c59a012b15aaaa42ed81f09c34c26bb Change-Id: I4b09db4a44d0eeded7a1658f6dc6c97d4b8be720
Diffstat (limited to 'media/libstagefright/wifi-display/MediaReceiver.cpp')
-rw-r--r--media/libstagefright/wifi-display/MediaReceiver.cpp311
1 files changed, 311 insertions, 0 deletions
diff --git a/media/libstagefright/wifi-display/MediaReceiver.cpp b/media/libstagefright/wifi-display/MediaReceiver.cpp
new file mode 100644
index 0000000..3c92d41
--- /dev/null
+++ b/media/libstagefright/wifi-display/MediaReceiver.cpp
@@ -0,0 +1,311 @@
+/*
+ * Copyright 2013, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "MediaReceiver"
+#include <utils/Log.h>
+
+#include "MediaReceiver.h"
+
+#include "ANetworkSession.h"
+#include "AnotherPacketSource.h"
+#include "rtp/RTPReceiver.h"
+
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/Utils.h>
+
+namespace android {
+
+MediaReceiver::MediaReceiver(
+ const sp<ANetworkSession> &netSession,
+ const sp<AMessage> &notify)
+ : mNetSession(netSession),
+ mNotify(notify),
+ mMode(MODE_UNDEFINED),
+ mGeneration(0),
+ mInitStatus(OK),
+ mInitDoneCount(0) {
+}
+
+MediaReceiver::~MediaReceiver() {
+}
+
+ssize_t MediaReceiver::addTrack(
+ RTPReceiver::TransportMode transportMode,
+ int32_t *localRTPPort) {
+ if (mMode != MODE_UNDEFINED) {
+ return INVALID_OPERATION;
+ }
+
+ size_t trackIndex = mTrackInfos.size();
+
+ TrackInfo info;
+
+ sp<AMessage> notify = new AMessage(kWhatReceiverNotify, id());
+ notify->setInt32("generation", mGeneration);
+ notify->setSize("trackIndex", trackIndex);
+
+ info.mReceiver = new RTPReceiver(mNetSession, notify);
+ looper()->registerHandler(info.mReceiver);
+
+ info.mReceiver->registerPacketType(
+ 33, RTPReceiver::PACKETIZATION_TRANSPORT_STREAM);
+
+ info.mReceiver->registerPacketType(
+ 96, RTPReceiver::PACKETIZATION_AAC);
+
+ info.mReceiver->registerPacketType(
+ 97, RTPReceiver::PACKETIZATION_H264);
+
+ status_t err = info.mReceiver->initAsync(transportMode, localRTPPort);
+
+ if (err != OK) {
+ looper()->unregisterHandler(info.mReceiver->id());
+ info.mReceiver.clear();
+
+ return err;
+ }
+
+ mTrackInfos.push_back(info);
+
+ return trackIndex;
+}
+
+status_t MediaReceiver::connectTrack(
+ size_t trackIndex,
+ const char *remoteHost,
+ int32_t remoteRTPPort,
+ int32_t remoteRTCPPort) {
+ if (trackIndex >= mTrackInfos.size()) {
+ return -ERANGE;
+ }
+
+ TrackInfo *info = &mTrackInfos.editItemAt(trackIndex);
+ return info->mReceiver->connect(remoteHost, remoteRTPPort, remoteRTCPPort);
+}
+
+status_t MediaReceiver::initAsync(Mode mode) {
+ if ((mode == MODE_TRANSPORT_STREAM || mode == MODE_TRANSPORT_STREAM_RAW)
+ && mTrackInfos.size() > 1) {
+ return INVALID_OPERATION;
+ }
+
+ sp<AMessage> msg = new AMessage(kWhatInit, id());
+ msg->setInt32("mode", mode);
+ msg->post();
+
+ return OK;
+}
+
+void MediaReceiver::onMessageReceived(const sp<AMessage> &msg) {
+ switch (msg->what()) {
+ case kWhatInit:
+ {
+ int32_t mode;
+ CHECK(msg->findInt32("mode", &mode));
+
+ CHECK_EQ(mMode, MODE_UNDEFINED);
+ mMode = (Mode)mode;
+
+ if (mInitStatus != OK || mInitDoneCount == mTrackInfos.size()) {
+ notifyInitDone(mInitStatus);
+ }
+
+ mTSParser = new ATSParser(ATSParser::ALIGNED_VIDEO_DATA);
+ mFormatKnownMask = 0;
+ break;
+ }
+
+ case kWhatReceiverNotify:
+ {
+ int32_t generation;
+ CHECK(msg->findInt32("generation", &generation));
+ if (generation != mGeneration) {
+ break;
+ }
+
+ onReceiverNotify(msg);
+ break;
+ }
+
+ default:
+ TRESPASS();
+ }
+}
+
+void MediaReceiver::onReceiverNotify(const sp<AMessage> &msg) {
+ int32_t what;
+ CHECK(msg->findInt32("what", &what));
+
+ switch (what) {
+ case RTPReceiver::kWhatInitDone:
+ {
+ ++mInitDoneCount;
+
+ int32_t err;
+ CHECK(msg->findInt32("err", &err));
+
+ if (err != OK) {
+ mInitStatus = err;
+ ++mGeneration;
+ }
+
+ if (mMode != MODE_UNDEFINED) {
+ if (mInitStatus != OK || mInitDoneCount == mTrackInfos.size()) {
+ notifyInitDone(mInitStatus);
+ }
+ }
+ break;
+ }
+
+ case RTPReceiver::kWhatError:
+ {
+ int32_t err;
+ CHECK(msg->findInt32("err", &err));
+
+ notifyError(err);
+ break;
+ }
+
+ case RTPReceiver::kWhatAccessUnit:
+ {
+ size_t trackIndex;
+ CHECK(msg->findSize("trackIndex", &trackIndex));
+
+ sp<ABuffer> accessUnit;
+ CHECK(msg->findBuffer("accessUnit", &accessUnit));
+
+ int32_t followsDiscontinuity;
+ if (!msg->findInt32(
+ "followsDiscontinuity", &followsDiscontinuity)) {
+ followsDiscontinuity = 0;
+ }
+
+ if (mMode == MODE_TRANSPORT_STREAM) {
+ if (followsDiscontinuity) {
+ mTSParser->signalDiscontinuity(
+ ATSParser::DISCONTINUITY_TIME, NULL /* extra */);
+ }
+
+ for (size_t offset = 0;
+ offset < accessUnit->size(); offset += 188) {
+ status_t err = mTSParser->feedTSPacket(
+ accessUnit->data() + offset, 188);
+
+ if (err != OK) {
+ notifyError(err);
+ break;
+ }
+ }
+
+ drainPackets(0 /* trackIndex */, ATSParser::VIDEO);
+ drainPackets(1 /* trackIndex */, ATSParser::AUDIO);
+ } else {
+ postAccessUnit(trackIndex, accessUnit, NULL);
+ }
+ break;
+ }
+
+ case RTPReceiver::kWhatPacketLost:
+ {
+ notifyPacketLost();
+ break;
+ }
+
+ default:
+ TRESPASS();
+ }
+}
+
+void MediaReceiver::drainPackets(
+ size_t trackIndex, ATSParser::SourceType type) {
+ sp<AnotherPacketSource> source =
+ static_cast<AnotherPacketSource *>(
+ mTSParser->getSource(type).get());
+
+ if (source == NULL) {
+ return;
+ }
+
+ sp<AMessage> format;
+ if (!(mFormatKnownMask & (1ul << trackIndex))) {
+ sp<MetaData> meta = source->getFormat();
+ CHECK(meta != NULL);
+
+ CHECK_EQ((status_t)OK, convertMetaDataToMessage(meta, &format));
+
+ mFormatKnownMask |= 1ul << trackIndex;
+ }
+
+ status_t finalResult;
+ while (source->hasBufferAvailable(&finalResult)) {
+ sp<ABuffer> accessUnit;
+ status_t err = source->dequeueAccessUnit(&accessUnit);
+ if (err == OK) {
+ postAccessUnit(trackIndex, accessUnit, format);
+ format.clear();
+ } else if (err != INFO_DISCONTINUITY) {
+ notifyError(err);
+ }
+ }
+
+ if (finalResult != OK) {
+ notifyError(finalResult);
+ }
+}
+
+void MediaReceiver::notifyInitDone(status_t err) {
+ sp<AMessage> notify = mNotify->dup();
+ notify->setInt32("what", kWhatInitDone);
+ notify->setInt32("err", err);
+ notify->post();
+}
+
+void MediaReceiver::notifyError(status_t err) {
+ sp<AMessage> notify = mNotify->dup();
+ notify->setInt32("what", kWhatError);
+ notify->setInt32("err", err);
+ notify->post();
+}
+
+void MediaReceiver::notifyPacketLost() {
+ sp<AMessage> notify = mNotify->dup();
+ notify->setInt32("what", kWhatPacketLost);
+ notify->post();
+}
+
+void MediaReceiver::postAccessUnit(
+ size_t trackIndex,
+ const sp<ABuffer> &accessUnit,
+ const sp<AMessage> &format) {
+ sp<AMessage> notify = mNotify->dup();
+ notify->setInt32("what", kWhatAccessUnit);
+ notify->setSize("trackIndex", trackIndex);
+ notify->setBuffer("accessUnit", accessUnit);
+
+ if (format != NULL) {
+ notify->setMessage("format", format);
+ }
+
+ notify->post();
+}
+
+} // namespace android
+
+