[asterisk-commits] dlee: branch dlee/playback-controls r389033 - in /team/dlee/playback-controls...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri May 17 17:14:51 CDT 2013


Author: dlee
Date: Fri May 17 17:14:47 2013
New Revision: 389033

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=389033
Log:
Controls work

Modified:
    team/dlee/playback-controls/include/asterisk/stasis_app_playback.h
    team/dlee/playback-controls/res/res_stasis_playback.c
    team/dlee/playback-controls/res/stasis_http/resource_playback.c
    team/dlee/playback-controls/rest-api/api-docs/playback.json

Modified: team/dlee/playback-controls/include/asterisk/stasis_app_playback.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/playback-controls/include/asterisk/stasis_app_playback.h?view=diff&rev=389033&r1=389032&r2=389033
==============================================================================
--- team/dlee/playback-controls/include/asterisk/stasis_app_playback.h (original)
+++ team/dlee/playback-controls/include/asterisk/stasis_app_playback.h Fri May 17 17:14:47 2013
@@ -39,18 +39,34 @@
 	STASIS_PLAYBACK_STATE_QUEUED,
 	/*! The media is currently playing */
 	STASIS_PLAYBACK_STATE_PLAYING,
+	/*! The media is currently playing */
+	STASIS_PLAYBACK_STATE_PAUSED,
 	/*! The media has stopped playing */
 	STASIS_PLAYBACK_STATE_COMPLETE,
-	/*! The media was cancelled before playback could start */
-	STASIS_PLAYBACK_STATE_CANCELLED,
+	/*! The playback was canceled. */
+	STASIS_PLAYBACK_STATE_CANCELED,
+	/*! The playback was stopped. */
+	STASIS_PLAYBACK_STATE_STOPPED,
+	/*! Enum end sentinel. */
+	STASIS_PLAYBACK_STATE_MAX,
 };
 
+/*! Valid operation for controlling a playback. */
 enum stasis_app_playback_media_operation {
+	/*! Stop the playback operation. */
 	STASIS_PLAYBACK_STOP,
+	/*! Restart the media from the beginning. */
+	STASIS_PLAYBACK_RESTART,
+	/*! Pause playback. */
 	STASIS_PLAYBACK_PAUSE,
-	STASIS_PLAYBACK_PLAY,
-	STASIS_PLAYBACK_REWIND,
-	STASIS_PLAYBACK_FAST_FORWARD,
+	/*! Resume paused playback. */
+	STASIS_PLAYBACK_UNPAUSE,
+	/*! Rewind playback. */
+	STASIS_PLAYBACK_REVERSE,
+	/*! Fast forward playback. */
+	STASIS_PLAYBACK_FORWARD,
+	/*! Enum end sentinel. */
+	STASIS_PLAYBACK_OPER_MAX,
 };
 
 /*!

Modified: team/dlee/playback-controls/res/res_stasis_playback.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/playback-controls/res/res_stasis_playback.c?view=diff&rev=389033&r1=389032&r2=389033
==============================================================================
--- team/dlee/playback-controls/res/res_stasis_playback.c (original)
+++ team/dlee/playback-controls/res/res_stasis_playback.c Fri May 17 17:14:47 2013
@@ -47,7 +47,7 @@
 #define PLAYBACK_BUCKETS 127
 
 /*! Number of milliseconds of media to skip */
-#define PLAYBACK_SKIPMS 250
+#define PLAYBACK_SKIPMS 3000
 
 #define SOUND_URI_SCHEME "sound:"
 #define RECORDING_URI_SCHEME "recording:"
@@ -153,7 +153,9 @@
 	ast_assert(playback != NULL);
 
 	ao2_lock(playback);
