Bug 1296198 - Somewhat of improvement on MediaCodecDataDecoder on Fennec. r?jwwang
MozReview-Commit-ID: 12z9ySoa0xv
--- a/dom/media/platforms/android/MediaCodecDataDecoder.cpp
+++ b/dom/media/platforms/android/MediaCodecDataDecoder.cpp
@@ -238,17 +238,17 @@ MediaCodecDataDecoder::MediaCodecDataDec
MediaDataDecoderCallback* aCallback)
: mType(aType)
, mMimeType(aMimeType)
, mFormat(aFormat)
, mCallback(aCallback)
, mInputBuffers(nullptr)
, mOutputBuffers(nullptr)
, mMonitor("MediaCodecDataDecoder::mMonitor")
- , mState(kDecoding)
+ , mState(ModuleState::kDecoding)
{
}
MediaCodecDataDecoder::~MediaCodecDataDecoder()
{
Shutdown();
}
@@ -291,19 +291,19 @@ MediaCodecDataDecoder::InitDecoder(Surfa
}
// This is in usec, so that's 10ms.
static const int64_t kDecoderTimeout = 10000;
#define BREAK_ON_DECODER_ERROR() \
if (NS_FAILED(res)) { \
NS_WARNING("Exiting decoder loop due to exception"); \
- if (State() == kDrainDecoder) { \
+ if (mState == ModuleState::kDrainDecoder) { \
INVOKE_CALLBACK(DrainComplete); \
- State(kDecoding); \
+ SetState(ModuleState::kDecoding); \
} \
INVOKE_CALLBACK(Error, MediaDataDecoderError::FATAL_ERROR); \
break; \
}
nsresult
MediaCodecDataDecoder::GetInputBuffer(
JNIEnv* aEnv, int aIndex, jni::Object::LocalRef* aBuffer)
@@ -327,42 +327,42 @@ MediaCodecDataDecoder::GetInputBuffer(
return NS_ERROR_FAILURE;
}
bool
MediaCodecDataDecoder::WaitForInput()
{
MonitorAutoLock lock(mMonitor);
- while (State() == kDecoding && mQueue.empty()) {
+ while (mState == ModuleState::kDecoding && mQueue.empty()) {
// Signal that we require more input.
INVOKE_CALLBACK(InputExhausted);
lock.Wait();
}
- return State() != kStopping;
+ return mState != ModuleState::kStopping;
}
already_AddRefed<MediaRawData>
MediaCodecDataDecoder::PeekNextSample()
{
MonitorAutoLock lock(mMonitor);
- if (State() == kFlushing) {
+ if (mState == ModuleState::kFlushing) {
mDecoder->Flush();
ClearQueue();
- State(kDecoding);
+ SetState(ModuleState::kDecoding);
lock.Notify();
return nullptr;
}
if (mQueue.empty()) {
- if (State() == kDrainQueue) {
- State(kDrainDecoder);
+ if (mState == ModuleState::kDrainQueue) {
+ SetState(ModuleState::kDrainDecoder);
}
return nullptr;
}
// We're not stopping or flushing, so try to get a sample.
return RefPtr<MediaRawData>(mQueue.front()).forget();
}
@@ -418,29 +418,29 @@ MediaCodecDataDecoder::QueueEOS()
res = mDecoder->DequeueInputBuffer(kDecoderTimeout, &inputIndex);
if (NS_FAILED(res) || inputIndex < 0) {
return res;
}
res = mDecoder->QueueInputBuffer(inputIndex, 0, 0, 0,
MediaCodec::BUFFER_FLAG_END_OF_STREAM);
if (NS_SUCCEEDED(res)) {
- State(kDrainWaitEOS);
+ SetState(ModuleState::kDrainWaitEOS);
mMonitor.Notify();
}
return res;
}
void
MediaCodecDataDecoder::HandleEOS(int32_t aOutputStatus)
{
MonitorAutoLock lock(mMonitor);
- if (State() == kDrainWaitEOS) {
- State(kDecoding);
+ if (mState == ModuleState::kDrainWaitEOS) {
+ SetState(ModuleState::kDecoding);
mMonitor.Notify();
INVOKE_CALLBACK(DrainComplete);
}
mDecoder->ReleaseOutputBuffer(aOutputStatus, false);
}
@@ -493,17 +493,17 @@ MediaCodecDataDecoder::DecoderLoop()
MediaFormat::LocalRef outputFormat(frame.GetEnv());
nsresult res = NS_OK;
while (WaitForInput()) {
RefPtr<MediaRawData> sample = PeekNextSample();
{
MonitorAutoLock lock(mMonitor);
- if (State() == kDrainDecoder) {
+ if (mState == ModuleState::kDrainDecoder) {
MOZ_ASSERT(!sample, "Shouldn't have a sample when pushing EOF frame");
res = QueueEOS();
BREAK_ON_DECODER_ERROR();
}
}
if (sample) {
res = QueueSample(sample);
@@ -560,55 +560,55 @@ MediaCodecDataDecoder::DecoderLoop()
BREAK_ON_DECODER_ERROR();
}
}
Cleanup();
// We're done.
MonitorAutoLock lock(mMonitor);
- State(kShutdown);
+ SetState(ModuleState::kShutdown);
mMonitor.Notify();
}
const char*
MediaCodecDataDecoder::ModuleStateStr(ModuleState aState) {
- static const char* kStr[] = {
- "Decoding", "Flushing", "DrainQueue", "DrainDecoder", "DrainWaitEOS",
- "Stopping", "Shutdown"
- };
-
- MOZ_ASSERT(aState < sizeof(kStr) / sizeof(kStr[0]));
- return kStr[aState];
-}
-
-MediaCodecDataDecoder::ModuleState
-MediaCodecDataDecoder::State() const
-{
- return mState;
+ switch (aState) {
+ case ModuleState::kDecoding: return "Decoding";
+ case ModuleState::kFlushing: return "Flushing";
+ case ModuleState::kDrainQueue: return "DrainQueue";
+ case ModuleState::kDrainDecoder: return "DrainDecoder";
+ case ModuleState::kDrainWaitEOS: return "DrainWaitEOS";
+ case ModuleState::kStopping: return "Stopping";
+ case ModuleState::kShutdown: return "Shutdown";
+ default: MOZ_ASSERT_UNREACHABLE("Invalid state.");
+ }
+ return "Unknown";
}
bool
-MediaCodecDataDecoder::State(ModuleState aState)
+MediaCodecDataDecoder::SetState(ModuleState aState)
{
bool ok = true;
- if (mState == kShutdown) {
+ if (mState == ModuleState::kShutdown) {
ok = false;
- } else if (mState == kStopping) {
- ok = aState == kShutdown;
- } else if (aState == kDrainDecoder) {
- ok = mState == kDrainQueue;
- } else if (aState == kDrainWaitEOS) {
- ok = mState == kDrainDecoder;
+ } else if (mState == ModuleState::kStopping) {
+ ok = aState == ModuleState::kShutdown;
+ } else if (aState == ModuleState::kDrainDecoder) {
+ ok = mState == ModuleState::kDrainQueue;
+ } else if (aState == ModuleState::kDrainWaitEOS) {
+ ok = mState == ModuleState::kDrainDecoder;
}
if (ok) {
LOG("%s -> %s", ModuleStateStr(mState), ModuleStateStr(aState));
mState = aState;
+ } else {
+ LOG("Fail to transit from %s to %s state", ModuleStateStr(mState), ModuleStateStr(aState));
}
return ok;
}
void
MediaCodecDataDecoder::ClearQueue()
{
@@ -639,52 +639,53 @@ MediaCodecDataDecoder::ResetOutputBuffer
{
return mDecoder->GetOutputBuffers(ReturnTo(&mOutputBuffers));
}
nsresult
MediaCodecDataDecoder::Flush()
{
MonitorAutoLock lock(mMonitor);
- if (!State(kFlushing)) {
+ if (!SetState(ModuleState::kFlushing)) {
return NS_OK;
}
lock.Notify();
- while (State() == kFlushing) {
+ while (mState == ModuleState::kFlushing) {
lock.Wait();
}
return NS_OK;
}
nsresult
MediaCodecDataDecoder::Drain()
{
MonitorAutoLock lock(mMonitor);
- if (State() == kDrainDecoder || State() == kDrainQueue) {
+ if (mState == ModuleState::kDrainDecoder ||
+ mState == ModuleState::kDrainQueue) {
return NS_OK;
}
- State(kDrainQueue);
+ SetState(ModuleState::kDrainQueue);
lock.Notify();
return NS_OK;
}
nsresult
MediaCodecDataDecoder::Shutdown()
{
MonitorAutoLock lock(mMonitor);
- State(kStopping);
+ SetState(ModuleState::kStopping);
lock.Notify();
- while (mThread && State() != kShutdown) {
+ while (mThread && mState != ModuleState::kShutdown) {
lock.Wait();
}
if (mThread) {
mThread->Shutdown();
mThread = nullptr;
}
--- a/dom/media/platforms/android/MediaCodecDataDecoder.h
+++ b/dom/media/platforms/android/MediaCodecDataDecoder.h
@@ -38,17 +38,17 @@ public:
nsresult Shutdown() override;
nsresult Input(MediaRawData* aSample) override;
const char* GetDescriptionName() const override
{
return "Android MediaCodec decoder";
}
protected:
- enum ModuleState {
+ enum class ModuleState : uint8_t {
kDecoding = 0,
kFlushing,
kDrainQueue,
kDrainDecoder,
kDrainWaitEOS,
kStopping,
kShutdown
};
@@ -86,19 +86,18 @@ protected:
already_AddRefed<MediaRawData> PeekNextSample();
nsresult QueueSample(const MediaRawData* aSample);
nsresult QueueEOS();
void HandleEOS(int32_t aOutputStatus);
Maybe<media::TimeUnit> GetOutputDuration();
nsresult ProcessOutput(java::sdk::BufferInfo::Param aInfo,
java::sdk::MediaFormat::Param aFormat,
int32_t aStatus);
- ModuleState State() const;
// Sets decoder state and returns whether the new state has become effective.
- bool State(ModuleState aState);
+ bool SetState(ModuleState aState);
void DecoderLoop();
virtual void ClearQueue();
MediaData::Type mType;
nsAutoCString mMimeType;
java::sdk::MediaFormat::GlobalRef mFormat;