diff options
Diffstat (limited to 'media/libstagefright/MPEG4Extractor.cpp')
-rwxr-xr-x | media/libstagefright/MPEG4Extractor.cpp | 76 |
1 files changed, 55 insertions, 21 deletions
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp index 9e7f298..80ef7b7 100755 --- a/media/libstagefright/MPEG4Extractor.cpp +++ b/media/libstagefright/MPEG4Extractor.cpp @@ -321,6 +321,12 @@ static const char *FourCC2MIME(uint32_t fourcc) { case FOURCC('m', 'p', '4', 'a'): return MEDIA_MIMETYPE_AUDIO_AAC; + case FOURCC('e', 'n', 'c', 'a'): + return MEDIA_MIMETYPE_AUDIO_AAC; + + case FOURCC('.', 'm', 'p', '3'): + return MEDIA_MIMETYPE_AUDIO_MPEG; + case FOURCC('s', 'a', 'm', 'r'): return MEDIA_MIMETYPE_AUDIO_AMR_NB; @@ -330,6 +336,9 @@ static const char *FourCC2MIME(uint32_t fourcc) { case FOURCC('m', 'p', '4', 'v'): return MEDIA_MIMETYPE_VIDEO_MPEG4; + case FOURCC('e', 'n', 'c', 'v'): + return MEDIA_MIMETYPE_VIDEO_MPEG4; + case FOURCC('s', '2', '6', '3'): case FOURCC('h', '2', '6', '3'): case FOURCC('H', '2', '6', '3'): @@ -1044,7 +1053,7 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { int64_t delay = (media_time * samplerate + 500000) / 1000000; mLastTrack->meta->setInt32(kKeyEncoderDelay, delay); - int64_t paddingus = duration - (segment_duration + media_time); + int64_t paddingus = duration - (int64_t)(segment_duration + media_time); if (paddingus < 0) { // track duration from media header (which is what kKeyDuration is) might // be slightly shorter than the segment duration, which would make the @@ -1373,7 +1382,14 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); off64_t stop_offset = *offset + chunk_size; - *offset = data_offset + sizeof(buffer); + if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_MPEG, FourCC2MIME(chunk_type)) || + !strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, FourCC2MIME(chunk_type))) { + // ESD is not required in mp3 + // amr wb with damr atom corrupted can cause the clip to not play + *offset = stop_offset; + } else { + *offset = data_offset + sizeof(buffer); + } while (*offset < stop_offset) { status_t err = parseChunk(offset, depth + 1); if (err != OK) { @@ -1612,13 +1628,21 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { return ERROR_MALFORMED; *offset += chunk_size; + // Ignore stss block for audio even if its present + // All audio sample are sync samples itself, + // self decodeable and playable. + // Parsing this block for audio restricts audio seek to few entries + // available in this block, sometimes 0, which is undesired. + const char *mime; + CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); + if (strncasecmp("audio/", mime, 6)) { + status_t err = + mLastTrack->sampleTable->setSyncSampleParams( + data_offset, chunk_data_size); - status_t err = - mLastTrack->sampleTable->setSyncSampleParams( - data_offset, chunk_data_size); - - if (err != OK) { - return err; + if (err != OK) { + return err; + } } break; @@ -1715,6 +1739,9 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { } } } + + updateVideoTrackInfoFromESDS_MPEG4Video(mLastTrack->meta); + break; } @@ -1984,6 +2011,9 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { return ERROR_IO; } + if (mLastTrack == NULL) + return ERROR_MALFORMED; + uint32_t type = ntohl(buffer); // For the 3GPP file format, the handler-type within the 'hdlr' box // shall be 'text'. We also want to support 'sbtl' handler type @@ -3010,12 +3040,12 @@ status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( return OK; } - if (objectTypeIndication == 0x6b) { - // The media subtype is MP3 audio - // Our software MP3 audio decoder may not be able to handle - // packetized MP3 audio; for now, lets just return ERROR_UNSUPPORTED - ALOGE("MP3 track in MP4/3GPP file is not supported"); - return ERROR_UNSUPPORTED; + if (objectTypeIndication == 0x6b + || objectTypeIndication == 0x69) { + // This is mpeg1/2 audio content, set mimetype to mpeg + mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG); + ALOGD("objectTypeIndication:0x%x, set mimetype to mpeg ",objectTypeIndication); + return OK; } const uint8_t *csd; @@ -3168,7 +3198,7 @@ status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( extensionFlag, objectType); } - if (numChannels == 0) { + if (numChannels == 0 && (br.numBitsLeft() > 0)) { int32_t channelsEffectiveNum = 0; int32_t channelsNum = 0; if (br.numBitsLeft() < 32) { @@ -3336,11 +3366,13 @@ MPEG4Source::MPEG4Source( const uint8_t *ptr = (const uint8_t *)data; - CHECK(size >= 7); - CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 - - // The number of bytes used to encode the length of a NAL unit. - mNALLengthSize = 1 + (ptr[4] & 3); + if (size < 7 || ptr[0] != 1) { + ALOGE("Invalid AVCC atom, size %zu, configurationVersion: %d", + size, ptr[0]); + } else { + // The number of bytes used to encode the length of a NAL unit. + mNALLengthSize = 1 + (ptr[4] & 3); + } } else if (mIsHEVC) { uint32_t type; const void *data; @@ -4661,7 +4693,9 @@ static bool LegacySniffMPEG4( return false; } - if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8) + if (!memcmp(header, "ftyp3g2a", 8) || !memcmp(header, "ftyp3g2b", 8) + || !memcmp(header, "ftyp3g2c", 8) + || !memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8) || !memcmp(header, "ftyp3gr6", 8) || !memcmp(header, "ftyp3gs6", 8) || !memcmp(header, "ftyp3ge6", 8) || !memcmp(header, "ftyp3gg6", 8) || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8) |