MediaSender.cpp revision a556c4822fc205db0d27834ba5b637c351d73ffa
1a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber/* 2a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber * Copyright 2013, The Android Open Source Project 3a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber * 4a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber * you may not use this file except in compliance with the License. 6a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber * You may obtain a copy of the License at 7a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber * 8a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber * 10a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber * Unless required by applicable law or agreed to in writing, software 11a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber * See the License for the specific language governing permissions and 14a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber * limitations under the License. 15a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber */ 16a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 17a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber//#define LOG_NDEBUG 0 18a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber#define LOG_TAG "MediaSender" 19a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber#include <utils/Log.h> 20a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 21a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber#include "MediaSender.h" 22a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 23a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber#include "ANetworkSession.h" 24a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber#include "rtp/RTPSender.h" 25a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber#include "source/TSPacketizer.h" 26a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 27a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber#include "include/avc_utils.h" 28a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 29a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber#include <media/IHDCP.h> 30a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber#include <media/stagefright/foundation/ABuffer.h> 31a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber#include <media/stagefright/foundation/ADebug.h> 32a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber#include <media/stagefright/foundation/AMessage.h> 33a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 34a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Hubernamespace android { 35a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 36a556c4822fc205db0d27834ba5b637c351d73ffaAndreas HuberMediaSender::MediaSender( 37a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber const sp<ANetworkSession> &netSession, 38a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber const sp<AMessage> ¬ify) 39a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber : mNetSession(netSession), 40a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber mNotify(notify), 41a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber mMode(MODE_UNDEFINED), 42a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber mGeneration(0), 43a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber mPrevTimeUs(-1ll), 44a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber mInitDoneCount(0) { 45a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber} 46a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 47a556c4822fc205db0d27834ba5b637c351d73ffaAndreas HuberMediaSender::~MediaSender() { 48a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber} 49a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 50a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huberstatus_t MediaSender::setHDCP(const sp<IHDCP> &hdcp) { 51a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber if (mMode != MODE_UNDEFINED) { 52a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber return INVALID_OPERATION; 53a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 54a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 55a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber mHDCP = hdcp; 56a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 57a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber return OK; 58a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber} 59a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 60a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huberssize_t MediaSender::addTrack(const sp<AMessage> &format, uint32_t flags) { 61a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber if (mMode != MODE_UNDEFINED) { 62a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber return INVALID_OPERATION; 63a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 64a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 65a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber TrackInfo info; 66a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber info.mFormat = format; 67a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber info.mFlags = flags; 68a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber info.mPacketizerTrackIndex = -1; 69a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 70a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber AString mime; 71a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber CHECK(format->findString("mime", &mime)); 72a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber info.mIsAudio = !strncasecmp("audio/", mime.c_str(), 6); 73a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 74a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber size_t index = mTrackInfos.size(); 75a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber mTrackInfos.push_back(info); 76a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 77a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber return index; 78a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber} 79a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 80a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huberstatus_t MediaSender::initAsync( 81a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber ssize_t trackIndex, 82a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber RTPSender::TransportMode transportMode, 83a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber const char *remoteHost, 84a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber int32_t remoteRTPPort, 85a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber int32_t remoteRTCPPort, 86a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber int32_t *localRTPPort) { 87a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber if (trackIndex < 0) { 88a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber if (mMode != MODE_UNDEFINED) { 89a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber return INVALID_OPERATION; 90a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 91a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 92a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber mTSPacketizer = new TSPacketizer; 93a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 94a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber status_t err = OK; 95a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber for (size_t i = 0; i < mTrackInfos.size(); ++i) { 96a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber TrackInfo *info = &mTrackInfos.editItemAt(i); 97a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 98a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber sp<AMessage> trackFormat = info->mFormat; 99a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber if (mHDCP != NULL && !info->mIsAudio) { 100a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber // HDCP2.0 _and_ HDCP 2.1 specs say to set the version 101a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber // inside the HDCP descriptor to 0x20!!! 102a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber trackFormat->setInt32("hdcp-version", 0x20); 103a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 104a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 105a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber ssize_t packetizerTrackIndex = 106a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber mTSPacketizer->addTrack(trackFormat); 107a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 108a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber if (packetizerTrackIndex < 0) { 109a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber err = packetizerTrackIndex; 110a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber break; 111a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 112a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 113a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber info->mPacketizerTrackIndex = packetizerTrackIndex; 114a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 115a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 116a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber if (err == OK) { 117a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber sp<AMessage> notify = new AMessage(kWhatSenderNotify, id()); 118a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber notify->setInt32("generation", mGeneration); 119a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber mTSSender = new RTPSender(mNetSession, notify); 120a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber looper()->registerHandler(mTSSender); 121a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 122a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber err = mTSSender->initAsync( 123a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber transportMode, 124a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber remoteHost, 125a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber remoteRTPPort, 126a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber remoteRTCPPort, 127a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber localRTPPort); 128a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 129a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber if (err != OK) { 130a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber looper()->unregisterHandler(mTSSender->id()); 131a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber mTSSender.clear(); 132a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 133a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 134a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 135a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber if (err != OK) { 136a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber for (size_t i = 0; i < mTrackInfos.size(); ++i) { 137a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber TrackInfo *info = &mTrackInfos.editItemAt(i); 138a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber info->mPacketizerTrackIndex = -1; 139a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 140a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 141a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber mTSPacketizer.clear(); 142a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber return err; 143a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 144a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 145a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber mMode = MODE_TRANSPORT_STREAM; 146a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber mInitDoneCount = 1; 147a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 148a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber return OK; 149a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 150a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 151a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber if (mMode == MODE_TRANSPORT_STREAM) { 152a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber return INVALID_OPERATION; 153a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 154a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 155a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber if ((size_t)trackIndex >= mTrackInfos.size()) { 156a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber return -ERANGE; 157a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 158a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 159a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber TrackInfo *info = &mTrackInfos.editItemAt(trackIndex); 160a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 161a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber if (info->mSender != NULL) { 162a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber return INVALID_OPERATION; 163a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 164a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 165a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber sp<AMessage> notify = new AMessage(kWhatSenderNotify, id()); 166a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber notify->setInt32("generation", mGeneration); 167a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber notify->setSize("trackIndex", trackIndex); 168a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 169a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber info->mSender = new RTPSender(mNetSession, notify); 170a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber looper()->registerHandler(info->mSender); 171a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 172a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber status_t err = info->mSender->initAsync( 173a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber transportMode, 174a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber remoteHost, 175a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber remoteRTPPort, 176a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber remoteRTCPPort, 177a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber localRTPPort); 178a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 179a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber if (err != OK) { 180a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber looper()->unregisterHandler(info->mSender->id()); 181a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber info->mSender.clear(); 182a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 183a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber return err; 184a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 185a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 186a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber if (mMode == MODE_UNDEFINED) { 187a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber mInitDoneCount = mTrackInfos.size(); 188a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 189a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 190a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber mMode = MODE_ELEMENTARY_STREAMS; 191a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 192a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber return OK; 193a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber} 194a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 195a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huberstatus_t MediaSender::queueAccessUnit( 196a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber size_t trackIndex, const sp<ABuffer> &accessUnit) { 197a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber if (mMode == MODE_UNDEFINED) { 198a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber return INVALID_OPERATION; 199a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 200a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 201a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber if (trackIndex >= mTrackInfos.size()) { 202a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber return -ERANGE; 203a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 204a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 205a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber if (mMode == MODE_TRANSPORT_STREAM) { 206a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber TrackInfo *info = &mTrackInfos.editItemAt(trackIndex); 207a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber info->mAccessUnits.push_back(accessUnit); 208a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 209a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber mTSPacketizer->extractCSDIfNecessary(info->mPacketizerTrackIndex); 210a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 211a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber for (;;) { 212a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber ssize_t minTrackIndex = -1; 213a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber int64_t minTimeUs = -1ll; 214a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 215a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber for (size_t i = 0; i < mTrackInfos.size(); ++i) { 216a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber const TrackInfo &info = mTrackInfos.itemAt(i); 217a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 218a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber if (info.mAccessUnits.empty()) { 219a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber minTrackIndex = -1; 220a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber minTimeUs = -1ll; 221a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber break; 222a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 223a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 224a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber int64_t timeUs; 225a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber const sp<ABuffer> &accessUnit = *info.mAccessUnits.begin(); 226a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs)); 227a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 228a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber if (minTrackIndex < 0 || timeUs < minTimeUs) { 229a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber minTrackIndex = i; 230a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber minTimeUs = timeUs; 231a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 232a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 233a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 234a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber if (minTrackIndex < 0) { 235a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber return OK; 236a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 237a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 238a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber TrackInfo *info = &mTrackInfos.editItemAt(minTrackIndex); 239a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber sp<ABuffer> accessUnit = *info->mAccessUnits.begin(); 240a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber info->mAccessUnits.erase(info->mAccessUnits.begin()); 241a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 242a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber sp<ABuffer> tsPackets; 243a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber status_t err = packetizeAccessUnit( 244a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber minTrackIndex, accessUnit, &tsPackets); 245a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 246a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber if (err == OK) { 247a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber err = mTSSender->queueBuffer( 248a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber tsPackets, 249a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 33 /* packetType */, 250a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber RTPSender::PACKETIZATION_TRANSPORT_STREAM); 251a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 252a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 253a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber if (err != OK) { 254a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber return err; 255a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 256a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 257a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 258a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 259a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber TrackInfo *info = &mTrackInfos.editItemAt(trackIndex); 260a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 261a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber return info->mSender->queueBuffer( 262a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber accessUnit, 263a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber info->mIsAudio ? 96 : 97 /* packetType */, 264a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber info->mIsAudio 265a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber ? RTPSender::PACKETIZATION_AAC : RTPSender::PACKETIZATION_H264); 266a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber} 267a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 268a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Hubervoid MediaSender::onMessageReceived(const sp<AMessage> &msg) { 269a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber switch (msg->what()) { 270a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber case kWhatSenderNotify: 271a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber { 272a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber int32_t generation; 273a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber CHECK(msg->findInt32("generation", &generation)); 274a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber if (generation != mGeneration) { 275a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber break; 276a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 277a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 278a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber onSenderNotify(msg); 279a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber break; 280a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 281a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 282a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber default: 283a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber TRESPASS(); 284a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 285a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber} 286a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 287a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Hubervoid MediaSender::onSenderNotify(const sp<AMessage> &msg) { 288a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber int32_t what; 289a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber CHECK(msg->findInt32("what", &what)); 290a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 291a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber switch (what) { 292a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber case RTPSender::kWhatInitDone: 293a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber { 294a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber --mInitDoneCount; 295a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 296a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber int32_t err; 297a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber CHECK(msg->findInt32("err", &err)); 298a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 299a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber if (err != OK) { 300a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber notifyInitDone(err); 301a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber ++mGeneration; 302a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber break; 303a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 304a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 305a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber if (mInitDoneCount == 0) { 306a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber notifyInitDone(OK); 307a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 308a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber break; 309a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 310a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 311a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber case RTPSender::kWhatError: 312a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber { 313a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber int32_t err; 314a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber CHECK(msg->findInt32("err", &err)); 315a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 316a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber notifyError(err); 317a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber break; 318a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 319a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 320a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber default: 321a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber TRESPASS(); 322a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 323a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber} 324a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 325a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Hubervoid MediaSender::notifyInitDone(status_t err) { 326a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber sp<AMessage> notify = mNotify->dup(); 327a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber notify->setInt32("what", kWhatInitDone); 328a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber notify->setInt32("err", err); 329a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber notify->post(); 330a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber} 331a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 332a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Hubervoid MediaSender::notifyError(status_t err) { 333a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber sp<AMessage> notify = mNotify->dup(); 334a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber notify->setInt32("what", kWhatError); 335a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber notify->setInt32("err", err); 336a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber notify->post(); 337a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber} 338a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 339a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huberstatus_t MediaSender::packetizeAccessUnit( 340a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber size_t trackIndex, 341a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber sp<ABuffer> accessUnit, 342a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber sp<ABuffer> *tsPackets) { 343a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber const TrackInfo &info = mTrackInfos.itemAt(trackIndex); 344a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 345a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber uint32_t flags = 0; 346a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 347a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber bool isHDCPEncrypted = false; 348a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber uint64_t inputCTR; 349a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber uint8_t HDCP_private_data[16]; 350a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 351a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber bool manuallyPrependSPSPPS = 352a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber !info.mIsAudio 353a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber && (info.mFlags & FLAG_MANUALLY_PREPEND_SPS_PPS) 354a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber && IsIDR(accessUnit); 355a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 356a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber if (mHDCP != NULL && !info.mIsAudio) { 357a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber isHDCPEncrypted = true; 358a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 359a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber if (manuallyPrependSPSPPS) { 360a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber accessUnit = mTSPacketizer->prependCSD( 361a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber info.mPacketizerTrackIndex, accessUnit); 362a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 363a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 364a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber status_t err = mHDCP->encrypt( 365a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber accessUnit->data(), accessUnit->size(), 366a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber trackIndex /* streamCTR */, 367a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber &inputCTR, 368a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber accessUnit->data()); 369a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 370a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber if (err != OK) { 371a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber ALOGE("Failed to HDCP-encrypt media data (err %d)", 372a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber err); 373a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 374a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber return err; 375a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 376a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 377a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber HDCP_private_data[0] = 0x00; 378a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 379a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber HDCP_private_data[1] = 380a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber (((trackIndex >> 30) & 3) << 1) | 1; 381a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 382a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber HDCP_private_data[2] = (trackIndex >> 22) & 0xff; 383a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 384a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber HDCP_private_data[3] = 385a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber (((trackIndex >> 15) & 0x7f) << 1) | 1; 386a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 387a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber HDCP_private_data[4] = (trackIndex >> 7) & 0xff; 388a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 389a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber HDCP_private_data[5] = 390a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber ((trackIndex & 0x7f) << 1) | 1; 391a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 392a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber HDCP_private_data[6] = 0x00; 393a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 394a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber HDCP_private_data[7] = 395a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber (((inputCTR >> 60) & 0x0f) << 1) | 1; 396a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 397a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber HDCP_private_data[8] = (inputCTR >> 52) & 0xff; 398a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 399a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber HDCP_private_data[9] = 400a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber (((inputCTR >> 45) & 0x7f) << 1) | 1; 401a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 402a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber HDCP_private_data[10] = (inputCTR >> 37) & 0xff; 403a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 404a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber HDCP_private_data[11] = 405a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber (((inputCTR >> 30) & 0x7f) << 1) | 1; 406a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 407a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber HDCP_private_data[12] = (inputCTR >> 22) & 0xff; 408a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 409a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber HDCP_private_data[13] = 410a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber (((inputCTR >> 15) & 0x7f) << 1) | 1; 411a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 412a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber HDCP_private_data[14] = (inputCTR >> 7) & 0xff; 413a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 414a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber HDCP_private_data[15] = 415a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber ((inputCTR & 0x7f) << 1) | 1; 416a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 417a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber flags |= TSPacketizer::IS_ENCRYPTED; 418a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } else if (manuallyPrependSPSPPS) { 419a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber flags |= TSPacketizer::PREPEND_SPS_PPS_TO_IDR_FRAMES; 420a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 421a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 422a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber int64_t timeUs = ALooper::GetNowUs(); 423a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber if (mPrevTimeUs < 0ll || mPrevTimeUs + 100000ll <= timeUs) { 424a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber flags |= TSPacketizer::EMIT_PCR; 425a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber flags |= TSPacketizer::EMIT_PAT_AND_PMT; 426a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 427a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber mPrevTimeUs = timeUs; 428a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 429a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 430a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber mTSPacketizer->packetize( 431a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber info.mPacketizerTrackIndex, 432a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber accessUnit, 433a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber tsPackets, 434a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber flags, 435a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber !isHDCPEncrypted ? NULL : HDCP_private_data, 436a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber !isHDCPEncrypted ? 0 : sizeof(HDCP_private_data), 437a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber info.mIsAudio ? 2 : 0 /* numStuffingBytes */); 438a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 439a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber return OK; 440a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber} 441a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 442a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber} // namespace android 443a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 444