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

📄 audio_sdl_old.cpp

📁 完整的RTP RTSP代码库
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	  fill_index++;	  fill_index %= DECODE_BUFFERS_MAX;	  m_fill_index++;	  m_fill_index %= DECODE_BUFFERS_MAX;	  if (locked)	    Our_SDL_UnlockAudio();	  audio_message(LOG_NOTICE, "Filling timestamp "U64" with silence",			m_last_fill_timestamp);	  m_last_fill_timestamp += m_msec_per_frame + 1; // fill plus extra	  ts_diff = ts - m_last_fill_timestamp;	  audio_message(LOG_DEBUG, "diff is "D64, ts_diff);	} while (ts_diff > 0);	locked = 0;	if (m_audio_initialized != 0) {	  Our_SDL_LockAudio();	  locked = 1;	}      }    } else {      if (m_last_fill_timestamp == ts) {	audio_message(LOG_NOTICE, "Repeat timestamp with audio "U64, ts);	if (locked)	  Our_SDL_UnlockAudio();	return;      }    }  }  m_last_fill_timestamp = ts;  m_buffer_filled[fill_index] = 1;  m_buffer_bytes_loaded += m_buffer_size;  m_buffer_time[fill_index] = ts;  if (resync) {    m_resync_required = 1;    m_resync_buffer = fill_index;#ifdef DEBUG_AUDIO_FILL    audio_message(LOG_DEBUG, "Resync from filled_audio_buffer");#endif  }  if (locked)    Our_SDL_UnlockAudio();  // Check this - we might not want to do this unless we're resyncing  if (resync)    m_psptr->wake_sync_thread();#ifdef DEBUG_AUDIO_FILL  audio_message(LOG_DEBUG, "Filling " U64 " %u %u", 		ts, fill_index, m_buffer_bytes_loaded);#endif}void CSDLAudioSync::set_eof(void) {   uint8_t *to;  if (m_buffer_offset_on != 0) {    to = get_audio_buffer();    if (to != NULL) {      uint32_t left;      left = m_buffer_size - m_buffer_offset_on;      memset(to + m_buffer_offset_on, 0, left);      m_buffer_offset_on = 0;      filled_audio_buffer(m_buffer_ts, 0);      m_buffer_ts += m_msec_per_frame;    }  }  CAudioSync::set_eof();}// Sync task api - initialize the sucker.// May need to check out non-standard frequencies, see about conversion.// returns 0 for not yet, 1 for initialized, -1 for errorint CSDLAudioSync::initialize_audio (int have_video) {  if (m_audio_initialized == 0) {    if (m_config_set) {      SDL_AudioSpec wanted;      m_do_sync = have_video;      memset(&wanted, 0, sizeof(wanted));      wanted.freq = m_freq;      wanted.channels = m_channels;      switch (m_format) {      case AUDIO_FMT_U8: wanted.format = AUDIO_U8; break;      case AUDIO_FMT_S8: wanted.format = AUDIO_S8; break;      case AUDIO_FMT_U16LSB: wanted.format = AUDIO_U16LSB; break;      case AUDIO_FMT_U16MSB: wanted.format = AUDIO_U16MSB; break;      case AUDIO_FMT_S16LSB: wanted.format = AUDIO_S16LSB; break;      case AUDIO_FMT_S16MSB: wanted.format = AUDIO_S16MSB; break;      case AUDIO_FMT_U16: wanted.format = AUDIO_U16SYS; break;      case AUDIO_FMT_S16: wanted.format = AUDIO_S16SYS; break;      case AUDIO_FMT_FLOAT: wanted.format = AUDIO_S16SYS; break;      case AUDIO_FMT_HW_AC3: wanted.format = AUDIO_FORMAT_HW_AC3; break;      }      int sample_size;      sample_size = m_buffer_size / (m_channels * m_bytes_per_sample_input);#ifndef _WIN32      uint32_t ix;      for (ix = 2; ix <= 0x8000; ix <<= 1) {	if ((sample_size & ~(ix - 1)) == 0) {	  break;	}      }      ix >>= 1;      audio_message(LOG_DEBUG, "Sample size is %d", ix);      m_sample_size = ix;#else      m_sample_size = 4096;#endif      if ((m_do_sync == 0) && m_sample_size < 4096)	m_sample_size = 4096;      if (config.get_config_value(CONFIG_LIMIT_AUDIO_SDL_BUFFER) > 0 &&	  m_sample_size > 4096) 	m_sample_size = 4096;      wanted.samples = m_sample_size;      wanted.callback = c_audio_callback;      wanted.userdata = this;#if 1       audio_message(LOG_INFO, 		     "requested f %d chan %d format %x samples %d",		     wanted.freq,		     wanted.channels,		     wanted.format,		     wanted.samples);#endif      int ret = Our_SDL_OpenAudio(&wanted, &m_obtained);      if (ret < 0) {	if (wanted.channels > 2) {	  wanted.channels = 2;	  ret = Our_SDL_OpenAudio(&wanted, &m_obtained);	}	if (ret < 0) {	  audio_message(LOG_CRIT, "Couldn't open audio, %s", SDL_GetError());	  return (-1);	}      }#if 1      char buffer[128];      if (Our_SDL_AudioDriverName(buffer, sizeof(buffer)) == NULL) {	strcpy(buffer, "no audio driver");      }      audio_message(LOG_INFO, "got f %d chan %d format %x samples %d size %u %s",		     m_obtained.freq,		     m_obtained.channels,		     m_obtained.format,		     m_obtained.samples,		     m_obtained.size,		    buffer);#endif#ifdef TEST_MONO_TO_STEREO#define CHECK_SDL_CHANS_RETURNED  TRUE#define OBTAINED_CHANS  2#else#define CHECK_SDL_CHANS_RETURNED m_obtained.channels != m_channels#define OBTAINED_CHANS  m_obtained.channels#endif      bool need_convert = false;      if (CHECK_SDL_CHANS_RETURNED) {	Our_SDL_CloseAudio();	wanted.channels = OBTAINED_CHANS;	wanted.format = AUDIO_S16SYS; // we're converting, so always choose	m_bytes_per_sample_output = 2;	ret = Our_SDL_OpenAudio(&wanted, &m_obtained);	audio_message(LOG_INFO, 		      "requested f %d chan %d format %x samples %d",		      wanted.freq,		      wanted.channels,		      wanted.format,		      wanted.samples);	if (ret < 0) {	  audio_message(LOG_CRIT, "Couldn't reopen audio, %s", SDL_GetError());	  return (-1);	}	audio_message(LOG_INFO, "got f %d chan %d format %x samples %d size %u %s",		      m_obtained.freq,		      m_obtained.channels,		      m_obtained.format,		      m_obtained.samples,		      m_obtained.size,		    buffer);	need_convert = true;      }      m_got_channels = m_obtained.channels;      if (m_format == AUDIO_FMT_FLOAT || need_convert) {	audio_message(LOG_DEBUG, "convert buffer size is %d", m_obtained.size);	audio_convert_init(m_obtained.size, m_obtained.samples);      }      m_audio_initialized = 1;      m_use_SDL_delay = Our_SDL_HasAudioDelayMsec();      if (m_use_SDL_delay)	audio_message(LOG_NOTICE, "Using delay measurement from SDL");    } else {      return 0; // check again pretty soon...    }  }  return (1);}// This is used by the sync thread to determine if a valid amount of// buffers are ready, and what time they start.  It is used to determine// when we should start.int CSDLAudioSync::is_audio_ready (uint64_t &disptime){  disptime = m_buffer_time[m_play_index];  return (m_dont_fill == 0 && m_buffer_filled[m_play_index] == 1);}// Used by the sync thread to see if resync is needed.// 0 - in sync.  > 0 - sync time we need. -1 - need to do sync uint64_t CSDLAudioSync::check_audio_sync (uint64_t current_time, int &have_eof){  if (get_eof() != 0) {    have_eof = m_audio_paused;    return (0);  }  // audio is initialized.  if (m_resync_required) {    if (m_audio_paused && m_buffer_filled[m_resync_buffer]) {      // Calculate the current time based on the latency      Our_SDL_LockAudio();      if (m_use_SDL_delay) {	current_time += Our_SDL_AudioDelayMsec();      } else {	current_time += m_buffer_latency;      }      uint64_t cmptime;      int freed = 0;      // Compare with times in buffer - we may need to skip if we fell      // behind.      do {	cmptime = m_buffer_time[m_resync_buffer];	if (cmptime < current_time) {#ifdef DEBUG_SYNC	  audio_message(LOG_INFO, "Passed time " U64 " " U64 " %u", 			       cmptime, current_time, m_resync_buffer);#endif	  m_buffer_filled[m_resync_buffer] = 0;	  m_resync_buffer++;	  m_resync_buffer %= DECODE_BUFFERS_MAX;	  freed = 1;	}      } while (m_buffer_filled[m_resync_buffer] == 1 && 	       cmptime < current_time - 2);      Our_SDL_UnlockAudio();      if (m_buffer_filled[m_resync_buffer] == 0) {	cmptime = 0;      } else {	if (cmptime >= current_time) {	  m_play_index = m_resync_buffer;	  m_resync_required = 0;	  play_audio();#ifdef DEBUG_SYNC	  audio_message(LOG_INFO, "Resynced audio at " U64 " %u %u", current_time, m_resync_buffer, m_play_index);#endif	  cmptime = 0;	}       }      if (freed != 0 && m_audio_waiting_buffer) {	m_audio_waiting_buffer = 0;	SDL_SemPost(m_audio_waiting);	//	audio_message(LOG_DEBUG, "post free passed time");      }      return cmptime;    } else {      return (0);    }  }  return (0);}// Audio callback from SDL.void CSDLAudioSync::audio_callback (Uint8 *outStream, int ilen){  int freed_buffer = 0;  uint32_t outBufferTotalBytes = (uint32_t)ilen;  uint64_t this_time;  int delay = 0;  uint64_t index_time;  if (m_resync_required) {    // resync required from codec side.  Shut down, and notify sync task    if (m_resync_buffer == m_play_index) {      Our_SDL_PauseAudio(1);      m_audio_paused = 1;      m_psptr->wake_sync_thread();#ifdef DEBUG_SYNC      audio_message(LOG_DEBUG, "sempost");#endif      return;    }  }  m_play_time = m_psptr->get_current_time();  if (m_use_SDL_delay != 0) {    delay = Our_SDL_AudioDelayMsec();    if (delay < 0) delay = 0;#ifdef DEBUG_DELAY    audio_message(LOG_DEBUG, "Audio delay is %d "U64, delay, m_play_time);#endif  }  if ((m_first_time == 0) &&      (m_use_SDL_delay == 0)) {    /*     * If we're not the first time, see if we're about a frame or more     * around the current time, with latency built in.  If not, skip     * the buffer.  This prevents us from playing past-due buffers.     */    int time_okay = 0;    this_time = 0;    while ((m_buffer_filled[m_play_index] == 1) &&	   (time_okay == 0)) {      uint64_t buffertime, playtime;      buffertime = m_buffer_time[m_play_index];      if (m_play_sample_index != 0) {	uint64_t temp;	temp = (uint64_t) m_play_sample_index * (uint64_t)m_msec_per_frame;	temp /= (uint64_t) m_buffer_size;	buffertime += temp;      }      if (m_use_SDL_delay != 0) 	playtime = m_play_time + delay; // m_buffer_latency;      else 	playtime = m_play_time + m_buffer_latency;      if (m_play_time != 0 && buffertime + m_msec_per_frame < playtime) {	audio_message(LOG_DEBUG, 		      "Skipped audio buffer " U64 "("U64") at " U64, 		      m_buffer_time[m_play_index],		      buffertime,		      playtime);	m_buffer_filled[m_play_index] = 0;	m_play_index++;	m_play_index %= DECODE_BUFFERS_MAX;	m_skipped_buffers++;	m_buffer_latency = 0; // recalculate...	m_first_time = 0;	m_play_sample_index = 0;	uint32_t diff;	diff = m_buffer_size - m_play_sample_index;	if (m_buffer_bytes_loaded >= diff) {	  m_buffer_bytes_loaded -= diff;	} else {		  m_buffer_bytes_loaded = 0;	}	m_consec_wrong_latency = 0;  // reset all latency calcs..	m_wrong_latency_total = 0;      } else {	time_okay = 1;	this_time = buffertime;      }    }  } else {    uint64_t temp = 0;    this_time = m_buffer_time[m_play_index];    if ((m_first_time == 0) && (m_play_sample_index != 0)) {      temp = (uint64_t) m_play_sample_index * (uint64_t)m_msec_per_frame;      temp /= (uint64_t) m_buffer_size;      this_time += temp;    }#if 0    audio_message(LOG_DEBUG, "time "U64" "U64, m_buffer_time[m_play_index],		  temp);#endif  }  // Do we have a buffer ?  If no, see if we need to stop.  if (m_buffer_bytes_loaded == 0) {    if (get_eof()) {      Our_SDL_PauseAudio(1);      m_audio_paused = 1;

⌨️ 快捷键说明

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