void aout_PacketPlay (audio_output_t *aout, block_t *block) { aout_packet_t *p = aout_packet (aout); mtime_t time_report; vlc_mutex_lock (&p->lock); aout_FifoPush (&p->partial, block); while ((block = aout_OutputSlice (aout)) != NULL) aout_FifoPush (&p->fifo, block); time_report = p->time_report; p->time_report = VLC_TS_INVALID; vlc_mutex_unlock (&p->lock); if (time_report != VLC_TS_INVALID) aout_TimeReport (aout, mdate () - time_report); }
static void Play(audio_output_t *aout, block_t *block) { aout_sys_t *sys = aout->sys; HRESULT hr; Enter(); if (likely(sys->clock != NULL)) { UINT64 pos, qpcpos; IAudioClock_GetPosition(sys->clock, &pos, &qpcpos); qpcpos = (qpcpos + 5) / 10; /* 100ns -> 1µs */ /* NOTE: this assumes mdate() uses QPC() (which it currently does). */ aout_TimeReport(aout, qpcpos); } for (;;) { UINT32 frames; hr = IAudioClient_GetCurrentPadding(sys->client, &frames); if (FAILED(hr)) { msg_Err(aout, "cannot get current padding (error 0x%lx)", hr); break; } assert(frames <= sys->frames); frames = sys->frames - frames; if (frames > block->i_nb_samples) frames = block->i_nb_samples; BYTE *dst; hr = IAudioRenderClient_GetBuffer(sys->render, frames, &dst); if (FAILED(hr)) { msg_Err(aout, "cannot get buffer (error 0x%lx)", hr); break; } const size_t copy = frames * (size_t)aout->format.i_bytes_per_frame; memcpy(dst, block->p_buffer, copy); hr = IAudioRenderClient_ReleaseBuffer(sys->render, frames, 0); if (FAILED(hr)) { msg_Err(aout, "cannot release buffer (error 0x%lx)", hr); break; } IAudioClient_Start(sys->client); block->p_buffer += copy; block->i_buffer -= copy; block->i_nb_samples -= frames; if (block->i_nb_samples == 0) break; /* done */ /* Out of buffer space, sleep */ msleep(AOUT_MIN_PREPARE_TIME + block->i_nb_samples * CLOCK_FREQ / aout->format.i_rate); } Leave(); block_Release(block); }