Fix seek handling in AAC and AMR extractors
AAC and AMR encoders were treating all seek operations as SEEK_PREVIOUS_SYNC
Bug: 179062958
Test: atest ExtractorUnitTest -- --enable-module-dynamic-download=true
Change-Id: Ic0dc0824ffa9998d72c750ca0d0a24c8dcc3c8a8
diff --git a/media/extractors/aac/AACExtractor.cpp b/media/extractors/aac/AACExtractor.cpp
index 8f60f6b..2fc4584 100644
--- a/media/extractors/aac/AACExtractor.cpp
+++ b/media/extractors/aac/AACExtractor.cpp
@@ -18,6 +18,8 @@
#define LOG_TAG "AACExtractor"
#include <utils/Log.h>
+#include <inttypes.h>
+
#include "AACExtractor.h"
#include <media/MediaExtractorPluginApi.h>
#include <media/stagefright/foundation/ABuffer.h>
@@ -277,7 +279,22 @@
ReadOptions::SeekMode mode;
if (options && options->getSeekTo(&seekTimeUs, &mode)) {
if (mFrameDurationUs > 0) {
- int64_t seekFrame = seekTimeUs / mFrameDurationUs;
+ int64_t seekFrame = 0;
+ switch(mode & 0x7) {
+ case ReadOptions::SEEK_NEXT_SYNC:
+ // "at or after"
+ seekFrame = (seekTimeUs + mFrameDurationUs - 1) / mFrameDurationUs;
+ break;
+ case ReadOptions::SEEK_CLOSEST_SYNC:
+ case ReadOptions::SEEK_CLOSEST:
+ seekFrame = (seekTimeUs + mFrameDurationUs/2) / mFrameDurationUs;
+ break;
+ case ReadOptions::SEEK_PREVIOUS_SYNC:
+ default:
+ // 'at or before'
+ seekFrame = seekTimeUs / mFrameDurationUs;
+ break;
+ }
if (seekFrame < 0 || seekFrame >= (int64_t)mOffsetVector.size()) {
android_errorWriteLog(0x534e4554, "70239507");
return AMEDIA_ERROR_MALFORMED;
diff --git a/media/extractors/amr/AMRExtractor.cpp b/media/extractors/amr/AMRExtractor.cpp
index 26431a4..e26ff0a 100644
--- a/media/extractors/amr/AMRExtractor.cpp
+++ b/media/extractors/amr/AMRExtractor.cpp
@@ -18,6 +18,8 @@
#define LOG_TAG "AMRExtractor"
#include <utils/Log.h>
+#include <inttypes.h>
+
#include "AMRExtractor.h"
#include <media/stagefright/foundation/ADebug.h>
@@ -283,8 +285,22 @@
ReadOptions::SeekMode mode;
if (mOffsetTableLength > 0 && options && options->getSeekTo(&seekTimeUs, &mode)) {
size_t size;
- int64_t seekFrame = seekTimeUs / 20000LL; // 20ms per frame.
- mCurrentTimeUs = seekFrame * 20000LL;
+ const int64_t frameDurationUs = 20000LL; // 20ms per frame.
+ int64_t seekFrame = 0;
+ switch(mode & 0x7) {
+ case ReadOptions::SEEK_NEXT_SYNC:
+ seekFrame = (seekTimeUs + frameDurationUs - 1) / frameDurationUs;
+ break;
+ case ReadOptions::SEEK_CLOSEST_SYNC:
+ case ReadOptions::SEEK_CLOSEST:
+ seekFrame = (seekTimeUs + frameDurationUs/2) / frameDurationUs;
+ break;
+ case ReadOptions::SEEK_PREVIOUS_SYNC:
+ default:
+ seekFrame = seekTimeUs / frameDurationUs;
+ break;
+ }
+ mCurrentTimeUs = seekFrame * frameDurationUs;
size_t index = seekFrame < 0 ? 0 : seekFrame / 50;
if (index >= mOffsetTableLength) {