Transcoder: Preserve source track's bitrate by default.
When no bitrate is passed in the transcoder now preserves the
source track's bitrate. If the bitrate is not available as metadata
the transcoder will sample the source track and estimate the bitrate.
Fixes: 160648740
Test: Unit tests.
Change-Id: I4e0284128aaa1116f5b61d908b52582b2ed3d7e4
diff --git a/media/libmediatranscoding/transcoder/tests/MediaSampleReaderNDKTests.cpp b/media/libmediatranscoding/transcoder/tests/MediaSampleReaderNDKTests.cpp
index 805095e..323e5ae 100644
--- a/media/libmediatranscoding/transcoder/tests/MediaSampleReaderNDKTests.cpp
+++ b/media/libmediatranscoding/transcoder/tests/MediaSampleReaderNDKTests.cpp
@@ -27,6 +27,8 @@
#include <media/MediaSampleReaderNDK.h>
#include <utils/Timers.h>
+#include <cmath>
+
// TODO(b/153453392): Test more asset types and validate sample data from readSampleDataForTrack.
namespace android {
@@ -70,6 +72,31 @@
mExtractorTimestamps[trackIndex].push_back(sampleTime);
} while (AMediaExtractor_advance(mExtractor));
+
+ AMediaExtractor_seekTo(mExtractor, 0, AMEDIAEXTRACTOR_SEEK_PREVIOUS_SYNC);
+ }
+
+ std::vector<int32_t> getTrackBitrates() {
+ size_t totalSize[mTrackCount];
+ memset(totalSize, 0, sizeof(totalSize));
+
+ do {
+ const int trackIndex = AMediaExtractor_getSampleTrackIndex(mExtractor);
+ totalSize[trackIndex] += AMediaExtractor_getSampleSize(mExtractor);
+ } while (AMediaExtractor_advance(mExtractor));
+
+ AMediaExtractor_seekTo(mExtractor, 0, AMEDIAEXTRACTOR_SEEK_PREVIOUS_SYNC);
+
+ std::vector<int32_t> bitrates;
+ for (int trackIndex = 0; trackIndex < mTrackCount; trackIndex++) {
+ int64_t durationUs;
+ AMediaFormat* trackFormat = AMediaExtractor_getTrackFormat(mExtractor, trackIndex);
+ EXPECT_NE(trackFormat, nullptr);
+ EXPECT_TRUE(AMediaFormat_getInt64(trackFormat, AMEDIAFORMAT_KEY_DURATION, &durationUs));
+ bitrates.push_back(roundf((float)totalSize[trackIndex] * 8 * 1000000 / durationUs));
+ }
+
+ return bitrates;
}
void TearDown() override {
@@ -141,6 +168,28 @@
}
}
+TEST_F(MediaSampleReaderNDKTests, TestEstimatedBitrateAccuracy) {
+ // Just put a somewhat reasonable upper bound on the estimated bitrate expected in our test
+ // assets. This is mostly to make sure the estimation is not way off.
+ static constexpr int32_t kMaxEstimatedBitrate = 100 * 1000 * 1000; // 100 Mbps
+
+ auto sampleReader = MediaSampleReaderNDK::createFromFd(mSourceFd, 0, mFileSize);
+ ASSERT_TRUE(sampleReader);
+
+ std::vector<int32_t> actualTrackBitrates = getTrackBitrates();
+ for (int trackIndex = 0; trackIndex < mTrackCount; ++trackIndex) {
+ int32_t bitrate;
+ EXPECT_EQ(sampleReader->getEstimatedBitrateForTrack(trackIndex, &bitrate), AMEDIA_OK);
+ EXPECT_GT(bitrate, 0);
+ EXPECT_LT(bitrate, kMaxEstimatedBitrate);
+
+ // Note: The test asset currently used in this test is shorter than the sampling duration
+ // used to estimate the bitrate in the sample reader. So for now the estimation should be
+ // exact but if/when a longer asset is used a reasonable delta needs to be defined.
+ EXPECT_EQ(bitrate, actualTrackBitrates[trackIndex]);
+ }
+}
+
TEST_F(MediaSampleReaderNDKTests, TestInvalidFd) {
std::shared_ptr<MediaSampleReader> sampleReader =
MediaSampleReaderNDK::createFromFd(0, 0, mFileSize);