static ssize_t rs_write(void *data, const void *buf, size_t size) { rsd_t *rsd = (rsd_t*)data; if (rsd->has_error) return -1; if (rsd->nonblock) { size_t avail, write_amt; rsd_callback_lock(rsd->rd); avail = fifo_write_avail(rsd->buffer); write_amt = avail > size ? size : avail; fifo_write(rsd->buffer, buf, write_amt); rsd_callback_unlock(rsd->rd); return write_amt; } else { size_t written = 0; while (written < size && !rsd->has_error) { size_t avail; rsd_callback_lock(rsd->rd); avail = fifo_write_avail(rsd->buffer); if (avail == 0) { rsd_callback_unlock(rsd->rd); if (!rsd->has_error) { slock_lock(rsd->cond_lock); scond_wait(rsd->cond, rsd->cond_lock); slock_unlock(rsd->cond_lock); } } else { size_t write_amt = size - written > avail ? avail : size - written; fifo_write(rsd->buffer, (const char*)buf + written, write_amt); rsd_callback_unlock(rsd->rd); written += write_amt; } } return written; } }
static ssize_t alsa_thread_write(void *data, const void *buf, size_t size) { alsa_thread_t *alsa = (alsa_thread_t*)data; if (alsa->thread_dead) return -1; if (alsa->nonblock) { size_t avail; size_t write_amt; slock_lock(alsa->fifo_lock); avail = fifo_write_avail(alsa->buffer); write_amt = MIN(avail, size); fifo_write(alsa->buffer, buf, write_amt); slock_unlock(alsa->fifo_lock); return write_amt; } else { size_t written = 0; while (written < size && !alsa->thread_dead) { size_t avail; slock_lock(alsa->fifo_lock); avail = fifo_write_avail(alsa->buffer); if (avail == 0) { slock_unlock(alsa->fifo_lock); slock_lock(alsa->cond_lock); if (!alsa->thread_dead) scond_wait(alsa->cond, alsa->cond_lock); slock_unlock(alsa->cond_lock); } else { size_t write_amt = MIN(size - written, avail); fifo_write(alsa->buffer, (const char*)buf + written, write_amt); slock_unlock(alsa->fifo_lock); written += write_amt; } } return written; } }
bool ffemu_push_audio(ffemu_t *handle, const struct ffemu_audio_data *data) { for (;;) { slock_lock(handle->lock); unsigned avail = fifo_write_avail(handle->audio_fifo); slock_unlock(handle->lock); if (!handle->alive) return false; if (avail >= data->frames * handle->params.channels * sizeof(int16_t)) break; slock_lock(handle->cond_lock); if (handle->can_sleep) { handle->can_sleep = false; scond_wait(handle->cond, handle->cond_lock); handle->can_sleep = true; } else scond_signal(handle->cond); slock_unlock(handle->cond_lock); } slock_lock(handle->lock); fifo_write(handle->audio_fifo, data->data, data->frames * handle->params.channels * sizeof(int16_t)); slock_unlock(handle->lock); scond_signal(handle->cond); return true; }
static ssize_t dsound_write(void *data, const void *buf_, size_t size) { size_t written = 0; dsound_t *ds = (dsound_t*)data; const uint8_t *buf = (const uint8_t*)buf_; if (!ds->thread_alive) return -1; while (size > 0) { size_t avail; EnterCriticalSection(&ds->crit); avail = fifo_write_avail(ds->buffer); if (avail > size) avail = size; fifo_write(ds->buffer, buf, avail); LeaveCriticalSection(&ds->crit); buf += avail; size -= avail; written += avail; if (ds->nonblock || !ds->thread_alive) break; if (avail == 0) WaitForSingleObject(ds->event, INFINITE); } return written; }
static size_t coreaudio_write_avail(void *data) { coreaudio_t *dev = (coreaudio_t*)data; pthread_mutex_lock(&dev->lock); size_t avail = fifo_write_avail(dev->buffer); pthread_mutex_unlock(&dev->lock); return avail; }
static size_t dsound_write_avail(void *data) { dsound_t *ds = (dsound_t*)data; EnterCriticalSection(&ds->crit); size_t avail = fifo_write_avail(ds->buffer); LeaveCriticalSection(&ds->crit); return avail; }
static uint32_t audioport_write_avail(cell_audio_handle_t handle) { audioport_t *port = handle; sys_lwmutex_lock(&port->lock, SYS_NO_TIMEOUT); uint32_t ret = fifo_write_avail(port->buffer); sys_lwmutex_unlock(&port->lock); return ret / sizeof(int16_t); }
static ssize_t ps3_audio_write(void *data, const void *buf, size_t size) { ps3_audio_t *aud = data; if (aud->nonblocking) { if (fifo_write_avail(aud->buffer) < size) return 0; } while (fifo_write_avail(aud->buffer) < size) sys_lwcond_wait(&aud->cond, 0); sys_lwmutex_lock(&aud->lock, SYS_NO_TIMEOUT); fifo_write(aud->buffer, buf, size); sys_lwmutex_unlock(&aud->lock); return size; }
static ssize_t sdl_audio_write(void *data, const void *buf, size_t size) { sdl_audio_t *sdl = (sdl_audio_t*)data; ssize_t ret = 0; if (sdl->nonblock) { SDL_LockAudio(); size_t avail = fifo_write_avail(sdl->buffer); size_t write_amt = avail > size ? size : avail; fifo_write(sdl->buffer, buf, write_amt); SDL_UnlockAudio(); ret = write_amt; } else { size_t written = 0; while (written < size) { SDL_LockAudio(); size_t avail = fifo_write_avail(sdl->buffer); if (avail == 0) { SDL_UnlockAudio(); slock_lock(sdl->lock); scond_wait(sdl->cond, sdl->lock); slock_unlock(sdl->lock); } else { size_t write_amt = size - written > avail ? avail : size - written; fifo_write(sdl->buffer, (const char*)buf + written, write_amt); SDL_UnlockAudio(); written += write_amt; } } ret = written; } return ret; }
static size_t alsa_write_avail(void *data) { alsa_t *alsa = (alsa_t*)data; if (alsa->thread_dead) return 0; slock_lock(alsa->fifo_lock); size_t val = fifo_write_avail(alsa->buffer); slock_unlock(alsa->fifo_lock); return val; }
bool ffemu_push_video(ffemu_t *handle, const struct ffemu_video_data *data) { unsigned y; bool drop_frame = handle->video.frame_drop_count++ % handle->video.frame_drop_ratio; handle->video.frame_drop_count %= handle->video.frame_drop_ratio; if (drop_frame) return true; for (;;) { slock_lock(handle->lock); unsigned avail = fifo_write_avail(handle->attr_fifo); slock_unlock(handle->lock); if (!handle->alive) return false; if (avail >= sizeof(*data)) break; slock_lock(handle->cond_lock); if (handle->can_sleep) { handle->can_sleep = false; scond_wait(handle->cond, handle->cond_lock); handle->can_sleep = true; } else scond_signal(handle->cond); slock_unlock(handle->cond_lock); } slock_lock(handle->lock); // Tightly pack our frame to conserve memory. libretro tends to use a very large pitch. struct ffemu_video_data attr_data = *data; if (attr_data.is_dupe) attr_data.width = attr_data.height = attr_data.pitch = 0; else attr_data.pitch = attr_data.width * handle->video.pix_size; fifo_write(handle->attr_fifo, &attr_data, sizeof(attr_data)); int offset = 0; for (y = 0; y < attr_data.height; y++, offset += data->pitch) fifo_write(handle->video_fifo, (const uint8_t*)data->data + offset, attr_data.pitch); slock_unlock(handle->lock); scond_signal(handle->cond); return true; }
static size_t coreaudio_write_avail(void *data) { size_t avail; coreaudio_t *dev = (coreaudio_t*)data; slock_lock(dev->lock); avail = fifo_write_avail(dev->buffer); slock_unlock(dev->lock); return avail; }
static size_t rs_write_avail(void *data) { rsd_t *rsd = (rsd_t*)data; if (rsd->has_error) return 0; rsd_callback_lock(rsd->rd); size_t val = fifo_write_avail(rsd->buffer); rsd_callback_unlock(rsd->rd); return val; }
static ssize_t coreaudio_write(void *data, const void *buf_, size_t size) { coreaudio_t *dev = (coreaudio_t*)data; const uint8_t *buf = (const uint8_t*)buf_; size_t written = 0; #ifdef IOS struct timeval time; gettimeofday(&time, 0); struct timespec timeout; memset(&timeout, 0, sizeof(timeout)); timeout.tv_sec = time.tv_sec + 3; timeout.tv_nsec = time.tv_usec * 1000; #endif while (!g_interrupted && size > 0) { pthread_mutex_lock(&dev->lock); size_t write_avail = fifo_write_avail(dev->buffer); if (write_avail > size) write_avail = size; fifo_write(dev->buffer, buf, write_avail); buf += write_avail; written += write_avail; size -= write_avail; if (dev->nonblock) { pthread_mutex_unlock(&dev->lock); break; } #ifdef IOS if (write_avail == 0 && pthread_cond_timedwait(&dev->cond, &dev->lock, &timeout) == ETIMEDOUT) g_interrupted = true; #else if (write_avail == 0) pthread_cond_wait(&dev->cond, &dev->lock); #endif pthread_mutex_unlock(&dev->lock); } return written; }
static bool ffmpeg_push_audio(void *data, const struct ffemu_audio_data *audio_data) { ffmpeg_t *handle = (ffmpeg_t*)data; if (!handle || !audio_data) return false; if (!handle->config.audio_enable) return true; for (;;) { unsigned avail; slock_lock(handle->lock); avail = fifo_write_avail(handle->audio_fifo); slock_unlock(handle->lock); if (!handle->alive) return false; if (avail >= audio_data->frames * handle->params.channels * sizeof(int16_t)) break; slock_lock(handle->cond_lock); if (handle->can_sleep) { handle->can_sleep = false; scond_wait(handle->cond, handle->cond_lock); handle->can_sleep = true; } else scond_signal(handle->cond); slock_unlock(handle->cond_lock); } slock_lock(handle->lock); fifo_write(handle->audio_fifo, audio_data->data, audio_data->frames * handle->params.channels * sizeof(int16_t)); slock_unlock(handle->lock); scond_signal(handle->cond); return true; }
static ssize_t coreaudio_write(void *data, const void *buf_, size_t size, bool is_perfcnt_enable) { coreaudio_t *dev = (coreaudio_t*)data; const uint8_t *buf = (const uint8_t*)buf_; size_t written = 0; while (!g_interrupted && size > 0) { size_t write_avail; slock_lock(dev->lock); write_avail = fifo_write_avail(dev->buffer); if (write_avail > size) write_avail = size; fifo_write(dev->buffer, buf, write_avail); buf += write_avail; written += write_avail; size -= write_avail; if (dev->nonblock) { slock_unlock(dev->lock); break; } #if TARGET_OS_IPHONE if (write_avail == 0 && !scond_wait_timeout( dev->cond, dev->lock, 3000000)) g_interrupted = true; #else if (write_avail == 0) scond_wait(dev->cond, dev->lock); #endif slock_unlock(dev->lock); } return written; }
static void libusb_hid_device_send_control(void *data, uint8_t* data_buf, size_t size) { struct libusb_adapter *adapter = (struct libusb_adapter*)data; if (!adapter) return; slock_lock(adapter->send_control_lock); if (fifo_write_avail(adapter->send_control_buffer) >= size + sizeof(size)) { fifo_write(adapter->send_control_buffer, &size, sizeof(size)); fifo_write(adapter->send_control_buffer, data_buf, size); } else { RARCH_WARN("adapter write buffer is full, cannot write send control\n"); } slock_unlock(adapter->send_control_lock); }
static int32_t audioport_write(cell_audio_handle_t handle, const int16_t *data, uint32_t samples) { int32_t ret = samples; uint32_t bytes = samples * sizeof(int16_t); audioport_t *port = handle; while (bytes) { sys_lwmutex_lock(&port->lock, SYS_NO_TIMEOUT); uint32_t avail = fifo_write_avail(port->buffer); sys_lwmutex_unlock(&port->lock); uint32_t to_write = avail < bytes ? avail : bytes; if (to_write) { sys_lwmutex_lock(&port->lock, SYS_NO_TIMEOUT); fifo_write(port->buffer, data, to_write); sys_lwmutex_unlock(&port->lock); bytes -= to_write; data += to_write >> 1; } else sys_lwcond_wait(&port->cond, 0); }