PlaybackSession.cpp revision 4a114f03a79e157cab9396f986ef947df2255f1d
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 "TSPacketizer.h"
27#include "include/avc_utils.h"
28
29#include <binder/IServiceManager.h>
30#include <gui/ISurfaceComposer.h>
31#include <gui/SurfaceComposerClient.h>
32#include <media/IHDCP.h>
33#include <media/stagefright/foundation/ABitReader.h>
34#include <media/stagefright/foundation/ABuffer.h>
35#include <media/stagefright/foundation/ADebug.h>
36#include <media/stagefright/foundation/AMessage.h>
37#include <media/stagefright/foundation/hexdump.h>
38#include <media/stagefright/AudioSource.h>
39#include <media/stagefright/DataSource.h>
40#include <media/stagefright/MediaDefs.h>
41#include <media/stagefright/MediaErrors.h>
42#include <media/stagefright/MediaExtractor.h>
43#include <media/stagefright/MediaSource.h>
44#include <media/stagefright/MetaData.h>
45#include <media/stagefright/MPEG2TSWriter.h>
46#include <media/stagefright/SurfaceMediaSource.h>
47#include <media/stagefright/Utils.h>
48
49#include <OMX_IVCommon.h>
50
51namespace android {
52
53static size_t kMaxRTPPacketSize = 1500;
54static size_t kMaxNumTSPacketsPerRTPPacket = (kMaxRTPPacketSize - 12) / 188;
55
56struct WifiDisplaySource::PlaybackSession::Track : public AHandler {
57    enum {
58        kWhatStopped,
59    };
60
61    Track(const sp<AMessage> &notify,
62          const sp<ALooper> &pullLooper,
63          const sp<ALooper> &codecLooper,
64          const sp<MediaPuller> &mediaPuller,
65          const sp<Converter> &converter);
66
67    void setRepeaterSource(const sp<RepeaterSource> &source);
68
69    sp<AMessage> getFormat();
70    bool isAudio() const;
71
72    const sp<Converter> &converter() const;
73    ssize_t packetizerTrackIndex() const;
74
75    void setPacketizerTrackIndex(size_t index);
76
77    status_t start();
78    void stopAsync();
79
80    void queueAccessUnit(const sp<ABuffer> &accessUnit);
81    sp<ABuffer> dequeueAccessUnit();
82
83    void requestIDRFrame();
84
85protected:
86    virtual void onMessageReceived(const sp<AMessage> &msg);
87    virtual ~Track();
88
89private:
90    enum {
91        kWhatMediaPullerStopped,
92    };
93
94    sp<AMessage> mNotify;
95    sp<ALooper> mPullLooper;
96    sp<ALooper> mCodecLooper;
97    sp<MediaPuller> mMediaPuller;
98    sp<Converter> mConverter;
99    bool mStarted;
100    ssize_t mPacketizerTrackIndex;
101    bool mIsAudio;
102    List<sp<ABuffer> > mQueuedAccessUnits;
103    sp<RepeaterSource> mRepeaterSource;
104
105    static bool IsAudioFormat(const sp<AMessage> &format);
106
107    DISALLOW_EVIL_CONSTRUCTORS(Track);
108};
109
110WifiDisplaySource::PlaybackSession::Track::Track(
111        const sp<AMessage> &notify,
112        const sp<ALooper> &pullLooper,
113        const sp<ALooper> &codecLooper,
114        const sp<MediaPuller> &mediaPuller,
115        const sp<Converter> &converter)
116    : mNotify(notify),
117      mPullLooper(pullLooper),
118      mCodecLooper(codecLooper),
119      mMediaPuller(mediaPuller),
120      mConverter(converter),
121      mStarted(false),
122      mPacketizerTrackIndex(-1),
123      mIsAudio(IsAudioFormat(mConverter->getOutputFormat())) {
124}
125
126WifiDisplaySource::PlaybackSession::Track::~Track() {
127    CHECK(!mStarted);
128}
129
130// static
131bool WifiDisplaySource::PlaybackSession::Track::IsAudioFormat(
132        const sp<AMessage> &format) {
133    AString mime;
134    CHECK(format->findString("mime", &mime));
135
136    return !strncasecmp(mime.c_str(), "audio/", 6);
137}
138
139sp<AMessage> WifiDisplaySource::PlaybackSession::Track::getFormat() {
140    return mConverter->getOutputFormat();
141}
142
143bool WifiDisplaySource::PlaybackSession::Track::isAudio() const {
144    return mIsAudio;
145}
146
147const sp<Converter> &WifiDisplaySource::PlaybackSession::Track::converter() const {
148    return mConverter;
149}
150
151ssize_t WifiDisplaySource::PlaybackSession::Track::packetizerTrackIndex() const {
152    return mPacketizerTrackIndex;
153}
154
155void WifiDisplaySource::PlaybackSession::Track::setPacketizerTrackIndex(size_t index) {
156    CHECK_LT(mPacketizerTrackIndex, 0);
157    mPacketizerTrackIndex = index;
158}
159
160status_t WifiDisplaySource::PlaybackSession::Track::start() {
161    ALOGV("Track::start isAudio=%d", mIsAudio);
162
163    CHECK(!mStarted);
164
165    status_t err = OK;
166
167    if (mMediaPuller != NULL) {
168        err = mMediaPuller->start();
169    }
170
171    if (err == OK) {
172        mStarted = true;
173    }
174
175    return err;
176}
177
178void WifiDisplaySource::PlaybackSession::Track::stopAsync() {
179    ALOGV("Track::stopAsync isAudio=%d", mIsAudio);
180
181    mConverter->shutdownAsync();
182
183    sp<AMessage> msg = new AMessage(kWhatMediaPullerStopped, id());
184
185    if (mStarted && mMediaPuller != NULL) {
186        if (mRepeaterSource != NULL) {
187            // Let's unblock MediaPuller's MediaSource::read().
188            mRepeaterSource->wakeUp();
189        }
190
191        mMediaPuller->stopAsync(msg);
192    } else {
193        msg->post();
194    }
195}
196
197void WifiDisplaySource::PlaybackSession::Track::onMessageReceived(
198        const sp<AMessage> &msg) {
199    switch (msg->what()) {
200        case kWhatMediaPullerStopped:
201        {
202            mConverter.clear();
203
204            mStarted = false;
205
206            sp<AMessage> notify = mNotify->dup();
207            notify->setInt32("what", kWhatStopped);
208            notify->post();
209
210            ALOGI("kWhatStopped %s posted", mIsAudio ? "audio" : "video");
211            break;
212        }
213
214        default:
215            TRESPASS();
216    }
217}
218
219void WifiDisplaySource::PlaybackSession::Track::queueAccessUnit(
220        const sp<ABuffer> &accessUnit) {
221    mQueuedAccessUnits.push_back(accessUnit);
222}
223
224sp<ABuffer> WifiDisplaySource::PlaybackSession::Track::dequeueAccessUnit() {
225    if (mQueuedAccessUnits.empty()) {
226        return NULL;
227    }
228
229    sp<ABuffer> accessUnit = *mQueuedAccessUnits.begin();
230    CHECK(accessUnit != NULL);
231
232    mQueuedAccessUnits.erase(mQueuedAccessUnits.begin());
233
234    return accessUnit;
235}
236
237void WifiDisplaySource::PlaybackSession::Track::setRepeaterSource(
238        const sp<RepeaterSource> &source) {
239    mRepeaterSource = source;
240}
241
242void WifiDisplaySource::PlaybackSession::Track::requestIDRFrame() {
243    if (mIsAudio) {
244        return;
245    }
246
247    if (mRepeaterSource != NULL) {
248        mRepeaterSource->wakeUp();
249    }
250
251    mConverter->requestIDRFrame();
252}
253
254////////////////////////////////////////////////////////////////////////////////
255
256WifiDisplaySource::PlaybackSession::PlaybackSession(
257        const sp<ANetworkSession> &netSession,
258        const sp<AMessage> &notify,
259        const in_addr &interfaceAddr,
260        const sp<IHDCP> &hdcp)
261    : mNetSession(netSession),
262      mNotify(notify),
263      mInterfaceAddr(interfaceAddr),
264      mHDCP(hdcp),
265      mWeAreDead(false),
266      mLastLifesignUs(),
267      mVideoTrackIndex(-1),
268      mTSQueue(new ABuffer(12 + kMaxNumTSPacketsPerRTPPacket * 188)),
269      mPrevTimeUs(-1ll),
270      mTransportMode(TRANSPORT_UDP),
271      mAllTracksHavePacketizerIndex(false),
272      mRTPChannel(0),
273      mRTCPChannel(0),
274      mRTPPort(0),
275      mRTPSessionID(0),
276      mRTCPSessionID(0),
277#if ENABLE_RETRANSMISSION
278      mRTPRetransmissionSessionID(0),
279      mRTCPRetransmissionSessionID(0),
280#endif
281      mClientRTPPort(0),
282      mClientRTCPPort(0),
283      mRTPConnected(false),
284      mRTCPConnected(false),
285      mRTPSeqNo(0),
286#if ENABLE_RETRANSMISSION
287      mRTPRetransmissionSeqNo(0),
288#endif
289      mLastNTPTime(0),
290      mLastRTPTime(0),
291      mNumRTPSent(0),
292      mNumRTPOctetsSent(0),
293      mNumSRsSent(0),
294      mSendSRPending(false)
295#if ENABLE_RETRANSMISSION
296      ,mHistoryLength(0)
297#endif
298#if TRACK_BANDWIDTH
299      ,mFirstPacketTimeUs(-1ll)
300      ,mTotalBytesSent(0ll)
301#endif
302#if LOG_TRANSPORT_STREAM
303      ,mLogFile(NULL)
304#endif
305{
306    mTSQueue->setRange(0, 12);
307
308#if LOG_TRANSPORT_STREAM
309    mLogFile = fopen("/system/etc/log.ts", "wb");
310#endif
311}
312
313status_t WifiDisplaySource::PlaybackSession::init(
314        const char *clientIP, int32_t clientRtp, int32_t clientRtcp,
315        TransportMode transportMode) {
316    mClientIP = clientIP;
317
318    status_t err = setupPacketizer();
319
320    if (err != OK) {
321        return err;
322    }
323
324    mTransportMode = transportMode;
325
326    if (transportMode == TRANSPORT_TCP_INTERLEAVED) {
327        mRTPChannel = clientRtp;
328        mRTCPChannel = clientRtcp;
329        mRTPPort = 0;
330        mRTPSessionID = 0;
331        mRTCPSessionID = 0;
332
333        updateLiveness();
334        return OK;
335    }
336
337    mRTPChannel = 0;
338    mRTCPChannel = 0;
339
340    if (mTransportMode == TRANSPORT_TCP) {
341        // XXX This is wrong, we need to allocate sockets here, we only
342        // need to do this because the dongles are not establishing their
343        // end until after PLAY instead of before SETUP.
344        mRTPPort = 20000;
345        mRTPSessionID = 0;
346        mRTCPSessionID = 0;
347        mClientRTPPort = clientRtp;
348        mClientRTCPPort = clientRtcp;
349
350        updateLiveness();
351        return OK;
352    }
353
354    int serverRtp;
355
356    sp<AMessage> rtpNotify = new AMessage(kWhatRTPNotify, id());
357    sp<AMessage> rtcpNotify = new AMessage(kWhatRTCPNotify, id());
358
359#if ENABLE_RETRANSMISSION
360    sp<AMessage> rtpRetransmissionNotify =
361        new AMessage(kWhatRTPRetransmissionNotify, id());
362
363    sp<AMessage> rtcpRetransmissionNotify =
364        new AMessage(kWhatRTCPRetransmissionNotify, id());
365#endif
366
367    for (serverRtp = 15550;; serverRtp += 2) {
368        int32_t rtpSession;
369        if (mTransportMode == TRANSPORT_UDP) {
370            err = mNetSession->createUDPSession(
371                        serverRtp, clientIP, clientRtp,
372                        rtpNotify, &rtpSession);
373        } else {
374            err = mNetSession->createTCPDatagramSession(
375                        serverRtp, clientIP, clientRtp,
376                        rtpNotify, &rtpSession);
377        }
378
379        if (err != OK) {
380            ALOGI("failed to create RTP socket on port %d", serverRtp);
381            continue;
382        }
383
384        int32_t rtcpSession = 0;
385
386        if (clientRtcp >= 0) {
387            if (mTransportMode == TRANSPORT_UDP) {
388                err = mNetSession->createUDPSession(
389                        serverRtp + 1, clientIP, clientRtcp,
390                        rtcpNotify, &rtcpSession);
391            } else {
392                err = mNetSession->createTCPDatagramSession(
393                        serverRtp + 1, clientIP, clientRtcp,
394                        rtcpNotify, &rtcpSession);
395            }
396
397            if (err != OK) {
398                ALOGI("failed to create RTCP socket on port %d", serverRtp + 1);
399
400                mNetSession->destroySession(rtpSession);
401                continue;
402            }
403        }
404
405#if ENABLE_RETRANSMISSION
406        if (mTransportMode == TRANSPORT_UDP) {
407            int32_t rtpRetransmissionSession;
408
409            err = mNetSession->createUDPSession(
410                        serverRtp + kRetransmissionPortOffset,
411                        clientIP,
412                        clientRtp + kRetransmissionPortOffset,
413                        rtpRetransmissionNotify,
414                        &rtpRetransmissionSession);
415
416            if (err != OK) {
417                mNetSession->destroySession(rtcpSession);
418                mNetSession->destroySession(rtpSession);
419                continue;
420            }
421
422            CHECK_GE(clientRtcp, 0);
423
424            int32_t rtcpRetransmissionSession;
425            err = mNetSession->createUDPSession(
426                        serverRtp + 1 + kRetransmissionPortOffset,
427                        clientIP,
428                        clientRtp + 1 + kRetransmissionPortOffset,
429                        rtcpRetransmissionNotify,
430                        &rtcpRetransmissionSession);
431
432            if (err != OK) {
433                mNetSession->destroySession(rtpRetransmissionSession);
434                mNetSession->destroySession(rtcpSession);
435                mNetSession->destroySession(rtpSession);
436                continue;
437            }
438
439            mRTPRetransmissionSessionID = rtpRetransmissionSession;
440            mRTCPRetransmissionSessionID = rtcpRetransmissionSession;
441
442            ALOGI("rtpRetransmissionSessionID = %d, "
443                  "rtcpRetransmissionSessionID = %d",
444                  rtpRetransmissionSession, rtcpRetransmissionSession);
445        }
446#endif
447
448        mRTPPort = serverRtp;
449        mRTPSessionID = rtpSession;
450        mRTCPSessionID = rtcpSession;
451
452        ALOGI("rtpSessionID = %d, rtcpSessionID = %d", rtpSession, rtcpSession);
453        break;
454    }
455
456    if (mRTPPort == 0) {
457        return UNKNOWN_ERROR;
458    }
459
460    updateLiveness();
461
462    return OK;
463}
464
465WifiDisplaySource::PlaybackSession::~PlaybackSession() {
466#if LOG_TRANSPORT_STREAM
467    if (mLogFile != NULL) {
468        fclose(mLogFile);
469        mLogFile = NULL;
470    }
471#endif
472}
473
474int32_t WifiDisplaySource::PlaybackSession::getRTPPort() const {
475    return mRTPPort;
476}
477
478int64_t WifiDisplaySource::PlaybackSession::getLastLifesignUs() const {
479    return mLastLifesignUs;
480}
481
482void WifiDisplaySource::PlaybackSession::updateLiveness() {
483    mLastLifesignUs = ALooper::GetNowUs();
484}
485
486status_t WifiDisplaySource::PlaybackSession::play() {
487    updateLiveness();
488
489    return OK;
490}
491
492status_t WifiDisplaySource::PlaybackSession::finishPlay() {
493    // XXX Give the dongle a second to bind its sockets.
494    (new AMessage(kWhatFinishPlay, id()))->post(1000000ll);
495    return OK;
496}
497
498status_t WifiDisplaySource::PlaybackSession::onFinishPlay() {
499    if (mTransportMode != TRANSPORT_TCP) {
500        return onFinishPlay2();
501    }
502
503    sp<AMessage> rtpNotify = new AMessage(kWhatRTPNotify, id());
504
505    status_t err = mNetSession->createTCPDatagramSession(
506                mRTPPort, mClientIP.c_str(), mClientRTPPort,
507                rtpNotify, &mRTPSessionID);
508
509    if (err != OK) {
510        return err;
511    }
512
513    if (mClientRTCPPort >= 0) {
514        sp<AMessage> rtcpNotify = new AMessage(kWhatRTCPNotify, id());
515
516        err = mNetSession->createTCPDatagramSession(
517                mRTPPort + 1, mClientIP.c_str(), mClientRTCPPort,
518                rtcpNotify, &mRTCPSessionID);
519    }
520
521    return err;
522}
523
524status_t WifiDisplaySource::PlaybackSession::onFinishPlay2() {
525    if (mRTCPSessionID != 0) {
526        scheduleSendSR();
527    }
528
529    for (size_t i = 0; i < mTracks.size(); ++i) {
530        CHECK_EQ((status_t)OK, mTracks.editValueAt(i)->start());
531    }
532
533    sp<AMessage> notify = mNotify->dup();
534    notify->setInt32("what", kWhatSessionEstablished);
535    notify->post();
536
537    return OK;
538}
539
540status_t WifiDisplaySource::PlaybackSession::pause() {
541    updateLiveness();
542
543    return OK;
544}
545
546void WifiDisplaySource::PlaybackSession::destroyAsync() {
547    ALOGI("destroyAsync");
548
549    for (size_t i = 0; i < mTracks.size(); ++i) {
550        mTracks.valueAt(i)->stopAsync();
551    }
552}
553
554void WifiDisplaySource::PlaybackSession::onMessageReceived(
555        const sp<AMessage> &msg) {
556    switch (msg->what()) {
557        case kWhatRTPNotify:
558        case kWhatRTCPNotify:
559#if ENABLE_RETRANSMISSION
560        case kWhatRTPRetransmissionNotify:
561        case kWhatRTCPRetransmissionNotify:
562#endif
563        {
564            int32_t reason;
565            CHECK(msg->findInt32("reason", &reason));
566
567            switch (reason) {
568                case ANetworkSession::kWhatError:
569                {
570                    int32_t sessionID;
571                    CHECK(msg->findInt32("sessionID", &sessionID));
572
573                    int32_t err;
574                    CHECK(msg->findInt32("err", &err));
575
576                    int32_t errorOccuredDuringSend;
577                    CHECK(msg->findInt32("send", &errorOccuredDuringSend));
578
579                    AString detail;
580                    CHECK(msg->findString("detail", &detail));
581
582                    if ((msg->what() == kWhatRTPNotify
583#if ENABLE_RETRANSMISSION
584                            || msg->what() == kWhatRTPRetransmissionNotify
585#endif
586                        ) && !errorOccuredDuringSend) {
587                        // This is ok, we don't expect to receive anything on
588                        // the RTP socket.
589                        break;
590                    }
591
592                    ALOGE("An error occurred during %s in session %d "
593                          "(%d, '%s' (%s)).",
594                          errorOccuredDuringSend ? "send" : "receive",
595                          sessionID,
596                          err,
597                          detail.c_str(),
598                          strerror(-err));
599
600                    mNetSession->destroySession(sessionID);
601
602                    if (sessionID == mRTPSessionID) {
603                        mRTPSessionID = 0;
604                    } else if (sessionID == mRTCPSessionID) {
605                        mRTCPSessionID = 0;
606                    }
607#if ENABLE_RETRANSMISSION
608                    else if (sessionID == mRTPRetransmissionSessionID) {
609                        mRTPRetransmissionSessionID = 0;
610                    } else if (sessionID == mRTCPRetransmissionSessionID) {
611                        mRTCPRetransmissionSessionID = 0;
612                    }
613#endif
614
615                    notifySessionDead();
616                    break;
617                }
618
619                case ANetworkSession::kWhatDatagram:
620                {
621                    int32_t sessionID;
622                    CHECK(msg->findInt32("sessionID", &sessionID));
623
624                    sp<ABuffer> data;
625                    CHECK(msg->findBuffer("data", &data));
626
627                    status_t err;
628                    if (msg->what() == kWhatRTCPNotify
629#if ENABLE_RETRANSMISSION
630                            || msg->what() == kWhatRTCPRetransmissionNotify
631#endif
632                       )
633                    {
634                        err = parseRTCP(data);
635                    }
636                    break;
637                }
638
639                case ANetworkSession::kWhatConnected:
640                {
641                    CHECK_EQ(mTransportMode, TRANSPORT_TCP);
642
643                    int32_t sessionID;
644                    CHECK(msg->findInt32("sessionID", &sessionID));
645
646                    if (sessionID == mRTPSessionID) {
647                        CHECK(!mRTPConnected);
648                        mRTPConnected = true;
649                        ALOGI("RTP Session now connected.");
650                    } else if (sessionID == mRTCPSessionID) {
651                        CHECK(!mRTCPConnected);
652                        mRTCPConnected = true;
653                        ALOGI("RTCP Session now connected.");
654                    } else {
655                        TRESPASS();
656                    }
657
658                    if (mRTPConnected
659                            && (mClientRTCPPort < 0 || mRTCPConnected)) {
660                        onFinishPlay2();
661                    }
662                    break;
663                }
664
665                default:
666                    TRESPASS();
667            }
668            break;
669        }
670
671        case kWhatSendSR:
672        {
673            mSendSRPending = false;
674
675            if (mRTCPSessionID == 0) {
676                break;
677            }
678
679            onSendSR();
680
681            scheduleSendSR();
682            break;
683        }
684
685        case kWhatConverterNotify:
686        {
687            if (mWeAreDead) {
688                ALOGV("dropping msg '%s' because we're dead",
689                      msg->debugString().c_str());
690
691                break;
692            }
693
694            int32_t what;
695            CHECK(msg->findInt32("what", &what));
696
697            size_t trackIndex;
698            CHECK(msg->findSize("trackIndex", &trackIndex));
699
700            if (what == Converter::kWhatAccessUnit) {
701                const sp<Track> &track = mTracks.valueFor(trackIndex);
702
703                ssize_t packetizerTrackIndex = track->packetizerTrackIndex();
704
705                if (packetizerTrackIndex < 0) {
706                    packetizerTrackIndex =
707                        mPacketizer->addTrack(track->getFormat());
708
709                    CHECK_GE(packetizerTrackIndex, 0);
710
711                    track->setPacketizerTrackIndex(packetizerTrackIndex);
712
713                    if (allTracksHavePacketizerIndex()) {
714                        status_t err = packetizeQueuedAccessUnits();
715
716                        if (err != OK) {
717                            notifySessionDead();
718                            break;
719                        }
720                    }
721                }
722
723                sp<ABuffer> accessUnit;
724                CHECK(msg->findBuffer("accessUnit", &accessUnit));
725
726                if (!allTracksHavePacketizerIndex()) {
727                    track->queueAccessUnit(accessUnit);
728                    break;
729                }
730
731                status_t err = packetizeAccessUnit(trackIndex, accessUnit);
732
733                if (err != OK) {
734                    notifySessionDead();
735                }
736                break;
737            } else if (what == Converter::kWhatEOS) {
738                CHECK_EQ(what, Converter::kWhatEOS);
739
740                ALOGI("output EOS on track %d", trackIndex);
741
742                ssize_t index = mTracks.indexOfKey(trackIndex);
743                CHECK_GE(index, 0);
744
745                const sp<Converter> &converter =
746                    mTracks.valueAt(index)->converter();
747                looper()->unregisterHandler(converter->id());
748
749                mTracks.removeItemsAt(index);
750
751                if (mTracks.isEmpty()) {
752                    ALOGI("Reached EOS");
753                }
754            } else {
755                CHECK_EQ(what, Converter::kWhatError);
756
757                status_t err;
758                CHECK(msg->findInt32("err", &err));
759
760                ALOGE("converter signaled error %d", err);
761
762                notifySessionDead();
763            }
764            break;
765        }
766
767        case kWhatFinishPlay:
768        {
769            onFinishPlay();
770            break;
771        }
772
773        case kWhatTrackNotify:
774        {
775            int32_t what;
776            CHECK(msg->findInt32("what", &what));
777
778            size_t trackIndex;
779            CHECK(msg->findSize("trackIndex", &trackIndex));
780
781            if (what == Track::kWhatStopped) {
782                ALOGI("Track %d stopped", trackIndex);
783
784                sp<Track> track = mTracks.valueFor(trackIndex);
785                looper()->unregisterHandler(track->id());
786                mTracks.removeItem(trackIndex);
787                track.clear();
788
789                if (!mTracks.isEmpty()) {
790                    ALOGI("not all tracks are stopped yet");
791                    break;
792                }
793
794                mPacketizer.clear();
795
796#if ENABLE_RETRANSMISSION
797                if (mRTCPRetransmissionSessionID != 0) {
798                    mNetSession->destroySession(mRTCPRetransmissionSessionID);
799                }
800
801                if (mRTPRetransmissionSessionID != 0) {
802                    mNetSession->destroySession(mRTPRetransmissionSessionID);
803                }
804#endif
805
806                if (mRTCPSessionID != 0) {
807                    mNetSession->destroySession(mRTCPSessionID);
808                }
809
810                if (mRTPSessionID != 0) {
811                    mNetSession->destroySession(mRTPSessionID);
812                }
813
814                sp<AMessage> notify = mNotify->dup();
815                notify->setInt32("what", kWhatSessionDestroyed);
816                notify->post();
817            }
818            break;
819        }
820
821        default:
822            TRESPASS();
823    }
824}
825
826status_t WifiDisplaySource::PlaybackSession::setupPacketizer() {
827    mPacketizer = new TSPacketizer;
828
829    status_t err = addVideoSource();
830
831    if (err != OK) {
832        return err;
833    }
834
835    return addAudioSource();
836}
837
838status_t WifiDisplaySource::PlaybackSession::addSource(
839        bool isVideo, const sp<MediaSource> &source, bool isRepeaterSource,
840        size_t *numInputBuffers) {
841    sp<ALooper> pullLooper = new ALooper;
842    pullLooper->setName("pull_looper");
843
844    pullLooper->start(
845            false /* runOnCallingThread */,
846            false /* canCallJava */,
847            PRIORITY_AUDIO);
848
849    sp<ALooper> codecLooper = new ALooper;
850    codecLooper->setName("codec_looper");
851
852    codecLooper->start(
853            false /* runOnCallingThread */,
854            false /* canCallJava */,
855            PRIORITY_AUDIO);
856
857    size_t trackIndex;
858
859    sp<AMessage> notify;
860
861    trackIndex = mTracks.size();
862
863    sp<AMessage> format;
864    status_t err = convertMetaDataToMessage(source->getFormat(), &format);
865    CHECK_EQ(err, (status_t)OK);
866
867    if (isVideo) {
868        format->setInt32("store-metadata-in-buffers", true);
869
870        format->setInt32(
871                "color-format", OMX_COLOR_FormatAndroidOpaque);
872    }
873
874    notify = new AMessage(kWhatConverterNotify, id());
875    notify->setSize("trackIndex", trackIndex);
876
877    sp<Converter> converter =
878        new Converter(notify, codecLooper, format);
879
880    if (converter->initCheck() != OK) {
881        return converter->initCheck();
882    }
883
884    looper()->registerHandler(converter);
885
886    notify = new AMessage(Converter::kWhatMediaPullerNotify, converter->id());
887    notify->setSize("trackIndex", trackIndex);
888
889    sp<MediaPuller> puller = new MediaPuller(source, notify);
890    pullLooper->registerHandler(puller);
891
892    if (numInputBuffers != NULL) {
893        *numInputBuffers = converter->getInputBufferCount();
894    }
895
896    notify = new AMessage(kWhatTrackNotify, id());
897    notify->setSize("trackIndex", trackIndex);
898
899    sp<Track> track = new Track(
900            notify, pullLooper, codecLooper, puller, converter);
901
902    if (isRepeaterSource) {
903        track->setRepeaterSource(static_cast<RepeaterSource *>(source.get()));
904    }
905
906    looper()->registerHandler(track);
907
908    mTracks.add(trackIndex, track);
909
910    if (isVideo) {
911        mVideoTrackIndex = trackIndex;
912    }
913
914    return OK;
915}
916
917status_t WifiDisplaySource::PlaybackSession::addVideoSource() {
918    sp<SurfaceMediaSource> source = new SurfaceMediaSource(width(), height());
919
920    source->setUseAbsoluteTimestamps();
921
922#if 1
923    sp<RepeaterSource> videoSource =
924        new RepeaterSource(source, 30.0 /* rateHz */);
925#endif
926
927#if 1
928    size_t numInputBuffers;
929    status_t err = addSource(
930            true /* isVideo */, videoSource, true /* isRepeaterSource */,
931            &numInputBuffers);
932#else
933    size_t numInputBuffers;
934    status_t err = addSource(
935            true /* isVideo */, source, false /* isRepeaterSource */,
936            &numInputBuffers);
937#endif
938
939    if (err != OK) {
940        return err;
941    }
942
943    err = source->setMaxAcquiredBufferCount(numInputBuffers);
944    CHECK_EQ(err, (status_t)OK);
945
946    mBufferQueue = source->getBufferQueue();
947
948    return OK;
949}
950
951status_t WifiDisplaySource::PlaybackSession::addAudioSource() {
952    sp<AudioSource> audioSource = new AudioSource(
953            AUDIO_SOURCE_REMOTE_SUBMIX,
954            48000 /* sampleRate */,
955            2 /* channelCount */);
956
957    if (audioSource->initCheck() == OK) {
958        return addSource(
959                false /* isVideo */, audioSource, false /* isRepeaterSource */,
960                NULL /* numInputBuffers */);
961    }
962
963    ALOGW("Unable to instantiate audio source");
964
965    return OK;
966}
967
968sp<ISurfaceTexture> WifiDisplaySource::PlaybackSession::getSurfaceTexture() {
969    return mBufferQueue;
970}
971
972int32_t WifiDisplaySource::PlaybackSession::width() const {
973    return 1280;
974}
975
976int32_t WifiDisplaySource::PlaybackSession::height() const {
977    return 720;
978}
979
980void WifiDisplaySource::PlaybackSession::scheduleSendSR() {
981    if (mSendSRPending) {
982        return;
983    }
984
985    mSendSRPending = true;
986    (new AMessage(kWhatSendSR, id()))->post(kSendSRIntervalUs);
987}
988
989void WifiDisplaySource::PlaybackSession::addSR(const sp<ABuffer> &buffer) {
990    uint8_t *data = buffer->data() + buffer->size();
991
992    // TODO: Use macros/utility functions to clean up all the bitshifts below.
993
994    data[0] = 0x80 | 0;
995    data[1] = 200;  // SR
996    data[2] = 0;
997    data[3] = 6;
998    data[4] = kSourceID >> 24;
999    data[5] = (kSourceID >> 16) & 0xff;
1000    data[6] = (kSourceID >> 8) & 0xff;
1001    data[7] = kSourceID & 0xff;
1002
1003    data[8] = mLastNTPTime >> (64 - 8);
1004    data[9] = (mLastNTPTime >> (64 - 16)) & 0xff;
1005    data[10] = (mLastNTPTime >> (64 - 24)) & 0xff;
1006    data[11] = (mLastNTPTime >> 32) & 0xff;
1007    data[12] = (mLastNTPTime >> 24) & 0xff;
1008    data[13] = (mLastNTPTime >> 16) & 0xff;
1009    data[14] = (mLastNTPTime >> 8) & 0xff;
1010    data[15] = mLastNTPTime & 0xff;
1011
1012    data[16] = (mLastRTPTime >> 24) & 0xff;
1013    data[17] = (mLastRTPTime >> 16) & 0xff;
1014    data[18] = (mLastRTPTime >> 8) & 0xff;
1015    data[19] = mLastRTPTime & 0xff;
1016
1017    data[20] = mNumRTPSent >> 24;
1018    data[21] = (mNumRTPSent >> 16) & 0xff;
1019    data[22] = (mNumRTPSent >> 8) & 0xff;
1020    data[23] = mNumRTPSent & 0xff;
1021
1022    data[24] = mNumRTPOctetsSent >> 24;
1023    data[25] = (mNumRTPOctetsSent >> 16) & 0xff;
1024    data[26] = (mNumRTPOctetsSent >> 8) & 0xff;
1025    data[27] = mNumRTPOctetsSent & 0xff;
1026
1027    buffer->setRange(buffer->offset(), buffer->size() + 28);
1028}
1029
1030void WifiDisplaySource::PlaybackSession::addSDES(const sp<ABuffer> &buffer) {
1031    uint8_t *data = buffer->data() + buffer->size();
1032    data[0] = 0x80 | 1;
1033    data[1] = 202;  // SDES
1034    data[4] = kSourceID >> 24;
1035    data[5] = (kSourceID >> 16) & 0xff;
1036    data[6] = (kSourceID >> 8) & 0xff;
1037    data[7] = kSourceID & 0xff;
1038
1039    size_t offset = 8;
1040
1041    data[offset++] = 1;  // CNAME
1042
1043    static const char *kCNAME = "someone@somewhere";
1044    data[offset++] = strlen(kCNAME);
1045
1046    memcpy(&data[offset], kCNAME, strlen(kCNAME));
1047    offset += strlen(kCNAME);
1048
1049    data[offset++] = 7;  // NOTE
1050
1051    static const char *kNOTE = "Hell's frozen over.";
1052    data[offset++] = strlen(kNOTE);
1053
1054    memcpy(&data[offset], kNOTE, strlen(kNOTE));
1055    offset += strlen(kNOTE);
1056
1057    data[offset++] = 0;
1058
1059    if ((offset % 4) > 0) {
1060        size_t count = 4 - (offset % 4);
1061        switch (count) {
1062            case 3:
1063                data[offset++] = 0;
1064            case 2:
1065                data[offset++] = 0;
1066            case 1:
1067                data[offset++] = 0;
1068        }
1069    }
1070
1071    size_t numWords = (offset / 4) - 1;
1072    data[2] = numWords >> 8;
1073    data[3] = numWords & 0xff;
1074
1075    buffer->setRange(buffer->offset(), buffer->size() + offset);
1076}
1077
1078// static
1079uint64_t WifiDisplaySource::PlaybackSession::GetNowNTP() {
1080    uint64_t nowUs = ALooper::GetNowUs();
1081
1082    nowUs += ((70ll * 365 + 17) * 24) * 60 * 60 * 1000000ll;
1083
1084    uint64_t hi = nowUs / 1000000ll;
1085    uint64_t lo = ((1ll << 32) * (nowUs % 1000000ll)) / 1000000ll;
1086
1087    return (hi << 32) | lo;
1088}
1089
1090void WifiDisplaySource::PlaybackSession::onSendSR() {
1091    sp<ABuffer> buffer = new ABuffer(1500);
1092    buffer->setRange(0, 0);
1093
1094    addSR(buffer);
1095    addSDES(buffer);
1096
1097    if (mTransportMode == TRANSPORT_TCP_INTERLEAVED) {
1098        sp<AMessage> notify = mNotify->dup();
1099        notify->setInt32("what", kWhatBinaryData);
1100        notify->setInt32("channel", mRTCPChannel);
1101        notify->setBuffer("data", buffer);
1102        notify->post();
1103    } else {
1104        sendPacket(mRTCPSessionID, buffer->data(), buffer->size());
1105    }
1106
1107    ++mNumSRsSent;
1108}
1109
1110ssize_t WifiDisplaySource::PlaybackSession::appendTSData(
1111        const void *data, size_t size, bool timeDiscontinuity, bool flush) {
1112    CHECK_EQ(size, 188);
1113
1114    CHECK_LE(mTSQueue->size() + size, mTSQueue->capacity());
1115
1116    memcpy(mTSQueue->data() + mTSQueue->size(), data, size);
1117    mTSQueue->setRange(0, mTSQueue->size() + size);
1118
1119    if (flush || mTSQueue->size() == mTSQueue->capacity()) {
1120        // flush
1121
1122        int64_t nowUs = ALooper::GetNowUs();
1123
1124#if TRACK_BANDWIDTH
1125        if (mFirstPacketTimeUs < 0ll) {
1126            mFirstPacketTimeUs = nowUs;
1127        }
1128#endif
1129
1130        // 90kHz time scale
1131        uint32_t rtpTime = (nowUs * 9ll) / 100ll;
1132
1133        uint8_t *rtp = mTSQueue->data();
1134        rtp[0] = 0x80;
1135        rtp[1] = 33 | (timeDiscontinuity ? (1 << 7) : 0);  // M-bit
1136        rtp[2] = (mRTPSeqNo >> 8) & 0xff;
1137        rtp[3] = mRTPSeqNo & 0xff;
1138        rtp[4] = rtpTime >> 24;
1139        rtp[5] = (rtpTime >> 16) & 0xff;
1140        rtp[6] = (rtpTime >> 8) & 0xff;
1141        rtp[7] = rtpTime & 0xff;
1142        rtp[8] = kSourceID >> 24;
1143        rtp[9] = (kSourceID >> 16) & 0xff;
1144        rtp[10] = (kSourceID >> 8) & 0xff;
1145        rtp[11] = kSourceID & 0xff;
1146
1147        ++mRTPSeqNo;
1148        ++mNumRTPSent;
1149        mNumRTPOctetsSent += mTSQueue->size() - 12;
1150
1151        mLastRTPTime = rtpTime;
1152        mLastNTPTime = GetNowNTP();
1153
1154        if (mTransportMode == TRANSPORT_TCP_INTERLEAVED) {
1155            sp<AMessage> notify = mNotify->dup();
1156            notify->setInt32("what", kWhatBinaryData);
1157
1158            sp<ABuffer> data = new ABuffer(mTSQueue->size());
1159            memcpy(data->data(), rtp, mTSQueue->size());
1160
1161            notify->setInt32("channel", mRTPChannel);
1162            notify->setBuffer("data", data);
1163            notify->post();
1164        } else {
1165            sendPacket(mRTPSessionID, rtp, mTSQueue->size());
1166
1167#if TRACK_BANDWIDTH
1168            mTotalBytesSent += mTSQueue->size();
1169            int64_t delayUs = ALooper::GetNowUs() - mFirstPacketTimeUs;
1170
1171            if (delayUs > 0ll) {
1172                ALOGI("approx. net bandwidth used: %.2f Mbit/sec",
1173                        mTotalBytesSent * 8.0 / delayUs);
1174            }
1175#endif
1176        }
1177
1178#if ENABLE_RETRANSMISSION
1179        mTSQueue->setInt32Data(mRTPSeqNo - 1);
1180
1181        mHistory.push_back(mTSQueue);
1182        ++mHistoryLength;
1183
1184        if (mHistoryLength > kMaxHistoryLength) {
1185            mTSQueue = *mHistory.begin();
1186            mHistory.erase(mHistory.begin());
1187
1188            --mHistoryLength;
1189        } else {
1190            mTSQueue = new ABuffer(12 + kMaxNumTSPacketsPerRTPPacket * 188);
1191        }
1192#endif
1193
1194        mTSQueue->setRange(0, 12);
1195    }
1196
1197    return size;
1198}
1199
1200status_t WifiDisplaySource::PlaybackSession::parseRTCP(
1201        const sp<ABuffer> &buffer) {
1202    const uint8_t *data = buffer->data();
1203    size_t size = buffer->size();
1204
1205    while (size > 0) {
1206        if (size < 8) {
1207            // Too short to be a valid RTCP header
1208            return ERROR_MALFORMED;
1209        }
1210
1211        if ((data[0] >> 6) != 2) {
1212            // Unsupported version.
1213            return ERROR_UNSUPPORTED;
1214        }
1215
1216        if (data[0] & 0x20) {
1217            // Padding present.
1218
1219            size_t paddingLength = data[size - 1];
1220
1221            if (paddingLength + 12 > size) {
1222                // If we removed this much padding we'd end up with something
1223                // that's too short to be a valid RTP header.
1224                return ERROR_MALFORMED;
1225            }
1226
1227            size -= paddingLength;
1228        }
1229
1230        size_t headerLength = 4 * (data[2] << 8 | data[3]) + 4;
1231
1232        if (size < headerLength) {
1233            // Only received a partial packet?
1234            return ERROR_MALFORMED;
1235        }
1236
1237        switch (data[1]) {
1238            case 200:
1239            case 201:  // RR
1240            case 202:  // SDES
1241            case 203:
1242            case 204:  // APP
1243                break;
1244
1245#if ENABLE_RETRANSMISSION
1246            case 205:  // TSFB (transport layer specific feedback)
1247                parseTSFB(data, headerLength);
1248                break;
1249#endif
1250
1251            case 206:  // PSFB (payload specific feedback)
1252                hexdump(data, headerLength);
1253                break;
1254
1255            default:
1256            {
1257                ALOGW("Unknown RTCP packet type %u of size %d",
1258                     (unsigned)data[1], headerLength);
1259                break;
1260            }
1261        }
1262
1263        data += headerLength;
1264        size -= headerLength;
1265    }
1266
1267    return OK;
1268}
1269
1270#if ENABLE_RETRANSMISSION
1271status_t WifiDisplaySource::PlaybackSession::parseTSFB(
1272        const uint8_t *data, size_t size) {
1273    if ((data[0] & 0x1f) != 1) {
1274        return ERROR_UNSUPPORTED;  // We only support NACK for now.
1275    }
1276
1277    uint32_t srcId = U32_AT(&data[8]);
1278    if (srcId != kSourceID) {
1279        return ERROR_MALFORMED;
1280    }
1281
1282    for (size_t i = 12; i < size; i += 4) {
1283        uint16_t seqNo = U16_AT(&data[i]);
1284        uint16_t blp = U16_AT(&data[i + 2]);
1285
1286        List<sp<ABuffer> >::iterator it = mHistory.begin();
1287        bool foundSeqNo = false;
1288        while (it != mHistory.end()) {
1289            const sp<ABuffer> &buffer = *it;
1290
1291            uint16_t bufferSeqNo = buffer->int32Data() & 0xffff;
1292
1293            bool retransmit = false;
1294            if (bufferSeqNo == seqNo) {
1295                retransmit = true;
1296            } else if (blp != 0) {
1297                for (size_t i = 0; i < 16; ++i) {
1298                    if ((blp & (1 << i))
1299                        && (bufferSeqNo == ((seqNo + i + 1) & 0xffff))) {
1300                        blp &= ~(1 << i);
1301                        retransmit = true;
1302                    }
1303                }
1304            }
1305
1306            if (retransmit) {
1307                ALOGI("retransmitting seqNo %d", bufferSeqNo);
1308
1309                sp<ABuffer> retransRTP = new ABuffer(2 + buffer->size());
1310                uint8_t *rtp = retransRTP->data();
1311                memcpy(rtp, buffer->data(), 12);
1312                rtp[2] = (mRTPRetransmissionSeqNo >> 8) & 0xff;
1313                rtp[3] = mRTPRetransmissionSeqNo & 0xff;
1314                rtp[12] = (bufferSeqNo >> 8) & 0xff;
1315                rtp[13] = bufferSeqNo & 0xff;
1316                memcpy(&rtp[14], buffer->data() + 12, buffer->size() - 12);
1317
1318                ++mRTPRetransmissionSeqNo;
1319
1320                sendPacket(
1321                        mRTPRetransmissionSessionID,
1322                        retransRTP->data(), retransRTP->size());
1323
1324                if (bufferSeqNo == seqNo) {
1325                    foundSeqNo = true;
1326                }
1327
1328                if (foundSeqNo && blp == 0) {
1329                    break;
1330                }
1331            }
1332
1333            ++it;
1334        }
1335
1336        if (!foundSeqNo || blp != 0) {
1337            ALOGI("Some sequence numbers were no longer available for "
1338                  "retransmission");
1339        }
1340    }
1341
1342    return OK;
1343}
1344#endif
1345
1346void WifiDisplaySource::PlaybackSession::requestIDRFrame() {
1347    for (size_t i = 0; i < mTracks.size(); ++i) {
1348        const sp<Track> &track = mTracks.valueAt(i);
1349
1350        track->requestIDRFrame();
1351    }
1352}
1353
1354status_t WifiDisplaySource::PlaybackSession::sendPacket(
1355        int32_t sessionID, const void *data, size_t size) {
1356    return mNetSession->sendRequest(sessionID, data, size);
1357}
1358
1359bool WifiDisplaySource::PlaybackSession::allTracksHavePacketizerIndex() {
1360    if (mAllTracksHavePacketizerIndex) {
1361        return true;
1362    }
1363
1364    for (size_t i = 0; i < mTracks.size(); ++i) {
1365        if (mTracks.valueAt(i)->packetizerTrackIndex() < 0) {
1366            return false;
1367        }
1368    }
1369
1370    mAllTracksHavePacketizerIndex = true;
1371
1372    return true;
1373}
1374
1375status_t WifiDisplaySource::PlaybackSession::packetizeAccessUnit(
1376        size_t trackIndex, const sp<ABuffer> &accessUnit) {
1377    const sp<Track> &track = mTracks.valueFor(trackIndex);
1378
1379    uint32_t flags = 0;
1380
1381    bool isHDCPEncrypted = false;
1382    uint64_t inputCTR;
1383    uint8_t HDCP_private_data[16];
1384    if (mHDCP != NULL && !track->isAudio()) {
1385        isHDCPEncrypted = true;
1386
1387        status_t err = mHDCP->encrypt(
1388                accessUnit->data(), accessUnit->size(),
1389                trackIndex  /* streamCTR */,
1390                &inputCTR,
1391                accessUnit->data());
1392
1393        if (err != OK) {
1394            ALOGE("Failed to HDCP-encrypt media data (err %d)",
1395                  err);
1396
1397            return err;
1398        }
1399
1400        HDCP_private_data[0] = 0x00;
1401
1402        HDCP_private_data[1] =
1403            (((trackIndex >> 30) & 3) << 1) | 1;
1404
1405        HDCP_private_data[2] = (trackIndex >> 22) & 0xff;
1406
1407        HDCP_private_data[3] =
1408            (((trackIndex >> 15) & 0x7f) << 1) | 1;
1409
1410        HDCP_private_data[4] = (trackIndex >> 7) & 0xff;
1411
1412        HDCP_private_data[5] =
1413            ((trackIndex & 0x7f) << 1) | 1;
1414
1415        HDCP_private_data[6] = 0x00;
1416
1417        HDCP_private_data[7] =
1418            (((inputCTR >> 60) & 0x0f) << 1) | 1;
1419
1420        HDCP_private_data[8] = (inputCTR >> 52) & 0xff;
1421
1422        HDCP_private_data[9] =
1423            (((inputCTR >> 45) & 0x7f) << 1) | 1;
1424
1425        HDCP_private_data[10] = (inputCTR >> 37) & 0xff;
1426
1427        HDCP_private_data[11] =
1428            (((inputCTR >> 30) & 0x7f) << 1) | 1;
1429
1430        HDCP_private_data[12] = (inputCTR >> 22) & 0xff;
1431
1432        HDCP_private_data[13] =
1433            (((inputCTR >> 15) & 0x7f) << 1) | 1;
1434
1435        HDCP_private_data[14] = (inputCTR >> 7) & 0xff;
1436
1437        HDCP_private_data[15] =
1438            ((inputCTR & 0x7f) << 1) | 1;
1439
1440#if 0
1441        ALOGI("HDCP_private_data:");
1442        hexdump(HDCP_private_data, sizeof(HDCP_private_data));
1443
1444        ABitReader br(HDCP_private_data, sizeof(HDCP_private_data));
1445        CHECK_EQ(br.getBits(13), 0);
1446        CHECK_EQ(br.getBits(2), (trackIndex >> 30) & 3);
1447        CHECK_EQ(br.getBits(1), 1u);
1448        CHECK_EQ(br.getBits(15), (trackIndex >> 15) & 0x7fff);
1449        CHECK_EQ(br.getBits(1), 1u);
1450        CHECK_EQ(br.getBits(15), trackIndex & 0x7fff);
1451        CHECK_EQ(br.getBits(1), 1u);
1452        CHECK_EQ(br.getBits(11), 0);
1453        CHECK_EQ(br.getBits(4), (inputCTR >> 60) & 0xf);
1454        CHECK_EQ(br.getBits(1), 1u);
1455        CHECK_EQ(br.getBits(15), (inputCTR >> 45) & 0x7fff);
1456        CHECK_EQ(br.getBits(1), 1u);
1457        CHECK_EQ(br.getBits(15), (inputCTR >> 30) & 0x7fff);
1458        CHECK_EQ(br.getBits(1), 1u);
1459        CHECK_EQ(br.getBits(15), (inputCTR >> 15) & 0x7fff);
1460        CHECK_EQ(br.getBits(1), 1u);
1461        CHECK_EQ(br.getBits(15), inputCTR & 0x7fff);
1462        CHECK_EQ(br.getBits(1), 1u);
1463#endif
1464
1465        flags |= TSPacketizer::IS_ENCRYPTED;
1466    }
1467
1468    int64_t timeUs = ALooper::GetNowUs();
1469    if (mPrevTimeUs < 0ll || mPrevTimeUs + 100000ll <= timeUs) {
1470        flags |= TSPacketizer::EMIT_PCR;
1471        flags |= TSPacketizer::EMIT_PAT_AND_PMT;
1472
1473        mPrevTimeUs = timeUs;
1474    }
1475
1476    sp<ABuffer> packets;
1477    mPacketizer->packetize(
1478            track->packetizerTrackIndex(), accessUnit, &packets, flags,
1479            !isHDCPEncrypted ? NULL : HDCP_private_data,
1480            !isHDCPEncrypted ? 0 : sizeof(HDCP_private_data));
1481
1482    for (size_t offset = 0;
1483            offset < packets->size(); offset += 188) {
1484        bool lastTSPacket = (offset + 188 >= packets->size());
1485
1486        // We're only going to flush video, audio packets are
1487        // much more frequent and would waste all that space
1488        // available in a full sized UDP packet.
1489        bool flush =
1490            lastTSPacket
1491                && ((ssize_t)trackIndex == mVideoTrackIndex);
1492
1493        appendTSData(
1494                packets->data() + offset,
1495                188,
1496                true /* timeDiscontinuity */,
1497                flush);
1498    }
1499
1500#if LOG_TRANSPORT_STREAM
1501    if (mLogFile != NULL) {
1502        fwrite(packets->data(), 1, packets->size(), mLogFile);
1503    }
1504#endif
1505
1506    return OK;
1507}
1508
1509status_t WifiDisplaySource::PlaybackSession::packetizeQueuedAccessUnits() {
1510    for (;;) {
1511        bool gotMoreData = false;
1512        for (size_t i = 0; i < mTracks.size(); ++i) {
1513            size_t trackIndex = mTracks.keyAt(i);
1514            const sp<Track> &track = mTracks.valueAt(i);
1515
1516            sp<ABuffer> accessUnit = track->dequeueAccessUnit();
1517            if (accessUnit != NULL) {
1518                status_t err = packetizeAccessUnit(trackIndex, accessUnit);
1519
1520                if (err != OK) {
1521                    return err;
1522                }
1523
1524                gotMoreData = true;
1525            }
1526        }
1527
1528        if (!gotMoreData) {
1529            break;
1530        }
1531    }
1532
1533    return OK;
1534}
1535
1536void WifiDisplaySource::PlaybackSession::notifySessionDead() {
1537    // Inform WifiDisplaySource of our premature death (wish).
1538    sp<AMessage> notify = mNotify->dup();
1539    notify->setInt32("what", kWhatSessionDead);
1540    notify->post();
1541
1542    mWeAreDead = true;
1543}
1544
1545}  // namespace android
1546
1547