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