Fix multiple-track mkv files
Structures stored in Vector might have their destructor called when
the Vector needs to be extended, so ensure we handle that correctly.
Bug: 128371202
Change-Id: I6eeb4aa67edaa63e0068f6102457f693f63768bc
diff --git a/media/extractors/mkv/MatroskaExtractor.cpp b/media/extractors/mkv/MatroskaExtractor.cpp
index 20cc643..d6d24c1 100644
--- a/media/extractors/mkv/MatroskaExtractor.cpp
+++ b/media/extractors/mkv/MatroskaExtractor.cpp
@@ -1336,6 +1336,13 @@
mReader = NULL;
delete mDataSource;
+
+ for (size_t i = 0; i < mTracks.size(); ++i) {
+ TrackInfo *info = &mTracks.editItemAt(i);
+ if (info->mMeta) {
+ AMediaFormat_delete(info->mMeta);
+ }
+ }
}
size_t MatroskaExtractor::countTracks() {
@@ -1808,6 +1815,8 @@
void MatroskaExtractor::addTracks() {
const mkvparser::Tracks *tracks = mSegment->GetTracks();
+ AMediaFormat *meta = nullptr;
+
for (size_t index = 0; index < tracks->GetTracksCount(); ++index) {
const mkvparser::Track *track = tracks->GetTrackByIndex(index);
@@ -1832,7 +1841,11 @@
enum { VIDEO_TRACK = 1, AUDIO_TRACK = 2 };
- AMediaFormat *meta = AMediaFormat_new();
+ if (meta) {
+ AMediaFormat_clear(meta);
+ } else {
+ meta = AMediaFormat_new();
+ }
status_t err = OK;
int32_t nalSize = -1;
@@ -2067,21 +2080,26 @@
long long durationNs = mSegment->GetDuration();
AMediaFormat_setInt64(meta, AMEDIAFORMAT_KEY_DURATION, (durationNs + 500) / 1000);
+ const char *mimetype = "";
+ if (!AMediaFormat_getString(meta, AMEDIAFORMAT_KEY_MIME, &mimetype)) {
+ // do not add this track to the track list
+ ALOGW("ignoring track with unknown mime");
+ continue;
+ }
+
mTracks.push();
size_t n = mTracks.size() - 1;
TrackInfo *trackInfo = &mTracks.editItemAt(n);
initTrackInfo(track, meta, trackInfo);
trackInfo->mNalLengthSize = nalSize;
- const char *mimetype = "";
- AMediaFormat_getString(meta, AMEDIAFORMAT_KEY_MIME, &mimetype);
-
if ((!strcmp("V_MPEG4/ISO/AVC", codecID) && codecPrivateSize == 0) ||
(!strcmp(mimetype, MEDIA_MIMETYPE_VIDEO_AVC) && isSetCsdFrom1stFrame)) {
// Attempt to recover from AVC track without codec private data
err = synthesizeAVCC(trackInfo, n);
if (err != OK) {
mTracks.pop();
+ continue;
}
} else if ((!strcmp("V_MPEG2", codecID) && codecPrivateSize == 0) ||
(!strcmp(mimetype, MEDIA_MIMETYPE_VIDEO_MPEG2) && isSetCsdFrom1stFrame)) {
@@ -2089,6 +2107,7 @@
err = synthesizeMPEG2(trackInfo, n);
if (err != OK) {
mTracks.pop();
+ continue;
}
} else if ((!strcmp("V_MPEG4/ISO/ASP", codecID) && codecPrivateSize == 0) ||
(!strcmp(mimetype, MEDIA_MIMETYPE_VIDEO_MPEG4) && isSetCsdFrom1stFrame) ||
@@ -2099,9 +2118,14 @@
err = synthesizeMPEG4(trackInfo, n);
if (err != OK) {
mTracks.pop();
+ continue;
}
}
-
+ // the TrackInfo owns the metadata now
+ meta = nullptr;
+ }
+ if (meta) {
+ AMediaFormat_delete(meta);
}
}
diff --git a/media/extractors/mkv/MatroskaExtractor.h b/media/extractors/mkv/MatroskaExtractor.h
index d53d9e3..99fad17 100644
--- a/media/extractors/mkv/MatroskaExtractor.h
+++ b/media/extractors/mkv/MatroskaExtractor.h
@@ -61,10 +61,8 @@
TrackInfo() {
mMeta = NULL;
}
+
~TrackInfo() {
- if (mMeta) {
- AMediaFormat_delete(mMeta);
- }
}
unsigned long mTrackNum;
bool mEncrypted;