12
12
#include " pch.h"
13
13
#include " Scenario1_DisplayDepthColorIR.xaml.h"
14
14
#include " FrameRenderer.h"
15
+ #include < unordered_set>
15
16
16
17
using namespace SDKTemplate ;
17
18
@@ -25,16 +26,6 @@ using namespace Windows::Media::Capture;
25
26
using namespace Windows ::Media::Capture::Frames;
26
27
using namespace Windows ::UI::Xaml::Media::Imaging;
27
28
28
- MediaFrameSourceInfo^ Scenario1_DisplayDepthColorIR::GetFirstSourceInfoOfKind(MediaFrameSourceGroup^ group, MediaFrameSourceKind kind)
29
- {
30
- auto matchingInfo = std::find_if (begin (group->SourceInfos ), end (group->SourceInfos ),
31
- [kind](MediaFrameSourceInfo^ sourceInfo)
32
- {
33
- return sourceInfo->SourceKind == kind;
34
- });
35
- return (matchingInfo != end (group->SourceInfos )) ? *matchingInfo : nullptr ;
36
- }
37
-
38
29
Scenario1_DisplayDepthColorIR::Scenario1_DisplayDepthColorIR ()
39
30
{
40
31
InitializeComponent ();
@@ -73,114 +64,110 @@ task<void> Scenario1_DisplayDepthColorIR::PickNextMediaSourceAsync()
73
64
74
65
task<void > Scenario1_DisplayDepthColorIR::PickNextMediaSourceWorkerAsync ()
75
66
{
76
- struct EligibleGroup
77
- {
78
- MediaFrameSourceGroup^ Group;
79
- std::array<MediaFrameSourceInfo^, 3 > SourceInfos;
80
- };
81
-
82
67
return CleanupMediaCaptureAsync ()
83
68
.then ([this ]()
84
69
{
85
70
return create_task (MediaFrameSourceGroup::FindAllAsync ());
86
- }).then ([this ](IVectorView<MediaFrameSourceGroup^>^ allGroups)
71
+ }, task_continuation_context::get_current_winrt_context ())
72
+ .then ([this ](IVectorView<MediaFrameSourceGroup^>^ allGroups)
87
73
{
88
- // Identify the color, depth, and infrared sources of each group,
89
- // and keep only the groups that have at least one recognized source.
90
- std::vector<EligibleGroup> eligibleGroups;
91
- for (auto group : allGroups)
92
- {
93
- EligibleGroup eligibleGroup;
94
- eligibleGroup.Group = group;
95
- // For each source kind, find the source which offers that kind of media frame,
96
- // or null if there is no such source.
97
- eligibleGroup.SourceInfos [0 ] = GetFirstSourceInfoOfKind (group, MediaFrameSourceKind::Color);
98
- eligibleGroup.SourceInfos [1 ] = GetFirstSourceInfoOfKind (group, MediaFrameSourceKind::Depth);
99
- eligibleGroup.SourceInfos [2 ] = GetFirstSourceInfoOfKind (group, MediaFrameSourceKind::Infrared);
100
- // If any source was found of any kind we support, keep this group.
101
- if (std::any_of (eligibleGroup.SourceInfos .begin (), eligibleGroup.SourceInfos .end (),
102
- [](MediaFrameSourceInfo^ sourceInfo) { return sourceInfo != nullptr ; }))
103
- {
104
- eligibleGroups.push_back (eligibleGroup);
105
- }
106
- }
107
-
108
- if (eligibleGroups.size () == 0 )
74
+ if (allGroups->Size == 0 )
109
75
{
110
- m_logger->Log (" No source group with color, depth or infrared found." );
76
+ m_logger->Log (" No source groups found." );
111
77
return task_from_result ();
112
78
}
113
79
114
80
// Pick next group in the array after each time the Next button is clicked.
115
- m_selectedSourceGroupIndex = (m_selectedSourceGroupIndex + 1 ) % eligibleGroups.size ();
81
+ m_selectedSourceGroupIndex = (m_selectedSourceGroupIndex + 1 ) % allGroups->Size ;
82
+ MediaFrameSourceGroup^ selectedGroup = allGroups->GetAt (m_selectedSourceGroupIndex);
116
83
117
- m_logger->Log (" Found " + eligibleGroups. size () .ToString () + " groups and " +
84
+ m_logger->Log (" Found " + allGroups-> Size .ToString () + " groups and " +
118
85
" selecting index [" + m_selectedSourceGroupIndex.ToString () + " ] : " +
119
- eligibleGroups[m_selectedSourceGroupIndex].Group ->DisplayName );
120
- EligibleGroup selected = eligibleGroups[m_selectedSourceGroupIndex];
86
+ selectedGroup->DisplayName );
121
87
122
88
// Initialize MediaCapture with selected group.
123
- return TryInitializeMediaCaptureAsync (selected. Group )
124
- .then ([this , selected ](bool initialized)
89
+ return TryInitializeMediaCaptureAsync (selectedGroup )
90
+ .then ([this , selectedGroup ](bool initialized)
125
91
{
126
92
if (!initialized)
127
93
{
128
94
return CleanupMediaCaptureAsync ();
129
95
}
130
96
131
97
// Set up frame readers, register event handlers and start streaming.
98
+ auto startedKinds = std::make_shared<std::unordered_set<MediaFrameSourceKind>>();
132
99
task<void > createReadersTask = task_from_result ();
133
- for (size_t i = 0 ; i < selected. SourceInfos . size (); i++ )
100
+ for (IKeyValuePair<String^, MediaFrameSource^>^ kvp : m_mediaCapture-> FrameSources )
134
101
{
135
- MediaFrameSourceInfo^ info = selected. SourceInfos [i] ;
136
- if (info != nullptr )
102
+ MediaFrameSource^ source = kvp-> Value ;
103
+ createReadersTask = createReadersTask. then ([ this , startedKinds, source]( )
137
104
{
138
- createReadersTask = createReadersTask && CreateReaderAsync (selected.Group , info);
139
- }
140
- else
105
+ MediaFrameSourceKind kind = source->Info ->SourceKind ;
106
+
107
+ // Ignore this source if we already have a source of this kind.
108
+ if (startedKinds->find (kind) != startedKinds->end ())
109
+ {
110
+ return task_from_result ();
111
+ }
112
+
113
+ // Look for a format which the FrameRenderer can render.
114
+ String^ requestedSubtype = nullptr ;
115
+ auto found = std::find_if (begin (source->SupportedFormats ), end (source->SupportedFormats ),
116
+ [&](MediaFrameFormat^ format)
117
+ {
118
+ requestedSubtype = FrameRenderer::GetSubtypeForFrameReader (kind, format);
119
+ return requestedSubtype != nullptr ;
120
+ });
121
+ if (requestedSubtype == nullptr )
122
+ {
123
+ // No acceptable format was found. Ignore this source.
124
+ return task_from_result ();
125
+ }
126
+
127
+ // Tell the source to use the format we can render.
128
+ return create_task (source->SetFormatAsync (*found))
129
+ .then ([this , source, requestedSubtype]()
130
+ {
131
+ return create_task (m_mediaCapture->CreateFrameReaderAsync (source, requestedSubtype));
132
+ }, task_continuation_context::get_current_winrt_context ())
133
+ .then ([this , kind](MediaFrameReader^ frameReader)
134
+ {
135
+ EventRegistrationToken token = frameReader->FrameArrived +=
136
+ ref new TypedEventHandler<MediaFrameReader^, MediaFrameArrivedEventArgs^>(this , &Scenario1_DisplayDepthColorIR::FrameReader_FrameArrived);
137
+
138
+ // Keep track of created reader and event handler so it can be stopped later.
139
+ m_readers.push_back (std::make_pair (frameReader, token));
140
+
141
+ m_logger->Log (kind.ToString () + " reader created" );
142
+
143
+ return create_task (frameReader->StartAsync ());
144
+ }, task_continuation_context::get_current_winrt_context ())
145
+ .then ([this , kind, startedKinds](MediaFrameReaderStartStatus status)
146
+ {
147
+ if (status == MediaFrameReaderStartStatus::Success)
148
+ {
149
+ m_logger->Log (" Started " + kind.ToString () + " reader." );
150
+ startedKinds->insert (kind);
151
+ }
152
+ else
153
+ {
154
+ m_logger->Log (" Unable to start " + kind.ToString () + " reader. Error: " + status.ToString ());
155
+ }
156
+ }, task_continuation_context::get_current_winrt_context ());
157
+ }, task_continuation_context::get_current_winrt_context ());
158
+ }
159
+ // Run the loop and see if any sources were used.
160
+ return createReadersTask.then ([this , startedKinds, selectedGroup]()
161
+ {
162
+ if (startedKinds->size () == 0 )
141
163
{
142
- String^ frameKind = (i == 0 ? " Color" : i == 1 ? " Depth" : " Infrared" );
143
- m_logger->Log (" No " + frameKind + " source in group " + selected.Group ->DisplayName );
164
+ m_logger->Log (" No eligible sources in " + selectedGroup->DisplayName + " ." );
144
165
}
145
-
146
- }
147
- return createReadersTask;
148
- });
166
+ }, task_continuation_context::get_current_winrt_context ());
167
+ }, task_continuation_context::get_current_winrt_context ());
149
168
}, task_continuation_context::get_current_winrt_context ());
150
169
}
151
170
152
- task<void > Scenario1_DisplayDepthColorIR::CreateReaderAsync (MediaFrameSourceGroup^ group, MediaFrameSourceInfo^ info)
153
- {
154
- // Access the initialized frame source by looking up the the Id of the source.
155
- // Verify that the Id is present, because it may have left the group while were were
156
- // busy deciding which group to use.
157
- if (!m_mediaCapture->FrameSources ->HasKey (info->Id ))
158
- {
159
- m_logger->Log (" Unable to start " + info->SourceKind .ToString () + " reader: Frame source not found" );
160
- return task_from_result ();
161
- }
162
-
163
- return create_task (m_mediaCapture->CreateFrameReaderAsync (m_mediaCapture->FrameSources ->Lookup (info->Id )))
164
- .then ([this , info](MediaFrameReader^ frameReader)
165
- {
166
- EventRegistrationToken token = frameReader->FrameArrived +=
167
- ref new TypedEventHandler<MediaFrameReader^, MediaFrameArrivedEventArgs^>(this , &Scenario1_DisplayDepthColorIR::FrameReader_FrameArrived);
168
-
169
- m_logger->Log (info->SourceKind .ToString () + " reader created" );
170
-
171
- // Keep track of created reader and event handler so it can be stopped later.
172
- m_readers.push_back (std::make_pair (frameReader, token));
173
-
174
- return create_task (frameReader->StartAsync ());
175
- }).then ([this , info](MediaFrameReaderStartStatus status)
176
- {
177
- if (status != MediaFrameReaderStartStatus::Success)
178
- {
179
- m_logger->Log (" Unable to start " + info->SourceKind .ToString () + " reader. Error: " + status.ToString ());
180
- }
181
- });
182
- }
183
-
184
171
task<bool > Scenario1_DisplayDepthColorIR::TryInitializeMediaCaptureAsync (MediaFrameSourceGroup^ group)
185
172
{
186
173
if (m_mediaCapture != nullptr )
0 commit comments