* Small coding style fixes and improved naming

of the thread related methods.
 * Explicitely reset the fThread member in
   _StopOutputThread().
 * Added TODO about the somewhat seemingly fragile method
   to ensure the previous buffer for a channel has
   been processed.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38527 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2010-09-04 10:41:12 +00:00
parent da81ea91d7
commit 3e9336fd20
2 changed files with 47 additions and 42 deletions

View File

@ -197,7 +197,7 @@ MultiAudioNode::MultiAudioNode(BMediaAddOn* addon, const char* name,
* fInputPreferredFormat.u.raw_audio.channel_count; * fInputPreferredFormat.u.raw_audio.channel_count;
if (config) { if (config != NULL) {
fConfig = *config; fConfig = *config;
PRINT_OBJECT(*config); PRINT_OBJECT(*config);
} }
@ -211,7 +211,7 @@ MultiAudioNode::~MultiAudioNode()
CALLED(); CALLED();
fAddOn->GetConfigurationFor(this, NULL); fAddOn->GetConfigurationFor(this, NULL);
_StopThread(); _StopOutputThread();
BMediaEventLooper::Quit(); BMediaEventLooper::Quit();
fWeb = NULL; fWeb = NULL;
@ -272,9 +272,8 @@ MultiAudioNode::GetFormat(media_format* format)
} }
// -------------------------------------------------------- // //#pragma mark - BMediaNode
// implementation of BMediaNode
// -------------------------------------------------------- //
BMediaAddOn* BMediaAddOn*
MultiAudioNode::AddOn(int32* _internalID) const MultiAudioNode::AddOn(int32* _internalID) const
@ -410,7 +409,7 @@ MultiAudioNode::NodeRegistered()
fWeb = MakeParameterWeb(); fWeb = MakeParameterWeb();
SetParameterWeb(fWeb); SetParameterWeb(fWeb);
/* apply configuration */ // Apply configuration
#ifdef PRINTING #ifdef PRINTING
bigtime_t start = system_time(); bigtime_t start = system_time();
#endif #endif
@ -468,12 +467,12 @@ MultiAudioNode::SetTimeSource(BTimeSource* timeSource)
// #pragma mark - BBufferConsumer // #pragma mark - BBufferConsumer
// Check to make sure the format is okay, then remove
// any wildcards corresponding to our requirements.
status_t status_t
MultiAudioNode::AcceptFormat(const media_destination& dest, MultiAudioNode::AcceptFormat(const media_destination& dest,
media_format* format) media_format* format)
{ {
// Check to make sure the format is okay, then remove
// any wildcards corresponding to our requirements.
CALLED(); CALLED();
if (format == NULL) if (format == NULL)
@ -628,14 +627,14 @@ MultiAudioNode::Connected(const media_source& producer,
{ {
CALLED(); CALLED();
if (out_input == 0) { if (out_input == 0) {
fprintf(stderr,"<- B_BAD_VALUE\n"); fprintf(stderr, "<- B_BAD_VALUE\n");
return B_BAD_VALUE; // no crashing return B_BAD_VALUE; // no crashing
} }
node_input *channel = _FindInput(where); node_input *channel = _FindInput(where);
if(channel==NULL) { if (channel == NULL) {
fprintf(stderr,"<- B_MEDIA_BAD_DESTINATION\n"); fprintf(stderr, "<- B_MEDIA_BAD_DESTINATION\n");
return B_MEDIA_BAD_DESTINATION; return B_MEDIA_BAD_DESTINATION;
} }
@ -646,8 +645,7 @@ MultiAudioNode::Connected(const media_source& producer,
channel->fInput.format = with_format; channel->fInput.format = with_format;
*out_input = channel->fInput; *out_input = channel->fInput;
// we are sure the thread is started _StartOutputThreadIfNeeded();
_StartThread();
return B_OK; return B_OK;
} }
@ -956,8 +954,7 @@ MultiAudioNode::Connect(status_t error, const media_source& source,
if (!channel->fBufferGroup) if (!channel->fBufferGroup)
_AllocateBuffers(*channel); _AllocateBuffers(*channel);
// we are sure the thread is started _StartOutputThreadIfNeeded();
_StartThread();
} }
@ -1096,8 +1093,6 @@ MultiAudioNode::HandleEvent(const media_timed_event* event, bigtime_t lateness,
} }
// TODO: how should we handle late buffers? drop them?
// notify the producer?
status_t status_t
MultiAudioNode::_HandleBuffer(const media_timed_event* event, MultiAudioNode::_HandleBuffer(const media_timed_event* event,
bigtime_t lateness, bool realTimeEvent) bigtime_t lateness, bool realTimeEvent)
@ -1132,6 +1127,8 @@ MultiAudioNode::_HandleBuffer(const media_timed_event* event,
buffer->Recycle(); buffer->Recycle();
} else { } else {
//WriteBuffer(buffer, *channel); //WriteBuffer(buffer, *channel);
// TODO: This seems like a very fragile mechanism to wait until
// the previous buffer for this channel has been processed...
if (channel->fBuffer != NULL) { if (channel->fBuffer != NULL) {
PRINT(("MultiAudioNode::HandleBuffer snoozing recycling channelId : %li, how_early:%Ld\n", channel->fChannelId, howEarly)); PRINT(("MultiAudioNode::HandleBuffer snoozing recycling channelId : %li, how_early:%Ld\n", channel->fChannelId, howEarly));
//channel->fBuffer->Recycle(); //channel->fBuffer->Recycle();
@ -1209,7 +1206,7 @@ MultiAudioNode::_HandleStop(const media_timed_event* event, bigtime_t lateness,
EventQueue()->FlushEvents(0, BTimedEventQueue::B_ALWAYS, true, EventQueue()->FlushEvents(0, BTimedEventQueue::B_ALWAYS, true,
BTimedEventQueue::B_HANDLE_BUFFER); BTimedEventQueue::B_HANDLE_BUFFER);
//_StopThread(); //_StopOutputThread();
return B_OK; return B_OK;
} }
@ -1244,7 +1241,7 @@ MultiAudioNode::TimeSourceOp(const time_source_op_info& op, void* _reserved)
PRINT(("TimeSourceOp op B_TIMESOURCE_START\n")); PRINT(("TimeSourceOp op B_TIMESOURCE_START\n"));
if (RunState() != BMediaEventLooper::B_STARTED) { if (RunState() != BMediaEventLooper::B_STARTED) {
fTimeSourceStarted = true; fTimeSourceStarted = true;
_StartThread(); _StartOutputThreadIfNeeded();
media_timed_event startEvent(0, BTimedEventQueue::B_START); media_timed_event startEvent(0, BTimedEventQueue::B_START);
EventQueue()->AddEvent(startEvent); EventQueue()->AddEvent(startEvent);
@ -1256,7 +1253,7 @@ MultiAudioNode::TimeSourceOp(const time_source_op_info& op, void* _reserved)
media_timed_event stopEvent(0, BTimedEventQueue::B_STOP); media_timed_event stopEvent(0, BTimedEventQueue::B_STOP);
EventQueue()->AddEvent(stopEvent); EventQueue()->AddEvent(stopEvent);
fTimeSourceStarted = false; fTimeSourceStarted = false;
_StopThread(); _StopOutputThread();
PublishTime(0, 0, 0); PublishTime(0, 0, 0);
} }
break; break;
@ -1266,7 +1263,7 @@ MultiAudioNode::TimeSourceOp(const time_source_op_info& op, void* _reserved)
media_timed_event stopEvent(0, BTimedEventQueue::B_STOP); media_timed_event stopEvent(0, BTimedEventQueue::B_STOP);
EventQueue()->AddEvent(stopEvent); EventQueue()->AddEvent(stopEvent);
fTimeSourceStarted = false; fTimeSourceStarted = false;
_StopThread(); _StopOutputThread();
PublishTime(0, 0, 0); PublishTime(0, 0, 0);
} }
break; break;
@ -1658,7 +1655,7 @@ MultiAudioNode::_CreateFrequencyParameterGroup(BParameterGroup* parentGroup,
int32 int32
MultiAudioNode::_RunThread() MultiAudioNode::_OutputThread()
{ {
CALLED(); CALLED();
multi_buffer_info bufferInfo; multi_buffer_info bufferInfo;
@ -1678,8 +1675,9 @@ MultiAudioNode::_RunThread()
while (true) { while (true) {
// TODO: why this semaphore?? // TODO: why this semaphore??
if (acquire_sem_etc(fBufferFreeSem, 1, B_RELATIVE_TIMEOUT, 0) if (acquire_sem_etc(fBufferFreeSem, 1, B_RELATIVE_TIMEOUT, 0)
== B_BAD_SEM_ID) == B_BAD_SEM_ID) {
return B_OK; return B_OK;
}
BAutolock locker(fBufferLock); BAutolock locker(fBufferLock);
// make sure the buffers don't change while we're playing with them // make sure the buffers don't change while we're playing with them
@ -1737,9 +1735,12 @@ MultiAudioNode::_RunThread()
} }
} }
PRINT(("MultiAudioNode::RunThread: recorded_real_time : %Ld\n", bufferInfo.recorded_real_time)); PRINT(("MultiAudioNode::RunThread: recorded_real_time : %Ld\n",
PRINT(("MultiAudioNode::RunThread: recorded_frames_count : %Ld\n", bufferInfo.recorded_frames_count)); bufferInfo.recorded_real_time));
PRINT(("MultiAudioNode::RunThread: record_buffer_cycle : %li\n", bufferInfo.record_buffer_cycle)); PRINT(("MultiAudioNode::RunThread: recorded_frames_count : %Ld\n",
bufferInfo.recorded_frames_count));
PRINT(("MultiAudioNode::RunThread: record_buffer_cycle : %li\n",
bufferInfo.record_buffer_cycle));
for (int32 i = 0; i < fOutputs.CountItems(); i++) { for (int32 i = 0; i < fOutputs.CountItems(); i++) {
node_output* output = (node_output*)fOutputs.ItemAt(i); node_output* output = (node_output*)fOutputs.ItemAt(i);
@ -1855,9 +1856,8 @@ void
MultiAudioNode::_FillWithZeros(node_input& input) MultiAudioNode::_FillWithZeros(node_input& input)
{ {
CALLED(); CALLED();
for (int32 i = 0; i < fDevice->BufferList().return_playback_buffers; i++) { for (int32 i = 0; i < fDevice->BufferList().return_playback_buffers; i++)
_WriteZeros(input, i); _WriteZeros(input, i);
}
} }
@ -2081,11 +2081,11 @@ MultiAudioNode::_FillNextBuffer(node_input& input, BBuffer* buffer)
status_t status_t
MultiAudioNode::_StartThread() MultiAudioNode::_StartOutputThreadIfNeeded()
{ {
CALLED(); CALLED();
// the thread is already started ? // the thread is already started ?
if (fThread > B_OK) if (fThread >= 0)
return B_OK; return B_OK;
// allocate buffer free semaphore // allocate buffer free semaphore
@ -2097,7 +2097,7 @@ MultiAudioNode::_StartThread()
PublishTime(-50, 0, 0); PublishTime(-50, 0, 0);
fThread = spawn_thread(_run_thread_, "multi_audio audio output", fThread = spawn_thread(_OutputThreadEntry, "multi_audio audio output",
B_REAL_TIME_PRIORITY, this); B_REAL_TIME_PRIORITY, this);
if (fThread < B_OK) { if (fThread < B_OK) {
delete_sem(fBufferFreeSem); delete_sem(fBufferFreeSem);
@ -2110,12 +2110,14 @@ MultiAudioNode::_StartThread()
status_t status_t
MultiAudioNode::_StopThread() MultiAudioNode::_StopOutputThread()
{ {
CALLED(); CALLED();
delete_sem(fBufferFreeSem); delete_sem(fBufferFreeSem);
wait_for_thread(fThread, &fThread); status_t exitValue;
wait_for_thread(fThread, &exitValue);
fThread = -1;
return B_OK; return B_OK;
} }
@ -2129,7 +2131,8 @@ MultiAudioNode::_AllocateBuffers(node_output &channel)
size_t size = channel.fOutput.format.u.raw_audio.buffer_size; size_t size = channel.fOutput.format.u.raw_audio.buffer_size;
int32 count = int32(fLatency / BufferDuration() + 1 + 1); int32 count = int32(fLatency / BufferDuration() + 1 + 1);
PRINT(("\tlatency = %Ld, buffer duration = %Ld\n", fLatency, BufferDuration())); PRINT(("\tlatency = %Ld, buffer duration = %Ld\n", fLatency,
BufferDuration()));
PRINT(("\tcreating group of %ld buffers, size = %lu\n", count, size)); PRINT(("\tcreating group of %ld buffers, size = %lu\n", count, size));
channel.fBufferGroup = new BBufferGroup(size, count); channel.fBufferGroup = new BBufferGroup(size, count);
} }
@ -2143,7 +2146,8 @@ MultiAudioNode::_UpdateTimeSource(multi_buffer_info& info,
if (!fTimeSourceStarted || oldInfo.played_real_time == 0) if (!fTimeSourceStarted || oldInfo.played_real_time == 0)
return; return;
fTimeComputer.AddTimeStamp(info.played_real_time, info.played_frames_count); fTimeComputer.AddTimeStamp(info.played_real_time,
info.played_frames_count);
PublishTime(fTimeComputer.PerformanceTime(), fTimeComputer.RealTime(), PublishTime(fTimeComputer.PerformanceTime(), fTimeComputer.RealTime(),
fTimeComputer.Drift()); fTimeComputer.Drift());
} }
@ -2180,7 +2184,8 @@ MultiAudioNode::_FillNextBuffer(multi_buffer_info &info, node_output &channel)
// now fill it with data, continuing where the last buffer left off // now fill it with data, continuing where the last buffer left off
memcpy(buffer->Data(), memcpy(buffer->Data(),
fDevice->BufferList().record_buffers[info.record_buffer_cycle] fDevice->BufferList().record_buffers[info.record_buffer_cycle]
[channel.fChannelId - fDevice->Description().output_channel_count].base, [channel.fChannelId
- fDevice->Description().output_channel_count].base,
channel.fOutput.format.u.raw_audio.buffer_size); channel.fOutput.format.u.raw_audio.buffer_size);
// fill in the buffer header // fill in the buffer header
@ -2298,10 +2303,10 @@ MultiAudioNode::_FindInput(int32 destinationId)
/*static*/ status_t /*static*/ status_t
MultiAudioNode::_run_thread_(void* data) MultiAudioNode::_OutputThreadEntry(void* data)
{ {
CALLED(); CALLED();
return static_cast<MultiAudioNode*>(data)->_RunThread(); return static_cast<MultiAudioNode*>(data)->_OutputThread();
} }

View File

@ -171,10 +171,10 @@ private:
void _FillNextBuffer(node_input& channel, void _FillNextBuffer(node_input& channel,
BBuffer* buffer); BBuffer* buffer);
static int32 _run_thread_(void* data); static int32 _OutputThreadEntry(void* data);
int32 _RunThread(); int32 _OutputThread();
status_t _StartThread(); status_t _StartOutputThreadIfNeeded();
status_t _StopThread(); status_t _StopOutputThread();
void _AllocateBuffers(node_output& channel); void _AllocateBuffers(node_output& channel);
BBuffer* _FillNextBuffer(multi_buffer_info& info, BBuffer* _FillNextBuffer(multi_buffer_info& info,