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

📄 a2dpd_timer.c

📁 linux蓝牙剖面实现
💻 C
字号:
/***  A2DPD - Bluetooth A2DP daemon for Linux**  Copyright (C) 2006  Frédéric DALLEAU <frederic.dalleau@palmsource.com>**  This program is free software; you can redistribute it and/or modify*  it under the terms of the GNU General Public License as published by*  the Free Software Foundation; either version 2 of the License, or*  (at your option) any later version.**  This program is distributed in the hope that it will be useful,*  but WITHOUT ANY WARRANTY; without even the implied warranty of*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the*  GNU General Public License for more details.**  You should have received a copy of the GNU General Public License*  along with this program; if not, write to the Free Software*  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*/#define MAXTOTALCOUNT (700000*1000)#include "a2dpd_timer.h"#include "a2dpd_protocol.h"#include <time.h>#include <unistd.h>#include <syslog.h>int sleeptodate(LPTIMERINFO lpTimerInfo, struct timeval *date, int predelay){	int result = 0;	struct timeval now;	struct timeval resolutionval = { 0, predelay + (int) (lpTimerInfo->timer_resolution.tv_nsec / 1000) };	// See if we have time to wait	timeradd(&lpTimerInfo->timeofday, &resolutionval, &now);	if (timercmp(date, &now, >)) {		// Synchronise with usleep 20 ms cycle		//usleep(1);		//result = 1;		//return 1;		// See if we must wait again		gettimeofday(&now, NULL);		timeradd(&now, &resolutionval, &now);		if (timercmp(date, &now, >)) {			struct timeval interval = { 0, 0 };			timersub(date, &now, &interval);			// sleep			usleep(interval.tv_usec);			//DBG("Sleeping %d", (int)interval.tv_usec);			result = interval.tv_usec;		} else {			// We're late, do not wait			//DBG("We waited");		}	} else {		// We're late, do not wait		//DBG("We're late (date=%d <= now=%d) res=%d", (int)date->tv_usec, (int)now.tv_usec, (int)(resolutionval.tv_usec));	}	if(result<lpTimerInfo->timer_resolution.tv_nsec)		result=1;	return result;}// This version uses values never resetint keepfreqtotal(LPTIMERINFO lpTimerInfo, int predelay){	int result = 0;	struct timeval playtime, theoricaldate;	gettimeofday(&lpTimerInfo->timeofday, NULL);	//FIXME It is not necessary to use unsigned long if we reset periodically the value of itotalcount (see MAXTOTALCOUNT)	// if MAXTOTALCOUNT < 700000, we will fit in signed 32bit and reset no more than every 36 mins.	// Resetting that value might cause a small sound break.	// Setting MAXTOTALCOUNT to lpTimerInfo->fps will reset every second (useful for testing purposes)	playtime.tv_sec = ((unsigned long) ((1.0 * (lpTimerInfo->itotalcount) / lpTimerInfo->fps)));	playtime.tv_usec = ((unsigned long) ((1.0 * 1000.0 * 1000.0 / lpTimerInfo->fps) * (lpTimerInfo->itotalcount))) % 1000000;	timeradd(&lpTimerInfo->totalcounter, &playtime, &theoricaldate);	//DBG("Frame %d will play at %d.%d", (int)lpTimerInfo->itotalcount, (int)theoricaldate.tv_sec, (int)(theoricaldate.tv_usec));	// If calculated date is higher than current date	if (timercmp(&theoricaldate, &lpTimerInfo->timeofday, >)) {		result = sleeptodate(lpTimerInfo, &theoricaldate, predelay);	} else {		// We're late, do not wait		//DBG("We're late (date=%d <= now=%d) res=%d", (int)lpTimerInfo->timeofday.tv_usec, (int)theoricaldate.tv_usec, (int)(theoricaldate.tv_usec));	}	return result;}void a2dp_timer_notifyframe(LPTIMERINFO lpTimerInfo){//	DBG("Frame");	struct timeval lastframe_interval = { 0, 0 };	struct timeval maxallowed_interval = { 0, 200 * 1000 };	gettimeofday(&lpTimerInfo->timeofday, NULL);	timersub(&lpTimerInfo->timeofday, &lpTimerInfo->lastframe, &lastframe_interval);	// Previous frames older than 1 second, reset counters	if (timercmp(&lastframe_interval, &maxallowed_interval, >)) {		// We must reset the total counter because else, we will believe the date is late		gettimeofday(&lpTimerInfo->totalcounter, NULL);		//DBG("Resetting interval at %d.%d", (int)lpTimerInfo->totalcounter.tv_sec, (int)lpTimerInfo->totalcounter.tv_usec);		lpTimerInfo->itotalcount = 0;	}	gettimeofday(&lpTimerInfo->lastframe, NULL);}int a2dp_timer_sleep(LPTIMERINFO lpTimerInfo, int predelay){	int result = 0;	gettimeofday(&lpTimerInfo->timeofday, NULL);	// Initialize timers	if (lpTimerInfo->staticcounter.tv_sec == 0)		gettimeofday(&lpTimerInfo->staticcounter, NULL);	if (lpTimerInfo->totalcounter.tv_sec == 0 || lpTimerInfo->itotalcount > MAXTOTALCOUNT) {		gettimeofday(&lpTimerInfo->totalcounter, NULL);		//DBG("Resetting counter at %d.%d", (int)lpTimerInfo->totalcounter.tv_sec, (int)lpTimerInfo->totalcounter.tv_usec);		lpTimerInfo->itotalcount = 0;	}	if (lpTimerInfo->timer_resolution.tv_nsec == 0)		clock_getres(CLOCK_REALTIME, &lpTimerInfo->timer_resolution);	// Duration since last call	timersub(&lpTimerInfo->timeofday, &lpTimerInfo->staticcounter, &lpTimerInfo->duration);	// Display data once per second	if (lpTimerInfo->duration.tv_sec > 0) {		// Reset all statistics		gettimeofday(&lpTimerInfo->staticcounter, NULL);		lpTimerInfo->display = lpTimerInfo->icount;		lpTimerInfo->icount = 0;	} else {		lpTimerInfo->display = 0;	}	result = keepfreqtotal(lpTimerInfo, predelay);	lpTimerInfo->icount++;	lpTimerInfo->itotalcount++;		return result;}

⌨️ 快捷键说明

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