Skip to content

Commit 6607b39

Browse files
author
Jamie Gennis
committed
Stagefright: idle OMX after ANW errors
This change fixes an issue in Stagefright where the state of an OMXCodec object can get out of sync with the state of the OMX component. In particular, if one of the ANativeWindow functions failed and put the OMXCodec into the ERROR state, this would cause Stagefright to skip doing the Executing -> Idle transition. Without this transition the freeBuffersOnPort call would never be made, and the MediaBuffers would end up being leaked (which would also leak the Gralloc buffers they reference). Bug: 5333695 Change-Id: I85ea0cf92d18e7ef6d35c7d1e2a7b4e2c9745d34
1 parent 5310a73 commit 6607b39

File tree

7 files changed

+68
-1
lines changed

7 files changed

+68
-1
lines changed

include/media/IOMX.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ class IOMX : public IInterface {
7878
node_id node, OMX_INDEXTYPE index,
7979
const void *params, size_t size) = 0;
8080

81+
virtual status_t getState(
82+
node_id node, OMX_STATETYPE* state) = 0;
83+
8184
virtual status_t storeMetaDataInBuffers(
8285
node_id node, OMX_U32 port_index, OMX_BOOL enable) = 0;
8386

media/libmedia/IOMX.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ enum {
3838
SET_PARAMETER,
3939
GET_CONFIG,
4040
SET_CONFIG,
41+
GET_STATE,
4142
ENABLE_GRAPHIC_BUFFERS,
4243
USE_BUFFER,
4344
USE_GRAPHIC_BUFFER,
@@ -198,6 +199,17 @@ class BpOMX : public BpInterface<IOMX> {
198199
return reply.readInt32();
199200
}
200201

202+
virtual status_t getState(
203+
node_id node, OMX_STATETYPE* state) {
204+
Parcel data, reply;
205+
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
206+
data.writeIntPtr((intptr_t)node);
207+
remote()->transact(GET_STATE, data, &reply);
208+
209+
*state = static_cast<OMX_STATETYPE>(reply.readInt32());
210+
return reply.readInt32();
211+
}
212+
201213
virtual status_t enableGraphicBuffers(
202214
node_id node, OMX_U32 port_index, OMX_BOOL enable) {
203215
Parcel data, reply;
@@ -524,6 +536,20 @@ status_t BnOMX::onTransact(
524536
return NO_ERROR;
525537
}
526538

539+
case GET_STATE:
540+
{
541+
CHECK_INTERFACE(IOMX, data, reply);
542+
543+
node_id node = (void*)data.readIntPtr();
544+
OMX_STATETYPE state = OMX_StateInvalid;
545+
546+
status_t err = getState(node, &state);
547+
reply->writeInt32(state);
548+
reply->writeInt32(err);
549+
550+
return NO_ERROR;
551+
}
552+
527553
case ENABLE_GRAPHIC_BUFFERS:
528554
{
529555
CHECK_INTERFACE(IOMX, data, reply);

media/libstagefright/OMXCodec.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3600,11 +3600,24 @@ status_t OMXCodec::stop() {
36003600
mAsyncCompletion.wait(mLock);
36013601
}
36023602

3603+
bool isError = false;
36033604
switch (mState) {
36043605
case LOADED:
3605-
case ERROR:
36063606
break;
36073607

3608+
case ERROR:
3609+
{
3610+
OMX_STATETYPE state = OMX_StateInvalid;
3611+
status_t err = mOMX->getState(mNode, &state);
3612+
CHECK_EQ(err, (status_t)OK);
3613+
3614+
if (state != OMX_StateExecuting) {
3615+
break;
3616+
}
3617+
// else fall through to the idling code
3618+
isError = true;
3619+
}
3620+
36083621
case EXECUTING:
36093622
{
36103623
setState(EXECUTING_TO_IDLE);
@@ -3639,6 +3652,12 @@ status_t OMXCodec::stop() {
36393652
mAsyncCompletion.wait(mLock);
36403653
}
36413654

3655+
if (isError) {
3656+
// We were in the ERROR state coming in, so restore that now
3657+
// that we've idled the OMX component.
3658+
setState(ERROR);
3659+
}
3660+
36423661
break;
36433662
}
36443663

media/libstagefright/include/OMX.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ class OMX : public BnOMX,
5959
node_id node, OMX_INDEXTYPE index,
6060
const void *params, size_t size);
6161

62+
virtual status_t getState(
63+
node_id node, OMX_STATETYPE* state);
64+
6265
virtual status_t enableGraphicBuffers(
6366
node_id node, OMX_U32 port_index, OMX_BOOL enable);
6467

media/libstagefright/include/OMXNodeInstance.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ struct OMXNodeInstance {
4949
status_t getConfig(OMX_INDEXTYPE index, void *params, size_t size);
5050
status_t setConfig(OMX_INDEXTYPE index, const void *params, size_t size);
5151

52+
status_t getState(OMX_STATETYPE* state);
53+
5254
status_t enableGraphicBuffers(OMX_U32 portIndex, OMX_BOOL enable);
5355

5456
status_t getGraphicBufferUsage(OMX_U32 portIndex, OMX_U32* usage);

media/libstagefright/omx/OMX.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,12 @@ status_t OMX::setConfig(
303303
index, params, size);
304304
}
305305

306+
status_t OMX::getState(
307+
node_id node, OMX_STATETYPE* state) {
308+
return findInstance(node)->getState(
309+
state);
310+
}
311+
306312
status_t OMX::enableGraphicBuffers(
307313
node_id node, OMX_U32 port_index, OMX_BOOL enable) {
308314
return findInstance(node)->enableGraphicBuffers(port_index, enable);

media/libstagefright/omx/OMXNodeInstance.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,14 @@ status_t OMXNodeInstance::setConfig(
266266
return StatusFromOMXError(err);
267267
}
268268

269+
status_t OMXNodeInstance::getState(OMX_STATETYPE* state) {
270+
Mutex::Autolock autoLock(mLock);
271+
272+
OMX_ERRORTYPE err = OMX_GetState(mHandle, state);
273+
274+
return StatusFromOMXError(err);
275+
}
276+
269277
status_t OMXNodeInstance::enableGraphicBuffers(
270278
OMX_U32 portIndex, OMX_BOOL enable) {
271279
Mutex::Autolock autoLock(mLock);

0 commit comments

Comments
 (0)