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