Skip to content
This repository has been archived by the owner on Jul 19, 2024. It is now read-only.

Enable audio support in MRVC #268

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
<Button x:Name="bnListen" Content="Start Listening" Click="bnListen_Click" Margin="0,0,5,0"/>
<Button x:Name="bnClose" Content="Close" Click="bnClose_Click" Margin="0,0,5,0"/>
<TextBox x:Name="txPort" Text="27772" InputScope="Number" MaxLength="5" Margin="0,0,5,0" />
<CheckBox x:Name="cbEnableAudio" Content="Capture Audio"></CheckBox>
</StackPanel>
</StackPanel>
</Grid>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,14 @@ private async void bnListen_Click(object sender, RoutedEventArgs e)
this.connection.Disconnected += Connection_Disconnected;
this.connection.Received += Connection_Received;

StartCapture();
StartCapture(cbEnableAudio.IsChecked.GetValueOrDefault(false));
}
}
}

private async void StartCapture()
private async void StartCapture(bool enableAudio)
{
captureEngine = await CaptureEngine.CreateAsync(false);
captureEngine = await CaptureEngine.CreateAsync(enableAudio);
if (this.captureEngine != null)
{
await this.captureEngine.StartAsync(false, this.connection);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@
<Capability Name="privateNetworkClientServer" />
<Capability Name="internetClient" />
<DeviceCapability Name="webcam" />
<DeviceCapability Name="microphone" />
</Capabilities>
</Package>
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ HRESULT CaptureEngineImpl::StartAsync(
ComPtr<MixedRemoteViewCompositor::Media::MrcAudioEffectDefinitionImpl> mrcAudioEffectDefinition;
MakeAndInitialize<MrcAudioEffectDefinitionImpl>(&mrcAudioEffectDefinition);

IFR(mrcAudioEffectDefinition->put_MixerMode(AudioMixerMode_Mic));
IFR(mrcAudioEffectDefinition->put_MixerMode(AudioMixerMode_MicAndLoopback));

ComPtr<ABI::Windows::Media::Effects::IAudioEffectDefinition> audioEffectDefinition;
IFR(mrcAudioEffectDefinition.As(&audioEffectDefinition));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,8 @@ HRESULT PlaybackEngineImpl::StartPlayback()

NULL_CHK_HR(_sourceReader, E_NOT_SET);

IFR(RequestNextSampleAsync(MF_SOURCE_READER_FIRST_VIDEO_STREAM));
IFR(RequestNextSampleAsync(MF_SOURCE_READER_ANY_STREAM));
//IFR(RequestNextSampleAsync(MF_SOURCE_READER_FIRST_VIDEO_STREAM));

//IFR(RequestNextSampleAsync(MF_SOURCE_READER_FIRST_AUDIO_STREAM));

Expand Down
174 changes: 90 additions & 84 deletions MixedRemoteViewCompositor/Source/Shared/Network/Connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -327,111 +327,117 @@ HRESULT ConnectionImpl::SendBundle(

_Use_decl_annotations_
HRESULT ConnectionImpl::SendBundleAsync(
IDataBundle *dataBundle,
IAsyncAction **sendAction)
IDataBundle *dataBundle,
IAsyncAction **sendAction)
{
Log(Log_Level_Info, L"ConnectionImpl::SendBundleAsync\n");
Log(Log_Level_Info, L"ConnectionImpl::SendBundleAsyncSequenced\n");

NULL_CHK(dataBundle);
NULL_CHK(sendAction);
NULL_CHK(dataBundle);
NULL_CHK(sendAction);

{
auto lock = _lock.Lock();
{
auto lock = _lock.Lock();

IFR(CheckClosed());
}
IFR(CheckClosed());
}

UINT32 bufferCount = 0;
IFR(dataBundle->get_BufferCount(&bufferCount));
ComPtr<WriteCompleteImpl> spWriteAction;
IFR(MakeAndInitialize<WriteCompleteImpl>(&spWriteAction, 1));

ComPtr<WriteCompleteImpl> spWriteAction;
IFR(MakeAndInitialize<WriteCompleteImpl>(&spWriteAction, bufferCount));
// define workitem
ComPtr<IDataBundle> spDataBundle(dataBundle);
ComPtr<ConnectionImpl> spThis(this);
auto workItem =
Microsoft::WRL::Callback<ABI::Windows::System::Threading::IWorkItemHandler>(
[this, spThis, spDataBundle, spWriteAction](IAsyncAction* asyncAction) -> HRESULT
{
ComPtr<IOutputStream> spOutputStream;
DataBundleImpl::Container buffers;
DataBundleImpl::Iterator iter;

// define workitem
ComPtr<IDataBundle> spDataBundle(dataBundle);
ComPtr<ConnectionImpl> spThis(this);
auto workItem =
Microsoft::WRL::Callback<ABI::Windows::System::Threading::IWorkItemHandler>(
[this, spThis, spDataBundle, spWriteAction](IAsyncAction* asyncAction) -> HRESULT
{
ComPtr<IOutputStream> spOutputStream;
DataBundleImpl::Container buffers;
DataBundleImpl::Iterator iter;
ComPtr<IStreamWriteOperation> writeOperation;
ComPtr<IBuffer> rawBuffer;
ComPtr<IDataBuffer> singleBuffer;

HRESULT hr = S_OK;
HRESULT hr = S_OK;

{
auto lock = _lock.Lock();

IFC(CheckClosed());

// get the output stream for socket
if (nullptr != _streamSocket)
{
IFC(_streamSocket->get_OutputStream(&spOutputStream));
}
else
{
IFC(E_UNEXPECTED);
}
}
{
auto lock = _lock.Lock();

DataBundleImpl* bundleImpl = static_cast<DataBundleImpl*>(spDataBundle.Get());
if (nullptr == bundleImpl)
{
IFC(E_INVALIDARG);
}
IFC(CheckClosed());

// send one buffer at a time syncronously
IFC(bundleImpl->get_Buffers(&buffers));
iter = buffers.begin();
for (; iter != buffers.end(); ++iter)
{
ComPtr<IStreamWriteOperation> spWriteOperation;
ComPtr<IBuffer> rawBuffer;
IFC((*iter).As(&rawBuffer));
// get the output stream for socket
if (nullptr != _streamSocket)
{
IFC(_streamSocket->get_OutputStream(&spOutputStream));
}
else
{
IFC(E_UNEXPECTED);
}
}

IFC(spOutputStream->WriteAsync(rawBuffer.Get(), &spWriteOperation));
DataBundleImpl* bundleImpl = static_cast<DataBundleImpl*>(spDataBundle.Get());
if (nullptr == bundleImpl)
{
IFC(E_INVALIDARG);
}

// start async write operation
IFC(StartAsyncThen(
spWriteOperation.Get(),
[this, spThis, spWriteAction](_In_ HRESULT hr, _In_ IStreamWriteOperation *asyncResult, _In_ AsyncStatus asyncStatus) -> HRESULT
{
LOG_RESULT(hr);
//make a single big buffer
ULONG totalSize;
IFC(bundleImpl->get_TotalSize(&totalSize));

spWriteAction->SignalCompleted(hr);
IFC(MakeAndInitialize<DataBufferImpl>(&singleBuffer, totalSize));

return S_OK;
}));
}
DataBufferImpl * bufferImpl = static_cast<DataBufferImpl*>(singleBuffer.Get());

done:
if (FAILED(hr))
{
spWriteAction->SignalCompleted(hr);
}
if (nullptr == bufferImpl)
{
IFC(E_INVALIDARG);
}

return S_OK;
});
BYTE* rawSingleBuffer;
IFC(bufferImpl->get_Buffer(&rawSingleBuffer));

ComPtr<IAsyncAction> workerAsync;
IFR(_threadPoolStatics->RunAsync(workItem.Get(), &workerAsync));
DWORD copied;
IFC(bundleImpl->CopyTo(0, totalSize, &rawSingleBuffer[0], &copied));

IFR(StartAsyncThen(
workerAsync.Get(),
[this, spThis, spWriteAction](_In_ HRESULT hr, _In_ IAsyncAction *asyncResult, _In_ AsyncStatus asyncStatus) -> HRESULT
{
if (FAILED(hr))
{
spWriteAction->SignalCompleted(hr);
}
IFC(bufferImpl->put_CurrentLength(copied));

return S_OK;
}));
IFC(singleBuffer.As(&rawBuffer));

IFC(spOutputStream->WriteAsync(rawBuffer.Get(), &writeOperation));

hr = SyncWait<UINT32, UINT32>(writeOperation.Get(), 1);

spWriteAction->SignalCompleted(hr);

done:
if (FAILED(hr))
{
spWriteAction->SignalCompleted(hr);
}

return S_OK;
});

ComPtr<IAsyncAction> workerAsync;
IFR(_threadPoolStatics->RunAsync(workItem.Get(), &workerAsync));

IFR(StartAsyncThen(
workerAsync.Get(),
[this, spThis, spWriteAction](_In_ HRESULT hr, _In_ IAsyncAction *asyncResult, _In_ AsyncStatus asyncStatus) -> HRESULT
{
if (FAILED(hr))
{
spWriteAction->SignalCompleted(hr);
}

return S_OK;
}));

// hand off async op
return spWriteAction.CopyTo(sendAction);
// hand off async op
return spWriteAction.CopyTo(sendAction);
}

// IConnectionInternal
Expand Down