Fixed the input buffer looping bug that existed if an input wouldn't receive new buffers. Now kips inputs that have no available data.

When no input is connected, use a fast path for sending an empty buffer.
No more debugging output when DEUBG < 1


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3763 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
beveloper 2003-06-30 15:45:37 +00:00
parent 4a87eedfcc
commit af8d0a4d4e
5 changed files with 58 additions and 15 deletions

View File

@ -435,13 +435,36 @@ MixerCore::MixThread()
if (!LockWithTimeout(10000))
continue;
// no inputs, skip further processing and just send an empty buffer
if (fInputs->IsEmpty()) {
int size = fOutput->MediaOutput().format.u.raw_audio.buffer_size;
BBuffer* buf = fBufferGroup->RequestBuffer(size, 5000);
if (buf) {
memset(buf->Data(), 0, size);
// fill in the buffer header
media_header* hdr = buf->Header();
hdr->type = B_MEDIA_RAW_AUDIO;
hdr->size_used = size;
hdr->time_source = fTimeSource->ID();
hdr->start_time = event_time;
if (B_OK != fNode->SendBuffer(buf, fOutput->MediaOutput().destination)) {
ERROR("MixerCore: SendBuffer failed\n");
buf->Recycle();
}
} else {
ERROR("MixerCore: RequestBuffer failed\n");
}
goto schedule_next_event;
}
int64 cur_framepos;
cur_framepos = frame_base + frame_pos;
// mix all data from all inputs into the mix buffer
ASSERT((frame_base + frame_pos) % fMixBufferFrameCount == 0);
ASSERT(cur_framepos % fMixBufferFrameCount == 0);
PRINT(4, "create new buffer event at %Ld, reading input frames at %Ld\n", event_time, frame_base + frame_pos);
int64 cur_framepos = frame_base + frame_pos;
PRINT(4, "create new buffer event at %Ld, reading input frames at %Ld\n", event_time, cur_framepos);
MixerInput *input;
for (int i = 0; (input = Input(i)) != 0; i++) {
@ -451,7 +474,8 @@ MixerCore::MixThread()
const float *base;
uint32 sample_offset;
float gain;
input->GetMixerChannelInfo(chan, cur_framepos, &base, &sample_offset, &type, &gain);
if (!input->GetMixerChannelInfo(chan, cur_framepos, event_time, &base, &sample_offset, &type, &gain))
continue;
if (type < 0 || type >= MAX_TYPES)
continue;
chan_info *info = InputChanInfos[type].Create();
@ -480,7 +504,8 @@ MixerCore::MixThread()
}
}
uint32 dst_sample_offset = fMixBufferChannelCount * sizeof(float);
uint32 dst_sample_offset;
dst_sample_offset = fMixBufferChannelCount * sizeof(float);
memset(fMixBuffer, 0, fMixBufferChannelCount * fMixBufferFrameCount * sizeof(float));
for (int chan = 0; chan < fMixBufferChannelCount; chan++) {
@ -499,8 +524,8 @@ MixerCore::MixThread()
}
// request a buffer
BBuffer* buf = fBufferGroup->RequestBuffer(fOutput->MediaOutput().format.u.raw_audio.buffer_size, 5000);
BBuffer *buf;
buf = fBufferGroup->RequestBuffer(fOutput->MediaOutput().format.u.raw_audio.buffer_size, 5000);
if (buf) {
// copy data from mix buffer into output buffer
@ -539,7 +564,8 @@ MixerCore::MixThread()
InputChanInfos[i].MakeEmpty();
for (int i = 0; i < fOutput->GetOutputChannelCount(); i++)
MixChanInfos[i].MakeEmpty();
schedule_next_event:
// schedule next event
frame_pos += fMixBufferFrameCount;
event_time = time_base + bigtime_t((1000000LL * frame_pos) / fMixBufferFrameRate);

View File

@ -24,6 +24,7 @@ MixerInput::MixerInput(MixerCore *core, const media_input &input, float mixFrame
fMixBuffer(0),
fMixBufferFrameRate(0),
fMixBufferFrameCount(0),
fLastDataAvailableTime(-1),
fResampler(0),
fRtmPool(0),
fUserOverridesChannelDesignations(false)
@ -107,6 +108,8 @@ MixerInput::BufferReceived(BBuffer *buffer)
ERROR("MixerInput::BufferReceived: buffer with negative start time of %Ld dropped\n", start);
return;
}
fLastDataAvailableTime = start + buffer_duration(fInput.format.u.raw_audio);
// swap the byte order of this buffer, if necessary
if (fInputByteSwap)

View File

@ -32,7 +32,7 @@ public:
float GetInputChannelGain(int channel);
// only for use by MixerCore
void GetMixerChannelInfo(int channel, int64 framepos, const float **buffer, uint32 *sample_offset, int *type, float *gain);
bool GetMixerChannelInfo(int channel, int64 framepos, bigtime_t time, const float **buffer, uint32 *sample_offset, int *type, float *gain);
int GetMixerChannelType(int channel);
protected:
@ -72,6 +72,8 @@ private:
int32 fMixBufferFrameRate;
uint32 fMixBufferFrameCount;
bigtime_t fLastDataAvailableTime;
Resampler **fResampler; // array
rtm_pool *fRtmPool;
@ -80,17 +82,21 @@ private:
int32 debugMixBufferFrames;
};
inline void
MixerInput::GetMixerChannelInfo(int channel, int64 framepos, const float **buffer, uint32 *sample_offset, int *type, float *gain)
inline bool
MixerInput::GetMixerChannelInfo(int channel, int64 framepos, bigtime_t time, const float **buffer, uint32 *sample_offset, int *type, float *gain)
{
ASSERT(fMixBuffer); // this function should not be called if we don't have a mix buffer!
ASSERT(channel >= 0 && channel < fMixerChannelCount);
if (time > fLastDataAvailableTime)
return false;
int32 offset = framepos % fMixBufferFrameCount;
if (channel == 0) PRINT(3, "GetMixerChannelInfo: frames %ld to %ld\n", offset, offset + debugMixBufferFrames - 1);
*buffer = reinterpret_cast<float *>(reinterpret_cast<char *>(fMixerChannelInfo[channel].buffer_base) + (offset * sizeof(float) * fInputChannelCount));
*sample_offset = sizeof(float) * fInputChannelCount;
*type = fMixerChannelInfo[channel].type;
*gain = fMixerChannelInfo[channel].gain;
return true;
}
inline int

