Sfoglia il codice sorgente

Merge branch 'dev' of http://mayun.itc.cmbchina.cn/QD_RemoteBankArea/LR04.02_RVCTerminalPlus into dev

gifur 4 anni fa
parent
commit
95cf37dd1a

+ 34 - 16
Module/mod_recorder/mod_recorder.cpp

@@ -83,7 +83,6 @@ public:
 		ErrorCodeEnum Error = Error_Succeed;
 		nActiveCamera = CAMERA_TYPE_ENV;
 		m_iCameraState = 'N';
-		BOOL bRet = FALSE;
 
 		//int nCameraCount = 0;
 		//Error = DecideCameraCount(nCameraCount);
@@ -91,19 +90,6 @@ public:
 		//	LOG_TRACE("decide camera count failed!");
 		//	return Error;
 		//}
-		if ((ePadtype == m_eDeviceType )||(eMobilePadType == m_eDeviceType)||(eDesk2SType == m_eDeviceType))
-		{
-			//pad 版增加远端视频队列
-			m_pRecorder = new Clibwmvrecord(&bRet, this, REC_COMMON_AUDIO_SHM_QUEUE, 
-				REC_COMMON_VIDEO_ENV_SHM_RTP_QUEUE,NULL);
-		} 
-		else 
-		{ 
-			//  == 2
-			m_pRecorder = new Clibwmvrecord(&bRet, this, REC_COMMON_AUDIO_SHM_QUEUE, 
-				REC_COMMON_VIDEO_ENV_SHM_RTP_QUEUE,REC_COMMON_VIDEO_OPT_SHM_RTP_QUEUE);
-		}
-		Dbg("init libwmvrecord success!");
 		
 		GetFunction()->SubscribeLog(m_SubIDStartRecord, this, Log_Event, Severity_Middle, Error_IgnoreAll, EVENT_MOD_BEGIN_RECORD, NULL, false);
 		GetFunction()->SubscribeLog(m_SubIDStopRecord, this, Log_Event, Severity_Middle, Error_IgnoreAll, EVENT_MOD_END_RECORD, NULL, false);
@@ -219,6 +205,35 @@ public:
 		Dbg("OnRecordFinished!");
 	}
 
+	BOOL InitRecorder()
+	{
+		BOOL bRet = FALSE;
+
+		if ((ePadtype == m_eDeviceType) || (eMobilePadType == m_eDeviceType) || (eDesk2SType == m_eDeviceType))
+		{
+			//pad 版增加远端视频队列
+			m_pRecorder = new Clibwmvrecord(&bRet, this, REC_COMMON_AUDIO_SHM_QUEUE,
+				REC_COMMON_VIDEO_ENV_SHM_RTP_QUEUE, NULL);
+		}
+		else
+		{
+			//  == 2
+			m_pRecorder = new Clibwmvrecord(&bRet, this, REC_COMMON_AUDIO_SHM_QUEUE,
+				REC_COMMON_VIDEO_ENV_SHM_RTP_QUEUE, REC_COMMON_VIDEO_OPT_SHM_RTP_QUEUE);
+		}
+		Dbg("init libwmvrecord success!");
+
+		return bRet;
+	}
+
+	BOOL ReleaseRecorder()
+	{
+		if (m_pRecorder){
+			delete m_pRecorder;
+			m_pRecorder = NULL;
+		}
+	}
+
 	virtual void OnLog(const CAutoArray<CUUID> &SubIDs, const CUUID nLogID,const LogTypeEnum eLogType, const SeverityLevelEnum eLevel,
 		const DWORD dwSysError,const DWORD dwUserCode,const DWORD dwEntityInstanceID, const WORD wEntityDevelID, 
 		const CAutoArray<DWORD> &Param, const char *pszEntityName, const char *pszModuleName,const char *pszMessage)
