コード例 #1
0
ファイル: GameProducer.cpp プロジェクト: AmirAbrams/haiku
status_t
GameProducer::GetLatency(bigtime_t* _latency)
{
	// report our *total* latency:  internal plus downstream plus scheduling
	*_latency = EventLatency() + SchedulingLatency();
	return B_OK;
}
コード例 #2
0
ファイル: ESDSinkNode.cpp プロジェクト: AmirAbrams/haiku
status_t ESDSinkNode::GetLatencyFor(
				const media_destination & for_whom,
				bigtime_t * out_latency,
				media_node_id * out_timesource)
{
	CALLED();
	if ((out_latency == 0) || (out_timesource == 0)) {
		fprintf(stderr,"<- B_BAD_VALUE\n");
		return B_BAD_VALUE;
	}
	
	if(fInput.destination != for_whom) {
		fprintf(stderr,"<- B_MEDIA_BAD_DESTINATION\n");
		return B_MEDIA_BAD_DESTINATION;
	}
	
	bigtime_t intl = EventLatency();
	bigtime_t netl = 0LL;
	if (fDevice)
		netl = fDevice->Latency();
	// I don't want to swap
	if (netl > 500000)
		netl = 500000;
	*out_latency = intl + netl;
	fprintf(stderr, "int latency %Ld, net latency %Ld, total latency %Ld\n", intl, netl, *out_latency);
	*out_timesource = TimeSource()->ID();
	return B_OK;
}
コード例 #3
0
// "This hook function is called when a BBufferConsumer that's receiving data
//  from you determines that its latency has changed. It will call its
//  BBufferConsumer::SendLatencyChange() function, and in response, the Media
//  Server will call your LatencyChanged() function.  The source argument
//  indicates your output that's involved in the connection, and destination
//  specifies the input on the consumer to which the connection is linked.
//  newLatency is the consumer's new latency. The flags are currently unused."
void StepMotionBlurFilter::LatencyChanged(
	const media_source& source,
	const media_destination& destination,
	bigtime_t newLatency,
	uint32 flags)
{
	PRINT(("StepMotionBlurFilter::LatencyChanged()\n"));
	
	if (source != m_output.source)
	{
		PRINT(("\tBad source.\n"));
		return;
	}
	if (destination != m_output.destination)
	{
		PRINT(("\tBad destination.\n"));
		return;
	}
	
	m_downstreamLatency = newLatency;
	SetEventLatency(m_downstreamLatency + m_processingLatency);
	
	if (m_input.source != media_source::null)
	{
		// pass new latency upstream
		status_t err = SendLatencyChange(m_input.source, m_input.destination, EventLatency() + SchedulingLatency());
		if(err < B_OK)
			PRINT(("\t!!! SendLatencyChange(): %s\n", strerror(err)));
	}
}
コード例 #4
0
status_t
ClientNode::GetLatency(bigtime_t *outLatency)
{
    printf("ClientNode::GetLatency\n");
    *outLatency = EventLatency() + SchedulingLatency();
    return B_OK;
}
コード例 #5
0
status_t FlipTransition::GetLatency(bigtime_t* poLatency)
{	
	PRINT(("FlipTransition::GetLatency()\n"));
	*poLatency = EventLatency() + SchedulingLatency();
	PRINT(("\treturning %Ld\n", *poLatency));
	
	return B_OK;
}
コード例 #6
0
status_t OffsetFilter::GetLatency(bigtime_t* poLatency)
{	
	PRINT(("OffsetFilter::GetLatency()\n"));
	*poLatency = EventLatency() + SchedulingLatency();
	PRINT(("\treturning %Ld\n", *poLatency));
	
	return B_OK;
}
コード例 #7
0
ファイル: FireWireDVNode.cpp プロジェクト: DonCN/haiku
status_t 
FireWireDVNode::GetLatency(bigtime_t* out_latency)
{
	CALLED();
	
	*out_latency = EventLatency() + SchedulingLatency();
	return B_OK;
}
コード例 #8
0
ファイル: MediaReader.cpp プロジェクト: jiangxilong/haiku
status_t MediaReader::GetLatency(
				bigtime_t * out_latency)
{
	CALLED();

	*out_latency = EventLatency() + SchedulingLatency();
	return B_OK;
}
コード例 #9
0
status_t StepMotionBlurFilter::GetLatency(bigtime_t* poLatency)
{	
	PRINT(("StepMotionBlurFilter::GetLatency()\n"));
	*poLatency = EventLatency() + SchedulingLatency();
	PRINT(("\treturning %Ld\n", *poLatency));
	
	return B_OK;
}
コード例 #10
0
ファイル: AudioFilterNode.cpp プロジェクト: mariuz/haiku
status_t AudioFilterNode::GetLatency(
	bigtime_t*									outLatency) {
	
	PRINT(("AudioFilterNode::GetLatency()\n"));
	*outLatency = EventLatency() + SchedulingLatency();
	PRINT(("\treturning %Ld\n", *outLatency));
	
	return B_OK;
}
コード例 #11
0
ファイル: SoundPlayNode.cpp プロジェクト: mariuz/haiku
status_t
SoundPlayNode::GetLatency(bigtime_t* _latency)
{
	CALLED();

	// report our *total* latency:  internal plus downstream plus scheduling
	*_latency = EventLatency() + SchedulingLatency();
	return B_OK;
}
コード例 #12
0
ファイル: FlangerNode.cpp プロジェクト: MaddTheSane/haiku
status_t FlangerNode::GetLatency(
	bigtime_t* poLatency) {

	PRINT(("FlangerNode::GetLatency()\n"));
	*poLatency = EventLatency() + SchedulingLatency();
	PRINT(("\treturning %" B_PRIdBIGTIME "\n", *poLatency));

	return B_OK;
}
コード例 #13
0
ファイル: ToneProducer.cpp プロジェクト: ModeenF/haiku
status_t
ToneProducer::GetLatency(bigtime_t* out_latency)
{
	FPRINTF(stderr, "ToneProducer::GetLatency\n");

	// report our *total* latency:  internal plus downstream plus scheduling
	*out_latency = EventLatency() + SchedulingLatency();
	return B_OK;
}
コード例 #14
0
ファイル: AudioProducer.cpp プロジェクト: mariuz/haiku
status_t
AudioProducer::GetLatency(bigtime_t* _latency)
{
	TRACE("%p->AudioProducer::GetLatency()\n", this);

	// report our *total* latency:  internal plus downstream plus scheduling
	*_latency = EventLatency() + SchedulingLatency();
	return B_OK;
}
コード例 #15
0
ファイル: FlangerNode.cpp プロジェクト: DonCN/haiku
void FlangerNode::Connect(
	status_t status,
	const media_source& source,
	const media_destination& destination,
	const media_format& format,
	char* pioName) {

	PRINT(("FlangerNode::Connect()\n"));
	status_t err;

	// connection failed?
	if(status < B_OK) {
		PRINT(("\tStatus: %s\n", strerror(status)));
		// 'unreserve' the output
		m_output.destination = media_destination::null;
		return;
	}

	// connection established:
	strncpy(pioName, m_output.name, B_MEDIA_NAME_LENGTH);
	m_output.destination = destination;
	m_format = format;

	// figure downstream latency
	media_node_id timeSource;
	err = FindLatencyFor(m_output.destination, &m_downstreamLatency, &timeSource);
	if(err < B_OK) {
		PRINT(("\t!!! FindLatencyFor(): %s\n", strerror(err)));
	}
	PRINT(("\tdownstream latency = %Ld\n", m_downstreamLatency));

	// prepare the filter
	initFilter();

	// figure processing time
	m_processingLatency = calcProcessingLatency();
	PRINT(("\tprocessing latency = %Ld\n", m_processingLatency));

	// store summed latency
	SetEventLatency(m_downstreamLatency + m_processingLatency);

	if(m_input.source != media_source::null) {
		// pass new latency upstream
		err = SendLatencyChange(
			m_input.source,
			m_input.destination,
			EventLatency() + SchedulingLatency());
		if(err < B_OK)
			PRINT(("\t!!! SendLatencyChange(): %s\n", strerror(err)));
	}

	// cache buffer duration
	SetBufferDuration(
		buffer_duration(
			m_format.u.raw_audio));
}
コード例 #16
0
status_t
VideoProducer::GetLatency(bigtime_t* _latency)
{
	if (!_latency)
		return B_BAD_VALUE;

	*_latency = EventLatency() + SchedulingLatency();

	return B_OK;
}
コード例 #17
0
ファイル: AudioConsumer.cpp プロジェクト: Barrett17/DETI
status_t
AudioConsumer::GetLatencyFor(const media_destination& dst,
	bigtime_t* latency, media_node_id* time_src)
{
	// we have multiple inputs with different IDs, but
	// the port number must match our ControlPort()
	if (dst.port != ControlPort())
		return B_MEDIA_BAD_DESTINATION;

	*latency = EventLatency();
	*time_src += TimeSource()->ID();

	return B_OK;
}
コード例 #18
0
void
EqualizerNode::LatencyChanged(const media_source &src,
                              const media_destination &dst, bigtime_t latency, uint32 flags)
{
    if (src != fOutputMedia.source || dst != fOutputMedia.destination)
        return;

    fDownstreamLatency = latency;
    SetEventLatency(fDownstreamLatency + fProcessLatency);

    if (fInputMedia.source != media_source::null) {
        SendLatencyChange(fInputMedia.source,
                          fInputMedia.destination,EventLatency() + SchedulingLatency());
    }
}
コード例 #19
0
ファイル: AudioFilterNode.cpp プロジェクト: mariuz/haiku
// [re-]initialize operation if necessary
void AudioFilterNode::updateOperation() {

	if(m_input.source == media_source::null ||
		m_output.destination == media_destination::null)
		// not fully connected; nothing to do
		return;
	
	// ask the factory for an operation
	ASSERT(m_opFactory);
	IAudioOp* op = m_opFactory->createOp(
		this,
		m_input.format.u.raw_audio,
		m_output.format.u.raw_audio);
	if(!op) {
		PRINT((
			"!!! AudioFilterNode::updateOperation(): no operation created!\n"));
			
		// clean up existing operation
		delete m_op;
		m_op = 0;
		return;
	}
	
	// install new operation
	op->replace(m_op);
	m_op = op;
	
	// do performance tests (what if I'm running? +++++)

	m_processingLatency = calcProcessingLatency();
	PRINT(("\tprocessing latency = %Ld\n", m_processingLatency));
	
	// store summed latency
	SetEventLatency(m_downstreamLatency + m_processingLatency);
	
	// pass new latency upstream
	status_t err = SendLatencyChange(
		m_input.source,
		m_input.destination,
		EventLatency() + SchedulingLatency());
	if(err < B_OK)
		PRINT(("\t!!! SendLatencyChange(): %s\n", strerror(err)));
}
コード例 #20
0
ファイル: ESDSinkNode.cpp プロジェクト: AmirAbrams/haiku
// how should we handle late buffers?  drop them?
// notify the producer?
status_t ESDSinkNode::HandleBuffer(
				const media_timed_event *event,
				bigtime_t lateness,
				bool realTimeEvent)
{
	CALLED();
	BBuffer * buffer = const_cast<BBuffer*>((BBuffer*)event->pointer);
	if (buffer == 0) {
		fprintf(stderr,"<- B_BAD_VALUE\n");
		return B_BAD_VALUE;
	}
	
	if(fInput.destination.id != buffer->Header()->destination) {
		fprintf(stderr,"<- B_MEDIA_BAD_DESTINATION\n");
		return B_MEDIA_BAD_DESTINATION;
	}
	
	media_header* hdr = buffer->Header();
	bigtime_t now = TimeSource()->Now();
	bigtime_t perf_time = hdr->start_time;
	
	// the how_early calculate here doesn't include scheduling latency because
	// we've already been scheduled to handle the buffer
	bigtime_t how_early = perf_time - EventLatency() - now;
	
	// if the buffer is late, we ignore it and report the fact to the producer
	// who sent it to us
	if ((RunMode() != B_OFFLINE) &&				// lateness doesn't matter in offline mode...
		(RunMode() != B_RECORDING) &&		// ...or in recording mode
		(how_early < 0LL))
	{
		//mLateBuffers++;
		NotifyLateProducer(fInput.source, -how_early, perf_time);
		fprintf(stderr,"	<- LATE BUFFER : %lli\n", how_early);
		buffer->Recycle();
	} else {
		if (fDevice->CanSend())
			fDevice->Write(buffer->Data(), buffer->SizeUsed());
	}
	return B_OK;
}
コード例 #21
0
void
EqualizerNode::Connect(status_t status, const media_source &src,
                       const media_destination &dst, const media_format &format, char* name)
{
    if (status < B_OK) {
        fOutputMedia.destination = media_destination::null;
        return;
    }

    strncpy(name, fOutputMedia.name, B_MEDIA_NAME_LENGTH);
    fOutputMedia.destination = dst;
    fFormat = format;

    media_node_id timeSource;
    FindLatencyFor(fOutputMedia.destination, &fDownstreamLatency, &timeSource);

    InitFilter();

    fProcessLatency = GetFilterLatency();
    SetEventLatency(fDownstreamLatency + fProcessLatency);

    if (fInputMedia.source != media_source::null) {
        SendLatencyChange(fInputMedia.source, fInputMedia.destination,
                          EventLatency() + SchedulingLatency());
    }

    bigtime_t duration = 0;

    int sample_size = (fFormat.u.raw_audio.format & 0xf)
                      * fFormat.u.raw_audio.channel_count;

    if (fFormat.u.raw_audio.buffer_size > 0
            && fFormat.u.raw_audio.frame_rate > 0 && sample_size > 0) {
        duration = (bigtime_t)(((fFormat.u.raw_audio.buffer_size / sample_size)
                                / fFormat.u.raw_audio.frame_rate) * 1000000.0);
    }

    SetBufferDuration(duration);
}
コード例 #22
0
ファイル: LoggingConsumer.cpp プロジェクト: mariuz/haiku
void 
LoggingConsumer::BufferReceived(BBuffer* buffer)
{
	bigtime_t bufferStart = buffer->Header()->start_time;
	bigtime_t now = TimeSource()->Now();
	bigtime_t how_early = bufferStart - EventLatency() - SchedulingLatency() - now;

	log_message logMsg;
	logMsg.now = now;
	logMsg.buffer_data.start_time = bufferStart;
	logMsg.buffer_data.offset = how_early;
	mLogger->Log(LOG_BUFFER_RECEIVED, logMsg);

	// There's a special case here with handling B_MEDIA_PARAMETERS buffers.
	// These contain sets of parameter value changes, with their own performance
	// times embedded in the buffers.  So, we want to dispatch those parameter
	// changes as their own events rather than pushing this buffer on the queue to
	// be handled later.
	if (B_MEDIA_PARAMETERS == buffer->Header()->type)
	{
		ApplyParameterData(buffer->Data(), buffer->SizeUsed());
		buffer->Recycle();
	}
	else		// ahh, it's a regular media buffer, so push it on the event queue
	{
		status_t err;
		media_timed_event event(buffer->Header()->start_time, BTimedEventQueue::B_HANDLE_BUFFER,
			buffer, BTimedEventQueue::B_RECYCLE_BUFFER);
		err = EventQueue()->AddEvent(event);

		// HandleEvent() will recycle the buffer.  However, if we incurred an error trying to
		// put the event into the queue, we have to recycle it ourselves, since HandleEvent()
		// will never see the buffer in that case.
		if (err) buffer->Recycle();
	}
}
コード例 #23
0
status_t
EqualizerNode::GetLatency(bigtime_t* latency)
{
    *latency = EventLatency() + SchedulingLatency();
    return B_OK;
}
コード例 #24
0
void
ClientNode::HandleEvent(const media_timed_event *event,
                        bigtime_t late, bool realTimeEvent)
{
    //printf("ClientNode::HandleEvent %d\n", event->type);
    switch (event->type) {
    case BTimedEventQueue::B_HANDLE_BUFFER:
    {
        printf("BTimedEventQueue::B_HANDLE_BUFFER\n");

        break;
    }
    case BTimedEventQueue::B_START:
    {
        printf("BTimedEventQueue::B_START\n");
        if (RunState() != B_STARTED) {
            fFramesSent = 0;
            fTime = TimeSource()->RealTime();
            int period = (fOwner->GetOutputPorts()->CountItems())*3;
            fBufferGroup = new BBufferGroup(fFormat.u.raw_audio.buffer_size,
                                            period);

            if (fBufferGroup->InitCheck() != B_OK)
                printf("error\n");

            bigtime_t start = ::system_time();
            ComputeCycle();
            bigtime_t produceLatency = ::system_time();
            fProcessLatency = produceLatency - start;

            printf("Estimated latency is %Ld\n", fProcessLatency);
            JackPortList* outputPorts = fOwner->GetOutputPorts();
            for (int i = 0; i < outputPorts->CountItems(); i++) {
                JackPort* port = outputPorts->ItemAt(i);
                port->CurrentBuffer()->Recycle();
            }

            int sample_size = (fFormat.u.raw_audio.format & 0xf)*
                              fFormat.u.raw_audio.channel_count;

            bigtime_t duration = bigtime_t(1000000) * fOwner->BufferSize() /
                                 bigtime_t(fFormat.u.raw_audio.frame_rate);

            SetBufferDuration(duration);

            SetEventLatency(fDownstreamLatency + fProcessLatency);

            _ScheduleOutputEvent(fTime);
        }
        break;
    }

    case BTimedEventQueue::B_STOP:
    {
        // stopped - don't process any more buffers, flush all buffers
        // from event queue
        EventQueue()->FlushEvents(0, BTimedEventQueue::B_ALWAYS, true,
                                  BTimedEventQueue::B_HANDLE_BUFFER);

        Stop(TimeSource()->Now(), true);
        NodeStopped(TimeSource()->Now());

        break;
    }

    case BTimedEventQueue::B_DATA_STATUS:
    {
        break;
    }

    case NEW_BUFFER_EVENT:
    {
        ComputeCycle();
        _DataAvailable(event->event_time);

        // Now we schedule the next event
        bigtime_t nextEvent = fTime + bigtime_t((1000000LL * fFramesSent)
                                                / (int32)fFormat.u.raw_audio.frame_rate)+EventLatency();
        _ScheduleOutputEvent(nextEvent);

        break;
    }

    default:
        break;
    }
}
コード例 #25
0
ファイル: LoggingConsumer.cpp プロジェクト: mariuz/haiku
void 
LoggingConsumer::HandleEvent(const media_timed_event *event, bigtime_t /* lateness */, bool /* realTimeEvent */)
{
	log_message logMsg;
	logMsg.now = TimeSource()->Now();
	mLogger->Log(LOG_HANDLE_EVENT, logMsg);

	switch (event->type)
	{
	case BTimedEventQueue::B_HANDLE_BUFFER:
		{
			BBuffer* buffer = const_cast<BBuffer*>((BBuffer*) event->pointer);
			if (buffer)
			{
				media_header* hdr = buffer->Header();
				if (hdr->destination == mInput.destination.id)
				{
					bigtime_t now = TimeSource()->Now();
					bigtime_t perf_time = hdr->start_time;

					// the how_early calculated here doesn't include scheduling latency because
					// we've already been scheduled to handle the buffer
					bigtime_t how_early = perf_time - mLatency - now;

					// logMsg.now is already set
					logMsg.buffer_data.start_time = perf_time;
					logMsg.buffer_data.offset = how_early;
					mLogger->Log(LOG_BUFFER_HANDLED, logMsg);

					// if the buffer is late, we ignore it and report the fact to the producer
					// who sent it to us
					if (how_early < 0)
					{
						mLateBuffers++;
						NotifyLateProducer(mInput.source, -how_early, perf_time);
					}
					else
					{
						// burn some percentage of our stated latency in CPU time (controlled by
						// a BParameter).  this simulates a user-configurable amount of CPU cost
						// associated with the consumer.
						bigtime_t spin_start = ::system_time();
						bigtime_t spin_now = spin_start;
						bigtime_t usecToSpin = bigtime_t(mSpinPercentage / 100.0 * mLatency);
						while (spin_now - spin_start < usecToSpin)
						{
							for (long k = 0; k < 1000000; k++) { /* intentionally blank */ }
							spin_now = ::system_time();
						}
					}

					// we're done "processing the buffer;" now we recycle it and return to the loop
					buffer->Recycle();
				}
				else
				{
					//fprintf(stderr, "* Woah!  Got a buffer for a different destination!\n");
				}
			}
		}
		break;

	// !!! change to B_PARAMETER as soon as it's available
	
	// +++++ e.moon [16jun99]
	// !!! this can't be right: the parameter value is accessed by the pointer
	//     originally passed to SetParameterValue().  there's no guarantee that
	//     value's still valid, is there?
	
	case BTimedEventQueue::B_USER_EVENT:
		{
			size_t dataSize = size_t(event->data);
			int32 param = int32(event->bigdata);
			logMsg.param.id = param;

			// handle the message if there's sufficient data provided.  we only check against
			// sizeof(float) because all of our parameters happen to be 4 bytes.  if various
			// parameters took different amounts of data, we'd check the size on a per-parameter
			// basis.
			if (dataSize >= sizeof(float)) switch (param)
			{
			case LATENCY_PARAM:
				{
					float value = *((float*) event->pointer);
					mLatency = bigtime_t(value* 1000);
					mLastLatencyChange = logMsg.now;

					// my latency just changed, so reconfigure the BMediaEventLooper
					// to give me my events at the proper time
					SetEventLatency(mLatency);

					// tell the producer that my latency changed, and broadcast a message
					// about the parameter change to any applications that may be looking
					// for it through the BMediaRoster::StartWatching() mechanism.
					//
					// if we had more than one input, we'd need to tell *all* producers about
					// the change in our latency.
					SendLatencyChange(mInput.source, mInput.destination, EventLatency() + SchedulingLatency());
					BroadcastNewParameterValue(logMsg.now, param, &value, sizeof(value));

					// log the new latency value, for recordkeeping
					logMsg.param.value = value;
					mLogger->Log(LOG_SET_PARAM_HANDLED, logMsg);
				}
				break;

			case CPU_SPIN_PARAM:
				{
					float value = *((float*) event->pointer);
					mSpinPercentage = value;
					mLastSpinChange = logMsg.now;
					BroadcastNewParameterValue(logMsg.now, param, &value, sizeof(value));
					logMsg.param.value = value;
					mLogger->Log(LOG_SET_PARAM_HANDLED, logMsg);
				}
				break;

			case PRIORITY_PARAM:
				{
					mPriority = *((int32*) event->pointer);
					// DO NOT use ::set_thead_priority() to directly alter the node's control
					// thread priority.  BMediaEventLooper tracks the priority itself and recalculates
					// the node's scheduling latency whenever SetPriority() is called.  This is VERY
					// important for correct functioning of a node chain.  You should *only* alter a
					// BMediaEventLooper's priority by calling its SetPriority() method.
					SetPriority(mPriority);

					mLastPrioChange = logMsg.now;
					BroadcastNewParameterValue(logMsg.now, param, &mPriority, sizeof(mPriority));
					logMsg.param.value = (float) mPriority;
					mLogger->Log(LOG_SET_PARAM_HANDLED, logMsg);
				}
				break;

			// log the fact that we "handled" a "set parameter" event for a
			// nonexistent parameter
			default:
				mLogger->Log(LOG_INVALID_PARAM_HANDLED, logMsg);
				break;
			}
		}
		break;

	case BTimedEventQueue::B_START:
		// okay, let's go!
		mLogger->Log(LOG_START_HANDLED, logMsg);
		break;

	case BTimedEventQueue::B_STOP:
		mLogger->Log(LOG_STOP_HANDLED, logMsg);
		// stopping implies not handling any more buffers.  So, we flush all pending
		// buffers out of the event queue before returning to the event loop.
		EventQueue()->FlushEvents(0, BTimedEventQueue::B_ALWAYS, true, BTimedEventQueue::B_HANDLE_BUFFER);
		break;

	case BTimedEventQueue::B_SEEK:
		// seeking the log doesn't make any sense, so we just log that we handled the seek
		// and return without doing anything else
		mLogger->Log(LOG_SEEK_HANDLED, logMsg);
		break;

	case BTimedEventQueue::B_WARP:
		// similarly, time warps aren't meaningful to the logger, so just record it and return
		mLogger->Log(LOG_WARP_HANDLED, logMsg);
		break;

	case BTimedEventQueue::B_DATA_STATUS:
		// we really don't care about the producer's data status, but this is where
		// we'd do something about it if we did.
		logMsg.data_status.status = event->data;
		mLogger->Log(LOG_DATA_STATUS_HANDLED, logMsg);
		break;

	default:
		// hmm, someone enqueued a message that we don't understand.  log and ignore it.
		logMsg.unknown.what = event->type;
		mLogger->Log(LOG_HANDLE_UNKNOWN, logMsg);
		break;
	}
}
コード例 #26
0
ファイル: AudioFilterNode.cpp プロジェクト: mariuz/haiku
// create or discard buffer group if necessary
void AudioFilterNode::updateBufferGroup() {

	status_t err;
	
	size_t inputSize = bytes_per_frame(m_input.format.u.raw_audio);
	size_t outputSize = bytes_per_frame(m_output.format.u.raw_audio);
	
	if(m_input.source == media_source::null ||
		m_output.destination == media_destination::null ||
		inputSize >= outputSize) {

		PRINT(("###### NO BUFFER GROUP NEEDED\n"));
		
		// no internal buffer group needed
		if(m_bufferGroup) {
			// does this block? +++++
			delete m_bufferGroup;
			m_bufferGroup = 0;
		}
		return;
	}
	
	int32 bufferCount = EventLatency() / BufferDuration() + 1 + 1;
	
	// +++++
	// [e.moon 27sep99] this is a reasonable number of buffers,
	// but it fails with looped file-player node in BeOS 4.5.2.
	//
	if(bufferCount < 5)
		bufferCount = 5;
//	if(bufferCount < 3)
//		bufferCount = 3;
		
	if(m_bufferGroup) {

		// is the current group sufficient?
		int32 curBufferCount;
		err = m_bufferGroup->CountBuffers(&curBufferCount);
		if(err == B_OK && curBufferCount >= bufferCount) {		
			BBuffer* buf = m_bufferGroup->RequestBuffer(
				outputSize, -1);
		
			if(buf) {
				// yup
				buf->Recycle();
				return;
			}
		}

		// nope, delete it to make way for the new one
		delete m_bufferGroup;
		m_bufferGroup = 0;		
	}
	
	// create buffer group
	PRINT((
		"##### AudioFilterNode::updateBufferGroup():\n"
		"##### creating %ld buffers of size %ld\n",
		bufferCount, m_output.format.u.raw_audio.buffer_size));

	m_bufferGroup = new BBufferGroup(
		m_output.format.u.raw_audio.buffer_size,
		bufferCount);
}
コード例 #27
0
ファイル: VideoProducer.cpp プロジェクト: stippi/Clockwerk
// GetLatency
status_t 
VideoProducer::GetLatency(bigtime_t* out_latency)
{
	*out_latency = EventLatency() + SchedulingLatency();
	return B_OK;
}
コード例 #28
0
ファイル: BeOutputNode.cpp プロジェクト: dakk/Faber
status_t EMBeOutputNode::GetLatency(bigtime_t* out_latency)
{
	// report our *total* latency:  internal plus downstream plus scheduling
	(*out_latency) = EventLatency() + SchedulingLatency();
	return B_OK;
}