-	if (playback->state == STASIS_PLAYBACK_STATE_CANCELLED) {
+	if (playback->state == STASIS_PLAYBACK_STATE_CANCELED) {
+		ast_log(LOG_NOTICE, "%s: Playback cancelled for %s\n",
+			ast_channel_uniqueid(chan), playback->media);
 		ao2_unlock(playback);
 		return NULL;
 	}
@@ -180,8 +182,16 @@
 		restart, skipms, &offsetms);
 
 	if (res != 0) {
-		ast_log(LOG_WARNING, "%s: Playback failed for %s",
-			ast_channel_uniqueid(chan), playback->media);
+		enum stasis_app_playback_state state =
+			stasis_app_playback_get_state(playback);
+
+		if (state == STASIS_PLAYBACK_STATE_CANCELED) {
+			ast_log(LOG_NOTICE, "%s: Playback stopped for %s\n",
+				ast_channel_uniqueid(chan), playback->media);
+		} else {
+			ast_log(LOG_WARNING, "%s: Playback failed for %s\n",
+				ast_channel_uniqueid(chan), playback->media);
+		}
 	}
 
 	return NULL;
@@ -264,10 +274,17 @@
 	case STASIS_PLAYBACK_STATE_PLAYING:
 		state = "playing";
 		break;
+	case STASIS_PLAYBACK_STATE_PAUSED:
+		state = "paused";
+		break;
+	case STASIS_PLAYBACK_STATE_STOPPED:
 	case STASIS_PLAYBACK_STATE_COMPLETE:
-	case STASIS_PLAYBACK_STATE_CANCELLED:
-		/* Treat cancelled as complete */
-		state = "complete";
+	case STASIS_PLAYBACK_STATE_CANCELED:
+		/* It doesn't really matter how we got here, but all of these
+		 * states really just mean 'done' */
+		state = "done";
+		break;
+	case STASIS_PLAYBACK_STATE_MAX:
 		break;
 	}
 
@@ -280,65 +297,113 @@
 	return ast_json_ref(json);
 }
 
