VOID Dx9Overlay_Present( IDirect3DDevice9* Device ) { static BOOLEAN initialized = FALSE; // Screenshot here (before we render) to exclude menu Dx9OvRender(Device); // Screenshot here (after we render) to include our menu if (TakeScreenShot) { MakeScreenShot(false); TakeScreenShot = false; } if (StartRecording) { StartRecording = FALSE; Recording = TRUE; InitFreqUnits(); InitializeAviFile(); } else if (StopRecording) { StopRecording = FALSE; Recording = FALSE; CreateThread(0, 0, &CloseAVI, 0, 0, 0); } if (Recording) { BOOLEAN result = RecordFrame(); if (!result) { OvLog(L"Dx9Overlay_Present: Failed to record frame"); } DebugRec(); //Put this after RecordFrame() to exclude it from recorded video. } if (!initialized) { if (D3D9Overlay->VsyncOverrideMode == VSYNC_FORCE_ON || D3D9Overlay->VsyncOverrideMode == VSYNC_FORCE_OFF) { D3D9Hook_ForceReset = TRUE; } initialized = TRUE; GraphicsApi = API_D3D9; } }
void LayerManagerD3D9::Render() { if (mSwapChain->PrepareForRendering() != DeviceOK) { return; } deviceManager()->SetupRenderState(); SetupPipeline(); if (CompositingDisabled()) { static_cast<LayerD3D9*>(mRoot->ImplData())->RenderLayer(); return; } nsIntRect rect; mWidget->GetClientBounds(rect); device()->Clear(0, nullptr, D3DCLEAR_TARGET, 0x00000000, 0, 0); device()->BeginScene(); const nsIntRect *clipRect = mRoot->GetClipRect(); RECT r; if (clipRect) { r.left = (LONG)clipRect->x; r.top = (LONG)clipRect->y; r.right = (LONG)(clipRect->x + clipRect->width); r.bottom = (LONG)(clipRect->y + clipRect->height); } else { r.left = r.top = 0; r.right = rect.width; r.bottom = rect.height; } device()->SetScissorRect(&r); static_cast<LayerD3D9*>(mRoot->ImplData())->RenderLayer(); device()->EndScene(); if (!mTarget) { const nsIntRect *r; for (nsIntRegionRectIterator iter(mClippingRegion); (r = iter.Next()) != nullptr;) { mSwapChain->Present(*r); } RecordFrame(); PostPresent(); } else { PaintToTarget(); } }
void C4Video::Execute() // Record frame, draw status { #ifdef _WIN32 // Not active if (!Active) return; // Flash time if (ShowFlash) ShowFlash--; // Record if (Recording) RecordFrame(); // Draw Draw(); #endif }
void LayerManagerComposite::Render() { PROFILER_LABEL("LayerManagerComposite", "Render", js::ProfileEntry::Category::GRAPHICS); if (mDestroyed) { NS_WARNING("Call on destroyed layer manager"); return; } // At this time, it doesn't really matter if these preferences change // during the execution of the function; we should be safe in all // permutations. However, may as well just get the values onces and // then use them, just in case the consistency becomes important in // the future. bool invertVal = gfxPrefs::LayersEffectInvert(); bool grayscaleVal = gfxPrefs::LayersEffectGrayscale(); float contrastVal = gfxPrefs::LayersEffectContrast(); bool haveLayerEffects = (invertVal || grayscaleVal || contrastVal != 0.0); // Set LayerScope begin/end frame LayerScopeAutoFrame frame(PR_Now()); // Dump to console if (gfxPrefs::LayersDump()) { this->Dump(); } else if (profiler_feature_active("layersdump")) { std::stringstream ss; Dump(ss); profiler_log(ss.str().c_str()); } // Dump to LayerScope Viewer if (LayerScope::CheckSendable()) { // Create a LayersPacket, dump Layers into it and transfer the // packet('s ownership) to LayerScope. auto packet = MakeUnique<layerscope::Packet>(); layerscope::LayersPacket* layersPacket = packet->mutable_layers(); this->Dump(layersPacket); LayerScope::SendLayerDump(Move(packet)); } /** Our more efficient but less powerful alter ego, if one is available. */ nsRefPtr<Composer2D> composer2D; composer2D = mCompositor->GetWidget()->GetComposer2D(); // We can't use composert2D if we have layer effects if (!mTarget && !haveLayerEffects && gfxPrefs::Composer2DCompositionEnabled() && composer2D && composer2D->HasHwc() && composer2D->TryRenderWithHwc(mRoot, mCompositor->GetWidget(), mGeometryChanged)) { LayerScope::SetHWComposed(); if (mFPS) { double fps = mFPS->mCompositionFps.AddFrameAndGetFps(TimeStamp::Now()); if (gfxPrefs::LayersDrawFPS()) { printf_stderr("HWComposer: FPS is %g\n", fps); } } mCompositor->EndFrameForExternalComposition(Matrix()); // Reset the invalid region as compositing is done mInvalidRegion.SetEmpty(); mLastFrameMissedHWC = false; return; } else if (!mTarget && !haveLayerEffects) { mLastFrameMissedHWC = !!composer2D; } { PROFILER_LABEL("LayerManagerComposite", "PreRender", js::ProfileEntry::Category::GRAPHICS); if (!mCompositor->GetWidget()->PreRender(this)) { return; } } nsIntRegion invalid; if (mTarget) { invalid = mTargetBounds; } else { invalid = mInvalidRegion; // Reset the invalid region now that we've begun compositing. mInvalidRegion.SetEmpty(); } ParentLayerIntRect clipRect; Rect bounds(mRenderBounds.x, mRenderBounds.y, mRenderBounds.width, mRenderBounds.height); Rect actualBounds; CompositorBench(mCompositor, bounds); if (mRoot->GetClipRect()) { clipRect = *mRoot->GetClipRect(); Rect rect(clipRect.x, clipRect.y, clipRect.width, clipRect.height); mCompositor->BeginFrame(invalid, &rect, bounds, nullptr, &actualBounds); } else { gfx::Rect rect; mCompositor->BeginFrame(invalid, nullptr, bounds, &rect, &actualBounds); clipRect = ParentLayerIntRect(rect.x, rect.y, rect.width, rect.height); } if (actualBounds.IsEmpty()) { mCompositor->GetWidget()->PostRender(this); return; } // Allow widget to render a custom background. mCompositor->GetWidget()->DrawWindowUnderlay(this, IntRect(actualBounds.x, actualBounds.y, actualBounds.width, actualBounds.height)); RefPtr<CompositingRenderTarget> previousTarget; if (haveLayerEffects) { previousTarget = PushGroupForLayerEffects(); } else { mTwoPassTmpTarget = nullptr; } // Render our layers. RootLayer()->Prepare(ViewAs<RenderTargetPixel>(clipRect, PixelCastJustification::RenderTargetIsParentLayerForRoot)); RootLayer()->RenderLayer(ParentLayerIntRect::ToUntyped(clipRect)); if (!mRegionToClear.IsEmpty()) { nsIntRegionRectIterator iter(mRegionToClear); const IntRect *r; while ((r = iter.Next())) { mCompositor->ClearRect(Rect(r->x, r->y, r->width, r->height)); } } if (mTwoPassTmpTarget) { MOZ_ASSERT(haveLayerEffects); PopGroupForLayerEffects(previousTarget, ParentLayerIntRect::ToUntyped(clipRect), grayscaleVal, invertVal, contrastVal); } // Allow widget to render a custom foreground. mCompositor->GetWidget()->DrawWindowOverlay(this, IntRect(actualBounds.x, actualBounds.y, actualBounds.width, actualBounds.height)); // Debugging RenderDebugOverlay(actualBounds); { PROFILER_LABEL("LayerManagerComposite", "EndFrame", js::ProfileEntry::Category::GRAPHICS); mCompositor->EndFrame(); mCompositor->SetDispAcquireFence(mRoot); // Call after EndFrame() } if (composer2D) { composer2D->Render(mCompositor->GetWidget()); } mCompositor->GetWidget()->PostRender(this); RecordFrame(); }
void LayerManagerComposite::Render(const nsIntRegion& aInvalidRegion, const nsIntRegion& aOpaqueRegion) { PROFILER_LABEL("LayerManagerComposite", "Render", js::ProfileEntry::Category::GRAPHICS); if (mDestroyed || !mCompositor || mCompositor->IsDestroyed()) { NS_WARNING("Call on destroyed layer manager"); return; } ClearLayerFlags(mRoot); // At this time, it doesn't really matter if these preferences change // during the execution of the function; we should be safe in all // permutations. However, may as well just get the values onces and // then use them, just in case the consistency becomes important in // the future. bool invertVal = gfxPrefs::LayersEffectInvert(); bool grayscaleVal = gfxPrefs::LayersEffectGrayscale(); float contrastVal = gfxPrefs::LayersEffectContrast(); bool haveLayerEffects = (invertVal || grayscaleVal || contrastVal != 0.0); // Set LayerScope begin/end frame LayerScopeAutoFrame frame(PR_Now()); // Dump to console if (gfxPrefs::LayersDump()) { this->Dump(/* aSorted= */true); } else if (profiler_feature_active("layersdump")) { std::stringstream ss; Dump(ss); profiler_log(ss.str().c_str()); } // Dump to LayerScope Viewer if (LayerScope::CheckSendable()) { // Create a LayersPacket, dump Layers into it and transfer the // packet('s ownership) to LayerScope. auto packet = MakeUnique<layerscope::Packet>(); layerscope::LayersPacket* layersPacket = packet->mutable_layers(); this->Dump(layersPacket); LayerScope::SendLayerDump(Move(packet)); } mozilla::widget::WidgetRenderingContext widgetContext; #if defined(XP_MACOSX) widgetContext.mLayerManager = this; #elif defined(MOZ_WIDGET_ANDROID) widgetContext.mCompositor = GetCompositor(); #endif { PROFILER_LABEL("LayerManagerComposite", "PreRender", js::ProfileEntry::Category::GRAPHICS); if (!mCompositor->GetWidget()->PreRender(&widgetContext)) { return; } } ParentLayerIntRect clipRect; IntRect bounds(mRenderBounds.x, mRenderBounds.y, mRenderBounds.width, mRenderBounds.height); IntRect actualBounds; CompositorBench(mCompositor, bounds); MOZ_ASSERT(mRoot->GetOpacity() == 1); #if defined(MOZ_WIDGET_ANDROID) LayerMetricsWrapper wrapper = GetRootContentLayer(); if (wrapper) { mCompositor->SetClearColor(wrapper.Metadata().GetBackgroundColor()); } else { mCompositor->SetClearColorToDefault(); } #endif if (mRoot->GetClipRect()) { clipRect = *mRoot->GetClipRect(); IntRect rect(clipRect.x, clipRect.y, clipRect.width, clipRect.height); mCompositor->BeginFrame(aInvalidRegion, &rect, bounds, aOpaqueRegion, nullptr, &actualBounds); } else { gfx::IntRect rect; mCompositor->BeginFrame(aInvalidRegion, nullptr, bounds, aOpaqueRegion, &rect, &actualBounds); clipRect = ParentLayerIntRect(rect.x, rect.y, rect.width, rect.height); } if (actualBounds.IsEmpty()) { mCompositor->GetWidget()->PostRender(&widgetContext); return; } // Allow widget to render a custom background. mCompositor->GetWidget()->DrawWindowUnderlay( &widgetContext, LayoutDeviceIntRect::FromUnknownRect(actualBounds)); RefPtr<CompositingRenderTarget> previousTarget; if (haveLayerEffects) { previousTarget = PushGroupForLayerEffects(); } else { mTwoPassTmpTarget = nullptr; } // Render our layers. RootLayer()->Prepare(ViewAs<RenderTargetPixel>(clipRect, PixelCastJustification::RenderTargetIsParentLayerForRoot)); RootLayer()->RenderLayer(clipRect.ToUnknownRect()); if (!mRegionToClear.IsEmpty()) { for (auto iter = mRegionToClear.RectIter(); !iter.Done(); iter.Next()) { const IntRect& r = iter.Get(); mCompositor->ClearRect(Rect(r.x, r.y, r.width, r.height)); } } if (mTwoPassTmpTarget) { MOZ_ASSERT(haveLayerEffects); PopGroupForLayerEffects(previousTarget, clipRect.ToUnknownRect(), grayscaleVal, invertVal, contrastVal); } // Allow widget to render a custom foreground. mCompositor->GetWidget()->DrawWindowOverlay( &widgetContext, LayoutDeviceIntRect::FromUnknownRect(actualBounds)); // Debugging RenderDebugOverlay(actualBounds); { PROFILER_LABEL("LayerManagerComposite", "EndFrame", js::ProfileEntry::Category::GRAPHICS); mCompositor->EndFrame(); // Call after EndFrame() mCompositor->SetDispAcquireFence(mRoot); } mCompositor->GetWidget()->PostRender(&widgetContext); RecordFrame(); }
int MediaSourceV4L2::GrabChunk(void* pChunkBuffer, int& pChunkSize, bool pDropChunk) { AVPacket tPacket; int tFrameFinished = 0; int tBytesDecoded = 0; // lock grabbing mGrabMutex.lock(); if (pChunkBuffer == NULL) { // unlock grabbing mGrabMutex.unlock(); // acknowledge failed MarkGrabChunkFailed("grab buffer is NULL"); return GRAB_RES_INVALID; } if (!mMediaSourceOpened) { // unlock grabbing mGrabMutex.unlock(); // acknowledge failed MarkGrabChunkFailed("video source is closed"); return GRAB_RES_INVALID; } if (mGrabbingStopped) { // unlock grabbing mGrabMutex.unlock(); // acknowledge failed MarkGrabChunkFailed("video source paused"); return GRAB_RES_INVALID; } // Assign appropriate parts of buffer to image planes in pFrameRGB avpicture_fill((AVPicture *)mRGBFrame, (uint8_t *)pChunkBuffer, PIX_FMT_RGB32, mTargetResX, mTargetResY); // Read new packet // return 0 if OK, < 0 if error or end of file. do { // read next frame from video source - blocking if (av_read_frame(mFormatContext, &tPacket) != 0) { // unlock grabbing mGrabMutex.unlock(); // acknowledge failed MarkGrabChunkFailed("couldn't read next video frame"); return GRAB_RES_INVALID; } }while (tPacket.stream_index != mMediaStreamIndex); if ((tPacket.data != NULL) && (tPacket.size > 0)) { #ifdef MSV_DEBUG_PACKETS LOG(LOG_VERBOSE, "Grabbed new video packet:"); LOG(LOG_VERBOSE, " ..duration: %d", tPacket.duration); LOG(LOG_VERBOSE, " ..pts: %ld stream [%d] pts: %ld", tPacket.pts, mMediaStreamIndex, mFormatContext->streams[mMediaStreamIndex]->pts); LOG(LOG_VERBOSE, " ..dts: %ld", tPacket.dts); LOG(LOG_VERBOSE, " ..size: %d", tPacket.size); LOG(LOG_VERBOSE, " ..pos: %ld", tPacket.pos); #endif // log statistics about original packets from device AnnouncePacket(tPacket.size); // decode packet and get a frame if ((!pDropChunk) || (mRecording)) { // Decode the next chunk of data tBytesDecoded = HM_avcodec_decode_video(mCodecContext, mSourceFrame, &tFrameFinished, &tPacket); // emulate set FPS mSourceFrame->pts = GetPtsFromFpsEmulator(); // // transfer the presentation time value // mSourceFrame->pts = tPacket.pts; #ifdef MSV_DEBUG_PACKETS LOG(LOG_VERBOSE, "Source video frame.."); LOG(LOG_VERBOSE, " ..key frame: %d", mSourceFrame->key_frame); switch(mSourceFrame->pict_type) { case AV_PICTURE_TYPE_I: LOG(LOG_VERBOSE, " ..picture type: i-frame"); break; case AV_PICTURE_TYPE_P: LOG(LOG_VERBOSE, " ..picture type: p-frame"); break; case AV_PICTURE_TYPE_B: LOG(LOG_VERBOSE, " ..picture type: b-frame"); break; default: LOG(LOG_VERBOSE, " ..picture type: %d", mSourceFrame->pict_type); break; } LOG(LOG_VERBOSE, " ..pts: %ld", mSourceFrame->pts); LOG(LOG_VERBOSE, " ..coded pic number: %d", mSourceFrame->coded_picture_number); LOG(LOG_VERBOSE, " ..display pic number: %d", mSourceFrame->display_picture_number); #endif // do we have valid data from video decoder? if ((tFrameFinished != 0) && (tBytesDecoded >= 0)) { // ############################ // ### ANNOUNCE FRAME (statistics) // ############################ AnnounceFrame(mSourceFrame); // ############################ // ### RECORD FRAME // ############################ if (mRecording) RecordFrame(mSourceFrame); // ############################ // ### SCALE FRAME (CONVERT) // ############################ if (!pDropChunk) { HM_sws_scale(mScalerContext, mSourceFrame->data, mSourceFrame->linesize, 0, mCodecContext->height, mRGBFrame->data, mRGBFrame->linesize); } }else { // unlock grabbing mGrabMutex.unlock(); // acknowledge failed MarkGrabChunkFailed("couldn't decode video frame"); return GRAB_RES_INVALID; } } av_free_packet(&tPacket); } // return size of decoded frame pChunkSize = avpicture_get_size(PIX_FMT_RGB32, mTargetResX, mTargetResY) * sizeof(uint8_t); // unlock grabbing mGrabMutex.unlock(); mFrameNumber++; // acknowledge success MarkGrabChunkSuccessful(mFrameNumber); return mFrameNumber; }
void LayerManagerComposite::Render() { PROFILER_LABEL("LayerManagerComposite", "Render", js::ProfileEntry::Category::GRAPHICS); if (mDestroyed) { NS_WARNING("Call on destroyed layer manager"); return; } /** Our more efficient but less powerful alter ego, if one is available. */ nsRefPtr<Composer2D> composer2D = mCompositor->GetWidget()->GetComposer2D(); // Set LayerScope begin/end frame LayerScopeAutoFrame frame(PR_Now()); // Dump to console if (gfxPrefs::LayersDump()) { this->Dump(); } // Dump to LayerScope Viewer if (LayerScope::CheckSendable()) { // Create a LayersPacket, dump Layers into it and transfer the // packet('s ownership) to LayerScope. auto packet = MakeUnique<layerscope::Packet>(); layerscope::LayersPacket* layersPacket = packet->mutable_layers(); this->Dump(layersPacket); LayerScope::SendLayerDump(Move(packet)); } if (!mTarget && composer2D && composer2D->TryRender(mRoot, mWorldMatrix, mGeometryChanged)) { if (mFPS) { double fps = mFPS->mCompositionFps.AddFrameAndGetFps(TimeStamp::Now()); if (gfxPrefs::LayersDrawFPS()) { printf_stderr("HWComposer: FPS is %g\n", fps); } } mCompositor->EndFrameForExternalComposition(mWorldMatrix); // Reset the invalid region as compositing is done mInvalidRegion.SetEmpty(); return; } { PROFILER_LABEL("LayerManagerComposite", "PreRender", js::ProfileEntry::Category::GRAPHICS); if (!mCompositor->GetWidget()->PreRender(this)) { return; } } nsIntRegion invalid; if (mTarget) { invalid = mTargetBounds; } else { invalid = mInvalidRegion; // Reset the invalid region now that we've begun compositing. mInvalidRegion.SetEmpty(); } nsIntRect clipRect; Rect bounds(mRenderBounds.x, mRenderBounds.y, mRenderBounds.width, mRenderBounds.height); Rect actualBounds; CompositorBench(mCompositor, bounds); if (mRoot->GetClipRect()) { clipRect = *mRoot->GetClipRect(); WorldTransformRect(clipRect); Rect rect(clipRect.x, clipRect.y, clipRect.width, clipRect.height); mCompositor->BeginFrame(invalid, &rect, mWorldMatrix, bounds, nullptr, &actualBounds); } else { gfx::Rect rect; mCompositor->BeginFrame(invalid, nullptr, mWorldMatrix, bounds, &rect, &actualBounds); clipRect = nsIntRect(rect.x, rect.y, rect.width, rect.height); } if (actualBounds.IsEmpty()) { mCompositor->GetWidget()->PostRender(this); return; } // Allow widget to render a custom background. mCompositor->GetWidget()->DrawWindowUnderlay(this, nsIntRect(actualBounds.x, actualBounds.y, actualBounds.width, actualBounds.height)); // Render our layers. RootLayer()->Prepare(clipRect); RootLayer()->RenderLayer(clipRect); if (!mRegionToClear.IsEmpty()) { nsIntRegionRectIterator iter(mRegionToClear); const nsIntRect *r; while ((r = iter.Next())) { mCompositor->ClearRect(Rect(r->x, r->y, r->width, r->height)); } } // Allow widget to render a custom foreground. mCompositor->GetWidget()->DrawWindowOverlay(this, nsIntRect(actualBounds.x, actualBounds.y, actualBounds.width, actualBounds.height)); // Debugging RenderDebugOverlay(actualBounds); { PROFILER_LABEL("LayerManagerComposite", "EndFrame", js::ProfileEntry::Category::GRAPHICS); mCompositor->EndFrame(); mCompositor->SetFBAcquireFence(mRoot); } mCompositor->GetWidget()->PostRender(this); RecordFrame(); }