зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1198094: P1. Limit rate at which InputExhausted could be called by mac decoder. r=rillian
This commit is contained in:
Родитель
12a82fa457
Коммит
9628c1371f
|
@ -44,6 +44,7 @@ AppleVDADecoder::AppleVDADecoder(const VideoInfo& aConfig,
|
||||||
, mIsShutDown(false)
|
, mIsShutDown(false)
|
||||||
, mUseSoftwareImages(false)
|
, mUseSoftwareImages(false)
|
||||||
, mIs106(!nsCocoaFeatures::OnLionOrLater())
|
, mIs106(!nsCocoaFeatures::OnLionOrLater())
|
||||||
|
, mQueuedSamples(0)
|
||||||
, mMonitor("AppleVideoDecoder")
|
, mMonitor("AppleVideoDecoder")
|
||||||
, mIsFlushing(false)
|
, mIsFlushing(false)
|
||||||
, mDecoder(nullptr)
|
, mDecoder(nullptr)
|
||||||
|
@ -213,15 +214,13 @@ PlatformCallback(void* decompressionOutputRefCon,
|
||||||
// FIXME: Distinguish between errors and empty flushed frames.
|
// FIXME: Distinguish between errors and empty flushed frames.
|
||||||
if (status != noErr || !image) {
|
if (status != noErr || !image) {
|
||||||
NS_WARNING("AppleVDADecoder decoder returned no data");
|
NS_WARNING("AppleVDADecoder decoder returned no data");
|
||||||
return;
|
image = nullptr;
|
||||||
}
|
} else if (infoFlags & kVDADecodeInfo_FrameDropped) {
|
||||||
MOZ_ASSERT(CFGetTypeID(image) == CVPixelBufferGetTypeID(),
|
|
||||||
"AppleVDADecoder returned an unexpected image type");
|
|
||||||
|
|
||||||
if (infoFlags & kVDADecodeInfo_FrameDropped)
|
|
||||||
{
|
|
||||||
NS_WARNING(" ...frame dropped...");
|
NS_WARNING(" ...frame dropped...");
|
||||||
return;
|
image = nullptr;
|
||||||
|
} else {
|
||||||
|
MOZ_ASSERT(image || CFGetTypeID(image) == CVPixelBufferGetTypeID(),
|
||||||
|
"AppleVDADecoder returned an unexpected image type");
|
||||||
}
|
}
|
||||||
|
|
||||||
AppleVDADecoder* decoder =
|
AppleVDADecoder* decoder =
|
||||||
|
@ -278,6 +277,7 @@ AppleVDADecoder::DrainReorderedFrames()
|
||||||
while (!mReorderQueue.IsEmpty()) {
|
while (!mReorderQueue.IsEmpty()) {
|
||||||
mCallback->Output(mReorderQueue.Pop().get());
|
mCallback->Output(mReorderQueue.Pop().get());
|
||||||
}
|
}
|
||||||
|
mQueuedSamples = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -286,6 +286,7 @@ AppleVDADecoder::ClearReorderedFrames()
|
||||||
while (!mReorderQueue.IsEmpty()) {
|
while (!mReorderQueue.IsEmpty()) {
|
||||||
mReorderQueue.Pop();
|
mReorderQueue.Pop();
|
||||||
}
|
}
|
||||||
|
mQueuedSamples = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy and return a decoded frame.
|
// Copy and return a decoded frame.
|
||||||
|
@ -308,6 +309,19 @@ AppleVDADecoder::OutputFrame(CFRefPtr<CVPixelBufferRef> aImage,
|
||||||
aFrameRef.is_sync_point ? " keyframe" : ""
|
aFrameRef.is_sync_point ? " keyframe" : ""
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (mQueuedSamples > mMaxRefFrames) {
|
||||||
|
// We had stopped requesting more input because we had received too much at
|
||||||
|
// the time. We can ask for more once again.
|
||||||
|
mCallback->InputExhausted();
|
||||||
|
}
|
||||||
|
MOZ_ASSERT(mQueuedSamples);
|
||||||
|
mQueuedSamples--;
|
||||||
|
|
||||||
|
if (!aImage) {
|
||||||
|
// Image was dropped by decoder.
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
// Where our resulting image will end up.
|
// Where our resulting image will end up.
|
||||||
nsRefPtr<VideoData> data;
|
nsRefPtr<VideoData> data;
|
||||||
// Bounds.
|
// Bounds.
|
||||||
|
@ -471,6 +485,8 @@ AppleVDADecoder::SubmitFrame(MediaRawData* aSample)
|
||||||
&kCFTypeDictionaryKeyCallBacks,
|
&kCFTypeDictionaryKeyCallBacks,
|
||||||
&kCFTypeDictionaryValueCallBacks);
|
&kCFTypeDictionaryValueCallBacks);
|
||||||
|
|
||||||
|
mQueuedSamples++;
|
||||||
|
|
||||||
OSStatus rv = VDADecoderDecode(mDecoder,
|
OSStatus rv = VDADecoderDecode(mDecoder,
|
||||||
0,
|
0,
|
||||||
block,
|
block,
|
||||||
|
@ -494,7 +510,7 @@ AppleVDADecoder::SubmitFrame(MediaRawData* aSample)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ask for more data.
|
// Ask for more data.
|
||||||
if (!mInputIncoming) {
|
if (!mInputIncoming && mQueuedSamples <= mMaxRefFrames) {
|
||||||
LOG("AppleVDADecoder task queue empty; requesting more data");
|
LOG("AppleVDADecoder task queue empty; requesting more data");
|
||||||
mCallback->InputExhausted();
|
mCallback->InputExhausted();
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,6 +122,11 @@ protected:
|
||||||
bool mUseSoftwareImages;
|
bool mUseSoftwareImages;
|
||||||
bool mIs106;
|
bool mIs106;
|
||||||
|
|
||||||
|
// Number of times a sample was queued via Input(). Will be decreased upon
|
||||||
|
// the decoder's callback being invoked.
|
||||||
|
// This is used to calculate how many frames has been buffered by the decoder.
|
||||||
|
uint32_t mQueuedSamples;
|
||||||
|
|
||||||
// For wait on mIsFlushing during Shutdown() process.
|
// For wait on mIsFlushing during Shutdown() process.
|
||||||
Monitor mMonitor;
|
Monitor mMonitor;
|
||||||
// Set on reader/decode thread calling Flush() to indicate that output is
|
// Set on reader/decode thread calling Flush() to indicate that output is
|
||||||
|
|
|
@ -167,14 +167,13 @@ PlatformCallback(void* decompressionOutputRefCon,
|
||||||
// Validate our arguments.
|
// Validate our arguments.
|
||||||
if (status != noErr || !image) {
|
if (status != noErr || !image) {
|
||||||
NS_WARNING("VideoToolbox decoder returned no data");
|
NS_WARNING("VideoToolbox decoder returned no data");
|
||||||
return;
|
image = nullptr;
|
||||||
}
|
} else if (flags & kVTDecodeInfo_FrameDropped) {
|
||||||
if (flags & kVTDecodeInfo_FrameDropped) {
|
|
||||||
NS_WARNING(" ...frame tagged as dropped...");
|
NS_WARNING(" ...frame tagged as dropped...");
|
||||||
|
} else {
|
||||||
|
MOZ_ASSERT(CFGetTypeID(image) == CVPixelBufferGetTypeID(),
|
||||||
|
"VideoToolbox returned an unexpected image type");
|
||||||
}
|
}
|
||||||
MOZ_ASSERT(CFGetTypeID(image) == CVPixelBufferGetTypeID(),
|
|
||||||
"VideoToolbox returned an unexpected image type");
|
|
||||||
|
|
||||||
nsCOMPtr<nsIRunnable> task =
|
nsCOMPtr<nsIRunnable> task =
|
||||||
NS_NewRunnableMethodWithArgs<CFRefPtr<CVPixelBufferRef>, AppleVTDecoder::AppleFrameRef>(
|
NS_NewRunnableMethodWithArgs<CFRefPtr<CVPixelBufferRef>, AppleVTDecoder::AppleFrameRef>(
|
||||||
decoder, &AppleVTDecoder::OutputFrame, image, *frameRef);
|
decoder, &AppleVTDecoder::OutputFrame, image, *frameRef);
|
||||||
|
@ -242,6 +241,8 @@ AppleVTDecoder::SubmitFrame(MediaRawData* aSample)
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mQueuedSamples++;
|
||||||
|
|
||||||
VTDecodeFrameFlags decodeFlags =
|
VTDecodeFrameFlags decodeFlags =
|
||||||
kVTDecodeFrame_EnableAsynchronousDecompression;
|
kVTDecodeFrame_EnableAsynchronousDecompression;
|
||||||
rv = VTDecompressionSessionDecodeFrame(mSession,
|
rv = VTDecompressionSessionDecodeFrame(mSession,
|
||||||
|
@ -257,7 +258,7 @@ AppleVTDecoder::SubmitFrame(MediaRawData* aSample)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ask for more data.
|
// Ask for more data.
|
||||||
if (!mInputIncoming) {
|
if (!mInputIncoming && mQueuedSamples <= mMaxRefFrames) {
|
||||||
LOG("AppleVTDecoder task queue empty; requesting more data");
|
LOG("AppleVTDecoder task queue empty; requesting more data");
|
||||||
mCallback->InputExhausted();
|
mCallback->InputExhausted();
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче