Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for step events #68

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions gst_client/gst_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,9 @@ static GstdClientCmd cmds[] = {
{"event_seek", gstd_client_cmd_socket,
"Perform a seek in the given pipeline",
"event_seek <pipe> <rate=1.0> <format=3> <flags=1> <start-type=1> <start=0> <end-type=1> <end=-1>"},
{"event_step", gstd_client_cmd_socket,
"Perform a step event in the given pipeline",
"event_step <pipe> <format=4> <amount=1> <rate=1.0> <flush=1> <intermediate=0>"},
{"event_flush_start", gstd_client_cmd_socket,
"Put the pipeline in flushing mode",
"event_flush_start <pipe>"},
Expand Down
89 changes: 88 additions & 1 deletion gstd/gstd_event_factory.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@
#define GSTD_EVENT_FACTORY_SEEK_STOP_TYPE_DEFAULT GST_SEEK_TYPE_SET
#define GSTD_EVENT_FACTORY_SEEK_STOP_DEFAULT GST_CLOCK_TIME_NONE
#define GSTD_EVENT_FACTORY_FLUSH_STOP_RESET_DEFAULT TRUE
#define GSTD_EVENT_FACTORY_STEP_FORMAT_DEFAULT GST_FORMAT_BUFFERS
#define GSTD_EVENT_FACTORY_STEP_AMOUNT_DEFAULT 1
#define GSTD_EVENT_FACTORY_STEP_RATE_DEFAULT 1.0
#define GSTD_EVENT_FACTORY_STEP_FLUSH_DEFAULT TRUE
#define GSTD_EVENT_FACTORY_STEP_INTERMEDIATE_DEFAULT FALSE


typedef enum _GstdEventType GstdEventType;

Expand Down Expand Up @@ -71,14 +77,17 @@ enum _GstdEventType

GSTD_EVENT_SEEK = 14,

GSTD_EVENT_NAVIGATION = 15
GSTD_EVENT_NAVIGATION = 15,

GSTD_EVENT_STEP = 16
};

static gboolean gstd_ascii_to_gint64 (const gchar *, gint64 *);
static gboolean gstd_ascii_to_double (const gchar *, gdouble *);
static gboolean gstd_ascii_to_boolean (const gchar *, gboolean *);
GstdEventType gstd_event_factory_parse_event (const gchar *);
static GstEvent *gstd_event_factory_make_seek_event (const gchar *);
static GstEvent *gstd_event_factory_make_step_event (const gchar *);
static GstEvent *gstd_event_factory_make_flush_stop_event (const gchar *);

GstEvent *
Expand All @@ -105,6 +114,9 @@ gstd_event_factory_make (const gchar * name, const gchar * description)
case GSTD_EVENT_FLUSH_STOP:
event = gstd_event_factory_make_flush_stop_event (description);
break;
case GSTD_EVENT_STEP:
event = gstd_event_factory_make_step_event (description);
break;
default:
event = NULL;
break;
Expand Down Expand Up @@ -254,6 +266,79 @@ gstd_event_factory_make_seek_event (const gchar * description)
}
}

static GstEvent *
gstd_event_factory_make_step_event (const gchar * description)
{
GstFormat format = GSTD_EVENT_FACTORY_STEP_FORMAT_DEFAULT;
guint64 amount = GSTD_EVENT_FACTORY_STEP_AMOUNT_DEFAULT;
gdouble rate = GSTD_EVENT_FACTORY_STEP_RATE_DEFAULT;
gboolean flush = GSTD_EVENT_FACTORY_STEP_FLUSH_DEFAULT;
gboolean intermediate = GSTD_EVENT_FACTORY_STEP_INTERMEDIATE_DEFAULT;
GstEvent *event = NULL;
gchar **tokens = NULL;
gint64 temp_format;
gint64 temp_flush;
gint64 temp_intermediate;

if (NULL != description) {
tokens = g_strsplit (description, " ", 5);
}

if (NULL == tokens || NULL == tokens[0]) {
goto fallback;
}

if (!gstd_ascii_to_gint64 (tokens[0], &temp_format)) {
goto out;
}
format = (GstFormat) temp_format;

if (NULL == tokens[1]) {
goto fallback;
}

if (!gstd_ascii_to_gint64 (tokens[1], &amount)) {
goto out;
}

if (NULL == tokens[2]) {
goto fallback;
}

if (!gstd_ascii_to_double (tokens[2], &rate)) {
goto out;
}

if (NULL == tokens[3]) {
goto fallback;
}

if (!gstd_ascii_to_gint64 (tokens[3], &temp_flush)) {
goto out;
}
flush = (gboolean) temp_flush;

if (NULL == tokens[4]) {
goto fallback;
}

if (!gstd_ascii_to_gint64 (tokens[4], &temp_intermediate)) {
goto out;
}
intermediate = (gboolean) temp_intermediate;

fallback:
{
event =
gst_event_new_step (format, amount, rate, flush, intermediate);
}
out:
{
g_strfreev (tokens);
return event;
}
}

