From af8d0a4d4e15c210c51678cd34de4057e43cf96e Mon Sep 17 00:00:00 2001 From: beveloper Date: Mon, 30 Jun 2003 15:45:37 +0000 Subject: [PATCH] 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 --- .../media/media-add-ons/mixer/MixerCore.cpp | 44 +++++++++++++++---- .../media/media-add-ons/mixer/MixerInput.cpp | 3 ++ .../media/media-add-ons/mixer/MixerInput.h | 12 +++-- .../media/media-add-ons/mixer/MixerUtils.cpp | 2 +- .../media/media-add-ons/mixer/MixerUtils.h | 12 ++++- 5 files changed, 58 insertions(+), 15 deletions(-) diff --git a/src/add-ons/media/media-add-ons/mixer/MixerCore.cpp b/src/add-ons/media/media-add-ons/mixer/MixerCore.cpp index 682d5cbe64..2ff6a7b56e 100644 --- a/src/add-ons/media/media-add-ons/mixer/MixerCore.cpp +++ b/src/add-ons/media/media-add-ons/mixer/MixerCore.cpp @@ -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); diff --git a/src/add-ons/media/media-add-ons/mixer/MixerInput.cpp b/src/add-ons/media/media-add-ons/mixer/MixerInput.cpp index 47d326dbf5..6e2238cb59 100644 --- a/src/add-ons/media/media-add-ons/mixer/MixerInput.cpp +++ b/src/add-ons/media/media-add-ons/mixer/MixerInput.cpp @@ -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) diff --git a/src/add-ons/media/media-add-ons/mixer/MixerInput.h b/src/add-ons/media/media-add-ons/mixer/MixerInput.h index 31ee9bd7ee..6885ac3922 100644 --- a/src/add-ons/media/media-add-ons/mixer/MixerInput.h +++ b/src/add-ons/media/media-add-ons/mixer/MixerInput.h @@ -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(reinterpret_cast(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 diff --git a/src/add-ons/media/media-add-ons/mixer/MixerUtils.cpp b/src/add-ons/media/media-add-ons/mixer/MixerUtils.cpp index b8710ac8ae..d13d06298d 100644 --- a/src/add-ons/media/media-add-ons/mixer/MixerUtils.cpp +++ b/src/add-ons/media/media-add-ons/mixer/MixerUtils.cpp @@ -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; } } diff --git a/src/add-ons/media/media-add-ons/mixer/MixerUtils.h b/src/add-ons/media/media-add-ons/mixer/MixerUtils.h index 94419462c2..667866f092 100644 --- a/src/add-ons/media/media-add-ons/mixer/MixerUtils.h +++ b/src/add-ons/media/media-add-ons/mixer/MixerUtils.h @@ -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