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