diff options
author | Lajos Molnar <lajos@google.com> | 2014-03-19 03:15:12 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2014-03-19 03:15:12 +0000 |
commit | 129c76538570cd42fce2154bfb0aec934cf84ff3 (patch) | |
tree | e83ec23188412392940089494187011f15aee1b8 | |
parent | 49b2e310f62c590a1af9f921cd8a134cdf589263 (diff) | |
parent | 9cde517297827156de1c3b2ff54e272a5d4ae7c3 (diff) | |
download | frameworks_av-129c76538570cd42fce2154bfb0aec934cf84ff3.zip frameworks_av-129c76538570cd42fce2154bfb0aec934cf84ff3.tar.gz frameworks_av-129c76538570cd42fce2154bfb0aec934cf84ff3.tar.bz2 |
am 9cde5172: am b635b0e6: mediaplayer: keep more buffers with the BufferQueue
* commit '9cde517297827156de1c3b2ff54e272a5d4ae7c3':
mediaplayer: keep more buffers with the BufferQueue
-rw-r--r-- | include/media/stagefright/ACodec.h | 1 | ||||
-rw-r--r-- | media/libstagefright/ACodec.cpp | 47 | ||||
-rw-r--r-- | media/libstagefright/OMXCodec.cpp | 38 |
3 files changed, 56 insertions, 30 deletions
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h index 7ba5acc..c4f8c36 100644 --- a/include/media/stagefright/ACodec.h +++ b/include/media/stagefright/ACodec.h @@ -203,6 +203,7 @@ private: unsigned mDequeueCounter; bool mStoreMetaDataInOutputBuffers; int32_t mMetaDataBuffersToSubmit; + size_t mNumUndequeuedBuffers; int64_t mRepeatFrameDelayUs; int64_t mMaxPtsGapUs; diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index 6dcedca..fc9bee7 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -640,18 +640,33 @@ status_t ACodec::configureOutputBuffersFromNativeWindow( return err; } - // XXX: Is this the right logic to use? It's not clear to me what the OMX - // buffer counts refer to - how do they account for the renderer holding on - // to buffers? - if (def.nBufferCountActual < def.nBufferCountMin + *minUndequeuedBuffers) { - OMX_U32 newBufferCount = def.nBufferCountMin + *minUndequeuedBuffers; + // FIXME: assume that surface is controlled by app (native window + // returns the number for the case when surface is not controlled by app) + (*minUndequeuedBuffers)++; + + + // Use conservative allocation while also trying to reduce starvation + // + // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the + // minimum needed for the consumer to be able to work + // 2. try to allocate two (2) additional buffers to reduce starvation from + // the consumer + for (OMX_U32 extraBuffers = 2; /* condition inside loop */; extraBuffers--) { + OMX_U32 newBufferCount = + def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers; def.nBufferCountActual = newBufferCount; err = mOMX->setParameter( mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); - if (err != OK) { - ALOGE("[%s] setting nBufferCountActual to %lu failed: %d", - mComponentName.c_str(), newBufferCount, err); + if (err == OK) { + *minUndequeuedBuffers += extraBuffers; + break; + } + + ALOGW("[%s] setting nBufferCountActual to %lu failed: %d", + mComponentName.c_str(), newBufferCount, err); + /* exit condition */ + if (extraBuffers == 0) { return err; } } @@ -676,6 +691,7 @@ status_t ACodec::allocateOutputBuffersFromNativeWindow() { &bufferCount, &bufferSize, &minUndequeuedBuffers); if (err != 0) return err; + mNumUndequeuedBuffers = minUndequeuedBuffers; ALOGV("[%s] Allocating %lu buffers from a native window of size %lu on " "output port", @@ -741,6 +757,7 @@ status_t ACodec::allocateOutputMetaDataBuffers() { &bufferCount, &bufferSize, &minUndequeuedBuffers); if (err != 0) return err; + mNumUndequeuedBuffers = minUndequeuedBuffers; ALOGV("[%s] Allocating %lu meta buffers on output port", mComponentName.c_str(), bufferCount); @@ -2482,19 +2499,7 @@ void ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() { return; } - int minUndequeuedBufs = 0; - status_t err = mNativeWindow->query( - mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, - &minUndequeuedBufs); - - if (err != OK) { - ALOGE("[%s] NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)", - mComponentName.c_str(), strerror(-err), -err); - - minUndequeuedBufs = 0; - } - - while (countBuffersOwnedByNativeWindow() > (size_t)minUndequeuedBufs + while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers && dequeueBufferFromNativeWindow() != NULL) { // these buffers will be submitted as regular buffers; account for this if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) { diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index 625922f..4c460bd 100644 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -94,6 +94,7 @@ static sp<MediaSource> InstantiateSoftwareEncoder( #define CODEC_LOGI(x, ...) ALOGI("[%s] "x, mComponentName, ##__VA_ARGS__) #define CODEC_LOGV(x, ...) ALOGV("[%s] "x, mComponentName, ##__VA_ARGS__) +#define CODEC_LOGW(x, ...) ALOGW("[%s] "x, mComponentName, ##__VA_ARGS__) #define CODEC_LOGE(x, ...) ALOGE("[%s] "x, mComponentName, ##__VA_ARGS__) struct OMXCodecObserver : public BnOMXObserver { @@ -1794,21 +1795,40 @@ status_t OMXCodec::allocateOutputBuffersFromNativeWindow() { strerror(-err), -err); return err; } - - // XXX: Is this the right logic to use? It's not clear to me what the OMX - // buffer counts refer to - how do they account for the renderer holding on - // to buffers? - if (def.nBufferCountActual < def.nBufferCountMin + minUndequeuedBufs) { - OMX_U32 newBufferCount = def.nBufferCountMin + minUndequeuedBufs; + // FIXME: assume that surface is controlled by app (native window + // returns the number for the case when surface is not controlled by app) + minUndequeuedBufs++; + + // Use conservative allocation while also trying to reduce starvation + // + // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the + // minimum needed for the consumer to be able to work + // 2. try to allocate two (2) additional buffers to reduce starvation from + // the consumer + CODEC_LOGI("OMX-buffers: min=%u actual=%u undeq=%d", + def.nBufferCountMin, def.nBufferCountActual, minUndequeuedBufs); + + for (OMX_U32 extraBuffers = 2; /* condition inside loop */; extraBuffers--) { + OMX_U32 newBufferCount = + def.nBufferCountMin + minUndequeuedBufs + extraBuffers; def.nBufferCountActual = newBufferCount; err = mOMX->setParameter( mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); - if (err != OK) { - CODEC_LOGE("setting nBufferCountActual to %lu failed: %d", - newBufferCount, err); + + if (err == OK) { + minUndequeuedBufs += extraBuffers; + break; + } + + CODEC_LOGW("setting nBufferCountActual to %lu failed: %d", + newBufferCount, err); + /* exit condition */ + if (extraBuffers == 0) { return err; } } + CODEC_LOGI("OMX-buffers: min=%u actual=%u undeq=%d", + def.nBufferCountMin, def.nBufferCountActual, minUndequeuedBufs); err = native_window_set_buffer_count( mNativeWindow.get(), def.nBufferCountActual); |