PlaybackSession.cpp revision 596b4cde38b9fe18d21b4ed20dbdba909514a457
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 "Serializer.h"
27#include "TSPacketizer.h"
28
29#include <binder/IServiceManager.h>
30#include <gui/ISurfaceComposer.h>
31#include <gui/SurfaceComposerClient.h>
32#include <media/stagefright/foundation/ABuffer.h>
33#include <media/stagefright/foundation/ADebug.h>
34#include <media/stagefright/foundation/AMessage.h>
35#include <media/stagefright/foundation/hexdump.h>
36#include <media/stagefright/AudioSource.h>
37#include <media/stagefright/DataSource.h>
38#include <media/stagefright/MediaDefs.h>
39#include <media/stagefright/MediaErrors.h>
40#include <media/stagefright/MediaExtractor.h>
41#include <media/stagefright/MediaSource.h>
42#include <media/stagefright/MetaData.h>
43#include <media/stagefright/MPEG2TSWriter.h>
44#include <media/stagefright/SurfaceMediaSource.h>
45#include <media/stagefright/Utils.h>
46
47#include <OMX_IVCommon.h>
48
49//#define FAKE_VIDEO      1
50#define USE_SERIALIZER  0
51
52namespace android {
53
54static size_t kMaxRTPPacketSize = 1500;
55static size_t kMaxNumTSPacketsPerRTPPacket = (kMaxRTPPacketSize - 12) / 188;
56
57struct WifiDisplaySource::PlaybackSession::Track : public RefBase {
58    Track(const sp<ALooper> &pullLooper,
59          const sp<ALooper> &codecLooper,
60          const sp<MediaPuller> &mediaPuller,
61          const sp<Converter> &converter);
62
63    Track(const sp<AMessage> &format);
64
65    sp<AMessage> getFormat();
66
67    const sp<Converter> &converter() const;
68    ssize_t packetizerTrackIndex() const;
69
70    void setPacketizerTrackIndex(size_t index);
71
72    status_t start();
73    status_t stop();
74
75protected:
76    virtual ~Track();
77
78private:
79    sp<ALooper> mPullLooper;
80    sp<ALooper> mCodecLooper;
81    sp<MediaPuller> mMediaPuller;
82    sp<Converter> mConverter;
83    sp<AMessage> mFormat;
84    bool mStarted;
85    ssize_t mPacketizerTrackIndex;
86
87    DISALLOW_EVIL_CONSTRUCTORS(Track);
88};
89
90WifiDisplaySource::PlaybackSession::Track::Track(
91        const sp<ALooper> &pullLooper,
92        const sp<ALooper> &codecLooper,
93        const sp<MediaPuller> &mediaPuller,
94        const sp<Converter> &converter)
95    : mPullLooper(pullLooper),
96      mCodecLooper(codecLooper),
97      mMediaPuller(mediaPuller),
98      mConverter(converter),
99      mStarted(false),
100      mPacketizerTrackIndex(-1) {
101}
102
103WifiDisplaySource::PlaybackSession::Track::Track(const sp<AMessage> &format)
104    : mFormat(format),
105      mPacketizerTrackIndex(-1) {
106}
107
108WifiDisplaySource::PlaybackSession::Track::~Track() {
109    stop();
110}
111
112sp<AMessage> WifiDisplaySource::PlaybackSession::Track::getFormat() {
113    if (mFormat != NULL) {
114        return mFormat;
115    }
116
117    return mConverter->getOutputFormat();
118}
119
120const sp<Converter> &WifiDisplaySource::PlaybackSession::Track::converter() const {
121    return mConverter;
122}
123
124ssize_t WifiDisplaySource::PlaybackSession::Track::packetizerTrackIndex() const {
125    return mPacketizerTrackIndex;
126}
127
128void WifiDisplaySource::PlaybackSession::Track::setPacketizerTrackIndex(size_t index) {
129    CHECK_LT(mPacketizerTrackIndex, 0);
130    mPacketizerTrackIndex = index;
131}
132
133status_t WifiDisplaySource::PlaybackSession::Track::start() {
134    if (mStarted) {
135        return INVALID_OPERATION;
136    }
137
138    status_t err = OK;
139
140    if (mMediaPuller != NULL) {
141        err = mMediaPuller->start();
142    }
143
144    if (err == OK) {
145        mStarted = true;
146    }
147
148    return err;
149}
150
151status_t WifiDisplaySource::PlaybackSession::Track::stop() {
152    if (!mStarted) {
153        return INVALID_OPERATION;
154    }
155
156    status_t err = OK;
157
158    if (mMediaPuller != NULL) {
159        err = mMediaPuller->stop();
160    }
161
162    mConverter.clear();
163
164    mStarted = false;
165
166    return err;
167}
168
169////////////////////////////////////////////////////////////////////////////////
170
171WifiDisplaySource::PlaybackSession::PlaybackSession(
172        const sp<ANetworkSession> &netSession,
173        const sp<AMessage> &notify,
174        bool legacyMode)
175    : mNetSession(netSession),
176      mNotify(notify),
177      mLegacyMode(legacyMode),
178      mLastLifesignUs(),
179      mVideoTrackIndex(-1),
180      mTSQueue(new ABuffer(12 + kMaxNumTSPacketsPerRTPPacket * 188)),
181      mPrevTimeUs(-1ll),
182      mUseInterleavedTCP(false),
183      mRTPChannel(0),
184      mRTCPChannel(0),
185      mRTPPort(0),
186      mRTPSessionID(0),
187      mRTCPSessionID(0),
188      mRTPSeqNo(0),
189      mLastNTPTime(0),
190      mLastRTPTime(0),
191      mNumRTPSent(0),
192      mNumRTPOctetsSent(0),
193      mNumSRsSent(0),
194      mSendSRPending(false),
195      mFirstPacketTimeUs(-1ll),
196      mHistoryLength(0)
197#if LOG_TRANSPORT_STREAM
198      ,mLogFile(NULL)
199#endif
200{
201    mTSQueue->setRange(0, 12);
202
203#if LOG_TRANSPORT_STREAM
204    mLogFile = fopen("/system/etc/log.ts", "wb");
205#endif
206}
207
208status_t WifiDisplaySource::PlaybackSession::init(
209        const char *clientIP, int32_t clientRtp, int32_t clientRtcp,
210        bool useInterleavedTCP) {
211    status_t err = setupPacketizer();
212
213    if (err != OK) {
214        return err;
215    }
216
217    if (useInterleavedTCP) {
218        mUseInterleavedTCP = true;
219        mRTPChannel = clientRtp;
220        mRTCPChannel = clientRtcp;
221        mRTPPort = 0;
222        mRTPSessionID = 0;
223        mRTCPSessionID = 0;
224
225        updateLiveness();
226        return OK;
227    }
228
229    mUseInterleavedTCP = false;
230    mRTPChannel = 0;
231    mRTCPChannel = 0;
232
233    int serverRtp;
234
235    sp<AMessage> rtpNotify = new AMessage(kWhatRTPNotify, id());
236    sp<AMessage> rtcpNotify = new AMessage(kWhatRTCPNotify, id());
237    for (serverRtp = 15550;; serverRtp += 2) {
238        int32_t rtpSession;
239        err = mNetSession->createUDPSession(
240                    serverRtp, clientIP, clientRtp,
241                    rtpNotify, &rtpSession);
242
243        if (err != OK) {
244            ALOGI("failed to create RTP socket on port %d", serverRtp);
245            continue;
246        }
247
248        if (clientRtcp < 0) {
249            // No RTCP.
250
251            mRTPPort = serverRtp;
252            mRTPSessionID = rtpSession;
253            mRTCPSessionID = 0;
254
255            ALOGI("rtpSessionId = %d", rtpSession);
256            break;
257        }
258
259        int32_t rtcpSession;
260        err = mNetSession->createUDPSession(
261                serverRtp + 1, clientIP, clientRtcp,
262                rtcpNotify, &rtcpSession);
263
264        if (err == OK) {
265            mRTPPort = serverRtp;
266            mRTPSessionID = rtpSession;
267            mRTCPSessionID = rtcpSession;
268
269            ALOGI("rtpSessionID = %d, rtcpSessionID = %d", rtpSession, rtcpSession);
270            break;
271        }
272
273        ALOGI("failed to create RTCP socket on port %d", serverRtp + 1);
274        mNetSession->destroySession(rtpSession);
275    }
276
277    if (mRTPPort == 0) {
278        return UNKNOWN_ERROR;
279    }
280
281    updateLiveness();
282
283    return OK;
284}
285
286WifiDisplaySource::PlaybackSession::~PlaybackSession() {
287#if LOG_TRANSPORT_STREAM
288    if (mLogFile != NULL) {
289        fclose(mLogFile);
290        mLogFile = NULL;
291    }
292#endif
293}
294
295int32_t WifiDisplaySource::PlaybackSession::getRTPPort() const {
296    return mRTPPort;
297}
298
299int64_t WifiDisplaySource::PlaybackSession::getLastLifesignUs() const {
300    return mLastLifesignUs;
301}
302
303void WifiDisplaySource::PlaybackSession::updateLiveness() {
304    mLastLifesignUs = ALooper::GetNowUs();
305}
306
307status_t WifiDisplaySource::PlaybackSession::play() {
308    updateLiveness();
309
310    if (mRTCPSessionID != 0) {
311        scheduleSendSR();
312    }
313
314    if (mSerializer != NULL) {
315        return mSerializer->start();
316    }
317
318    for (size_t i = 0; i < mTracks.size(); ++i) {
319        status_t err = mTracks.editValueAt(i)->start();
320
321        if (err != OK) {
322            for (size_t j = 0; j < i; ++j) {
323                mTracks.editValueAt(j)->stop();
324            }
325
326            return err;
327        }
328    }
329
330    return OK;
331}
332
333status_t WifiDisplaySource::PlaybackSession::pause() {
334    updateLiveness();
335
336    return OK;
337}
338
339status_t WifiDisplaySource::PlaybackSession::destroy() {
340    mTracks.clear();
341
342    mPacketizer.clear();
343
344    if (mSerializer != NULL) {
345        mSerializer->stop();
346
347        looper()->unregisterHandler(mSerializer->id());
348        mSerializer.clear();
349    }
350
351    mTracks.clear();
352
353    if (mSerializerLooper != NULL) {
354        mSerializerLooper->stop();
355        mSerializerLooper.clear();
356    }
357
358    if (mLegacyMode) {
359        sp<IServiceManager> sm = defaultServiceManager();
360        sp<IBinder> binder = sm->getService(String16("SurfaceFlinger"));
361        sp<ISurfaceComposer> service = interface_cast<ISurfaceComposer>(binder);
362        CHECK(service != NULL);
363
364        service->connectDisplay(NULL);
365    }
366
367    if (mRTCPSessionID != 0) {
368        mNetSession->destroySession(mRTCPSessionID);
369    }
370
371    if (mRTPSessionID != 0) {
372        mNetSession->destroySession(mRTPSessionID);
373    }
374
375    return OK;
376}
377
378void WifiDisplaySource::PlaybackSession::onMessageReceived(
379        const sp<AMessage> &msg) {
380    switch (msg->what()) {
381        case kWhatRTPNotify:
382        case kWhatRTCPNotify:
383        {
384            int32_t reason;
385            CHECK(msg->findInt32("reason", &reason));
386
387            switch (reason) {
388                case ANetworkSession::kWhatError:
389                {
390                    int32_t sessionID;
391                    CHECK(msg->findInt32("sessionID", &sessionID));
392
393                    int32_t err;
394                    CHECK(msg->findInt32("err", &err));
395
396                    int32_t errorOccuredDuringSend;
397                    CHECK(msg->findInt32("send", &errorOccuredDuringSend));
398
399                    AString detail;
400                    CHECK(msg->findString("detail", &detail));
401
402                    if (msg->what() == kWhatRTPNotify
403                            && !errorOccuredDuringSend) {
404                        // This is ok, we don't expect to receive anything on
405                        // the RTP socket.
406                        break;
407                    }
408
409                    ALOGE("An error occurred during %s in session %d "
410                          "(%d, '%s' (%s)).",
411                          errorOccuredDuringSend ? "send" : "receive",
412                          sessionID,
413                          err,
414                          detail.c_str(),
415                          strerror(-err));
416
417                    mNetSession->destroySession(sessionID);
418
419                    if (sessionID == mRTPSessionID) {
420                        mRTPSessionID = 0;
421                    } else if (sessionID == mRTCPSessionID) {
422                        mRTCPSessionID = 0;
423                    }
424
425                    // Inform WifiDisplaySource of our premature death (wish).
426                    sp<AMessage> notify = mNotify->dup();
427                    notify->setInt32("what", kWhatSessionDead);
428                    notify->post();
429                    break;
430                }
431
432                case ANetworkSession::kWhatDatagram:
433                {
434                    int32_t sessionID;
435                    CHECK(msg->findInt32("sessionID", &sessionID));
436
437                    sp<ABuffer> data;
438                    CHECK(msg->findBuffer("data", &data));
439
440                    status_t err;
441                    if (msg->what() == kWhatRTCPNotify) {
442                        err = parseRTCP(data);
443                    }
444                    break;
445                }
446
447                default:
448                    TRESPASS();
449            }
450            break;
451        }
452
453        case kWhatSendSR:
454        {
455            mSendSRPending = false;
456
457            if (mRTCPSessionID == 0) {
458                break;
459            }
460
461            onSendSR();
462
463            scheduleSendSR();
464            break;
465        }
466
467        case kWhatSerializerNotify:
468        {
469            int32_t what;
470            CHECK(msg->findInt32("what", &what));
471
472            if (what == Serializer::kWhatEOS) {
473                ALOGI("input eos");
474
475                for (size_t i = 0; i < mTracks.size(); ++i) {
476#if FAKE_VIDEO
477                    sp<AMessage> msg = new AMessage(kWhatConverterNotify, id());
478                    msg->setInt32("what", Converter::kWhatEOS);
479                    msg->setSize("trackIndex", i);
480                    msg->post();
481#else
482                    mTracks.valueAt(i)->converter()->signalEOS();
483#endif
484                }
485            } else {
486                CHECK_EQ(what, Serializer::kWhatAccessUnit);
487
488                size_t trackIndex;
489                CHECK(msg->findSize("trackIndex", &trackIndex));
490
491                sp<ABuffer> accessUnit;
492                CHECK(msg->findBuffer("accessUnit", &accessUnit));
493
494#if FAKE_VIDEO
495                int64_t timeUs;
496                CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));
497
498                void *mbuf;
499                CHECK(accessUnit->meta()->findPointer("mediaBuffer", &mbuf));
500
501                ((MediaBuffer *)mbuf)->release();
502                mbuf = NULL;
503
504                sp<AMessage> msg = new AMessage(kWhatConverterNotify, id());
505                msg->setInt32("what", Converter::kWhatAccessUnit);
506                msg->setSize("trackIndex", trackIndex);
507                msg->setBuffer("accessUnit", accessUnit);
508                msg->post();
509#else
510                mTracks.valueFor(trackIndex)->converter()
511                    ->feedAccessUnit(accessUnit);
512#endif
513            }
514            break;
515        }
516
517        case kWhatConverterNotify:
518        {
519            int32_t what;
520            CHECK(msg->findInt32("what", &what));
521
522            size_t trackIndex;
523            CHECK(msg->findSize("trackIndex", &trackIndex));
524
525            if (what == Converter::kWhatAccessUnit) {
526                const sp<Track> &track = mTracks.valueFor(trackIndex);
527
528                uint32_t flags = 0;
529
530                ssize_t packetizerTrackIndex = track->packetizerTrackIndex();
531                if (packetizerTrackIndex < 0) {
532                    flags = TSPacketizer::EMIT_PAT_AND_PMT;
533
534                    packetizerTrackIndex =
535                        mPacketizer->addTrack(track->getFormat());
536
537                    if (packetizerTrackIndex >= 0) {
538                        track->setPacketizerTrackIndex(packetizerTrackIndex);
539                    }
540                }
541
542                if (packetizerTrackIndex >= 0) {
543                    sp<ABuffer> accessUnit;
544                    CHECK(msg->findBuffer("accessUnit", &accessUnit));
545
546                    int64_t timeUs;
547                    CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));
548
549                    if (mPrevTimeUs < 0ll || mPrevTimeUs + 100000ll >= timeUs) {
550                        flags |= TSPacketizer::EMIT_PCR;
551                        mPrevTimeUs = timeUs;
552                    }
553
554                    sp<ABuffer> packets;
555                    mPacketizer->packetize(
556                            packetizerTrackIndex, accessUnit, &packets, flags);
557
558                    for (size_t offset = 0;
559                            offset < packets->size(); offset += 188) {
560                        bool lastTSPacket = (offset + 188 >= packets->size());
561
562                        // We're only going to flush video, audio packets are
563                        // much more frequent and would waste all that space
564                        // available in a full sized UDP packet.
565                        bool flush =
566                            lastTSPacket
567                                && ((ssize_t)trackIndex == mVideoTrackIndex);
568
569                        appendTSData(
570                                packets->data() + offset,
571                                188,
572                                true /* timeDiscontinuity */,
573                                flush);
574                    }
575
576#if LOG_TRANSPORT_STREAM
577                    if (mLogFile != NULL) {
578                        fwrite(packets->data(), 1, packets->size(), mLogFile);
579                    }
580#endif
581                }
582            } else if (what == Converter::kWhatEOS) {
583                CHECK_EQ(what, Converter::kWhatEOS);
584
585                ALOGI("output EOS on track %d", trackIndex);
586
587                ssize_t index = mTracks.indexOfKey(trackIndex);
588                CHECK_GE(index, 0);
589
590#if !FAKE_VIDEO
591                const sp<Converter> &converter =
592                    mTracks.valueAt(index)->converter();
593                looper()->unregisterHandler(converter->id());
594#endif
595
596                mTracks.removeItemsAt(index);
597
598                if (mTracks.isEmpty()) {
599                    ALOGI("Reached EOS");
600                }
601            } else {
602                CHECK_EQ(what, Converter::kWhatError);
603
604                status_t err;
605                CHECK(msg->findInt32("err", &err));
606
607                ALOGE("converter signaled error %d", err);
608            }
609            break;
610        }
611
612        default:
613            TRESPASS();
614    }
615}
616
617status_t WifiDisplaySource::PlaybackSession::setupPacketizer() {
618    sp<AMessage> msg = new AMessage(kWhatSerializerNotify, id());
619
620    mPacketizer = new TSPacketizer;
621
622#if FAKE_VIDEO
623    return addFakeSources();
624#else
625    status_t err = addVideoSource();
626
627    if (err != OK) {
628        return err;
629    }
630
631    return addAudioSource();
632#endif
633}
634
635status_t WifiDisplaySource::PlaybackSession::addFakeSources() {
636#if FAKE_VIDEO
637    mSerializerLooper = new ALooper;
638    mSerializerLooper->setName("serializer_looper");
639    mSerializerLooper->start();
640
641    sp<AMessage> msg = new AMessage(kWhatSerializerNotify, id());
642    mSerializer = new Serializer(
643            true /* throttled */, msg);
644
645    mSerializerLooper->registerHandler(mSerializer);
646
647    DataSource::RegisterDefaultSniffers();
648
649    sp<DataSource> dataSource =
650        DataSource::CreateFromURI(
651                "/system/etc/inception_1500.mp4");
652
653    CHECK(dataSource != NULL);
654
655    sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource);
656    CHECK(extractor != NULL);
657
658    bool haveAudio = false;
659    bool haveVideo = false;
660    for (size_t i = 0; i < extractor->countTracks(); ++i) {
661        sp<MetaData> meta = extractor->getTrackMetaData(i);
662
663        const char *mime;
664        CHECK(meta->findCString(kKeyMIMEType, &mime));
665
666        bool useTrack = false;
667        if (!strncasecmp(mime, "audio/", 6) && !haveAudio) {
668            useTrack = true;
669            haveAudio = true;
670        } else if (!strncasecmp(mime, "video/", 6) && !haveVideo) {
671            useTrack = true;
672            haveVideo = true;
673        }
674
675        if (!useTrack) {
676            continue;
677        }
678
679        sp<MediaSource> source = extractor->getTrack(i);
680
681        ssize_t index = mSerializer->addSource(source);
682        CHECK_GE(index, 0);
683
684        sp<AMessage> format;
685        status_t err = convertMetaDataToMessage(source->getFormat(), &format);
686        CHECK_EQ(err, (status_t)OK);
687
688        mTracks.add(index, new Track(format));
689    }
690    CHECK(haveAudio || haveVideo);
691#endif
692
693    return OK;
694}
695
696status_t WifiDisplaySource::PlaybackSession::addSource(
697        bool isVideo, const sp<MediaSource> &source, size_t *numInputBuffers) {
698#if USE_SERIALIZER
699    if (mSerializer == NULL) {
700        mSerializerLooper = new ALooper;
701        mSerializerLooper->setName("serializer_looper");
702        mSerializerLooper->start();
703
704        sp<AMessage> msg = new AMessage(kWhatSerializerNotify, id());
705        mSerializer = new Serializer(
706                false /* throttled */, msg);
707
708        mSerializerLooper->registerHandler(mSerializer);
709    }
710#else
711    sp<ALooper> pullLooper = new ALooper;
712    pullLooper->setName("pull_looper");
713
714    pullLooper->start(
715            false /* runOnCallingThread */,
716            false /* canCallJava */,
717            PRIORITY_DEFAULT);
718#endif
719
720    sp<ALooper> codecLooper = new ALooper;
721    codecLooper->setName("codec_looper");
722
723    codecLooper->start(
724            false /* runOnCallingThread */,
725            false /* canCallJava */,
726            PRIORITY_DEFAULT);
727
728    size_t trackIndex;
729
730    sp<AMessage> notify;
731
732#if USE_SERIALIZER
733    trackIndex = mSerializer->addSource(source);
734#else
735    trackIndex = mTracks.size();
736
737    notify = new AMessage(kWhatSerializerNotify, id());
738    notify->setSize("trackIndex", trackIndex);
739    sp<MediaPuller> puller = new MediaPuller(source, notify);
740    pullLooper->registerHandler(puller);
741#endif
742
743    sp<AMessage> format;
744    status_t err = convertMetaDataToMessage(source->getFormat(), &format);
745    CHECK_EQ(err, (status_t)OK);
746
747    if (isVideo) {
748        format->setInt32("store-metadata-in-buffers", true);
749
750        format->setInt32(
751                "color-format", OMX_COLOR_FormatAndroidOpaque);
752    }
753
754    notify = new AMessage(kWhatConverterNotify, id());
755    notify->setSize("trackIndex", trackIndex);
756
757    sp<Converter> converter =
758        new Converter(notify, codecLooper, format);
759    CHECK_EQ(converter->initCheck(), (status_t)OK);
760
761    looper()->registerHandler(converter);
762
763    if (numInputBuffers != NULL) {
764        *numInputBuffers = converter->getInputBufferCount();
765    }
766
767#if USE_SERIALIZER
768    mTracks.add(trackIndex, new Track(NULL, codecLooper, NULL, converter));
769#else
770    mTracks.add(trackIndex, new Track(pullLooper, codecLooper, puller, converter));
771#endif
772
773    if (isVideo) {
774        mVideoTrackIndex = trackIndex;
775    }
776
777    return OK;
778}
779
780status_t WifiDisplaySource::PlaybackSession::addVideoSource() {
781    sp<SurfaceMediaSource> source = new SurfaceMediaSource(width(), height());
782
783    sp<MediaSource> videoSource =
784            new RepeaterSource(source, 30.0 /* rateHz */);
785
786    size_t numInputBuffers;
787    status_t err = addSource(true /* isVideo */, videoSource, &numInputBuffers);
788
789    if (err != OK) {
790        return err;
791    }
792
793    // Add one reference to account for the serializer.
794    err = source->setMaxAcquiredBufferCount(numInputBuffers);
795    CHECK_EQ(err, (status_t)OK);
796
797    mBufferQueue = source->getBufferQueue();
798
799    if (mLegacyMode) {
800        sp<IServiceManager> sm = defaultServiceManager();
801        sp<IBinder> binder = sm->getService(String16("SurfaceFlinger"));
802        sp<ISurfaceComposer> service = interface_cast<ISurfaceComposer>(binder);
803        CHECK(service != NULL);
804
805        service->connectDisplay(mBufferQueue);
806    }
807
808    return OK;
809}
810
811status_t WifiDisplaySource::PlaybackSession::addAudioSource() {
812    sp<AudioSource> audioSource = new AudioSource(
813            AUDIO_SOURCE_REMOTE_SUBMIX,
814            48000 /* sampleRate */,
815            2 /* channelCount */);
816
817    if (audioSource->initCheck() == OK) {
818        audioSource->setUseLooperTime(true);
819
820        return addSource(
821                false /* isVideo */, audioSource, NULL /* numInputBuffers */);
822    }
823
824    ALOGW("Unable to instantiate audio source");
825
826    return OK;
827}
828
829sp<ISurfaceTexture> WifiDisplaySource::PlaybackSession::getSurfaceTexture() {
830    return mBufferQueue;
831}
832
833int32_t WifiDisplaySource::PlaybackSession::width() const {
834    return mLegacyMode ? 720 : 1280;
835}
836
837int32_t WifiDisplaySource::PlaybackSession::height() const {
838    return mLegacyMode ? 1280 : 720;
839}
840
841void WifiDisplaySource::PlaybackSession::scheduleSendSR() {
842    if (mSendSRPending) {
843        return;
844    }
845
846    mSendSRPending = true;
847    (new AMessage(kWhatSendSR, id()))->post(kSendSRIntervalUs);
848}
849
850void WifiDisplaySource::PlaybackSession::addSR(const sp<ABuffer> &buffer) {
851    uint8_t *data = buffer->data() + buffer->size();
852
853    // TODO: Use macros/utility functions to clean up all the bitshifts below.
854
855    data[0] = 0x80 | 0;
856    data[1] = 200;  // SR
857    data[2] = 0;
858    data[3] = 6;
859    data[4] = kSourceID >> 24;
860    data[5] = (kSourceID >> 16) & 0xff;
861    data[6] = (kSourceID >> 8) & 0xff;
862    data[7] = kSourceID & 0xff;
863
864    data[8] = mLastNTPTime >> (64 - 8);
865    data[9] = (mLastNTPTime >> (64 - 16)) & 0xff;
866    data[10] = (mLastNTPTime >> (64 - 24)) & 0xff;
867    data[11] = (mLastNTPTime >> 32) & 0xff;
868    data[12] = (mLastNTPTime >> 24) & 0xff;
869    data[13] = (mLastNTPTime >> 16) & 0xff;
870    data[14] = (mLastNTPTime >> 8) & 0xff;
871    data[15] = mLastNTPTime & 0xff;
872
873    data[16] = (mLastRTPTime >> 24) & 0xff;
874    data[17] = (mLastRTPTime >> 16) & 0xff;
875    data[18] = (mLastRTPTime >> 8) & 0xff;
876    data[19] = mLastRTPTime & 0xff;
877
878    data[20] = mNumRTPSent >> 24;
879    data[21] = (mNumRTPSent >> 16) & 0xff;
880    data[22] = (mNumRTPSent >> 8) & 0xff;
881    data[23] = mNumRTPSent & 0xff;
882
883    data[24] = mNumRTPOctetsSent >> 24;
884    data[25] = (mNumRTPOctetsSent >> 16) & 0xff;
885    data[26] = (mNumRTPOctetsSent >> 8) & 0xff;
886    data[27] = mNumRTPOctetsSent & 0xff;
887
888    buffer->setRange(buffer->offset(), buffer->size() + 28);
889}
890
891void WifiDisplaySource::PlaybackSession::addSDES(const sp<ABuffer> &buffer) {
892    uint8_t *data = buffer->data() + buffer->size();
893    data[0] = 0x80 | 1;
894    data[1] = 202;  // SDES
895    data[4] = kSourceID >> 24;
896    data[5] = (kSourceID >> 16) & 0xff;
897    data[6] = (kSourceID >> 8) & 0xff;
898    data[7] = kSourceID & 0xff;
899
900    size_t offset = 8;
901
902    data[offset++] = 1;  // CNAME
903
904    static const char *kCNAME = "someone@somewhere";
905    data[offset++] = strlen(kCNAME);
906
907    memcpy(&data[offset], kCNAME, strlen(kCNAME));
908    offset += strlen(kCNAME);
909
910    data[offset++] = 7;  // NOTE
911
912    static const char *kNOTE = "Hell's frozen over.";
913    data[offset++] = strlen(kNOTE);
914
915    memcpy(&data[offset], kNOTE, strlen(kNOTE));
916    offset += strlen(kNOTE);
917
918    data[offset++] = 0;
919
920    if ((offset % 4) > 0) {
921        size_t count = 4 - (offset % 4);
922        switch (count) {
923            case 3:
924                data[offset++] = 0;
925            case 2:
926                data[offset++] = 0;
927            case 1:
928                data[offset++] = 0;
929        }
930    }
931
932    size_t numWords = (offset / 4) - 1;
933    data[2] = numWords >> 8;
934    data[3] = numWords & 0xff;
935
936    buffer->setRange(buffer->offset(), buffer->size() + offset);
937}
938
939// static
940uint64_t WifiDisplaySource::PlaybackSession::GetNowNTP() {
941    uint64_t nowUs = ALooper::GetNowUs();
942
943    nowUs += ((70ll * 365 + 17) * 24) * 60 * 60 * 1000000ll;
944
945    uint64_t hi = nowUs / 1000000ll;
946    uint64_t lo = ((1ll << 32) * (nowUs % 1000000ll)) / 1000000ll;
947
948    return (hi << 32) | lo;
949}
950
951void WifiDisplaySource::PlaybackSession::onSendSR() {
952    sp<ABuffer> buffer = new ABuffer(1500);
953    buffer->setRange(0, 0);
954
955    addSR(buffer);
956    addSDES(buffer);
957
958    if (mUseInterleavedTCP) {
959        sp<AMessage> notify = mNotify->dup();
960        notify->setInt32("what", kWhatBinaryData);
961        notify->setInt32("channel", mRTCPChannel);
962        notify->setBuffer("data", buffer);
963        notify->post();
964    } else {
965        mNetSession->sendRequest(
966                mRTCPSessionID, buffer->data(), buffer->size());
967    }
968
969    ++mNumSRsSent;
970}
971
972ssize_t WifiDisplaySource::PlaybackSession::appendTSData(
973        const void *data, size_t size, bool timeDiscontinuity, bool flush) {
974    CHECK_EQ(size, 188);
975
976    CHECK_LE(mTSQueue->size() + size, mTSQueue->capacity());
977
978    memcpy(mTSQueue->data() + mTSQueue->size(), data, size);
979    mTSQueue->setRange(0, mTSQueue->size() + size);
980
981    if (flush || mTSQueue->size() == mTSQueue->capacity()) {
982        // flush
983
984        int64_t nowUs = ALooper::GetNowUs();
985        if (mFirstPacketTimeUs < 0ll) {
986            mFirstPacketTimeUs = nowUs;
987        }
988
989        // 90kHz time scale
990        uint32_t rtpTime = ((nowUs - mFirstPacketTimeUs) * 9ll) / 100ll;
991
992        uint8_t *rtp = mTSQueue->data();
993        rtp[0] = 0x80;
994        rtp[1] = 33 | (timeDiscontinuity ? (1 << 7) : 0);  // M-bit
995        rtp[2] = (mRTPSeqNo >> 8) & 0xff;
996        rtp[3] = mRTPSeqNo & 0xff;
997        rtp[4] = rtpTime >> 24;
998        rtp[5] = (rtpTime >> 16) & 0xff;
999        rtp[6] = (rtpTime >> 8) & 0xff;
1000        rtp[7] = rtpTime & 0xff;
1001        rtp[8] = kSourceID >> 24;
1002        rtp[9] = (kSourceID >> 16) & 0xff;
1003        rtp[10] = (kSourceID >> 8) & 0xff;
1004        rtp[11] = kSourceID & 0xff;
1005
1006        ++mRTPSeqNo;
1007        ++mNumRTPSent;
1008        mNumRTPOctetsSent += mTSQueue->size() - 12;
1009
1010        mLastRTPTime = rtpTime;
1011        mLastNTPTime = GetNowNTP();
1012
1013        if (mUseInterleavedTCP) {
1014            sp<AMessage> notify = mNotify->dup();
1015            notify->setInt32("what", kWhatBinaryData);
1016
1017            sp<ABuffer> data = new ABuffer(mTSQueue->size());
1018            memcpy(data->data(), rtp, mTSQueue->size());
1019
1020            notify->setInt32("channel", mRTPChannel);
1021            notify->setBuffer("data", data);
1022            notify->post();
1023        } else {
1024            mNetSession->sendRequest(
1025                    mRTPSessionID, rtp, mTSQueue->size());
1026        }
1027
1028        mTSQueue->setInt32Data(mRTPSeqNo - 1);
1029        mHistory.push_back(mTSQueue);
1030        ++mHistoryLength;
1031
1032        if (mHistoryLength > kMaxHistoryLength) {
1033            mTSQueue = *mHistory.begin();
1034            mHistory.erase(mHistory.begin());
1035
1036            --mHistoryLength;
1037        } else {
1038            mTSQueue = new ABuffer(12 + kMaxNumTSPacketsPerRTPPacket * 188);
1039        }
1040
1041        mTSQueue->setRange(0, 12);
1042    }
1043
1044    return size;
1045}
1046
1047status_t WifiDisplaySource::PlaybackSession::parseRTCP(
1048        const sp<ABuffer> &buffer) {
1049    const uint8_t *data = buffer->data();
1050    size_t size = buffer->size();
1051
1052    while (size > 0) {
1053        if (size < 8) {
1054            // Too short to be a valid RTCP header
1055            return ERROR_MALFORMED;
1056        }
1057
1058        if ((data[0] >> 6) != 2) {
1059            // Unsupported version.
1060            return ERROR_UNSUPPORTED;
1061        }
1062
1063        if (data[0] & 0x20) {
1064            // Padding present.
1065
1066            size_t paddingLength = data[size - 1];
1067
1068            if (paddingLength + 12 > size) {
1069                // If we removed this much padding we'd end up with something
1070                // that's too short to be a valid RTP header.
1071                return ERROR_MALFORMED;
1072            }
1073
1074            size -= paddingLength;
1075        }
1076
1077        size_t headerLength = 4 * (data[2] << 8 | data[3]) + 4;
1078
1079        if (size < headerLength) {
1080            // Only received a partial packet?
1081            return ERROR_MALFORMED;
1082        }
1083
1084        switch (data[1]) {
1085            case 200:
1086            case 201:  // RR
1087            case 202:  // SDES
1088            case 203:
1089            case 204:  // APP
1090                break;
1091
1092            case 205:  // TSFB (transport layer specific feedback)
1093                parseTSFB(data, headerLength);
1094                break;
1095
1096            case 206:  // PSFB (payload specific feedback)
1097                hexdump(data, headerLength);
1098                break;
1099
1100            default:
1101            {
1102                ALOGW("Unknown RTCP packet type %u of size %d",
1103                     (unsigned)data[1], headerLength);
1104                break;
1105            }
1106        }
1107
1108        data += headerLength;
1109        size -= headerLength;
1110    }
1111
1112    return OK;
1113}
1114
1115status_t WifiDisplaySource::PlaybackSession::parseTSFB(
1116        const uint8_t *data, size_t size) {
1117    if ((data[0] & 0x1f) != 1) {
1118        return ERROR_UNSUPPORTED;  // We only support NACK for now.
1119    }
1120
1121    uint32_t srcId = U32_AT(&data[8]);
1122    if (srcId != kSourceID) {
1123        return ERROR_MALFORMED;
1124    }
1125
1126    for (size_t i = 12; i < size; i += 4) {
1127        uint16_t seqNo = U16_AT(&data[i]);
1128        uint16_t blp = U16_AT(&data[i + 2]);
1129
1130        List<sp<ABuffer> >::iterator it = mHistory.begin();
1131        bool found = false;
1132        while (it != mHistory.end()) {
1133            const sp<ABuffer> &buffer = *it;
1134
1135            uint16_t bufferSeqNo = buffer->int32Data() & 0xffff;
1136
1137            if (bufferSeqNo == seqNo) {
1138                mNetSession->sendRequest(
1139                        mRTPSessionID, buffer->data(), buffer->size());
1140
1141                found = true;
1142                break;
1143            }
1144
1145            ++it;
1146        }
1147
1148        if (found) {
1149            ALOGI("retransmitting seqNo %d", seqNo);
1150        } else {
1151            ALOGI("seqNo %d no longer available", seqNo);
1152        }
1153    }
1154
1155    return OK;
1156}
1157
1158}  // namespace android
1159
1160