static GstEvent *
gstd_event_factory_make_flush_stop_event (const gchar * description)
{
Expand Down Expand Up @@ -284,6 +369,8 @@ gstd_event_factory_parse_event (const gchar * name)
ret = GSTD_EVENT_FLUSH_START;
} else if (!strcmp (name, "flush-stop") || !strcmp (name, "flush_stop")) {
ret = GSTD_EVENT_FLUSH_STOP;
} else if (!strcmp (name, "step")) {
ret = GSTD_EVENT_STEP;
}
return ret;
}
28 changes: 28 additions & 0 deletions gstd/gstd_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ static GstdReturnCode gstd_parser_event_eos (GstdSession *, gchar *, gchar *,
gchar **);
static GstdReturnCode gstd_parser_event_seek (GstdSession *, gchar *, gchar *,
gchar **);
static GstdReturnCode gstd_parser_event_step (GstdSession *, gchar *, gchar *,
gchar **);
static GstdReturnCode gstd_parser_event_flush_start (GstdSession *, gchar *,
gchar *, gchar **);
static GstdReturnCode gstd_parser_event_flush_stop (GstdSession *, gchar *,
Expand Down Expand Up @@ -125,6 +127,7 @@ static GstdCmd cmds[] = {

{"event_eos", gstd_parser_event_eos},
{"event_seek", gstd_parser_event_seek},
{"event_step", gstd_parser_event_step},
{"event_flush_start", gstd_parser_event_flush_start},
{"event_flush_stop", gstd_parser_event_flush_stop},

Expand Down Expand Up @@ -668,6 +671,31 @@ gstd_parser_event_seek (GstdSession * session, gchar * action, gchar * args,
return ret;
}

static GstdReturnCode
gstd_parser_event_step (GstdSession * session, gchar * action, gchar * args,
gchar ** response)
{
GstdReturnCode ret;
gchar *uri;
gchar **tokens;

g_return_val_if_fail (GSTD_IS_SESSION (session), GSTD_NULL_ARGUMENT);
g_return_val_if_fail (args, GSTD_NULL_ARGUMENT);
g_return_val_if_fail (response, GSTD_NULL_ARGUMENT);

tokens = g_strsplit (args, " ", 2);
check_argument (tokens[0], GSTD_BAD_COMMAND);
// We don't check for the second token since we want to allow defaults
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use C Code Style
/* We don't check for the second token since we want to allow defaults Write */


uri = g_strdup_printf ("/pipelines/%s/event step %s", tokens[0], tokens[1]);
ret = gstd_parser_parse_raw_cmd (session, (gchar*)"create", uri, response);

g_free (uri);
g_strfreev (tokens);

return ret;
}

static GstdReturnCode
gstd_parser_event_flush_start (GstdSession * session, gchar * action,
gchar * pipeline, gchar ** response)
Expand Down
31 changes: 31 additions & 0 deletions libgstc/libgstc.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
#define PIPELINE_EVENT_FORMAT "/pipelines/%s/event"

#define SEEK_FORMAT "seek %f %d %d %d %lld %d %lld"
#define STEP_FORMAT "step %d %lld %f %d %d"
#define FLUSH_STOP_FORMAT "flush_stop %s"
#define TIMEOUT_FORMAT "%lli"

Expand Down Expand Up @@ -670,6 +671,36 @@ gstc_pipeline_seek(GstClient *client, const char *pipeline_name,
return ret;
}

GstcStatus
gstc_pipeline_step(GstClient *client, const char *pipeline_name,
int format, long long amount, double rate, int flush,
int intermediate)
{
GstcStatus ret;
int asprintf_ret;
char *where;
char *what;

gstc_assert_and_ret_val (NULL != client, GSTC_NULL_ARGUMENT);
gstc_assert_and_ret_val (NULL != pipeline_name, GSTC_NULL_ARGUMENT);

asprintf_ret = asprintf (&where, PIPELINE_EVENT_FORMAT, pipeline_name);
if(asprintf_ret == PRINTF_ERROR) {
return GSTC_OOM;
}
asprintf_ret = asprintf (&what, STEP_FORMAT, format, amount, rate, flush, intermediate);
if(asprintf_ret == PRINTF_ERROR) {
return GSTC_OOM;
}

ret = gstc_cmd_create (client, where, what);

free (where);
free (what);

return ret;
}

GstcStatus
gstc_pipeline_list_elements (GstClient * client,
const char *pipeline_name, char **elements[], int *list_lenght)
Expand Down
26 changes: 26 additions & 0 deletions libgstc/libgstc.h
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,32 @@ GstcStatus gstc_pipeline_seek(GstClient *client, const char *pname,
int stop_type, long long stop);


/**
* gstc_pipeline_step:
* @client: The client returned by gstc_client_new()
* @pname: Name associated with the pipeline
* @format: Format for seek values: undefined (0), default (1), bytes (2),
* nanoseconds(3), buffers (4) or percent (5) where default means to use the
* format of the pad/element, nanoseconds means time in nanoseconds and percentage
* means percentage of the stream.
* @amount: the amount of data to step
* @rate: New playback rate, e.g. 1 is normal, 0.5 is half speed,
* 2 is twice as fast as normal. A rate of <= 0.0 is not allowed.
* @flush: The flush flag will clear any pending data in the pipeline before starting the step operation: false (0), true (1).
* @intermediate: The intermediate flag instructs the pipeline that this step operation is part of a larger step operation: false (0), true (1).
*
* Creates a new step event. The purpose of the step event is to instruct a sink to skip
* @amount (expressed in @format) of media. It can be used to implement stepping through
* the video frame by frame or for doing fast trick modes.
*
* Returns: GstcStatus indicating success, daemon unreachable, daemon timeout,
* bad pipeline name, out of memory
*/
GstcStatus gstc_pipeline_step(GstClient *client, const char *pname,
int format, long long amount, double rate, int flush,
int intermediate);


/**
* Configures playback of the pipeline between @start to @stop at the speed
* given in @rate. Effectively causes gstd to invoke gst_element_seek().
Expand Down