1 /* 2 * Copyright (C) 2011 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_TAG "LibAAH_RTP" 18 //#define LOG_NDEBUG 0 19 20 #include <utils/Log.h> 21 22 #include <include/avc_utils.h> 23 #include <media/stagefright/MediaBuffer.h> 24 #include <media/stagefright/MediaDefs.h> 25 #include <media/stagefright/MetaData.h> 26 #include <media/stagefright/OMXCodec.h> 27 #include <media/stagefright/Utils.h> 28 29 #include "aah_rx_player.h" 30 #include "aah_tx_packet.h" 31 32 inline uint32_t min(uint32_t a, uint32_t b) { 33 return (a < b ? a : b); 34 } 35 36 namespace android { 37 38 int64_t AAH_RXPlayer::Substream::kAboutToUnderflowThreshold = 39 50ull * 1000; 40 41 AAH_RXPlayer::Substream::Substream(uint32_t ssrc, OMXClient& omx) { 42 ssrc_ = ssrc; 43 substream_details_known_ = false; 44 buffer_in_progress_ = NULL; 45 status_ = OK; 46 codec_mime_type_ = ""; 47 48 decoder_ = new AAH_DecoderPump(omx); 49 if (decoder_ == NULL) { 50 ALOGE("%s failed to allocate decoder pump!", __PRETTY_FUNCTION__); 51 } 52 if (OK != decoder_->initCheck()) { 53 ALOGE("%s failed to initialize decoder pump!", __PRETTY_FUNCTION__); 54 } 55 56 // cleanupBufferInProgress will reset most of the internal state variables. 57 // Just need to make sure that buffer_in_progress_ is NULL before calling. 58 cleanupBufferInProgress(); 59 } 60 61 AAH_RXPlayer::Substream::~Substream() { 62 shutdown(); 63 } 64 65 void AAH_RXPlayer::Substream::shutdown() { 66 substream_meta_ = NULL; 67 status_ = OK; 68 cleanupBufferInProgress(); 69 cleanupDecoder(); 70 } 71 72 void AAH_RXPlayer::Substream::cleanupBufferInProgress() { 73 if (NULL != buffer_in_progress_) { 74 buffer_in_progress_->release(); 75 buffer_in_progress_ = NULL; 76 } 77 78 expected_buffer_size_ = 0; 79 buffer_filled_ = 0; 80 waiting_for_rap_ = true; 81 82 aux_data_in_progress_.clear(); 83 aux_data_expected_size_ = 0; 84 } 85 86 void AAH_RXPlayer::Substream::cleanupDecoder() { 87 if (decoder_ != NULL) { 88 decoder_->shutdown(); 89 } 90 } 91 92 bool AAH_RXPlayer::Substream::shouldAbort(const char* log_tag) { 93 // If we have already encountered a fatal error, do nothing. We are just 94 // waiting for our owner to shut us down now. 95 if (OK != status_) { 96 ALOGV("Skipping %s, substream has encountered fatal error (%d).", 97 log_tag, status_); 98 return true; 99 } 100 101 return false; 102 } 103 104 void AAH_RXPlayer::Substream::processPayloadStart(uint8_t* buf, 105 uint32_t amt, 106 int32_t ts_lower) { 107 uint32_t min_length = 6; 108 109 if (shouldAbort(__PRETTY_FUNCTION__)) { 110 return; 111 } 112 113 // Do we have a buffer in progress already? If so, abort the buffer. In 114 // theory, this should never happen. If there were a discontinutity in the 115 // stream, the discon in the seq_nos at the RTP level should have already 116 // triggered a cleanup of the buffer in progress. To see a problem at this 117 // level is an indication either of a bug in the transmitter, or some form 118 // of terrible corruption/tampering on the wire. 119 if (NULL != buffer_in_progress_) { 120 ALOGE("processPayloadStart is aborting payload already in progress."); 121 cleanupBufferInProgress(); 122 } 123 124 // Parse enough of the header to know where we stand. Since this is a 125 // payload start, it should begin with a TRTP header which has to be at 126 // least 6 bytes long. 127 if (amt < min_length) { 128 ALOGV("Discarding payload too short to contain TRTP header (len = %u)", 129 amt); 130 return; 131 } 132 133 // Check the TRTP version number. 134 if (0x01 != buf[0]) { 135 ALOGV("Unexpected TRTP version (%u) in header. Expected %u.", 136 buf[0], 1); 137 return; 138 } 139 140 // Extract the substream type field and make sure its one we understand (and 141 // one that does not conflict with any previously received substream type. 142 uint8_t header_type = (buf[1] >> 4) & 0xF; 143 switch (header_type) { 144 case TRTPPacket::kHeaderTypeAudio: 145 // Audio, yay! Just break. We understand audio payloads. 146 break; 147 case TRTPPacket::kHeaderTypeVideo: 148 ALOGV("RXed packet with unhandled TRTP header type (Video)."); 149 return; 150 case TRTPPacket::kHeaderTypeSubpicture: 151 ALOGV("RXed packet with unhandled TRTP header type (Subpicture)."); 152 return; 153 case TRTPPacket::kHeaderTypeControl: 154 ALOGV("RXed packet with unhandled TRTP header type (Control)."); 155 return; 156 default: 157 ALOGV("RXed packet with unhandled TRTP header type (%u).", 158 header_type); 159 return; 160 } 161 162 if (substream_details_known_ && (header_type != substream_type_)) { 163 ALOGV("RXed TRTP Payload for SSRC=0x%08x where header type (%u) does" 164 " not match previously received header type (%u)", 165 ssrc_, header_type, substream_type_); 166 return; 167 } 168 169 // Check the flags to see if there is another 32 bits of timestamp present. 170 uint32_t trtp_header_len = 6; 171 bool ts_valid = buf[1] & TRTPPacket::kFlag_TSValid; 172 if (ts_valid) { 173 min_length += 4; 174 trtp_header_len += 4; 175 if (amt < min_length) { 176 ALOGV("Discarding payload too short to contain TRTP timestamp" 177 " (len = %u)", amt); 178 return; 179 } 180 } 181 182 // Extract the TRTP length field and sanity check it. 183 uint32_t trtp_len = U32_AT(buf + 2); 184 if (trtp_len < min_length) { 185 ALOGV("TRTP length (%u) is too short to be valid. Must be at least %u" 186 " bytes.", trtp_len, min_length); 187 return; 188 } 189 190 // Extract the rest of the timestamp field if valid. 191 int64_t ts = 0; 192 uint32_t parse_offset = 6; 193 if (ts_valid) { 194 uint32_t ts_upper = U32_AT(buf + parse_offset); 195 parse_offset += 4; 196 ts = (static_cast<int64_t>(ts_upper) << 32) | ts_lower; 197 } 198 199 // Check the flags to see if there is another 24 bytes of timestamp 200 // transformation present. 201 if (buf[1] & TRTPPacket::kFlag_TSTransformPresent) { 202 min_length += 24; 203 parse_offset += 24; 204 trtp_header_len += 24; 205 if (amt < min_length) { 206 ALOGV("Discarding payload too short to contain TRTP timestamp" 207 " transformation (len = %u)", amt); 208 return; 209 } 210 } 211 212 // TODO : break the parsing into individual parsers for the different 213 // payload types (audio, video, etc). 214 // 215 // At this point in time, we know that this is audio. Go ahead and parse 216 // the basic header, check the codec type, and find the payload portion of 217 // the packet. 218 min_length += 3; 219 if (trtp_len < min_length) { 220 ALOGV("TRTP length (%u) is too short to be a valid audio payload. Must" 221 " be at least %u bytes.", trtp_len, min_length); 222 return; 223 } 224 225 if (amt < min_length) { 226 ALOGV("TRTP porttion of RTP payload (%u bytes) too small to contain" 227 " entire TRTP header. TRTP does not currently support" 228 " fragmenting TRTP headers across RTP payloads", amt); 229 return; 230 } 231 232 uint8_t codec_type = buf[parse_offset ]; 233 uint8_t flags = buf[parse_offset + 1]; 234 uint8_t volume = buf[parse_offset + 2]; 235 parse_offset += 3; 236 trtp_header_len += 3; 237 238 if (!setupSubstreamType(header_type, codec_type)) { 239 return; 240 } 241 242 if (decoder_ != NULL) { 243 decoder_->setRenderVolume(volume); 244 } 245 246 if (waiting_for_rap_ && !(flags & TRTPAudioPacket::kFlag_RandomAccessPoint)) { 247 ALOGV("Dropping non-RAP TRTP Audio Payload while waiting for RAP."); 248 return; 249 } 250 251 // Check for the presence of codec aux data. 252 if (flags & TRTPAudioPacket::kFlag_AuxLengthPresent) { 253 min_length += 4; 254 trtp_header_len += 4; 255 256 if (trtp_len < min_length) { 257 ALOGV("TRTP length (%u) is too short to be a valid audio payload. " 258 "Must be at least %u bytes.", trtp_len, min_length); 259 return; 260 } 261 262 if (amt < min_length) { 263 ALOGV("TRTP porttion of RTP payload (%u bytes) too small to contain" 264 " entire TRTP header. TRTP does not currently support" 265 " fragmenting TRTP headers across RTP payloads", amt); 266 return; 267 } 268 269 aux_data_expected_size_ = U32_AT(buf + parse_offset); 270 aux_data_in_progress_.clear(); 271 if (aux_data_in_progress_.capacity() < aux_data_expected_size_) { 272 aux_data_in_progress_.setCapacity(aux_data_expected_size_); 273 } 274 } else { 275 aux_data_expected_size_ = 0; 276 } 277 278 if ((aux_data_expected_size_ + trtp_header_len) > trtp_len) { 279 ALOGV("Expected codec aux data length (%u) and TRTP header overhead" 280 " (%u) too large for total TRTP payload length (%u).", 281 aux_data_expected_size_, trtp_header_len, trtp_len); 282 return; 283 } 284 285 // OK - everything left is just payload. Compute the payload size, start 286 // the buffer in progress and pack as much payload as we can into it. If 287 // the payload is finished once we are done, go ahead and send the payload 288 // to the decoder. 289 expected_buffer_size_ = trtp_len 290 - trtp_header_len 291 - aux_data_expected_size_; 292 if (!expected_buffer_size_) { 293 ALOGV("Dropping TRTP Audio Payload with 0 Access Unit length"); 294 return; 295 } 296 297 CHECK(amt >= trtp_header_len); 298 uint32_t todo = amt - trtp_header_len; 299 if ((expected_buffer_size_ + aux_data_expected_size_) < todo) { 300 ALOGV("Extra data (%u > %u) present in initial TRTP Audio Payload;" 301 " dropping payload.", todo, 302 expected_buffer_size_ + aux_data_expected_size_); 303 return; 304 } 305 306 buffer_filled_ = 0; 307 buffer_in_progress_ = new MediaBuffer(expected_buffer_size_); 308 if ((NULL == buffer_in_progress_) || 309 (NULL == buffer_in_progress_->data())) { 310 ALOGV("Failed to allocate MediaBuffer of length %u", 311 expected_buffer_size_); 312 cleanupBufferInProgress(); 313 return; 314 } 315 316 sp<MetaData> meta = buffer_in_progress_->meta_data(); 317 if (meta == NULL) { 318 ALOGV("Missing metadata structure in allocated MediaBuffer; dropping" 319 " payload"); 320 cleanupBufferInProgress(); 321 return; 322 } 323 324 meta->setCString(kKeyMIMEType, codec_mime_type_); 325 if (ts_valid) { 326 meta->setInt64(kKeyTime, ts); 327 } 328 329 // Skip over the header we have already extracted. 330 amt -= trtp_header_len; 331 buf += trtp_header_len; 332 333 // Extract as much of the expected aux data as we can. 334 todo = min(aux_data_expected_size_, amt); 335 if (todo) { 336 aux_data_in_progress_.appendArray(buf, todo); 337 buf += todo; 338 amt -= todo; 339 } 340 341 // Extract as much of the expected payload as we can. 342 todo = min(expected_buffer_size_, amt); 343 if (todo > 0) { 344 uint8_t* tgt = 345 reinterpret_cast<uint8_t*>(buffer_in_progress_->data()); 346 memcpy(tgt, buf, todo); 347 buffer_filled_ = amt; 348 buf += todo; 349 amt -= todo; 350 } 351 352 if (buffer_filled_ >= expected_buffer_size_) { 353 processCompletedBuffer(); 354 } 355 } 356 357 void AAH_RXPlayer::Substream::processPayloadCont(uint8_t* buf, 358 uint32_t amt) { 359 if (shouldAbort(__PRETTY_FUNCTION__)) { 360 return; 361 } 362 363 if (NULL == buffer_in_progress_) { 364 ALOGV("TRTP Receiver skipping payload continuation; no buffer currently" 365 " in progress."); 366 return; 367 } 368 369 CHECK(aux_data_in_progress_.size() <= aux_data_expected_size_); 370 uint32_t aux_left = aux_data_expected_size_ - aux_data_in_progress_.size(); 371 if (aux_left) { 372 uint32_t todo = min(aux_left, amt); 373 aux_data_in_progress_.appendArray(buf, todo); 374 amt -= todo; 375 buf += todo; 376 377 if (!amt) 378 return; 379 } 380 381 CHECK(buffer_filled_ < expected_buffer_size_); 382 uint32_t buffer_left = expected_buffer_size_ - buffer_filled_; 383 if (amt > buffer_left) { 384 ALOGV("Extra data (%u > %u) present in continued TRTP Audio Payload;" 385 " dropping payload.", amt, buffer_left); 386 cleanupBufferInProgress(); 387 return; 388 } 389 390 if (amt > 0) { 391 uint8_t* tgt = 392 reinterpret_cast<uint8_t*>(buffer_in_progress_->data()); 393 memcpy(tgt + buffer_filled_, buf, amt); 394 buffer_filled_ += amt; 395 } 396 397 if (buffer_filled_ >= expected_buffer_size_) { 398 processCompletedBuffer(); 399 } 400 } 401 402 void AAH_RXPlayer::Substream::processCompletedBuffer() { 403 status_t res; 404 405 CHECK(NULL != buffer_in_progress_); 406 407 if (decoder_ == NULL) { 408 ALOGV("Dropping complete buffer, no decoder pump allocated"); 409 goto bailout; 410 } 411 412 // Make sure our metadata used to initialize the decoder has been properly 413 // set up. 414 if (!setupSubstreamMeta()) 415 goto bailout; 416 417 // If our decoder has not be set up, do so now. 418 res = decoder_->init(substream_meta_); 419 if (OK != res) { 420 ALOGE("Failed to init decoder (res = %d)", res); 421 cleanupDecoder(); 422 substream_meta_ = NULL; 423 goto bailout; 424 } 425 426 // Queue the payload for decode. 427 res = decoder_->queueForDecode(buffer_in_progress_); 428 429 if (res != OK) { 430 ALOGD("Failed to queue payload for decode, resetting decoder pump!" 431 " (res = %d)", res); 432 status_ = res; 433 cleanupDecoder(); 434 cleanupBufferInProgress(); 435 } 436 437 // NULL out buffer_in_progress before calling the cleanup helper. 438 // 439 // MediaBuffers use something of a hybrid ref-counting pattern which prevent 440 // the AAH_DecoderPump's input queue from adding their own reference to the 441 // MediaBuffer. MediaBuffers start life with a reference count of 0, as 442 // well as an observer which starts as NULL. Before being given an 443 // observer, the ref count cannot be allowed to become non-zero as it will 444 // cause calls to release() to assert. Basically, before a MediaBuffer has 445 // an observer, they behave like non-ref counted obects where release() 446 // serves the roll of delete. After a MediaBuffer has an observer, they 447 // become more like ref counted objects where add ref and release can be 448 // used, and when the ref count hits zero, the MediaBuffer is handed off to 449 // the observer. 450 // 451 // Given all of this, when we give the buffer to the decoder pump to wait in 452 // the to-be-processed queue, the decoder cannot add a ref to the buffer as 453 // it would in a traditional ref counting system. Instead it needs to 454 // "steal" the non-existent ref. In the case of queue failure, we need to 455 // make certain to release this non-existent reference so that the buffer is 456 // cleaned up during the cleanupBufferInProgress helper. In the case of a 457 // successful queue operation, we need to make certain that the 458 // cleanupBufferInProgress helper does not release the buffer since it needs 459 // to remain alive in the queue. We acomplish this by NULLing out the 460 // buffer pointer before calling the cleanup helper. 461 buffer_in_progress_ = NULL; 462 463 bailout: 464 cleanupBufferInProgress(); 465 } 466 467 bool AAH_RXPlayer::Substream::setupSubstreamMeta() { 468 switch (codec_type_) { 469 case TRTPAudioPacket::kCodecMPEG1Audio: 470 codec_mime_type_ = MEDIA_MIMETYPE_AUDIO_MPEG; 471 return setupMP3SubstreamMeta(); 472 473 case TRTPAudioPacket::kCodecAACAudio: 474 codec_mime_type_ = MEDIA_MIMETYPE_AUDIO_AAC; 475 return setupAACSubstreamMeta(); 476 477 default: 478 ALOGV("Failed to setup substream metadata for unsupported codec" 479 " type (%u)", codec_type_); 480 break; 481 } 482 483 return false; 484 } 485 486 bool AAH_RXPlayer::Substream::setupMP3SubstreamMeta() { 487 const uint8_t* buffer_data = NULL; 488 int sample_rate; 489 int channel_count; 490 size_t frame_size; 491 status_t res; 492 493 buffer_data = reinterpret_cast<const uint8_t*>(buffer_in_progress_->data()); 494 if (buffer_in_progress_->size() < 4) { 495 ALOGV("MP3 payload too short to contain header, dropping payload."); 496 return false; 497 } 498 499 // Extract the channel count and the sample rate from the MP3 header. The 500 // stagefright MP3 requires that these be delivered before decoing can 501 // begin. 502 if (!GetMPEGAudioFrameSize(U32_AT(buffer_data), 503 &frame_size, 504 &sample_rate, 505 &channel_count, 506 NULL, 507 NULL)) { 508 ALOGV("Failed to parse MP3 header in payload, droping payload."); 509 return false; 510 } 511 512 513 // Make sure that our substream metadata is set up properly. If there has 514 // been a format change, be sure to reset the underlying decoder. In 515 // stagefright, it seems like the only way to do this is to destroy and 516 // recreate the decoder. 517 if (substream_meta_ == NULL) { 518 substream_meta_ = new MetaData(); 519 520 if (substream_meta_ == NULL) { 521 ALOGE("Failed to allocate MetaData structure for MP3 substream"); 522 return false; 523 } 524 525 substream_meta_->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG); 526 substream_meta_->setInt32 (kKeyChannelCount, channel_count); 527 substream_meta_->setInt32 (kKeySampleRate, sample_rate); 528 } else { 529 int32_t prev_sample_rate; 530 int32_t prev_channel_count; 531 substream_meta_->findInt32(kKeySampleRate, &prev_sample_rate); 532 substream_meta_->findInt32(kKeyChannelCount, &prev_channel_count); 533 534 if ((prev_channel_count != channel_count) || 535 (prev_sample_rate != sample_rate)) { 536 ALOGW("MP3 format change detected, forcing decoder reset."); 537 cleanupDecoder(); 538 539 substream_meta_->setInt32(kKeyChannelCount, channel_count); 540 substream_meta_->setInt32(kKeySampleRate, sample_rate); 541 } 542 } 543 544 return true; 545 } 546 547 bool AAH_RXPlayer::Substream::setupAACSubstreamMeta() { 548 int32_t sample_rate, channel_cnt; 549 static const size_t overhead = sizeof(sample_rate) 550 + sizeof(channel_cnt); 551 552 if (aux_data_in_progress_.size() < overhead) { 553 ALOGE("Not enough aux data (%u) to initialize AAC substream decoder", 554 aux_data_in_progress_.size()); 555 return false; 556 } 557 558 const uint8_t* aux_data = aux_data_in_progress_.array(); 559 size_t aux_data_size = aux_data_in_progress_.size(); 560 sample_rate = U32_AT(aux_data); 561 channel_cnt = U32_AT(aux_data + sizeof(sample_rate)); 562 563 const uint8_t* esds_data = NULL; 564 size_t esds_data_size = 0; 565 if (aux_data_size > overhead) { 566 esds_data = aux_data + overhead; 567 esds_data_size = aux_data_size - overhead; 568 } 569 570 // Do we already have metadata? If so, has it changed at all? If not, then 571 // there should be nothing else to do. Otherwise, release our old stream 572 // metadata and make new metadata. 573 if (substream_meta_ != NULL) { 574 uint32_t type; 575 const void* data; 576 size_t size; 577 int32_t prev_sample_rate; 578 int32_t prev_channel_count; 579 bool res; 580 581 res = substream_meta_->findInt32(kKeySampleRate, &prev_sample_rate); 582 CHECK(res); 583 res = substream_meta_->findInt32(kKeyChannelCount, &prev_channel_count); 584 CHECK(res); 585 586 // If nothing has changed about the codec aux data (esds, sample rate, 587 // channel count), then we can just do nothing and get out. Otherwise, 588 // we will need to reset the decoder and make a new metadata object to 589 // deal with the format change. 590 bool hasData = (esds_data != NULL); 591 bool hadData = substream_meta_->findData(kKeyESDS, &type, &data, &size); 592 bool esds_change = (hadData != hasData); 593 594 if (!esds_change && hasData) 595 esds_change = ((size != esds_data_size) || 596 memcmp(data, esds_data, size)); 597 598 if (!esds_change && 599 (prev_sample_rate == sample_rate) && 600 (prev_channel_count == channel_cnt)) { 601 return true; // no change, just get out. 602 } 603 604 ALOGW("AAC format change detected, forcing decoder reset."); 605 cleanupDecoder(); 606 substream_meta_ = NULL; 607 } 608 609 CHECK(substream_meta_ == NULL); 610 611 substream_meta_ = new MetaData(); 612 if (substream_meta_ == NULL) { 613 ALOGE("Failed to allocate MetaData structure for AAC substream"); 614 return false; 615 } 616 617 substream_meta_->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); 618 substream_meta_->setInt32 (kKeySampleRate, sample_rate); 619 substream_meta_->setInt32 (kKeyChannelCount, channel_cnt); 620 621 if (esds_data) { 622 substream_meta_->setData(kKeyESDS, kTypeESDS, 623 esds_data, esds_data_size); 624 } 625 626 return true; 627 } 628 629 void AAH_RXPlayer::Substream::processTSTransform(const LinearTransform& trans) { 630 if (decoder_ != NULL) { 631 decoder_->setRenderTSTransform(trans); 632 } 633 } 634 635 bool AAH_RXPlayer::Substream::isAboutToUnderflow() { 636 if (decoder_ == NULL) { 637 return false; 638 } 639 640 return decoder_->isAboutToUnderflow(kAboutToUnderflowThreshold); 641 } 642 643 bool AAH_RXPlayer::Substream::setupSubstreamType(uint8_t substream_type, 644 uint8_t codec_type) { 645 // Sanity check the codec type. Right now we only support MP3 and AAC. 646 // Also check for conflicts with previously delivered codec types. 647 if (substream_details_known_) { 648 if (codec_type != codec_type_) { 649 ALOGV("RXed TRTP Payload for SSRC=0x%08x where codec type (%u) does" 650 " not match previously received codec type (%u)", 651 ssrc_, codec_type, codec_type_); 652 return false; 653 } 654 655 return true; 656 } 657 658 switch (codec_type) { 659 // MP3 and AAC are all we support right now. 660 case TRTPAudioPacket::kCodecMPEG1Audio: 661 case TRTPAudioPacket::kCodecAACAudio: 662 break; 663 664 default: 665 ALOGV("RXed TRTP Audio Payload for SSRC=0x%08x with unsupported" 666 " codec type (%u)", ssrc_, codec_type); 667 return false; 668 } 669 670 substream_type_ = substream_type; 671 codec_type_ = codec_type; 672 substream_details_known_ = true; 673 674 return true; 675 } 676 677 } // namespace android 678