⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xaosproducer.cpp

📁 另一个分形程序
💻 CPP
📖 第 1 页 / 共 4 页
字号:
				if (/*ts_running*/1) {			bigtime_t now_real = BTimeSource::RealTime();			if (m_stopping) {				// There's a pending Stop request.				if (now_real >= TimeSource()->RealTimeFor(m_tpStop, TotalLatency())) {					// It's time to handle that Stop request.					TRANSPORT(stderr, "XaoSProducer::Stop() takes effect\n");					m_running = false;					m_stopping = false; // we've now stopped					if (m_seeking) {						// There's a seek pending, but we'll defer any						// pending seeks until we next start.						m_seeking = false;					}					else {						// Set the seek time so that, by default, we						// restart where we stopped.						m_tmSeekTo = m_tpStop-m_delta;						TRANSPORT(stderr, "Setting m_tmSeekTo to %.4f\n", us_to_s(m_tmSeekTo));					}					// Very important! Tell the Consumer that we're no longer					// sending data to it, so it doesn't sit around waiting for					// the buffers that never come.					if (connected) {						SendDataStatus(B_DATA_NOT_AVAILABLE, m_output.destination, m_tpStop);					}					//	Restart the loop because we changed timing info.					continue;				}				else {					// It's not quite yet time to Stop, but if it's a sooner					// event than our next perf_target, set it to be the					// next perf_target.					if (m_tpStop < perf_target) {						TRANSPORT(stderr, "m_tpStop perf_target from %.4f to %.4f\n",							us_to_s(perf_target), us_to_s(m_tpStop));						perf_target = m_tpStop;					}				}			}			if (m_seeking) {				// There's a pending Seek request.				if (now_real >= TimeSource()->RealTimeFor(m_tpSeekAt, TotalLatency())) {					// It's time to handle that Seek request.					TRANSPORT(stderr, "XaoSProducer::Seek() takes effect\n");					m_seeking = false;					// Seek gives us the relationship between media time					// and performance time. We represent this relationship					// via m_delta -- see the description in XaoSProducer.h.					//					// Note: m_frames_played is not addressed here, which I					// believe is incorrect. Something to look into when					// we actually use Seek...					m_delta = m_tpSeekAt-m_tmSeekTo;					TRANSPORT(stderr, "setting m_delta to %.4f\n", us_to_s(m_delta));					//	Restart the loop because we changed timing info.					continue;				}				else {					// It's not quite yet time to Seek, but if it's a sooner					// event than our next perf_target, set it to be the					// next perf_target.					if (m_tpSeekAt < perf_target) {						TRANSPORT(stderr, "m_tpSeek perf_target from %.4f to %.4f\n",							us_to_s(perf_target), us_to_s(m_tpSeekAt));						perf_target = m_tpSeekAt;					}				}			}			if (m_starting) {				// There's a pending Start request.				printf("Starting thread!\n");				if (now_real >= TimeSource()->RealTimeFor(m_tpStart, TotalLatency())) {					printf("Starting OK\n");					// It's time to handle that Start request.					TRANSPORT(stderr, "XaoSProducer::Start() takes effect\n");					m_running = true;					// Seek to the correct point in the media before					// we begin. This offset might have been set by					// a Seek operation or the last Stop operation.					// We seek by setting the offset between media time					// and performance time.					m_delta = m_tpStart-m_tmSeekTo;					TRANSPORT(stderr, "setting m_delta to %.4f\n", us_to_s(m_delta));					m_frames_played = 0;					m_starting = false; // we've now started									// Very important! Tell the Consumer that we'll be sending					// data to it, so it's expecting us.					if (connected) {						SendDataStatus(B_DATA_AVAILABLE, m_output.destination, m_tpStart);					}					//	Restart the loop because we changed timing info.					continue;				}				else {					// It's not quite yet time to Start, but if it's a sooner					// event than our next perf_target, set it to be the					// next perf_target.					if (m_tpStart < perf_target) {						TRANSPORT(stderr, "m_tpStart perf_target from %.4f to %.4f\n",							us_to_s(perf_target), us_to_s(m_tpStart));						perf_target = m_tpStart;					}				}			}						// Finally, calculate the all-important timeout value.			// The timeout value is the difference in real time			// between now and the real time at which our thread			// needs to handle the next event which occurs at			// perf_target.			timeout = TimeSource()->RealTimeFor(perf_target, TotalLatency()) -				BTimeSource::RealTime();		}		else if (m_running) {			// pathological case: we set a strange timeout value that we			// can recognize later on if necessary. If we're not connected,			// we'll make it a huge timeout and catch that error later			// on.			timeout = connected ? 9999 : 9999999;			WARNING(stderr, "XaoSProducer: m_running but not (connected && ts_running)\n"); 		} else {			WARNING(stderr, "XaoSProducer: ! ts_running\n");		}				// Adjust the timeout to make sure it's reasonable.		if (timeout <= 0) {			// We needed to start handling the next event before now.			if ((RunMode() != B_OFFLINE) && (timeout < -50000)) {				// We're way behind in a real-time run mode --				// just skip forward in the media to catch up!				m_delta -= timeout-5000;			}						// Give us some breathing room to check for messages.			// We don't simply refuse to handle messages when			// we're behind so that we can remain responsive even			// when our buffer-producing ability is maxed out.			timeout = 1000;		}				////////////////////////////////////////////////////////////		// Step 2: Check for pending messages.				// Conveniently enough, if there are no pending messages,		// this call to read_port_etc will force our thread to		// wait for the length of timeout. Recall, we just set		// timeout to be the real time until the next performance		// event or buffer production needs to happen, whichever		// comes first.		int32 code = 0;		fprintf(stderr, "XaoS Thread:Waiting for messages\n");		status_t err = read_port_etc(m_port, &code, msg, B_MEDIA_MESSAGE_SIZE, B_TIMEOUT, timeout);		fprintf(stderr, "XaoS Thread:message received\n");		//	If we received a message, err will be the size of the message (including 0).				if (err >= 0) {			bad = 0;			NODE(stderr, "XaoSProducer msg %#010lx\n", code);						// Check for our private stop message.			if (code == MSG_QUIT_NOW) {	//	quit now				NODE(stderr, "XaoSProducer quitting\n");#if 0				if (m_notifyHook) {					(*m_notifyHook)(m_cookie, B_NODE_DIES, 0);				}				else {					Notify(B_NODE_DIES, 0);				}#endif				break;			}			//	Else it is hopefully a regular media kit message; go ahead and			//	dispatch it. (HandleMessage addresses the case that the message			//	wasn't understood by anybody.)			else {				HandleMessage(code, msg, err);			}		}		//	Timing out means that there was no buffer, which is ok.		//	Other errors, though, are bad.		else if (err != B_TIMED_OUT) {			WARNING(stderr, "XaoSProducer::ServiceThread(): port says %#010lx (%s)\n", err, strerror(err));			bad++;			//	If we receive three bad reads with no good messages in between,			//	things are probably not going to improve (like the port disappeared			//	or something) so we call it a day.			if (bad > 3) {#if 0				if (m_notifyHook) {					(*m_notifyHook)(m_cookie, B_NODE_DIES, bad, err, code, msg);				}				else {					Notify(B_NODE_DIES, bad, err, code, msg);				}#endif				break;			}		}		else {			////////////////////////////////////////////////////////////			// Step 3: Produce and send a buffer			bad = 0;			if (timeout > 1000000) {				// We set a huge timeout when we were running, but the				// time source isn't running, and we're not connected?				continue;	// don't actually play			}						// Only make a buffer if time is running, and if we are			// running, connected, enabled, and can get a buffer.			if (ts_running) {				if (connected && m_running) {					char c[100];					string_for_format(m_output.format,c,100);					fprintf(stderr,"Buffer! %s\n",100);					BBuffer * buffer = m_buffers->RequestBuffer(	                                        m_output.format.u.raw_video.display.line_count*m_output.format.u.raw_video.display.bytes_per_row);					fprintf(stderr,"Buffer! OK\n");					if (buffer) {						bigtime_t now = TimeSource()->Now();						NODE(stderr, "XaoSProducer making a buffer at %Ld.\n", now);						// Whee, we actually get to make a buffer!						// Fill the buffer's header fields.						buffer->Header()->start_time = buffer_perf;						buffer->Header()->size_used = (m_output.format.u.raw_video.display.line_count*m_output.format.u.raw_video.display.bytes_per_row);						//	If there is a play hook, let the interested party have at it!#if 0						if (m_playHook) {							(*m_playHook)(m_cookie, buffer->Header()->start_time-m_delta,								buffer->Data(), buffer->Header()->size_used,								m_output.format.u.raw_video);						}						else {							Play(buffer->Header()->start_time-m_delta,								buffer->Data(), buffer->Header()->size_used,								m_output.format.u.raw_video);						}#endif												// Update our frame counter and send the buffer off!						// If the send is successful, the last consumer to use						// the buffer will recycle it for us.						m_frames_played ++;						if (acquire_sem_etc(m_sendBufferSem, 1, B_TIMEOUT, 30000) != B_OK) {							WARNING(stderr, "XaoSProducer: couldn't acquire send buffer sem\n");							buffer->Recycle();						} else {							if (SendBuffer(buffer, m_output.destination) < B_OK) {								// On the other hand, if the send is unsuccessful,								// we mustn't forget to recycle the buffer ourselves.								buffer->Recycle();							}							release_sem(m_sendBufferSem);						}					}					else {						// Something has gone screwy with our buffer group. To						// avoid spewing lots of debug output, we'll only print						// a message once every 256 occurrences.						static int32 warning_cnt = 0;						if (!(atomic_add(&warning_cnt, 1) & 255)) {							WARNING(stderr, "XaoSProducer: RequestBuffer() failed\n");						}					}				}				else {					// Time is running, but there's no reason for us to					// actually process a buffer, becuase we won't be					// sending it -- we're not connected, running, or					// we've been told to shut up. We'll fake up timing					// values so that our next timeout is as short as					// possible.					bigtime_t now = TimeSource()->Now();					// Pretend that our next performance is exactly our					// latency's worth away (i.e. that we need to start					// processing right away).					buffer_perf = now+TotalLatency();					// Set m_frames_played based on this value, so that the					// top of the next loop will Do the Right Thing.#if 0					m_frames_played = frames_for_duration(m_output.format.u.raw_video,						buffer_perf-m_delta);#endif					m_frames_played = (int)((buffer_perf - m_delta) * m_output.format.u.raw_video.field_rate / 1000000);				}			}			else {				// We can't do anything when time isn't running.				TRANSPORT(stderr, "time source is not running\n");			}		}	}}void XaoSProducer::alloc_buffers(){	delete m_buffers;        int size;	char fmt[100];	bigtime_t latency = TotalLatency();	int count = (int)(latency * m_output.format.u.raw_video.field_rate / 1000000+ 2);	fprintf(stderr,"XaoSProducer:: alloc_buffers (latency:%i count:%i field rate:%i)\n",(int)latency, (int)count, (int)m_output.format.u.raw_video.field_rate);		string_for_format(m_output.format, fmt, 100);		FORMAT(stderr, "We've decided to use %s\n", fmt);	// But if count is too small, we'd like to have three buffers	// at the very least, to give us some stability.	if (count < 3) count = 3;	size = m_output.format.u.raw_video.display.line_count*m_output.format.u.raw_video.display.bytes_per_row;#define MAXSIZE (1024*1024*4) /*Maximal bufer is 4MB*/	if (count*(long long)size > (long long)MAXSIZE) {		count = MAXSIZE/size;		if (count < 1) count = 1;         }#if 0	// We should set a reasonable maximum on the size of our memory	// pool. We'll restrict it to 128K.	if (count*m_output.format.u.raw_video.buffer_size > 128000) {		count = 128000/m_output.format.u.raw_audio.buffer_size;		// We do need to make sure there's at least one buffer, though.		if (count < 1) count = 1;	}#endif	NODE(stderr, "Need %d buffers of size %i\n", count, size);	m_buffers = new BBufferGroup(size, count);}bigtime_tXaoSProducer::ProcessingLatency(){       /* XaoS attempts to keep framerate higher than 5 frames per second, but sometimes it is imposible */	return (1000000/25);}bigtime_tXaoSProducer::TotalLatency(){	return ProcessingLatency() + m_downstream_latency + m_private_latency;}voidXaoSProducer::Play(	bigtime_t /* time */,	void * /* data */,	size_t /* size */,	const media_raw_video_format & /* format */){	//	If there is no play hook installed, we instead call this function	//	for received buffers.}voidXaoSProducer::Notify(	int32 /* cause */,	...){	//	If there is no notification hook installed, we instead call this function	//	for giving notification of various events.}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -