audio_sdl.cpp
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:25k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2.  * The contents of this file are subject to the Mozilla Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/MPL/
  6.  * 
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  * 
  12.  * The Original Code is MPEG4IP.
  13.  * 
  14.  * The Initial Developer of the Original Code is Cisco Systems Inc.
  15.  * Portions created by Cisco Systems Inc. are
  16.  * Copyright (C) Cisco Systems Inc. 2000, 2001.  All Rights Reserved.
  17.  * 
  18.  * Contributor(s): 
  19.  *              Bill May        wmay@cisco.com
  20.  */
  21. /*
  22.  * audio.cpp provides an interface (CAudioSync) between the codec and
  23.  * the SDL audio APIs.
  24.  */
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #include "player_session.h"
  28. #include "audio_sdl.h"
  29. #include "player_util.h"
  30. #include <SDL_thread.h>
  31. //#define DEBUG_SYNC 1
  32. //#define DEBUG_AUDIO_FILL 1
  33. //#define DEBUG_DELAY 1
  34. #ifdef _WIN32
  35. DEFINE_MESSAGE_MACRO(audio_message, "audiosync")
  36. #else
  37. #define audio_message(loglevel, fmt...) message(loglevel, "audiosync", fmt)
  38. #endif
  39. /*
  40.  * c routine to call into the AudioSync class callback
  41.  */
  42. static void c_audio_callback (void *userdata, Uint8 *stream, int len)
  43. {
  44.   CSDLAudioSync *a = (CSDLAudioSync *)userdata;
  45.   a->audio_callback(stream, len);
  46. }
  47. /*
  48.  * Create an CSDLAudioSync for a session.  Don't alloc any buffers until
  49.  * config is called by codec
  50.  */
  51. CSDLAudioSync::CSDLAudioSync (CPlayerSession *psptr, int volume) :
  52.   CAudioSync(psptr)
  53. {
  54.   SDL_Init(SDL_INIT_AUDIO | SDL_INIT_NOPARACHUTE);
  55.   m_fill_index = m_play_index = 0;
  56.   for (int ix = 0; ix < DECODE_BUFFERS_MAX; ix++) {
  57.     m_buffer_filled[ix] = 0;
  58.     m_sample_buffer[ix] = NULL;
  59.   }
  60.   m_buffer_size = 0;
  61.   m_config_set = 0;
  62.   m_audio_initialized = 0;
  63.   m_audio_paused = 1;
  64.   m_resync_required = 1;
  65.   m_dont_fill = 0;
  66.   m_consec_no_buffers = 0;
  67.   //SDL_Init(SDL_INIT_AUDIO);
  68.   m_audio_waiting_buffer = 0;
  69.   m_audio_waiting = SDL_CreateSemaphore(0); //NULL; // will be set by decode thread
  70.   m_skipped_buffers = 0;
  71.   m_didnt_fill_buffers = 0;
  72.   m_play_time = 0         ;
  73.   m_buffer_latency = 0;
  74.   m_volume = (volume * SDL_MIX_MAXVOLUME)/100;
  75.   m_first_time = 1;
  76.   m_first_filled = 1;
  77.   m_buffer_offset_on = 0;
  78.   m_buffer_ts = 0;
  79.   m_load_audio_do_next_resync = 0;
  80. }
  81. /*
  82.  * Close out audio sync - stop and disconnect from SDL
  83.  */
  84. CSDLAudioSync::~CSDLAudioSync (void)
  85. {
  86.   SDL_PauseAudio(1);
  87.   SDL_CloseAudio();
  88.   for (int ix = 0; ix < DECODE_BUFFERS_MAX; ix++) {
  89.     if (m_sample_buffer[ix] != NULL)
  90.       free(m_sample_buffer[ix]);
  91.     m_sample_buffer[ix] = NULL;
  92.   }
  93.   audio_message(LOG_NOTICE, 
  94. "Audio sync skipped %u buffers", 
  95. m_skipped_buffers);
  96.   audio_message(LOG_NOTICE, "didn't fill %u buffers", m_didnt_fill_buffers);
  97. }
  98. /*
  99.  * codec api - set up information about the stream
  100.  */
  101. void CSDLAudioSync::set_config (int freq, 
  102.      int channels, 
  103.      int format, 
  104.      uint32_t sample_size) 
  105. {
  106.   if (m_config_set != 0) 
  107.     return;
  108.   
  109.   if (format == AUDIO_U8 || format == AUDIO_S8)
  110.     m_bytes_per_sample = 1;
  111.   else
  112.     m_bytes_per_sample = 2;
  113.   if (sample_size == 0) {
  114.     int temp;
  115.     temp = freq;
  116.     while ((temp & 0x1) == 0) temp >>= 1;
  117.     sample_size = temp;
  118.   } 
  119.   
  120.   m_buffer_size = channels * sample_size * m_bytes_per_sample;
  121.   for (int ix = 0; ix < DECODE_BUFFERS_MAX; ix++) {
  122.     m_buffer_filled[ix] = 0;
  123.     // I'm not sure where the 2 * comes in... Check this out
  124.     m_sample_buffer[ix] = 
  125.       (uint8_t *)malloc(2 * m_buffer_size);
  126.   }
  127.   m_freq = freq;
  128.   m_channels = channels;
  129.   m_format = format;
  130.   m_config_set = 1;
  131.   m_msec_per_frame = sample_size * 1000 / m_freq;
  132.   audio_message(LOG_DEBUG, "buffer size %d msec per frame %d", 
  133. m_buffer_size, m_msec_per_frame);
  134. };
  135. /*
  136.  * Codec api - get_audio_buffer - will wait if there are no available
  137.  * buffers
  138.  */
  139. uint8_t *CSDLAudioSync::get_audio_buffer (void)
  140. {
  141.   int ret;
  142.   int locked = 0;
  143.   if (m_dont_fill == 1) {
  144. #ifdef DEBUG_AUDIO_FILL
  145.     audio_message(LOG_DEBUG, "first dont fill");
  146. #endif
  147.     return (NULL);
  148.   }
  149.   if (m_audio_initialized != 0) {
  150.     locked = 1;
  151.     SDL_LockAudio();
  152.   }
  153.   ret = m_buffer_filled[m_fill_index];
  154.   if (locked)
  155.     SDL_UnlockAudio();
  156.   if (ret == 1) {
  157.     m_audio_waiting_buffer = 1;
  158.     SDL_SemWait(m_audio_waiting);
  159.     m_audio_waiting_buffer = 0;
  160.     if (m_dont_fill != 0) {
  161. #ifdef DEBUG_AUDIO_FILL
  162.       audio_message(LOG_DEBUG, "2nd don't fill");
  163. #endif
  164.       return (NULL);
  165.     }
  166.     locked = 0;
  167.     if (m_audio_initialized != 0) {
  168.       SDL_LockAudio();
  169.       locked = 1;
  170.     }
  171.     ret = m_buffer_filled[m_fill_index];
  172.     if (locked)
  173.       SDL_UnlockAudio();
  174.     if (ret == 1) {
  175. #ifdef DEBUG_AUDIO_FILL
  176.       audio_message(LOG_DEBUG, "no buff");
  177. #endif
  178.       return (NULL);
  179.     }
  180.   }
  181.   return (m_sample_buffer[m_fill_index]);
  182. }
  183. uint32_t CSDLAudioSync::load_audio_buffer (uint8_t *from, 
  184.    uint32_t bytes, 
  185.    uint64_t ts, 
  186.    int resync)
  187. {
  188.   uint8_t *to;
  189.   uint32_t copied;
  190.   int64_t diff, calc;
  191. #ifdef DEBUG_AUDIO_FILL
  192.   audio_message(LOG_DEBUG, "fill %d bytes at "LLU", offset %d", 
  193. bytes, ts, m_buffer_offset_on);
  194. #endif
  195.   copied = 0;
  196.   if (m_buffer_offset_on == 0) {
  197.     if (m_buffer_ts != 0 && m_buffer_ts != ts) {
  198.       m_load_audio_do_next_resync = 1;
  199.     }
  200.     m_buffer_ts = ts;
  201.   } else {
  202.     diff = ts - m_buffer_ts;
  203.     calc = m_buffer_offset_on * M_LLU;
  204.     calc /= m_bytes_per_sample;
  205.     calc /= m_freq;
  206.     if (diff > calc + 2) {
  207.       audio_message(LOG_DEBUG, "potential resync at ts "LLU" diff is "LLD" calc is "LLD, 
  208.     ts, diff, calc);
  209.       uint32_t left;
  210.       left = m_buffer_size - m_buffer_offset_on;
  211.       to = get_audio_buffer();
  212.       memset(to + m_buffer_offset_on, 0, left);
  213.       filled_audio_buffer(m_buffer_ts, 0);
  214.       m_buffer_offset_on = 0;
  215.       m_load_audio_do_next_resync = 1;
  216.       m_buffer_ts = ts;
  217.     }
  218.   }
  219.   while ( bytes > 0) {
  220.     to = get_audio_buffer();
  221.     if (to == NULL) {
  222.       return copied;
  223.     }
  224.     int copy;
  225.     uint32_t left;
  226.     left = m_buffer_size - m_buffer_offset_on;
  227.     copy = MIN(left, bytes);
  228.     memcpy(to + m_buffer_offset_on, 
  229.    from,
  230.    copy);
  231.     bytes -= copy;
  232.     copied += copy;
  233.     from += copy;
  234.     m_buffer_offset_on += copy;
  235.     if (m_buffer_offset_on >= m_buffer_size) {
  236.       m_buffer_offset_on = 0;
  237.       filled_audio_buffer(m_buffer_ts, resync | m_load_audio_do_next_resync);
  238.       m_buffer_ts += m_msec_per_frame;
  239.       resync = 0;
  240.       m_load_audio_do_next_resync = 0;
  241.     }
  242.   }
  243.   return (copied);
  244. }
  245.     
  246.   
  247. /*
  248.  * filled_audio_buffer - codec API - after codec fills the buffer from
  249.  * get_audio_buffer, it will call here.
  250.  */
  251. void CSDLAudioSync::filled_audio_buffer (uint64_t ts, int resync)
  252. {
  253.   uint32_t fill_index;
  254.   int locked;
  255.   // m_dont_fill will be set when we have a pause
  256.   if (m_dont_fill == 1) {
  257.     return;
  258.   }
  259.   fill_index = m_fill_index;
  260.   m_fill_index++;
  261.   m_fill_index %= DECODE_BUFFERS_MAX;
  262.   locked = 0;
  263.   if (m_audio_initialized != 0) {
  264.     SDL_LockAudio();
  265.     locked = 1;
  266.   }
  267.   if (m_first_filled != 0) {
  268.     m_first_filled = 0;
  269.   } else {
  270.     int64_t diff;
  271.     diff = ts - m_last_fill_timestamp;
  272.     if (diff - m_msec_per_frame > m_msec_per_frame) {
  273.       // have a hole here - don't want to resync
  274. #ifdef DEBUG_AUDIO_FILL
  275.       audio_message(LOG_DEBUG, 
  276.     "Filling - last %llu new %llu", m_last_fill_timestamp, ts);
  277. #endif
  278.       if (diff > ((m_msec_per_frame + 1) * 4)) {
  279. resync = 1;
  280.       } else {
  281. // try to fill the holes
  282. m_last_fill_timestamp += m_msec_per_frame + 1; // fill plus extra
  283. if (locked)
  284.   SDL_UnlockAudio();
  285. int64_t ts_diff;
  286. do {
  287.   uint8_t *retbuffer;
  288.   // Get and swap buffers.
  289.   retbuffer = get_audio_buffer();
  290.   if (retbuffer == NULL) {
  291.     return;
  292.   }
  293.   if (retbuffer != m_sample_buffer[m_fill_index]) {
  294.     audio_message(LOG_ERR, "retbuffer not fill index in audio sync");
  295.     return;
  296.   }
  297.   locked = 0;
  298.   if (m_audio_initialized != 0) {
  299.     SDL_LockAudio();
  300.     locked = 1;
  301.   }
  302.   m_sample_buffer[m_fill_index] = m_sample_buffer[fill_index];
  303.   m_sample_buffer[fill_index] = retbuffer;
  304.   memset(retbuffer, m_obtained.silence, m_buffer_size);
  305.   m_buffer_time[fill_index] = m_last_fill_timestamp;
  306.   m_buffer_filled[fill_index] = 1;
  307.   m_samples_loaded += m_buffer_size;
  308.   fill_index++;
  309.   fill_index %= DECODE_BUFFERS_MAX;
  310.   m_fill_index++;
  311.   m_fill_index %= DECODE_BUFFERS_MAX;
  312.   if (locked)
  313.     SDL_UnlockAudio();
  314.   audio_message(LOG_NOTICE, "Filling timestamp %llu with silence",
  315. m_last_fill_timestamp);
  316.   m_last_fill_timestamp += m_msec_per_frame + 1; // fill plus extra
  317.   ts_diff = ts - m_last_fill_timestamp;
  318.   audio_message(LOG_DEBUG, "diff is %lld", ts_diff);
  319. } while (ts_diff > 0);
  320. locked = 0;
  321. if (m_audio_initialized != 0) {
  322.   SDL_LockAudio();
  323.   locked = 1;
  324. }
  325.       }
  326.     } else {
  327.       if (m_last_fill_timestamp == ts) {
  328. audio_message(LOG_NOTICE, "Repeat timestamp with audio %llu", ts);
  329. if (locked)
  330.   SDL_UnlockAudio();
  331. return;
  332.       }
  333.     }
  334.   }
  335.   m_last_fill_timestamp = ts;
  336.   m_buffer_filled[fill_index] = 1;
  337.   m_samples_loaded += m_buffer_size;
  338.   m_buffer_time[fill_index] = ts;
  339.   if (resync) {
  340.     m_resync_required = 1;
  341.     m_resync_buffer = fill_index;
  342. #ifdef DEBUG_AUDIO_FILL
  343.     audio_message(LOG_DEBUG, "Resync from filled_audio_buffer");
  344. #endif
  345.   }
  346.   if (locked)
  347.     SDL_UnlockAudio();
  348.   // Check this - we might not want to do this unless we're resyncing
  349.   if (resync)
  350.     m_psptr->wake_sync_thread();
  351. #ifdef DEBUG_AUDIO_FILL
  352.   audio_message(LOG_DEBUG, "Filling " LLU " %u %u", 
  353. ts, fill_index, m_samples_loaded);
  354. #endif
  355. }
  356. void CSDLAudioSync::set_eof(void) 
  357.   uint8_t *to;
  358.   if (m_buffer_offset_on != 0) {
  359.     to = get_audio_buffer();
  360.     if (to != NULL) {
  361.       uint32_t left;
  362.       left = m_buffer_size - m_buffer_offset_on;
  363.       memset(to + m_buffer_offset_on, 0, left);
  364.       m_buffer_offset_on = 0;
  365.       filled_audio_buffer(m_buffer_ts, 0);
  366.       m_buffer_ts += m_msec_per_frame;
  367.     }
  368.   }
  369.   CAudioSync::set_eof();
  370. }
  371. // Sync task api - initialize the sucker.
  372. // May need to check out non-standard frequencies, see about conversion.
  373. // returns 0 for not yet, 1 for initialized, -1 for error
  374. int CSDLAudioSync::initialize_audio (int have_video) 
  375. {
  376.   if (m_audio_initialized == 0) {
  377.     if (m_config_set) {
  378.       SDL_AudioSpec wanted;
  379.       m_do_sync = have_video;
  380.       wanted.freq = m_freq;
  381.       wanted.channels = m_channels;
  382.       wanted.format = m_format;
  383.       int sample_size;
  384.       sample_size = m_buffer_size / (m_channels * m_bytes_per_sample);
  385. #ifndef _WINDOWS
  386.       uint32_t ix;
  387.       for (ix = 2; ix <= 0x8000; ix <<= 1) {
  388. if ((sample_size & ~(ix - 1)) == 0) {
  389.   break;
  390. }
  391.       }
  392.       ix >>= 1;
  393.       audio_message(LOG_DEBUG, "Sample size is %d", ix);
  394.       m_sample_size = ix;
  395. #else
  396.       m_sample_size = 4096;
  397. #endif
  398.       if ((m_do_sync == 0) && m_sample_size < 4096)
  399. m_sample_size = 4096;
  400.       wanted.samples = m_sample_size;
  401.       wanted.callback = c_audio_callback;
  402.       wanted.userdata = this;
  403. #if 1
  404.        audio_message(LOG_INFO, 
  405.      "requested f %d chan %d format %x samples %d",
  406.      wanted.freq,
  407.      wanted.channels,
  408.      wanted.format,
  409.      wanted.samples);
  410. #endif
  411.       int ret = SDL_OpenAudio(&wanted, &m_obtained);
  412.       if (ret < 0) {
  413. audio_message(LOG_CRIT, "Couldn't open audio, %s", SDL_GetError());
  414. return (-1);
  415.       }
  416. #if 1
  417.        audio_message(LOG_INFO, "got f %d chan %d format %x samples %d size %u",
  418.      m_obtained.freq,
  419.      m_obtained.channels,
  420.      m_obtained.format,
  421.      m_obtained.samples,
  422.      m_obtained.size);
  423. #endif
  424.       m_audio_initialized = 1;
  425.       m_use_SDL_delay = SDL_HasAudioDelayMsec();
  426.       if (m_use_SDL_delay)
  427. audio_message(LOG_NOTICE, "Using delay measurement from SDL");
  428.     } else {
  429.       return 0; // check again pretty soon...
  430.     }
  431.   }
  432.   return (1);
  433. }
  434. // This is used by the sync thread to determine if a valid amount of
  435. // buffers are ready, and what time they start.  It is used to determine
  436. // when we should start.
  437. int CSDLAudioSync::is_audio_ready (uint64_t &disptime)
  438. {
  439.   disptime = m_buffer_time[m_play_index];
  440.   return (m_dont_fill == 0 && m_buffer_filled[m_play_index] == 1);
  441. }
  442. // Used by the sync thread to see if resync is needed.
  443. // 0 - in sync.  > 0 - sync time we need. -1 - need to do sync 
  444. uint64_t CSDLAudioSync::check_audio_sync (uint64_t current_time, int &have_eof)
  445. {
  446.   if (get_eof() != 0) {
  447.     have_eof = m_audio_paused;
  448.     return (0);
  449.   }
  450.   // audio is initialized.
  451.   if (m_resync_required) {
  452.     if (m_audio_paused && m_buffer_filled[m_resync_buffer]) {
  453.       // Calculate the current time based on the latency
  454.       SDL_LockAudio();
  455.       if (m_use_SDL_delay) {
  456. current_time +=SDL_AudioDelayMsec();
  457.       } else {
  458. current_time += m_buffer_latency;
  459.       }
  460.       uint64_t cmptime;
  461.       int freed = 0;
  462.       // Compare with times in buffer - we may need to skip if we fell
  463.       // behind.
  464.       do {
  465. cmptime = m_buffer_time[m_resync_buffer];
  466. if (cmptime < current_time) {
  467. #ifdef DEBUG_SYNC
  468.   audio_message(LOG_INFO, "Passed time " LLU " " LLU " %u", 
  469.        cmptime, current_time, m_resync_buffer);
  470. #endif
  471.   m_buffer_filled[m_resync_buffer] = 0;
  472.   m_resync_buffer++;
  473.   m_resync_buffer %= DECODE_BUFFERS_MAX;
  474.   freed = 1;
  475. }
  476.       } while (m_buffer_filled[m_resync_buffer] == 1 && 
  477.        cmptime < current_time - 2);
  478.       SDL_UnlockAudio();
  479.       if (m_buffer_filled[m_resync_buffer] == 0) {
  480. cmptime = 0;
  481.       } else {
  482. if (cmptime >= current_time) {
  483.   m_play_index = m_resync_buffer;
  484.   play_audio();
  485. #if 1
  486.   audio_message(LOG_INFO, "Resynced audio at " LLU " %u %u", current_time, m_resync_buffer, m_play_index);
  487. #endif
  488.   cmptime = 0;
  489.       }
  490.       if (freed != 0 && m_audio_waiting_buffer) {
  491. m_audio_waiting_buffer = 0;
  492. SDL_SemPost(m_audio_waiting);
  493. // audio_message(LOG_DEBUG, "post free passed time");
  494.       }
  495.       return cmptime;
  496.     } else {
  497.       return (0);
  498.     }
  499.   }
  500.   return (0);
  501. }
  502. // Audio callback from SDL.
  503. void CSDLAudioSync::audio_callback (Uint8 *stream, int ilen)
  504. {
  505.   int freed_buffer = 0;
  506.   uint32_t len = (uint32_t)ilen;
  507.   uint64_t this_time;
  508.   int delay = 0;
  509.   if (m_resync_required) {
  510.     // resync required from codec side.  Shut down, and notify sync task
  511.     if (m_resync_buffer == m_play_index) {
  512.       SDL_PauseAudio(1);
  513.       m_audio_paused = 1;
  514.       m_psptr->wake_sync_thread();
  515. #ifdef DEBUG_SYNC
  516.       audio_message(LOG_DEBUG, "sempost");
  517. #endif
  518.       return;
  519.     }
  520.   }
  521.   m_play_time = m_psptr->get_current_time();
  522.   if (m_use_SDL_delay != 0) {
  523.     delay = SDL_AudioDelayMsec();
  524.     if (delay < 0) delay = 0;
  525. #ifdef DEBUG_DELAY
  526.     audio_message(LOG_DEBUG, "Audio delay is %d %llu", delay, m_play_time);
  527. #endif
  528.   }
  529.   if ((m_first_time == 0) &&
  530.       (m_use_SDL_delay == 0)) {
  531.     /*
  532.      * If we're not the first time, see if we're about a frame or more
  533.      * around the current time, with latency built in.  If not, skip
  534.      * the buffer.  This prevents us from playing past-due buffers.
  535.      */
  536.     int time_okay = 0;
  537.     this_time = 0;
  538.     while ((m_buffer_filled[m_play_index] == 1) &&
  539.    (time_okay == 0)) {
  540.       uint64_t buffertime, playtime;
  541.       buffertime = m_buffer_time[m_play_index];
  542.       if (m_play_sample_index != 0) {
  543. uint64_t temp;
  544. temp = (uint64_t) m_play_sample_index * (uint64_t)m_msec_per_frame;
  545. temp /= (uint64_t) m_buffer_size;
  546. buffertime += temp;
  547.       }
  548.       if (m_use_SDL_delay != 0) 
  549. playtime = m_play_time + delay; // m_buffer_latency;
  550.       else 
  551. playtime = m_play_time + m_buffer_latency;
  552.       if (m_play_time != 0 && buffertime + m_msec_per_frame < playtime) {
  553. audio_message(LOG_DEBUG, 
  554.       "Skipped audio buffer " LLU "("LLU") at " LLU, 
  555.       m_buffer_time[m_play_index],
  556.       buffertime,
  557.       playtime);
  558. m_buffer_filled[m_play_index] = 0;
  559. m_play_index++;
  560. m_play_index %= DECODE_BUFFERS_MAX;
  561. m_skipped_buffers++;
  562. m_buffer_latency = 0; // recalculate...
  563. m_first_time = 0;
  564. m_play_sample_index = 0;
  565. uint32_t diff;
  566. diff = m_buffer_size - m_play_sample_index;
  567. if (m_samples_loaded >= diff) {
  568.   m_samples_loaded -= diff;
  569. } else {
  570.   m_samples_loaded = 0;
  571. }
  572. m_consec_wrong_latency = 0;  // reset all latency calcs..
  573. m_wrong_latency_total = 0;
  574.       } else {
  575. time_okay = 1;
  576. this_time = buffertime;
  577.       }
  578.     }
  579.   } else {
  580.     this_time = m_buffer_time[m_play_index];
  581.     if (m_first_time == 0) {
  582.       if (m_play_sample_index != 0) {
  583. uint64_t temp;
  584. temp = (uint64_t) m_play_sample_index * (uint64_t)m_msec_per_frame;
  585. temp /= (uint64_t) m_buffer_size;
  586. this_time += temp;
  587.       }
  588.     }
  589.   }
  590.   // Do we have a buffer ?  If no, see if we need to stop.
  591.   if (m_samples_loaded == 0) {
  592.     if (get_eof()) {
  593.       SDL_PauseAudio(1);
  594.       m_audio_paused = 1;
  595.       m_psptr->wake_sync_thread();
  596.       return;
  597.     }
  598. #ifdef DEBUG_SYNC
  599.     audio_message(LOG_DEBUG, "No buffer in audio callback %u %u", 
  600.   m_samples_loaded, len);
  601. #endif
  602.     m_consec_no_buffers++;
  603.     if (m_consec_no_buffers > 10) {
  604.       SDL_PauseAudio(1);
  605.       m_audio_paused = 1;
  606.       m_resync_required = 1;
  607.       m_resync_buffer = m_play_index;
  608.       m_psptr->wake_sync_thread();
  609.     }
  610.     if (m_audio_waiting_buffer) {
  611.       m_audio_waiting_buffer = 0;
  612.       SDL_SemPost(m_audio_waiting);
  613.       //audio_message(LOG_DEBUG, "post no data");
  614.     }
  615.     audio_message(LOG_DEBUG, "return - no samples");
  616.     return;
  617.   }
  618.   // We have a valid buffer.  Push it to SDL.
  619.   m_consec_no_buffers = 0;
  620.   while (len > 0) {
  621.     uint32_t thislen;
  622.     thislen = m_buffer_size - m_play_sample_index;
  623.     if (len < thislen) thislen = len;
  624.     SDL_MixAudio(stream, 
  625.  (const unsigned char *)&m_sample_buffer[m_play_index][m_play_sample_index],
  626.  thislen,
  627.  m_volume);
  628.     len -= thislen;
  629.     stream += thislen;
  630.     if (thislen <= m_samples_loaded)
  631.       m_samples_loaded -= thislen;
  632.     else 
  633.       m_samples_loaded = 0;
  634.     m_play_sample_index += thislen;
  635.     if (m_play_sample_index >= m_buffer_size) {
  636. #ifdef DEBUG_SYNC
  637.       audio_message(LOG_DEBUG, "finished with buffer %d %d", 
  638.     m_play_index, m_samples_loaded);
  639. #endif
  640.       m_buffer_filled[m_play_index] = 0;
  641.       m_play_index++;
  642.       m_play_index %= DECODE_BUFFERS_MAX;
  643.       m_play_sample_index = 0;
  644.       freed_buffer = 1;
  645.     }
  646.   }
  647.       
  648.   // Increment past this buffer.
  649.   if (m_first_time != 0) {
  650.     // First time through - tell the sync task we've started, so it can
  651.     // keep sync time.
  652.     m_first_time = 0;
  653.     if (m_use_SDL_delay != 0) 
  654.       m_buffer_latency = delay;
  655.     else
  656.       m_buffer_latency = 0;
  657.     m_psptr->audio_is_ready(m_buffer_latency, this_time);
  658.     m_consec_wrong_latency = 0;
  659.     m_wrong_latency_total = 0;
  660.   } 
  661.   else if (m_do_sync) {
  662. #define ALLOWED_LATENCY 2
  663.     if (m_use_SDL_delay != 0) {
  664.       // Here, we're using the delay value from the audio buffers,
  665.       // rather than the calculated time...
  666.       // Okay - now we check for latency changes.
  667.       uint64_t index_time = delay + m_play_time;
  668.       if (this_time > index_time + ALLOWED_LATENCY || 
  669.   this_time < index_time - ALLOWED_LATENCY) {
  670. #if DEBUG_SYNC
  671. audio_message(LOG_DEBUG, 
  672.       "potential change - index time "LLU" time "LLU, 
  673.       index_time, this_time);
  674. #endif
  675. m_consec_wrong_latency++;
  676. m_wrong_latency_total += this_time - index_time;
  677. int64_t test;
  678. test = m_wrong_latency_total / m_consec_wrong_latency;
  679. if (test > ALLOWED_LATENCY || test < -ALLOWED_LATENCY) {
  680.   if (m_consec_wrong_latency > 3) {
  681.     m_consec_wrong_latency = 0;
  682.     m_wrong_latency_total = 0;
  683.     m_psptr->adjust_start_time(test);
  684.   }
  685. } else {
  686.   // average wrong latency is not greater than allowed latency
  687.   m_consec_wrong_latency = 0;
  688.   m_wrong_latency_total = 0;
  689. }
  690.       } else {
  691. m_consec_wrong_latency = 0;
  692. m_wrong_latency_total = 0;
  693.       }
  694.     } else {
  695.       // We're using the calculate latency values - they're not very
  696.       // accurate, but better than nothing...
  697.       // we have a latency number - see if it really is correct
  698.       uint64_t index_time = delay + m_play_time;
  699. #if DEBUG_SYNC
  700.       audio_message(LOG_DEBUG, 
  701.     "latency - time " LLU " index " LLU " latency " LLU " %u", 
  702.     this_time, index_time, m_buffer_latency, m_samples_loaded);
  703. #endif
  704.       if (this_time > index_time + ALLOWED_LATENCY || 
  705.   this_time < index_time - ALLOWED_LATENCY) {
  706. m_consec_wrong_latency++;
  707. m_wrong_latency_total += this_time - index_time;
  708. int64_t test;
  709. test = m_wrong_latency_total / m_consec_wrong_latency;
  710. if (test > ALLOWED_LATENCY || test < -ALLOWED_LATENCY) {
  711.   if (m_consec_wrong_latency > 20) {
  712.     m_consec_wrong_latency = 0;
  713.     if (test < 0 && test + m_buffer_latency > 0) {
  714.       m_buffer_latency = 0;
  715.     } else {
  716.       m_buffer_latency += test; 
  717.     }
  718.     m_psptr->audio_is_ready(m_buffer_latency, this_time);
  719.     audio_message(LOG_INFO, "Latency off by " LLD " - now is " LLU, 
  720.  test, m_buffer_latency);
  721.   }
  722. } else {
  723.   // average wrong latency is not greater 5 or less -5
  724.   m_consec_wrong_latency = 0;
  725.   m_wrong_latency_total = 0;
  726. }
  727.       } else {
  728. m_consec_wrong_latency = 0;
  729. m_wrong_latency_total = 0;
  730.       }
  731.     }
  732.   } else {
  733. #ifdef DEBUG_SYNC
  734.     audio_message(LOG_DEBUG, "playing %llu %llu latency %llu", 
  735.   this_time, m_play_time, m_buffer_latency);
  736. #endif
  737.   }
  738.   // If we had the decoder task waiting, signal it.
  739.   if (freed_buffer != 0 && m_audio_waiting_buffer) {
  740.     m_audio_waiting_buffer = 0;
  741.     SDL_SemPost(m_audio_waiting);
  742.     //audio_message(LOG_DEBUG, "post freed");
  743.   }
  744. }
  745. void CSDLAudioSync::play_audio (void)
  746. {
  747.   m_first_time = 1;
  748.   m_resync_required = 0;
  749.   m_audio_paused = 0;
  750.   m_play_sample_index = 0;
  751.   SDL_PauseAudio(0);
  752. }
  753. // Called from the sync thread when we want to stop.  Pause the audio,
  754. // and indicate that we're not to fill any more buffers - this should let
  755. // the decode thread get back to receive the pause message.  Only called
  756. // when pausing - could cause m_dont_fill race conditions if called on play
  757. void CSDLAudioSync::flush_sync_buffers (void)
  758. {
  759.   // we don't need to signal the decode task right now - 
  760.   // Go ahead 
  761.   clear_eof();
  762.   SDL_PauseAudio(1);
  763.   m_dont_fill = 1;
  764.   if (m_audio_waiting_buffer) {
  765.     m_audio_waiting_buffer = 0;
  766.     SDL_SemPost(m_audio_waiting);
  767.     //audio_message(LOG_DEBUG, "post flush sync");
  768.     
  769.   }
  770.   //  player_debug_message("Flushed sync");
  771. }
  772. // this is called from the decode thread.  It gets called on entry into pause,
  773. // and entry into play.  This way, m_dont_fill race conditions are resolved.
  774. void CSDLAudioSync::flush_decode_buffers (void)
  775. {
  776.   int locked = 0;
  777.   if (m_audio_initialized != 0) {
  778.     locked = 1;
  779.     SDL_LockAudio();
  780.   }
  781.   m_dont_fill = 0;
  782.   m_first_filled = 1;
  783.   for (int ix = 0; ix < DECODE_BUFFERS_MAX; ix++) {
  784.     m_buffer_filled[ix] = 0;
  785.   }
  786.   m_buffer_offset_on = 0;
  787.   m_play_index = m_fill_index = 0;
  788.   m_audio_paused = 1;
  789.   m_resync_buffer = 0;
  790.   m_samples_loaded = 0;
  791.   if (locked)
  792.     SDL_UnlockAudio();
  793.   //player_debug_message("flushed decode");
  794. }
  795. void CSDLAudioSync::set_volume (int volume)
  796. {
  797.   m_volume = (volume * SDL_MIX_MAXVOLUME)/100;
  798. }
  799. static void c_audio_config (void *ifptr, int freq, 
  800.     int chans, int format, uint32_t max_buffer_size)
  801. {
  802.   ((CSDLAudioSync *)ifptr)->set_config(freq,
  803.     chans,
  804.     format,
  805.     max_buffer_size);
  806. }
  807. static uint8_t *c_get_audio_buffer (void *ifptr)
  808. {
  809.   return ((CSDLAudioSync *)ifptr)->get_audio_buffer();
  810. }
  811. static void c_filled_audio_buffer (void *ifptr,
  812.    uint64_t ts,
  813.    int resync_req)
  814. {
  815.   ((CSDLAudioSync *)ifptr)->filled_audio_buffer(ts, 
  816.      resync_req);
  817. }
  818. static uint32_t c_load_audio_buffer (void *ifptr, 
  819.      uint8_t *from, 
  820.      uint32_t bytes, 
  821.      uint64_t ts, 
  822.      int resync)
  823. {
  824.   return ((CSDLAudioSync *)ifptr)->load_audio_buffer(from,
  825.   bytes,
  826.   ts, 
  827.   resync);
  828. }
  829.   
  830. static audio_vft_t audio_vft = {
  831.   message,
  832.   c_audio_config,
  833.   c_get_audio_buffer,
  834.   c_filled_audio_buffer,
  835.   c_load_audio_buffer
  836. };
  837. CAudioSync *create_audio_sync (CPlayerSession *psptr, int volume)
  838. {
  839.   return new CSDLAudioSync(psptr, volume);
  840. }
  841. audio_vft_t *get_audio_vft (void)
  842. {
  843.   return &audio_vft;
  844. }
  845. int do_we_have_audio (void) 
  846. {
  847.   char buffer[80];
  848.   if (SDL_Init(SDL_INIT_AUDIO | SDL_INIT_NOPARACHUTE) < 0) {
  849.     return (0);
  850.   } 
  851.   if (SDL_AudioDriverName(buffer, sizeof(buffer)) == NULL) {
  852.     return (0);
  853.   }
  854.   return (1);
  855. }
  856. /* end audio.cpp */