PlaybackSession.cpp revision 45d76bb6c8f15335f89c287dbae04cc38f79d0a8
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 3 secs to bind its sockets.
419    (new AMessage(kWhatFinishPlay, id()))->post(3000000ll);
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            break;
827        }
828
829        case kWhatFinishPlay:
830        {
831            onFinishPlay();
832            break;
833        }
834
835        default:
836            TRESPASS();
837    }
838}
839
840status_t WifiDisplaySource::PlaybackSession::setupPacketizer() {
841    mPacketizer = new TSPacketizer;
842
843    status_t err = addVideoSource();
844
845    if (err != OK) {
846        return err;
847    }
848
849    return addAudioSource();
850}
851
852status_t WifiDisplaySource::PlaybackSession::addSource(
853        bool isVideo, const sp<MediaSource> &source, size_t *numInputBuffers) {
854    sp<ALooper> pullLooper = new ALooper;
855    pullLooper->setName("pull_looper");
856
857    pullLooper->start(
858            false /* runOnCallingThread */,
859            false /* canCallJava */,
860            PRIORITY_DEFAULT);
861
862    sp<ALooper> codecLooper = new ALooper;
863    codecLooper->setName("codec_looper");
864
865    codecLooper->start(
866            false /* runOnCallingThread */,
867            false /* canCallJava */,
868            PRIORITY_DEFAULT);
869
870    size_t trackIndex;
871
872    sp<AMessage> notify;
873
874    trackIndex = mTracks.size();
875
876    notify = new AMessage(kWhatMediaPullerNotify, id());
877    notify->setSize("trackIndex", trackIndex);
878    sp<MediaPuller> puller = new MediaPuller(source, notify);
879    pullLooper->registerHandler(puller);
880
881    sp<AMessage> format;
882    status_t err = convertMetaDataToMessage(source->getFormat(), &format);
883    CHECK_EQ(err, (status_t)OK);
884
885    if (isVideo) {
886        format->setInt32("store-metadata-in-buffers", true);
887
888        format->setInt32(
889                "color-format", OMX_COLOR_FormatAndroidOpaque);
890    }
891
892    notify = new AMessage(kWhatConverterNotify, id());
893    notify->setSize("trackIndex", trackIndex);
894
895    sp<Converter> converter =
896        new Converter(notify, codecLooper, format);
897    CHECK_EQ(converter->initCheck(), (status_t)OK);
898
899    looper()->registerHandler(converter);
900
901    if (numInputBuffers != NULL) {
902        *numInputBuffers = converter->getInputBufferCount();
903    }
904
905    mTracks.add(trackIndex, new Track(pullLooper, codecLooper, puller, converter));
906
907    if (isVideo) {
908        mVideoTrackIndex = trackIndex;
909    }
910
911    return OK;
912}
913
914status_t WifiDisplaySource::PlaybackSession::addVideoSource() {
915    sp<SurfaceMediaSource> source = new SurfaceMediaSource(width(), height());
916
917    sp<MediaSource> videoSource =
918            new RepeaterSource(source, 30.0 /* rateHz */);
919
920    size_t numInputBuffers;
921    status_t err = addSource(true /* isVideo */, videoSource, &numInputBuffers);
922
923    if (err != OK) {
924        return err;
925    }
926
927    err = source->setMaxAcquiredBufferCount(numInputBuffers);
928    CHECK_EQ(err, (status_t)OK);
929
930    mBufferQueue = source->getBufferQueue();
931
932    return OK;
933}
934
935status_t WifiDisplaySource::PlaybackSession::addAudioSource() {
936    sp<AudioSource> audioSource = new AudioSource(
937            AUDIO_SOURCE_REMOTE_SUBMIX,
938            48000 /* sampleRate */,
939            2 /* channelCount */);
940
941    if (audioSource->initCheck() == OK) {
942        audioSource->setUseLooperTime(true);
943
944        return addSource(
945                false /* isVideo */, audioSource, NULL /* numInputBuffers */);
946    }
947
948    ALOGW("Unable to instantiate audio source");
949
950    return OK;
951}
952
953sp<ISurfaceTexture> WifiDisplaySource::PlaybackSession::getSurfaceTexture() {
954    return mBufferQueue;
955}
956
957int32_t WifiDisplaySource::PlaybackSession::width() const {
958    return 1280;
959}
960
961int32_t WifiDisplaySource::PlaybackSession::height() const {
962    return 720;
963}
964
965void WifiDisplaySource::PlaybackSession::scheduleSendSR() {
966    if (mSendSRPending) {
967        return;
968    }
969
970    mSendSRPending = true;
971    (new AMessage(kWhatSendSR, id()))->post(kSendSRIntervalUs);
972}
973
974void WifiDisplaySource::PlaybackSession::addSR(const sp<ABuffer> &buffer) {
975    uint8_t *data = buffer->data() + buffer->size();
976
977    // TODO: Use macros/utility functions to clean up all the bitshifts below.
978
979    data[0] = 0x80 | 0;
980    data[1] = 200;  // SR
981    data[2] = 0;
982    data[3] = 6;
983    data[4] = kSourceID >> 24;
984    data[5] = (kSourceID >> 16) & 0xff;
985    data[6] = (kSourceID >> 8) & 0xff;
986    data[7] = kSourceID & 0xff;
987
988    data[8] = mLastNTPTime >> (64 - 8);
989    data[9] = (mLastNTPTime >> (64 - 16)) & 0xff;
990    data[10] = (mLastNTPTime >> (64 - 24)) & 0xff;
991    data[11] = (mLastNTPTime >> 32) & 0xff;
992    data[12] = (mLastNTPTime >> 24) & 0xff;
993    data[13] = (mLastNTPTime >> 16) & 0xff;
994    data[14] = (mLastNTPTime >> 8) & 0xff;
995    data[15] = mLastNTPTime & 0xff;
996
997    data[16] = (mLastRTPTime >> 24) & 0xff;
998    data[17] = (mLastRTPTime >> 16) & 0xff;
999    data[18] = (mLastRTPTime >> 8) & 0xff;
1000    data[19] = mLastRTPTime & 0xff;
1001
1002    data[20] = mNumRTPSent >> 24;
1003    data[21] = (mNumRTPSent >> 16) & 0xff;
1004    data[22] = (mNumRTPSent >> 8) & 0xff;
1005    data[23] = mNumRTPSent & 0xff;
1006
1007    data[24] = mNumRTPOctetsSent >> 24;
1008    data[25] = (mNumRTPOctetsSent >> 16) & 0xff;
1009    data[26] = (mNumRTPOctetsSent >> 8) & 0xff;
1010    data[27] = mNumRTPOctetsSent & 0xff;
1011
1012    buffer->setRange(buffer->offset(), buffer->size() + 28);
1013}
1014
1015void WifiDisplaySource::PlaybackSession::addSDES(const sp<ABuffer> &buffer) {
1016    uint8_t *data = buffer->data() + buffer->size();
1017    data[0] = 0x80 | 1;
1018    data[1] = 202;  // SDES
1019    data[4] = kSourceID >> 24;
1020    data[5] = (kSourceID >> 16) & 0xff;
1021    data[6] = (kSourceID >> 8) & 0xff;
1022    data[7] = kSourceID & 0xff;
1023
1024    size_t offset = 8;
1025
1026    data[offset++] = 1;  // CNAME
1027
1028    static const char *kCNAME = "someone@somewhere";
1029    data[offset++] = strlen(kCNAME);
1030
1031    memcpy(&data[offset], kCNAME, strlen(kCNAME));
1032    offset += strlen(kCNAME);
1033
1034    data[offset++] = 7;  // NOTE
1035
1036    static const char *kNOTE = "Hell's frozen over.";
1037    data[offset++] = strlen(kNOTE);
1038
1039    memcpy(&data[offset], kNOTE, strlen(kNOTE));
1040    offset += strlen(kNOTE);
1041
1042    data[offset++] = 0;
1043
1044    if ((offset % 4) > 0) {
1045        size_t count = 4 - (offset % 4);
1046        switch (count) {
1047            case 3:
1048                data[offset++] = 0;
1049            case 2:
1050                data[offset++] = 0;
1051            case 1:
1052                data[offset++] = 0;
1053        }
1054    }
1055
1056    size_t numWords = (offset / 4) - 1;
1057    data[2] = numWords >> 8;
1058    data[3] = numWords & 0xff;
1059
1060    buffer->setRange(buffer->offset(), buffer->size() + offset);
1061}
1062
1063// static
1064uint64_t WifiDisplaySource::PlaybackSession::GetNowNTP() {
1065    uint64_t nowUs = ALooper::GetNowUs();
1066
1067    nowUs += ((70ll * 365 + 17) * 24) * 60 * 60 * 1000000ll;
1068
1069    uint64_t hi = nowUs / 1000000ll;
1070    uint64_t lo = ((1ll << 32) * (nowUs % 1000000ll)) / 1000000ll;
1071
1072    return (hi << 32) | lo;
1073}
1074
1075void WifiDisplaySource::PlaybackSession::onSendSR() {
1076    sp<ABuffer> buffer = new ABuffer(1500);
1077    buffer->setRange(0, 0);
1078
1079    addSR(buffer);
1080    addSDES(buffer);
1081
1082    if (mTransportMode == TRANSPORT_TCP_INTERLEAVED) {
1083        sp<AMessage> notify = mNotify->dup();
1084        notify->setInt32("what", kWhatBinaryData);
1085        notify->setInt32("channel", mRTCPChannel);
1086        notify->setBuffer("data", buffer);
1087        notify->post();
1088    } else {
1089        sendPacket(mRTCPSessionID, buffer->data(), buffer->size());
1090    }
1091
1092    ++mNumSRsSent;
1093}
1094
1095ssize_t WifiDisplaySource::PlaybackSession::appendTSData(
1096        const void *data, size_t size, bool timeDiscontinuity, bool flush) {
1097    CHECK_EQ(size, 188);
1098
1099    CHECK_LE(mTSQueue->size() + size, mTSQueue->capacity());
1100
1101    memcpy(mTSQueue->data() + mTSQueue->size(), data, size);
1102    mTSQueue->setRange(0, mTSQueue->size() + size);
1103
1104    if (flush || mTSQueue->size() == mTSQueue->capacity()) {
1105        // flush
1106
1107        int64_t nowUs = ALooper::GetNowUs();
1108        if (mFirstPacketTimeUs < 0ll) {
1109            mFirstPacketTimeUs = nowUs;
1110        }
1111
1112        // 90kHz time scale
1113        uint32_t rtpTime = ((nowUs - mFirstPacketTimeUs) * 9ll) / 100ll;
1114
1115        uint8_t *rtp = mTSQueue->data();
1116        rtp[0] = 0x80;
1117        rtp[1] = 33 | (timeDiscontinuity ? (1 << 7) : 0);  // M-bit
1118        rtp[2] = (mRTPSeqNo >> 8) & 0xff;
1119        rtp[3] = mRTPSeqNo & 0xff;
1120        rtp[4] = rtpTime >> 24;
1121        rtp[5] = (rtpTime >> 16) & 0xff;
1122        rtp[6] = (rtpTime >> 8) & 0xff;
1123        rtp[7] = rtpTime & 0xff;
1124        rtp[8] = kSourceID >> 24;
1125        rtp[9] = (kSourceID >> 16) & 0xff;
1126        rtp[10] = (kSourceID >> 8) & 0xff;
1127        rtp[11] = kSourceID & 0xff;
1128
1129        ++mRTPSeqNo;
1130        ++mNumRTPSent;
1131        mNumRTPOctetsSent += mTSQueue->size() - 12;
1132
1133        mLastRTPTime = rtpTime;
1134        mLastNTPTime = GetNowNTP();
1135
1136        if (mTransportMode == TRANSPORT_TCP_INTERLEAVED) {
1137            sp<AMessage> notify = mNotify->dup();
1138            notify->setInt32("what", kWhatBinaryData);
1139
1140            sp<ABuffer> data = new ABuffer(mTSQueue->size());
1141            memcpy(data->data(), rtp, mTSQueue->size());
1142
1143            notify->setInt32("channel", mRTPChannel);
1144            notify->setBuffer("data", data);
1145            notify->post();
1146        } else {
1147            sendPacket(mRTPSessionID, rtp, mTSQueue->size());
1148
1149            mTotalBytesSent += mTSQueue->size();
1150            int64_t delayUs = ALooper::GetNowUs() - mFirstPacketTimeUs;
1151
1152            if (delayUs > 0ll) {
1153                ALOGV("approx. net bandwidth used: %.2f Mbit/sec",
1154                        mTotalBytesSent * 8.0 / delayUs);
1155            }
1156        }
1157
1158        mTSQueue->setInt32Data(mRTPSeqNo - 1);
1159        mHistory.push_back(mTSQueue);
1160        ++mHistoryLength;
1161
1162        if (mHistoryLength > kMaxHistoryLength) {
1163            mTSQueue = *mHistory.begin();
1164            mHistory.erase(mHistory.begin());
1165
1166            --mHistoryLength;
1167        } else {
1168            mTSQueue = new ABuffer(12 + kMaxNumTSPacketsPerRTPPacket * 188);
1169        }
1170
1171        mTSQueue->setRange(0, 12);
1172    }
1173
1174    return size;
1175}
1176
1177status_t WifiDisplaySource::PlaybackSession::parseRTCP(
1178        const sp<ABuffer> &buffer) {
1179    const uint8_t *data = buffer->data();
1180    size_t size = buffer->size();
1181
1182    while (size > 0) {
1183        if (size < 8) {
1184            // Too short to be a valid RTCP header
1185            return ERROR_MALFORMED;
1186        }
1187
1188        if ((data[0] >> 6) != 2) {
1189            // Unsupported version.
1190            return ERROR_UNSUPPORTED;
1191        }
1192
1193        if (data[0] & 0x20) {
1194            // Padding present.
1195
1196            size_t paddingLength = data[size - 1];
1197
1198            if (paddingLength + 12 > size) {
1199                // If we removed this much padding we'd end up with something
1200                // that's too short to be a valid RTP header.
1201                return ERROR_MALFORMED;
1202            }
1203
1204            size -= paddingLength;
1205        }
1206
1207        size_t headerLength = 4 * (data[2] << 8 | data[3]) + 4;
1208
1209        if (size < headerLength) {
1210            // Only received a partial packet?
1211            return ERROR_MALFORMED;
1212        }
1213
1214        switch (data[1]) {
1215            case 200:
1216            case 201:  // RR
1217            case 202:  // SDES
1218            case 203:
1219            case 204:  // APP
1220                break;
1221
1222#if ENABLE_RETRANSMISSION
1223            case 205:  // TSFB (transport layer specific feedback)
1224                parseTSFB(data, headerLength);
1225                break;
1226#endif
1227
1228            case 206:  // PSFB (payload specific feedback)
1229                hexdump(data, headerLength);
1230                break;
1231
1232            default:
1233            {
1234                ALOGW("Unknown RTCP packet type %u of size %d",
1235                     (unsigned)data[1], headerLength);
1236                break;
1237            }
1238        }
1239
1240        data += headerLength;
1241        size -= headerLength;
1242    }
1243
1244    return OK;
1245}
1246
1247#if ENABLE_RETRANSMISSION
1248status_t WifiDisplaySource::PlaybackSession::parseTSFB(
1249        const uint8_t *data, size_t size) {
1250    if ((data[0] & 0x1f) != 1) {
1251        return ERROR_UNSUPPORTED;  // We only support NACK for now.
1252    }
1253
1254    uint32_t srcId = U32_AT(&data[8]);
1255    if (srcId != kSourceID) {
1256        return ERROR_MALFORMED;
1257    }
1258
1259    for (size_t i = 12; i < size; i += 4) {
1260        uint16_t seqNo = U16_AT(&data[i]);
1261        uint16_t blp = U16_AT(&data[i + 2]);
1262
1263        List<sp<ABuffer> >::iterator it = mHistory.begin();
1264        bool foundSeqNo = false;
1265        while (it != mHistory.end()) {
1266            const sp<ABuffer> &buffer = *it;
1267
1268            uint16_t bufferSeqNo = buffer->int32Data() & 0xffff;
1269
1270            bool retransmit = false;
1271            if (bufferSeqNo == seqNo) {
1272                retransmit = true;
1273            } else if (blp != 0) {
1274                for (size_t i = 0; i < 16; ++i) {
1275                    if ((blp & (1 << i))
1276                        && (bufferSeqNo == ((seqNo + i + 1) & 0xffff))) {
1277                        blp &= ~(1 << i);
1278                        retransmit = true;
1279                    }
1280                }
1281            }
1282
1283            if (retransmit) {
1284                ALOGI("retransmitting seqNo %d", bufferSeqNo);
1285
1286                sp<ABuffer> retransRTP = new ABuffer(2 + buffer->size());
1287                uint8_t *rtp = retransRTP->data();
1288                memcpy(rtp, buffer->data(), 12);
1289                rtp[2] = (mRTPRetransmissionSeqNo >> 8) & 0xff;
1290                rtp[3] = mRTPRetransmissionSeqNo & 0xff;
1291                rtp[12] = (bufferSeqNo >> 8) & 0xff;
1292                rtp[13] = bufferSeqNo & 0xff;
1293                memcpy(&rtp[14], buffer->data() + 12, buffer->size() - 12);
1294
1295                ++mRTPRetransmissionSeqNo;
1296
1297                sendPacket(
1298                        mRTPRetransmissionSessionID,
1299                        retransRTP->data(), retransRTP->size());
1300
1301                if (bufferSeqNo == seqNo) {
1302                    foundSeqNo = true;
1303                }
1304
1305                if (foundSeqNo && blp == 0) {
1306                    break;
1307                }
1308            }
1309
1310            ++it;
1311        }
1312
1313        if (!foundSeqNo || blp != 0) {
1314            ALOGI("Some sequence numbers were no longer available for "
1315                  "retransmission");
1316        }
1317    }
1318
1319    return OK;
1320}
1321#endif
1322
1323void WifiDisplaySource::PlaybackSession::requestIDRFrame() {
1324    for (size_t i = 0; i < mTracks.size(); ++i) {
1325        const sp<Track> &track = mTracks.valueAt(i);
1326
1327        track->converter()->requestIDRFrame();
1328    }
1329}
1330
1331status_t WifiDisplaySource::PlaybackSession::sendPacket(
1332        int32_t sessionID, const void *data, size_t size) {
1333    return mNetSession->sendRequest(sessionID, data, size);
1334}
1335
1336}  // namespace android
1337
1338