From 81f82c32459029bf0744e28c73f95a7f18cab5ac Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Mon, 12 Apr 2010 16:05:57 -0700 Subject: Distinguish QCELP audio from mpeg4 audio, ignore QCELP audio tracks since we don't have a decoder for it, ignore potentially malformed metadata for AMR NB and WB tracks. Change-Id: Ic9a9198413431db4ea40bb63b9de91aa8a7183af related-to-bug: 2587341 --- media/libstagefright/AwesomePlayer.cpp | 9 +++++++-- media/libstagefright/ESDS.cpp | 15 ++++++++++++++- media/libstagefright/MPEG4Extractor.cpp | 34 +++++++++++++++++++++++++-------- media/libstagefright/MediaDefs.cpp | 1 + media/libstagefright/include/ESDS.h | 2 ++ 5 files changed, 50 insertions(+), 11 deletions(-) (limited to 'media/libstagefright') diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp index c1987dc..2bc8139 100644 --- a/media/libstagefright/AwesomePlayer.cpp +++ b/media/libstagefright/AwesomePlayer.cpp @@ -763,9 +763,14 @@ status_t AwesomePlayer::initAudioDecoder() { mDurationUs = durationUs; } } - } - mAudioSource->start(); + mAudioSource->start(); + } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_QCELP)) { + // For legacy reasons we're simply going to ignore the absence + // of an audio decoder for QCELP instead of aborting playback + // altogether. + return OK; + } return mAudioSource != NULL ? OK : UNKNOWN_ERROR; } diff --git a/media/libstagefright/ESDS.cpp b/media/libstagefright/ESDS.cpp index 28d338c..b7c8e0c 100644 --- a/media/libstagefright/ESDS.cpp +++ b/media/libstagefright/ESDS.cpp @@ -25,7 +25,8 @@ ESDS::ESDS(const void *data, size_t size) mSize(size), mInitCheck(NO_INIT), mDecoderSpecificOffset(0), - mDecoderSpecificLength(0) { + mDecoderSpecificLength(0), + mObjectTypeIndication(0) { memcpy(mData, data, size); mInitCheck = parse(); @@ -40,6 +41,16 @@ status_t ESDS::InitCheck() const { return mInitCheck; } +status_t ESDS::getObjectTypeIndication(uint8_t *objectTypeIndication) const { + if (mInitCheck != OK) { + return mInitCheck; + } + + *objectTypeIndication = mObjectTypeIndication; + + return OK; +} + status_t ESDS::getCodecSpecificInfo(const void **data, size_t *size) const { if (mInitCheck != OK) { return mInitCheck; @@ -164,6 +175,8 @@ status_t ESDS::parseDecoderConfigDescriptor(size_t offset, size_t size) { return ERROR_MALFORMED; } + mObjectTypeIndication = mData[offset]; + offset += 13; size -= 13; diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp index bd3925a..0e21d08 100644 --- a/media/libstagefright/MPEG4Extractor.cpp +++ b/media/libstagefright/MPEG4Extractor.cpp @@ -741,19 +741,25 @@ status_t MPEG4Extractor::parseChunk(off_t *offset, int depth) { uint16_t data_ref_index = U16_AT(&buffer[6]); uint16_t num_channels = U16_AT(&buffer[16]); + uint16_t sample_size = U16_AT(&buffer[18]); + uint32_t sample_rate = U32_AT(&buffer[24]) >> 16; + if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, - FourCC2MIME(chunk_type)) - || !strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, + FourCC2MIME(chunk_type))) { + // AMR NB audio is always mono, 8kHz + num_channels = 1; + sample_rate = 8000; + } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, FourCC2MIME(chunk_type))) { - // AMR audio is always mono. + // AMR WB audio is always mono, 16kHz num_channels = 1; + sample_rate = 16000; } - uint16_t sample_size = U16_AT(&buffer[18]); - uint32_t sample_rate = U32_AT(&buffer[24]) >> 16; - - // printf("*** coding='%s' %d channels, size %d, rate %d\n", - // chunk, num_channels, sample_size, sample_rate); +#if 0 + printf("*** coding='%s' %d channels, size %d, rate %d\n", + chunk, num_channels, sample_size, sample_rate); +#endif mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); @@ -1235,6 +1241,18 @@ status_t MPEG4Extractor::verifyTrack(Track *track) { status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( const void *esds_data, size_t esds_size) { ESDS esds(esds_data, esds_size); + + uint8_t objectTypeIndication; + if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) { + return ERROR_MALFORMED; + } + + if (objectTypeIndication == 0xe1) { + // This isn't MPEG4 audio at all, it's QCELP 14k... + mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP); + return OK; + } + const uint8_t *csd; size_t csd_size; if (esds.getCodecSpecificInfo( diff --git a/media/libstagefright/MediaDefs.cpp b/media/libstagefright/MediaDefs.cpp index 04b1454..3a89170 100644 --- a/media/libstagefright/MediaDefs.cpp +++ b/media/libstagefright/MediaDefs.cpp @@ -29,6 +29,7 @@ const char *MEDIA_MIMETYPE_AUDIO_AMR_NB = "audio/3gpp"; const char *MEDIA_MIMETYPE_AUDIO_AMR_WB = "audio/amr-wb"; const char *MEDIA_MIMETYPE_AUDIO_MPEG = "audio/mpeg"; const char *MEDIA_MIMETYPE_AUDIO_AAC = "audio/mp4a-latm"; +const char *MEDIA_MIMETYPE_AUDIO_QCELP = "audio/qcelp"; const char *MEDIA_MIMETYPE_AUDIO_RAW = "audio/raw"; const char *MEDIA_MIMETYPE_CONTAINER_MPEG4 = "video/mpeg4"; diff --git a/media/libstagefright/include/ESDS.h b/media/libstagefright/include/ESDS.h index 01bcd18..3a79951 100644 --- a/media/libstagefright/include/ESDS.h +++ b/media/libstagefright/include/ESDS.h @@ -31,6 +31,7 @@ public: status_t InitCheck() const; + status_t getObjectTypeIndication(uint8_t *objectTypeIndication) const; status_t getCodecSpecificInfo(const void **data, size_t *size) const; private: @@ -47,6 +48,7 @@ private: size_t mDecoderSpecificOffset; size_t mDecoderSpecificLength; + uint8_t mObjectTypeIndication; status_t skipDescriptorHeader( size_t offset, size_t size, -- cgit v1.1