Skip to content

Commit 4484bdd

Browse files
committed
Separate the notion of "stop" from that of "release", i.e.
stop - means transition back to LOADED state and keeping the component instance allocated. release - means we get rid of the component completely. Change-Id: I40ad01ce70821faaad43f57999249904f9144924
1 parent f64dfcc commit 4484bdd

File tree

7 files changed

+207
-58
lines changed

7 files changed

+207
-58
lines changed

cmds/stagefright/SimplePlayer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ status_t SimplePlayer::onReset() {
396396
for (size_t i = 0; i < mStateByTrackIndex.size(); ++i) {
397397
CodecState *state = &mStateByTrackIndex.editValueAt(i);
398398

399-
CHECK_EQ(state->mCodec->stop(), (status_t)OK);
399+
CHECK_EQ(state->mCodec->release(), (status_t)OK);
400400
}
401401

402402
mStartTimeRealUs = -1ll;

cmds/stagefright/codec.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ static int decode(
295295
for (size_t i = 0; i < stateByTrack.size(); ++i) {
296296
CodecState *state = &stateByTrack.editValueAt(i);
297297

298-
CHECK_EQ((status_t)OK, state->mCodec->stop());
298+
CHECK_EQ((status_t)OK, state->mCodec->release());
299299
}
300300

301301
return 0;

include/media/stagefright/ACodec.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ struct ACodec : public AHierarchicalStateMachine {
4949
void initiateSetup(const sp<AMessage> &msg);
5050
void signalFlush();
5151
void signalResume();
52-
void initiateShutdown();
52+
void initiateShutdown(bool keepComponentAllocated = false);
5353

5454
void initiateAllocateComponent(const sp<AMessage> &msg);
5555
void initiateConfigureComponent(const sp<AMessage> &msg);
@@ -61,6 +61,7 @@ struct ACodec : public AHierarchicalStateMachine {
6161
private:
6262
struct BaseState;
6363
struct UninitializedState;
64+
struct LoadedState;
6465
struct LoadedToIdleState;
6566
struct IdleToExecutingState;
6667
struct ExecutingState;
@@ -107,6 +108,7 @@ struct ACodec : public AHierarchicalStateMachine {
107108
sp<AMessage> mNotify;
108109

109110
sp<UninitializedState> mUninitializedState;
111+
sp<LoadedState> mLoadedState;
110112
sp<LoadedToIdleState> mLoadedToIdleState;
111113
sp<IdleToExecutingState> mIdleToExecutingState;
112114
sp<ExecutingState> mExecutingState;
@@ -131,6 +133,12 @@ struct ACodec : public AHierarchicalStateMachine {
131133
bool mSentFormat;
132134
bool mIsEncoder;
133135

136+
bool mShutdownInProgress;
137+
138+
// If "mKeepComponentAllocated" we only transition back to Loaded state
139+
// and do not release the component instance.
140+
bool mKeepComponentAllocated;
141+
134142
status_t allocateBuffersOnPort(OMX_U32 portIndex);
135143
status_t freeBuffersOnPort(OMX_U32 portIndex);
136144
status_t freeBuffer(OMX_U32 portIndex, size_t i);

include/media/stagefright/MediaCodec.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,15 @@ struct MediaCodec : public AHandler {
5353
uint32_t flags);
5454

5555
status_t start();
56+
57+
// Returns to a state in which the component remains allocated but
58+
// unconfigured.
5659
status_t stop();
5760

61+
// Client MUST call release before releasing final reference to this
62+
// object.
63+
status_t release();
64+
5865
status_t flush();
5966

6067
status_t queueInputBuffer(
@@ -97,6 +104,7 @@ struct MediaCodec : public AHandler {
97104
STARTED,
98105
FLUSHING,
99106
STOPPING,
107+
RELEASING,
100108
};
101109

102110
enum {
@@ -109,6 +117,7 @@ struct MediaCodec : public AHandler {
109117
kWhatConfigure = 'conf',
110118
kWhatStart = 'strt',
111119
kWhatStop = 'stop',
120+
kWhatRelease = 'rele',
112121
kWhatDequeueInputBuffer = 'deqI',
113122
kWhatQueueInputBuffer = 'queI',
114123
kWhatDequeueOutputBuffer = 'deqO',

media/jni/android_media_MediaCodec.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ status_t JMediaCodec::initCheck() const {
8484
}
8585

8686
JMediaCodec::~JMediaCodec() {
87-
mCodec->stop();
87+
mCodec->release();
8888

8989
JNIEnv *env = AndroidRuntime::getJNIEnv();
9090

media/libstagefright/ACodec.cpp

Lines changed: 144 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -165,18 +165,36 @@ struct ACodec::UninitializedState : public ACodec::BaseState {
165165

166166
protected:
167167
virtual bool onMessageReceived(const sp<AMessage> &msg);
168+
virtual void stateEntered();
168169

169170
private:
170171
void onSetup(const sp<AMessage> &msg);
171-
void onAllocateComponent(const sp<AMessage> &msg);
172-
void onConfigureComponent(const sp<AMessage> &msg);
173-
void onStart();
172+
bool onAllocateComponent(const sp<AMessage> &msg);
174173

175174
DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
176175
};
177176

178177
////////////////////////////////////////////////////////////////////////////////
179178

179+
struct ACodec::LoadedState : public ACodec::BaseState {
180+
LoadedState(ACodec *codec);
181+
182+
protected:
183+
virtual bool onMessageReceived(const sp<AMessage> &msg);
184+
virtual void stateEntered();
185+
186+
private:
187+
friend struct ACodec::UninitializedState;
188+
189+
bool onConfigureComponent(const sp<AMessage> &msg);
190+
void onStart();
191+
void onShutdown(bool keepComponentAllocated);
192+
193+
DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
194+
};
195+
196+
////////////////////////////////////////////////////////////////////////////////
197+
180198
struct ACodec::LoadedToIdleState : public ACodec::BaseState {
181199
LoadedToIdleState(ACodec *codec);
182200

@@ -312,8 +330,10 @@ struct ACodec::FlushingState : public ACodec::BaseState {
312330
ACodec::ACodec()
313331
: mNode(NULL),
314332
mSentFormat(false),
315-
mIsEncoder(false) {
333+
mIsEncoder(false),
334+
mShutdownInProgress(false) {
316335
mUninitializedState = new UninitializedState(this);
336+
mLoadedState = new LoadedState(this);
317337
mLoadedToIdleState = new LoadedToIdleState(this);
318338
mIdleToExecutingState = new IdleToExecutingState(this);
319339
mExecutingState = new ExecutingState(this);
@@ -369,8 +389,10 @@ void ACodec::signalResume() {
369389
(new AMessage(kWhatResume, id()))->post();
370390
}
371391

372-
void ACodec::initiateShutdown() {
373-
(new AMessage(kWhatShutdown, id()))->post();
392+
void ACodec::initiateShutdown(bool keepComponentAllocated) {
393+
sp<AMessage> msg = new AMessage(kWhatShutdown, id());
394+
msg->setInt32("keepComponentAllocated", keepComponentAllocated);
395+
msg->post();
374396
}
375397

376398
status_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
@@ -2492,6 +2514,10 @@ ACodec::UninitializedState::UninitializedState(ACodec *codec)
24922514
: BaseState(codec) {
24932515
}
24942516

2517+
void ACodec::UninitializedState::stateEntered() {
2518+
ALOGV("Now uninitialized");
2519+
}
2520+
24952521
bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
24962522
bool handled = false;
24972523

@@ -2511,22 +2537,13 @@ bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
25112537
break;
25122538
}
25132539

2514-
case ACodec::kWhatConfigureComponent:
2515-
{
2516-
onConfigureComponent(msg);
2517-
handled = true;
2518-
break;
2519-
}
2520-
2521-
case ACodec::kWhatStart:
2522-
{
2523-
onStart();
2524-
handled = true;
2525-
break;
2526-
}
2527-
25282540
case ACodec::kWhatShutdown:
25292541
{
2542+
int32_t keepComponentAllocated;
2543+
CHECK(msg->findInt32(
2544+
"keepComponentAllocated", &keepComponentAllocated));
2545+
CHECK(!keepComponentAllocated);
2546+
25302547
sp<AMessage> notify = mCodec->mNotify->dup();
25312548
notify->setInt32("what", ACodec::kWhatShutdownCompleted);
25322549
notify->post();
@@ -2554,22 +2571,16 @@ bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
25542571

25552572
void ACodec::UninitializedState::onSetup(
25562573
const sp<AMessage> &msg) {
2557-
onAllocateComponent(msg);
2558-
onConfigureComponent(msg);
2559-
onStart();
2574+
if (onAllocateComponent(msg)
2575+
&& mCodec->mLoadedState->onConfigureComponent(msg)) {
2576+
mCodec->mLoadedState->onStart();
2577+
}
25602578
}
25612579

2562-
void ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
2580+
bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
25632581
ALOGV("onAllocateComponent");
25642582

2565-
if (mCodec->mNode != NULL) {
2566-
CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
2567-
2568-
mCodec->mNativeWindow.clear();
2569-
mCodec->mNode = NULL;
2570-
mCodec->mOMX.clear();
2571-
mCodec->mComponentName.clear();
2572-
}
2583+
CHECK(mCodec->mNode == NULL);
25732584

25742585
OMXClient client;
25752586
CHECK_EQ(client.connect(), (status_t)OK);
@@ -2628,7 +2639,7 @@ void ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
26282639
}
26292640

26302641
mCodec->signalError(OMX_ErrorComponentNotFound);
2631-
return;
2642+
return false;
26322643
}
26332644

26342645
sp<AMessage> notify = new AMessage(kWhatOMXMessage, mCodec->id());
@@ -2649,9 +2660,96 @@ void ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
26492660
notify->setString("componentName", mCodec->mComponentName.c_str());
26502661
notify->post();
26512662
}
2663+
2664+
mCodec->changeState(mCodec->mLoadedState);
2665+
2666+
return true;
26522667
}
26532668

2654-
void ACodec::UninitializedState::onConfigureComponent(
2669+
////////////////////////////////////////////////////////////////////////////////
2670+
2671+
ACodec::LoadedState::LoadedState(ACodec *codec)
2672+
: BaseState(codec) {
2673+
}
2674+
2675+
void ACodec::LoadedState::stateEntered() {
2676+
ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
2677+
2678+
if (mCodec->mShutdownInProgress) {
2679+
bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
2680+
2681+
mCodec->mShutdownInProgress = false;
2682+
mCodec->mKeepComponentAllocated = false;
2683+
2684+
onShutdown(keepComponentAllocated);
2685+
}
2686+
}
2687+
2688+
void ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
2689+
if (!keepComponentAllocated) {
2690+
CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
2691+
2692+
mCodec->mNativeWindow.clear();
2693+
mCodec->mNode = NULL;
2694+
mCodec->mOMX.clear();
2695+
mCodec->mComponentName.clear();
2696+
2697+
mCodec->changeState(mCodec->mUninitializedState);
2698+
}
2699+
2700+
sp<AMessage> notify = mCodec->mNotify->dup();
2701+
notify->setInt32("what", ACodec::kWhatShutdownCompleted);
2702+
notify->post();
2703+
}
2704+
2705+
bool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
2706+
bool handled = false;
2707+
2708+
switch (msg->what()) {
2709+
case ACodec::kWhatConfigureComponent:
2710+
{
2711+
onConfigureComponent(msg);
2712+
handled = true;
2713+
break;
2714+
}
2715+
2716+
case ACodec::kWhatStart:
2717+
{
2718+
onStart();
2719+
handled = true;
2720+
break;
2721+
}
2722+
2723+
case ACodec::kWhatShutdown:
2724+
{
2725+
int32_t keepComponentAllocated;
2726+
CHECK(msg->findInt32(
2727+
"keepComponentAllocated", &keepComponentAllocated));
2728+
2729+
onShutdown(keepComponentAllocated);
2730+
2731+
handled = true;
2732+
break;
2733+
}
2734+
2735+
case ACodec::kWhatFlush:
2736+
{
2737+
sp<AMessage> notify = mCodec->mNotify->dup();
2738+
notify->setInt32("what", ACodec::kWhatFlushCompleted);
2739+
notify->post();
2740+
2741+
handled = true;
2742+
break;
2743+
}
2744+
2745+
default:
2746+
return BaseState::onMessageReceived(msg);
2747+
}
2748+
2749+
return handled;
2750+
}
2751+
2752+
bool ACodec::LoadedState::onConfigureComponent(
26552753
const sp<AMessage> &msg) {
26562754
ALOGV("onConfigureComponent");
26572755

@@ -2664,7 +2762,7 @@ void ACodec::UninitializedState::onConfigureComponent(
26642762

26652763
if (err != OK) {
26662764
mCodec->signalError(OMX_ErrorUndefined, err);
2667-
return;
2765+
return false;
26682766
}
26692767

26702768
sp<RefBase> obj;
@@ -2682,9 +2780,11 @@ void ACodec::UninitializedState::onConfigureComponent(
26822780
notify->setInt32("what", ACodec::kWhatComponentConfigured);
26832781
notify->post();
26842782
}
2783+
2784+
return true;
26852785
}
26862786

2687-
void ACodec::UninitializedState::onStart() {
2787+
void ACodec::LoadedState::onStart() {
26882788
ALOGV("onStart");
26892789

26902790
CHECK_EQ(mCodec->mOMX->sendCommand(
@@ -2873,6 +2973,13 @@ bool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
28732973
switch (msg->what()) {
28742974
case kWhatShutdown:
28752975
{
2976+
int32_t keepComponentAllocated;
2977+
CHECK(msg->findInt32(
2978+
"keepComponentAllocated", &keepComponentAllocated));
2979+
2980+
mCodec->mShutdownInProgress = true;
2981+
mCodec->mKeepComponentAllocated = keepComponentAllocated;
2982+
28762983
mActive = false;
28772984

28782985
CHECK_EQ(mCodec->mOMX->sendCommand(
@@ -3210,20 +3317,7 @@ bool ACodec::IdleToLoadedState::onOMXEvent(
32103317
CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
32113318
CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
32123319

3213-
ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
3214-
3215-
CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
3216-
3217-
mCodec->mNativeWindow.clear();
3218-
mCodec->mNode = NULL;
3219-
mCodec->mOMX.clear();
3220-
mCodec->mComponentName.clear();
3221-
3222-
mCodec->changeState(mCodec->mUninitializedState);
3223-
3224-
sp<AMessage> notify = mCodec->mNotify->dup();
3225-
notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3226-
notify->post();
3320+
mCodec->changeState(mCodec->mLoadedState);
32273321

32283322
return true;
32293323
}

0 commit comments

Comments
 (0)