View File

@ -114,7 +114,7 @@ fix_multiaudio_format(media_multi_audio_format *format)
&& int(format->frame_rate + 0.5) == 11025
&& format->byte_order == B_MEDIA_BIG_ENDIAN
&& format->buffer_size == 548) {
printf("### quicktime extractor bug workaround activated, changing buffer size from 548 into 4096\n");
ERROR("Mixer: quicktime extractor bug workaround activated, changing buffer size from 548 into 4096\n");
format->buffer_size = 4096;
}
}

View File

@ -1,11 +1,17 @@
#ifndef _MIXER_UTILS_H
#define _MIXER_UTILS_H
#if DEBUG > 0
#define PRINT_CHANNEL_MASK(fmt) do { char s[200]; string_for_channel_mask(s, (fmt).u.raw_audio.channel_mask); printf(" channel_mask 0x%08X %s\n", (fmt).u.raw_audio.channel_mask, s); } while (0)
#else
#define PRINT_CHANNEL_MASK(fmt) ((void)0)
#endif
void string_for_channel_mask(char *str, uint32 mask);
void fix_multiaudio_format(media_multi_audio_format *format);
int count_nonzero_bits(uint32 value);
#define PRINT_CHANNEL_MASK(fmt) do { char s[200]; string_for_channel_mask(s, (fmt).u.raw_audio.channel_mask); printf(" channel_mask 0x%08X %s\n", (fmt).u.raw_audio.channel_mask, s); } while (0)
uint32 GetChannelMask(int channel, uint32 all_channel_masks);
bool HasKawamba();
@ -27,3 +33,5 @@ uint32 ChannelTypeToChannelMask(int type);
double us_to_s(bigtime_t usecs);
bigtime_t s_to_us(double secs);
#endif //_MIXER_UTILS_H