PlaybackSession.cpp revision 3a0ef0dc71f3776d115f30d87f1d8867daefea88
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
850    if (converter->initCheck() != OK) {
851        return converter->initCheck();
852    }
853
854    looper()->registerHandler(converter);
855
856    notify = new AMessage(Converter::kWhatMediaPullerNotify, converter->id());
857    notify->setSize("trackIndex", trackIndex);
858
859    sp<MediaPuller> puller = new MediaPuller(source, notify);
860    pullLooper->registerHandler(puller);
861
862    if (numInputBuffers != NULL) {
863        *numInputBuffers = converter->getInputBufferCount();
864    }
865
866    notify = new AMessage(kWhatTrackNotify, id());
867    notify->setSize("trackIndex", trackIndex);
868
869    sp<Track> track = new Track(
870            notify, pullLooper, codecLooper, puller, converter);
871
872    looper()->registerHandler(track);
873
874    mTracks.add(trackIndex, track);
875
876    if (isVideo) {
877        mVideoTrackIndex = trackIndex;
878    }
879
880    return OK;
881}
882
883status_t WifiDisplaySource::PlaybackSession::addVideoSource() {
884    sp<SurfaceMediaSource> source = new SurfaceMediaSource(width(), height());
885
886    sp<MediaSource> videoSource =
887            new RepeaterSource(source, 24.0 /* rateHz */);
888
889    size_t numInputBuffers;
890    status_t err = addSource(true /* isVideo */, videoSource, &numInputBuffers);
891
892    if (err != OK) {
893        return err;
894    }
895
896    err = source->setMaxAcquiredBufferCount(numInputBuffers);
897    CHECK_EQ(err, (status_t)OK);
898
899    mBufferQueue = source->getBufferQueue();
900
901    return OK;
902}
903
904status_t WifiDisplaySource::PlaybackSession::addAudioSource() {
905    sp<AudioSource> audioSource = new AudioSource(
906            AUDIO_SOURCE_REMOTE_SUBMIX,
907            48000 /* sampleRate */,
908            2 /* channelCount */);
909
910    if (audioSource->initCheck() == OK) {
911        audioSource->setUseLooperTime(true);
912
913        return addSource(
914                false /* isVideo */, audioSource, NULL /* numInputBuffers */);
915    }
916
917    ALOGW("Unable to instantiate audio source");
918
919    return OK;
920}
921
922sp<ISurfaceTexture> WifiDisplaySource::PlaybackSession::getSurfaceTexture() {
923    return mBufferQueue;
924}
925
926int32_t WifiDisplaySource::PlaybackSession::width() const {
927    return 1280;
928}
929
930int32_t WifiDisplaySource::PlaybackSession::height() const {
931    return 720;
932}
933
934void WifiDisplaySource::PlaybackSession::scheduleSendSR() {
935    if (mSendSRPending) {
936        return;
937    }
938
939    mSendSRPending = true;
940    (new AMessage(kWhatSendSR, id()))->post(kSendSRIntervalUs);
941}
942
943void WifiDisplaySource::PlaybackSession::addSR(const sp<ABuffer> &buffer) {
944    uint8_t *data = buffer->data() + buffer->size();
945
946    // TODO: Use macros/utility functions to clean up all the bitshifts below.
947
948    data[0] = 0x80 | 0;
949    data[1] = 200;  // SR
950    data[2] = 0;
951    data[3] = 6;
952    data[4] = kSourceID >> 24;
953    data[5] = (kSourceID >> 16) & 0xff;
954    data[6] = (kSourceID >> 8) & 0xff;
955    data[7] = kSourceID & 0xff;
956
957    data[8] = mLastNTPTime >> (64 - 8);
958    data[9] = (mLastNTPTime >> (64 - 16)) & 0xff;
959    data[10] = (mLastNTPTime >> (64 - 24)) & 0xff;
960    data[11] = (mLastNTPTime >> 32) & 0xff;
961    data[12] = (mLastNTPTime >> 24) & 0xff;
962    data[13] = (mLastNTPTime >> 16) & 0xff;
963    data[14] = (mLastNTPTime >> 8) & 0xff;
964    data[15] = mLastNTPTime & 0xff;
965
966    data[16] = (mLastRTPTime >> 24) & 0xff;
967    data[17] = (mLastRTPTime >> 16) & 0xff;
968    data[18] = (mLastRTPTime >> 8) & 0xff;
969    data[19] = mLastRTPTime & 0xff;
970
971    data[20] = mNumRTPSent >> 24;
972    data[21] = (mNumRTPSent >> 16) & 0xff;
973    data[22] = (mNumRTPSent >> 8) & 0xff;
974    data[23] = mNumRTPSent & 0xff;
975
976    data[24] = mNumRTPOctetsSent >> 24;
977    data[25] = (mNumRTPOctetsSent >> 16) & 0xff;
978    data[26] = (mNumRTPOctetsSent >> 8) & 0xff;
979    data[27] = mNumRTPOctetsSent & 0xff;
980
981    buffer->setRange(buffer->offset(), buffer->size() + 28);
982}
983
984void WifiDisplaySource::PlaybackSession::addSDES(const sp<ABuffer> &buffer) {
985    uint8_t *data = buffer->data() + buffer->size();
986    data[0] = 0x80 | 1;
987    data[1] = 202;  // SDES
988    data[4] = kSourceID >> 24;
989    data[5] = (kSourceID >> 16) & 0xff;
990    data[6] = (kSourceID >> 8) & 0xff;
991    data[7] = kSourceID & 0xff;
992
993    size_t offset = 8;
994
995    data[offset++] = 1;  // CNAME
996
997    static const char *kCNAME = "someone@somewhere";
998    data[offset++] = strlen(kCNAME);
999
1000    memcpy(&data[offset], kCNAME, strlen(kCNAME));
1001    offset += strlen(kCNAME);
1002
1003    data[offset++] = 7;  // NOTE
1004
1005    static const char *kNOTE = "Hell's frozen over.";
1006    data[offset++] = strlen(kNOTE);
1007
1008    memcpy(&data[offset], kNOTE, strlen(kNOTE));
1009    offset += strlen(kNOTE);
1010
1011    data[offset++] = 0;
1012
1013    if ((offset % 4) > 0) {
1014        size_t count = 4 - (offset % 4);
1015        switch (count) {
1016            case 3:
1017                data[offset++] = 0;
1018            case 2:
1019                data[offset++] = 0;
1020            case 1:
1021                data[offset++] = 0;
1022        }
1023    }
1024
1025    size_t numWords = (offset / 4) - 1;
1026    data[2] = numWords >> 8;
1027    data[3] = numWords & 0xff;
1028
1029    buffer->setRange(buffer->offset(), buffer->size() + offset);
1030}
1031
1032// static
1033uint64_t WifiDisplaySource::PlaybackSession::GetNowNTP() {
1034    uint64_t nowUs = ALooper::GetNowUs();
1035
1036    nowUs += ((70ll * 365 + 17) * 24) * 60 * 60 * 1000000ll;
1037
1038    uint64_t hi = nowUs / 1000000ll;
1039    uint64_t lo = ((1ll << 32) * (nowUs % 1000000ll)) / 1000000ll;
1040
1041    return (hi << 32) | lo;
1042}
1043
1044void WifiDisplaySource::PlaybackSession::onSendSR() {
1045    sp<ABuffer> buffer = new ABuffer(1500);
1046    buffer->setRange(0, 0);
1047
1048    addSR(buffer);
1049    addSDES(buffer);
1050
1051    if (mTransportMode == TRANSPORT_TCP_INTERLEAVED) {
1052        sp<AMessage> notify = mNotify->dup();
1053        notify->setInt32("what", kWhatBinaryData);
1054        notify->setInt32("channel", mRTCPChannel);
1055        notify->setBuffer("data", buffer);
1056        notify->post();
1057    } else {
1058        sendPacket(mRTCPSessionID, buffer->data(), buffer->size());
1059    }
1060
1061    ++mNumSRsSent;
1062}
1063
1064ssize_t WifiDisplaySource::PlaybackSession::appendTSData(
1065        const void *data, size_t size, bool timeDiscontinuity, bool flush) {
1066    CHECK_EQ(size, 188);
1067
1068    CHECK_LE(mTSQueue->size() + size, mTSQueue->capacity());
1069
1070    memcpy(mTSQueue->data() + mTSQueue->size(), data, size);
1071    mTSQueue->setRange(0, mTSQueue->size() + size);
1072
1073    if (flush || mTSQueue->size() == mTSQueue->capacity()) {
1074        // flush
1075
1076        int64_t nowUs = ALooper::GetNowUs();
1077        if (mFirstPacketTimeUs < 0ll) {
1078            mFirstPacketTimeUs = nowUs;
1079        }
1080
1081        // 90kHz time scale
1082        uint32_t rtpTime = ((nowUs - mFirstPacketTimeUs) * 9ll) / 100ll;
1083
1084        uint8_t *rtp = mTSQueue->data();
1085        rtp[0] = 0x80;
1086        rtp[1] = 33 | (timeDiscontinuity ? (1 << 7) : 0);  // M-bit
1087        rtp[2] = (mRTPSeqNo >> 8) & 0xff;
1088        rtp[3] = mRTPSeqNo & 0xff;
1089        rtp[4] = rtpTime >> 24;
1090        rtp[5] = (rtpTime >> 16) & 0xff;
1091        rtp[6] = (rtpTime >> 8) & 0xff;
1092        rtp[7] = rtpTime & 0xff;
1093        rtp[8] = kSourceID >> 24;
1094        rtp[9] = (kSourceID >> 16) & 0xff;
1095        rtp[10] = (kSourceID >> 8) & 0xff;
1096        rtp[11] = kSourceID & 0xff;
1097
1098        ++mRTPSeqNo;
1099        ++mNumRTPSent;
1100        mNumRTPOctetsSent += mTSQueue->size() - 12;
1101
1102        mLastRTPTime = rtpTime;
1103        mLastNTPTime = GetNowNTP();
1104
1105        if (mTransportMode == TRANSPORT_TCP_INTERLEAVED) {
1106            sp<AMessage> notify = mNotify->dup();
1107            notify->setInt32("what", kWhatBinaryData);
1108
1109            sp<ABuffer> data = new ABuffer(mTSQueue->size());
1110            memcpy(data->data(), rtp, mTSQueue->size());
1111
1112            notify->setInt32("channel", mRTPChannel);
1113            notify->setBuffer("data", data);
1114            notify->post();
1115        } else {
1116            sendPacket(mRTPSessionID, rtp, mTSQueue->size());
1117
1118            mTotalBytesSent += mTSQueue->size();
1119            int64_t delayUs = ALooper::GetNowUs() - mFirstPacketTimeUs;
1120
1121            if (delayUs > 0ll) {
1122                ALOGV("approx. net bandwidth used: %.2f Mbit/sec",
1123                        mTotalBytesSent * 8.0 / delayUs);
1124            }
1125        }
1126
1127        mTSQueue->setInt32Data(mRTPSeqNo - 1);
1128        mHistory.push_back(mTSQueue);
1129        ++mHistoryLength;
1130
1131        if (mHistoryLength > kMaxHistoryLength) {
1132            mTSQueue = *mHistory.begin();
1133            mHistory.erase(mHistory.begin());
1134
1135            --mHistoryLength;
1136        } else {
1137            mTSQueue = new ABuffer(12 + kMaxNumTSPacketsPerRTPPacket * 188);
1138        }
1139
1140        mTSQueue->setRange(0, 12);
1141    }
1142
1143    return size;
1144}
1145
1146status_t WifiDisplaySource::PlaybackSession::parseRTCP(
1147        const sp<ABuffer> &buffer) {
1148    const uint8_t *data = buffer->data();
1149    size_t size = buffer->size();
1150
1151    while (size > 0) {
1152        if (size < 8) {
1153            // Too short to be a valid RTCP header
1154            return ERROR_MALFORMED;
1155        }
1156
1157        if ((data[0] >> 6) != 2) {
1158            // Unsupported version.
1159            return ERROR_UNSUPPORTED;
1160        }
1161
1162        if (data[0] & 0x20) {
1163            // Padding present.
1164
1165            size_t paddingLength = data[size - 1];
1166
1167            if (paddingLength + 12 > size) {
1168                // If we removed this much padding we'd end up with something
1169                // that's too short to be a valid RTP header.
1170                return ERROR_MALFORMED;
1171            }
1172
1173            size -= paddingLength;
1174        }
1175
1176        size_t headerLength = 4 * (data[2] << 8 | data[3]) + 4;
1177
1178        if (size < headerLength) {
1179            // Only received a partial packet?
1180            return ERROR_MALFORMED;
1181        }
1182
1183        switch (data[1]) {
1184            case 200:
1185            case 201:  // RR
1186            case 202:  // SDES
1187            case 203:
1188            case 204:  // APP
1189                break;
1190
1191#if ENABLE_RETRANSMISSION
1192            case 205:  // TSFB (transport layer specific feedback)
1193                parseTSFB(data, headerLength);
1194                break;
1195#endif
1196
1197            case 206:  // PSFB (payload specific feedback)
1198                hexdump(data, headerLength);
1199                break;
1200
1201            default:
1202            {
1203                ALOGW("Unknown RTCP packet type %u of size %d",
1204                     (unsigned)data[1], headerLength);
1205                break;
1206            }
1207        }
1208
1209        data += headerLength;
1210        size -= headerLength;
1211    }
1212
1213    return OK;
1214}
1215
1216#if ENABLE_RETRANSMISSION
1217status_t WifiDisplaySource::PlaybackSession::parseTSFB(
1218        const uint8_t *data, size_t size) {
1219    if ((data[0] & 0x1f) != 1) {
1220        return ERROR_UNSUPPORTED;  // We only support NACK for now.
1221    }
1222
1223    uint32_t srcId = U32_AT(&data[8]);
1224    if (srcId != kSourceID) {
1225        return ERROR_MALFORMED;
1226    }
1227
1228    for (size_t i = 12; i < size; i += 4) {
1229        uint16_t seqNo = U16_AT(&data[i]);
1230        uint16_t blp = U16_AT(&data[i + 2]);
1231
1232        List<sp<ABuffer> >::iterator it = mHistory.begin();
1233        bool foundSeqNo = false;
1234        while (it != mHistory.end()) {
1235            const sp<ABuffer> &buffer = *it;
1236
1237            uint16_t bufferSeqNo = buffer->int32Data() & 0xffff;
1238
1239            bool retransmit = false;
1240            if (bufferSeqNo == seqNo) {
1241                retransmit = true;
1242            } else if (blp != 0) {
1243                for (size_t i = 0; i < 16; ++i) {
1244                    if ((blp & (1 << i))
1245                        && (bufferSeqNo == ((seqNo + i + 1) & 0xffff))) {
1246                        blp &= ~(1 << i);
1247                        retransmit = true;
1248                    }
1249                }
1250            }
1251
1252            if (retransmit) {
1253                ALOGI("retransmitting seqNo %d", bufferSeqNo);
1254
1255                sp<ABuffer> retransRTP = new ABuffer(2 + buffer->size());
1256                uint8_t *rtp = retransRTP->data();
1257                memcpy(rtp, buffer->data(), 12);
1258                rtp[2] = (mRTPRetransmissionSeqNo >> 8) & 0xff;
1259                rtp[3] = mRTPRetransmissionSeqNo & 0xff;
1260                rtp[12] = (bufferSeqNo >> 8) & 0xff;
1261                rtp[13] = bufferSeqNo & 0xff;
1262                memcpy(&rtp[14], buffer->data() + 12, buffer->size() - 12);
1263
1264                ++mRTPRetransmissionSeqNo;
1265
1266                sendPacket(
1267                        mRTPRetransmissionSessionID,
1268                        retransRTP->data(), retransRTP->size());
1269
1270                if (bufferSeqNo == seqNo) {
1271                    foundSeqNo = true;
1272                }
1273
1274                if (foundSeqNo && blp == 0) {
1275                    break;
1276                }
1277            }
1278
1279            ++it;
1280        }
1281
1282        if (!foundSeqNo || blp != 0) {
1283            ALOGI("Some sequence numbers were no longer available for "
1284                  "retransmission");
1285        }
1286    }
1287
1288    return OK;
1289}
1290#endif
1291
1292void WifiDisplaySource::PlaybackSession::requestIDRFrame() {
1293    for (size_t i = 0; i < mTracks.size(); ++i) {
1294        const sp<Track> &track = mTracks.valueAt(i);
1295
1296        track->converter()->requestIDRFrame();
1297    }
1298}
1299
1300status_t WifiDisplaySource::PlaybackSession::sendPacket(
1301        int32_t sessionID, const void *data, size_t size) {
1302    return mNetSession->sendRequest(sessionID, data, size);
1303}
1304
1305bool WifiDisplaySource::PlaybackSession::allTracksHavePacketizerIndex() {
1306    if (mAllTracksHavePacketizerIndex) {
1307        return true;
1308    }
1309
1310    for (size_t i = 0; i < mTracks.size(); ++i) {
1311        if (mTracks.valueAt(i)->packetizerTrackIndex() < 0) {
1312            return false;
1313        }
1314    }
1315
1316    mAllTracksHavePacketizerIndex = true;
1317
1318    return true;
1319}
1320
1321static inline size_t MIN(size_t a, size_t b) {
1322    return (a < b) ? a : b;
1323}
1324
1325status_t WifiDisplaySource::PlaybackSession::packetizeAccessUnit(
1326        size_t trackIndex, sp<ABuffer> accessUnit) {
1327    const sp<Track> &track = mTracks.valueFor(trackIndex);
1328
1329    uint32_t flags = 0;
1330
1331    bool isHDCPEncrypted = false;
1332    uint64_t inputCTR;
1333    uint8_t HDCP_private_data[16];
1334    if (mHDCP != NULL && !track->isAudio()) {
1335        isHDCPEncrypted = true;
1336
1337#if 0
1338        ALOGI("in:");
1339        hexdump(accessUnit->data(), MIN(64, accessUnit->size()));
1340#endif
1341
1342        if (IsIDR(accessUnit)) {
1343            // XXX remove this once the encoder takes care of this.
1344            accessUnit = mPacketizer->prependCSD(
1345                    track->packetizerTrackIndex(), accessUnit);
1346        }
1347
1348        status_t err = mHDCP->encrypt(
1349                accessUnit->data(), accessUnit->size(),
1350                trackIndex  /* streamCTR */,
1351                &inputCTR,
1352                accessUnit->data());
1353
1354        if (err != OK) {
1355            ALOGE("Failed to HDCP-encrypt media data (err %d)",
1356                  err);
1357
1358            return err;
1359        } else {
1360#if 0
1361            ALOGI("out:");
1362            hexdump(accessUnit->data(), MIN(64, accessUnit->size()));
1363            ALOGI("inputCTR: 0x%016llx", inputCTR);
1364            ALOGI("streamCTR: 0x%08x", trackIndex);
1365#endif
1366        }
1367
1368        HDCP_private_data[0] = 0x00;
1369
1370        HDCP_private_data[1] =
1371            (((trackIndex >> 30) & 3) << 1) | 1;
1372
1373        HDCP_private_data[2] = (trackIndex >> 22) & 0xff;
1374
1375        HDCP_private_data[3] =
1376            (((trackIndex >> 15) & 0x7f) << 1) | 1;
1377
1378        HDCP_private_data[4] = (trackIndex >> 7) & 0xff;
1379
1380        HDCP_private_data[5] =
1381            ((trackIndex & 0x7f) << 1) | 1;
1382
1383        HDCP_private_data[6] = 0x00;
1384
1385        HDCP_private_data[7] =
1386            (((inputCTR >> 60) & 0x0f) << 1) | 1;
1387
1388        HDCP_private_data[8] = (inputCTR >> 52) & 0xff;
1389
1390        HDCP_private_data[9] =
1391            (((inputCTR >> 45) & 0x7f) << 1) | 1;
1392
1393        HDCP_private_data[10] = (inputCTR >> 37) & 0xff;
1394
1395        HDCP_private_data[11] =
1396            (((inputCTR >> 30) & 0x7f) << 1) | 1;
1397
1398        HDCP_private_data[12] = (inputCTR >> 22) & 0xff;
1399
1400        HDCP_private_data[13] =
1401            (((inputCTR >> 15) & 0x7f) << 1) | 1;
1402
1403        HDCP_private_data[14] = (inputCTR >> 7) & 0xff;
1404
1405        HDCP_private_data[15] =
1406            ((inputCTR & 0x7f) << 1) | 1;
1407
1408#if 0
1409        ALOGI("HDCP_private_data:");
1410        hexdump(HDCP_private_data, sizeof(HDCP_private_data));
1411
1412        ABitReader br(HDCP_private_data, sizeof(HDCP_private_data));
1413        CHECK_EQ(br.getBits(13), 0);
1414        CHECK_EQ(br.getBits(2), (trackIndex >> 30) & 3);
1415        CHECK_EQ(br.getBits(1), 1u);
1416        CHECK_EQ(br.getBits(15), (trackIndex >> 15) & 0x7fff);
1417        CHECK_EQ(br.getBits(1), 1u);
1418        CHECK_EQ(br.getBits(15), trackIndex & 0x7fff);
1419        CHECK_EQ(br.getBits(1), 1u);
1420        CHECK_EQ(br.getBits(11), 0);
1421        CHECK_EQ(br.getBits(4), (inputCTR >> 60) & 0xf);
1422        CHECK_EQ(br.getBits(1), 1u);
1423        CHECK_EQ(br.getBits(15), (inputCTR >> 45) & 0x7fff);
1424        CHECK_EQ(br.getBits(1), 1u);
1425        CHECK_EQ(br.getBits(15), (inputCTR >> 30) & 0x7fff);
1426        CHECK_EQ(br.getBits(1), 1u);
1427        CHECK_EQ(br.getBits(15), (inputCTR >> 15) & 0x7fff);
1428        CHECK_EQ(br.getBits(1), 1u);
1429        CHECK_EQ(br.getBits(15), inputCTR & 0x7fff);
1430        CHECK_EQ(br.getBits(1), 1u);
1431#endif
1432
1433        flags |= TSPacketizer::IS_ENCRYPTED;
1434    }
1435
1436    int64_t timeUs = ALooper::GetNowUs();
1437    if (mPrevTimeUs < 0ll || mPrevTimeUs + 100000ll <= timeUs) {
1438        flags |= TSPacketizer::EMIT_PCR;
1439        flags |= TSPacketizer::EMIT_PAT_AND_PMT;
1440
1441        mPrevTimeUs = timeUs;
1442    }
1443
1444    sp<ABuffer> packets;
1445    mPacketizer->packetize(
1446            track->packetizerTrackIndex(), accessUnit, &packets, flags,
1447            !isHDCPEncrypted ? NULL : HDCP_private_data,
1448            !isHDCPEncrypted ? 0 : sizeof(HDCP_private_data));
1449
1450    for (size_t offset = 0;
1451            offset < packets->size(); offset += 188) {
1452        bool lastTSPacket = (offset + 188 >= packets->size());
1453
1454        // We're only going to flush video, audio packets are
1455        // much more frequent and would waste all that space
1456        // available in a full sized UDP packet.
1457        bool flush =
1458            lastTSPacket
1459                && ((ssize_t)trackIndex == mVideoTrackIndex);
1460
1461        appendTSData(
1462                packets->data() + offset,
1463                188,
1464                true /* timeDiscontinuity */,
1465                flush);
1466    }
1467
1468#if LOG_TRANSPORT_STREAM
1469    if (mLogFile != NULL) {
1470        fwrite(packets->data(), 1, packets->size(), mLogFile);
1471    }
1472#endif
1473
1474    return OK;
1475}
1476
1477status_t WifiDisplaySource::PlaybackSession::packetizeQueuedAccessUnits() {
1478    for (;;) {
1479        bool gotMoreData = false;
1480        for (size_t i = 0; i < mTracks.size(); ++i) {
1481            size_t trackIndex = mTracks.keyAt(i);
1482            const sp<Track> &track = mTracks.valueAt(i);
1483
1484            sp<ABuffer> accessUnit = track->dequeueAccessUnit();
1485            if (accessUnit != NULL) {
1486                status_t err = packetizeAccessUnit(trackIndex, accessUnit);
1487
1488                if (err != OK) {
1489                    return err;
1490                }
1491
1492                gotMoreData = true;
1493            }
1494        }
1495
1496        if (!gotMoreData) {
1497            break;
1498        }
1499    }
1500
1501    return OK;
1502}
1503
1504void WifiDisplaySource::PlaybackSession::notifySessionDead() {
1505    // Inform WifiDisplaySource of our premature death (wish).
1506    sp<AMessage> notify = mNotify->dup();
1507    notify->setInt32("what", kWhatSessionDead);
1508    notify->post();
1509
1510    mWeAreDead = true;
1511}
1512
1513}  // namespace android
1514
1515