Home | History | Annotate | Download | only in libaah_rtp
      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