summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/wifi-display/source
diff options
context:
space:
mode:
Diffstat (limited to 'media/libstagefright/wifi-display/source')
-rw-r--r--media/libstagefright/wifi-display/source/PlaybackSession.cpp423
-rw-r--r--media/libstagefright/wifi-display/source/PlaybackSession.h38
-rw-r--r--media/libstagefright/wifi-display/source/RepeaterSource.h2
-rw-r--r--media/libstagefright/wifi-display/source/Sender.cpp878
-rw-r--r--media/libstagefright/wifi-display/source/Sender.h169
-rw-r--r--media/libstagefright/wifi-display/source/TSPacketizer.cpp26
-rw-r--r--media/libstagefright/wifi-display/source/TSPacketizer.h2
-rw-r--r--media/libstagefright/wifi-display/source/WifiDisplaySource.cpp12
8 files changed, 105 insertions, 1445 deletions
diff --git a/media/libstagefright/wifi-display/source/PlaybackSession.cpp b/media/libstagefright/wifi-display/source/PlaybackSession.cpp
index ede4e60..ea195b3 100644
--- a/media/libstagefright/wifi-display/source/PlaybackSession.cpp
+++ b/media/libstagefright/wifi-display/source/PlaybackSession.cpp
@@ -23,8 +23,6 @@
#include "Converter.h"
#include "MediaPuller.h"
#include "RepeaterSource.h"
-#include "Sender.h"
-#include "TSPacketizer.h"
#include "include/avc_utils.h"
#include "WifiDisplaySource.h"
@@ -65,9 +63,9 @@ struct WifiDisplaySource::PlaybackSession::Track : public AHandler {
bool isAudio() const;
const sp<Converter> &converter() const;
- ssize_t packetizerTrackIndex() const;
- void setPacketizerTrackIndex(size_t index);
+ ssize_t mediaSenderTrackIndex() const;
+ void setMediaSenderTrackIndex(size_t index);
status_t start();
void stopAsync();
@@ -107,7 +105,7 @@ private:
sp<MediaPuller> mMediaPuller;
sp<Converter> mConverter;
bool mStarted;
- ssize_t mPacketizerTrackIndex;
+ ssize_t mMediaSenderTrackIndex;
bool mIsAudio;
List<sp<ABuffer> > mQueuedAccessUnits;
sp<RepeaterSource> mRepeaterSource;
@@ -131,7 +129,6 @@ WifiDisplaySource::PlaybackSession::Track::Track(
mMediaPuller(mediaPuller),
mConverter(converter),
mStarted(false),
- mPacketizerTrackIndex(-1),
mIsAudio(IsAudioFormat(mConverter->getOutputFormat())),
mLastOutputBufferQueuedTimeUs(-1ll) {
}
@@ -161,13 +158,14 @@ const sp<Converter> &WifiDisplaySource::PlaybackSession::Track::converter() cons
return mConverter;
}
-ssize_t WifiDisplaySource::PlaybackSession::Track::packetizerTrackIndex() const {
- return mPacketizerTrackIndex;
+ssize_t WifiDisplaySource::PlaybackSession::Track::mediaSenderTrackIndex() const {
+ CHECK_GE(mMediaSenderTrackIndex, 0);
+ return mMediaSenderTrackIndex;
}
-void WifiDisplaySource::PlaybackSession::Track::setPacketizerTrackIndex(size_t index) {
- CHECK_LT(mPacketizerTrackIndex, 0);
- mPacketizerTrackIndex = index;
+void WifiDisplaySource::PlaybackSession::Track::setMediaSenderTrackIndex(
+ size_t index) {
+ mMediaSenderTrackIndex = index;
}
status_t WifiDisplaySource::PlaybackSession::Track::start() {
@@ -331,22 +329,28 @@ WifiDisplaySource::PlaybackSession::PlaybackSession(
mNotify(notify),
mInterfaceAddr(interfaceAddr),
mHDCP(hdcp),
+ mLocalRTPPort(-1),
mWeAreDead(false),
mPaused(false),
mLastLifesignUs(),
mVideoTrackIndex(-1),
- mPrevTimeUs(-1ll),
- mAllTracksHavePacketizerIndex(false) {
+ mPrevTimeUs(-1ll) {
}
status_t WifiDisplaySource::PlaybackSession::init(
const char *clientIP, int32_t clientRtp, int32_t clientRtcp,
- Sender::TransportMode transportMode,
+ RTPSender::TransportMode transportMode,
bool enableAudio,
bool usePCMAudio,
bool enableVideo,
VideoFormats::ResolutionType videoResolutionType,
size_t videoResolutionIndex) {
+ sp<AMessage> notify = new AMessage(kWhatMediaSenderNotify, id());
+ mMediaSender = new MediaSender(mNetSession, notify);
+ looper()->registerHandler(mMediaSender);
+
+ mMediaSender->setHDCP(mHDCP);
+
status_t err = setupPacketizer(
enableAudio,
usePCMAudio,
@@ -354,26 +358,22 @@ status_t WifiDisplaySource::PlaybackSession::init(
videoResolutionType,
videoResolutionIndex);
- if (err != OK) {
- return err;
+ if (err == OK) {
+ err = mMediaSender->initAsync(
+ -1 /* trackIndex */,
+ transportMode,
+ clientIP,
+ clientRtp,
+ clientRtcp,
+ &mLocalRTPPort);
}
- sp<AMessage> notify = new AMessage(kWhatSenderNotify, id());
- mSender = new Sender(mNetSession, notify);
-
- mSenderLooper = new ALooper;
- mSenderLooper->setName("sender_looper");
-
- mSenderLooper->start(
- false /* runOnCallingThread */,
- false /* canCallJava */,
- PRIORITY_AUDIO);
-
- mSenderLooper->registerHandler(mSender);
+ if (err != OK) {
+ mLocalRTPPort = -1;
- err = mSender->init(clientIP, clientRtp, clientRtcp, transportMode);
+ looper()->unregisterHandler(mMediaSender->id());
+ mMediaSender.clear();
- if (err != OK) {
return err;
}
@@ -386,7 +386,7 @@ WifiDisplaySource::PlaybackSession::~PlaybackSession() {
}
int32_t WifiDisplaySource::PlaybackSession::getRTPPort() const {
- return mSender->getRTPPort();
+ return mLocalRTPPort;
}
int64_t WifiDisplaySource::PlaybackSession::getLastLifesignUs() const {
@@ -406,18 +406,10 @@ status_t WifiDisplaySource::PlaybackSession::play() {
}
status_t WifiDisplaySource::PlaybackSession::finishPlay() {
- // XXX Give the dongle a second to bind its sockets.
- (new AMessage(kWhatFinishPlay, id()))->post(1000000ll);
return OK;
}
-status_t WifiDisplaySource::PlaybackSession::onFinishPlay() {
- return mSender->finishInit();
-}
-
-status_t WifiDisplaySource::PlaybackSession::onFinishPlay2() {
- mSender->scheduleSendSR();
-
+status_t WifiDisplaySource::PlaybackSession::onMediaSenderInitialized() {
for (size_t i = 0; i < mTracks.size(); ++i) {
CHECK_EQ((status_t)OK, mTracks.editValueAt(i)->start());
}
@@ -464,44 +456,18 @@ void WifiDisplaySource::PlaybackSession::onMessageReceived(
CHECK(msg->findSize("trackIndex", &trackIndex));
if (what == Converter::kWhatAccessUnit) {
- const sp<Track> &track = mTracks.valueFor(trackIndex);
-
- ssize_t packetizerTrackIndex = track->packetizerTrackIndex();
-
- if (packetizerTrackIndex < 0) {
- sp<AMessage> trackFormat = track->getFormat()->dup();
- if (mHDCP != NULL && !track->isAudio()) {
- // HDCP2.0 _and_ HDCP 2.1 specs say to set the version
- // inside the HDCP descriptor to 0x20!!!
- trackFormat->setInt32("hdcp-version", 0x20);
- }
- packetizerTrackIndex = mPacketizer->addTrack(trackFormat);
-
- CHECK_GE(packetizerTrackIndex, 0);
-
- track->setPacketizerTrackIndex(packetizerTrackIndex);
-
- if (allTracksHavePacketizerIndex()) {
- status_t err = packetizeQueuedAccessUnits();
-
- if (err != OK) {
- notifySessionDead();
- break;
- }
- }
- }
-
sp<ABuffer> accessUnit;
CHECK(msg->findBuffer("accessUnit", &accessUnit));
- if (!allTracksHavePacketizerIndex()) {
- track->queueAccessUnit(accessUnit);
- break;
- }
+ const sp<Track> &track = mTracks.valueFor(trackIndex);
- track->queueOutputBuffer(accessUnit);
+ status_t err = mMediaSender->queueAccessUnit(
+ track->mediaSenderTrackIndex(),
+ accessUnit);
- drainAccessUnits();
+ if (err != OK) {
+ notifySessionDead();
+ }
break;
} else if (what == Converter::kWhatEOS) {
CHECK_EQ(what, Converter::kWhatEOS);
@@ -533,37 +499,25 @@ void WifiDisplaySource::PlaybackSession::onMessageReceived(
break;
}
- case kWhatSenderNotify:
+ case kWhatMediaSenderNotify:
{
int32_t what;
CHECK(msg->findInt32("what", &what));
- if (what == Sender::kWhatInitDone) {
- onFinishPlay2();
- } else if (what == Sender::kWhatSessionDead) {
- notifySessionDead();
- } else if (what == Sender::kWhatBinaryData) {
- sp<AMessage> notify = mNotify->dup();
- notify->setInt32("what", kWhatBinaryData);
-
- int32_t channel;
- CHECK(msg->findInt32("channel", &channel));
- notify->setInt32("channel", channel);
+ if (what == MediaSender::kWhatInitDone) {
+ status_t err;
+ CHECK(msg->findInt32("err", &err));
- sp<ABuffer> data;
- CHECK(msg->findBuffer("data", &data));
- notify->setBuffer("data", data);
- notify->post();
+ if (err == OK) {
+ onMediaSenderInitialized();
+ } else {
+ notifySessionDead();
+ }
+ } else if (what == MediaSender::kWhatError) {
+ notifySessionDead();
} else {
TRESPASS();
}
-
- break;
- }
-
- case kWhatFinishPlay:
- {
- onFinishPlay();
break;
}
@@ -588,11 +542,8 @@ void WifiDisplaySource::PlaybackSession::onMessageReceived(
break;
}
- mSenderLooper->unregisterHandler(mSender->id());
- mSender.clear();
- mSenderLooper.clear();
-
- mPacketizer.clear();
+ looper()->unregisterHandler(mMediaSender->id());
+ mMediaSender.clear();
sp<AMessage> notify = mNotify->dup();
notify->setInt32("what", kWhatSessionDestroyed);
@@ -601,28 +552,6 @@ void WifiDisplaySource::PlaybackSession::onMessageReceived(
break;
}
- case kWhatPacketize:
- {
- size_t trackIndex;
- CHECK(msg->findSize("trackIndex", &trackIndex));
-
- sp<ABuffer> accessUnit;
- CHECK(msg->findBuffer("accessUnit", &accessUnit));
-
-#if 0
- if ((ssize_t)trackIndex == mVideoTrackIndex) {
- int64_t nowUs = ALooper::GetNowUs();
- static int64_t prevNowUs = 0ll;
-
- ALOGI("sending AU, dNowUs=%lld us", nowUs - prevNowUs);
-
- prevNowUs = nowUs;
- }
-#endif
-
- break;
- }
-
case kWhatPause:
{
if (mPaused) {
@@ -664,8 +593,6 @@ status_t WifiDisplaySource::PlaybackSession::setupPacketizer(
size_t videoResolutionIndex) {
CHECK(enableAudio || enableVideo);
- mPacketizer = new TSPacketizer;
-
if (enableVideo) {
status_t err = addVideoSource(
videoResolutionType, videoResolutionIndex);
@@ -763,6 +690,17 @@ status_t WifiDisplaySource::PlaybackSession::addSource(
mVideoTrackIndex = trackIndex;
}
+ uint32_t flags = 0;
+ if (converter->needToManuallyPrependSPSPPS()) {
+ flags |= MediaSender::FLAG_MANUALLY_PREPEND_SPS_PPS;
+ }
+
+ ssize_t mediaSenderTrackIndex =
+ mMediaSender->addTrack(converter->getOutputFormat(), flags);
+ CHECK_GE(mediaSenderTrackIndex, 0);
+
+ track->setMediaSenderTrackIndex(mediaSenderTrackIndex);
+
return OK;
}
@@ -832,168 +770,6 @@ void WifiDisplaySource::PlaybackSession::requestIDRFrame() {
}
}
-bool WifiDisplaySource::PlaybackSession::allTracksHavePacketizerIndex() {
- if (mAllTracksHavePacketizerIndex) {
- return true;
- }
-
- for (size_t i = 0; i < mTracks.size(); ++i) {
- if (mTracks.valueAt(i)->packetizerTrackIndex() < 0) {
- return false;
- }
- }
-
- mAllTracksHavePacketizerIndex = true;
-
- return true;
-}
-
-status_t WifiDisplaySource::PlaybackSession::packetizeAccessUnit(
- size_t trackIndex, sp<ABuffer> accessUnit,
- sp<ABuffer> *packets) {
- const sp<Track> &track = mTracks.valueFor(trackIndex);
-
- uint32_t flags = 0;
-
- bool isHDCPEncrypted = false;
- uint64_t inputCTR;
- uint8_t HDCP_private_data[16];
-
- bool manuallyPrependSPSPPS =
- !track->isAudio()
- && track->converter()->needToManuallyPrependSPSPPS()
- && IsIDR(accessUnit);
-
- if (mHDCP != NULL && !track->isAudio()) {
- isHDCPEncrypted = true;
-
- if (manuallyPrependSPSPPS) {
- accessUnit = mPacketizer->prependCSD(
- track->packetizerTrackIndex(), accessUnit);
- }
-
- status_t err = mHDCP->encrypt(
- accessUnit->data(), accessUnit->size(),
- trackIndex /* streamCTR */,
- &inputCTR,
- accessUnit->data());
-
- if (err != OK) {
- ALOGE("Failed to HDCP-encrypt media data (err %d)",
- err);
-
- return err;
- }
-
- HDCP_private_data[0] = 0x00;
-
- HDCP_private_data[1] =
- (((trackIndex >> 30) & 3) << 1) | 1;
-
- HDCP_private_data[2] = (trackIndex >> 22) & 0xff;
-
- HDCP_private_data[3] =
- (((trackIndex >> 15) & 0x7f) << 1) | 1;
-
- HDCP_private_data[4] = (trackIndex >> 7) & 0xff;
-
- HDCP_private_data[5] =
- ((trackIndex & 0x7f) << 1) | 1;
-
- HDCP_private_data[6] = 0x00;
-
- HDCP_private_data[7] =
- (((inputCTR >> 60) & 0x0f) << 1) | 1;
-
- HDCP_private_data[8] = (inputCTR >> 52) & 0xff;
-
- HDCP_private_data[9] =
- (((inputCTR >> 45) & 0x7f) << 1) | 1;
-
- HDCP_private_data[10] = (inputCTR >> 37) & 0xff;
-
- HDCP_private_data[11] =
- (((inputCTR >> 30) & 0x7f) << 1) | 1;
-
- HDCP_private_data[12] = (inputCTR >> 22) & 0xff;
-
- HDCP_private_data[13] =
- (((inputCTR >> 15) & 0x7f) << 1) | 1;
-
- HDCP_private_data[14] = (inputCTR >> 7) & 0xff;
-
- HDCP_private_data[15] =
- ((inputCTR & 0x7f) << 1) | 1;
-
-#if 0
- ALOGI("HDCP_private_data:");
- hexdump(HDCP_private_data, sizeof(HDCP_private_data));
-
- ABitReader br(HDCP_private_data, sizeof(HDCP_private_data));
- CHECK_EQ(br.getBits(13), 0);
- CHECK_EQ(br.getBits(2), (trackIndex >> 30) & 3);
- CHECK_EQ(br.getBits(1), 1u);
- CHECK_EQ(br.getBits(15), (trackIndex >> 15) & 0x7fff);
- CHECK_EQ(br.getBits(1), 1u);
- CHECK_EQ(br.getBits(15), trackIndex & 0x7fff);
- CHECK_EQ(br.getBits(1), 1u);
- CHECK_EQ(br.getBits(11), 0);
- CHECK_EQ(br.getBits(4), (inputCTR >> 60) & 0xf);
- CHECK_EQ(br.getBits(1), 1u);
- CHECK_EQ(br.getBits(15), (inputCTR >> 45) & 0x7fff);
- CHECK_EQ(br.getBits(1), 1u);
- CHECK_EQ(br.getBits(15), (inputCTR >> 30) & 0x7fff);
- CHECK_EQ(br.getBits(1), 1u);
- CHECK_EQ(br.getBits(15), (inputCTR >> 15) & 0x7fff);
- CHECK_EQ(br.getBits(1), 1u);
- CHECK_EQ(br.getBits(15), inputCTR & 0x7fff);
- CHECK_EQ(br.getBits(1), 1u);
-#endif
-
- flags |= TSPacketizer::IS_ENCRYPTED;
- } else if (manuallyPrependSPSPPS) {
- flags |= TSPacketizer::PREPEND_SPS_PPS_TO_IDR_FRAMES;
- }
-
- int64_t timeUs = ALooper::GetNowUs();
- if (mPrevTimeUs < 0ll || mPrevTimeUs + 100000ll <= timeUs) {
- flags |= TSPacketizer::EMIT_PCR;
- flags |= TSPacketizer::EMIT_PAT_AND_PMT;
-
- mPrevTimeUs = timeUs;
- }
-
- mPacketizer->packetize(
- track->packetizerTrackIndex(), accessUnit, packets, flags,
- !isHDCPEncrypted ? NULL : HDCP_private_data,
- !isHDCPEncrypted ? 0 : sizeof(HDCP_private_data),
- track->isAudio() ? 2 : 0 /* numStuffingBytes */);
-
- return OK;
-}
-
-status_t WifiDisplaySource::PlaybackSession::packetizeQueuedAccessUnits() {
- for (;;) {
- bool gotMoreData = false;
- for (size_t i = 0; i < mTracks.size(); ++i) {
- size_t trackIndex = mTracks.keyAt(i);
- const sp<Track> &track = mTracks.valueAt(i);
-
- sp<ABuffer> accessUnit = track->dequeueAccessUnit();
- if (accessUnit != NULL) {
- track->queueOutputBuffer(accessUnit);
- gotMoreData = true;
- }
- }
-
- if (!gotMoreData) {
- break;
- }
- }
-
- return OK;
-}
-
void WifiDisplaySource::PlaybackSession::notifySessionDead() {
// Inform WifiDisplaySource of our premature death (wish).
sp<AMessage> notify = mNotify->dup();
@@ -1003,78 +779,5 @@ void WifiDisplaySource::PlaybackSession::notifySessionDead() {
mWeAreDead = true;
}
-void WifiDisplaySource::PlaybackSession::drainAccessUnits() {
- ALOGV("audio/video has %d/%d buffers ready.",
- mTracks.valueFor(1)->countQueuedOutputBuffers(),
- mTracks.valueFor(0)->countQueuedOutputBuffers());
-
- while (drainAccessUnit()) {
- }
-}
-
-bool WifiDisplaySource::PlaybackSession::drainAccessUnit() {
- ssize_t minTrackIndex = -1;
- int64_t minTimeUs = -1ll;
-
- for (size_t i = 0; i < mTracks.size(); ++i) {
- const sp<Track> &track = mTracks.valueAt(i);
-
- int64_t timeUs;
- if (track->hasOutputBuffer(&timeUs)) {
- if (minTrackIndex < 0 || timeUs < minTimeUs) {
- minTrackIndex = mTracks.keyAt(i);
- minTimeUs = timeUs;
- }
- }
-#if SUSPEND_VIDEO_IF_IDLE
- else if (!track->isSuspended()) {
- // We still consider this track "live", so it should keep
- // delivering output data whose time stamps we'll have to
- // consider for proper interleaving.
- return false;
- }
-#else
- else {
- // We need access units available on all tracks to be able to
- // dequeue the earliest one.
- return false;
- }
-#endif
- }
-
- if (minTrackIndex < 0) {
- return false;
- }
-
- const sp<Track> &track = mTracks.valueFor(minTrackIndex);
- sp<ABuffer> accessUnit = track->dequeueOutputBuffer();
-
- sp<ABuffer> packets;
- status_t err = packetizeAccessUnit(minTrackIndex, accessUnit, &packets);
-
- if (err != OK) {
- notifySessionDead();
- return false;
- }
-
- if ((ssize_t)minTrackIndex == mVideoTrackIndex) {
- packets->meta()->setInt32("isVideo", 1);
- }
- mSender->queuePackets(minTimeUs, packets);
-
-#if 0
- if (minTrackIndex == mVideoTrackIndex) {
- int64_t nowUs = ALooper::GetNowUs();
-
- // Latency from "data acquired" to "ready to send if we wanted to".
- ALOGI("[%s] latencyUs = %lld ms",
- minTrackIndex == mVideoTrackIndex ? "video" : "audio",
- (nowUs - minTimeUs) / 1000ll);
- }
-#endif
-
- return true;
-}
-
} // namespace android
diff --git a/media/libstagefright/wifi-display/source/PlaybackSession.h b/media/libstagefright/wifi-display/source/PlaybackSession.h
index 7365c78..cd6da85 100644
--- a/media/libstagefright/wifi-display/source/PlaybackSession.h
+++ b/media/libstagefright/wifi-display/source/PlaybackSession.h
@@ -18,7 +18,7 @@
#define PLAYBACK_SESSION_H_
-#include "Sender.h"
+#include "MediaSender.h"
#include "VideoFormats.h"
#include "WifiDisplaySource.h"
@@ -30,7 +30,7 @@ struct IHDCP;
struct IGraphicBufferProducer;
struct MediaPuller;
struct MediaSource;
-struct TSPacketizer;
+struct MediaSender;
// Encapsulates the state of an RTP/RTCP session in the context of wifi
// display.
@@ -43,7 +43,7 @@ struct WifiDisplaySource::PlaybackSession : public AHandler {
status_t init(
const char *clientIP, int32_t clientRtp, int32_t clientRtcp,
- Sender::TransportMode transportMode,
+ RTPSender::TransportMode transportMode,
bool enableAudio,
bool usePCMAudio,
bool enableVideo,
@@ -83,26 +83,25 @@ private:
kWhatMediaPullerNotify,
kWhatConverterNotify,
kWhatTrackNotify,
- kWhatSenderNotify,
kWhatUpdateSurface,
- kWhatFinishPlay,
- kWhatPacketize,
kWhatPause,
kWhatResume,
+ kWhatMediaSenderNotify,
};
sp<ANetworkSession> mNetSession;
- sp<Sender> mSender;
- sp<ALooper> mSenderLooper;
sp<AMessage> mNotify;
in_addr mInterfaceAddr;
sp<IHDCP> mHDCP;
+
+ sp<MediaSender> mMediaSender;
+ int32_t mLocalRTPPort;
+
bool mWeAreDead;
bool mPaused;
int64_t mLastLifesignUs;
- sp<TSPacketizer> mPacketizer;
sp<BufferQueue> mBufferQueue;
KeyedVector<size_t, sp<Track> > mTracks;
@@ -110,8 +109,6 @@ private:
int64_t mPrevTimeUs;
- bool mAllTracksHavePacketizerIndex;
-
status_t setupPacketizer(
bool enableAudio,
bool usePCMAudio,
@@ -132,27 +129,10 @@ private:
status_t addAudioSource(bool usePCMAudio);
- ssize_t appendTSData(
- const void *data, size_t size, bool timeDiscontinuity, bool flush);
-
- status_t onFinishPlay();
- status_t onFinishPlay2();
-
- bool allTracksHavePacketizerIndex();
-
- status_t packetizeAccessUnit(
- size_t trackIndex, sp<ABuffer> accessUnit,
- sp<ABuffer> *packets);
-
- status_t packetizeQueuedAccessUnits();
+ status_t onMediaSenderInitialized();
void notifySessionDead();
- void drainAccessUnits();
-
- // Returns true iff an access unit was successfully drained.
- bool drainAccessUnit();
-
DISALLOW_EVIL_CONSTRUCTORS(PlaybackSession);
};
diff --git a/media/libstagefright/wifi-display/source/RepeaterSource.h b/media/libstagefright/wifi-display/source/RepeaterSource.h
index a13973c..146af32 100644
--- a/media/libstagefright/wifi-display/source/RepeaterSource.h
+++ b/media/libstagefright/wifi-display/source/RepeaterSource.h
@@ -6,7 +6,7 @@
#include <media/stagefright/foundation/AHandlerReflector.h>
#include <media/stagefright/MediaSource.h>
-#define SUSPEND_VIDEO_IF_IDLE 1
+#define SUSPEND_VIDEO_IF_IDLE 0
namespace android {
diff --git a/media/libstagefright/wifi-display/source/Sender.cpp b/media/libstagefright/wifi-display/source/Sender.cpp
deleted file mode 100644
index 8b7d93f..0000000
--- a/media/libstagefright/wifi-display/source/Sender.cpp
+++ /dev/null
@@ -1,878 +0,0 @@
-/*
- * Copyright 2012, 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 "Sender"
-#include <utils/Log.h>
-
-#include "Sender.h"
-
-#include "ANetworkSession.h"
-#include "TimeSeries.h"
-
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/hexdump.h>
-#include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/Utils.h>
-
-namespace android {
-
-static size_t kMaxRTPPacketSize = 1500;
-static size_t kMaxNumTSPacketsPerRTPPacket = (kMaxRTPPacketSize - 12) / 188;
-
-Sender::Sender(
- const sp<ANetworkSession> &netSession,
- const sp<AMessage> &notify)
- : mNetSession(netSession),
- mNotify(notify),
- mTransportMode(TRANSPORT_UDP),
- mRTPChannel(0),
- mRTCPChannel(0),
- mRTPPort(0),
- mRTPSessionID(0),
- mRTCPSessionID(0),
-#if ENABLE_RETRANSMISSION && RETRANSMISSION_ACCORDING_TO_RFC_XXXX
- mRTPRetransmissionSessionID(0),
- mRTCPRetransmissionSessionID(0),
-#endif
- mClientRTPPort(0),
- mClientRTCPPort(0),
- mRTPConnected(false),
- mRTCPConnected(false),
- mFirstOutputBufferReadyTimeUs(-1ll),
- mFirstOutputBufferSentTimeUs(-1ll),
- mRTPSeqNo(0),
-#if ENABLE_RETRANSMISSION && RETRANSMISSION_ACCORDING_TO_RFC_XXXX
- mRTPRetransmissionSeqNo(0),
-#endif
- mLastNTPTime(0),
- mLastRTPTime(0),
- mNumRTPSent(0),
- mNumRTPOctetsSent(0),
- mNumSRsSent(0),
- mSendSRPending(false)
-#if ENABLE_RETRANSMISSION
- ,mHistoryLength(0)
-#endif
-#if TRACK_BANDWIDTH
- ,mFirstPacketTimeUs(-1ll)
- ,mTotalBytesSent(0ll)
-#endif
-#if LOG_TRANSPORT_STREAM
- ,mLogFile(NULL)
-#endif
-{
-#if LOG_TRANSPORT_STREAM
- mLogFile = fopen("/system/etc/log.ts", "wb");
-#endif
-}
-
-Sender::~Sender() {
-#if ENABLE_RETRANSMISSION && RETRANSMISSION_ACCORDING_TO_RFC_XXXX
- 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);
- }
-
-#if LOG_TRANSPORT_STREAM
- if (mLogFile != NULL) {
- fclose(mLogFile);
- mLogFile = NULL;
- }
-#endif
-}
-
-status_t Sender::init(
- const char *clientIP, int32_t clientRtp, int32_t clientRtcp,
- TransportMode transportMode) {
- mClientIP = clientIP;
- mTransportMode = transportMode;
-
- if (transportMode == TRANSPORT_TCP_INTERLEAVED) {
- mRTPChannel = clientRtp;
- mRTCPChannel = clientRtcp;
- mRTPPort = 0;
- mRTPSessionID = 0;
- mRTCPSessionID = 0;
- return OK;
- }
-
- mRTPChannel = 0;
- mRTCPChannel = 0;
-
- if (mTransportMode == TRANSPORT_TCP) {
- // XXX This is wrong, we need to allocate sockets here, we only
- // need to do this because the dongles are not establishing their
- // end until after PLAY instead of before SETUP.
- mRTPPort = 20000;
- mRTPSessionID = 0;
- mRTCPSessionID = 0;
- mClientRTPPort = clientRtp;
- mClientRTCPPort = clientRtcp;
- return OK;
- }
-
- int serverRtp;
-
- sp<AMessage> rtpNotify = new AMessage(kWhatRTPNotify, id());
- sp<AMessage> rtcpNotify = new AMessage(kWhatRTCPNotify, id());
-
-#if ENABLE_RETRANSMISSION && RETRANSMISSION_ACCORDING_TO_RFC_XXXX
- sp<AMessage> rtpRetransmissionNotify =
- new AMessage(kWhatRTPRetransmissionNotify, id());
-
- sp<AMessage> rtcpRetransmissionNotify =
- new AMessage(kWhatRTCPRetransmissionNotify, id());
-#endif
-
- status_t err;
- for (serverRtp = 15550;; serverRtp += 2) {
- int32_t rtpSession;
- if (mTransportMode == TRANSPORT_UDP) {
- err = mNetSession->createUDPSession(
- serverRtp, clientIP, clientRtp,
- rtpNotify, &rtpSession);
- } else {
- err = mNetSession->createTCPDatagramSession(
- serverRtp, clientIP, clientRtp,
- rtpNotify, &rtpSession);
- }
-
- if (err != OK) {
- ALOGI("failed to create RTP socket on port %d", serverRtp);
- continue;
- }
-
- int32_t rtcpSession = 0;
-
- if (clientRtcp >= 0) {
- if (mTransportMode == TRANSPORT_UDP) {
- err = mNetSession->createUDPSession(
- serverRtp + 1, clientIP, clientRtcp,
- rtcpNotify, &rtcpSession);
- } else {
- err = mNetSession->createTCPDatagramSession(
- serverRtp + 1, clientIP, clientRtcp,
- rtcpNotify, &rtcpSession);
- }
-
- if (err != OK) {
- ALOGI("failed to create RTCP socket on port %d", serverRtp + 1);
-
- mNetSession->destroySession(rtpSession);
- continue;
- }
- }
-
-#if ENABLE_RETRANSMISSION && RETRANSMISSION_ACCORDING_TO_RFC_XXXX
- if (mTransportMode == TRANSPORT_UDP) {
- int32_t rtpRetransmissionSession;
-
- err = mNetSession->createUDPSession(
- serverRtp + kRetransmissionPortOffset,
- clientIP,
- clientRtp + kRetransmissionPortOffset,
- rtpRetransmissionNotify,
- &rtpRetransmissionSession);
-
- if (err != OK) {
- mNetSession->destroySession(rtcpSession);
- mNetSession->destroySession(rtpSession);
- continue;
- }
-
- CHECK_GE(clientRtcp, 0);
-
- int32_t rtcpRetransmissionSession;
- err = mNetSession->createUDPSession(
- serverRtp + 1 + kRetransmissionPortOffset,
- clientIP,
- clientRtp + 1 + kRetransmissionPortOffset,
- rtcpRetransmissionNotify,
- &rtcpRetransmissionSession);
-
- if (err != OK) {
- mNetSession->destroySession(rtpRetransmissionSession);
- mNetSession->destroySession(rtcpSession);
- mNetSession->destroySession(rtpSession);
- continue;
- }
-
- mRTPRetransmissionSessionID = rtpRetransmissionSession;
- mRTCPRetransmissionSessionID = rtcpRetransmissionSession;
-
- ALOGI("rtpRetransmissionSessionID = %d, "
- "rtcpRetransmissionSessionID = %d",
- rtpRetransmissionSession, rtcpRetransmissionSession);
- }
-#endif
-
- mRTPPort = serverRtp;
- mRTPSessionID = rtpSession;
- mRTCPSessionID = rtcpSession;
-
- ALOGI("rtpSessionID = %d, rtcpSessionID = %d", rtpSession, rtcpSession);
- break;
- }
-
- if (mRTPPort == 0) {
- return UNKNOWN_ERROR;
- }
-
- return OK;
-}
-
-status_t Sender::finishInit() {
- if (mTransportMode != TRANSPORT_TCP) {
- notifyInitDone();
- return OK;
- }
-
- sp<AMessage> rtpNotify = new AMessage(kWhatRTPNotify, id());
-
- status_t err = mNetSession->createTCPDatagramSession(
- mRTPPort, mClientIP.c_str(), mClientRTPPort,
- rtpNotify, &mRTPSessionID);
-
- if (err != OK) {
- return err;
- }
-
- if (mClientRTCPPort >= 0) {
- sp<AMessage> rtcpNotify = new AMessage(kWhatRTCPNotify, id());
-
- err = mNetSession->createTCPDatagramSession(
- mRTPPort + 1, mClientIP.c_str(), mClientRTCPPort,
- rtcpNotify, &mRTCPSessionID);
-
- if (err != OK) {
- return err;
- }
- }
-
- return OK;
-}
-
-int32_t Sender::getRTPPort() const {
- return mRTPPort;
-}
-
-void Sender::queuePackets(
- int64_t timeUs, const sp<ABuffer> &tsPackets) {
- const size_t numTSPackets = tsPackets->size() / 188;
-
- const size_t numRTPPackets =
- (numTSPackets + kMaxNumTSPacketsPerRTPPacket - 1)
- / kMaxNumTSPacketsPerRTPPacket;
-
- sp<ABuffer> udpPackets = new ABuffer(
- numRTPPackets * (12 + kMaxNumTSPacketsPerRTPPacket * 188));
-
- udpPackets->meta()->setInt64("timeUs", timeUs);
-
- size_t dstOffset = 0;
- for (size_t i = 0; i < numTSPackets; ++i) {
- if ((i % kMaxNumTSPacketsPerRTPPacket) == 0) {
- static const bool kMarkerBit = false;
-
- uint8_t *rtp = udpPackets->data() + dstOffset;
- rtp[0] = 0x80;
- rtp[1] = 33 | (kMarkerBit ? (1 << 7) : 0); // M-bit
- rtp[2] = (mRTPSeqNo >> 8) & 0xff;
- rtp[3] = mRTPSeqNo & 0xff;
- rtp[4] = 0x00; // rtp time to be filled in later.
- rtp[5] = 0x00;
- rtp[6] = 0x00;
- rtp[7] = 0x00;
- rtp[8] = kSourceID >> 24;
- rtp[9] = (kSourceID >> 16) & 0xff;
- rtp[10] = (kSourceID >> 8) & 0xff;
- rtp[11] = kSourceID & 0xff;
-
- ++mRTPSeqNo;
-
- dstOffset += 12;
- }
-
- memcpy(udpPackets->data() + dstOffset,
- tsPackets->data() + 188 * i,
- 188);
-
- dstOffset += 188;
- }
-
- udpPackets->setRange(0, dstOffset);
-
- sp<AMessage> msg = new AMessage(kWhatDrainQueue, id());
- msg->setBuffer("udpPackets", udpPackets);
- msg->post();
-
-#if LOG_TRANSPORT_STREAM
- if (mLogFile != NULL) {
- fwrite(tsPackets->data(), 1, tsPackets->size(), mLogFile);
- }
-#endif
-}
-
-void Sender::onMessageReceived(const sp<AMessage> &msg) {
- switch (msg->what()) {
- case kWhatRTPNotify:
- case kWhatRTCPNotify:
-#if ENABLE_RETRANSMISSION && RETRANSMISSION_ACCORDING_TO_RFC_XXXX
- case kWhatRTPRetransmissionNotify:
- case kWhatRTCPRetransmissionNotify:
-#endif
- {
- int32_t reason;
- CHECK(msg->findInt32("reason", &reason));
-
- switch (reason) {
- case ANetworkSession::kWhatError:
- {
- int32_t sessionID;
- CHECK(msg->findInt32("sessionID", &sessionID));
-
- int32_t err;
- CHECK(msg->findInt32("err", &err));
-
- int32_t errorOccuredDuringSend;
- CHECK(msg->findInt32("send", &errorOccuredDuringSend));
-
- AString detail;
- CHECK(msg->findString("detail", &detail));
-
- if ((msg->what() == kWhatRTPNotify
-#if ENABLE_RETRANSMISSION && RETRANSMISSION_ACCORDING_TO_RFC_XXXX
- || msg->what() == kWhatRTPRetransmissionNotify
-#endif
- ) && !errorOccuredDuringSend) {
- // This is ok, we don't expect to receive anything on
- // the RTP socket.
- break;
- }
-
- ALOGE("An error occurred during %s in session %d "
- "(%d, '%s' (%s)).",
- errorOccuredDuringSend ? "send" : "receive",
- sessionID,
- err,
- detail.c_str(),
- strerror(-err));
-
- mNetSession->destroySession(sessionID);
-
- if (sessionID == mRTPSessionID) {
- mRTPSessionID = 0;
- } else if (sessionID == mRTCPSessionID) {
- mRTCPSessionID = 0;
- }
-#if ENABLE_RETRANSMISSION && RETRANSMISSION_ACCORDING_TO_RFC_XXXX
- else if (sessionID == mRTPRetransmissionSessionID) {
- mRTPRetransmissionSessionID = 0;
- } else if (sessionID == mRTCPRetransmissionSessionID) {
- mRTCPRetransmissionSessionID = 0;
- }
-#endif
-
- notifySessionDead();
- break;
- }
-
- case ANetworkSession::kWhatDatagram:
- {
- int32_t sessionID;
- CHECK(msg->findInt32("sessionID", &sessionID));
-
- sp<ABuffer> data;
- CHECK(msg->findBuffer("data", &data));
-
- status_t err;
- if (msg->what() == kWhatRTCPNotify
-#if ENABLE_RETRANSMISSION && RETRANSMISSION_ACCORDING_TO_RFC_XXXX
- || msg->what() == kWhatRTCPRetransmissionNotify
-#endif
- )
- {
- err = parseRTCP(data);
- }
- break;
- }
-
- case ANetworkSession::kWhatConnected:
- {
- CHECK_EQ(mTransportMode, TRANSPORT_TCP);
-
- int32_t sessionID;
- CHECK(msg->findInt32("sessionID", &sessionID));
-
- if (sessionID == mRTPSessionID) {
- CHECK(!mRTPConnected);
- mRTPConnected = true;
- ALOGI("RTP Session now connected.");
- } else if (sessionID == mRTCPSessionID) {
- CHECK(!mRTCPConnected);
- mRTCPConnected = true;
- ALOGI("RTCP Session now connected.");
- } else {
- TRESPASS();
- }
-
- if (mRTPConnected
- && (mClientRTCPPort < 0 || mRTCPConnected)) {
- notifyInitDone();
- }
- break;
- }
-
- default:
- TRESPASS();
- }
- break;
- }
-
- case kWhatDrainQueue:
- {
- sp<ABuffer> udpPackets;
- CHECK(msg->findBuffer("udpPackets", &udpPackets));
-
- onDrainQueue(udpPackets);
- break;
- }
-
- case kWhatSendSR:
- {
- mSendSRPending = false;
-
- if (mRTCPSessionID == 0) {
- break;
- }
-
- onSendSR();
-
- scheduleSendSR();
- break;
- }
- }
-}
-
-void Sender::scheduleSendSR() {
- if (mSendSRPending || mRTCPSessionID == 0) {
- return;
- }
-
- mSendSRPending = true;
- (new AMessage(kWhatSendSR, id()))->post(kSendSRIntervalUs);
-}
-
-void Sender::addSR(const sp<ABuffer> &buffer) {
- uint8_t *data = buffer->data() + buffer->size();
-
- // TODO: Use macros/utility functions to clean up all the bitshifts below.
-
- data[0] = 0x80 | 0;
- data[1] = 200; // SR
- data[2] = 0;
- data[3] = 6;
- data[4] = kSourceID >> 24;
- data[5] = (kSourceID >> 16) & 0xff;
- data[6] = (kSourceID >> 8) & 0xff;
- data[7] = kSourceID & 0xff;
-
- data[8] = mLastNTPTime >> (64 - 8);
- data[9] = (mLastNTPTime >> (64 - 16)) & 0xff;
- data[10] = (mLastNTPTime >> (64 - 24)) & 0xff;
- data[11] = (mLastNTPTime >> 32) & 0xff;
- data[12] = (mLastNTPTime >> 24) & 0xff;
- data[13] = (mLastNTPTime >> 16) & 0xff;
- data[14] = (mLastNTPTime >> 8) & 0xff;
- data[15] = mLastNTPTime & 0xff;
-
- data[16] = (mLastRTPTime >> 24) & 0xff;
- data[17] = (mLastRTPTime >> 16) & 0xff;
- data[18] = (mLastRTPTime >> 8) & 0xff;
- data[19] = mLastRTPTime & 0xff;
-
- data[20] = mNumRTPSent >> 24;
- data[21] = (mNumRTPSent >> 16) & 0xff;
- data[22] = (mNumRTPSent >> 8) & 0xff;
- data[23] = mNumRTPSent & 0xff;
-
- data[24] = mNumRTPOctetsSent >> 24;
- data[25] = (mNumRTPOctetsSent >> 16) & 0xff;
- data[26] = (mNumRTPOctetsSent >> 8) & 0xff;
- data[27] = mNumRTPOctetsSent & 0xff;
-
- buffer->setRange(buffer->offset(), buffer->size() + 28);
-}
-
-void Sender::addSDES(const sp<ABuffer> &buffer) {
- uint8_t *data = buffer->data() + buffer->size();
- data[0] = 0x80 | 1;
- data[1] = 202; // SDES
- data[4] = kSourceID >> 24;
- data[5] = (kSourceID >> 16) & 0xff;
- data[6] = (kSourceID >> 8) & 0xff;
- data[7] = kSourceID & 0xff;
-
- size_t offset = 8;
-
- data[offset++] = 1; // CNAME
-
- static const char *kCNAME = "someone@somewhere";
- data[offset++] = strlen(kCNAME);
-
- memcpy(&data[offset], kCNAME, strlen(kCNAME));
- offset += strlen(kCNAME);
-
- data[offset++] = 7; // NOTE
-
- static const char *kNOTE = "Hell's frozen over.";
- data[offset++] = strlen(kNOTE);
-
- memcpy(&data[offset], kNOTE, strlen(kNOTE));
- offset += strlen(kNOTE);
-
- data[offset++] = 0;
-
- if ((offset % 4) > 0) {
- size_t count = 4 - (offset % 4);
- switch (count) {
- case 3:
- data[offset++] = 0;
- case 2:
- data[offset++] = 0;
- case 1:
- data[offset++] = 0;
- }
- }
-
- size_t numWords = (offset / 4) - 1;
- data[2] = numWords >> 8;
- data[3] = numWords & 0xff;
-
- buffer->setRange(buffer->offset(), buffer->size() + offset);
-}
-
-// static
-uint64_t Sender::GetNowNTP() {
- uint64_t nowUs = ALooper::GetNowUs();
-
- nowUs += ((70ll * 365 + 17) * 24) * 60 * 60 * 1000000ll;
-
- uint64_t hi = nowUs / 1000000ll;
- uint64_t lo = ((1ll << 32) * (nowUs % 1000000ll)) / 1000000ll;
-
- return (hi << 32) | lo;
-}
-
-void Sender::onSendSR() {
- sp<ABuffer> buffer = new ABuffer(1500);
- buffer->setRange(0, 0);
-
- addSR(buffer);
- addSDES(buffer);
-
- if (mTransportMode == TRANSPORT_TCP_INTERLEAVED) {
- sp<AMessage> notify = mNotify->dup();
- notify->setInt32("what", kWhatBinaryData);
- notify->setInt32("channel", mRTCPChannel);
- notify->setBuffer("data", buffer);
- notify->post();
- } else {
- sendPacket(mRTCPSessionID, buffer->data(), buffer->size());
- }
-
- ++mNumSRsSent;
-}
-
-#if ENABLE_RETRANSMISSION
-status_t Sender::parseTSFB(
- const uint8_t *data, size_t size) {
- if ((data[0] & 0x1f) != 1) {
- return ERROR_UNSUPPORTED; // We only support NACK for now.
- }
-
- uint32_t srcId = U32_AT(&data[8]);
- if (srcId != kSourceID) {
- return ERROR_MALFORMED;
- }
-
- for (size_t i = 12; i < size; i += 4) {
- uint16_t seqNo = U16_AT(&data[i]);
- uint16_t blp = U16_AT(&data[i + 2]);
-
- List<sp<ABuffer> >::iterator it = mHistory.begin();
- bool foundSeqNo = false;
- while (it != mHistory.end()) {
- const sp<ABuffer> &buffer = *it;
-
- uint16_t bufferSeqNo = buffer->int32Data() & 0xffff;
-
- bool retransmit = false;
- if (bufferSeqNo == seqNo) {
- retransmit = true;
- } else if (blp != 0) {
- for (size_t i = 0; i < 16; ++i) {
- if ((blp & (1 << i))
- && (bufferSeqNo == ((seqNo + i + 1) & 0xffff))) {
- blp &= ~(1 << i);
- retransmit = true;
- }
- }
- }
-
- if (retransmit) {
- ALOGI("retransmitting seqNo %d", bufferSeqNo);
-
-#if RETRANSMISSION_ACCORDING_TO_RFC_XXXX
- sp<ABuffer> retransRTP = new ABuffer(2 + buffer->size());
- uint8_t *rtp = retransRTP->data();
- memcpy(rtp, buffer->data(), 12);
- rtp[2] = (mRTPRetransmissionSeqNo >> 8) & 0xff;
- rtp[3] = mRTPRetransmissionSeqNo & 0xff;
- rtp[12] = (bufferSeqNo >> 8) & 0xff;
- rtp[13] = bufferSeqNo & 0xff;
- memcpy(&rtp[14], buffer->data() + 12, buffer->size() - 12);
-
- ++mRTPRetransmissionSeqNo;
-
- sendPacket(
- mRTPRetransmissionSessionID,
- retransRTP->data(), retransRTP->size());
-#else
- sendPacket(
- mRTPSessionID, buffer->data(), buffer->size());
-#endif
-
- if (bufferSeqNo == seqNo) {
- foundSeqNo = true;
- }
-
- if (foundSeqNo && blp == 0) {
- break;
- }
- }
-
- ++it;
- }
-
- if (!foundSeqNo || blp != 0) {
- ALOGI("Some sequence numbers were no longer available for "
- "retransmission (seqNo = %d, foundSeqNo = %d, blp = 0x%04x)",
- seqNo, foundSeqNo, blp);
-
- if (!mHistory.empty()) {
- int32_t earliest = (*mHistory.begin())->int32Data() & 0xffff;
- int32_t latest = (*--mHistory.end())->int32Data() & 0xffff;
-
- ALOGI("have seq numbers from %d - %d", earliest, latest);
- }
- }
- }
-
- return OK;
-}
-#endif
-
-status_t Sender::parseRTCP(
- const sp<ABuffer> &buffer) {
- const uint8_t *data = buffer->data();
- size_t size = buffer->size();
-
- while (size > 0) {
- if (size < 8) {
- // Too short to be a valid RTCP header
- return ERROR_MALFORMED;
- }
-
- if ((data[0] >> 6) != 2) {
- // Unsupported version.
- return ERROR_UNSUPPORTED;
- }
-
- if (data[0] & 0x20) {
- // Padding present.
-
- size_t paddingLength = data[size - 1];
-
- if (paddingLength + 12 > size) {
- // If we removed this much padding we'd end up with something
- // that's too short to be a valid RTP header.
- return ERROR_MALFORMED;
- }
-
- size -= paddingLength;
- }
-
- size_t headerLength = 4 * (data[2] << 8 | data[3]) + 4;
-
- if (size < headerLength) {
- // Only received a partial packet?
- return ERROR_MALFORMED;
- }
-
- switch (data[1]) {
- case 200:
- case 201: // RR
- case 202: // SDES
- case 203:
- case 204: // APP
- break;
-
-#if ENABLE_RETRANSMISSION
- case 205: // TSFB (transport layer specific feedback)
- parseTSFB(data, headerLength);
- break;
-#endif
-
- case 206: // PSFB (payload specific feedback)
- hexdump(data, headerLength);
- break;
-
- default:
- {
- ALOGW("Unknown RTCP packet type %u of size %d",
- (unsigned)data[1], headerLength);
- break;
- }
- }
-
- data += headerLength;
- size -= headerLength;
- }
-
- return OK;
-}
-
-status_t Sender::sendPacket(
- int32_t sessionID, const void *data, size_t size) {
- return mNetSession->sendRequest(sessionID, data, size);
-}
-
-void Sender::notifyInitDone() {
- sp<AMessage> notify = mNotify->dup();
- notify->setInt32("what", kWhatInitDone);
- notify->post();
-}
-
-void Sender::notifySessionDead() {
- sp<AMessage> notify = mNotify->dup();
- notify->setInt32("what", kWhatSessionDead);
- notify->post();
-}
-
-void Sender::onDrainQueue(const sp<ABuffer> &udpPackets) {
- static const size_t kFullRTPPacketSize =
- 12 + 188 * kMaxNumTSPacketsPerRTPPacket;
-
- size_t srcOffset = 0;
- while (srcOffset < udpPackets->size()) {
- uint8_t *rtp = udpPackets->data() + srcOffset;
-
- size_t rtpPacketSize = udpPackets->size() - srcOffset;
- if (rtpPacketSize > kFullRTPPacketSize) {
- rtpPacketSize = kFullRTPPacketSize;
- }
-
- int64_t nowUs = ALooper::GetNowUs();
- mLastNTPTime = GetNowNTP();
-
- // 90kHz time scale
- uint32_t rtpTime = (nowUs * 9ll) / 100ll;
-
- rtp[4] = rtpTime >> 24;
- rtp[5] = (rtpTime >> 16) & 0xff;
- rtp[6] = (rtpTime >> 8) & 0xff;
- rtp[7] = rtpTime & 0xff;
-
- ++mNumRTPSent;
- mNumRTPOctetsSent += rtpPacketSize - 12;
-
- mLastRTPTime = rtpTime;
-
- if (mTransportMode == TRANSPORT_TCP_INTERLEAVED) {
- sp<AMessage> notify = mNotify->dup();
- notify->setInt32("what", kWhatBinaryData);
-
- sp<ABuffer> data = new ABuffer(rtpPacketSize);
- memcpy(data->data(), rtp, rtpPacketSize);
-
- notify->setInt32("channel", mRTPChannel);
- notify->setBuffer("data", data);
- notify->post();
- } else {
- sendPacket(mRTPSessionID, rtp, rtpPacketSize);
-
-#if TRACK_BANDWIDTH
- mTotalBytesSent += rtpPacketSize->size();
- int64_t delayUs = ALooper::GetNowUs() - mFirstPacketTimeUs;
-
- if (delayUs > 0ll) {
- ALOGI("approx. net bandwidth used: %.2f Mbit/sec",
- mTotalBytesSent * 8.0 / delayUs);
- }
-#endif
- }
-
-#if ENABLE_RETRANSMISSION
- addToHistory(rtp, rtpPacketSize);
-#endif
-
- srcOffset += rtpPacketSize;
- }
-
-#if 0
- int64_t timeUs;
- CHECK(udpPackets->meta()->findInt64("timeUs", &timeUs));
-
- ALOGI("dTimeUs = %lld us", ALooper::GetNowUs() - timeUs);
-#endif
-}
-
-#if ENABLE_RETRANSMISSION
-void Sender::addToHistory(const uint8_t *rtp, size_t rtpPacketSize) {
- sp<ABuffer> packet = new ABuffer(rtpPacketSize);
- memcpy(packet->data(), rtp, rtpPacketSize);
-
- unsigned rtpSeqNo = U16_AT(&rtp[2]);
- packet->setInt32Data(rtpSeqNo);
-
- mHistory.push_back(packet);
- ++mHistoryLength;
-
- if (mHistoryLength > kMaxHistoryLength) {
- mHistory.erase(mHistory.begin());
- --mHistoryLength;
- }
-}
-#endif
-
-} // namespace android
-
diff --git a/media/libstagefright/wifi-display/source/Sender.h b/media/libstagefright/wifi-display/source/Sender.h
deleted file mode 100644
index 66951f7..0000000
--- a/media/libstagefright/wifi-display/source/Sender.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright 2012, 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.
- */
-
-#ifndef SENDER_H_
-
-#define SENDER_H_
-
-#include <media/stagefright/foundation/AHandler.h>
-
-namespace android {
-
-#define LOG_TRANSPORT_STREAM 0
-#define TRACK_BANDWIDTH 0
-
-#define ENABLE_RETRANSMISSION 1
-
-// If retransmission is enabled the following define determines what
-// kind we support, if RETRANSMISSION_ACCORDING_TO_RFC_XXXX is 0
-// we'll send NACKs on the original RTCP channel and retransmit packets
-// on the original RTP channel, otherwise a separate channel pair is used
-// for this purpose.
-#define RETRANSMISSION_ACCORDING_TO_RFC_XXXX 0
-
-struct ABuffer;
-struct ANetworkSession;
-
-struct Sender : public AHandler {
- Sender(const sp<ANetworkSession> &netSession, const sp<AMessage> &notify);
-
- enum {
- kWhatInitDone,
- kWhatSessionDead,
- kWhatBinaryData,
- };
-
- enum TransportMode {
- TRANSPORT_UDP,
- TRANSPORT_TCP_INTERLEAVED,
- TRANSPORT_TCP,
- };
- status_t init(
- const char *clientIP, int32_t clientRtp, int32_t clientRtcp,
- TransportMode transportMode);
-
- status_t finishInit();
-
- int32_t getRTPPort() const;
-
- void queuePackets(int64_t timeUs, const sp<ABuffer> &tsPackets);
- void scheduleSendSR();
-
-protected:
- virtual ~Sender();
- virtual void onMessageReceived(const sp<AMessage> &msg);
-
-private:
- enum {
- kWhatDrainQueue,
- kWhatSendSR,
- kWhatRTPNotify,
- kWhatRTCPNotify,
-#if ENABLE_RETRANSMISSION && RETRANSMISSION_ACCORDING_TO_RFC_XXXX
- kWhatRTPRetransmissionNotify,
- kWhatRTCPRetransmissionNotify,
-#endif
- };
-
- static const int64_t kSendSRIntervalUs = 10000000ll;
-
- static const uint32_t kSourceID = 0xdeadbeef;
- static const size_t kMaxHistoryLength = 128;
-
-#if ENABLE_RETRANSMISSION && RETRANSMISSION_ACCORDING_TO_RFC_XXXX
- static const size_t kRetransmissionPortOffset = 120;
-#endif
-
- sp<ANetworkSession> mNetSession;
- sp<AMessage> mNotify;
-
- TransportMode mTransportMode;
- AString mClientIP;
-
- // in TCP mode
- int32_t mRTPChannel;
- int32_t mRTCPChannel;
-
- // in UDP mode
- int32_t mRTPPort;
- int32_t mRTPSessionID;
- int32_t mRTCPSessionID;
-
-#if ENABLE_RETRANSMISSION && RETRANSMISSION_ACCORDING_TO_RFC_XXXX
- int32_t mRTPRetransmissionSessionID;
- int32_t mRTCPRetransmissionSessionID;
-#endif
-
- int32_t mClientRTPPort;
- int32_t mClientRTCPPort;
- bool mRTPConnected;
- bool mRTCPConnected;
-
- int64_t mFirstOutputBufferReadyTimeUs;
- int64_t mFirstOutputBufferSentTimeUs;
-
- uint32_t mRTPSeqNo;
-#if ENABLE_RETRANSMISSION && RETRANSMISSION_ACCORDING_TO_RFC_XXXX
- uint32_t mRTPRetransmissionSeqNo;
-#endif
-
- uint64_t mLastNTPTime;
- uint32_t mLastRTPTime;
- uint32_t mNumRTPSent;
- uint32_t mNumRTPOctetsSent;
- uint32_t mNumSRsSent;
-
- bool mSendSRPending;
-
-#if ENABLE_RETRANSMISSION
- List<sp<ABuffer> > mHistory;
- size_t mHistoryLength;
-#endif
-
-#if TRACK_BANDWIDTH
- int64_t mFirstPacketTimeUs;
- uint64_t mTotalBytesSent;
-#endif
-
-#if LOG_TRANSPORT_STREAM
- FILE *mLogFile;
-#endif
-
- void onSendSR();
- void addSR(const sp<ABuffer> &buffer);
- void addSDES(const sp<ABuffer> &buffer);
- static uint64_t GetNowNTP();
-
-#if ENABLE_RETRANSMISSION
- status_t parseTSFB(const uint8_t *data, size_t size);
- void addToHistory(const uint8_t *rtp, size_t rtpPacketSize);
-#endif
-
- status_t parseRTCP(const sp<ABuffer> &buffer);
-
- status_t sendPacket(int32_t sessionID, const void *data, size_t size);
-
- void notifyInitDone();
- void notifySessionDead();
-
- void onDrainQueue(const sp<ABuffer> &udpPackets);
-
- DISALLOW_EVIL_CONSTRUCTORS(Sender);
-};
-
-} // namespace android
-
-#endif // SENDER_H_
diff --git a/media/libstagefright/wifi-display/source/TSPacketizer.cpp b/media/libstagefright/wifi-display/source/TSPacketizer.cpp
index ef57a4d..8420529 100644
--- a/media/libstagefright/wifi-display/source/TSPacketizer.cpp
+++ b/media/libstagefright/wifi-display/source/TSPacketizer.cpp
@@ -58,6 +58,7 @@ struct TSPacketizer::Track : public RefBase {
sp<ABuffer> descriptorAt(size_t index) const;
void finalize();
+ void extractCSDIfNecessary();
protected:
virtual ~Track();
@@ -77,6 +78,7 @@ private:
bool mAudioLacksATDSHeaders;
bool mFinalized;
+ bool mExtractedCSD;
DISALLOW_EVIL_CONSTRUCTORS(Track);
};
@@ -90,14 +92,21 @@ TSPacketizer::Track::Track(
mStreamID(streamID),
mContinuityCounter(0),
mAudioLacksATDSHeaders(false),
- mFinalized(false) {
+ mFinalized(false),
+ mExtractedCSD(false) {
CHECK(format->findString("mime", &mMIME));
+}
+
+void TSPacketizer::Track::extractCSDIfNecessary() {
+ if (mExtractedCSD) {
+ return;
+ }
if (!strcasecmp(mMIME.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)
|| !strcasecmp(mMIME.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) {
for (size_t i = 0;; ++i) {
sp<ABuffer> csd;
- if (!format->findBuffer(StringPrintf("csd-%d", i).c_str(), &csd)) {
+ if (!mFormat->findBuffer(StringPrintf("csd-%d", i).c_str(), &csd)) {
break;
}
@@ -111,6 +120,8 @@ TSPacketizer::Track::Track(
}
}
}
+
+ mExtractedCSD = true;
}
TSPacketizer::Track::~Track() {
@@ -407,6 +418,17 @@ ssize_t TSPacketizer::addTrack(const sp<AMessage> &format) {
return mTracks.add(track);
}
+status_t TSPacketizer::extractCSDIfNecessary(size_t trackIndex) {
+ if (trackIndex >= mTracks.size()) {
+ return -ERANGE;
+ }
+
+ const sp<Track> &track = mTracks.itemAt(trackIndex);
+ track->extractCSDIfNecessary();
+
+ return OK;
+}
+
status_t TSPacketizer::packetize(
size_t trackIndex,
const sp<ABuffer> &_accessUnit,
diff --git a/media/libstagefright/wifi-display/source/TSPacketizer.h b/media/libstagefright/wifi-display/source/TSPacketizer.h
index a37917d..5d1d70e 100644
--- a/media/libstagefright/wifi-display/source/TSPacketizer.h
+++ b/media/libstagefright/wifi-display/source/TSPacketizer.h
@@ -50,6 +50,8 @@ struct TSPacketizer : public RefBase {
const uint8_t *PES_private_data, size_t PES_private_data_len,
size_t numStuffingBytes = 0);
+ status_t extractCSDIfNecessary(size_t trackIndex);
+
// XXX to be removed once encoder config option takes care of this for
// encrypted mode.
sp<ABuffer> prependCSD(
diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
index 825ebc6..07eb237 100644
--- a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
+++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
@@ -22,7 +22,7 @@
#include "PlaybackSession.h"
#include "Parameters.h"
#include "ParsedMessage.h"
-#include "Sender.h"
+#include "rtp/RTPSender.h"
#include <binder/IServiceManager.h>
#include <gui/IGraphicBufferProducer.h>
@@ -1140,7 +1140,7 @@ status_t WifiDisplaySource::onSetupRequest(
return ERROR_MALFORMED;
}
- Sender::TransportMode transportMode = Sender::TRANSPORT_UDP;
+ RTPSender::TransportMode transportMode = RTPSender::TRANSPORT_UDP;
int clientRtp, clientRtcp;
if (transport.startsWith("RTP/AVP/TCP;")) {
@@ -1149,7 +1149,7 @@ status_t WifiDisplaySource::onSetupRequest(
transport.c_str(), "interleaved", &interleaved)
&& sscanf(interleaved.c_str(), "%d-%d",
&clientRtp, &clientRtcp) == 2) {
- transportMode = Sender::TRANSPORT_TCP_INTERLEAVED;
+ transportMode = RTPSender::TRANSPORT_TCP_INTERLEAVED;
} else {
bool badRequest = false;
@@ -1171,7 +1171,7 @@ status_t WifiDisplaySource::onSetupRequest(
return ERROR_MALFORMED;
}
- transportMode = Sender::TRANSPORT_TCP;
+ transportMode = RTPSender::TRANSPORT_TCP;
}
} else if (transport.startsWith("RTP/AVP;unicast;")
|| transport.startsWith("RTP/AVP/UDP;unicast;")) {
@@ -1263,7 +1263,7 @@ status_t WifiDisplaySource::onSetupRequest(
AString response = "RTSP/1.0 200 OK\r\n";
AppendCommonResponse(&response, cseq, playbackSessionID);
- if (transportMode == Sender::TRANSPORT_TCP_INTERLEAVED) {
+ if (transportMode == RTPSender::TRANSPORT_TCP_INTERLEAVED) {
response.append(
StringPrintf(
"Transport: RTP/AVP/TCP;interleaved=%d-%d;",
@@ -1272,7 +1272,7 @@ status_t WifiDisplaySource::onSetupRequest(
int32_t serverRtp = playbackSession->getRTPPort();
AString transportString = "UDP";
- if (transportMode == Sender::TRANSPORT_TCP) {
+ if (transportMode == RTPSender::TRANSPORT_TCP) {
transportString = "TCP";
}