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