Пример #1
0
// Audio encoding main process
int CAudioEncoder::ThreadMain(void) 
{
  CMsg* pMsg;
  bool stop = false;

  debug_message("audio encoder thread %s %s %s start", Profile()->GetName(),
		Profile()->GetStringValue(CFG_AUDIO_ENCODER), 
		Profile()->GetStringValue(CFG_AUDIO_ENCODING));

  while (stop == false && SDL_SemWait(m_myMsgQueueSemaphore) == 0) {
    pMsg = m_myMsgQueue.get_message();
    if (pMsg != NULL) {
      switch (pMsg->get_value()) {
      case MSG_NODE_STOP_THREAD:
	DoStopAudio();
	stop = true;
	break;
      case MSG_NODE_START:
	// DoStartTransmit();  Anything ?
	break;
      case MSG_NODE_STOP:
	DoStopAudio();
	break;
      case MSG_SINK_FRAME: {
	uint32_t dontcare;
	CMediaFrame *mf = (CMediaFrame*)pMsg->get_message(dontcare);
	if (m_stop_thread == false)
	  ProcessAudioFrame(mf);
	if (mf->RemoveReference()) {
	  delete mf;
	}
	break;
      }
      }
      
      delete pMsg;
    }
  }
  while ((pMsg = m_myMsgQueue.get_message()) != NULL) {
    if (pMsg->get_value() == MSG_SINK_FRAME) {
      uint32_t dontcare;
      CMediaFrame *mf = (CMediaFrame*)pMsg->get_message(dontcare);
      if (mf->RemoveReference()) {
	delete mf;
      }
    }
    delete pMsg;
  }

  if (m_audioResample != NULL) {
    for (uint ix = 0; ix < m_audioDstChannels; ix++) {
      st_resample_stop(m_audioResample[ix]);
      m_audioResample[ix] = NULL;
    }
    free(m_audioResample);
  }
  CHECK_AND_FREE(m_audioPreEncodingBuffer);
  debug_message("audio encoder thread %s exit", Profile()->GetName());
  return 0;
}
Пример #2
0
void COSSAudioSource::ProcessAudio(void)
{
#ifdef SNDCTL_DSP_GETERROR
  audio_errinfo errinfo;
  if (m_audioSrcFrameNumber == 0) {
    ioctl(m_audioDevice, SNDCTL_DSP_GETERROR, &errinfo);
  } else {
    ioctl(m_audioDevice, SNDCTL_DSP_GETERROR, &errinfo);
    if (errinfo.rec_overruns > 0) {
      debug_message("overrun error found in audio - adding "U64" samples",
		    SrcBytesToSamples(errinfo.rec_ptradjust));
      close(m_audioDevice);
      InitDevice();
      m_audioSrcSampleNumber = 0;
    }
  }
#endif

  if (m_audioSrcFrameNumber == 0) {
    // Pull the trigger and start the audio input
    int enablebits;
    ioctl(m_audioDevice, SNDCTL_DSP_GETTRIGGER, &enablebits);
    enablebits |= PCM_ENABLE_INPUT;
    ioctl(m_audioDevice, SNDCTL_DSP_SETTRIGGER, &enablebits);
  }

  // for efficiency, process 1 second before returning to check for commands
  for (int pass = 0; pass < m_maxPasses; pass++) {

    audio_buf_info info;
    int rc = ioctl(m_audioDevice, SNDCTL_DSP_GETISPACE, &info);
    Timestamp currentTime = GetTimestamp();

    if (rc<0) {
      error_message("Failed to query OSS GETISPACE");
      info.bytes = 0;
    }

    uint32_t bytesRead = read(m_audioDevice, m_pcmFrameBuffer, m_pcmFrameSize);
    if (bytesRead < m_pcmFrameSize) {
      debug_message("bad audio read");
      continue;
    }

    Timestamp timestamp;

    if (info.bytes == m_audioOssMaxBufferSize) {
      // means the audio buffer is full, and not capturing
      // we want to make the timestamp based on the previous one
      // When we hit this case, we start using the m_timestampOverflowArray
      // This will give us a timestamp for when the array is full.
      // 
      // In other words, if we have a full audio buffer (ie: it's not loading
      // any more), we start storing the current timestamp into the array.
      // This will let us "catch up", and have a somewhat accurate timestamp
      // when we loop around
      // 
      // wmay - I'm not convinced that this actually works - if the buffer
      // cleans up, we'll ignore m_timestampOverflowArray
      if (m_timestampOverflowArray != NULL && 
	  m_timestampOverflowArray[m_timestampOverflowArrayIndex] != 0) {
	timestamp = m_timestampOverflowArray[m_timestampOverflowArrayIndex];
      } else {
	timestamp = m_prevTimestamp + SrcSamplesToTicks(m_audioSrcSamplesPerFrame);
      }

      if (m_timestampOverflowArray != NULL)
	m_timestampOverflowArray[m_timestampOverflowArrayIndex] = currentTime;

      debug_message("audio buffer full !");

    } else {
      // buffer is not full - so, we make the timestamp based on the number
      // of bytes in the buffer that we read.
      timestamp = currentTime - SrcSamplesToTicks(SrcBytesToSamples(info.bytes));
      if (m_timestampOverflowArray != NULL)
	m_timestampOverflowArray[m_timestampOverflowArrayIndex] = 0;
    }

#ifdef DEBUG_TIMESTAMPS
    debug_message("info.bytes=%d t="U64" timestamp="U64" delta="U64,
                  info.bytes, currentTime, timestamp, timestamp - m_prevTimestamp);
#endif

    m_prevTimestamp = timestamp;
    if (m_timestampOverflowArray != NULL) {
      m_timestampOverflowArrayIndex = (m_timestampOverflowArrayIndex + 1) % 
	m_audioOssMaxBufferFrames;
    }

    ProcessAudioFrame(m_pcmFrameBuffer, m_pcmFrameSize, timestamp);

  }
}