Bug 1341210 - refactor ProcessOutput() to remove mDecodePromise and mDrainPromise. r?jya
MozReview-Commit-ID: 9kK7lzJriqC
--- a/dom/media/platforms/wmf/WMFMediaDataDecoder.cpp
+++ b/dom/media/platforms/wmf/WMFMediaDataDecoder.cpp
@@ -102,85 +102,67 @@ WMFMediaDataDecoder::Decode(MediaRawData
MOZ_DIAGNOSTIC_ASSERT(!mIsShutDown);
return InvokeAsync<MediaRawData*>(mTaskQueue, this, __func__,
&WMFMediaDataDecoder::ProcessDecode,
aSample);
}
RefPtr<MediaDataDecoder::DecodePromise>
+WMFMediaDataDecoder::ProcessError(HRESULT aError, const char* aReason)
+{
+ if (!mRecordedError) {
+ SendTelemetry(aError);
+ mRecordedError = true;
+ }
+ return DecodePromise::CreateAndReject(
+ MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
+ RESULT_DETAIL("%s:%x", aReason, aError)),
+ __func__);
+}
+
+RefPtr<MediaDataDecoder::DecodePromise>
WMFMediaDataDecoder::ProcessDecode(MediaRawData* aSample)
{
+ DecodedData results;
HRESULT hr = mMFTManager->Input(aSample);
if (hr == MF_E_NOTACCEPTING) {
- ProcessOutput();
+ ProcessOutput(results);
hr = mMFTManager->Input(aSample);
}
if (FAILED(hr)) {
NS_WARNING("MFTManager rejected sample");
- if (!mRecordedError) {
- SendTelemetry(hr);
- mRecordedError = true;
- }
- return DecodePromise::CreateAndReject(
- MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
- RESULT_DETAIL("MFTManager::Input:%x", hr)),
- __func__);
+ return ProcessError(hr, "MFTManager::Input");
}
mDrainStatus = DrainStatus::DRAINABLE;
mLastStreamOffset = aSample->mOffset;
- RefPtr<DecodePromise> p = mDecodePromise.Ensure(__func__);
- ProcessOutput();
- return p;
+ hr = ProcessOutput(results);
+ if (SUCCEEDED(hr) || hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
+ return DecodePromise::CreateAndResolve(Move(results), __func__);
+ }
+ return ProcessError(hr, "MFTManager::Output");
}
-void
-WMFMediaDataDecoder::ProcessOutput()
+HRESULT
+WMFMediaDataDecoder::ProcessOutput(DecodedData& aResults)
{
RefPtr<MediaData> output;
HRESULT hr = S_OK;
- DecodedData results;
while (SUCCEEDED(hr = mMFTManager->Output(mLastStreamOffset, output))) {
MOZ_ASSERT(output.get(), "Upon success, we must receive an output");
mHasSuccessfulOutput = true;
- results.AppendElement(Move(output));
+ aResults.AppendElement(Move(output));
if (mDrainStatus == DrainStatus::DRAINING) {
break;
}
}
-
- if (SUCCEEDED(hr) || hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
- if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT && !mDrainPromise.IsEmpty()) {
- mDrainStatus = DrainStatus::DRAINED;
- }
- if (!mDecodePromise.IsEmpty()) {
- mDecodePromise.Resolve(Move(results), __func__);
- } else {
- mDrainPromise.Resolve(Move(results), __func__);
- }
- return;
- }
-
- NS_WARNING("WMFMediaDataDecoder failed to output data");
- const auto error = MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
- RESULT_DETAIL("MFTManager::Output:%x", hr));
- if (!mDecodePromise.IsEmpty()) {
- mDecodePromise.Reject(error, __func__);
- }
- else {
- mDrainPromise.Reject(error, __func__);
- }
-
- if (!mRecordedError) {
- SendTelemetry(hr);
- mRecordedError = true;
- }
+ return hr;
}
RefPtr<MediaDataDecoder::FlushPromise>
WMFMediaDataDecoder::ProcessFlush()
{
if (mMFTManager) {
mMFTManager->Flush();
}
@@ -198,25 +180,33 @@ WMFMediaDataDecoder::Flush()
}
RefPtr<MediaDataDecoder::DecodePromise>
WMFMediaDataDecoder::ProcessDrain()
{
if (!mMFTManager || mDrainStatus == DrainStatus::DRAINED) {
return DecodePromise::CreateAndResolve(DecodedData(), __func__);
}
+
if (mDrainStatus != DrainStatus::DRAINING) {
// Order the decoder to drain...
mMFTManager->Drain();
mDrainStatus = DrainStatus::DRAINING;
}
+
// Then extract all available output.
- RefPtr<DecodePromise> p = mDrainPromise.Ensure(__func__);
- ProcessOutput();
- return p;
+ DecodedData results;
+ HRESULT hr = ProcessOutput(results);
+ if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
+ mDrainStatus = DrainStatus::DRAINED;
+ }
+ if (SUCCEEDED(hr) || hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
+ return DecodePromise::CreateAndResolve(Move(results), __func__);
+ }
+ return ProcessError(hr, "MFTManager::Output");
}
RefPtr<MediaDataDecoder::DecodePromise>
WMFMediaDataDecoder::Drain()
{
MOZ_DIAGNOSTIC_ASSERT(!mIsShutDown);
return InvokeAsync(mTaskQueue, this, __func__,
--- a/dom/media/platforms/wmf/WMFMediaDataDecoder.h
+++ b/dom/media/platforms/wmf/WMFMediaDataDecoder.h
@@ -112,23 +112,25 @@ public:
MOZ_ASSERT(mMFTManager);
return mMFTManager->NeedsConversion();
}
virtual void SetSeekThreshold(const media::TimeUnit& aTime) override;
private:
+ RefPtr<DecodePromise> ProcessError(HRESULT aError, const char* aReason);
+
// Called on the task queue. Inserts the sample into the decoder, and
// extracts output if available.
RefPtr<DecodePromise> ProcessDecode(MediaRawData* aSample);
// Called on the task queue. Extracts output if available, and delivers
// it to the reader. Called after ProcessDecode() and ProcessDrain().
- void ProcessOutput();
+ HRESULT ProcessOutput(DecodedData& aResults);
// Called on the task queue. Orders the MFT to flush. There is no output to
// extract.
RefPtr<FlushPromise> ProcessFlush();
// Called on the task queue. Orders the MFT to drain, and then extracts
// all available output.
RefPtr<DecodePromise> ProcessDrain();
@@ -140,18 +142,16 @@ private:
nsAutoPtr<MFTManager> mMFTManager;
// The last offset into the media resource that was passed into Input().
// This is used to approximate the decoder's position in the media resource.
int64_t mLastStreamOffset;
bool mIsShutDown = false;
- MozPromiseHolder<DecodePromise> mDecodePromise;
- MozPromiseHolder<DecodePromise> mDrainPromise;
enum class DrainStatus
{
DRAINED,
DRAINABLE,
DRAINING,
};
DrainStatus mDrainStatus = DrainStatus::DRAINED;