summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJamie Gennis <jgennis@google.com>2011-07-22 16:24:03 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2011-07-22 16:24:03 -0700
commitbbb85c8e4e4e67f4fa018694b587fd3228b0d1b2 (patch)
tree1eb340996b65cd6f2af43be135691e78aba37200
parent5bae58dff90025dd1419bd7508d17bbd32c26beb (diff)
parent5ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9 (diff)
downloadframeworks_base-bbb85c8e4e4e67f4fa018694b587fd3228b0d1b2.zip
frameworks_base-bbb85c8e4e4e67f4fa018694b587fd3228b0d1b2.tar.gz
frameworks_base-bbb85c8e4e4e67f4fa018694b587fd3228b0d1b2.tar.bz2
Merge changes Ibd261f7b,Ifdd234ef,I0e2f0bc3
* changes: SurfaceTexture: add the abandon method. SurfaceTexture: add a deadlock scenario test SurfaceMediaSource: remove getAllocator method
-rw-r--r--include/gui/ISurfaceTexture.h2
-rw-r--r--include/gui/SurfaceTexture.h20
-rw-r--r--include/media/stagefright/SurfaceMediaSource.h9
-rw-r--r--libs/gui/ISurfaceTexture.cpp14
-rw-r--r--libs/gui/SurfaceTexture.cpp83
-rw-r--r--libs/gui/SurfaceTextureClient.cpp9
-rw-r--r--libs/gui/tests/SurfaceTexture_test.cpp151
-rw-r--r--media/libstagefright/SurfaceMediaSource.cpp19
8 files changed, 264 insertions, 43 deletions
diff --git a/include/gui/ISurfaceTexture.h b/include/gui/ISurfaceTexture.h
index 405a25a..1eda646 100644
--- a/include/gui/ISurfaceTexture.h
+++ b/include/gui/ISurfaceTexture.h
@@ -51,7 +51,7 @@ protected:
// the given slot index, and the client is expected to mirror the
// slot->buffer mapping so that it's not necessary to transfer a
// GraphicBuffer for every dequeue operation.
- virtual sp<GraphicBuffer> requestBuffer(int slot) = 0;
+ virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) = 0;
// setBufferCount sets the number of buffer slots available. Calling this
// will also cause all buffer slots to be emptied. The caller should empty
diff --git a/include/gui/SurfaceTexture.h b/include/gui/SurfaceTexture.h
index 62ea943..134c208 100644
--- a/include/gui/SurfaceTexture.h
+++ b/include/gui/SurfaceTexture.h
@@ -69,7 +69,7 @@ public:
// SurfaceTexture object (i.e. they are not owned by the client).
virtual status_t setBufferCount(int bufferCount);
- virtual sp<GraphicBuffer> requestBuffer(int buf);
+ virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf);
// dequeueBuffer gets the next buffer slot index for the client to use. If a
// buffer slot is available then that slot index is written to the location
@@ -190,6 +190,17 @@ public:
// getCurrentScalingMode returns the scaling mode of the current buffer
uint32_t getCurrentScalingMode() const;
+ // abandon frees all the buffers and puts the SurfaceTexture into the
+ // 'abandoned' state. Once put in this state the SurfaceTexture can never
+ // leave it. When in the 'abandoned' state, all methods of the
+ // ISurfaceTexture interface will fail with the NO_INIT error.
+ //
+ // Note that while calling this method causes all the buffers to be freed
+ // from the perspective of the the SurfaceTexture, if there are additional
+ // references on the buffers (e.g. if a buffer is referenced by a client or
+ // by OpenGL ES as a texture) then those buffer will remain allocated.
+ void abandon();
+
// dump our state in a String
void dump(String8& result) const;
void dump(String8& result, const char* prefix, char* buffer, size_t SIZE) const;
@@ -411,6 +422,13 @@ private:
typedef Vector<int> Fifo;
Fifo mQueue;
+ // mAbandoned indicates that the SurfaceTexture will no longer be used to
+ // consume images buffers pushed to it using the ISurfaceTexture interface.
+ // It is initialized to false, and set to true in the abandon method. A
+ // SurfaceTexture that has been abandoned will return the NO_INIT error from
+ // all ISurfaceTexture methods capable of returning an error.
+ bool mAbandoned;
+
// mMutex is the mutex used to prevent concurrent access to the member
// variables of SurfaceTexture objects. It must be locked whenever the
// member variables are accessed.
diff --git a/include/media/stagefright/SurfaceMediaSource.h b/include/media/stagefright/SurfaceMediaSource.h
index e1852ec..4251ba9 100644
--- a/include/media/stagefright/SurfaceMediaSource.h
+++ b/include/media/stagefright/SurfaceMediaSource.h
@@ -81,7 +81,7 @@ public:
// SurfaceMediaSource object (i.e. they are not owned by the client).
virtual status_t setBufferCount(int bufferCount);
- virtual sp<GraphicBuffer> requestBuffer(int buf);
+ virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf);
// dequeueBuffer gets the next buffer slot index for the client to use. If a
// buffer slot is available then that slot index is written to the location
@@ -163,13 +163,6 @@ public:
// when a new frame becomes available.
void setFrameAvailableListener(const sp<FrameAvailableListener>& listener);
- // getAllocator retrieves the binder object that must be referenced as long
- // as the GraphicBuffers dequeued from this SurfaceMediaSource are referenced.
- // Holding this binder reference prevents SurfaceFlinger from freeing the
- // buffers before the client is done with them.
- sp<IBinder> getAllocator();
-
-
// getCurrentBuffer returns the buffer associated with the current image.
sp<GraphicBuffer> getCurrentBuffer() const;
diff --git a/libs/gui/ISurfaceTexture.cpp b/libs/gui/ISurfaceTexture.cpp
index c9c7397..55246dc 100644
--- a/libs/gui/ISurfaceTexture.cpp
+++ b/libs/gui/ISurfaceTexture.cpp
@@ -54,18 +54,18 @@ public:
{
}
- virtual sp<GraphicBuffer> requestBuffer(int bufferIdx) {
+ virtual status_t requestBuffer(int bufferIdx, sp<GraphicBuffer>* buf) {
Parcel data, reply;
data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
data.writeInt32(bufferIdx);
remote()->transact(REQUEST_BUFFER, data, &reply);
- sp<GraphicBuffer> buffer;
bool nonNull = reply.readInt32();
if (nonNull) {
- buffer = new GraphicBuffer();
- reply.read(*buffer);
+ *buf = new GraphicBuffer();
+ reply.read(**buf);
}
- return buffer;
+ status_t result = reply.readInt32();
+ return result;
}
virtual status_t setBufferCount(int bufferCount)
@@ -192,11 +192,13 @@ status_t BnSurfaceTexture::onTransact(
case REQUEST_BUFFER: {
CHECK_INTERFACE(ISurfaceTexture, data, reply);
int bufferIdx = data.readInt32();
- sp<GraphicBuffer> buffer(requestBuffer(bufferIdx));
+ sp<GraphicBuffer> buffer;
+ int result = requestBuffer(bufferIdx, &buffer);
reply->writeInt32(buffer != 0);
if (buffer != 0) {
reply->write(*buffer);
}
+ reply->writeInt32(result);
return NO_ERROR;
} break;
case SET_BUFFER_COUNT: {
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index 54d963f..c190195 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -94,7 +94,8 @@ SurfaceTexture::SurfaceTexture(GLuint tex, bool allowSynchronousMode) :
mTexName(tex),
mSynchronousMode(false),
mAllowSynchronousMode(allowSynchronousMode),
- mConnectedApi(NO_CONNECTED_API) {
+ mConnectedApi(NO_CONNECTED_API),
+ mAbandoned(false) {
LOGV("SurfaceTexture::SurfaceTexture");
sp<ISurfaceComposer> composer(ComposerService::getComposerService());
mGraphicBufferAlloc = composer->createGraphicBufferAlloc();
@@ -150,6 +151,11 @@ status_t SurfaceTexture::setBufferCount(int bufferCount) {
LOGV("SurfaceTexture::setBufferCount");
Mutex::Autolock lock(mMutex);
+ if (mAbandoned) {
+ LOGE("setBufferCount: SurfaceTexture has been abandoned!");
+ return NO_INIT;
+ }
+
if (bufferCount > NUM_BUFFER_SLOTS) {
LOGE("setBufferCount: bufferCount larger than slots available");
return BAD_VALUE;
@@ -199,22 +205,32 @@ status_t SurfaceTexture::setDefaultBufferSize(uint32_t w, uint32_t h)
return OK;
}
-sp<GraphicBuffer> SurfaceTexture::requestBuffer(int buf) {
+status_t SurfaceTexture::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
LOGV("SurfaceTexture::requestBuffer");
Mutex::Autolock lock(mMutex);
- if (buf < 0 || mBufferCount <= buf) {
+ if (mAbandoned) {
+ LOGE("requestBuffer: SurfaceTexture has been abandoned!");
+ return NO_INIT;
+ }
+ if (slot < 0 || mBufferCount <= slot) {
LOGE("requestBuffer: slot index out of range [0, %d]: %d",
- mBufferCount, buf);
- return 0;
+ mBufferCount, slot);
+ return BAD_VALUE;
}
- mSlots[buf].mRequestBufferCalled = true;
- return mSlots[buf].mGraphicBuffer;
+ mSlots[slot].mRequestBufferCalled = true;
+ *buf = mSlots[slot].mGraphicBuffer;
+ return NO_ERROR;
}
status_t SurfaceTexture::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
uint32_t format, uint32_t usage) {
LOGV("SurfaceTexture::dequeueBuffer");
+ if (mAbandoned) {
+ LOGE("dequeueBuffer: SurfaceTexture has been abandoned!");
+ return NO_INIT;
+ }
+
if ((w && !h) || (!w && h)) {
LOGE("dequeueBuffer: invalid size: w=%u, h=%u", w, h);
return BAD_VALUE;
@@ -252,6 +268,11 @@ status_t SurfaceTexture::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
// wait for the FIFO to drain
while (!mQueue.isEmpty()) {
mDequeueCondition.wait(mMutex);
+ if (mAbandoned) {
+ LOGE("dequeueBuffer: SurfaceTexture was abandoned while "
+ "blocked!");
+ return NO_INIT;
+ }
}
minBufferCountNeeded = mSynchronousMode ?
MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS;
@@ -380,6 +401,11 @@ status_t SurfaceTexture::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
status_t SurfaceTexture::setSynchronousMode(bool enabled) {
Mutex::Autolock lock(mMutex);
+ if (mAbandoned) {
+ LOGE("setSynchronousMode: SurfaceTexture has been abandoned!");
+ return NO_INIT;
+ }
+
status_t err = OK;
if (!mAllowSynchronousMode && enabled)
return err;
@@ -410,6 +436,10 @@ status_t SurfaceTexture::queueBuffer(int buf, int64_t timestamp,
{ // scope for the lock
Mutex::Autolock lock(mMutex);
+ if (mAbandoned) {
+ LOGE("queueBuffer: SurfaceTexture has been abandoned!");
+ return NO_INIT;
+ }
if (buf < 0 || buf >= mBufferCount) {
LOGE("queueBuffer: slot index out of range [0, %d]: %d",
mBufferCount, buf);
@@ -475,6 +505,12 @@ status_t SurfaceTexture::queueBuffer(int buf, int64_t timestamp,
void SurfaceTexture::cancelBuffer(int buf) {
LOGV("SurfaceTexture::cancelBuffer");
Mutex::Autolock lock(mMutex);
+
+ if (mAbandoned) {
+ LOGW("cancelBuffer: SurfaceTexture has been abandoned!");
+ return;
+ }
+
if (buf < 0 || buf >= mBufferCount) {
LOGE("cancelBuffer: slot index out of range [0, %d]: %d",
mBufferCount, buf);
@@ -491,6 +527,10 @@ void SurfaceTexture::cancelBuffer(int buf) {
status_t SurfaceTexture::setCrop(const Rect& crop) {
LOGV("SurfaceTexture::setCrop");
Mutex::Autolock lock(mMutex);
+ if (mAbandoned) {
+ LOGE("setCrop: SurfaceTexture has been abandoned!");
+ return NO_INIT;
+ }
mNextCrop = crop;
return OK;
}
@@ -498,6 +538,10 @@ status_t SurfaceTexture::setCrop(const Rect& crop) {
status_t SurfaceTexture::setTransform(uint32_t transform) {
LOGV("SurfaceTexture::setTransform");
Mutex::Autolock lock(mMutex);
+ if (mAbandoned) {
+ LOGE("setTransform: SurfaceTexture has been abandoned!");
+ return NO_INIT;
+ }
mNextTransform = transform;
return OK;
}
@@ -505,6 +549,12 @@ status_t SurfaceTexture::setTransform(uint32_t transform) {
status_t SurfaceTexture::connect(int api) {
LOGV("SurfaceTexture::connect(this=%p, %d)", this, api);
Mutex::Autolock lock(mMutex);
+
+ if (mAbandoned) {
+ LOGE("connect: SurfaceTexture has been abandoned!");
+ return NO_INIT;
+ }
+
int err = NO_ERROR;
switch (api) {
case NATIVE_WINDOW_API_EGL:
@@ -529,6 +579,12 @@ status_t SurfaceTexture::connect(int api) {
status_t SurfaceTexture::disconnect(int api) {
LOGV("SurfaceTexture::disconnect(this=%p, %d)", this, api);
Mutex::Autolock lock(mMutex);
+
+ if (mAbandoned) {
+ LOGE("connect: SurfaceTexture has been abandoned!");
+ return NO_INIT;
+ }
+
int err = NO_ERROR;
switch (api) {
case NATIVE_WINDOW_API_EGL:
@@ -837,6 +893,12 @@ uint32_t SurfaceTexture::getCurrentScalingMode() const {
int SurfaceTexture::query(int what, int* outValue)
{
Mutex::Autolock lock(mMutex);
+
+ if (mAbandoned) {
+ LOGE("query: SurfaceTexture has been abandoned!");
+ return NO_INIT;
+ }
+
int value;
switch (what) {
case NATIVE_WINDOW_WIDTH:
@@ -863,6 +925,13 @@ int SurfaceTexture::query(int what, int* outValue)
return NO_ERROR;
}
+void SurfaceTexture::abandon() {
+ Mutex::Autolock lock(mMutex);
+ freeAllBuffers();
+ mAbandoned = true;
+ mDequeueCondition.signal();
+}
+
void SurfaceTexture::dump(String8& result) const
{
char buffer[1024];
diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp
index 688b99b..df0ad5a 100644
--- a/libs/gui/SurfaceTextureClient.cpp
+++ b/libs/gui/SurfaceTextureClient.cpp
@@ -148,10 +148,11 @@ int SurfaceTextureClient::dequeueBuffer(android_native_buffer_t** buffer) {
}
if ((result & ISurfaceTexture::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) {
- gbuf = mSurfaceTexture->requestBuffer(buf);
- if (gbuf == 0) {
- LOGE("dequeueBuffer: ISurfaceTexture::requestBuffer failed");
- return NO_MEMORY;
+ result = mSurfaceTexture->requestBuffer(buf, &gbuf);
+ if (result != NO_ERROR) {
+ LOGE("dequeueBuffer: ISurfaceTexture::requestBuffer failed: %d",
+ result);
+ return result;
}
mQueryWidth = gbuf->width;
mQueryHeight = gbuf->height;
diff --git a/libs/gui/tests/SurfaceTexture_test.cpp b/libs/gui/tests/SurfaceTexture_test.cpp
index 9abe89d..0fac6cd 100644
--- a/libs/gui/tests/SurfaceTexture_test.cpp
+++ b/libs/gui/tests/SurfaceTexture_test.cpp
@@ -1018,6 +1018,83 @@ TEST_F(SurfaceTextureGLTest, DISABLED_TexturingFromGLFilledRGBABufferPow2) {
EXPECT_TRUE(checkPixel( 3, 52, 153, 153, 153, 153));
}
+TEST_F(SurfaceTextureGLTest, AbandonUnblocksDequeueBuffer) {
+ class ProducerThread : public Thread {
+ public:
+ ProducerThread(const sp<ANativeWindow>& anw):
+ mANW(anw),
+ mDequeueError(NO_ERROR) {
+ }
+
+ virtual ~ProducerThread() {
+ }
+
+ virtual bool threadLoop() {
+ Mutex::Autolock lock(mMutex);
+ ANativeWindowBuffer* anb;
+
+ // Frame 1
+ if (mANW->dequeueBuffer(mANW.get(), &anb) != NO_ERROR) {
+ return false;
+ }
+ if (anb == NULL) {
+ return false;
+ }
+ if (mANW->queueBuffer(mANW.get(), anb)
+ != NO_ERROR) {
+ return false;
+ }
+
+ // Frame 2
+ if (mANW->dequeueBuffer(mANW.get(), &anb) != NO_ERROR) {
+ return false;
+ }
+ if (anb == NULL) {
+ return false;
+ }
+ if (mANW->queueBuffer(mANW.get(), anb)
+ != NO_ERROR) {
+ return false;
+ }
+
+ // Frame 3 - error expected
+ mDequeueError = mANW->dequeueBuffer(mANW.get(), &anb);
+ return false;
+ }
+
+ status_t getDequeueError() {
+ Mutex::Autolock lock(mMutex);
+ return mDequeueError;
+ }
+
+ private:
+ sp<ANativeWindow> mANW;
+ status_t mDequeueError;
+ Mutex mMutex;
+ };
+
+ sp<FrameWaiter> fw(new FrameWaiter);
+ mST->setFrameAvailableListener(fw);
+ ASSERT_EQ(OK, mST->setSynchronousMode(true));
+ ASSERT_EQ(OK, mST->setBufferCountServer(2));
+
+ sp<Thread> pt(new ProducerThread(mANW));
+ pt->run();
+
+ fw->waitForFrame();
+ fw->waitForFrame();
+
+ // Sleep for 100ms to allow the producer thread's dequeueBuffer call to
+ // block waiting for a buffer to become available.
+ usleep(100000);
+
+ mST->abandon();
+
+ pt->requestExitAndWait();
+ ASSERT_EQ(NO_INIT,
+ reinterpret_cast<ProducerThread*>(pt.get())->getDequeueError());
+}
+
/*
* This test is for testing GL -> GL texture streaming via SurfaceTexture. It
* contains functionality to create a producer thread that will perform GL
@@ -1205,7 +1282,7 @@ protected:
sp<FrameCondition> mFC;
};
-TEST_F(SurfaceTextureGLToGLTest, UpdateTexImageBeforeFrameFinishedWorks) {
+TEST_F(SurfaceTextureGLToGLTest, UpdateTexImageBeforeFrameFinishedCompletes) {
class PT : public ProducerThread {
virtual void render() {
glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
@@ -1223,7 +1300,7 @@ TEST_F(SurfaceTextureGLToGLTest, UpdateTexImageBeforeFrameFinishedWorks) {
// TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
}
-TEST_F(SurfaceTextureGLToGLTest, UpdateTexImageAfterFrameFinishedWorks) {
+TEST_F(SurfaceTextureGLToGLTest, UpdateTexImageAfterFrameFinishedCompletes) {
class PT : public ProducerThread {
virtual void render() {
glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
@@ -1241,7 +1318,7 @@ TEST_F(SurfaceTextureGLToGLTest, UpdateTexImageAfterFrameFinishedWorks) {
// TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
}
-TEST_F(SurfaceTextureGLToGLTest, RepeatedUpdateTexImageBeforeFrameFinishedWorks) {
+TEST_F(SurfaceTextureGLToGLTest, RepeatedUpdateTexImageBeforeFrameFinishedCompletes) {
enum { NUM_ITERATIONS = 1024 };
class PT : public ProducerThread {
@@ -1269,7 +1346,7 @@ TEST_F(SurfaceTextureGLToGLTest, RepeatedUpdateTexImageBeforeFrameFinishedWorks)
}
}
-TEST_F(SurfaceTextureGLToGLTest, RepeatedUpdateTexImageAfterFrameFinishedWorks) {
+TEST_F(SurfaceTextureGLToGLTest, RepeatedUpdateTexImageAfterFrameFinishedCompletes) {
enum { NUM_ITERATIONS = 1024 };
class PT : public ProducerThread {
@@ -1297,4 +1374,70 @@ TEST_F(SurfaceTextureGLToGLTest, RepeatedUpdateTexImageAfterFrameFinishedWorks)
}
}
+// XXX: This test is disabled because it is currently hanging on some devices.
+TEST_F(SurfaceTextureGLToGLTest, DISABLED_RepeatedSwapBuffersWhileDequeueStalledCompletes) {
+ enum { NUM_ITERATIONS = 64 };
+
+ class PT : public ProducerThread {
+ virtual void render() {
+ for (int i = 0; i < NUM_ITERATIONS; i++) {
+ glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+ LOGV("+swapBuffers");
+ swapBuffers();
+ LOGV("-swapBuffers");
+ }
+ }
+ };
+
+ ASSERT_EQ(OK, mST->setSynchronousMode(true));
+ ASSERT_EQ(OK, mST->setBufferCountServer(2));
+
+ runProducerThread(new PT());
+
+ // Allow three frames to be rendered and queued before starting the
+ // rendering in this thread. For the latter two frames we don't call
+ // updateTexImage so the next dequeue from the producer thread will block
+ // waiting for a frame to become available.
+ mFC->waitForFrame();
+ mFC->finishFrame();
+
+ // We must call updateTexImage to consume the first frame so that the
+ // SurfaceTexture is able to reduce the buffer count to 2. This is because
+ // the GL driver may dequeue a buffer when the EGLSurface is created, and
+ // that happens before we call setBufferCountServer. It's possible that the
+ // driver does not dequeue a buffer at EGLSurface creation time, so we
+ // cannot rely on this to cause the second dequeueBuffer call to block.
+ mST->updateTexImage();
+
+ mFC->waitForFrame();
+ mFC->finishFrame();
+ mFC->waitForFrame();
+ mFC->finishFrame();
+
+ // Sleep for 100ms to allow the producer thread's dequeueBuffer call to
+ // block waiting for a buffer to become available.
+ usleep(100000);
+
+ // Render and present a number of images. This thread should not be blocked
+ // by the fact that the producer thread is blocking in dequeue.
+ for (int i = 0; i < NUM_ITERATIONS; i++) {
+ glClear(GL_COLOR_BUFFER_BIT);
+ eglSwapBuffers(mEglDisplay, mEglSurface);
+ }
+
+ // Consume the two pending buffers to unblock the producer thread.
+ mST->updateTexImage();
+ mST->updateTexImage();
+
+ // Consume the remaining buffers from the producer thread.
+ for (int i = 0; i < NUM_ITERATIONS-3; i++) {
+ mFC->waitForFrame();
+ mFC->finishFrame();
+ LOGV("+updateTexImage");
+ mST->updateTexImage();
+ LOGV("-updateTexImage");
+ }
+}
+
} // namespace android
diff --git a/media/libstagefright/SurfaceMediaSource.cpp b/media/libstagefright/SurfaceMediaSource.cpp
index db208dd..7d08f09 100644
--- a/media/libstagefright/SurfaceMediaSource.cpp
+++ b/media/libstagefright/SurfaceMediaSource.cpp
@@ -147,16 +147,17 @@ status_t SurfaceMediaSource::setBufferCount(int bufferCount) {
return OK;
}
-sp<GraphicBuffer> SurfaceMediaSource::requestBuffer(int buf) {
+status_t SurfaceMediaSource::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
LOGV("SurfaceMediaSource::requestBuffer");
Mutex::Autolock lock(mMutex);
- if (buf < 0 || mBufferCount <= buf) {
+ if (slot < 0 || mBufferCount <= slot) {
LOGE("requestBuffer: slot index out of range [0, %d]: %d",
- mBufferCount, buf);
- return 0;
+ mBufferCount, slot);
+ return BAD_VALUE;
}
- mSlots[buf].mRequestBufferCalled = true;
- return mSlots[buf].mGraphicBuffer;
+ mSlots[slot].mRequestBufferCalled = true;
+ *buf = mSlots[slot].mGraphicBuffer;
+ return NO_ERROR;
}
status_t SurfaceMediaSource::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
@@ -525,12 +526,6 @@ void SurfaceMediaSource::setFrameAvailableListener(
mFrameAvailableListener = listener;
}
-sp<IBinder> SurfaceMediaSource::getAllocator() {
- LOGV("getAllocator");
- return mGraphicBufferAlloc->asBinder();
-}
-
-
void SurfaceMediaSource::freeAllBuffers() {
LOGV("freeAllBuffers");
for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {