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