Skip to content

Commit a0d93ed

Browse files
committed
Add error handling for gst_element_set_state calls
1 parent 4642d85 commit a0d93ed

File tree

1 file changed

+33
-17
lines changed

1 file changed

+33
-17
lines changed

samples/kvssink_intermittent_sample.cpp

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,19 @@ typedef struct _CustomData {
4444
GstElement *pipeline;
4545
} CustomData;
4646

47-
void sigint_handler(int sigint) {
48-
LOG_DEBUG("SIGINT received. Exiting...");
47+
void shutdown_sample () {
4948
terminated = TRUE;
5049
cv.notify_all();
5150
if (main_loop != NULL) {
5251
g_main_loop_quit(main_loop);
5352
}
5453
}
5554

55+
void sigint_handler(int sigint) {
56+
LOG_DEBUG("SIGINT received. Exiting...");
57+
shutdown_sample();
58+
}
59+
5660
bool check_element(GstElement* element, const char* name) {
5761
if (!element) {
5862
LOG_ERROR("[KVS sample] Failed to create element: " << name);
@@ -133,14 +137,15 @@ void determine_aws_credentials(GstElement *kvssink, char* streamName) {
133137
void stopStartLoop(GstElement *pipeline, GstElement *source) {
134138
std::mutex cv_m;
135139
std::unique_lock<std::mutex> lck(cv_m);
140+
GstStateChangeReturn gst_state_change_ret;
136141

137142
while (!terminated) {
138143
// Using cv.wait_for to break sleep early upon signal interrupt.
139144
if (cv.wait_for(lck, std::chrono::seconds(KVS_INTERMITTENT_PLAYING_INTERVAL_SECONDS)) != std::cv_status::timeout) {
140145
break;
141146
}
142147

143-
LOG_INFO("[KVS sample] Stopping stream to KVS for " << KVS_INTERMITTENT_PAUSED_INTERVAL_SECONDS << " seconds");
148+
LOG_INFO("[KVS sample] Stopping stream to KVS for " << KVS_INTERMITTENT_PAUSED_INTERVAL_SECONDS << " seconds.");
144149

145150
// EOS event pushes frames buffered by the h264enc element down to kvssink.
146151
GstEvent* eos = gst_event_new_eos();
@@ -153,7 +158,11 @@ void stopStartLoop(GstElement *pipeline, GstElement *source) {
153158
// Set videotestsrc to paused state because it does not stop producing frames upon EOS,
154159
// and the frames are not cleared upon flushing.
155160
if (STRCMPI(GST_ELEMENT_NAME(source), KVS_GST_TEST_SOURCE_NAME) == 0) {
156-
gst_element_set_state(source, GST_STATE_PAUSED);
161+
gst_state_change_ret = gst_element_set_state(source, GST_STATE_PAUSED);
162+
if (gst_state_change_ret == GST_STATE_CHANGE_FAILURE) {
163+
LOG_ERROR("[KVS sample] Unable to set the source to the paused state.");
164+
shutdown_sample();
165+
}
157166
}
158167

159168
// Flushing to remove EOS status.
@@ -165,19 +174,23 @@ void stopStartLoop(GstElement *pipeline, GstElement *source) {
165174
break;
166175
}
167176

168-
LOG_INFO("[KVS sample] Starting stream to KVS for " << KVS_INTERMITTENT_PLAYING_INTERVAL_SECONDS << " seconds");
177+
LOG_INFO("[KVS sample] Starting stream to KVS for " << KVS_INTERMITTENT_PLAYING_INTERVAL_SECONDS << " seconds.");
169178

170179
// Stop the flush now that we are resuming streaming.
171180
GstEvent* flush_stop = gst_event_new_flush_stop(TRUE);
172181
gst_element_send_event(pipeline, flush_stop);
173182

174183
// Set videotestsrc back to playing state.
175184
if (STRCMPI(GST_ELEMENT_NAME(source), KVS_GST_TEST_SOURCE_NAME) == 0) {
176-
gst_element_set_state(source, GST_STATE_PLAYING);
185+
gst_state_change_ret = gst_element_set_state(source, GST_STATE_PLAYING);
186+
if (gst_state_change_ret == GST_STATE_CHANGE_FAILURE) {
187+
LOG_ERROR("[KVS sample] Unable to set the source to the playing state.");
188+
shutdown_sample();
189+
}
177190
}
178191
}
179192

180-
LOG_DEBUG("[KVS sample] Exited stopStartLoop");
193+
LOG_DEBUG("[KVS sample] Exited stopStartLoop.");
181194
}
182195

183196
int main(int argc, char *argv[]) {
@@ -190,6 +203,7 @@ int main(int argc, char *argv[]) {
190203
guint bus_watch_id;
191204
StreamSource source_type;
192205
char stream_name[MAX_STREAM_NAME_LEN + 1] = {0};
206+
GstStateChangeReturn gst_state_change_ret;
193207

194208
int runtime_duration_seconds = DEFAULT_SAMPLE_DURATION_SECONDS;
195209

@@ -233,6 +247,7 @@ int main(int argc, char *argv[]) {
233247
}
234248
}
235249

250+
236251
/* Create GStreamer elements */
237252

238253
pipeline = gst_pipeline_new("kvs-pipeline");
@@ -314,14 +329,19 @@ int main(int argc, char *argv[]) {
314329

315330
// Link the elements together.
316331
if (!gst_element_link_many(source, clock_overlay, video_convert, source_filter, encoder, sink_filter, kvssink, NULL)) {
317-
LOG_ERROR("[KVS sample] Elements could not be linked");
332+
LOG_ERROR("[KVS sample] Elements could not be linked.");
318333
gst_object_unref(pipeline);
319334
return -1;
320335
}
321336

322337
// Set the pipeline to playing state.
323-
LOG_INFO("[KVS sample] Starting stream to KVS for " << KVS_INTERMITTENT_PLAYING_INTERVAL_SECONDS << " seconds");
324-
gst_element_set_state(pipeline, GST_STATE_PLAYING);
338+
LOG_INFO("[KVS sample] Starting stream to KVS for " << KVS_INTERMITTENT_PLAYING_INTERVAL_SECONDS << " seconds.");
339+
gst_state_change_ret = gst_element_set_state(pipeline, GST_STATE_PLAYING);
340+
if (gst_state_change_ret == GST_STATE_CHANGE_FAILURE) {
341+
LOG_ERROR("[KVS sample] Unable to set the pipeline to the playing state.");
342+
gst_object_unref(pipeline);
343+
return -1;
344+
}
325345

326346
// Start the stop/start thread for intermittent streaming.
327347
std::thread stopStartThread(stopStartLoop, pipeline, source);
@@ -330,22 +350,18 @@ int main(int argc, char *argv[]) {
330350
std::this_thread::sleep_for(std::chrono::seconds(runtime_duration_seconds));
331351
if (!terminated) {
332352
LOG_INFO("[KVS sample] Reached maximum runtime of " << runtime_duration_seconds << " seconds. Terminating.");
333-
terminated = TRUE;
334-
cv.notify_all();
335-
if (main_loop != NULL) {
336-
g_main_loop_quit(main_loop);
337-
}
353+
shutdown_sample();
338354
}
339355
});
340356

341-
LOG_INFO("[KVS sample] Starting GStreamer main loop");
357+
LOG_INFO("[KVS sample] Starting GStreamer main loop.");
342358
g_main_loop_run(main_loop);
343359

344360
stopStartThread.join();
345361
timerThread.join();
346362

347363
// Application terminated, cleanup.
348-
LOG_INFO("[KVS sample] Streaming terminated, cleaning up");
364+
LOG_INFO("[KVS sample] Streaming terminated, cleaning up.");
349365
gst_element_set_state(pipeline, GST_STATE_NULL);
350366
gst_object_unref(GST_OBJECT(pipeline));
351367
g_source_remove(bus_watch_id);

0 commit comments

Comments
 (0)