Esempio n. 1
0
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);
        }
    }
}
Esempio n. 2
0
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;
		}
	}
}