+typedef int (*playback_opreation_cb)(struct stasis_app_playback *playback);
+
+static int playback_noop(struct stasis_app_playback *playback)
+{
+	return 0;
+}
+
+static int playback_cancel(struct stasis_app_playback *playback)
+{
+	playback_set_state(playback, STASIS_PLAYBACK_STATE_CANCELED);
+	return 0;
+}
+
+static int playback_stop(struct stasis_app_playback *playback)
+{
+	playback_set_state(playback, STASIS_PLAYBACK_STATE_CANCELED);
+	return stasis_app_control_queue_control(playback->control,
+		AST_CONTROL_STREAM_STOP);
+}
+
+static int playback_restart(struct stasis_app_playback *playback)
+{
+	return stasis_app_control_queue_control(playback->control,
+		AST_CONTROL_STREAM_RESTART);
+}
+
+static int playback_pause(struct stasis_app_playback *playback)
+{
+	playback_set_state(playback, STASIS_PLAYBACK_STATE_PAUSED);
+	return stasis_app_control_queue_control(playback->control,
+		AST_CONTROL_STREAM_SUSPEND);
+}
+
+static int playback_unpause(struct stasis_app_playback *playback)
+{
+	playback_set_state(playback, STASIS_PLAYBACK_STATE_PLAYING);
+	return stasis_app_control_queue_control(playback->control,
+		AST_CONTROL_STREAM_SUSPEND);
+}
+
+static int playback_reverse(struct stasis_app_playback *playback)
+{
+	return stasis_app_control_queue_control(playback->control,
+		AST_CONTROL_STREAM_REVERSE);
+}
+
+static int playback_forward(struct stasis_app_playback *playback)
+{
+	return stasis_app_control_queue_control(playback->control,
+		AST_CONTROL_STREAM_FORWARD);
+}
+
+/*!
+ * \brief A sparse array detailing how commands should be handled in the
+ * various playback states. Unset entries imply invalid operations.
+ */
+playback_opreation_cb operations[STASIS_PLAYBACK_STATE_MAX][STASIS_PLAYBACK_OPER_MAX] = {
+	[STASIS_PLAYBACK_STATE_QUEUED][STASIS_PLAYBACK_STOP] = playback_cancel,
+	[STASIS_PLAYBACK_STATE_QUEUED][STASIS_PLAYBACK_RESTART] = playback_noop,
+
+	[STASIS_PLAYBACK_STATE_PLAYING][STASIS_PLAYBACK_STOP] = playback_stop,
+	[STASIS_PLAYBACK_STATE_PLAYING][STASIS_PLAYBACK_RESTART] = playback_restart,
+	[STASIS_PLAYBACK_STATE_PLAYING][STASIS_PLAYBACK_PAUSE] = playback_pause,
+	[STASIS_PLAYBACK_STATE_PLAYING][STASIS_PLAYBACK_UNPAUSE] = playback_noop,
+	[STASIS_PLAYBACK_STATE_PLAYING][STASIS_PLAYBACK_REVERSE] = playback_reverse,
+	[STASIS_PLAYBACK_STATE_PLAYING][STASIS_PLAYBACK_FORWARD] = playback_forward,
+
+	[STASIS_PLAYBACK_STATE_PAUSED][STASIS_PLAYBACK_STOP] = playback_stop,
+	[STASIS_PLAYBACK_STATE_PAUSED][STASIS_PLAYBACK_PAUSE] = playback_noop,
+	[STASIS_PLAYBACK_STATE_PAUSED][STASIS_PLAYBACK_UNPAUSE] = playback_unpause,
+
+	[STASIS_PLAYBACK_STATE_COMPLETE][STASIS_PLAYBACK_STOP] = playback_noop,
+	[STASIS_PLAYBACK_STATE_CANCELED][STASIS_PLAYBACK_STOP] = playback_noop,
+	[STASIS_PLAYBACK_STATE_STOPPED][STASIS_PLAYBACK_STOP] = playback_noop,
+};
+
 int stasis_app_playback_operation(struct stasis_app_playback *playback,
 	enum stasis_app_playback_media_operation operation)
 {
-	enum ast_control_frame_type frame_type = -1;
-	int res;
-
+	playback_opreation_cb cb;
 	SCOPED_AO2LOCK(lock, playback);
 
-	switch (playback->state) {
-	case STASIS_PLAYBACK_STATE_COMPLETE:
-	case STASIS_PLAYBACK_STATE_CANCELLED:
-		if (operation == STASIS_PLAYBACK_STOP) {
-			/* Already stopped. */
-			return 0;
+	ast_assert(playback->state >= 0 && playback->state < STASIS_PLAYBACK_STATE_MAX);
+
+	if (operation < 0 || operation >= STASIS_PLAYBACK_OPER_MAX) {
+		ast_log(LOG_ERROR, "Invalid playback operation %d\n", operation);
+		return -1;
+	}
+
+	cb = operations[playback->state][operation];
+
+	if (!cb) {
+		if (playback->state != STASIS_PLAYBACK_STATE_PLAYING) {
+			/* So we can be specific in our error message. */
+			return STASIS_PLAYBACK_OPER_NOT_PLAYING;
 		} else {
-			/* Invalid state for operation */
-			return STASIS_PLAYBACK_OPER_NOT_PLAYING;
+			/* And, really, all operations should be valid during
+			 * playback */
+			ast_log(LOG_ERROR,
+				"Unhandled operation during playback: %d\n",
+				operation);
+			return STASIS_PLAYBACK_OPER_FAILED;
 		}
-		break;
-	case STASIS_PLAYBACK_STATE_QUEUED:
-		if (operation == STASIS_PLAYBACK_STOP) {
-			/* Cancel a playback before it starts */
-			playback_set_state(playback,
-				STASIS_PLAYBACK_STATE_CANCELLED);
-		} else {
-			/* None of the other ops make sense for queued media */
-			return STASIS_PLAYBACK_OPER_NOT_PLAYING;
-		}
-		break;
-	case STASIS_PLAYBACK_STATE_PLAYING:
-		/* Media control makes sense. Carry on, then. */
-		break;
-	}
-
-	switch (operation) {
-	case STASIS_PLAYBACK_STOP:
-		frame_type = AST_CONTROL_STREAM_STOP;
-		break;
-	case STASIS_PLAYBACK_PAUSE:
-		frame_type = AST_CONTROL_STREAM_SUSPEND;
-		break;
-	case STASIS_PLAYBACK_PLAY:
-		frame_type = AST_CONTROL_STREAM_RESTART;
-		break;
-	case STASIS_PLAYBACK_REWIND:
-		frame_type = AST_CONTROL_STREAM_REVERSE;
-		break;
-	case STASIS_PLAYBACK_FAST_FORWARD:
-		frame_type = AST_CONTROL_STREAM_FORWARD;
-		break;
-	}
-
-	if (frame_type == -1) {
-		/* Invalid operation. Tsk, tsk. */
-		return STASIS_PLAYBACK_OPER_FAILED;
-	}
-
-	res = stasis_app_control_queue_control(playback->control, frame_type);
-	return res ? STASIS_PLAYBACK_OPER_FAILED : STASIS_PLAYBACK_OPER_OK;
+	}
+
+	return cb(playback) ?
+		STASIS_PLAYBACK_OPER_FAILED : STASIS_PLAYBACK_OPER_OK;
 }
 
 static int load_module(void)

Modified: team/dlee/playback-controls/res/stasis_http/resource_playback.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/playback-controls/res/stasis_http/resource_playback.c?view=diff&rev=389033&r1=389032&r2=389033
==============================================================================
--- team/dlee/playback-controls/res/stasis_http/resource_playback.c (original)
+++ team/dlee/playback-controls/res/stasis_http/resource_playback.c Fri May 17 17:14:47 2013
@@ -93,14 +93,16 @@
 	enum stasis_app_playback_media_operation oper;
 	enum stasis_playback_oper_results res;
 
-	if (strcmp(args->operation, "play") == 0) {
-		oper = STASIS_PLAYBACK_PLAY;
+	if (strcmp(args->operation, "unpause") == 0) {
+		oper = STASIS_PLAYBACK_UNPAUSE;
 	} else if (strcmp(args->operation, "pause") == 0) {
 		oper = STASIS_PLAYBACK_PAUSE;
-	} else if (strcmp(args->operation, "rewind") == 0) {
-		oper = STASIS_PLAYBACK_REWIND;
-	} else if (strcmp(args->operation, "fast-forward") == 0) {
-		oper = STASIS_PLAYBACK_FAST_FORWARD;
+	} else if (strcmp(args->operation, "restart") == 0) {
+		oper = STASIS_PLAYBACK_RESTART;
+	} else if (strcmp(args->operation, "reverse") == 0) {
+		oper = STASIS_PLAYBACK_REVERSE;
+	} else if (strcmp(args->operation, "forward") == 0) {
+		oper = STASIS_PLAYBACK_FORWARD;
 	} else {
 		stasis_http_response_error(response, 400,
 			"Bad Request", "Invalid operation %s",
@@ -128,8 +130,6 @@
 			args->operation);
 		return;
 	case STASIS_PLAYBACK_OPER_NOT_PLAYING:
-		/* Stop operation should be valid even when not playing */
-		ast_assert(0);
 		stasis_http_response_error(response, 409, "Conflict",
 			"Can only %s while media is playing", args->operation);
 		return;

Modified: team/dlee/playback-controls/rest-api/api-docs/playback.json
URL: http://svnview.digium.com/svn/asterisk/team/dlee/playback-controls/rest-api/api-docs/playback.json?view=diff&rev=389033&r1=389032&r2=389033
==============================================================================
--- team/dlee/playback-controls/rest-api/api-docs/playback.json (original)
+++ team/dlee/playback-controls/rest-api/api-docs/playback.json Fri May 17 17:14:47 2013
@@ -73,10 +73,11 @@
 							"allowableValues": {
 								"valueType": "LIST",
 								"values": [
-									"play",
+									"restart",
 									"pause",
-									"rewind",
-									"fast-forward"
+									"unpause",
+									"reverse",
+									"forward"
 								]
 							}
 						}




More information about the asterisk-commits mailing list