summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/wifi-display/source/PlaybackSession.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'media/libstagefright/wifi-display/source/PlaybackSession.cpp')
-rw-r--r--media/libstagefright/wifi-display/source/PlaybackSession.cpp423
1 files changed, 63 insertions, 360 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