Changeset 2296 for pjproject/trunk


Ignore:
Timestamp:
Sep 19, 2008 1:28:40 PM (16 years ago)
Author:
nanang
Message:

More ticket #633: Fixed DirectSound? implementation to avoid playback buffer read & write cursor race.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/src/pjmedia/dsound.c

    r2288 r2296  
    2626#if PJMEDIA_SOUND_IMPLEMENTATION == PJMEDIA_SOUND_WIN32_DIRECT_SOUND 
    2727 
     28#define PJ_MIN(x, y)    ((x < y) ? (x) : (y)) 
     29 
    2830#ifdef _MSC_VER 
    2931#   pragma warning(push, 3) 
     
    150152    DSBPOSITIONNOTIFY dsPosNotify[MAX_PACKET_BUFFER_COUNT]; 
    151153    unsigned bytes_per_frame; 
     154    unsigned max_latency; 
    152155    unsigned i; 
    153156 
     
    239242    ds_strm->dwDsBufferSize = buffer_count * bytes_per_frame; 
    240243    ds_strm->timestamp.u64 = 0; 
    241     ds_strm->latency = buffer_count * samples_per_frame * 1000 / clock_rate /  
    242                        channel_count; 
     244    /* 
     245     * Play latency does not need to be on a frame boundry, it is just how far 
     246     * ahead of the read pointer we set the write pointer.  So we should just 
     247     * use the user configured latency.  However, if the latency measured in 
     248     * bytes causes more buffers than we are allowed, we must cap the latency 
     249     * at the time contained in 1-buffer_count. 
     250     */ 
     251    max_latency = (1 - buffer_count) * samples_per_frame * 1000 / clock_rate / 
     252        channel_count; 
     253    ds_strm->latency = PJ_MIN(max_latency, snd_output_latency); 
    243254 
    244255    /* Done setting up play device. */ 
     
    346357    ds_strm->timestamp.u64 = 0; 
    347358    ds_strm->dwDsBufferSize = buffer_count * bytes_per_frame; 
     359    /* 
     360     * Capture latency must always be on a frame boundry, 
     361     * so compute it based off the calculated buffer_count. 
     362     */ 
    348363    ds_strm->latency = buffer_count * samples_per_frame * 1000 / clock_rate /  
    349364                       channel_count; 
     
    812827        buffer_count = clock_rate * snd_output_latency / samples_per_frame / 
    813828                       1000; 
     829        /* There must always be one more buffer than required for the latency */ 
     830        buffer_count += 1; 
    814831        if (buffer_count < MIN_PACKET_BUFFER_COUNT) 
    815832            buffer_count = MIN_PACKET_BUFFER_COUNT; 
     
    959976            return PJ_RETURN_OS_ERROR(hr); 
    960977         
    961         stream->play_strm.dwBytePos = 0; 
     978        /* Set the write pointer ahead of the read pointer by latency bytes */ 
     979        stream->play_strm.dwBytePos = BYTES_PER_SAMPLE * stream->clock_rate * 
     980                stream->channel_count * stream->play_strm.latency / 1000; 
    962981 
    963982        hr = IDirectSoundBuffer_Play(stream->play_strm.ds.play.lpDsBuffer,  
Note: See TracChangeset for help on using the changeset viewer.