Merge "Don't check mFilledBuffers whether it is empty or not when the port reconfiguration is not meant for buffer reallocation"
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 7509239..c2c6715 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -1078,6 +1078,11 @@
frames = mRemainingFrames;
}
+ int32_t waitCount = -1;
+ if (mUpdatePeriod || (!mMarkerReached && mMarkerPosition) || mLoopCount) {
+ waitCount = 1;
+ }
+
do {
audioBuffer.frameCount = frames;
@@ -1085,7 +1090,7 @@
// Calling obtainBuffer() with a wait count of 1
// limits wait time to WAIT_PERIOD_MS. This prevents from being
// stuck here not being able to handle timed events (position, markers, loops).
- status_t err = obtainBuffer(&audioBuffer, 1);
+ status_t err = obtainBuffer(&audioBuffer, waitCount);
if (err < NO_ERROR) {
if (err != TIMED_OUT) {
LOGE_IF(err != status_t(NO_MORE_BUFFERS), "Error obtaining an audio buffer, giving up.");
diff --git a/media/libmedia/IMediaPlayer.cpp b/media/libmedia/IMediaPlayer.cpp
index bd89ad8..50a41ca 100644
--- a/media/libmedia/IMediaPlayer.cpp
+++ b/media/libmedia/IMediaPlayer.cpp
@@ -108,6 +108,7 @@
Parcel data, reply;
data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
data.writeStrongBinder(source->asBinder());
+ remote()->transact(SET_DATA_SOURCE_STREAM, data, &reply);
return reply.readInt32();
}
diff --git a/media/libstagefright/AudioPlayer.cpp b/media/libstagefright/AudioPlayer.cpp
index d41ab1b..ba076f5 100644
--- a/media/libstagefright/AudioPlayer.cpp
+++ b/media/libstagefright/AudioPlayer.cpp
@@ -20,8 +20,8 @@
#include <binder/IPCThreadState.h>
#include <media/AudioTrack.h>
+#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/AudioPlayer.h>
-#include <media/stagefright/MediaDebug.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MediaSource.h>
@@ -60,7 +60,7 @@
}
void AudioPlayer::setSource(const sp<MediaSource> &source) {
- CHECK_EQ(mSource, NULL);
+ CHECK(mSource == NULL);
mSource = source;
}
@@ -466,6 +466,8 @@
}
int64_t AudioPlayer::getRealTimeUsLocked() const {
+ CHECK(mStarted);
+ CHECK_NE(mSampleRate, 0);
return -mLatencyUs + (mNumFramesPlayed * 1000000) / mSampleRate;
}
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 47224cc..07a46bd 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -1736,7 +1736,9 @@
modifyFlags(TEXT_RUNNING, SET);
}
- TimeSource *ts = (mFlags & AUDIO_AT_EOS) ? &mSystemTimeSource : mTimeSource;
+ TimeSource *ts =
+ ((mFlags & AUDIO_AT_EOS) || !(mFlags & AUDIOPLAYER_STARTED))
+ ? &mSystemTimeSource : mTimeSource;
if (mFlags & FIRST_FRAME) {
modifyFlags(FIRST_FRAME, CLEAR);
diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp
index 778c0b5..c74cb5a 100644
--- a/media/libstagefright/StagefrightMetadataRetriever.cpp
+++ b/media/libstagefright/StagefrightMetadataRetriever.cpp
@@ -283,8 +283,15 @@
return NULL;
}
+ sp<MetaData> fileMeta = mExtractor->getMetaData();
+
+ if (fileMeta == NULL) {
+ LOGV("extractor doesn't publish metadata, failed to initialize?");
+ return NULL;
+ }
+
int32_t drm = 0;
- if (mExtractor->getMetaData()->findInt32(kKeyIsDRM, &drm) && drm != 0) {
+ if (fileMeta->findInt32(kKeyIsDRM, &drm) && drm != 0) {
LOGE("frame grab not allowed.");
return NULL;
}
@@ -320,7 +327,7 @@
const void *data;
uint32_t type;
size_t dataSize;
- if (mExtractor->getMetaData()->findData(kKeyAlbumArt, &type, &data, &dataSize)
+ if (fileMeta->findData(kKeyAlbumArt, &type, &data, &dataSize)
&& mAlbumArt == NULL) {
mAlbumArt = new MediaAlbumArt;
mAlbumArt->mSize = dataSize;
@@ -387,6 +394,11 @@
void StagefrightMetadataRetriever::parseMetaData() {
sp<MetaData> meta = mExtractor->getMetaData();
+ if (meta == NULL) {
+ LOGV("extractor doesn't publish metadata, failed to initialize?");
+ return;
+ }
+
struct Map {
int from;
int to;
diff --git a/media/libstagefright/SurfaceMediaSource.cpp b/media/libstagefright/SurfaceMediaSource.cpp
index 50dd804..306f1f6 100644
--- a/media/libstagefright/SurfaceMediaSource.cpp
+++ b/media/libstagefright/SurfaceMediaSource.cpp
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-// #define LOG_NDEBUG 0
+//#define LOG_NDEBUG 0
#define LOG_TAG "SurfaceMediaSource"
#include <media/stagefright/SurfaceMediaSource.h>
@@ -458,6 +458,10 @@
LOGV("queueBuffer");
Mutex::Autolock lock(mMutex);
+ *outWidth = mDefaultWidth;
+ *outHeight = mDefaultHeight;
+ *outTransform = 0;
+
if (bufIndex < 0 || bufIndex >= mBufferCount) {
LOGE("queueBuffer: slot index out of range [0, %d]: %d",
mBufferCount, bufIndex);
@@ -518,9 +522,6 @@
// buffer is available
onFrameReceivedLocked();
- *outWidth = mDefaultWidth;
- *outHeight = mDefaultHeight;
- *outTransform = 0;
return OK;
}
diff --git a/media/libstagefright/matroska/MatroskaExtractor.cpp b/media/libstagefright/matroska/MatroskaExtractor.cpp
index 3ef7b71..ffa3356 100644
--- a/media/libstagefright/matroska/MatroskaExtractor.cpp
+++ b/media/libstagefright/matroska/MatroskaExtractor.cpp
@@ -93,7 +93,7 @@
void advance();
void reset();
- void seek(int64_t seekTimeUs);
+ void seek(int64_t seekTimeUs, bool seekToKeyFrame);
const mkvparser::Block *block() const;
int64_t blockTimeUs() const;
@@ -137,6 +137,7 @@
sp<MatroskaExtractor> mExtractor;
size_t mTrackIndex;
Type mType;
+ bool mIsAudio;
BlockIterator mBlockIter;
size_t mNALSizeLen; // for type AVC
@@ -156,6 +157,7 @@
: mExtractor(extractor),
mTrackIndex(index),
mType(OTHER),
+ mIsAudio(false),
mBlockIter(mExtractor.get(),
mExtractor->mTracks.itemAt(index).mTrackNum),
mNALSizeLen(0) {
@@ -164,6 +166,8 @@
const char *mime;
CHECK(meta->findCString(kKeyMIMEType, &mime));
+ mIsAudio = !strncasecmp("audio/", mime, 6);
+
if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
mType = AVC;
@@ -299,7 +303,7 @@
} while (!eos() && block()->GetTrackNumber() != mTrackNum);
}
-void BlockIterator::seek(int64_t seekTimeUs) {
+void BlockIterator::seek(int64_t seekTimeUs, bool seekToKeyFrame) {
Mutex::Autolock autoLock(mExtractor->mLock);
mCluster = mExtractor->mSegment->FindCluster(seekTimeUs * 1000ll);
@@ -311,8 +315,10 @@
}
while (!eos() && block()->GetTrackNumber() != mTrackNum);
- while (!eos() && !mBlockEntry->GetBlock()->IsKey()) {
- advance_l();
+ if (seekToKeyFrame) {
+ while (!eos() && !mBlockEntry->GetBlock()->IsKey()) {
+ advance_l();
+ }
}
}
@@ -396,7 +402,11 @@
if (options && options->getSeekTo(&seekTimeUs, &mode)
&& !mExtractor->isLiveStreaming()) {
clearPendingFrames();
- mBlockIter.seek(seekTimeUs);
+
+ // Apparently keyframe indication in audio tracks is unreliable,
+ // fortunately in all our currently supported audio encodings every
+ // frame is effectively a keyframe.
+ mBlockIter.seek(seekTimeUs, !mIsAudio);
}
again:
@@ -537,6 +547,13 @@
return;
}
+#if 0
+ const mkvparser::SegmentInfo *info = mSegment->GetInfo();
+ LOGI("muxing app: %s, writing app: %s",
+ info->GetMuxingAppAsUTF8(),
+ info->GetWritingAppAsUTF8());
+#endif
+
addTracks();
}
diff --git a/media/libstagefright/tests/SurfaceMediaSource_test.cpp b/media/libstagefright/tests/SurfaceMediaSource_test.cpp
index d663602..d7bb703 100644
--- a/media/libstagefright/tests/SurfaceMediaSource_test.cpp
+++ b/media/libstagefright/tests/SurfaceMediaSource_test.cpp
@@ -156,8 +156,6 @@
eglDestroySurface(mEglDisplay, mEglSurface);
}
if (mEglDisplay != EGL_NO_DISPLAY) {
- eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
- EGL_NO_CONTEXT);
eglTerminate(mEglDisplay);
}
ASSERT_EQ(EGL_SUCCESS, eglGetError());
@@ -461,6 +459,7 @@
// The following call dequeues and queues the buffer
eglSwapBuffers(mEglDisplay, mEglSurface);
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
glDisable(GL_SCISSOR_TEST);
}
@@ -796,7 +795,12 @@
LOGV("framesCount = %d", nFramesCount);
}
- ASSERT_EQ(NO_ERROR, native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_EGL));
+ EXPECT_TRUE(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
+ EGL_NO_CONTEXT));
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+ eglDestroySurface(mEglDisplay, mEglSurface);
+ mEglSurface = EGL_NO_SURFACE;
+
writer.stop();
}
// Test to examine whether we can render GL buffers in to the surface
@@ -875,7 +879,12 @@
LOGV("framesCount = %d", nFramesCount);
}
- ASSERT_EQ(NO_ERROR, native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_EGL));
+ EXPECT_TRUE(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
+ EGL_NO_CONTEXT));
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+ eglDestroySurface(mEglDisplay, mEglSurface);
+ mEglSurface = EGL_NO_SURFACE;
+
LOGV("Stopping MediaRecorder...");
CHECK_EQ(OK, mr->stop());
mr.clear();
@@ -913,7 +922,12 @@
LOGV("framesCount = %d", nFramesCount);
}
- ASSERT_EQ(NO_ERROR, native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_EGL));
+ EXPECT_TRUE(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
+ EGL_NO_CONTEXT));
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+ eglDestroySurface(mEglDisplay, mEglSurface);
+ mEglSurface = EGL_NO_SURFACE;
+
LOGV("Stopping MediaRecorder...");
CHECK_EQ(OK, mr->stop());
mr.clear();