@@ -226,17 +241,20 @@ public:
 		if (/*(dwUserCode == EVENT_MOD_CUSTOMERAWARE_BEGIN)||*/(dwUserCode == EVENT_MOD_BEGIN_RECORD))
 		{ 
 			Dbg("start record!");
-			StartRecord(pszMessage);
+			if (InitRecorder()){
+				StartRecord(pszMessage);
+			}
 		} 
 		else if (/*(dwUserCode == EVENT_MOD_CUSTOMERAWARE_END)||*/(dwUserCode == EVENT_MOD_END_RECORD)) 
 		{
 			Dbg("stop record!");
 			StopRecord();
+			ReleaseRecorder();
 		}
 		else if (dwUserCode == LOG_EVT_UI_RETURNMENU) // 返回主菜单
 		{
 			//本地录像,退回到首页关闭当前文件,重新开始录制
-			if (m_bStarted)
+			if (m_bStarted&&m_pRecorder)
 			{
 				Dbg("return menu,close video file!");
 				m_pRecorder->CloseVideoFile();

+ 1 - 1
Other/libaudioframework/audioengine.c

@@ -257,7 +257,7 @@ void audioengine_stop_context(audioengine_t *e, audiocontext_t *ctx)
 		int i;
 		apr_thread_mutex_lock(e->mtx);
 		for (i = 0; i < e->arr_ctx->nelts; ++i) {
-			if (ctx = APR_ARRAY_IDX(e->arr_ctx, i, audiocontext_t*)) {
+			if (ctx == APR_ARRAY_IDX(e->arr_ctx, i, audiocontext_t*)) {
 				if (i < e->arr_ctx->nelts-1) {
 					audiocontext_t *tmp = APR_ARRAY_IDX(e->arr_ctx, i, audiocontext_t*);
 					APR_ARRAY_IDX(e->arr_ctx, i, audiocontext_t*) = APR_ARRAY_IDX(e->arr_ctx, e->arr_ctx->nelts-1, audiocontext_t*);

+ 133 - 81
Other/libaudioframework/audiomicspkpulse.c

@@ -19,18 +19,27 @@
 #define AUDIO_STRM_ON       1
 #define AUDIO_STRM_OFF      0
 
+#ifndef RVC_MAX_AUDIO_BUFFER_LEN
+#define RVC_MAX_AUDIO_BUFFER_LEN 1024
+#endif
+
+#ifndef RVC_DELAY_AUDIO_LEN
+#define RVC_DELAY_AUDIO_LEN 160
+#endif
+
 #ifndef RVC_PA_ADJUST_LATENCY_PROTOCOL_VERSION
 #define RVC_PA_ADJUST_LATENCY_PROTOCOL_VERSION 13
 #endif
 
 static uint32_t latency_ms = 10; // requested initial latency in milisec: 0 use max
-static pa_usec_t latency = 0; //real latency in usec (for timestamping)
+static pa_usec_t latency = 0; 	 //real latency in usec (for timestamping)
 
+static pa_usec_t play_latency = 0; 	 //real latency in usec (for timestamping)
 
-pa_stream* recordstream;	  /* pulse audio stream*/
-pa_context* pa_ctx;			  /* pulse context*/
+//pa_stream* recordstream;	  /* pulse audio stream*/
+//pa_context* pa_ctx;			  /* pulse context*/
 
-pa_stream* playstream;		/* pulse audio stream*/
+//pa_stream* playstream;		/* pulse audio stream*/
 pa_context* play_pa_ctx;			  /* pulse context*/
 
 static apr_status_t read_frame(void* self, audioframe_t* frame)
@@ -352,30 +361,31 @@ int pa_get_devicelist(audio_context_t* audio_ctx)
 int audio_init_pulseaudio(audio_context_t* audio_ctx)
 {
 	/*assertions*/
-	assert(NULL != audio_ctx);
+assert(NULL != audio_ctx);
 
-	if (pa_get_devicelist(audio_ctx) < 0)
-	{
-		audio_log_v(AUDIO_LOG_LEVEL_INFO, "pulse audio failed to get audio device list from pulse server.");
-		return -1;
-	}
+if (pa_get_devicelist(audio_ctx) < 0)
+{
+	audio_log_v(AUDIO_LOG_LEVEL_INFO, "pulse audio failed to get audio device list from pulse server.");
+	return -1;
+}
 
-	return 0;
+return 0;
 }
 
 apr_status_t audio_context_create(apr_pool_t* pool, audio_context_t** audio_ctx)
 {
 	audio_context_t* actx = (audio_context_t*)apr_pcalloc(pool, sizeof(audio_context_t));
-	
+
 	if (NULL == actx) {
 		audio_log_v(AUDIO_LOG_LEVEL_INFO, "%s:%d couldn't apr_pcalloc audio context.", __FUNCTION__, __LINE__);
 		return APR_EGENERAL;
 	}
 
-	/*initialize the mutex*/
-	pthread_mutex_init(&actx->mutex, NULL);
+	actx->paudio_buffer = (char*)malloc(RVC_MAX_AUDIO_BUFFER_LEN*sizeof(char));
+	actx->uaudio_len = 0;
+
 
-	if (audio_init_pulseaudio(actx)){
+	if (audio_init_pulseaudio(actx)) {
 		audio_log_v(AUDIO_LOG_LEVEL_ERROR, "%s:%d audio init pulse audio failed.", __FUNCTION__, __LINE__);
 	}
 	else
@@ -405,53 +415,92 @@ static void get_latency(pa_stream* s)
 {
 	pa_usec_t l;
 	int negative;
-
 	pa_stream_get_timing_info(s);
-
 	if (pa_stream_get_latency(s, &l, &negative) != 0)
 	{
 		return;
 	}
+	latency = l;
+}
+
 
-	latency = l; 
+static void get_play_latency(pa_stream* s)
+{
+	pa_usec_t l;
+	int negative;
 
+	pa_stream_get_timing_info(s);
+	if (pa_stream_get_latency(s, &l, &negative) != 0) {
+		audio_log_v(AUDIO_LOG_LEVEL_INFO, "%s:%d pa_stream_get_latency failed for %s.", __FUNCTION__, __LINE__, pa_strerror(pa_context_errno(play_pa_ctx)));
+		return;
+	}
+	play_latency = l;
 }
 
 
+
 static void  stream_write_request_cb(pa_stream* s, size_t length, void* data)
 {
 	audio_context_t* audio_ctx = (audio_context_t*)data;
-	if (audio_ctx->channels == 0) {
-		return;
-	}
 
-	if (audio_ctx->samprate == 0) {
+	if (0 == audio_ctx->play_channels || 0 == audio_ctx->play_samprate) {
 		return;
 	}
 
-	audio_log_v(AUDIO_LOG_LEVEL_INFO, "%s:%d .", __FUNCTION__, __LINE__);
-	while (pa_stream_writable_size(s) > 0)
+	size_t nbytes = 0;
+	void* audiodata;
+	while ((nbytes = pa_stream_writable_size(s)) != (size_t)-1)
 	{
-		audio_log_v(AUDIO_LOG_LEVEL_INFO, "%s:%d .", __FUNCTION__, __LINE__);
-		/*write to stream*/
-		char playBuffer[160] = { 0 };
-		if (audio_ctx->bstart_put_flag && audio_ctx->micspkpulse_parent) {
-			int iget = delay_buf_get((delay_buf*)((audiomicspkpulse_t*)(audio_ctx->micspkpulse_parent))->ply_buf, (short*)playBuffer);
-			audio_log_v(AUDIO_LOG_LEVEL_INFO, "%s:%d delay_buf_get ret is %d.", __FUNCTION__, __LINE__, iget);
+		get_play_latency(s);
+		if (0 == nbytes){
+			return;
 		}
-		if (pa_stream_write(playstream, (void*)& playBuffer, write,
-			NULL, (int64_t)0, PA_SEEK_RELATIVE) != PA_OK)
+
+		/*write to stream*/
+		if (PA_OK == pa_stream_begin_write(s, &audiodata, &nbytes))
 		{
-			audio_log_v(AUDIO_LOG_LEVEL_INFO, "AUDIO: pulse audio pa_stream_write failed!");
-			return;
+			//audio_log_v(AUDIO_LOG_LEVEL_INFO, "%s:%d pa_stream_begin_write nbytes = %d.", __FUNCTION__, __LINE__, nbytes);
+
+			while (audio_ctx->uaudio_len < nbytes)
+			{
+				char delaybuffer[RVC_DELAY_AUDIO_LEN] = { 0 };
+				if (audio_ctx->bstart_get_flag && audio_ctx->micspkpulse_parent) {
+					if (0 == ((audiomicspkpulse_t*)(audio_ctx->micspkpulse_parent))->ply_buf_cnt) {
+						int iget = delay_buf_get((delay_buf*)((audiomicspkpulse_t*)(audio_ctx->micspkpulse_parent))->ply_dbuf, (short*)delaybuffer);
+						if (0 == iget){
+							if (audio_ctx->uaudio_len + RVC_DELAY_AUDIO_LEN < RVC_MAX_AUDIO_BUFFER_LEN){
+								memcpy(audio_ctx->paudio_buffer + audio_ctx->uaudio_len, delaybuffer, RVC_DELAY_AUDIO_LEN);
+								audio_ctx->uaudio_len += RVC_DELAY_AUDIO_LEN;
+							}
+							else{
+								memcpy(audio_ctx->paudio_buffer + audio_ctx->uaudio_len, delaybuffer, RVC_MAX_AUDIO_BUFFER_LEN - audio_ctx->uaudio_len);
+								audio_ctx->uaudio_len = nbytes = RVC_MAX_AUDIO_BUFFER_LEN;
+								break;
+							}
+						}
+					}
+				}
+			}
+
+			int ileft = audio_ctx->uaudio_len - nbytes;
+			memcpy(audiodata, audio_ctx->paudio_buffer, nbytes);
+			audio_ctx->uaudio_len = ileft;
+			if (ileft > 0) {
+				memcpy(audio_ctx->paudio_buffer, audio_ctx->paudio_buffer + nbytes, ileft);
+			}
+
+			if (PA_OK != pa_stream_write(s, audiodata, nbytes, NULL, 0, PA_SEEK_RELATIVE)) {
+				//audio_log_v(AUDIO_LOG_LEVEL_INFO, "%s:%d pa_stream_write failed.", __FUNCTION__, __LINE__);
+				break;
+			}
+			//else {
+			//	audio_log_v(AUDIO_LOG_LEVEL_INFO, "%s:%d pa_stream_write success.", __FUNCTION__, __LINE__);
+			//}
 		}
 		else {
-			audio_log_v(AUDIO_LOG_LEVEL_INFO, "%s:%d AUDIO: pulse audio pa_stream_write success!", __FUNCTION__, __LINE__);
+			audio_log_v(AUDIO_LOG_LEVEL_INFO, "%s:%d pa_stream_begin_write failed for %s.", __FUNCTION__, __LINE__, pa_strerror(pa_context_errno(play_pa_ctx)));
 		}
-
-		pa_stream_drop(s); /*clean the samples*/
 	}
-	audio_log_v(AUDIO_LOG_LEVEL_INFO, "%s:%d .", __FUNCTION__, __LINE__);
 }
 
 static void stream_request_cb(pa_stream* s, size_t length, void* data)
@@ -480,7 +529,7 @@ static void stream_request_cb(pa_stream* s, size_t length, void* data)
 		/*read from stream*/
 		if (pa_stream_peek(s, &inputBuffer, &length) < 0)
 		{
-			audio_log_v(AUDIO_LOG_LEVEL_INFO, "AUDIO: pulse audio pa_stream_peek failed");
+			audio_log_v(AUDIO_LOG_LEVEL_INFO, "AUDIO: pulse audio pa_stream_peek failed.");
 			return;
 		}
 		else {
@@ -516,6 +565,7 @@ void* pulse_read_audio(void* data)
 
 	pa_mainloop* pa_ml;
 	pa_mainloop_api* pa_mlapi;
+	pa_context* pa_ctx;
 	pa_buffer_attr bufattr;
 	pa_sample_spec ss;
 	pa_stream_flags_t flags = PA_STREAM_NOFLAGS;
@@ -566,7 +616,7 @@ void* pulse_read_audio(void* data)
 	ss.channels = audio_ctx->channels;
 	ss.format = audio_ctx->eformat/*PA_SAMPLE_FLOAT32LE*/; /*for PCM -> PA_SAMPLE_S16LE*/
 
-	recordstream = pa_stream_new(pa_ctx, "Record", &ss, NULL);
+	pa_stream* recordstream = pa_stream_new(pa_ctx, "Record", &ss, NULL);
 	if (!recordstream){
 		audio_log_v(AUDIO_LOG_LEVEL_INFO, "pulse audio pa_stream_new failed (chan:%d rate:%d)", ss.channels, ss.rate);
 	}
@@ -610,7 +660,7 @@ void* pulse_read_audio(void* data)
 
 	if (r < 0)
 	{
-		audio_log_v(AUDIO_LOG_LEVEL_INFO, "AUDIO: (pulse audio) pa_stream_connect_record failed for %s.", pa_context_errno(pa_ctx));
+		audio_log_v(AUDIO_LOG_LEVEL_INFO, "AUDIO: (pulse audio) pa_stream_connect_record failed for %d.", pa_context_errno(pa_ctx));
 		finish(pa_ctx, pa_ml);
 		return ((void*)-1);
 	}
@@ -658,6 +708,13 @@ int audio_start_pulseaudio(audio_context_t* audio_ctx)
 }
 
 
+static void stream_latency_cb(pa_stream* p, void* userdata) 
+{
+	pa_operation* o;
+	o = pa_stream_update_timing_info(p, NULL, NULL);
+	pa_operation_unref(o);
+}
+
 void* pulse_write_audio(void* data)
 {
 	audio_context_t* audio_ctx = (audio_context_t*)data;
@@ -670,6 +727,7 @@ void* pulse_write_audio(void* data)
 	pa_sample_spec ss;
 	pa_stream_flags_t flags = PA_STREAM_NOFLAGS;
 	int32_t pastream_flag = (int32_t)PA_STREAM_NOFLAGS;
+
 	int r;
 	int pa_ready = 0;
 	char* dev = NULL;
@@ -682,7 +740,7 @@ void* pulse_write_audio(void* data)
 	play_pa_ctx = pa_context_new(pa_mlapi, "rvc play api");
 
 	if (PA_OK != pa_context_connect(play_pa_ctx, NULL, PA_CONTEXT_NOFLAGS, NULL)) {
-		audio_log_v(AUDIO_LOG_LEVEL_INFO, "AUDIO: PULSE - unable to connect to server: pa_context_connect failed for %s.", pa_context_errno(play_pa_ctx));
+		audio_log_v(AUDIO_LOG_LEVEL_INFO, "AUDIO: PULSE - unable to connect to server: pa_context_connect failed for %d.", pa_context_errno(play_pa_ctx));
 		finish(play_pa_ctx, pa_ml);
 		return ((void*)-1);
 	}
@@ -695,38 +753,35 @@ void* pulse_write_audio(void* data)
 	 * If there's an error, the callback will set pa_ready to 2
 	 */
 	pa_context_set_state_callback(play_pa_ctx, pa_state_cb, &pa_ready);
-
 	 /*
 	  * We can't do anything until PA is ready, so just iterate the mainloop
 	  * and continue
 	  */
 
-
 	while (pa_ready == 0) {
 		pa_mainloop_iterate(pa_ml, 1, NULL);
 	}
 	if (pa_ready == 2) {
-		audio_log_v(AUDIO_LOG_LEVEL_INFO, "%s:%d", __FUNCTION__, __LINE__);
 		finish(play_pa_ctx, pa_ml);
-		audio_log_v(AUDIO_LOG_LEVEL_INFO, "%s:%d", __FUNCTION__, __LINE__);
 		return ((void*)-1);
 	}
 
-
 	/* set the sample spec (frame rate, channels and format) */
 	ss.rate = audio_ctx->play_samprate;
 	ss.channels = audio_ctx->play_channels;
 	ss.format = audio_ctx->play_eformat;
 
-	playstream = pa_stream_new(play_pa_ctx, "playStream", &ss, NULL);
+	pa_stream* playstream = pa_stream_new(play_pa_ctx, "playStream", &ss, NULL);
 	if (!playstream) {
-		audio_log_v(AUDIO_LOG_LEVEL_INFO, "play audio pa_stream_new failed (chan:%d rate:%d) for %s.", ss.channels, ss.rate, pa_context_errno(play_pa_ctx));
+		audio_log_v(AUDIO_LOG_LEVEL_INFO, "play audio pa_stream_new failed (chan:%d rate:%d) for %d.", ss.channels, ss.rate, pa_context_errno(play_pa_ctx));
 	}
 
-	audio_log_v(AUDIO_LOG_LEVEL_INFO, "play audio stream state is %d", pa_stream_get_state(playstream));
+	audio_log_v(AUDIO_LOG_LEVEL_INFO, "play audio stream state is %d.", pa_stream_get_state(playstream));
 	/* define the callbacks */
 	pa_stream_set_write_callback(playstream, stream_write_request_cb, (void*)audio_ctx);
 
+	pa_stream_set_latency_update_callback(playstream, stream_latency_cb, NULL);
+
 	// Set properties of the record buffer
 	pa_zero(bufattr);
 	/* optimal value for all is (uint32_t)-1   ~= 2 sec */
@@ -734,44 +789,36 @@ void* pulse_write_audio(void* data)
 	bufattr.prebuf = (uint32_t)-1;
 	bufattr.minreq = (uint32_t)-1;
 
-	if (audio_ctx->latency > 0) {
-		bufattr.fragsize = bufattr.tlength = pa_usec_to_bytes((audio_ctx->latency * 1000) * PA_USEC_PER_MSEC, &ss);
+	if (audio_ctx->play_latency > 0) {
+		bufattr.fragsize = bufattr.tlength = pa_usec_to_bytes((audio_ctx->play_latency * 1000) * PA_USEC_PER_MSEC, &ss);
 		pastream_flag |= PA_STREAM_ADJUST_LATENCY;
 	}
-	else {
+	else{
 		bufattr.fragsize = bufattr.tlength = (uint32_t)-1;
 	}
-
-
+	
 	pastream_flag |= PA_STREAM_INTERPOLATE_TIMING;
 	pastream_flag |= PA_STREAM_AUTO_TIMING_UPDATE;
 
 	dev = audio_ctx->list_output_devices[audio_ctx->play_device].name;
 
-	audio_log_v(AUDIO_LOG_LEVEL_INFO, "play audio connecting to device %s (channels %d rate %d)", dev, ss.channels, ss.rate);
-
-	//if (update_speaker_volume_at_startup_) {
-	//	pa_cvolume cVolumes;
-	//	ptr_cvolume = &cVolumes;
-
-	//	// Set the same volume for all channels
-	//	const pa_sample_spec* spec = LATE(pa_stream_get_sample_spec)(_playStream);
-	//	LATE(pa_cvolume_set)(&cVolumes, spec->channels, volume);
-	//	update_speaker_volume_at_startup_ = false;
-	//}
+	audio_log_v(AUDIO_LOG_LEVEL_INFO, "play audio connecting to device %s (channels %d rate %d buf fragsize %d buf tlength %d)", dev, ss.channels, ss.rate, bufattr.fragsize, bufattr.tlength);
 
 	// Connect the stream to a sink
 	r = pa_stream_connect_playback(playstream, dev, &bufattr, (pa_stream_flags_t)pastream_flag, ptr_cvolume, NULL);
 	if (PA_OK != r)
 	{
-		audio_log_v(AUDIO_LOG_LEVEL_INFO, "play stream connected failed for %s.", pa_context_errno(play_pa_ctx));
+		audio_log_v(AUDIO_LOG_LEVEL_INFO, "play stream connected failed for %d.", pa_context_errno(play_pa_ctx));
 		finish(play_pa_ctx, pa_ml);
 		return ((void*)-1);
 	}
+	else {
+		audio_log_v(AUDIO_LOG_LEVEL_INFO, "play stream connected.");
+		const pa_sample_spec* spec = pa_stream_get_sample_spec(playstream);
+		audio_log_v(AUDIO_LOG_LEVEL_INFO, "play stream spec->format = %d, spec->channels = %d, spec->rate = %d.", spec->format, spec->channels, spec->rate);
+	}
 
-	audio_log_v(AUDIO_LOG_LEVEL_INFO, "play stream connected");
-
-	get_latency(playstream);
+	get_play_latency(playstream);
 
 	/*
 	 * Iterate the main loop while streaming.  The second argument is whether
@@ -804,7 +851,7 @@ int audio_start_audioplay(audio_context_t* audio_ctx)
 	if (pthread_create(&audio_ctx->writethreadid, NULL, pulse_write_audio, (void*)audio_ctx)) {
 		audio_log_v(AUDIO_LOG_LEVEL_INFO, "AUDIO: (pulse audio) write thread creation failed.");
 		audio_ctx->play_stream_flag = AUDIO_STRM_OFF;
-		return (-1);
+		return -1;
 	}
 	else {
 		audio_log_v(AUDIO_LOG_LEVEL_INFO, "AUDIO: (pulse audio) write thread create success, and thread id is %u.", audio_ctx->writethreadid);
@@ -862,15 +909,21 @@ void audio_close_pulseaudio(audio_context_t* audio_ctx)
 		audio_stop_pulseaudio(audio_ctx);
 	}
 
-	if (audio_ctx->list_input_devices != NULL) {
+	if (NULL != audio_ctx->list_input_devices) {
 		free(audio_ctx->list_input_devices);
 	}
 	audio_ctx->list_input_devices = NULL;
 
-	if (audio_ctx->list_output_devices != NULL) {
+	if (NULL != audio_ctx->list_output_devices) {
 		free(audio_ctx->list_output_devices);
 	}
 	audio_ctx->list_output_devices = NULL;
+
+	if (NULL != audio_ctx->paudio_buffer){
+		free(audio_ctx->paudio_buffer);
+	}
+	audio_ctx->paudio_buffer = NULL;
+	audio_ctx->uaudio_len = 0;
 }
 
 
@@ -958,7 +1011,8 @@ static int initialize_speaker(audiomicspkpulse_t* micspk)
 	}
 
 	audio_set_playdeviceid(micspk->audio_ctx, ply_dev_id);
-	audio_set_play_latency(micspk->audio_ctx, 0.01);
+	//audio_set_play_latency(micspk->audio_ctx, 0.01325);
+	audio_set_play_latency(micspk->audio_ctx, 0.02);
 	audio_set_play_samprate(micspk->audio_ctx, 8000);
 	audio_set_play_channels(micspk->audio_ctx, 1);
 	audio_set_playformat(micspk->audio_ctx, PA_SAMPLE_S16LE);
@@ -993,11 +1047,11 @@ static int initialize_micro(audiomicspkpulse_t* micspk)
 	audio_set_channels(micspk->audio_ctx, 1);
 	audio_set_capformat(micspk->audio_ctx, PA_SAMPLE_S16LE);
 
-	if (0 == audio_start_pulseaudio(micspk->audio_ctx)){
+	if (0 == audio_start_pulseaudio(micspk->audio_ctx)) {
 		audio_log_v(AUDIO_LOG_LEVEL_INFO, "audio micro create success, audio input device start pulse audio success!");
 		iret = 0;
 	}
-	else{
+	else {
 		audio_log_v(AUDIO_LOG_LEVEL_INFO, "audio micro create success, audio input device start pulse audio failed!");
 	}
 
@@ -1049,7 +1103,7 @@ void* APR_THREAD_FUNC* audiowork_proc(apr_thread_t* threadhandle, void* param)
 	// record and play <---> record and play
 	//
 	audio_log_v(AUDIO_LOG_LEVEL_INFO, "%s:%d micspk addr is 0x%0x, current sem addr is 0x%0x.started flag is %s.", __FUNCTION__, __LINE__, param, micspk->audio_device_started_sem, micspk->baudio_device_started_flag ? "true" : "false");
-	audio_log_v(AUDIO_LOG_LEVEL_INFO, "%s:%d  micspk->opt = %d.", __FUNCTION__, __LINE__, micspk->opt);
+	audio_log_v(AUDIO_LOG_LEVEL_INFO, "%s:%d micspk->opt = %d.", __FUNCTION__, __LINE__, micspk->opt);
 
 	if (micspk->opt & AMS_OPT_RECPLAY) {
 		rc = initialize_speaker(micspk);
@@ -1201,7 +1255,7 @@ apr_status_t audiomicspkpulse_create(apr_pool_t* pool,
 	apr_status_t err = apr_thread_create(&micspk->audio_work_thread, NULL, &audiowork_proc, micspk, pool);
 	if (APR_SUCCESS == err) {
 		bool baudio_work_thread_exit = false;
-		audio_log_v(AUDIO_LOG_LEVEL_INFO, "%s:%d audio_work_thread id is %d.", __FUNCTION__, __LINE__, micspk->audio_work_thread);
+		audio_log_v(AUDIO_LOG_LEVEL_INFO, "%s:%d audio_work_thread id is %u.", __FUNCTION__, __LINE__, micspk->audio_work_thread);
 
 		do {
 			struct timespec ts;
@@ -1239,9 +1293,9 @@ apr_status_t audiomicspkpulse_create(apr_pool_t* pool,
 
 	micspk->audio_ctx->micspkpulse_parent = (void*)micspk;
 	micspk->audio_ctx->bstart_put_flag = true;
+	micspk->audio_ctx->bstart_get_flag = true;
 	*p_micspk = micspk;
 
-
 	return APR_SUCCESS;
 }
 
@@ -1249,8 +1303,6 @@ apr_status_t audiomicspkpulse_create(apr_pool_t* pool,
 void audiomicspkpulse_destroy(audiomicspkpulse_t* micspk)
 {
 	assert(NULL != micspk);
-	/*destroy the mutex*/
-	pthread_mutex_destroy(&micspk->audio_ctx->mutex);
 
 	sem_post(micspk->audio_device_started_sem);
 	

+ 5 - 1
Other/libaudioframework/audiomicspkpulse.h

@@ -59,6 +59,8 @@ typedef struct audio_context_s
 {
 	void* micspkpulse_parent;
 	bool bstart_put_flag;
+	bool bstart_get_flag;
+
 	int num_input_dev;            /*number of audio input devices in list*/
 	audio_device_t* list_input_devices; /*audio input devices list*/
 
@@ -85,11 +87,13 @@ typedef struct audio_context_s
 	int64_t ts_drift;             /*drift between real and generated ts*/
 
 	int stream_flag;              /*stream flag*/
-	pthread_mutex_t mutex;        /*audio mutex*/
 
 	int play_stream_flag;              /*stream flag*/
 	pthread_t readthreadid;
 	pthread_t writethreadid;
+
+	char* paudio_buffer;
+	size_t uaudio_len;
 }audio_context_t;
 
 typedef struct audiomicspkpulse_s

+ 0 - 2
Other/libsharememory/CMakeLists.txt

@@ -14,8 +14,6 @@ target_include_directories(${MODULE_NAME} PRIVATE
 	${RVC_COMMON_INCLUDE_DIR}
 	)
 
-message(STATUS "conan rvcframework root include path is ${CONAN_RVCFRAMEWORK_ROOT}/include")
-
 target_compile_definitions(${MODULE_NAME} PUBLIC "LIBSHAREMEMORY_EXPORTS")
 
 if(MSVC)

+ 7 - 72
Other/libsharememory/libsharememory.cpp

@@ -4,7 +4,7 @@
 #include "stdafx.h"
 #include "libsharememory.h"
 #include <stdio.h>
-#include "SpBase.h"
+//#include "SpBase.h"
 
 
 //#define TESTSHAREMEM 0
@@ -18,7 +18,7 @@ void Debug(const char* fmt, ...)
 //#ifdef TESTSHAREMEM
 //	printf("%s\n", strfmt);
 //#else
-//	//Dbg("%s", strfmt);
+//	Dbg("%s", strfmt);
 //#endif
 //	va_end(args);
 //	fflush(stdout);
@@ -59,13 +59,11 @@ public:
 		memset(m_strshmname, 0, MAX_PATH);
 #endif // RVC_OS_WIN
 		m_dwBytes=0;
-		Debug("%s:%d", __FUNCTION__,__LINE__);
 	}
 
 	~libsharememory_impl()
 	{
 		CloseShareMem();
-		Debug("%s:%d", __FUNCTION__, __LINE__);
 	}
 
 
@@ -83,10 +81,10 @@ public:
 				sprintf_s(m_strsemname, MAX_PATH, "/mutex.%s", szName);
 				m_shid = shm_open(szName, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
 				if (m_shid >= 0) {
-					Debug("%s:%d shm_open O_CREAT|O_RDWR|O_EXCL success and share memory %s and size is %d", __FUNCTION__, __LINE__, szName, dwBytes);
+					//Debug("%s:%d shm_open O_CREAT|O_RDWR|O_EXCL success and share memory %s and size is %d", __FUNCTION__, __LINE__, szName, dwBytes);
 				}
 				else {
-					Debug("%s:%d shm_open O_CREAT|O_RDWR|O_EXCL %s failed for %s, and errno is %d", __FUNCTION__, __LINE__, m_strshmname, strerror(errno), errno);
+					//Debug("%s:%d shm_open O_CREAT|O_RDWR|O_EXCL %s failed for %s, and errno is %d", __FUNCTION__, __LINE__, m_strshmname, strerror(errno), errno);
 					if (EEXIST == errno) {
 						m_shid = shm_open(szName, O_RDWR, 0);
 					}
@@ -97,37 +95,26 @@ public:
 						ftruncate(m_shid, dwBytes);
 						m_pData = mmap(NULL, dwBytes, PROT_READ | PROT_WRITE, MAP_SHARED, m_shid, 0);
 						if (MAP_FAILED != m_pData) {
-							Debug("%s:%d %s mmap success, and m_pData = 0x%0x.", __FUNCTION__, __LINE__, szName, m_pData);
 							*((LPDWORD)m_pData) = dwBytes;
 							m_dwBytes = dwBytes;
 							sem_t* semt = sem_open(m_strsemname, O_CREAT | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, 1);
 							if (NULL == semt) {
-								Debug("%s:%d sem_open O_CREAT|O_EXCL %s failed for %s, and errno is %d", __FUNCTION__, __LINE__, m_strshmname, strerror(errno), errno);
 								if (EEXIST == errno) {
 									semt = sem_open(m_strsemname, 0);
 									sem_init(semt,32, 1);
 								}
 							}
-							else {
-								Debug("%s:%d sem_open sem %s O_CREAT|O_EXCL success.", __FUNCTION__, __LINE__, m_strsemname);
-							}
+
 
 							if (NULL != semt) {
 								m_semt = semt;
 								int ivalue = -1;
 								sem_getvalue(m_semt, &ivalue);
-								Debug("%s:%d sem %s value is %d.", __FUNCTION__, __LINE__, m_strsemname, ivalue);
 								bRet = true;
 							}
 						}
-						else {
-							Debug("%s:%d mmap failed!", __FUNCTION__, __LINE__);
-						}
 					}
 				}
-				else {
-					Debug("%s:%d shm_open %s failed for %s, and errno is %d", __FUNCTION__, __LINE__, m_strshmname, strerror(errno), errno);
-				}
 			}
 		}
 		return bRet;
@@ -137,7 +124,6 @@ public:
 	//创建共享内存区
 	bool CreateShareMem(const char* szName, unsigned int dwBytes)
 	{
-		Debug("%s:%s:%d", __FILE__, __FUNCTION__, __LINE__);
 		bool T =false;
 #ifdef RVC_OS_WIN
 		char szBuf[MAX_PATH];
@@ -175,43 +161,8 @@ public:
 			}
 		}
 #else
-		//if (szName != NULL && dwBytes > 0) {
-		//	char szBuf[MAX_PATH];
-		//	const char* szFile = tmpnam(szBuf);
-		//	if (szFile != NULL) {
-		//		sprintf_s(m_strshmname, MAX_PATH, "%s", szName);
-		//		m_shid = shm_open(szName, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
-		//		if (m_shid >= 0) {
-		//			Debug("%s:%d shm_open success and share memory %s and size is %d", __FUNCTION__, __LINE__, szName, dwBytes);
-		//			ftruncate(m_shid, dwBytes);
-		//			m_pData = mmap(NULL, dwBytes, PROT_READ | PROT_WRITE, MAP_SHARED, m_shid, 0);
-		//			if (MAP_FAILED != m_pData) {
-		//				Debug("%s:%d %s mmap success, and m_pData = 0x%0x.", __FUNCTION__, __LINE__, szName, m_pData);
-		//				*((LPDWORD)m_pData) = dwBytes;
-		//				m_dwBytes = dwBytes;
-		//				sprintf_s(m_strsemname, MAX_PATH, "/mutex.%s", szName);
-		//				sem_t* semt = sem_open(m_strsemname, O_CREAT | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, 1);
-		//				if (NULL != semt) {
-		//					m_semt = semt;
-		//					int ivalue = -1;
-		//					sem_getvalue(m_semt, &ivalue);
-		//					Debug("%s:%d sem_open sem %s O_CREAT|O_EXCL success, and sem value is %d.", __FUNCTION__, __LINE__, m_strsemname, ivalue);
-		//					T = true;
-		//				}
-		//				else {
-		//					Debug("%s:%d sem_open sem %s O_CREAT|O_EXCL failed, and errno is %d, error info is %s.", __FUNCTION__, __LINE__, m_strsemname, errno, strerror(errno));
-		//				}
-		//			}
-		//		}
-		//		else
-		//		{
-		//			Debug("%s:%d shm_open %s failed for %s", __FUNCTION__, __LINE__, m_strshmname, strerror(errno));
-		//		}
-		//	}
-		//}
 		T = CreateShareMemLinux(szName, dwBytes);
 #endif // RVC_OS_WIN
-		Debug("%s:%d and create share memory %s result is %d.", __FUNCTION__, __LINE__,szName, T);
 		return T;
 	}
 
@@ -255,16 +206,13 @@ public:
 			int shid = shm_open(szName, O_RDWR, 0);
 			if (-1 != shid) {
 				m_shid = shid;
-				Debug("%s:%d shm_open %s success.and shid is %d.", __FUNCTION__, __LINE__, szName, shid);
 				sem_t* semt = sem_open(m_strsemname, 0);
 				if (SEM_FAILED != semt){
 					m_semt = semt;
 					int ivalue = -1;
 					sem_getvalue(semt, &ivalue);
-					Debug("%s:%d sem_open %s success, and sem value is %d.", __FUNCTION__, __LINE__, m_strsemname, ivalue);
 					m_pData = mmap(NULL, m_dwBytes, PROT_READ | PROT_WRITE, MAP_SHARED, shid, 0);
 					if (MAP_FAILED != m_pData) {
-						Debug("%s:%d %s mmap success, and m_pData = 0x%0x.", __FUNCTION__, __LINE__, szName, m_pData);
 						if (LockShareMem()){
 							m_dwBytes = *((LPDWORD)m_pData);
 							UnlockShareMem();
@@ -275,12 +223,6 @@ public:
 						}
 					}
 				}
-				else {
-					Debug("%s:%d sem_open %s failed for %s", __FUNCTION__, __LINE__, m_strsemname, strerror(errno));
-				}
-			}
-			else {
-				Debug("%s:%d shm_open %s failed for %s", __FUNCTION__, __LINE__, szName, strerror(errno));
 			}
 			
 			if (!T){
@@ -365,7 +307,7 @@ public:
 			}
 		}
 #else
-		Debug("IsShareMemValid flag is %d, m_pData = 0x%0x, m_bLocked flag is %s.", IsShareMemValid(), m_pData, m_bLocked ? "true" : "false");
+		//Debug("IsShareMemValid flag is %d, m_pData = 0x%0x, m_bLocked flag is %s.", IsShareMemValid(), m_pData, m_bLocked ? "true" : "false");
 		if (IsShareMemValid() && m_pData != NULL && !m_bLocked)
 		{
 			struct timespec ts;
@@ -374,27 +316,20 @@ public:
 			ts.tv_sec += (unsec / 1000000000);
 			ts.tv_nsec = (unsec % 1000000000);
 
-			Debug("%s:%d ts.tv_sec = %d", __FUNCTION__, __LINE__, ts.tv_sec);
 			int ivalue = -1;
 			sem_getvalue(m_semt, &ivalue);
-			Debug("%s:%d sem_getvalue = %d", __FUNCTION__, __LINE__, ivalue);
 			if (0 == sem_timedwait(m_semt,&ts))
 			{
 				sem_getvalue(m_semt, &ivalue);
-				Debug("%s:%d set m_bLocked to true, sem_getvalue = %d", __FUNCTION__, __LINE__, ivalue);
 				m_bLocked = true;
 			}
-			else {
-				Debug("%s:%d sem_timedwait error for %s.", __FUNCTION__, __LINE__, strerror(errno));
-			}
+
 			if (m_bLocked)
 			{
-				Debug("%s:%d set pData value, and m_pData is 0x%0x", __FUNCTION__, __LINE__, m_pData);
 				pData = (void*)((LPDWORD)m_pData + 1);
 			}
 		}
 #endif // _WIN32
-		Debug("%s:%d result is pData == 0x%0x", __FUNCTION__, __LINE__, pData);
 		return pData;
 	}
 	//内存区是否互斥锁定

+ 24 - 16
Other/libvideocapture/libvideocapture.cpp

@@ -555,9 +555,6 @@ int VideoCaptureImpl::StartVideoCapture()
 		return -1;
 	}
 
-	if (false == GetCamBrightnessInfo()){
-		return -1;
-	}
 	// Supported video formats in preferred order.
 	// If the requested resolution is larger than VGA, we prefer MJPEG. Go for
 	// I420 otherwise.
@@ -611,6 +608,7 @@ int VideoCaptureImpl::StartVideoCapture()
 	struct v4l2_format video_fmt;
 	memset(&video_fmt, 0, sizeof(v4l2_format));
 	video_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	video_fmt.fmt.pix.field = V4L2_FIELD_ANY;
 	video_fmt.fmt.pix.width = mode_width[m_capture->param.cap_mode];
 	video_fmt.fmt.pix.height = mode_height[m_capture->param.cap_mode];
 	video_fmt.fmt.pix.pixelformat = fmts[fmtsIdx];
@@ -692,6 +690,10 @@ int VideoCaptureImpl::StartVideoCapture()
 		}
 	}
 
+	if (false == GetCamBrightnessInfo()) {
+		return -1;
+	}
+
 	if (!AllocateVideoBuffers()) {
 		m_callback->Debug("failed to allocate video capture buffers");
 		return -1;
@@ -832,12 +834,16 @@ bool VideoCaptureImpl::GetStopCaptureFlag()
 
 int VideoCaptureImpl::StopVideoCapture()
 {
-	if (m_bCaptureStarted)
-	{
+	if (m_bCaptureStarted){
 		m_bCaptureStarted = false;
 		m_bStopCapture = true;
 
-		pthread_cancel(m_CaptureThreadId);
+		if (0 == pthread_join(m_CaptureThreadId, NULL))		{
+			m_callback->Debug("thread join video capture thread success.");
+		}
+		else {
+			m_callback->Debug("thread join video capture thread failed for %s.", strerror(errno));
+		}
 
 		DeAllocateVideoBuffers();
 		close(m_deviceFd);
@@ -891,16 +897,18 @@ int VideoCaptureImpl::SetCamBrightness(int ibright)
 int VideoCaptureImpl::SetCamAutoBrightness()
 {
 	int iret = -1;
-	struct v4l2_control ctrl;
-	ctrl.id = V4L2_CID_BRIGHTNESS;
-	ctrl.value = m_idefaultbrightness;
-	if (ioctl(m_deviceFd, VIDIOC_S_CTRL, &ctrl) == -1) {
-		m_callback->Debug("VIDIOC_S_CTRL set V4L2_CID_AUTOBRIGHTNESS error for %s", strerror(errno));
-	}
-	else {
-		//m_callback->Debug("VIDIOC_S_CTRL set V4L2_CID_AUTOBRIGHTNESS success.");
-		iret = 0;
-	}
+
+	//struct v4l2_control ctrl;
+	//ctrl.id = V4L2_CID_BRIGHTNESS;
+	//ctrl.value = m_idefaultbrightness;
+	//if (ioctl(m_deviceFd, VIDIOC_S_CTRL, &ctrl) == -1) {
+	//	m_callback->Debug("VIDIOC_S_CTRL set V4L2_CID_AUTOBRIGHTNESS error for %s", strerror(errno));
+	//}
+	//else {
+	//	//m_callback->Debug("VIDIOC_S_CTRL set V4L2_CID_AUTOBRIGHTNESS success.");
+	//	iret = 0;
+	//}
+	iret = 0;
 
 	return iret;
 }