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