MediaSender.cpp revision e2aef54fee88fdeb585a41e1e9834e3d975b263c
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 case kWhatNetworkStall: 329 { 330 size_t numBytesQueued; 331 CHECK(msg->findSize("numBytesQueued", &numBytesQueued)); 332 333 notifyNetworkStall(numBytesQueued); 334 break; 335 } 336 337 default: 338 TRESPASS(); 339 } 340} 341 342void MediaSender::notifyInitDone(status_t err) { 343 sp<AMessage> notify = mNotify->dup(); 344 notify->setInt32("what", kWhatInitDone); 345 notify->setInt32("err", err); 346 notify->post(); 347} 348 349void MediaSender::notifyError(status_t err) { 350 sp<AMessage> notify = mNotify->dup(); 351 notify->setInt32("what", kWhatError); 352 notify->setInt32("err", err); 353 notify->post(); 354} 355 356void MediaSender::notifyNetworkStall(size_t numBytesQueued) { 357 sp<AMessage> notify = mNotify->dup(); 358 notify->setInt32("what", kWhatNetworkStall); 359 notify->setSize("numBytesQueued", numBytesQueued); 360 notify->post(); 361} 362 363status_t MediaSender::packetizeAccessUnit( 364 size_t trackIndex, 365 sp<ABuffer> accessUnit, 366 sp<ABuffer> *tsPackets) { 367 const TrackInfo &info = mTrackInfos.itemAt(trackIndex); 368 369 uint32_t flags = 0; 370 371 bool isHDCPEncrypted = false; 372 uint64_t inputCTR; 373 uint8_t HDCP_private_data[16]; 374 375 bool manuallyPrependSPSPPS = 376 !info.mIsAudio 377 && (info.mFlags & FLAG_MANUALLY_PREPEND_SPS_PPS) 378 && IsIDR(accessUnit); 379 380 if (mHDCP != NULL && !info.mIsAudio) { 381 isHDCPEncrypted = true; 382 383 if (manuallyPrependSPSPPS) { 384 accessUnit = mTSPacketizer->prependCSD( 385 info.mPacketizerTrackIndex, accessUnit); 386 } 387 388 status_t err = mHDCP->encrypt( 389 accessUnit->data(), accessUnit->size(), 390 trackIndex /* streamCTR */, 391 &inputCTR, 392 accessUnit->data()); 393 394 if (err != OK) { 395 ALOGE("Failed to HDCP-encrypt media data (err %d)", 396 err); 397 398 return err; 399 } 400 401 HDCP_private_data[0] = 0x00; 402 403 HDCP_private_data[1] = 404 (((trackIndex >> 30) & 3) << 1) | 1; 405 406 HDCP_private_data[2] = (trackIndex >> 22) & 0xff; 407 408 HDCP_private_data[3] = 409 (((trackIndex >> 15) & 0x7f) << 1) | 1; 410 411 HDCP_private_data[4] = (trackIndex >> 7) & 0xff; 412 413 HDCP_private_data[5] = 414 ((trackIndex & 0x7f) << 1) | 1; 415 416 HDCP_private_data[6] = 0x00; 417 418 HDCP_private_data[7] = 419 (((inputCTR >> 60) & 0x0f) << 1) | 1; 420 421 HDCP_private_data[8] = (inputCTR >> 52) & 0xff; 422 423 HDCP_private_data[9] = 424 (((inputCTR >> 45) & 0x7f) << 1) | 1; 425 426 HDCP_private_data[10] = (inputCTR >> 37) & 0xff; 427 428 HDCP_private_data[11] = 429 (((inputCTR >> 30) & 0x7f) << 1) | 1; 430 431 HDCP_private_data[12] = (inputCTR >> 22) & 0xff; 432 433 HDCP_private_data[13] = 434 (((inputCTR >> 15) & 0x7f) << 1) | 1; 435 436 HDCP_private_data[14] = (inputCTR >> 7) & 0xff; 437 438 HDCP_private_data[15] = 439 ((inputCTR & 0x7f) << 1) | 1; 440 441 flags |= TSPacketizer::IS_ENCRYPTED; 442 } else if (manuallyPrependSPSPPS) { 443 flags |= TSPacketizer::PREPEND_SPS_PPS_TO_IDR_FRAMES; 444 } 445 446 int64_t timeUs = ALooper::GetNowUs(); 447 if (mPrevTimeUs < 0ll || mPrevTimeUs + 100000ll <= timeUs) { 448 flags |= TSPacketizer::EMIT_PCR; 449 flags |= TSPacketizer::EMIT_PAT_AND_PMT; 450 451 mPrevTimeUs = timeUs; 452 } 453 454 mTSPacketizer->packetize( 455 info.mPacketizerTrackIndex, 456 accessUnit, 457 tsPackets, 458 flags, 459 !isHDCPEncrypted ? NULL : HDCP_private_data, 460 !isHDCPEncrypted ? 0 : sizeof(HDCP_private_data), 461 info.mIsAudio ? 2 : 0 /* numStuffingBytes */); 462 463 return OK; 464} 465 466} // namespace android 467 468