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