Fix buffering issues

master
Nikola Forró 7 years ago
parent b065c3f7e3
commit acf168b042

@ -261,87 +261,83 @@ bool mirror(IMMDevice *monitor, IMMDevice *output)
break; break;
} }
UINT32 padding = 0; for (;;)
if ((res = out_client->lpVtbl->GetCurrentPadding(out_client, &padding)) != S_OK)
{
fprintf(stderr, "Failed to get current padding of output client! [0x%08lx]\n", res);
goto out;
}
UINT32 packet_size = 0;
if ((res = capture->lpVtbl->GetNextPacketSize(capture, &packet_size)) != S_OK)
{ {
fprintf(stderr, "Failed to get next packet size of monitor client! [0x%08lx]\n", res); UINT32 padding = 0;
goto out;
}
fprintf(stderr, "packet_size = %d, buffer_size = %d, padding = %d\n", packet_size, buffer_size, padding);
BYTE *mon_data = NULL;
BYTE *out_data = NULL;
UINT32 frames = 0;
DWORD flags = 0;
if (packet_size > buffer_size - padding)
{
if ((res = capture->lpVtbl->GetBuffer(capture, &mon_data, &frames, &flags,
NULL, NULL)) != S_OK)
{
fprintf(stderr, "Failed to get capture buffer of monitor client! [0x%08lx]\n", res);
goto out;
}
if ((res = capture->lpVtbl->ReleaseBuffer(capture, 0)) != S_OK) if ((res = out_client->lpVtbl->GetCurrentPadding(out_client, &padding)) != S_OK)
{ {
fprintf(stderr, "Failed to release capture buffer of monitor client! [0x%08lx]\n", res); fprintf(stderr, "Failed to get current padding of output client! [0x%08lx]\n", res);
goto out; goto out;
} }
} UINT32 packet_size = 0;
else if (packet_size > 0)
{
if ((res = capture->lpVtbl->GetBuffer(capture, &mon_data, &frames, &flags,
NULL, NULL)) != S_OK)
{
fprintf(stderr, "Failed to get capture buffer of monitor client! [0x%08lx]\n", res);
goto out;
}
if ((res = render->lpVtbl->GetBuffer(render, frames, &out_data)) != S_OK) if ((res = capture->lpVtbl->GetNextPacketSize(capture, &packet_size)) != S_OK)
{ {
fprintf(stderr, "Failed to get render buffer of output client! [0x%08lx]\n", res); fprintf(stderr, "Failed to get next packet size of monitor client! [0x%08lx]\n", res);
goto out; goto out;
} }
CopyMemory(out_data, mon_data, frames * format->nBlockAlign); fprintf(stderr, "packet_size = %d, buffer_size = %d, padding = %d\n", packet_size, buffer_size, padding);
if ((res = capture->lpVtbl->ReleaseBuffer(capture, frames)) != S_OK) BYTE *mon_data = NULL;
BYTE *out_data = NULL;
UINT32 frames = 0;
DWORD flags = 0;
if (packet_size == 0)
{ {
fprintf(stderr, "Failed to release capture buffer of monitor client! [0x%08lx]\n", res); // no input data, play silence
goto out;
if ((res = render->lpVtbl->GetBuffer(render, buffer_size - padding, &out_data)) != S_OK)
{
fprintf(stderr, "Failed to get render buffer of output client! [0x%08lx]\n", res);
goto out;
}
if ((res = render->lpVtbl->ReleaseBuffer(render, buffer_size - padding,
AUDCLNT_BUFFERFLAGS_SILENT)) != S_OK)
{
fprintf(stderr, "Failed to release render buffer of output client! [0x%08lx]\n", res);
goto out;
}
break;
} }
else if (packet_size > buffer_size - padding)
if ((res = render->lpVtbl->ReleaseBuffer(render, frames, 0)) != S_OK)
{ {
fprintf(stderr, "Failed to release render buffer of output client! [0x%08lx]\n", res); // output buffer is full, we have to wait
goto out; break;
} }
} else
else
{
if ((res = render->lpVtbl->GetBuffer(render, buffer_size - padding, &out_data)) != S_OK)
{ {
fprintf(stderr, "Failed to get render buffer of output client! [0x%08lx]\n", res); if ((res = capture->lpVtbl->GetBuffer(capture, &mon_data, &frames, &flags,
goto out; NULL, NULL)) != S_OK)
} {
fprintf(stderr, "Failed to get capture buffer of monitor client! [0x%08lx]\n", res);
if ((res = render->lpVtbl->ReleaseBuffer(render, buffer_size - padding, goto out;
AUDCLNT_BUFFERFLAGS_SILENT)) != S_OK) }
{
fprintf(stderr, "Failed to release render buffer of output client! [0x%08lx]\n", res); if ((res = render->lpVtbl->GetBuffer(render, frames, &out_data)) != S_OK)
goto out; {
fprintf(stderr, "Failed to get render buffer of output client! [0x%08lx]\n", res);
goto out;
}
CopyMemory(out_data, mon_data, frames * format->nBlockAlign);
if ((res = capture->lpVtbl->ReleaseBuffer(capture, frames)) != S_OK)
{
fprintf(stderr, "Failed to release capture buffer of monitor client! [0x%08lx]\n", res);
goto out;
}
if ((res = render->lpVtbl->ReleaseBuffer(render, frames, 0)) != S_OK)
{
fprintf(stderr, "Failed to release render buffer of output client! [0x%08lx]\n", res);
goto out;
}
} }
} }
} }

Loading…
Cancel
Save