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