Bug 1198094: P1. Limit rate at which InputExhausted could be called by mac decoder. r=rillian

This commit is contained in:
Jean-Yves Avenard 2015-08-25 15:33:23 +10:00
Родитель 517ebc93c6
Коммит a2b1b65a1e
3 изменённых файлов: 38 добавлений и 16 удалений

Просмотреть файл

@ -44,6 +44,7 @@ AppleVDADecoder::AppleVDADecoder(const VideoInfo& aConfig,
, mIsShutDown(false)
, mUseSoftwareImages(false)
, mIs106(!nsCocoaFeatures::OnLionOrLater())
, mQueuedSamples(0)
, mMonitor("AppleVideoDecoder")
, mIsFlushing(false)
, mDecoder(nullptr)
@ -213,15 +214,13 @@ PlatformCallback(void* decompressionOutputRefCon,
// FIXME: Distinguish between errors and empty flushed frames.
if (status != noErr || !image) {
NS_WARNING("AppleVDADecoder decoder returned no data");
return;
}
MOZ_ASSERT(CFGetTypeID(image) == CVPixelBufferGetTypeID(),
"AppleVDADecoder returned an unexpected image type");
if (infoFlags & kVDADecodeInfo_FrameDropped)
{
image = nullptr;
} else if (infoFlags & kVDADecodeInfo_FrameDropped) {
NS_WARNING(" ...frame dropped...");
return;
image = nullptr;
} else {
MOZ_ASSERT(image || CFGetTypeID(image) == CVPixelBufferGetTypeID(),
"AppleVDADecoder returned an unexpected image type");
}
AppleVDADecoder* decoder =
@ -278,6 +277,7 @@ AppleVDADecoder::DrainReorderedFrames()
while (!mReorderQueue.IsEmpty()) {
mCallback->Output(mReorderQueue.Pop().get());
}
mQueuedSamples = 0;
}
void
@ -286,6 +286,7 @@ AppleVDADecoder::ClearReorderedFrames()
while (!mReorderQueue.IsEmpty()) {
mReorderQueue.Pop();
}
mQueuedSamples = 0;
}
// Copy and return a decoded frame.
@ -308,6 +309,19 @@ AppleVDADecoder::OutputFrame(CFRefPtr<CVPixelBufferRef> aImage,
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.
nsRefPtr<VideoData> data;
// Bounds.
@ -471,6 +485,8 @@ AppleVDADecoder::SubmitFrame(MediaRawData* aSample)
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
mQueuedSamples++;
OSStatus rv = VDADecoderDecode(mDecoder,
0,
block,
@ -494,7 +510,7 @@ AppleVDADecoder::SubmitFrame(MediaRawData* aSample)
}
// Ask for more data.
if (!mInputIncoming) {
if (!mInputIncoming && mQueuedSamples <= mMaxRefFrames) {
LOG("AppleVDADecoder task queue empty; requesting more data");
mCallback->InputExhausted();
}

Просмотреть файл

@ -122,6 +122,11 @@ protected:
bool mUseSoftwareImages;
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.
Monitor mMonitor;
// Set on reader/decode thread calling Flush() to indicate that output is

Просмотреть файл

@ -167,14 +167,13 @@ PlatformCallback(void* decompressionOutputRefCon,
// Validate our arguments.
if (status != noErr || !image) {
NS_WARNING("VideoToolbox decoder returned no data");
return;
}
if (flags & kVTDecodeInfo_FrameDropped) {
image = nullptr;
} else if (flags & kVTDecodeInfo_FrameDropped) {
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 =
NS_NewRunnableMethodWithArgs<CFRefPtr<CVPixelBufferRef>, AppleVTDecoder::AppleFrameRef>(
decoder, &AppleVTDecoder::OutputFrame, image, *frameRef);
@ -242,6 +241,8 @@ AppleVTDecoder::SubmitFrame(MediaRawData* aSample)
return NS_ERROR_FAILURE;
}
mQueuedSamples++;
VTDecodeFrameFlags decodeFlags =
kVTDecodeFrame_EnableAsynchronousDecompression;
rv = VTDecompressionSessionDecodeFrame(mSession,
@ -257,7 +258,7 @@ AppleVTDecoder::SubmitFrame(MediaRawData* aSample)
}
// Ask for more data.
if (!mInputIncoming) {
if (!mInputIncoming && mQueuedSamples <= mMaxRefFrames) {
LOG("AppleVTDecoder task queue empty; requesting more data");
mCallback->InputExhausted();
}