Commit 1cc65c49 authored by Ghislain MARY's avatar Ghislain MARY

Prevent two instances of the reader or of the writer to conflict.

parent 85545b2e
......@@ -53,9 +53,7 @@ static void ms_wasapi_read_process(MSFilter *f) {
if (!r->isStarted()) {
r->start();
}
if (r->isStarted()) {
r->feed(f->outputs[0]);
}
r->feed(f);
}
static void ms_wasapi_read_postprocess(MSFilter *f) {
......@@ -185,9 +183,7 @@ static void ms_wasapi_write_process(MSFilter *f) {
if (!w->isStarted()) {
w->start();
}
if (w->isStarted()) {
w->feed(f->inputs[0]);
}
w->feed(f);
}
static void ms_wasapi_write_postprocess(MSFilter *f) {
......
......@@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "mediastreamer2/mscommon.h"
#include "mediastreamer2/msticker.h"
#include "mswasapi_reader.h"
......@@ -44,6 +45,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
}
bool MSWASAPIReader::smInstantiated = false;
MSWASAPIReader::MSWASAPIReader()
: mAudioClient(NULL), mAudioCaptureClient(NULL), mBufferFrameCount(0), mIsInitialized(false), mIsActivated(false), mIsStarted(false)
{
......@@ -55,6 +59,15 @@ MSWASAPIReader::MSWASAPIReader()
ms_error("Could not get the CaptureId of the MSWASAPI audio input interface");
goto error;
}
if (smInstantiated) {
ms_error("An MSWASAPIReader is already instantiated. A second one can not be created.");
// Initialize the frame rate and the number of channels to be able to generate silence.
mRate = 8000;
mNChannels = 1;
return;
}
result = ActivateAudioInterface(mCaptureId, IID_IAudioClient, (void **)&mAudioClient);
REPORT_ERROR("Could not activate the MSWASAPI audio input interface [%i]", result);
result = mAudioClient->GetMixFormat(&pWfx);
......@@ -63,6 +76,7 @@ MSWASAPIReader::MSWASAPIReader()
mNChannels = pWfx->nChannels;
FREE_PTR(pWfx);
mIsInitialized = true;
smInstantiated = true;
error:
return;
......@@ -72,6 +86,7 @@ MSWASAPIReader::~MSWASAPIReader()
{
RELEASE_CLIENT(mAudioClient);
FREE_PTR(mCaptureId);
smInstantiated = false;
}
......@@ -155,7 +170,7 @@ void MSWASAPIReader::stop()
}
}
int MSWASAPIReader::feed(MSQueue *output)
int MSWASAPIReader::feed(MSFilter *f)
{
HRESULT result;
DWORD flags;
......@@ -164,24 +179,46 @@ int MSWASAPIReader::feed(MSQueue *output)
mblk_t *m;
int bytesPerFrame = (16 * mNChannels / 8);
result = mAudioCaptureClient->GetNextPacketSize(&numFramesInNextPacket);
REPORT_ERROR("Could not get next packet size for the MSWASAPI audio input interface [%i]", result);
if (numFramesInNextPacket > 0) {
m = allocb(numFramesInNextPacket * bytesPerFrame, 0);
result = mAudioCaptureClient->GetBuffer(&pData, &numFramesInNextPacket, &flags, NULL, NULL);
REPORT_ERROR("Could not get buffer from the MSWASAPI audio input interface [%i]", result);
if (flags & AUDCLNT_BUFFERFLAGS_SILENT) {
memset(m->b_wptr, 0, numFramesInNextPacket * bytesPerFrame);
} else {
memcpy(m->b_wptr, pData, numFramesInNextPacket * bytesPerFrame);
if (isStarted()) {
result = mAudioCaptureClient->GetNextPacketSize(&numFramesInNextPacket);
REPORT_ERROR("Could not get next packet size for the MSWASAPI audio input interface [%i]", result);
if (numFramesInNextPacket > 0) {
m = allocb(numFramesInNextPacket * bytesPerFrame, 0);
if (m == NULL) {
ms_error("Could not allocate memory for the captured data from the MSWASAPI audio input interface");
goto error;
}
result = mAudioCaptureClient->GetBuffer(&pData, &numFramesInNextPacket, &flags, NULL, NULL);
REPORT_ERROR("Could not get buffer from the MSWASAPI audio input interface [%i]", result);
if (flags & AUDCLNT_BUFFERFLAGS_SILENT) {
memset(m->b_wptr, 0, numFramesInNextPacket * bytesPerFrame);
} else {
memcpy(m->b_wptr, pData, numFramesInNextPacket * bytesPerFrame);
}
m->b_wptr += numFramesInNextPacket * bytesPerFrame;
result = mAudioCaptureClient->ReleaseBuffer(numFramesInNextPacket);
REPORT_ERROR("Could not release buffer of the MSWASAPI audio input interface [%i]", result);
ms_queue_put(f->outputs[0], m);
}
m->b_wptr += numFramesInNextPacket * bytesPerFrame;
result = mAudioCaptureClient->ReleaseBuffer(numFramesInNextPacket);
REPORT_ERROR("Could not release buffer of the MSWASAPI audio input interface [%i]", result);
ms_queue_put(output, m);
} else {
silence(f);
}
return 0;
error:
return -1;
}
void MSWASAPIReader::silence(MSFilter *f)
{
mblk_t *om;
unsigned int bufsize;
unsigned int nsamples;
nsamples = (f->ticker->interval * mRate) / 1000;
bufsize = nsamples * mNChannels * 2;
om = allocb(bufsize, 0);
memset(om->b_wptr, 0, bufsize);
om->b_wptr += bufsize;
ms_queue_put(f->outputs[0], om);
}
\ No newline at end of file
......@@ -21,7 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "mediastreamer2/msqueue.h"
#include "mediastreamer2/msfilter.h"
#include <objbase.h>
#include <audioclient.h>
......@@ -38,12 +38,15 @@ public:
bool isStarted() { return mIsStarted; }
void start();
void stop();
int feed(MSQueue *output);
int feed(MSFilter *f);
int getRate() { return mRate; }
int getNChannels() { return mNChannels; }
private:
void silence(MSFilter *f);
static bool smInstantiated;
LPCWSTR mCaptureId;
IAudioClient *mAudioClient;
IAudioCaptureClient *mAudioCaptureClient;
......
......@@ -44,6 +44,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
}
bool MSWASAPIWriter::smInstantiated = false;
MSWASAPIWriter::MSWASAPIWriter()
: mAudioClient(NULL), mAudioRenderClient(NULL), mBufferFrameCount(0), mIsInitialized(false), mIsActivated(false), mIsStarted(false)
{
......@@ -56,6 +59,12 @@ MSWASAPIWriter::MSWASAPIWriter()
ms_error("Could not get the RenderId of the MSWASAPI audio output interface");
goto error;
}
if (smInstantiated) {
ms_error("An MSWASAPIWriter is already instantiated. A second one can not be created.");
return;
}
result = ActivateAudioInterface(mRenderId, IID_IAudioClient, (void **)&mAudioClient);
REPORT_ERROR("Could not activate the MSWASAPI audio output interface [%i]", result);
result = mAudioClient->GetMixFormat(&pWfx);
......@@ -64,6 +73,7 @@ MSWASAPIWriter::MSWASAPIWriter()
mNChannels = pWfx->nChannels;
FREE_PTR(pWfx);
mIsInitialized = true;
smInstantiated = true;
error:
return;
......@@ -74,6 +84,7 @@ MSWASAPIWriter::~MSWASAPIWriter()
RELEASE_CLIENT(mAudioClient);
FREE_PTR(mRenderId);
ms_bufferizer_uninit(&mMSBuffer);
smInstantiated = false;
}
......@@ -157,7 +168,7 @@ void MSWASAPIWriter::stop()
}
}
int MSWASAPIWriter::feed(MSQueue *input)
int MSWASAPIWriter::feed(MSFilter *f)
{
HRESULT result;
BYTE *buffer;
......@@ -168,36 +179,50 @@ int MSWASAPIWriter::feed(MSQueue *input)
int msNumFramesAvailable;
int bytesPerFrame = (16 * mNChannels / 8);
// Fill the bufferizer from the input
ms_bufferizer_put_from_queue(&mMSBuffer, input);
msBufferSizeAvailable = ms_bufferizer_get_avail(&mMSBuffer);
if (msBufferSizeAvailable < 0) msBufferSizeAvailable = 0;
msNumFramesAvailable = msBufferSizeAvailable / bytesPerFrame;
if (msNumFramesAvailable > 0) {
// Calculate the number of frames to pass to the Audio Render Client
result = mAudioClient->GetCurrentPadding(&numFramesPadding);
REPORT_ERROR("Could not get current buffer padding for the MSWASAPI audio output interface [%i]", result);
numFramesAvailable = mBufferFrameCount - numFramesPadding;
if ((UINT32)msNumFramesAvailable > numFramesAvailable) {
// The bufferizer is filled more than the space available in the Audio Render Client.
// Consider dropping some frames: TODO
numFramesFed = numFramesAvailable;
if (isStarted()) {
// Fill the bufferizer from the input
ms_bufferizer_put_from_queue(&mMSBuffer, f->inputs[0]);
msBufferSizeAvailable = ms_bufferizer_get_avail(&mMSBuffer);
if (msBufferSizeAvailable < 0) msBufferSizeAvailable = 0;
msNumFramesAvailable = msBufferSizeAvailable / bytesPerFrame;
if (msNumFramesAvailable > 0) {
// Calculate the number of frames to pass to the Audio Render Client
result = mAudioClient->GetCurrentPadding(&numFramesPadding);
REPORT_ERROR("Could not get current buffer padding for the MSWASAPI audio output interface [%i]", result);
numFramesAvailable = mBufferFrameCount - numFramesPadding;
if ((UINT32)msNumFramesAvailable > numFramesAvailable) {
// The bufferizer is filled more than the space available in the Audio Render Client.
// Consider dropping some frames: TODO
numFramesFed = numFramesAvailable;
} else {
numFramesFed = msNumFramesAvailable;
}
// Feed the Audio Render Client
if (numFramesFed > 0) {
result = mAudioRenderClient->GetBuffer(numFramesFed, &buffer);
REPORT_ERROR("Could not get buffer from the MSWASAPI audio output interface [%i]", result);
ms_bufferizer_read(&mMSBuffer, (uint8_t *)buffer, numFramesFed * bytesPerFrame);
result = mAudioRenderClient->ReleaseBuffer(numFramesFed, 0);
REPORT_ERROR("Could not release buffer of the MSWASAPI audio output interface [%i]", result);
}
} else {
numFramesFed = msNumFramesAvailable;
}
// Feed the Audio Render Client
if (numFramesFed > 0) {
result = mAudioRenderClient->GetBuffer(numFramesFed, &buffer);
REPORT_ERROR("Could not get buffer from the MSWASAPI audio output interface [%i]", result);
ms_bufferizer_read(&mMSBuffer, (uint8_t *)buffer, numFramesFed * bytesPerFrame);
result = mAudioRenderClient->ReleaseBuffer(numFramesFed, 0);
REPORT_ERROR("Could not release buffer of the MSWASAPI audio output interface [%i]", result);
ms_warning("Playback underrun on the MSWASAPI audio output interface");
}
} else {
drop(f);
}
return 0;
error:
return -1;
}
void MSWASAPIWriter::drop(MSFilter *f) {
mblk_t *im;
while ((im = ms_queue_get(f->inputs[0])) != NULL) {
freemsg(im);
}
}
......@@ -21,7 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "mediastreamer2/msqueue.h"
#include "mediastreamer2/msfilter.h"
#include <objbase.h>
#include <audioclient.h>
......@@ -38,12 +38,15 @@ public:
bool isStarted() { return mIsStarted; }
void start();
void stop();
int feed(MSQueue *input);
int feed(MSFilter *f);
int getRate() { return mRate; }
int getNChannels() { return mNChannels; }
private:
void drop(MSFilter *f);
static bool smInstantiated;
LPCWSTR mRenderId;
IAudioClient *mAudioClient;
IAudioRenderClient *mAudioRenderClient;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment