PlaybackSession.cpp revision c6920dfdca378a168a2168f4a64d21af4d37d539
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    void queueAccessUnit(const sp<ABuffer> &accessUnit);
79    sp<ABuffer> dequeueAccessUnit();
80
81protected:
82    virtual void onMessageReceived(const sp<AMessage> &msg);
83    virtual ~Track();
84
85private:
86    enum {
87        kWhatMediaPullerStopped,
88    };
89
90    sp<AMessage> mNotify;
91    sp<ALooper> mPullLooper;
92    sp<ALooper> mCodecLooper;
93    sp<MediaPuller> mMediaPuller;
94    sp<Converter> mConverter;
95    bool mStarted;
96    ssize_t mPacketizerTrackIndex;
97    bool mIsAudio;
98    List<sp<ABuffer> > mQueuedAccessUnits;
99
100    static bool IsAudioFormat(const sp<AMessage> &format);
101
102    DISALLOW_EVIL_CONSTRUCTORS(Track);
103};
104
105WifiDisplaySource::PlaybackSession::Track::Track(
106        const sp<AMessage> &notify,
107        const sp<ALooper> &pullLooper,
108        const sp<ALooper> &codecLooper,
109        const sp<MediaPuller> &mediaPuller,
110        const sp<Converter> &converter)
111    : mNotify(notify),
112      mPullLooper(pullLooper),
113      mCodecLooper(codecLooper),
114      mMediaPuller(mediaPuller),
115      mConverter(converter),
116      mStarted(false),
117      mPacketizerTrackIndex(-1),
118      mIsAudio(IsAudioFormat(mConverter->getOutputFormat())) {
119}
120
121WifiDisplaySource::PlaybackSession::Track::~Track() {
122    CHECK(!mStarted);
123}
124
125// static
126bool WifiDisplaySource::PlaybackSession::Track::IsAudioFormat(
127        const sp<AMessage> &format) {
128    AString mime;
129    CHECK(format->findString("mime", &mime));
130
131    return !strncasecmp(mime.c_str(), "audio/", 6);
132}
133
134sp<AMessage> WifiDisplaySource::PlaybackSession::Track::getFormat() {
135    return mConverter->getOutputFormat();
136}
137
138bool WifiDisplaySource::PlaybackSession::Track::isAudio() const {
139    return mIsAudio;
140}
141
142const sp<Converter> &WifiDisplaySource::PlaybackSession::Track::converter() const {
143    return mConverter;
144}
145
146ssize_t WifiDisplaySource::PlaybackSession::Track::packetizerTrackIndex() const {
147    return mPacketizerTrackIndex;
148}
149
150void WifiDisplaySource::PlaybackSession::Track::setPacketizerTrackIndex(size_t index) {
151    CHECK_LT(mPacketizerTrackIndex, 0);
152    mPacketizerTrackIndex = index;
153}
154
155status_t WifiDisplaySource::PlaybackSession::Track::start() {
156    ALOGV("Track::start isAudio=%d", mIsAudio);
157
158    CHECK(!mStarted);
159
160    status_t err = OK;
161
162    if (mMediaPuller != NULL) {
163        err = mMediaPuller->start();
164    }
165
166    if (err == OK) {
167        mStarted = true;
168    }
169
170    return err;
171}
172
173void WifiDisplaySource::PlaybackSession::Track::stopAsync() {
174    ALOGV("Track::stopAsync isAudio=%d", mIsAudio);
175
176    mConverter->shutdownAsync();
177
178    sp<AMessage> msg = new AMessage(kWhatMediaPullerStopped, id());
179
180    if (mStarted && mMediaPuller != NULL) {
181        mMediaPuller->stopAsync(msg);
182    } else {
183        msg->post();
184    }
185}
186
187void WifiDisplaySource::PlaybackSession::Track::onMessageReceived(
188        const sp<AMessage> &msg) {
189    switch (msg->what()) {
190        case kWhatMediaPullerStopped:
191        {
192            mConverter.clear();
193
194            mStarted = false;
195
196            sp<AMessage> notify = mNotify->dup();
197            notify->setInt32("what", kWhatStopped);
198            notify->post();
199
200            ALOGI("kWhatStopped %s posted", mIsAudio ? "audio" : "video");
201            break;
202        }
203
204        default:
205            TRESPASS();
206    }
207}
208
209void WifiDisplaySource::PlaybackSession::Track::queueAccessUnit(
210        const sp<ABuffer> &accessUnit) {
211    mQueuedAccessUnits.push_back(accessUnit);
212}
213
214sp<ABuffer> WifiDisplaySource::PlaybackSession::Track::dequeueAccessUnit() {
215    if (mQueuedAccessUnits.empty()) {
216        return NULL;
217    }
218
219    sp<ABuffer> accessUnit = *mQueuedAccessUnits.begin();
220    CHECK(accessUnit != NULL);
221
222    mQueuedAccessUnits.erase(mQueuedAccessUnits.begin());
223
224    return accessUnit;
225}
226
227////////////////////////////////////////////////////////////////////////////////
228
229WifiDisplaySource::PlaybackSession::PlaybackSession(
230        const sp<ANetworkSession> &netSession,
231        const sp<AMessage> &notify,
232        const in_addr &interfaceAddr,
233        const sp<IHDCP> &hdcp)
234    : mNetSession(netSession),
235      mNotify(notify),
236      mInterfaceAddr(interfaceAddr),
237      mHDCP(hdcp),
238      mWeAreDead(false),
239      mLastLifesignUs(),
240      mVideoTrackIndex(-1),
241      mTSQueue(new ABuffer(12 + kMaxNumTSPacketsPerRTPPacket * 188)),
242      mPrevTimeUs(-1ll),
243      mTransportMode(TRANSPORT_UDP),
244      mAllTracksHavePacketizerIndex(false),
245      mRTPChannel(0),
246      mRTCPChannel(0),
247      mRTPPort(0),
248      mRTPSessionID(0),
249      mRTCPSessionID(0),
250#if ENABLE_RETRANSMISSION
251      mRTPRetransmissionSessionID(0),
252      mRTCPRetransmissionSessionID(0),
253#endif
254      mClientRTPPort(0),
255      mClientRTCPPort(0),
256      mRTPConnected(false),
257      mRTCPConnected(false),
258      mRTPSeqNo(0),
259#if ENABLE_RETRANSMISSION
260      mRTPRetransmissionSeqNo(0),
261#endif
262      mLastNTPTime(0),
263      mLastRTPTime(0),
264      mNumRTPSent(0),
265      mNumRTPOctetsSent(0),
266      mNumSRsSent(0),
267      mSendSRPending(false),
268      mHistoryLength(0)
269#if TRACK_BANDWIDTH
270      ,mFirstPacketTimeUs(-1ll)
271      ,mTotalBytesSent(0ll)
272#endif
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    switch (msg->what()) {
528        case kWhatRTPNotify:
529        case kWhatRTCPNotify:
530#if ENABLE_RETRANSMISSION
531        case kWhatRTPRetransmissionNotify:
532        case kWhatRTCPRetransmissionNotify:
533#endif
534        {
535            int32_t reason;
536            CHECK(msg->findInt32("reason", &reason));
537
538            switch (reason) {
539                case ANetworkSession::kWhatError:
540                {
541                    int32_t sessionID;
542                    CHECK(msg->findInt32("sessionID", &sessionID));
543
544                    int32_t err;
545                    CHECK(msg->findInt32("err", &err));
546
547                    int32_t errorOccuredDuringSend;
548                    CHECK(msg->findInt32("send", &errorOccuredDuringSend));
549
550                    AString detail;
551                    CHECK(msg->findString("detail", &detail));
552
553                    if ((msg->what() == kWhatRTPNotify
554#if ENABLE_RETRANSMISSION
555                            || msg->what() == kWhatRTPRetransmissionNotify
556#endif
557                        ) && !errorOccuredDuringSend) {
558                        // This is ok, we don't expect to receive anything on
559                        // the RTP socket.
560                        break;
561                    }
562
563                    ALOGE("An error occurred during %s in session %d "
564                          "(%d, '%s' (%s)).",
565                          errorOccuredDuringSend ? "send" : "receive",
566                          sessionID,
567                          err,
568                          detail.c_str(),
569                          strerror(-err));
570
571                    mNetSession->destroySession(sessionID);
572
573                    if (sessionID == mRTPSessionID) {
574                        mRTPSessionID = 0;
575                    } else if (sessionID == mRTCPSessionID) {
576                        mRTCPSessionID = 0;
577                    }
578#if ENABLE_RETRANSMISSION
579                    else if (sessionID == mRTPRetransmissionSessionID) {
580                        mRTPRetransmissionSessionID = 0;
581                    } else if (sessionID == mRTCPRetransmissionSessionID) {
582                        mRTCPRetransmissionSessionID = 0;
583                    }
584#endif
585
586                    notifySessionDead();
587                    break;
588                }
589
590                case ANetworkSession::kWhatDatagram:
591                {
592                    int32_t sessionID;
593                    CHECK(msg->findInt32("sessionID", &sessionID));
594
595                    sp<ABuffer> data;
596                    CHECK(msg->findBuffer("data", &data));
597
598                    status_t err;
599                    if (msg->what() == kWhatRTCPNotify
600#if ENABLE_RETRANSMISSION
601                            || msg->what() == kWhatRTCPRetransmissionNotify
602#endif
603                       )
604                    {
605                        err = parseRTCP(data);
606                    }
607                    break;
608                }
609
610                case ANetworkSession::kWhatConnected:
611                {
612                    CHECK_EQ(mTransportMode, TRANSPORT_TCP);
613
614                    int32_t sessionID;
615                    CHECK(msg->findInt32("sessionID", &sessionID));
616
617                    if (sessionID == mRTPSessionID) {
618                        CHECK(!mRTPConnected);
619                        mRTPConnected = true;
620                        ALOGI("RTP Session now connected.");
621                    } else if (sessionID == mRTCPSessionID) {
622                        CHECK(!mRTCPConnected);
623                        mRTCPConnected = true;
624                        ALOGI("RTCP Session now connected.");
625                    } else {
626                        TRESPASS();
627                    }
628
629                    if (mRTPConnected
630                            && (mClientRTCPPort < 0 || mRTCPConnected)) {
631                        onFinishPlay2();
632                    }
633                    break;
634                }
635
636                default:
637                    TRESPASS();
638            }
639            break;
640        }
641
642        case kWhatSendSR:
643        {
644            mSendSRPending = false;
645
646            if (mRTCPSessionID == 0) {
647                break;
648            }
649
650            onSendSR();
651
652            scheduleSendSR();
653            break;
654        }
655
656        case kWhatConverterNotify:
657        {
658            if (mWeAreDead) {
659                ALOGV("dropping msg '%s' because we're dead",
660                      msg->debugString().c_str());
661
662                break;
663            }
664
665            int32_t what;
666            CHECK(msg->findInt32("what", &what));
667
668            size_t trackIndex;
669            CHECK(msg->findSize("trackIndex", &trackIndex));
670
671            if (what == Converter::kWhatAccessUnit) {
672                const sp<Track> &track = mTracks.valueFor(trackIndex);
673
674                ssize_t packetizerTrackIndex = track->packetizerTrackIndex();
675
676                if (packetizerTrackIndex < 0) {
677                    packetizerTrackIndex =
678                        mPacketizer->addTrack(track->getFormat());
679
680                    CHECK_GE(packetizerTrackIndex, 0);
681
682                    track->setPacketizerTrackIndex(packetizerTrackIndex);
683
684                    if (allTracksHavePacketizerIndex()) {
685                        status_t err = packetizeQueuedAccessUnits();
686
687                        if (err != OK) {
688                            notifySessionDead();
689                            break;
690                        }
691                    }
692                }
693
694                sp<ABuffer> accessUnit;
695                CHECK(msg->findBuffer("accessUnit", &accessUnit));
696
697                if (!allTracksHavePacketizerIndex()) {
698                    track->queueAccessUnit(accessUnit);
699                    break;
700                }
701
702                status_t err = packetizeAccessUnit(trackIndex, accessUnit);
703
704                if (err != OK) {
705                    notifySessionDead();
706                }
707                break;
708            } else if (what == Converter::kWhatEOS) {
709                CHECK_EQ(what, Converter::kWhatEOS);
710
711                ALOGI("output EOS on track %d", trackIndex);
712
713                ssize_t index = mTracks.indexOfKey(trackIndex);
714                CHECK_GE(index, 0);
715
716                const sp<Converter> &converter =
717                    mTracks.valueAt(index)->converter();
718                looper()->unregisterHandler(converter->id());
719
720                mTracks.removeItemsAt(index);
721
722                if (mTracks.isEmpty()) {
723                    ALOGI("Reached EOS");
724                }
725            } else {
726                CHECK_EQ(what, Converter::kWhatError);
727
728                status_t err;
729                CHECK(msg->findInt32("err", &err));
730
731                ALOGE("converter signaled error %d", err);
732
733                notifySessionDead();
734            }
735            break;
736        }
737
738        case kWhatFinishPlay:
739        {
740            onFinishPlay();
741            break;
742        }
743
744        case kWhatTrackNotify:
745        {
746            int32_t what;
747            CHECK(msg->findInt32("what", &what));
748
749            size_t trackIndex;
750            CHECK(msg->findSize("trackIndex", &trackIndex));
751
752            if (what == Track::kWhatStopped) {
753                ALOGI("Track %d stopped", trackIndex);
754
755                sp<Track> track = mTracks.valueFor(trackIndex);
756                looper()->unregisterHandler(track->id());
757                mTracks.removeItem(trackIndex);
758                track.clear();
759
760                if (!mTracks.isEmpty()) {
761                    ALOGI("not all tracks are stopped yet");
762                    break;
763                }
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    source->setUseAbsoluteTimestamps();
887
888    size_t numInputBuffers;
889    status_t err = addSource(true /* isVideo */, source, &numInputBuffers);
890
891    if (err != OK) {
892        return err;
893    }
894
895    err = source->setMaxAcquiredBufferCount(numInputBuffers);
896    CHECK_EQ(err, (status_t)OK);
897
898    mBufferQueue = source->getBufferQueue();
899
900    return OK;
901}
902
903status_t WifiDisplaySource::PlaybackSession::addAudioSource() {
904    sp<AudioSource> audioSource = new AudioSource(
905            AUDIO_SOURCE_REMOTE_SUBMIX,
906            48000 /* sampleRate */,
907            2 /* channelCount */);
908
909    if (audioSource->initCheck() == OK) {
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
1075#if TRACK_BANDWIDTH
1076        if (mFirstPacketTimeUs < 0ll) {
1077            mFirstPacketTimeUs = nowUs;
1078        }
1079#endif
1080
1081        // 90kHz time scale
1082        uint32_t rtpTime = (nowUs * 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#if TRACK_BANDWIDTH
1119            mTotalBytesSent += mTSQueue->size();
1120            int64_t delayUs = ALooper::GetNowUs() - mFirstPacketTimeUs;
1121
1122            if (delayUs > 0ll) {
1123                ALOGI("approx. net bandwidth used: %.2f Mbit/sec",
1124                        mTotalBytesSent * 8.0 / delayUs);
1125            }
1126#endif
1127        }
1128
1129        mTSQueue->setInt32Data(mRTPSeqNo - 1);
1130        mHistory.push_back(mTSQueue);
1131        ++mHistoryLength;
1132
1133        if (mHistoryLength > kMaxHistoryLength) {
1134            mTSQueue = *mHistory.begin();
1135            mHistory.erase(mHistory.begin());
1136
1137            --mHistoryLength;
1138        } else {
1139            mTSQueue = new ABuffer(12 + kMaxNumTSPacketsPerRTPPacket * 188);
1140        }
1141
1142        mTSQueue->setRange(0, 12);
1143    }
1144
1145    return size;
1146}
1147
1148status_t WifiDisplaySource::PlaybackSession::parseRTCP(
1149        const sp<ABuffer> &buffer) {
1150    const uint8_t *data = buffer->data();
1151    size_t size = buffer->size();
1152
1153    while (size > 0) {
1154        if (size < 8) {
1155            // Too short to be a valid RTCP header
1156            return ERROR_MALFORMED;
1157        }
1158
1159        if ((data[0] >> 6) != 2) {
1160            // Unsupported version.
1161            return ERROR_UNSUPPORTED;
1162        }
1163
1164        if (data[0] & 0x20) {
1165            // Padding present.
1166
1167            size_t paddingLength = data[size - 1];
1168
1169            if (paddingLength + 12 > size) {
1170                // If we removed this much padding we'd end up with something
1171                // that's too short to be a valid RTP header.
1172                return ERROR_MALFORMED;
1173            }
1174
1175            size -= paddingLength;
1176        }
1177
1178        size_t headerLength = 4 * (data[2] << 8 | data[3]) + 4;
1179
1180        if (size < headerLength) {
1181            // Only received a partial packet?
1182            return ERROR_MALFORMED;
1183        }
1184
1185        switch (data[1]) {
1186            case 200:
1187            case 201:  // RR
1188            case 202:  // SDES
1189            case 203:
1190            case 204:  // APP
1191                break;
1192
1193#if ENABLE_RETRANSMISSION
1194            case 205:  // TSFB (transport layer specific feedback)
1195                parseTSFB(data, headerLength);
1196                break;
1197#endif
1198
1199            case 206:  // PSFB (payload specific feedback)
1200                hexdump(data, headerLength);
1201                break;
1202
1203            default:
1204            {
1205                ALOGW("Unknown RTCP packet type %u of size %d",
1206                     (unsigned)data[1], headerLength);
1207                break;
1208            }
1209        }
1210
1211        data += headerLength;
1212        size -= headerLength;
1213    }
1214
1215    return OK;
1216}
1217
1218#if ENABLE_RETRANSMISSION
1219status_t WifiDisplaySource::PlaybackSession::parseTSFB(
1220        const uint8_t *data, size_t size) {
1221    if ((data[0] & 0x1f) != 1) {
1222        return ERROR_UNSUPPORTED;  // We only support NACK for now.
1223    }
1224
1225    uint32_t srcId = U32_AT(&data[8]);
1226    if (srcId != kSourceID) {
1227        return ERROR_MALFORMED;
1228    }
1229
1230    for (size_t i = 12; i < size; i += 4) {
1231        uint16_t seqNo = U16_AT(&data[i]);
1232        uint16_t blp = U16_AT(&data[i + 2]);
1233
1234        List<sp<ABuffer> >::iterator it = mHistory.begin();
1235        bool foundSeqNo = false;
1236        while (it != mHistory.end()) {
1237            const sp<ABuffer> &buffer = *it;
1238
1239            uint16_t bufferSeqNo = buffer->int32Data() & 0xffff;
1240
1241            bool retransmit = false;
1242            if (bufferSeqNo == seqNo) {
1243                retransmit = true;
1244            } else if (blp != 0) {
1245                for (size_t i = 0; i < 16; ++i) {
1246                    if ((blp & (1 << i))
1247                        && (bufferSeqNo == ((seqNo + i + 1) & 0xffff))) {
1248                        blp &= ~(1 << i);
1249                        retransmit = true;
1250                    }
1251                }
1252            }
1253
1254            if (retransmit) {
1255                ALOGI("retransmitting seqNo %d", bufferSeqNo);
1256
1257                sp<ABuffer> retransRTP = new ABuffer(2 + buffer->size());
1258                uint8_t *rtp = retransRTP->data();
1259                memcpy(rtp, buffer->data(), 12);
1260                rtp[2] = (mRTPRetransmissionSeqNo >> 8) & 0xff;
1261                rtp[3] = mRTPRetransmissionSeqNo & 0xff;
1262                rtp[12] = (bufferSeqNo >> 8) & 0xff;
1263                rtp[13] = bufferSeqNo & 0xff;
1264                memcpy(&rtp[14], buffer->data() + 12, buffer->size() - 12);
1265
1266                ++mRTPRetransmissionSeqNo;
1267
1268                sendPacket(
1269                        mRTPRetransmissionSessionID,
1270                        retransRTP->data(), retransRTP->size());
1271
1272                if (bufferSeqNo == seqNo) {
1273                    foundSeqNo = true;
1274                }
1275
1276                if (foundSeqNo && blp == 0) {
1277                    break;
1278                }
1279            }
1280
1281            ++it;
1282        }
1283
1284        if (!foundSeqNo || blp != 0) {
1285            ALOGI("Some sequence numbers were no longer available for "
1286                  "retransmission");
1287        }
1288    }
1289
1290    return OK;
1291}
1292#endif
1293
1294void WifiDisplaySource::PlaybackSession::requestIDRFrame() {
1295    for (size_t i = 0; i < mTracks.size(); ++i) {
1296        const sp<Track> &track = mTracks.valueAt(i);
1297
1298        track->converter()->requestIDRFrame();
1299    }
1300}
1301
1302status_t WifiDisplaySource::PlaybackSession::sendPacket(
1303        int32_t sessionID, const void *data, size_t size) {
1304    return mNetSession->sendRequest(sessionID, data, size);
1305}
1306
1307bool WifiDisplaySource::PlaybackSession::allTracksHavePacketizerIndex() {
1308    if (mAllTracksHavePacketizerIndex) {
1309        return true;
1310    }
1311
1312    for (size_t i = 0; i < mTracks.size(); ++i) {
1313        if (mTracks.valueAt(i)->packetizerTrackIndex() < 0) {
1314            return false;
1315        }
1316    }
1317
1318    mAllTracksHavePacketizerIndex = true;
1319
1320    return true;
1321}
1322
1323status_t WifiDisplaySource::PlaybackSession::packetizeAccessUnit(
1324        size_t trackIndex, const sp<ABuffer> &accessUnit) {
1325    const sp<Track> &track = mTracks.valueFor(trackIndex);
1326
1327    uint32_t flags = 0;
1328
1329    bool isHDCPEncrypted = false;
1330    uint64_t inputCTR;
1331    uint8_t HDCP_private_data[16];
1332    if (mHDCP != NULL && !track->isAudio()) {
1333        isHDCPEncrypted = true;
1334
1335        status_t err = mHDCP->encrypt(
1336                accessUnit->data(), accessUnit->size(),
1337                trackIndex  /* streamCTR */,
1338                &inputCTR,
1339                accessUnit->data());
1340
1341        if (err != OK) {
1342            ALOGE("Failed to HDCP-encrypt media data (err %d)",
1343                  err);
1344
1345            return err;
1346        }
1347
1348        HDCP_private_data[0] = 0x00;
1349
1350        HDCP_private_data[1] =
1351            (((trackIndex >> 30) & 3) << 1) | 1;
1352
1353        HDCP_private_data[2] = (trackIndex >> 22) & 0xff;
1354
1355        HDCP_private_data[3] =
1356            (((trackIndex >> 15) & 0x7f) << 1) | 1;
1357
1358        HDCP_private_data[4] = (trackIndex >> 7) & 0xff;
1359
1360        HDCP_private_data[5] =
1361            ((trackIndex & 0x7f) << 1) | 1;
1362
1363        HDCP_private_data[6] = 0x00;
1364
1365        HDCP_private_data[7] =
1366            (((inputCTR >> 60) & 0x0f) << 1) | 1;
1367
1368        HDCP_private_data[8] = (inputCTR >> 52) & 0xff;
1369
1370        HDCP_private_data[9] =
1371            (((inputCTR >> 45) & 0x7f) << 1) | 1;
1372
1373        HDCP_private_data[10] = (inputCTR >> 37) & 0xff;
1374
1375        HDCP_private_data[11] =
1376            (((inputCTR >> 30) & 0x7f) << 1) | 1;
1377
1378        HDCP_private_data[12] = (inputCTR >> 22) & 0xff;
1379
1380        HDCP_private_data[13] =
1381            (((inputCTR >> 15) & 0x7f) << 1) | 1;
1382
1383        HDCP_private_data[14] = (inputCTR >> 7) & 0xff;
1384
1385        HDCP_private_data[15] =
1386            ((inputCTR & 0x7f) << 1) | 1;
1387
1388#if 0
1389        ALOGI("HDCP_private_data:");
1390        hexdump(HDCP_private_data, sizeof(HDCP_private_data));
1391
1392        ABitReader br(HDCP_private_data, sizeof(HDCP_private_data));
1393        CHECK_EQ(br.getBits(13), 0);
1394        CHECK_EQ(br.getBits(2), (trackIndex >> 30) & 3);
1395        CHECK_EQ(br.getBits(1), 1u);
1396        CHECK_EQ(br.getBits(15), (trackIndex >> 15) & 0x7fff);
1397        CHECK_EQ(br.getBits(1), 1u);
1398        CHECK_EQ(br.getBits(15), trackIndex & 0x7fff);
1399        CHECK_EQ(br.getBits(1), 1u);
1400        CHECK_EQ(br.getBits(11), 0);
1401        CHECK_EQ(br.getBits(4), (inputCTR >> 60) & 0xf);
1402        CHECK_EQ(br.getBits(1), 1u);
1403        CHECK_EQ(br.getBits(15), (inputCTR >> 45) & 0x7fff);
1404        CHECK_EQ(br.getBits(1), 1u);
1405        CHECK_EQ(br.getBits(15), (inputCTR >> 30) & 0x7fff);
1406        CHECK_EQ(br.getBits(1), 1u);
1407        CHECK_EQ(br.getBits(15), (inputCTR >> 15) & 0x7fff);
1408        CHECK_EQ(br.getBits(1), 1u);
1409        CHECK_EQ(br.getBits(15), inputCTR & 0x7fff);
1410        CHECK_EQ(br.getBits(1), 1u);
1411#endif
1412
1413        flags |= TSPacketizer::IS_ENCRYPTED;
1414    }
1415
1416    int64_t timeUs = ALooper::GetNowUs();
1417    if (mPrevTimeUs < 0ll || mPrevTimeUs + 100000ll <= timeUs) {
1418        flags |= TSPacketizer::EMIT_PCR;
1419        flags |= TSPacketizer::EMIT_PAT_AND_PMT;
1420
1421        mPrevTimeUs = timeUs;
1422    }
1423
1424    sp<ABuffer> packets;
1425    mPacketizer->packetize(
1426            track->packetizerTrackIndex(), accessUnit, &packets, flags,
1427            !isHDCPEncrypted ? NULL : HDCP_private_data,
1428            !isHDCPEncrypted ? 0 : sizeof(HDCP_private_data));
1429
1430    for (size_t offset = 0;
1431            offset < packets->size(); offset += 188) {
1432        bool lastTSPacket = (offset + 188 >= packets->size());
1433
1434        // We're only going to flush video, audio packets are
1435        // much more frequent and would waste all that space
1436        // available in a full sized UDP packet.
1437        bool flush =
1438            lastTSPacket
1439                && ((ssize_t)trackIndex == mVideoTrackIndex);
1440
1441        appendTSData(
1442                packets->data() + offset,
1443                188,
1444                true /* timeDiscontinuity */,
1445                flush);
1446    }
1447
1448#if LOG_TRANSPORT_STREAM
1449    if (mLogFile != NULL) {
1450        fwrite(packets->data(), 1, packets->size(), mLogFile);
1451    }
1452#endif
1453
1454    return OK;
1455}
1456
1457status_t WifiDisplaySource::PlaybackSession::packetizeQueuedAccessUnits() {
1458    for (;;) {
1459        bool gotMoreData = false;
1460        for (size_t i = 0; i < mTracks.size(); ++i) {
1461            size_t trackIndex = mTracks.keyAt(i);
1462            const sp<Track> &track = mTracks.valueAt(i);
1463
1464            sp<ABuffer> accessUnit = track->dequeueAccessUnit();
1465            if (accessUnit != NULL) {
1466                status_t err = packetizeAccessUnit(trackIndex, accessUnit);
1467
1468                if (err != OK) {
1469                    return err;
1470                }
1471
1472                gotMoreData = true;
1473            }
1474        }
1475
1476        if (!gotMoreData) {
1477            break;
1478        }
1479    }
1480
1481    return OK;
1482}
1483
1484void WifiDisplaySource::PlaybackSession::notifySessionDead() {
1485    // Inform WifiDisplaySource of our premature death (wish).
1486    sp<AMessage> notify = mNotify->dup();
1487    notify->setInt32("what", kWhatSessionDead);
1488    notify->post();
1489
1490    mWeAreDead = true;
1491}
1492
1493}  // namespace android
1494
1495