예제 #1
0
static int stream_echo_write(struct ast_channel *chan, struct ast_frame *frame,
	enum ast_media_type type, int one_to_one)
{
	int i;
	int num;
	struct ast_stream_topology *topology;

	/*
	 * Since this is an echo application if we get a frame in on a stream
	 * we simply want to echo it back out onto the same stream number.
	 */
	num = ast_channel_is_multistream(chan) ? frame->stream_num : -1;

	if (ast_write_stream(chan, num, frame)) {
		return stream_echo_write_error(chan, frame, num);
	}

	/*
	 * If the frame's type and given type don't match, or we are operating in
	 * a one to one stream echo mode then there is nothing left to do.
	 *
	 * Note, if the channel is not multi-stream capable then one_to_one will
	 * always be true, so it is safe to also not check for that here too.
	 */
	if (one_to_one || ast_format_get_type(frame->subclass.format) != type) {
		return 0;
	}

	/*
	 * However, if we are operating in a single stream echoed to many stream
	 * mode, and the frame's type matches the given type then we also need to
	 * find the other streams of the same type and write out to those streams
	 * as well.
	 *
	 * If we are here, then it's accepted that whatever stream number the frame
	 * was read from for the given type is the only one set to send/receive,
	 * while the others of the same type are set to receive only. Since we
	 * shouldn't assume any order to the streams, we'll loop back through all
	 * streams in the channel's topology writing only to those of the same type.
	 * And, of course also not the stream which has already been written to.
	 */
	topology = ast_channel_get_stream_topology(chan);

	for (i = 0; i < ast_stream_topology_get_count(topology); ++i) {
		struct ast_stream *stream = ast_stream_topology_get_stream(topology, i);

		if (num != i && ast_stream_get_type(stream) == type) {
			if (ast_write_stream(chan, i, frame)) {
				return stream_echo_write_error(chan, frame, i);
			}
		}
	}

	return 0;
}
예제 #2
0
void ast_ari_recordings_get_stored_file(struct ast_tcptls_session_instance *ser,
	struct ast_variable *headers, struct ast_ari_recordings_get_stored_file_args *args,
	struct ast_ari_response *response)
{
	RAII_VAR(struct stasis_app_stored_recording *, recording,
		stasis_app_stored_recording_find_by_name(args->recording_name),
		ao2_cleanup);
	static const char *format_type_names[AST_MEDIA_TYPE_TEXT + 1] = {
		[AST_MEDIA_TYPE_UNKNOWN] = "binary",
		[AST_MEDIA_TYPE_AUDIO] = "audio",
		[AST_MEDIA_TYPE_VIDEO] = "video",
		[AST_MEDIA_TYPE_IMAGE] = "image",
		[AST_MEDIA_TYPE_TEXT] = "text",
	};
	struct ast_format *format;

	response->message = ast_json_null();

	if (!recording) {
		ast_ari_response_error(response, 404, "Not Found",
			"Recording not found");
		return;
	}

	format = ast_get_format_for_file_ext(stasis_app_stored_recording_get_extension(recording));
	if (!format) {
		ast_ari_response_error(response, 500, "Internal Server Error",
			"Format specified by recording not available or loaded");
		return;
	}

	response->fd = open(stasis_app_stored_recording_get_filename(recording), O_RDONLY);
	if (response->fd < 0) {
		ast_ari_response_error(response, 403, "Forbidden",
			"Recording could not be opened");
		return;
	}

	ast_str_append(&response->headers, 0, "Content-Type: %s/%s\r\n",
		format_type_names[ast_format_get_type(format)],
		stasis_app_stored_recording_get_extension(recording));
	ast_ari_response_ok(response, ast_json_null());
}
예제 #3
0
static int stream_echo_write_error(struct ast_channel *chan, struct ast_frame *frame, int pos)
{
	char frame_type[32];
	const char *media_type;
	struct ast_stream *stream;

	ast_frame_type2str(frame->frametype, frame_type, sizeof(frame_type));

	stream = pos < 0 ?
		ast_channel_get_default_stream(chan, ast_format_get_type(frame->subclass.format)) :
		ast_stream_topology_get_stream(ast_channel_get_stream_topology(chan), pos);

	media_type = ast_codec_media_type2str(ast_stream_get_type(stream));

	ast_log(LOG_ERROR, "%s - unable to write frame type '%s' to stream type '%s' at "
		"position '%d'\n", ast_channel_name(chan), frame_type, media_type,
		ast_stream_get_position(stream));

	return -1;
}