Merge "Separate the notion of "stop" from that of "release", i.e."
This commit is contained in:
committed by
Android (Google) Code Review
commit
0c9aa1b6fc
@@ -396,7 +396,7 @@ status_t SimplePlayer::onReset() {
|
||||
for (size_t i = 0; i < mStateByTrackIndex.size(); ++i) {
|
||||
CodecState *state = &mStateByTrackIndex.editValueAt(i);
|
||||
|
||||
CHECK_EQ(state->mCodec->stop(), (status_t)OK);
|
||||
CHECK_EQ(state->mCodec->release(), (status_t)OK);
|
||||
}
|
||||
|
||||
mStartTimeRealUs = -1ll;
|
||||
|
||||
@@ -295,7 +295,7 @@ static int decode(
|
||||
for (size_t i = 0; i < stateByTrack.size(); ++i) {
|
||||
CodecState *state = &stateByTrack.editValueAt(i);
|
||||
|
||||
CHECK_EQ((status_t)OK, state->mCodec->stop());
|
||||
CHECK_EQ((status_t)OK, state->mCodec->release());
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -49,7 +49,7 @@ struct ACodec : public AHierarchicalStateMachine {
|
||||
void initiateSetup(const sp<AMessage> &msg);
|
||||
void signalFlush();
|
||||
void signalResume();
|
||||
void initiateShutdown();
|
||||
void initiateShutdown(bool keepComponentAllocated = false);
|
||||
|
||||
void initiateAllocateComponent(const sp<AMessage> &msg);
|
||||
void initiateConfigureComponent(const sp<AMessage> &msg);
|
||||
@@ -61,6 +61,7 @@ protected:
|
||||
private:
|
||||
struct BaseState;
|
||||
struct UninitializedState;
|
||||
struct LoadedState;
|
||||
struct LoadedToIdleState;
|
||||
struct IdleToExecutingState;
|
||||
struct ExecutingState;
|
||||
@@ -107,6 +108,7 @@ private:
|
||||
sp<AMessage> mNotify;
|
||||
|
||||
sp<UninitializedState> mUninitializedState;
|
||||
sp<LoadedState> mLoadedState;
|
||||
sp<LoadedToIdleState> mLoadedToIdleState;
|
||||
sp<IdleToExecutingState> mIdleToExecutingState;
|
||||
sp<ExecutingState> mExecutingState;
|
||||
@@ -131,6 +133,12 @@ private:
|
||||
bool mSentFormat;
|
||||
bool mIsEncoder;
|
||||
|
||||
bool mShutdownInProgress;
|
||||
|
||||
// If "mKeepComponentAllocated" we only transition back to Loaded state
|
||||
// and do not release the component instance.
|
||||
bool mKeepComponentAllocated;
|
||||
|
||||
status_t allocateBuffersOnPort(OMX_U32 portIndex);
|
||||
status_t freeBuffersOnPort(OMX_U32 portIndex);
|
||||
status_t freeBuffer(OMX_U32 portIndex, size_t i);
|
||||
|
||||
@@ -53,8 +53,15 @@ struct MediaCodec : public AHandler {
|
||||
uint32_t flags);
|
||||
|
||||
status_t start();
|
||||
|
||||
// Returns to a state in which the component remains allocated but
|
||||
// unconfigured.
|
||||
status_t stop();
|
||||
|
||||
// Client MUST call release before releasing final reference to this
|
||||
// object.
|
||||
status_t release();
|
||||
|
||||
status_t flush();
|
||||
|
||||
status_t queueInputBuffer(
|
||||
@@ -97,6 +104,7 @@ private:
|
||||
STARTED,
|
||||
FLUSHING,
|
||||
STOPPING,
|
||||
RELEASING,
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -109,6 +117,7 @@ private:
|
||||
kWhatConfigure = 'conf',
|
||||
kWhatStart = 'strt',
|
||||
kWhatStop = 'stop',
|
||||
kWhatRelease = 'rele',
|
||||
kWhatDequeueInputBuffer = 'deqI',
|
||||
kWhatQueueInputBuffer = 'queI',
|
||||
kWhatDequeueOutputBuffer = 'deqO',
|
||||
|
||||
@@ -84,7 +84,7 @@ status_t JMediaCodec::initCheck() const {
|
||||
}
|
||||
|
||||
JMediaCodec::~JMediaCodec() {
|
||||
mCodec->stop();
|
||||
mCodec->release();
|
||||
|
||||
JNIEnv *env = AndroidRuntime::getJNIEnv();
|
||||
|
||||
|
||||
@@ -165,18 +165,36 @@ struct ACodec::UninitializedState : public ACodec::BaseState {
|
||||
|
||||
protected:
|
||||
virtual bool onMessageReceived(const sp<AMessage> &msg);
|
||||
virtual void stateEntered();
|
||||
|
||||
private:
|
||||
void onSetup(const sp<AMessage> &msg);
|
||||
void onAllocateComponent(const sp<AMessage> &msg);
|
||||
void onConfigureComponent(const sp<AMessage> &msg);
|
||||
void onStart();
|
||||
bool onAllocateComponent(const sp<AMessage> &msg);
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct ACodec::LoadedState : public ACodec::BaseState {
|
||||
LoadedState(ACodec *codec);
|
||||
|
||||
protected:
|
||||
virtual bool onMessageReceived(const sp<AMessage> &msg);
|
||||
virtual void stateEntered();
|
||||
|
||||
private:
|
||||
friend struct ACodec::UninitializedState;
|
||||
|
||||
bool onConfigureComponent(const sp<AMessage> &msg);
|
||||
void onStart();
|
||||
void onShutdown(bool keepComponentAllocated);
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct ACodec::LoadedToIdleState : public ACodec::BaseState {
|
||||
LoadedToIdleState(ACodec *codec);
|
||||
|
||||
@@ -312,8 +330,10 @@ private:
|
||||
ACodec::ACodec()
|
||||
: mNode(NULL),
|
||||
mSentFormat(false),
|
||||
mIsEncoder(false) {
|
||||
mIsEncoder(false),
|
||||
mShutdownInProgress(false) {
|
||||
mUninitializedState = new UninitializedState(this);
|
||||
mLoadedState = new LoadedState(this);
|
||||
mLoadedToIdleState = new LoadedToIdleState(this);
|
||||
mIdleToExecutingState = new IdleToExecutingState(this);
|
||||
mExecutingState = new ExecutingState(this);
|
||||
@@ -369,8 +389,10 @@ void ACodec::signalResume() {
|
||||
(new AMessage(kWhatResume, id()))->post();
|
||||
}
|
||||
|
||||
void ACodec::initiateShutdown() {
|
||||
(new AMessage(kWhatShutdown, id()))->post();
|
||||
void ACodec::initiateShutdown(bool keepComponentAllocated) {
|
||||
sp<AMessage> msg = new AMessage(kWhatShutdown, id());
|
||||
msg->setInt32("keepComponentAllocated", keepComponentAllocated);
|
||||
msg->post();
|
||||
}
|
||||
|
||||
status_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
|
||||
@@ -2492,6 +2514,10 @@ ACodec::UninitializedState::UninitializedState(ACodec *codec)
|
||||
: BaseState(codec) {
|
||||
}
|
||||
|
||||
void ACodec::UninitializedState::stateEntered() {
|
||||
ALOGV("Now uninitialized");
|
||||
}
|
||||
|
||||
bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
|
||||
bool handled = false;
|
||||
|
||||
@@ -2511,22 +2537,13 @@ bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
|
||||
break;
|
||||
}
|
||||
|
||||
case ACodec::kWhatConfigureComponent:
|
||||
{
|
||||
onConfigureComponent(msg);
|
||||
handled = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case ACodec::kWhatStart:
|
||||
{
|
||||
onStart();
|
||||
handled = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case ACodec::kWhatShutdown:
|
||||
{
|
||||
int32_t keepComponentAllocated;
|
||||
CHECK(msg->findInt32(
|
||||
"keepComponentAllocated", &keepComponentAllocated));
|
||||
CHECK(!keepComponentAllocated);
|
||||
|
||||
sp<AMessage> notify = mCodec->mNotify->dup();
|
||||
notify->setInt32("what", ACodec::kWhatShutdownCompleted);
|
||||
notify->post();
|
||||
@@ -2554,22 +2571,16 @@ bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
|
||||
|
||||
void ACodec::UninitializedState::onSetup(
|
||||
const sp<AMessage> &msg) {
|
||||
onAllocateComponent(msg);
|
||||
onConfigureComponent(msg);
|
||||
onStart();
|
||||
if (onAllocateComponent(msg)
|
||||
&& mCodec->mLoadedState->onConfigureComponent(msg)) {
|
||||
mCodec->mLoadedState->onStart();
|
||||
}
|
||||
}
|
||||
|
||||
void ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
|
||||
bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
|
||||
ALOGV("onAllocateComponent");
|
||||
|
||||
if (mCodec->mNode != NULL) {
|
||||
CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
|
||||
|
||||
mCodec->mNativeWindow.clear();
|
||||
mCodec->mNode = NULL;
|
||||
mCodec->mOMX.clear();
|
||||
mCodec->mComponentName.clear();
|
||||
}
|
||||
CHECK(mCodec->mNode == NULL);
|
||||
|
||||
OMXClient client;
|
||||
CHECK_EQ(client.connect(), (status_t)OK);
|
||||
@@ -2628,7 +2639,7 @@ void ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
|
||||
}
|
||||
|
||||
mCodec->signalError(OMX_ErrorComponentNotFound);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
sp<AMessage> notify = new AMessage(kWhatOMXMessage, mCodec->id());
|
||||
@@ -2649,9 +2660,96 @@ void ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
|
||||
notify->setString("componentName", mCodec->mComponentName.c_str());
|
||||
notify->post();
|
||||
}
|
||||
|
||||
mCodec->changeState(mCodec->mLoadedState);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ACodec::UninitializedState::onConfigureComponent(
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ACodec::LoadedState::LoadedState(ACodec *codec)
|
||||
: BaseState(codec) {
|
||||
}
|
||||
|
||||
void ACodec::LoadedState::stateEntered() {
|
||||
ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
|
||||
|
||||
if (mCodec->mShutdownInProgress) {
|
||||
bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
|
||||
|
||||
mCodec->mShutdownInProgress = false;
|
||||
mCodec->mKeepComponentAllocated = false;
|
||||
|
||||
onShutdown(keepComponentAllocated);
|
||||
}
|
||||
}
|
||||
|
||||
void ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
|
||||
if (!keepComponentAllocated) {
|
||||
CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
|
||||
|
||||
mCodec->mNativeWindow.clear();
|
||||
mCodec->mNode = NULL;
|
||||
mCodec->mOMX.clear();
|
||||
mCodec->mComponentName.clear();
|
||||
|
||||
mCodec->changeState(mCodec->mUninitializedState);
|
||||
}
|
||||
|
||||
sp<AMessage> notify = mCodec->mNotify->dup();
|
||||
notify->setInt32("what", ACodec::kWhatShutdownCompleted);
|
||||
notify->post();
|
||||
}
|
||||
|
||||
bool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
|
||||
bool handled = false;
|
||||
|
||||
switch (msg->what()) {
|
||||
case ACodec::kWhatConfigureComponent:
|
||||
{
|
||||
onConfigureComponent(msg);
|
||||
handled = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case ACodec::kWhatStart:
|
||||
{
|
||||
onStart();
|
||||
handled = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case ACodec::kWhatShutdown:
|
||||
{
|
||||
int32_t keepComponentAllocated;
|
||||
CHECK(msg->findInt32(
|
||||
"keepComponentAllocated", &keepComponentAllocated));
|
||||
|
||||
onShutdown(keepComponentAllocated);
|
||||
|
||||
handled = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case ACodec::kWhatFlush:
|
||||
{
|
||||
sp<AMessage> notify = mCodec->mNotify->dup();
|
||||
notify->setInt32("what", ACodec::kWhatFlushCompleted);
|
||||
notify->post();
|
||||
|
||||
handled = true;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return BaseState::onMessageReceived(msg);
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
bool ACodec::LoadedState::onConfigureComponent(
|
||||
const sp<AMessage> &msg) {
|
||||
ALOGV("onConfigureComponent");
|
||||
|
||||
@@ -2664,7 +2762,7 @@ void ACodec::UninitializedState::onConfigureComponent(
|
||||
|
||||
if (err != OK) {
|
||||
mCodec->signalError(OMX_ErrorUndefined, err);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
sp<RefBase> obj;
|
||||
@@ -2682,9 +2780,11 @@ void ACodec::UninitializedState::onConfigureComponent(
|
||||
notify->setInt32("what", ACodec::kWhatComponentConfigured);
|
||||
notify->post();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ACodec::UninitializedState::onStart() {
|
||||
void ACodec::LoadedState::onStart() {
|
||||
ALOGV("onStart");
|
||||
|
||||
CHECK_EQ(mCodec->mOMX->sendCommand(
|
||||
@@ -2873,6 +2973,13 @@ bool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
|
||||
switch (msg->what()) {
|
||||
case kWhatShutdown:
|
||||
{
|
||||
int32_t keepComponentAllocated;
|
||||
CHECK(msg->findInt32(
|
||||
"keepComponentAllocated", &keepComponentAllocated));
|
||||
|
||||
mCodec->mShutdownInProgress = true;
|
||||
mCodec->mKeepComponentAllocated = keepComponentAllocated;
|
||||
|
||||
mActive = false;
|
||||
|
||||
CHECK_EQ(mCodec->mOMX->sendCommand(
|
||||
@@ -3210,20 +3317,7 @@ bool ACodec::IdleToLoadedState::onOMXEvent(
|
||||
CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
|
||||
CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
|
||||
|
||||
ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
|
||||
|
||||
CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
|
||||
|
||||
mCodec->mNativeWindow.clear();
|
||||
mCodec->mNode = NULL;
|
||||
mCodec->mOMX.clear();
|
||||
mCodec->mComponentName.clear();
|
||||
|
||||
mCodec->changeState(mCodec->mUninitializedState);
|
||||
|
||||
sp<AMessage> notify = mCodec->mNotify->dup();
|
||||
notify->setInt32("what", ACodec::kWhatShutdownCompleted);
|
||||
notify->post();
|
||||
mCodec->changeState(mCodec->mLoadedState);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -164,6 +164,13 @@ status_t MediaCodec::stop() {
|
||||
return PostAndAwaitResponse(msg, &response);
|
||||
}
|
||||
|
||||
status_t MediaCodec::release() {
|
||||
sp<AMessage> msg = new AMessage(kWhatRelease, id());
|
||||
|
||||
sp<AMessage> response;
|
||||
return PostAndAwaitResponse(msg, &response);
|
||||
}
|
||||
|
||||
status_t MediaCodec::queueInputBuffer(
|
||||
size_t index,
|
||||
size_t offset,
|
||||
@@ -422,6 +429,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
|
||||
}
|
||||
|
||||
case STOPPING:
|
||||
case RELEASING:
|
||||
{
|
||||
// Ignore the error, assuming we'll still get
|
||||
// the shutdown complete notification.
|
||||
@@ -577,7 +585,9 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
|
||||
{
|
||||
/* size_t index = */updateBuffers(kPortIndexInput, msg);
|
||||
|
||||
if (mState == FLUSHING || mState == STOPPING) {
|
||||
if (mState == FLUSHING
|
||||
|| mState == STOPPING
|
||||
|| mState == RELEASING) {
|
||||
returnBuffersToCodecOnPort(kPortIndexInput);
|
||||
break;
|
||||
}
|
||||
@@ -596,7 +606,9 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
|
||||
{
|
||||
/* size_t index = */updateBuffers(kPortIndexOutput, msg);
|
||||
|
||||
if (mState == FLUSHING || mState == STOPPING) {
|
||||
if (mState == FLUSHING
|
||||
|| mState == STOPPING
|
||||
|| mState == RELEASING) {
|
||||
returnBuffersToCodecOnPort(kPortIndexOutput);
|
||||
break;
|
||||
}
|
||||
@@ -628,8 +640,12 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
|
||||
|
||||
case ACodec::kWhatShutdownCompleted:
|
||||
{
|
||||
CHECK_EQ(mState, STOPPING);
|
||||
setState(UNINITIALIZED);
|
||||
if (mState == STOPPING) {
|
||||
setState(INITIALIZED);
|
||||
} else {
|
||||
CHECK_EQ(mState, RELEASING);
|
||||
setState(UNINITIALIZED);
|
||||
}
|
||||
|
||||
(new AMessage)->postReply(mReplyID);
|
||||
break;
|
||||
@@ -767,6 +783,28 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
|
||||
mReplyID = replyID;
|
||||
setState(STOPPING);
|
||||
|
||||
mCodec->initiateShutdown(true /* keepComponentAllocated */);
|
||||
returnBuffersToCodec();
|
||||
break;
|
||||
}
|
||||
|
||||
case kWhatRelease:
|
||||
{
|
||||
uint32_t replyID;
|
||||
CHECK(msg->senderAwaitsResponse(&replyID));
|
||||
|
||||
if (mState != INITIALIZED
|
||||
&& mState != CONFIGURED && mState != STARTED) {
|
||||
sp<AMessage> response = new AMessage;
|
||||
response->setInt32("err", INVALID_OPERATION);
|
||||
|
||||
response->postReply(replyID);
|
||||
break;
|
||||
}
|
||||
|
||||
mReplyID = replyID;
|
||||
setState(RELEASING);
|
||||
|
||||
mCodec->initiateShutdown();
|
||||
returnBuffersToCodec();
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user