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