void openal_stream_update(audio_stream *stream) { openal_stream *local = stream_get_userdata(stream); // See if we have any empty buffers to fill int val; alGetSourcei(local->source, AL_BUFFERS_PROCESSED, &val); if(val <= 0) { return; } // Handle buffer filling and loading char buf[AUDIO_BUFFER_SIZE]; ALuint n; while(val--) { // Fill buffer & re-queue int ret = source_update(stream->src, buf, AUDIO_BUFFER_SIZE); if(ret > 0) { alSourceUnqueueBuffers(local->source, 1, &n); alBufferData(n, local->format, buf, ret, source_get_frequency(stream->src)); alSourceQueueBuffers(local->source, 1, &n); // Check for any errors int err = alGetError(); if(err != AL_NO_ERROR) { PERROR("OpenAL Stream: Error %d while buffering!", err); } } else { stream_set_finished(stream); break; } } // Make sure we are playing stream if(stream_get_status(stream) == STREAM_STATUS_PLAYING) { ALenum state; alGetSourcei(local->source, AL_SOURCE_STATE, &state); if(state != AL_PLAYING) { alSourcePlay(local->source); } } }
static void commit_planes_for_stream(struct dc *dc, struct dc_surface_update *srf_updates, int surface_count, struct dc_stream_state *stream, struct dc_stream_update *stream_update, enum surface_update_type update_type, struct dc_state *context) { int i, j; if (update_type == UPDATE_TYPE_FULL) { dc->hwss.set_bandwidth(dc, context, false); context_clock_trace(dc, context); } if (update_type > UPDATE_TYPE_FAST) { for (j = 0; j < dc->res_pool->pipe_count; j++) { struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe_ctx); } } if (surface_count == 0) { /* * In case of turning off screen, no need to program front end a second time. * just return after program front end. */ dc->hwss.apply_ctx_for_surface(dc, stream, surface_count, context); return; } /* Lock pipes for provided surfaces, or all active if full update*/ for (i = 0; i < surface_count; i++) { struct dc_plane_state *plane_state = srf_updates[i].surface; for (j = 0; j < dc->res_pool->pipe_count; j++) { struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; if (update_type != UPDATE_TYPE_FULL && pipe_ctx->plane_state != plane_state) continue; if (!pipe_ctx->plane_state || pipe_ctx->top_pipe) continue; dc->hwss.pipe_control_lock( dc, pipe_ctx, true); } if (update_type == UPDATE_TYPE_FULL) break; } /* Full fe update*/ for (j = 0; j < dc->res_pool->pipe_count; j++) { struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; if (update_type != UPDATE_TYPE_FULL || !pipe_ctx->plane_state) continue; if (!pipe_ctx->top_pipe && pipe_ctx->stream) { struct dc_stream_status *stream_status = stream_get_status(context, pipe_ctx->stream); dc->hwss.apply_ctx_for_surface( dc, pipe_ctx->stream, stream_status->plane_count, context); } } if (update_type > UPDATE_TYPE_FAST) context_timing_trace(dc, &context->res_ctx); /* Perform requested Updates */ for (i = 0; i < surface_count; i++) { struct dc_plane_state *plane_state = srf_updates[i].surface; if (update_type == UPDATE_TYPE_MED) dc->hwss.apply_ctx_for_surface( dc, stream, surface_count, context); for (j = 0; j < dc->res_pool->pipe_count; j++) { struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; if (pipe_ctx->plane_state != plane_state) continue; if (srf_updates[i].flip_addr) dc->hwss.update_plane_addr(dc, pipe_ctx); if (update_type == UPDATE_TYPE_FAST) continue; /* work around to program degamma regs for split pipe after set mode. */ if (srf_updates[i].in_transfer_func || (pipe_ctx->top_pipe && pipe_ctx->top_pipe->plane_state == pipe_ctx->plane_state)) dc->hwss.set_input_transfer_func( pipe_ctx, pipe_ctx->plane_state); if (stream_update != NULL && stream_update->out_transfer_func != NULL) { dc->hwss.set_output_transfer_func( pipe_ctx, pipe_ctx->stream); } if (srf_updates[i].hdr_static_metadata) { resource_build_info_frame(pipe_ctx); dc->hwss.update_info_frame(pipe_ctx); } } } /* Unlock pipes */ for (i = dc->res_pool->pipe_count - 1; i >= 0; i--) { struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; for (j = 0; j < surface_count; j++) { if (update_type != UPDATE_TYPE_FULL && srf_updates[j].surface != pipe_ctx->plane_state) continue; if (!pipe_ctx->plane_state || pipe_ctx->top_pipe) continue; dc->hwss.pipe_control_lock( dc, pipe_ctx, false); break; } } }