1/*
2 * Copyright 2012, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "PlaybackSession"
19#include <utils/Log.h>
20
21#include "PlaybackSession.h"
22
23#include "Converter.h"
24#include "MediaPuller.h"
25#include "RepeaterSource.h"
26#include "Sender.h"
27#include "TSPacketizer.h"
28#include "include/avc_utils.h"
29
30#include <binder/IServiceManager.h>
31#include <gui/ISurfaceComposer.h>
32#include <gui/SurfaceComposerClient.h>
33#include <media/IHDCP.h>
34#include <media/stagefright/foundation/ABitReader.h>
35#include <media/stagefright/foundation/ABuffer.h>
36#include <media/stagefright/foundation/ADebug.h>
37#include <media/stagefright/foundation/AMessage.h>
38#include <media/stagefright/foundation/hexdump.h>
39#include <media/stagefright/AudioSource.h>
40#include <media/stagefright/DataSource.h>
41#include <media/stagefright/MediaDefs.h>
42#include <media/stagefright/MediaErrors.h>
43#include <media/stagefright/MediaExtractor.h>
44#include <media/stagefright/MediaSource.h>
45#include <media/stagefright/MetaData.h>
46#include <media/stagefright/MPEG2TSWriter.h>
47#include <media/stagefright/SurfaceMediaSource.h>
48#include <media/stagefright/Utils.h>
49
50#include <OMX_IVCommon.h>
51
52namespace android {
53
54struct WifiDisplaySource::PlaybackSession::Track : public AHandler {
55    enum {
56        kWhatStopped,
57    };
58
59    Track(const sp<AMessage> &notify,
60          const sp<ALooper> &pullLooper,
61          const sp<ALooper> &codecLooper,
62          const sp<MediaPuller> &mediaPuller,
63          const sp<Converter> &converter);
64
65    void setRepeaterSource(const sp<RepeaterSource> &source);
66
67    sp<AMessage> getFormat();
68    bool isAudio() const;
69
70    const sp<Converter> &converter() const;
71    ssize_t packetizerTrackIndex() const;
72
73    void setPacketizerTrackIndex(size_t index);
74
75    status_t start();
76    void stopAsync();
77
78    void queueAccessUnit(const sp<ABuffer> &accessUnit);
79    sp<ABuffer> dequeueAccessUnit();
80
81    bool hasOutputBuffer(int64_t *timeUs) const;
82    void queueOutputBuffer(const sp<ABuffer> &accessUnit);
83    sp<ABuffer> dequeueOutputBuffer();
84    bool isSuspended() const;
85
86    size_t countQueuedOutputBuffers() const {
87        return mQueuedOutputBuffers.size();
88    }
89
90    void requestIDRFrame();
91
92protected:
93    virtual void onMessageReceived(const sp<AMessage> &msg);
94    virtual ~Track();
95
96private:
97    enum {
98        kWhatMediaPullerStopped,
99    };
100
101    sp<AMessage> mNotify;
102    sp<ALooper> mPullLooper;
103    sp<ALooper> mCodecLooper;
104    sp<MediaPuller> mMediaPuller;
105    sp<Converter> mConverter;
106    bool mStarted;
107    ssize_t mPacketizerTrackIndex;
108    bool mIsAudio;
109    List<sp<ABuffer> > mQueuedAccessUnits;
110    sp<RepeaterSource> mRepeaterSource;
111    List<sp<ABuffer> > mQueuedOutputBuffers;
112    int64_t mLastOutputBufferQueuedTimeUs;
113
114    static bool IsAudioFormat(const sp<AMessage> &format);
115
116    DISALLOW_EVIL_CONSTRUCTORS(Track);
117};
118
119WifiDisplaySource::PlaybackSession::Track::Track(
120        const sp<AMessage> &notify,
121        const sp<ALooper> &pullLooper,
122        const sp<ALooper> &codecLooper,
123        const sp<MediaPuller> &mediaPuller,
124        const sp<Converter> &converter)
125    : mNotify(notify),
126      mPullLooper(pullLooper),
127      mCodecLooper(codecLooper),
128      mMediaPuller(mediaPuller),
129      mConverter(converter),
130      mStarted(false),
131      mPacketizerTrackIndex(-1),
132      mIsAudio(IsAudioFormat(mConverter->getOutputFormat())),
133      mLastOutputBufferQueuedTimeUs(-1ll) {
134}
135
136WifiDisplaySource::PlaybackSession::Track::~Track() {
137    CHECK(!mStarted);
138}
139
140// static
141bool WifiDisplaySource::PlaybackSession::Track::IsAudioFormat(
142        const sp<AMessage> &format) {
143    AString mime;
144    CHECK(format->findString("mime", &mime));
145
146    return !strncasecmp(mime.c_str(), "audio/", 6);
147}
148
149sp<AMessage> WifiDisplaySource::PlaybackSession::Track::getFormat() {
150    return mConverter->getOutputFormat();
151}
152
153bool WifiDisplaySource::PlaybackSession::Track::isAudio() const {
154    return mIsAudio;
155}
156
157const sp<Converter> &WifiDisplaySource::PlaybackSession::Track::converter() const {
158    return mConverter;
159}
160
161ssize_t WifiDisplaySource::PlaybackSession::Track::packetizerTrackIndex() const {
162    return mPacketizerTrackIndex;
163}
164
165void WifiDisplaySource::PlaybackSession::Track::setPacketizerTrackIndex(size_t index) {
166    CHECK_LT(mPacketizerTrackIndex, 0);
167    mPacketizerTrackIndex = index;
168}
169
170status_t WifiDisplaySource::PlaybackSession::Track::start() {
171    ALOGV("Track::start isAudio=%d", mIsAudio);
172
173    CHECK(!mStarted);
174
175    status_t err = OK;
176
177    if (mMediaPuller != NULL) {
178        err = mMediaPuller->start();
179    }
180
181    if (err == OK) {
182        mStarted = true;
183    }
184
185    return err;
186}
187
188void WifiDisplaySource::PlaybackSession::Track::stopAsync() {
189    ALOGV("Track::stopAsync isAudio=%d", mIsAudio);
190
191    mConverter->shutdownAsync();
192
193    sp<AMessage> msg = new AMessage(kWhatMediaPullerStopped, id());
194
195    if (mStarted && mMediaPuller != NULL) {
196        if (mRepeaterSource != NULL) {
197            // Let's unblock MediaPuller's MediaSource::read().
198            mRepeaterSource->wakeUp();
199        }
200
201        mMediaPuller->stopAsync(msg);
202    } else {
203        msg->post();
204    }
205}
206
207void WifiDisplaySource::PlaybackSession::Track::onMessageReceived(
208        const sp<AMessage> &msg) {
209    switch (msg->what()) {
210        case kWhatMediaPullerStopped:
211        {
212            mConverter.clear();
213
214            mStarted = false;
215
216            sp<AMessage> notify = mNotify->dup();
217            notify->setInt32("what", kWhatStopped);
218            notify->post();
219
220            ALOGI("kWhatStopped %s posted", mIsAudio ? "audio" : "video");
221            break;
222        }
223
224        default:
225            TRESPASS();
226    }
227}
228
229void WifiDisplaySource::PlaybackSession::Track::queueAccessUnit(
230        const sp<ABuffer> &accessUnit) {
231    mQueuedAccessUnits.push_back(accessUnit);
232}
233
234sp<ABuffer> WifiDisplaySource::PlaybackSession::Track::dequeueAccessUnit() {
235    if (mQueuedAccessUnits.empty()) {
236        return NULL;
237    }
238
239    sp<ABuffer> accessUnit = *mQueuedAccessUnits.begin();
240    CHECK(accessUnit != NULL);
241
242    mQueuedAccessUnits.erase(mQueuedAccessUnits.begin());
243
244    return accessUnit;
245}
246
247void WifiDisplaySource::PlaybackSession::Track::setRepeaterSource(
248        const sp<RepeaterSource> &source) {
249    mRepeaterSource = source;
250}
251
252void WifiDisplaySource::PlaybackSession::Track::requestIDRFrame() {
253    if (mIsAudio) {
254        return;
255    }
256
257    if (mRepeaterSource != NULL) {
258        mRepeaterSource->wakeUp();
259    }
260
261    mConverter->requestIDRFrame();
262}
263
264bool WifiDisplaySource::PlaybackSession::Track::hasOutputBuffer(
265        int64_t *timeUs) const {
266    *timeUs = 0ll;
267
268    if (mQueuedOutputBuffers.empty()) {
269        return false;
270    }
271
272    const sp<ABuffer> &outputBuffer = *mQueuedOutputBuffers.begin();
273
274    CHECK(outputBuffer->meta()->findInt64("timeUs", timeUs));
275
276    return true;
277}
278
279void WifiDisplaySource::PlaybackSession::Track::queueOutputBuffer(
280        const sp<ABuffer> &accessUnit) {
281    mQueuedOutputBuffers.push_back(accessUnit);
282
283    mLastOutputBufferQueuedTimeUs = ALooper::GetNowUs();
284}
285
286sp<ABuffer> WifiDisplaySource::PlaybackSession::Track::dequeueOutputBuffer() {
287    CHECK(!mQueuedOutputBuffers.empty());
288
289    sp<ABuffer> outputBuffer = *mQueuedOutputBuffers.begin();
290    mQueuedOutputBuffers.erase(mQueuedOutputBuffers.begin());
291
292    return outputBuffer;
293}
294
295bool WifiDisplaySource::PlaybackSession::Track::isSuspended() const {
296    if (!mQueuedOutputBuffers.empty()) {
297        return false;
298    }
299
300    if (mLastOutputBufferQueuedTimeUs < 0ll) {
301        // We've never seen an output buffer queued, but tracks start
302        // out live, not suspended.
303        return false;
304    }
305
306    // If we've not seen new output data for 60ms or more, we consider
307    // this track suspended for the time being.
308    return (ALooper::GetNowUs() - mLastOutputBufferQueuedTimeUs) > 60000ll;
309}
310
311////////////////////////////////////////////////////////////////////////////////
312
313WifiDisplaySource::PlaybackSession::PlaybackSession(
314        const sp<ANetworkSession> &netSession,
315        const sp<AMessage> &notify,
316        const in_addr &interfaceAddr,
317        const sp<IHDCP> &hdcp)
318    : mNetSession(netSession),
319      mNotify(notify),
320      mInterfaceAddr(interfaceAddr),
321      mHDCP(hdcp),
322      mWeAreDead(false),
323      mLastLifesignUs(),
324      mVideoTrackIndex(-1),
325      mPrevTimeUs(-1ll),
326      mAllTracksHavePacketizerIndex(false) {
327}
328
329status_t WifiDisplaySource::PlaybackSession::init(
330        const char *clientIP, int32_t clientRtp, int32_t clientRtcp,
331        Sender::TransportMode transportMode,
332        bool usePCMAudio) {
333    status_t err = setupPacketizer(usePCMAudio);
334
335    if (err != OK) {
336        return err;
337    }
338
339    sp<AMessage> notify = new AMessage(kWhatSenderNotify, id());
340    mSender = new Sender(mNetSession, notify);
341
342    mSenderLooper = new ALooper;
343    mSenderLooper->setName("sender_looper");
344
345    mSenderLooper->start(
346            false /* runOnCallingThread */,
347            false /* canCallJava */,
348            PRIORITY_AUDIO);
349
350    mSenderLooper->registerHandler(mSender);
351
352    err = mSender->init(clientIP, clientRtp, clientRtcp, transportMode);
353
354    if (err != OK) {
355        return err;
356    }
357
358    updateLiveness();
359
360    return OK;
361}
362
363WifiDisplaySource::PlaybackSession::~PlaybackSession() {
364}
365
366int32_t WifiDisplaySource::PlaybackSession::getRTPPort() const {
367    return mSender->getRTPPort();
368}
369
370int64_t WifiDisplaySource::PlaybackSession::getLastLifesignUs() const {
371    return mLastLifesignUs;
372}
373
374void WifiDisplaySource::PlaybackSession::updateLiveness() {
375    mLastLifesignUs = ALooper::GetNowUs();
376}
377
378status_t WifiDisplaySource::PlaybackSession::play() {
379    updateLiveness();
380
381    return OK;
382}
383
384status_t WifiDisplaySource::PlaybackSession::finishPlay() {
385    // XXX Give the dongle a second to bind its sockets.
386    (new AMessage(kWhatFinishPlay, id()))->post(1000000ll);
387    return OK;
388}
389
390status_t WifiDisplaySource::PlaybackSession::onFinishPlay() {
391    return mSender->finishInit();
392}
393
394status_t WifiDisplaySource::PlaybackSession::onFinishPlay2() {
395    mSender->scheduleSendSR();
396
397    for (size_t i = 0; i < mTracks.size(); ++i) {
398        CHECK_EQ((status_t)OK, mTracks.editValueAt(i)->start());
399    }
400
401    sp<AMessage> notify = mNotify->dup();
402    notify->setInt32("what", kWhatSessionEstablished);
403    notify->post();
404
405    return OK;
406}
407
408status_t WifiDisplaySource::PlaybackSession::pause() {
409    updateLiveness();
410
411    return OK;
412}
413
414void WifiDisplaySource::PlaybackSession::destroyAsync() {
415    ALOGI("destroyAsync");
416
417    for (size_t i = 0; i < mTracks.size(); ++i) {
418        mTracks.valueAt(i)->stopAsync();
419    }
420}
421
422void WifiDisplaySource::PlaybackSession::onMessageReceived(
423        const sp<AMessage> &msg) {
424    switch (msg->what()) {
425        case kWhatConverterNotify:
426        {
427            if (mWeAreDead) {
428                ALOGV("dropping msg '%s' because we're dead",
429                      msg->debugString().c_str());
430
431                break;
432            }
433
434            int32_t what;
435            CHECK(msg->findInt32("what", &what));
436
437            size_t trackIndex;
438            CHECK(msg->findSize("trackIndex", &trackIndex));
439
440            if (what == Converter::kWhatAccessUnit) {
441                const sp<Track> &track = mTracks.valueFor(trackIndex);
442
443                ssize_t packetizerTrackIndex = track->packetizerTrackIndex();
444
445                if (packetizerTrackIndex < 0) {
446                    packetizerTrackIndex =
447                        mPacketizer->addTrack(track->getFormat());
448
449                    CHECK_GE(packetizerTrackIndex, 0);
450
451                    track->setPacketizerTrackIndex(packetizerTrackIndex);
452
453                    if (allTracksHavePacketizerIndex()) {
454                        status_t err = packetizeQueuedAccessUnits();
455
456                        if (err != OK) {
457                            notifySessionDead();
458                            break;
459                        }
460                    }
461                }
462
463                sp<ABuffer> accessUnit;
464                CHECK(msg->findBuffer("accessUnit", &accessUnit));
465
466                if (!allTracksHavePacketizerIndex()) {
467                    track->queueAccessUnit(accessUnit);
468                    break;
469                }
470
471                track->queueOutputBuffer(accessUnit);
472
473                drainAccessUnits();
474                break;
475            } else if (what == Converter::kWhatEOS) {
476                CHECK_EQ(what, Converter::kWhatEOS);
477
478                ALOGI("output EOS on track %d", trackIndex);
479
480                ssize_t index = mTracks.indexOfKey(trackIndex);
481                CHECK_GE(index, 0);
482
483                const sp<Converter> &converter =
484                    mTracks.valueAt(index)->converter();
485                looper()->unregisterHandler(converter->id());
486
487                mTracks.removeItemsAt(index);
488
489                if (mTracks.isEmpty()) {
490                    ALOGI("Reached EOS");
491                }
492            } else {
493                CHECK_EQ(what, Converter::kWhatError);
494
495                status_t err;
496                CHECK(msg->findInt32("err", &err));
497
498                ALOGE("converter signaled error %d", err);
499
500                notifySessionDead();
501            }
502            break;
503        }
504
505        case kWhatSenderNotify:
506        {
507            int32_t what;
508            CHECK(msg->findInt32("what", &what));
509
510            if (what == Sender::kWhatInitDone) {
511                onFinishPlay2();
512            } else if (what == Sender::kWhatSessionDead) {
513                notifySessionDead();
514            } else {
515                TRESPASS();
516            }
517
518            break;
519        }
520
521        case kWhatFinishPlay:
522        {
523            onFinishPlay();
524            break;
525        }
526
527        case kWhatTrackNotify:
528        {
529            int32_t what;
530            CHECK(msg->findInt32("what", &what));
531
532            size_t trackIndex;
533            CHECK(msg->findSize("trackIndex", &trackIndex));
534
535            if (what == Track::kWhatStopped) {
536                ALOGI("Track %d stopped", trackIndex);
537
538                sp<Track> track = mTracks.valueFor(trackIndex);
539                looper()->unregisterHandler(track->id());
540                mTracks.removeItem(trackIndex);
541                track.clear();
542
543                if (!mTracks.isEmpty()) {
544                    ALOGI("not all tracks are stopped yet");
545                    break;
546                }
547
548                mSenderLooper->unregisterHandler(mSender->id());
549                mSender.clear();
550                mSenderLooper.clear();
551
552                mPacketizer.clear();
553
554                sp<AMessage> notify = mNotify->dup();
555                notify->setInt32("what", kWhatSessionDestroyed);
556                notify->post();
557            }
558            break;
559        }
560
561        case kWhatPacketize:
562        {
563            size_t trackIndex;
564            CHECK(msg->findSize("trackIndex", &trackIndex));
565
566            sp<ABuffer> accessUnit;
567            CHECK(msg->findBuffer("accessUnit", &accessUnit));
568
569#if 0
570            if ((ssize_t)trackIndex == mVideoTrackIndex) {
571                int64_t nowUs = ALooper::GetNowUs();
572                static int64_t prevNowUs = 0ll;
573
574                ALOGI("sending AU, dNowUs=%lld us", nowUs - prevNowUs);
575
576                prevNowUs = nowUs;
577            }
578#endif
579
580            break;
581        }
582
583        default:
584            TRESPASS();
585    }
586}
587
588status_t WifiDisplaySource::PlaybackSession::setupPacketizer(bool usePCMAudio) {
589    mPacketizer = new TSPacketizer;
590
591    status_t err = addVideoSource();
592
593    if (err != OK) {
594        return err;
595    }
596
597    return addAudioSource(usePCMAudio);
598}
599
600status_t WifiDisplaySource::PlaybackSession::addSource(
601        bool isVideo, const sp<MediaSource> &source, bool isRepeaterSource,
602        bool usePCMAudio, size_t *numInputBuffers) {
603    CHECK(!usePCMAudio || !isVideo);
604    CHECK(!isRepeaterSource || isVideo);
605
606    sp<ALooper> pullLooper = new ALooper;
607    pullLooper->setName("pull_looper");
608
609    pullLooper->start(
610            false /* runOnCallingThread */,
611            false /* canCallJava */,
612            PRIORITY_AUDIO);
613
614    sp<ALooper> codecLooper = new ALooper;
615    codecLooper->setName("codec_looper");
616
617    codecLooper->start(
618            false /* runOnCallingThread */,
619            false /* canCallJava */,
620            PRIORITY_AUDIO);
621
622    size_t trackIndex;
623
624    sp<AMessage> notify;
625
626    trackIndex = mTracks.size();
627
628    sp<AMessage> format;
629    status_t err = convertMetaDataToMessage(source->getFormat(), &format);
630    CHECK_EQ(err, (status_t)OK);
631
632    if (isVideo) {
633        format->setInt32("store-metadata-in-buffers", true);
634
635        format->setInt32(
636                "color-format", OMX_COLOR_FormatAndroidOpaque);
637    }
638
639    notify = new AMessage(kWhatConverterNotify, id());
640    notify->setSize("trackIndex", trackIndex);
641
642    sp<Converter> converter =
643        new Converter(notify, codecLooper, format, usePCMAudio);
644
645    if (converter->initCheck() != OK) {
646        return converter->initCheck();
647    }
648
649    looper()->registerHandler(converter);
650
651    notify = new AMessage(Converter::kWhatMediaPullerNotify, converter->id());
652    notify->setSize("trackIndex", trackIndex);
653
654    sp<MediaPuller> puller = new MediaPuller(source, notify);
655    pullLooper->registerHandler(puller);
656
657    if (numInputBuffers != NULL) {
658        *numInputBuffers = converter->getInputBufferCount();
659    }
660
661    notify = new AMessage(kWhatTrackNotify, id());
662    notify->setSize("trackIndex", trackIndex);
663
664    sp<Track> track = new Track(
665            notify, pullLooper, codecLooper, puller, converter);
666
667    if (isRepeaterSource) {
668        track->setRepeaterSource(static_cast<RepeaterSource *>(source.get()));
669    }
670
671    looper()->registerHandler(track);
672
673    mTracks.add(trackIndex, track);
674
675    if (isVideo) {
676        mVideoTrackIndex = trackIndex;
677    }
678
679    return OK;
680}
681
682status_t WifiDisplaySource::PlaybackSession::addVideoSource() {
683    sp<SurfaceMediaSource> source = new SurfaceMediaSource(width(), height());
684
685    source->setUseAbsoluteTimestamps();
686
687#if 1
688    sp<RepeaterSource> videoSource =
689        new RepeaterSource(source, 30.0 /* rateHz */);
690#endif
691
692#if 1
693    size_t numInputBuffers;
694    status_t err = addSource(
695            true /* isVideo */, videoSource, true /* isRepeaterSource */,
696            false /* usePCMAudio */, &numInputBuffers);
697#else
698    size_t numInputBuffers;
699    status_t err = addSource(
700            true /* isVideo */, source, false /* isRepeaterSource */,
701            false /* usePCMAudio */, &numInputBuffers);
702#endif
703
704    if (err != OK) {
705        return err;
706    }
707
708    err = source->setMaxAcquiredBufferCount(numInputBuffers);
709    CHECK_EQ(err, (status_t)OK);
710
711    mBufferQueue = source->getBufferQueue();
712
713    return OK;
714}
715
716status_t WifiDisplaySource::PlaybackSession::addAudioSource(bool usePCMAudio) {
717    sp<AudioSource> audioSource = new AudioSource(
718            AUDIO_SOURCE_REMOTE_SUBMIX,
719            48000 /* sampleRate */,
720            2 /* channelCount */);
721
722    if (audioSource->initCheck() == OK) {
723        return addSource(
724                false /* isVideo */, audioSource, false /* isRepeaterSource */,
725                usePCMAudio, NULL /* numInputBuffers */);
726    }
727
728    ALOGW("Unable to instantiate audio source");
729
730    return OK;
731}
732
733sp<ISurfaceTexture> WifiDisplaySource::PlaybackSession::getSurfaceTexture() {
734    return mBufferQueue;
735}
736
737int32_t WifiDisplaySource::PlaybackSession::width() const {
738    return 1280;
739}
740
741int32_t WifiDisplaySource::PlaybackSession::height() const {
742    return 720;
743}
744
745void WifiDisplaySource::PlaybackSession::requestIDRFrame() {
746    for (size_t i = 0; i < mTracks.size(); ++i) {
747        const sp<Track> &track = mTracks.valueAt(i);
748
749        track->requestIDRFrame();
750    }
751}
752
753bool WifiDisplaySource::PlaybackSession::allTracksHavePacketizerIndex() {
754    if (mAllTracksHavePacketizerIndex) {
755        return true;
756    }
757
758    for (size_t i = 0; i < mTracks.size(); ++i) {
759        if (mTracks.valueAt(i)->packetizerTrackIndex() < 0) {
760            return false;
761        }
762    }
763
764    mAllTracksHavePacketizerIndex = true;
765
766    return true;
767}
768
769status_t WifiDisplaySource::PlaybackSession::packetizeAccessUnit(
770        size_t trackIndex, const sp<ABuffer> &accessUnit,
771        sp<ABuffer> *packets) {
772    const sp<Track> &track = mTracks.valueFor(trackIndex);
773
774    uint32_t flags = 0;
775
776    bool isHDCPEncrypted = false;
777    uint64_t inputCTR;
778    uint8_t HDCP_private_data[16];
779    if (mHDCP != NULL && !track->isAudio()) {
780        isHDCPEncrypted = true;
781
782        status_t err = mHDCP->encrypt(
783                accessUnit->data(), accessUnit->size(),
784                trackIndex  /* streamCTR */,
785                &inputCTR,
786                accessUnit->data());
787
788        if (err != OK) {
789            ALOGE("Failed to HDCP-encrypt media data (err %d)",
790                  err);
791
792            return err;
793        }
794
795        HDCP_private_data[0] = 0x00;
796
797        HDCP_private_data[1] =
798            (((trackIndex >> 30) & 3) << 1) | 1;
799
800        HDCP_private_data[2] = (trackIndex >> 22) & 0xff;
801
802        HDCP_private_data[3] =
803            (((trackIndex >> 15) & 0x7f) << 1) | 1;
804
805        HDCP_private_data[4] = (trackIndex >> 7) & 0xff;
806
807        HDCP_private_data[5] =
808            ((trackIndex & 0x7f) << 1) | 1;
809
810        HDCP_private_data[6] = 0x00;
811
812        HDCP_private_data[7] =
813            (((inputCTR >> 60) & 0x0f) << 1) | 1;
814
815        HDCP_private_data[8] = (inputCTR >> 52) & 0xff;
816
817        HDCP_private_data[9] =
818            (((inputCTR >> 45) & 0x7f) << 1) | 1;
819
820        HDCP_private_data[10] = (inputCTR >> 37) & 0xff;
821
822        HDCP_private_data[11] =
823            (((inputCTR >> 30) & 0x7f) << 1) | 1;
824
825        HDCP_private_data[12] = (inputCTR >> 22) & 0xff;
826
827        HDCP_private_data[13] =
828            (((inputCTR >> 15) & 0x7f) << 1) | 1;
829
830        HDCP_private_data[14] = (inputCTR >> 7) & 0xff;
831
832        HDCP_private_data[15] =
833            ((inputCTR & 0x7f) << 1) | 1;
834
835#if 0
836        ALOGI("HDCP_private_data:");
837        hexdump(HDCP_private_data, sizeof(HDCP_private_data));
838
839        ABitReader br(HDCP_private_data, sizeof(HDCP_private_data));
840        CHECK_EQ(br.getBits(13), 0);
841        CHECK_EQ(br.getBits(2), (trackIndex >> 30) & 3);
842        CHECK_EQ(br.getBits(1), 1u);
843        CHECK_EQ(br.getBits(15), (trackIndex >> 15) & 0x7fff);
844        CHECK_EQ(br.getBits(1), 1u);
845        CHECK_EQ(br.getBits(15), trackIndex & 0x7fff);
846        CHECK_EQ(br.getBits(1), 1u);
847        CHECK_EQ(br.getBits(11), 0);
848        CHECK_EQ(br.getBits(4), (inputCTR >> 60) & 0xf);
849        CHECK_EQ(br.getBits(1), 1u);
850        CHECK_EQ(br.getBits(15), (inputCTR >> 45) & 0x7fff);
851        CHECK_EQ(br.getBits(1), 1u);
852        CHECK_EQ(br.getBits(15), (inputCTR >> 30) & 0x7fff);
853        CHECK_EQ(br.getBits(1), 1u);
854        CHECK_EQ(br.getBits(15), (inputCTR >> 15) & 0x7fff);
855        CHECK_EQ(br.getBits(1), 1u);
856        CHECK_EQ(br.getBits(15), inputCTR & 0x7fff);
857        CHECK_EQ(br.getBits(1), 1u);
858#endif
859
860        flags |= TSPacketizer::IS_ENCRYPTED;
861    }
862
863    int64_t timeUs = ALooper::GetNowUs();
864    if (mPrevTimeUs < 0ll || mPrevTimeUs + 100000ll <= timeUs) {
865        flags |= TSPacketizer::EMIT_PCR;
866        flags |= TSPacketizer::EMIT_PAT_AND_PMT;
867
868        mPrevTimeUs = timeUs;
869    }
870
871    mPacketizer->packetize(
872            track->packetizerTrackIndex(), accessUnit, packets, flags,
873            !isHDCPEncrypted ? NULL : HDCP_private_data,
874            !isHDCPEncrypted ? 0 : sizeof(HDCP_private_data),
875            track->isAudio() ? 2 : 0 /* numStuffingBytes */);
876
877    return OK;
878}
879
880status_t WifiDisplaySource::PlaybackSession::packetizeQueuedAccessUnits() {
881    for (;;) {
882        bool gotMoreData = false;
883        for (size_t i = 0; i < mTracks.size(); ++i) {
884            size_t trackIndex = mTracks.keyAt(i);
885            const sp<Track> &track = mTracks.valueAt(i);
886
887            sp<ABuffer> accessUnit = track->dequeueAccessUnit();
888            if (accessUnit != NULL) {
889                track->queueOutputBuffer(accessUnit);
890                gotMoreData = true;
891            }
892        }
893
894        if (!gotMoreData) {
895            break;
896        }
897    }
898
899    return OK;
900}
901
902void WifiDisplaySource::PlaybackSession::notifySessionDead() {
903    // Inform WifiDisplaySource of our premature death (wish).
904    sp<AMessage> notify = mNotify->dup();
905    notify->setInt32("what", kWhatSessionDead);
906    notify->post();
907
908    mWeAreDead = true;
909}
910
911void WifiDisplaySource::PlaybackSession::drainAccessUnits() {
912    ALOGV("audio/video has %d/%d buffers ready.",
913            mTracks.valueFor(1)->countQueuedOutputBuffers(),
914            mTracks.valueFor(0)->countQueuedOutputBuffers());
915
916    while (drainAccessUnit()) {
917    }
918}
919
920bool WifiDisplaySource::PlaybackSession::drainAccessUnit() {
921    ssize_t minTrackIndex = -1;
922    int64_t minTimeUs = -1ll;
923
924    for (size_t i = 0; i < mTracks.size(); ++i) {
925        const sp<Track> &track = mTracks.valueAt(i);
926
927        int64_t timeUs;
928        if (track->hasOutputBuffer(&timeUs)) {
929            if (minTrackIndex < 0 || timeUs < minTimeUs) {
930                minTrackIndex = mTracks.keyAt(i);
931                minTimeUs = timeUs;
932            }
933        } else if (!track->isSuspended()) {
934            // We still consider this track "live", so it should keep
935            // delivering output data whose time stamps we'll have to
936            // consider for proper interleaving.
937            return false;
938        }
939    }
940
941    if (minTrackIndex < 0) {
942        return false;
943    }
944
945    const sp<Track> &track = mTracks.valueFor(minTrackIndex);
946    sp<ABuffer> accessUnit = track->dequeueOutputBuffer();
947
948    sp<ABuffer> packets;
949    status_t err = packetizeAccessUnit(minTrackIndex, accessUnit, &packets);
950
951    if (err != OK) {
952        notifySessionDead();
953    }
954
955    if ((ssize_t)minTrackIndex == mVideoTrackIndex) {
956        packets->meta()->setInt32("isVideo", 1);
957    }
958    mSender->queuePackets(minTimeUs, packets);
959
960    return true;
961}
962
963}  // namespace android
964
965