@@ -53,49 +53,75 @@ namespace winrt::StyleTransferEffectCpp::implementation
5353 return std::wstring (ids[id].begin (), ids[id].end ());
5454 }
5555
56- void StyleTransferEffect::ProcessFrame (ProcessVideoFrameContext context) {
57-
58- OutputDebugString (L" PF Start | " );
59- // OutputDebugString(index(thread().get_id()).c_str());
60- auto now = std::chrono::high_resolution_clock::now ();
61- VideoFrame inputFrame = context.InputFrame ();
62- VideoFrame outputFrame = context.OutputFrame ();
63- VideoFrame temp = cachedOutput;
64-
65- OutputDebugString (L" PF Eval | " );
66- if (evalStatus == nullptr || evalStatus.Status () != Windows::Foundation::AsyncStatus::Started)
56+ void StyleTransferEffect::SubmitEval (int swapchaindex, VideoFrame input, VideoFrame output, VideoFrame temp) {
57+ // Different way of waiting for a swapchain index to finish?
58+ // Or would it be just setting the output to be a cached frame?
59+ if (bindings[swapchaindex].activetask == nullptr
60+ || bindings[swapchaindex].activetask .Status () != Windows::Foundation::AsyncStatus::Started)
6761 {
68- Binding.Bind (InputImageDescription, inputFrame);
69- Binding.Bind (OutputImageDescription, outputTransformed);
70- auto nowEval = std::chrono::high_resolution_clock::now ();
62+ OutputDebugString (L" PF Start new Eval " );
63+ std::wostringstream ss;
64+ ss << swapchaindex;
65+ OutputDebugString (ss.str ().c_str ());
66+ OutputDebugString (L" | " );
67+
68+ // bind the input and the output buffers by name
69+ bindings[swapchaindex].binding .Bind (InputImageDescription, input);
70+ bindings[swapchaindex].binding .Bind (OutputImageDescription, outputTransformed);
71+ // submit an eval and wait for it to finish submitting work
7172 std::lock_guard<mutex> guard{ Processing };
72- evalStatus = Session.EvaluateAsync (Binding, L" test" );
73- evalStatus.Completed ([&, nowEval](auto && asyncInfo, winrt::Windows::Foundation::AsyncStatus const args) {
73+ bindings[swapchaindex].activetask = Session.EvaluateAsync (bindings[swapchaindex].binding , L" 0" );
74+ bindings[swapchaindex].activetask .Completed ([&](auto && asyncInfo, winrt::Windows::Foundation::AsyncStatus const args) {
75+ OutputDebugString (L" PF Eval completed | " );
76+ // OutputDebugString(ss.str().c_str());
77+ // OutputDebugString(L" | ");
78+
7479 VideoFrame output = asyncInfo.GetResults ().Outputs ().Lookup (OutputImageDescription).try_as <VideoFrame>();
7580 OutputDebugString (L" PF Copy | " );
81+ // OutputDebugString(ss.str().c_str());
82+ // OutputDebugString(L" | ");
83+ // second lock to protect shared resource of cachedOutputCopy
7684 output.CopyToAsync (cachedOutputCopy);
7785 {
7886 cachedOutput = cachedOutputCopy;
7987 }
80- OutputDebugString (L" PF End\n " );
81- auto timePassedEval = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now () - nowEval);
82- std::wostringstream ss;
83- ss << (timePassedEval.count () / 1000 .f );
84- Notifier.SetFrameRate (timePassedEval.count () / 1000 .f );
85- OutputDebugString (L" \n Eval Time : " );
86- OutputDebugString (ss.str ().c_str ());
88+ OutputDebugString (L" PF End " );
89+ // OutputDebugString(ss.str().c_str());
90+ // OutputDebugString(L"\n");
8791 });
88-
8992 }
9093 if (temp != nullptr ) {
9194 OutputDebugString (L" \n Start CopyAsync | " );
92- temp.CopyToAsync (context. OutputFrame ()) .get ();
95+ temp.CopyToAsync (output) .get (); // Make sure using reference, ie. shows up in context.OutputFrame()
9396 OutputDebugString (L" Stop CopyAsync\n " );
9497 }
98+ // return without waiting for the submit to finish, setup the completion handler
99+ }
100+
101+ // Whenever an evaluate async is finished, call this function
102+ void StyleTransferEffect::EvaluateComplete (VideoFrame evalFrame) {
103+ OutputDebugString (L" PF Copy | " );
104+ // second lock to protect shared resource of cachedOutputCopy
105+ evalFrame.CopyToAsync (cachedOutputCopy);
106+ {
107+ cachedOutput = cachedOutputCopy;
108+ }
109+ OutputDebugString (L" PF End\n " );
110+ }
111+
112+ void StyleTransferEffect::ProcessFrame (ProcessVideoFrameContext context) {
113+ OutputDebugString (L" PF Start | " );
114+ // OutputDebugString(index(thread().get_id()).c_str());
115+ auto now = std::chrono::high_resolution_clock::now ();
116+ VideoFrame inputFrame = context.InputFrame ();
117+ VideoFrame outputFrame = context.OutputFrame ();
118+ VideoFrame temp = cachedOutput;
119+
120+ SubmitEval (swapChainIndex, inputFrame, outputFrame, temp);
95121
122+ swapChainIndex = (++swapChainIndex) % swapChainEntryCount; // move on to the next entry after each call to PF.
96123 auto timePassed = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now () - now);
97124 // Notifier.SetFrameRate(1000.f / timePassed.count()); // Convert to FPS: milli to seconds, invert
98-
99125 }
100126
101127 void StyleTransferEffect::SetEncodingProperties (VideoEncodingProperties props, IDirect3DDevice device) {
@@ -124,5 +150,10 @@ namespace winrt::StyleTransferEffectCpp::implementation
124150
125151 InputImageDescription = L" inputImage" ;
126152 OutputImageDescription = L" outputImage" ;
153+
154+ // Create set of bindings to cycle through
155+ for (int i = 0 ; i < swapChainEntryCount; i++) {
156+ bindings[swapChainIndex].binding = LearningModelBinding{ Session };
157+ }
127158 }
128159}
0 commit comments