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