in Shared/HoloLensForCV/MediaFrameSourceGroup.cpp [115:390]
Concurrency::task<void> MediaFrameSourceGroup::InitializeMediaSourceWorkerAsync()
{
return CleanupMediaCaptureAsync()
.then([this]()
{
return Concurrency::create_task(
Windows::Media::Capture::Frames::MediaFrameSourceGroup::FindAllAsync());
}, Concurrency::task_continuation_context::get_current_winrt_context())
.then([this](Windows::Foundation::Collections::IVectorView<Windows::Media::Capture::Frames::MediaFrameSourceGroup^>^ sourceGroups)
{
Windows::Media::Capture::Frames::MediaFrameSourceGroup^ selectedSourceGroup;
for (Windows::Media::Capture::Frames::MediaFrameSourceGroup^ sourceGroup : sourceGroups)
{
const wchar_t* sourceGroupDisplayName =
sourceGroup->DisplayName->Data();
//
// Note: this is the display name of the media frame source group associated
// with the photo/video camera (or, RGB camera) on HoloLens Development Edition.
//
const wchar_t* c_HoloLensDevelopmentEditionPhotoVideoSourceGroupDisplayName =
L"MN34150";
const wchar_t* c_HoloLensResearchModeSensorStreamingGroupDisplayName =
L"Sensor Streaming";
if (MediaFrameSourceGroupType::PhotoVideoCamera == _mediaFrameSourceGroupType &&
(0 == wcscmp(c_HoloLensDevelopmentEditionPhotoVideoSourceGroupDisplayName, sourceGroupDisplayName)))
{
#if DBG_ENABLE_INFORMATIONAL_LOGGING
dbg::trace(
L"MediaFrameSourceGroup::InitializeMediaSourceWorkerAsync: found the photo-video media frame source group.");
#endif /* DBG_ENABLE_INFORMATIONAL_LOGGING */
selectedSourceGroup =
sourceGroup;
break;
}
#if ENABLE_HOLOLENS_RESEARCH_MODE_SENSORS
else if (MediaFrameSourceGroupType::HoloLensResearchModeSensors == _mediaFrameSourceGroupType &&
(0 == wcscmp(c_HoloLensResearchModeSensorStreamingGroupDisplayName, sourceGroupDisplayName)))
{
#if DBG_ENABLE_INFORMATIONAL_LOGGING
dbg::trace(
L"MediaFrameSourceGroup::InitializeMediaSourceWorkerAsync: found the HoloLens Sensor Streaming media frame source group.");
#endif /* DBG_ENABLE_INFORMATIONAL_LOGGING */
selectedSourceGroup =
sourceGroup;
break;
}
#endif /* ENABLE_HOLOLENS_RESEARCH_MODE_SENSORS */
}
if (nullptr == selectedSourceGroup)
{
#if DBG_ENABLE_INFORMATIONAL_LOGGING
dbg::trace(
L"MediaFrameSourceGroup::InitializeMediaSourceWorkerAsync: selected media frame source group not found.");
#endif /* DBG_ENABLE_INFORMATIONAL_LOGGING */
return Concurrency::task_from_result();
}
//
// Initialize MediaCapture with the selected group.
//
return TryInitializeMediaCaptureAsync(selectedSourceGroup)
.then([this, selectedSourceGroup](bool initialized)
{
if (!initialized)
{
return CleanupMediaCaptureAsync();
}
//
// Set up frame readers, register event handlers and start streaming.
//
auto startedSensors =
std::make_shared<std::unordered_set<SensorType, SensorTypeHash>>();
Concurrency::task<void> createReadersTask =
Concurrency::task_from_result();
#if DBG_ENABLE_INFORMATIONAL_LOGGING
dbg::trace(
L"MediaFrameSourceGroup::InitializeMediaSourceWorkerAsync: selected group has %i media frame sources",
_mediaCapture->FrameSources->Size);
#endif /* DBG_ENABLE_INFORMATIONAL_LOGGING */
for (Windows::Foundation::Collections::IKeyValuePair<Platform::String^, Windows::Media::Capture::Frames::MediaFrameSource^>^ kvp : _mediaCapture->FrameSources)
{
Windows::Media::Capture::Frames::MediaFrameSource^ source =
kvp->Value;
createReadersTask = createReadersTask.then([this, startedSensors, source]()
{
SensorType sensorType =
GetSensorType(
source);
if (SensorType::Undefined == sensorType)
{
//
// We couldn't map the source to a Research Mode sensor type. Ignore this source.
//
#if DBG_ENABLE_INFORMATIONAL_LOGGING
dbg::trace(
L"MediaFrameSourceGroup::InitializeMediaSourceWorkerAsync: could not map the media frame source to a Research Mode sensor type!");
#endif /* DBG_ENABLE_INFORMATIONAL_LOGGING */
return Concurrency::task_from_result();
}
else if (startedSensors->find(sensorType) != startedSensors->end())
{
//
// We couldn't map the source to a Research Mode sensor type. Ignore this source.
//
#if DBG_ENABLE_INFORMATIONAL_LOGGING
dbg::trace(
L"MediaFrameSourceGroup::InitializeMediaSourceWorkerAsync: sensor type %s has already been initialized!",
sensorType.ToString());
#endif /* DBG_ENABLE_INFORMATIONAL_LOGGING */
return Concurrency::task_from_result();
}
else if (!IsEnabled(sensorType))
{
//
// The sensor type was not explicitly enabled by user. Ignore this source.
//
#if DBG_ENABLE_INFORMATIONAL_LOGGING
dbg::trace(
L"MediaFrameSourceGroup::InitializeMediaSourceWorkerAsync: sensor type %s has not been enabled!",
sensorType.ToString());
#endif /* DBG_ENABLE_INFORMATIONAL_LOGGING */
return Concurrency::task_from_result();
}
//
// Look for a format which the FrameRenderer can render.
//
Platform::String^ requestedSubtype =
nullptr;
auto found =
std::find_if(
begin(source->SupportedFormats),
end(source->SupportedFormats),
[&](Windows::Media::Capture::Frames::MediaFrameFormat^ format)
{
requestedSubtype =
GetSubtypeForFrameReader(
source->Info->SourceKind,
format);
return requestedSubtype != nullptr;
});
if (requestedSubtype == nullptr)
{
//
// No acceptable format was found. Ignore this source.
//
return Concurrency::task_from_result();
}
//
// Tell the source to use the format we can render.
//
return Concurrency::create_task(
source->SetFormatAsync(*found))
.then([this, source, requestedSubtype]()
{
return Concurrency::create_task(
_mediaCapture->CreateFrameReaderAsync(
source,
requestedSubtype));
}, Concurrency::task_continuation_context::get_current_winrt_context())
.then([this, sensorType](Windows::Media::Capture::Frames::MediaFrameReader^ frameReader)
{
ISensorFrameSink^ optionalSensorFrameSink =
nullptr != _optionalSensorFrameSinkGroup
? _optionalSensorFrameSinkGroup->GetSensorFrameSink(
sensorType)
: nullptr;
MediaFrameReaderContext^ frameReaderContext =
ref new MediaFrameReaderContext(
sensorType,
_spatialPerception,
optionalSensorFrameSink);
_frameReaders[(int32_t)sensorType] =
frameReaderContext;
Windows::Foundation::EventRegistrationToken token =
frameReader->FrameArrived +=
ref new Windows::Foundation::TypedEventHandler<
Windows::Media::Capture::Frames::MediaFrameReader^,
Windows::Media::Capture::Frames::MediaFrameArrivedEventArgs^>(
frameReaderContext,
&MediaFrameReaderContext::FrameArrived);
//
// Keep track of created reader and event handler so it can be stopped later.
//
_frameEventRegistrations.push_back(
std::make_pair(
frameReader,
token));
#if DBG_ENABLE_INFORMATIONAL_LOGGING
dbg::trace(
L"MediaFrameSourceGroup::InitializeMediaSourceWorkerAsync: created the '%s' frame reader",
sensorType.ToString()->Data());
#endif /* DBG_ENABLE_INFORMATIONAL_LOGGING */
return Concurrency::create_task(
frameReader->StartAsync());
}, Concurrency::task_continuation_context::get_current_winrt_context())
.then([this, sensorType, startedSensors](Windows::Media::Capture::Frames::MediaFrameReaderStartStatus status)
{
if (status == Windows::Media::Capture::Frames::MediaFrameReaderStartStatus::Success)
{
#if DBG_ENABLE_INFORMATIONAL_LOGGING
dbg::trace(
L"MediaFrameSourceGroup::InitializeMediaSourceWorkerAsync: started the '%s' frame reader",
sensorType.ToString()->Data());
#endif /* DBG_ENABLE_INFORMATIONAL_LOGGING */
startedSensors->insert(
sensorType);
}
else
{
#if DBG_ENABLE_ERROR_LOGGING
dbg::trace(
L"MediaFrameSourceGroup::InitializeMediaSourceWorkerAsync: unable to start the '%s' frame reader. Error: %s",
sensorType.ToString()->Data(),
status.ToString()->Data());
#endif /* DBG_ENABLE_ERROR_LOGGING */
}
}, Concurrency::task_continuation_context::get_current_winrt_context());
}, Concurrency::task_continuation_context::get_current_winrt_context());
}
//
// Run the loop and see if any sources were used.
//
return createReadersTask.then([this, startedSensors, selectedSourceGroup]()
{
if (startedSensors->size() == 0)
{
#if DBG_ENABLE_INFORMATIONAL_LOGGING
dbg::trace(
L"MediaFrameSourceGroup::InitializeMediaSourceWorkerAsync: no eligible sources in '%s'",
selectedSourceGroup->DisplayName->Data());
#endif /* DBG_ENABLE_INFORMATIONAL_LOGGING */
}
}, Concurrency::task_continuation_context::get_current_winrt_context());
}, Concurrency::task_continuation_context::get_current_winrt_context());
}, Concurrency::task_continuation_context::get_current_winrt_context());
}