+++ This bug was initially created as a clone of Bug #639415 +++ I'm breaking this out into its own bug. We don't use the prescaling path when rendering the first few frames of video, because BasicImageContainer::SetScaleHint has not yet been called when they are decoded and BasicPlanarYCbCrImages are created around them. roc says: > We could reorganize nsVideoFrame::BuildLayer so that SetScaleHint gets computed > and called after > if (videoSize.width <= 0 || videoSize.height <= 0 || area.IsEmpty()) > return nsnull; > and before we check for an actual image. That should make scale hints available > to the decoder much earlier.
We're bailing on the videoSize check because it's not set yet. The decoder doesn't set it until the first nsMediaDecoder::Invalidate fires (via nsBuiltinDecoder::MetadataLoaded dispatched to the main thread). It's further complicated by the fact that a bunch of frames are decoded very early during the call to nsBuilinDecoderReader::FindStartTime, which is called as part of the metadata loading process.
So one fix would be to change the metadata loading logic so that it fires a synchronous event to update the media element's size as soon as it's known, then carry on with the rest of the metadata loading logic (including FindStartTime).
And that turns out to be tricky because we need the logic in nsMediaDecoder::SetVideoData/nsMediaDecoder::Invalidate to compute the element's size... and for that we need an Image.
Seems like we could factor out that code so the size can also be computed from th nsVideoInfo. Then nsBuiltinDecoderStateMachine::LoadMetadata could compute the size and do a synchronous event dispatch to the main thread so set the media size early. This would probably be good for getting the video frame size set correctly earlier for intrinsically-sized video elements as well.
It might make sense to dispatch that new event asynchronously instead of synchronously.