NS_IMETHODIMP PluginStreamListener::OnStartRequest(nsIRequest* request, nsISupports *ctxt) { AUTO_PROFILER_LABEL("PluginStreamListener::OnStartRequest", NETWORK); nsCOMPtr<nsIContent> embed = mPluginDoc->GetPluginContent(); nsCOMPtr<nsIObjectLoadingContent> objlc = do_QueryInterface(embed); nsCOMPtr<nsIStreamListener> objListener = do_QueryInterface(objlc); if (!objListener) { MOZ_ASSERT_UNREACHABLE("PluginStreamListener without appropriate content " "node"); return NS_BINDING_ABORTED; } SetStreamListener(objListener); // Sets up the ObjectLoadingContent tag as if it is waiting for a // channel, so it can proceed with a load normally once it gets OnStartRequest nsresult rv = objlc->InitializeFromChannel(request); if (NS_FAILED(rv)) { MOZ_ASSERT_UNREACHABLE("InitializeFromChannel failed"); return rv; } // Note that because we're now hooked up to a plugin listener, this will // likely spawn a plugin, which may re-enter. return MediaDocumentStreamListener::OnStartRequest(request, ctxt); }
nsresult OggWriter::WriteEncodedTrack(const EncodedFrameContainer& aData, uint32_t aFlags) { AUTO_PROFILER_LABEL("OggWriter::WriteEncodedTrack", OTHER); uint32_t len = aData.GetEncodedFrames().Length(); for (uint32_t i = 0; i < len; i++) { if (aData.GetEncodedFrames()[i]->GetFrameType() != EncodedFrame::OPUS_AUDIO_FRAME) { LOG("[OggWriter] wrong encoded data type!"); return NS_ERROR_FAILURE; } // only pass END_OF_STREAM on the last frame! nsresult rv = WriteEncodedData(aData.GetEncodedFrames()[i]->GetFrameData(), aData.GetEncodedFrames()[i]->GetDuration(), i < len-1 ? (aFlags & ~ContainerWriter::END_OF_STREAM) : aFlags); if (NS_FAILED(rv)) { LOG("%p Failed to WriteEncodedTrack!", this); return rv; } } return NS_OK; }
nsresult nsNPAPIPluginStreamListener::OnStartBinding(nsPluginStreamListenerPeer* streamPeer) { AUTO_PROFILER_LABEL("nsNPAPIPluginStreamListener::OnStartBinding", OTHER); if (!mInst || !mInst->CanFireNotifications() || mStreamCleanedUp) return NS_ERROR_FAILURE; PluginDestructionGuard guard(mInst); nsNPAPIPlugin* plugin = mInst->GetPlugin(); if (!plugin || !plugin->GetLibrary()) return NS_ERROR_FAILURE; NPPluginFuncs* pluginFunctions = plugin->PluginFuncs(); if (!pluginFunctions->newstream) return NS_ERROR_FAILURE; NPP npp; mInst->GetNPP(&npp); char* contentType; uint16_t streamType = NP_NORMAL; NPError error; streamPeer->GetURL(&mNPStreamWrapper->mNPStream.url); streamPeer->GetLength((uint32_t*)&(mNPStreamWrapper->mNPStream.end)); streamPeer->GetLastModified((uint32_t*)&(mNPStreamWrapper->mNPStream.lastmodified)); streamPeer->GetContentType(&contentType); if (!mResponseHeaders.IsEmpty()) { mResponseHeaderBuf = PL_strdup(mResponseHeaders.get()); mNPStreamWrapper->mNPStream.headers = mResponseHeaderBuf; } mStreamListenerPeer = streamPeer; NPPAutoPusher nppPusher(npp); NS_TRY_SAFE_CALL_RETURN(error, (*pluginFunctions->newstream)(npp, (char*)contentType, &mNPStreamWrapper->mNPStream, false, &streamType), mInst, NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO); NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPP NewStream called: this=%p, npp=%p, mime=%s, seek=%d, type=%d, return=%d, url=%s\n", this, npp, (char *)contentType, false, streamType, error, mNPStreamWrapper->mNPStream.url)); if (error != NPERR_NO_ERROR) return NS_ERROR_FAILURE; mStreamState = eNewStreamCalled; if (streamType != NP_NORMAL) { return NS_ERROR_FAILURE; } return NS_OK; }
void ClientPaintedLayer::PaintThebes(nsTArray<ReadbackProcessor::Update>* aReadbackUpdates) { AUTO_PROFILER_LABEL("ClientPaintedLayer::PaintThebes", GRAPHICS); NS_ASSERTION(ClientManager()->InDrawing(), "Can only draw in drawing phase"); mContentClient->BeginPaint(); uint32_t flags = GetPaintFlags(); PaintState state = mContentClient->BeginPaintBuffer(this, flags); if (!UpdatePaintRegion(state)) { return; } bool didUpdate = false; RotatedContentBuffer::DrawIterator iter; while (DrawTarget* target = mContentClient->BorrowDrawTargetForPainting(state, &iter)) { if (!target || !target->IsValid()) { if (target) { mContentClient->ReturnDrawTargetToBuffer(target); } continue; } SetAntialiasingFlags(this, target); RefPtr<gfxContext> ctx = gfxContext::CreatePreservingTransformOrNull(target); MOZ_ASSERT(ctx); // already checked the target above ClientManager()->GetPaintedLayerCallback()(this, ctx, iter.mDrawRegion, iter.mDrawRegion, state.mClip, state.mRegionToInvalidate, ClientManager()->GetPaintedLayerCallbackData()); ctx = nullptr; mContentClient->ReturnDrawTargetToBuffer(target); didUpdate = true; } mContentClient->EndPaint(aReadbackUpdates); if (didUpdate) { UpdateContentClient(state); } }
nsresult OggWriter::GetContainerData(nsTArray<nsTArray<uint8_t> >* aOutputBufs, uint32_t aFlags) { int rc = -1; AUTO_PROFILER_LABEL("OggWriter::GetContainerData", OTHER); // Generate the oggOpus Header if (aFlags & ContainerWriter::GET_HEADER) { OpusMetadata* meta = static_cast<OpusMetadata*>(mMetadata.get()); NS_ASSERTION(meta, "should have meta data"); NS_ASSERTION(meta->GetKind() == TrackMetadataBase::METADATA_OPUS, "should have Opus meta data"); nsresult rv = WriteEncodedData(meta->mIdHeader, 0); NS_ENSURE_SUCCESS(rv, rv); rc = ogg_stream_flush(&mOggStreamState, &mOggPage); NS_ENSURE_TRUE(rc > 0, NS_ERROR_FAILURE); ProduceOggPage(aOutputBufs); rv = WriteEncodedData(meta->mCommentHeader, 0); NS_ENSURE_SUCCESS(rv, rv); rc = ogg_stream_flush(&mOggStreamState, &mOggPage); NS_ENSURE_TRUE(rc > 0, NS_ERROR_FAILURE); ProduceOggPage(aOutputBufs); return NS_OK; // Force generate a page even if the amount of packet data is not enough. // Usually do so after a header packet. } else if (aFlags & ContainerWriter::FLUSH_NEEDED) { // rc = 0 means no packet to put into a page, or an internal error. rc = ogg_stream_flush(&mOggStreamState, &mOggPage); } else { // rc = 0 means insufficient data has accumulated to fill a page, or an // internal error has occurred. rc = ogg_stream_pageout(&mOggStreamState, &mOggPage); } if (rc) { ProduceOggPage(aOutputBufs); } if (aFlags & ContainerWriter::FLUSH_NEEDED) { mIsWritingComplete = true; } return (rc > 0) ? NS_OK : NS_ERROR_FAILURE; }
nsresult OggWriter::SetMetadata(TrackMetadataBase* aMetadata) { MOZ_ASSERT(aMetadata); AUTO_PROFILER_LABEL("OggWriter::SetMetadata", OTHER); if (aMetadata->GetKind() != TrackMetadataBase::METADATA_OPUS) { LOG("wrong meta data type!"); return NS_ERROR_FAILURE; } // Validate each field of METADATA mMetadata = static_cast<OpusMetadata*>(aMetadata); if (mMetadata->mIdHeader.Length() == 0) { LOG("miss mIdHeader!"); return NS_ERROR_FAILURE; } if (mMetadata->mCommentHeader.Length() == 0) { LOG("miss mCommentHeader!"); return NS_ERROR_FAILURE; } return NS_OK; }
bool ClientLayerManager::EndTransactionInternal(DrawPaintedLayerCallback aCallback, void* aCallbackData, EndTransactionFlags) { PaintTelemetry::AutoRecord record(PaintTelemetry::Metric::Rasterization); AutoProfilerTracing tracing("Paint", "Rasterize"); Maybe<TimeStamp> startTime; if (gfxPrefs::LayersDrawFPS()) { startTime = Some(TimeStamp::Now()); } #ifdef WIN32 if (aCallbackData) { // Content processes don't get OnPaint called. So update here whenever we // may do Thebes drawing. gfxDWriteFont::UpdateClearTypeUsage(); } #endif AUTO_PROFILER_LABEL("ClientLayerManager::EndTransactionInternal", GRAPHICS); #ifdef MOZ_LAYERS_HAVE_LOG MOZ_LAYERS_LOG((" ----- (beginning paint)")); Log(); #endif NS_ASSERTION(InConstruction(), "Should be in construction phase"); mPhase = PHASE_DRAWING; ClientLayer* root = ClientLayer::ToClientLayer(GetRoot()); mTransactionIncomplete = false; // Apply pending tree updates before recomputing effective // properties. GetRoot()->ApplyPendingUpdatesToSubtree(); mPaintedLayerCallback = aCallback; mPaintedLayerCallbackData = aCallbackData; GetRoot()->ComputeEffectiveTransforms(Matrix4x4()); // Skip the painting if the device is in device-reset status. if (!gfxPlatform::GetPlatform()->DidRenderingDeviceReset()) { if (gfxPrefs::AlwaysPaint() && XRE_IsContentProcess()) { TimeStamp start = TimeStamp::Now(); root->RenderLayer(); mLastPaintTime = TimeStamp::Now() - start; } else { root->RenderLayer(); } } else { gfxCriticalNote << "LayerManager::EndTransaction skip RenderLayer()."; } if (!mRepeatTransaction && !GetRoot()->GetInvalidRegion().IsEmpty()) { GetRoot()->Mutated(); } if (!mIsRepeatTransaction) { mAnimationReadyTime = TimeStamp::Now(); GetRoot()->StartPendingAnimations(mAnimationReadyTime); } mPaintedLayerCallback = nullptr; mPaintedLayerCallbackData = nullptr; // Go back to the construction phase if the transaction isn't complete. // Layout will update the layer tree and call EndTransaction(). mPhase = mTransactionIncomplete ? PHASE_CONSTRUCTION : PHASE_NONE; NS_ASSERTION(!aCallback || !mTransactionIncomplete, "If callback is not null, transaction must be complete"); if (gfxPlatform::GetPlatform()->DidRenderingDeviceReset()) { FrameLayerBuilder::InvalidateAllLayers(this); } if (startTime) { PaintTiming& pt = mForwarder->GetPaintTiming(); pt.rasterMs() = (TimeStamp::Now() - startTime.value()).ToMilliseconds(); } return !mTransactionIncomplete; }
NS_IMETHODIMP nsPluginStreamListenerPeer::OnStartRequest(nsIRequest *request, nsISupports* aContext) { nsresult rv = NS_OK; AUTO_PROFILER_LABEL("nsPluginStreamListenerPeer::OnStartRequest", OTHER); if (mRequests.IndexOfObject(request) == -1) { NS_ASSERTION(mRequests.Count() == 0, "Only our initial stream should be unknown!"); TrackRequest(request); } if (mHaveFiredOnStartRequest) { return NS_OK; } mHaveFiredOnStartRequest = true; nsCOMPtr<nsIChannel> channel = do_QueryInterface(request); NS_ENSURE_TRUE(channel, NS_ERROR_FAILURE); // deal with 404 (Not Found) HTTP response, // just return, this causes the request to be ignored. nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel)); if (httpChannel) { uint32_t responseCode = 0; rv = httpChannel->GetResponseStatus(&responseCode); if (NS_FAILED(rv)) { // NPP_Notify() will be called from OnStopRequest // in nsNPAPIPluginStreamListener::CleanUpStream // return error will cancel this request // ...and we also need to tell the plugin that mRequestFailed = true; return NS_ERROR_FAILURE; } if (responseCode > 206) { // not normal uint32_t wantsAllNetworkStreams = 0; // We don't always have an instance here already, but if we do, check // to see if it wants all streams. if (mPluginInstance) { rv = mPluginInstance->GetValueFromPlugin(NPPVpluginWantsAllNetworkStreams, &wantsAllNetworkStreams); // If the call returned an error code make sure we still use our default value. if (NS_FAILED(rv)) { wantsAllNetworkStreams = 0; } } if (!wantsAllNetworkStreams) { mRequestFailed = true; return NS_ERROR_FAILURE; } } } nsAutoCString contentType; rv = channel->GetContentType(contentType); if (NS_FAILED(rv)) return rv; // Check ShouldProcess with content policy RefPtr<nsPluginInstanceOwner> owner; if (mPluginInstance) { owner = mPluginInstance->GetOwner(); } nsCOMPtr<nsIDOMElement> element; nsCOMPtr<nsIDocument> doc; if (owner) { owner->GetDOMElement(getter_AddRefs(element)); owner->GetDocument(getter_AddRefs(doc)); } nsCOMPtr<nsIPrincipal> principal = doc ? doc->NodePrincipal() : nullptr; int16_t shouldLoad = nsIContentPolicy::ACCEPT; rv = NS_CheckContentProcessPolicy(nsIContentPolicy::TYPE_OBJECT_SUBREQUEST, mURL, principal, // loading principal principal, // triggering principal element, contentType, nullptr, &shouldLoad); if (NS_FAILED(rv) || NS_CP_REJECTED(shouldLoad)) { mRequestFailed = true; return NS_ERROR_CONTENT_BLOCKED; } // Get the notification callbacks from the channel and save it as // week ref we'll use it in nsPluginStreamInfo::RequestRead() when // we'll create channel for byte range request. nsCOMPtr<nsIInterfaceRequestor> callbacks; channel->GetNotificationCallbacks(getter_AddRefs(callbacks)); if (callbacks) mWeakPtrChannelCallbacks = do_GetWeakReference(callbacks); nsCOMPtr<nsILoadGroup> loadGroup; channel->GetLoadGroup(getter_AddRefs(loadGroup)); if (loadGroup) mWeakPtrChannelLoadGroup = do_GetWeakReference(loadGroup); int64_t length; rv = channel->GetContentLength(&length); // it's possible for the server to not send a Content-Length. // we should still work in this case. if (NS_FAILED(rv) || length < 0 || length > UINT32_MAX) { // check out if this is file channel nsCOMPtr<nsIFileChannel> fileChannel = do_QueryInterface(channel); if (fileChannel) { // file does not exist mRequestFailed = true; return NS_ERROR_FAILURE; } mLength = 0; } else { mLength = uint32_t(length); } nsCOMPtr<nsIURI> aURL; rv = channel->GetURI(getter_AddRefs(aURL)); if (NS_FAILED(rv)) return rv; aURL->GetSpec(mURLSpec); if (!contentType.IsEmpty()) mContentType = contentType; #ifdef PLUGIN_LOGGING MOZ_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_NOISY, ("nsPluginStreamListenerPeer::OnStartRequest this=%p request=%p mime=%s, url=%s\n", this, request, contentType.get(), mURLSpec.get())); PR_LogFlush(); #endif // Set up the stream listener... rv = SetUpStreamListener(request, aURL); if (NS_FAILED(rv)) { return rv; } return rv; }