/* main context */ static void spice_gst_decoder_destroy(VideoDecoder *video_decoder) { SpiceGstDecoder *decoder = (SpiceGstDecoder*)video_decoder; /* Stop and free the pipeline to ensure there will not be any further * new_sample() call (clearing thread-safety concerns). */ free_pipeline(decoder); /* Even if we kept the decoder around, once we return the stream will be * destroyed making it impossible to display frames. So cancel any * scheduled display_frame() call and drop the queued frames. */ if (decoder->timer_id) { g_source_remove(decoder->timer_id); } g_mutex_clear(&decoder->queues_mutex); SpiceGstFrame *gstframe; while ((gstframe = g_queue_pop_head(decoder->decoding_queue))) { free_gst_frame(gstframe); } g_queue_free(decoder->decoding_queue); while ((gstframe = g_queue_pop_head(decoder->display_queue))) { free_gst_frame(gstframe); } g_queue_free(decoder->display_queue); free(decoder); /* Don't call gst_deinit() as other parts of the client * may still be using GStreamer. */ }
static gboolean create_pipeline(SpiceGstDecoder *decoder) { gchar *desc; gboolean auto_enabled; guint opt; GstAppSinkCallbacks appsink_cbs = { NULL }; GError *err = NULL; GstBus *bus; auto_enabled = (g_getenv("SPICE_GSTVIDEO_AUTO") != NULL); if (auto_enabled || !VALID_VIDEO_CODEC_TYPE(decoder->base.codec_type)) { SPICE_DEBUG("Trying %s for codec type %d %s", gst_opts[0].dec_name, decoder->base.codec_type, (auto_enabled) ? "(SPICE_GSTVIDEO_AUTO is set)" : ""); opt = 0; } else { opt = decoder->base.codec_type; } /* - We schedule the frame display ourselves so set sync=false on appsink * so the pipeline decodes them as fast as possible. This will also * minimize the risk of frames getting lost when we rebuild the * pipeline. * - Set max-bytes=0 on appsrc so it does not drop frames that may be * needed by those that follow. */ desc = g_strdup_printf("appsrc name=src is-live=true format=time max-bytes=0 block=true " "%s ! %s ! videoconvert ! appsink name=sink " "caps=video/x-raw,format=BGRx sync=false drop=false", gst_opts[opt].dec_caps, gst_opts[opt].dec_name); SPICE_DEBUG("GStreamer pipeline: %s", desc); decoder->pipeline = gst_parse_launch_full(desc, NULL, GST_PARSE_FLAG_FATAL_ERRORS, &err); g_free(desc); if (!decoder->pipeline) { spice_warning("GStreamer error: %s", err->message); g_clear_error(&err); return FALSE; } decoder->appsrc = GST_APP_SRC(gst_bin_get_by_name(GST_BIN(decoder->pipeline), "src")); decoder->appsink = GST_APP_SINK(gst_bin_get_by_name(GST_BIN(decoder->pipeline), "sink")); appsink_cbs.new_sample = new_sample; gst_app_sink_set_callbacks(decoder->appsink, &appsink_cbs, decoder, NULL); bus = gst_pipeline_get_bus(GST_PIPELINE(decoder->pipeline)); gst_bus_add_watch(bus, handle_pipeline_message, decoder); gst_object_unref(bus); decoder->clock = gst_pipeline_get_clock(GST_PIPELINE(decoder->pipeline)); if (gst_element_set_state(decoder->pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) { SPICE_DEBUG("GStreamer error: Unable to set the pipeline to the playing state."); free_pipeline(decoder); return FALSE; } return TRUE; }
static gboolean handle_pipeline_message(GstBus *bus, GstMessage *msg, gpointer video_decoder) { SpiceGstDecoder *decoder = video_decoder; if (GST_MESSAGE_TYPE(msg) == GST_MESSAGE_ERROR) { GError *err = NULL; gchar *debug_info = NULL; gst_message_parse_error(msg, &err, &debug_info); spice_warning("GStreamer error from element %s: %s", GST_OBJECT_NAME(msg->src), err->message); if (debug_info) { SPICE_DEBUG("debug information: %s", debug_info); g_free(debug_info); } g_clear_error(&err); /* We won't be able to process any more frame anyway */ free_pipeline(decoder); } return TRUE; }
int main(int argc, char *argv[]){ char *line; pipeline pl; int run; //flags int redo = 0; int skip = 0; int isResume = 0; char *promptstr; char* buffer; numExits = 0; jobIndex = 0; histIndex = 0; back = 0; script = 0; FILE* in; /* check for the right number of arguments */ //if ( argc > 2 ) { // printusage(argv[0]); // exit(-1); //} if (argc >= 2) { DIR* dirp; struct dirent *dp; int isFound = 0; if ((dirp = opendir(".")) == NULL) { perror("couldn't open path"); return 0; } //put files into array and sort their names while ((dp = readdir(dirp)) != NULL) { if (strcmp(dp->d_name, argv[1]) == 0) { isFound = 1; } } if (isFound == 0) { printf("%s: Command not found\n", argv[1]); } else { in = fopen(argv[1], "r"); buffer = (char*)malloc(sizeof(in)); script = 1; } } //struct termios saved_term_mode; struct sigaction action; action.sa_handler = killHandle; /* set tick to be the handler function */ sigemptyset(&action.sa_mask); /* clear out masked functions */ action.sa_flags = 0; /* no special handling */ struct sigaction action2; action2.sa_handler = susHandle; /* set tick to be the handler function */ sigemptyset(&action2.sa_mask); /* clear out masked functions */ action2.sa_flags = 0; /* no special handling */ /* * Use the sigaction function to associate the signal action with SIGALRM. */ if (sigaction(SIGINT, &action, NULL) < 0 ) { fprintf(stderr, "SIGINT\n"); exit(-1); } if(sigaction(SIGTSTP, &action2, NULL) < 0) { fprintf(stderr, "SIGTSTP\n"); exit(-1); } //saved_term_mode = set_raw_term_mode(); initHistory(); initJobs(); //strcpy(jobs[1], "hey"); /* set prompt */ promptstr = PROMPT; run = TRUE; if (script == 0) prompt(promptstr); while ( run ) { /// if reexecute was not called if (redo == 0) { if (script == 0) { if ( NULL == (line = readLongString(stdin)) ) { if ( feof(stdin) ) run = FALSE; } } else { fgets(line, sizeof(in), in); if (line[0] == '%') { line++; isResume = 1; } } } else { //printf("histInd: %d\n", histIndex); ///if reexecute was called, ///find the correct place in the history ///list to extract the reexecuted command int temp = histIndex; temp--; int ind = 0; while (ind != reNumber) { temp--; ind++; } line = history[temp]; printf("%s\n", line); } if (line == NULL) { if (feof(stdin)) run = FALSE; } else { if (line[0] == '%') { line++; isResume = 1; } /* We got a line, send it off to the pipeline cracker and * launch it */ //if (redo == 0) //{ pl = crack_pipeline(line); //} redo = 0; /* * Show that it worked. This is where you're going to do * something radically different: rather than printing the * pipeline, you're going to execute it. */ if ( pl != NULL && strlen(pl->cline) > 0) { /* if (pl->cline[0] == '%') { int i; isResume = 1; pl->stage[0].argv[0][0] = ' '; for (i = 0; i < strlen(pl->cline)-1; i++) { pl->stage[0].argv[0][i] = pl->stage[0].argv[0][i+1]; } pl->stage[0].argv[0][strlen(pl->cline)-1] = '\0'; } */ //print_pipeline(stdout,pl); /* print it. */ addHistory(pl->cline); ///add to the history what was typed into the command line if (strcmp(pl->stage[0].argv[0], "history") == 0) { ///print the history if possible if (pl->stage[0].argc > 1) { printf("Junk after built-in command\n"); skip = 1; } numExits = 0; if (skip == 0) printHistory(); skip = 0; } else if (strcmp(pl->stage[0].argv[0], "jobs") == 0) { ///print the suspended jobs if possible if (pl->stage[0].argc > 1) { printf("Junk after built-in command\n"); skip = 1; } numExits = 0; if (skip == 0) printJobs(); skip = 0; } else if (strcmp(pl->stage[0].argv[0], "exit") == 0) { ///exit vssh if possible if (pl->stage[0].argc > 1) { fprintf(stderr, "Junk after built-in command\n"); skip = 1; } numExits++; if (skip == 0) exitCmd(); skip = 0; } else if (strcmp(pl->stage[0].argv[0], "bg") == 0) { ///background the most recently suspended job if possible if (pl->stage[0].argc > 1) { fprintf(stderr, "Junk after built-in command\n"); skip = 1; } numExits = 0; if (skip == 0) bg(jobs[jobIndex-1]); skip = 0; } else if (strcmp(pl->stage[0].argv[0], "fg") == 0) { ///foreground the most recently backgrounded job if possible if (pl->stage[0].argc > 1) { fprintf(stderr, "Junk after built-in command\n"); skip = 1; } numExits = 0; if (skip == 0) fg(jobs[jobIndex-1]); skip = 0; } else if (strcmp(pl->stage[0].argv[0], "cd") == 0) { ///change the directory of vssh if possible if (pl->stage[0].argc > 2) { fprintf(stderr, "Junk after built-in command\n"); skip = 1; } numExits = 0; if (skip == 0) cd(pl->stage[0].argv[1]); skip = 0; } else if (isResume == 1) { ///foreground the specified job if possible if (pl->stage[0].argc > 1) { fprintf(stderr, "Junk after built-in command\n"); skip = 1; } numExits = 0; if (skip == 0) { //pl->stage[0].argv[0]++; int i; int killFlag = 0; for (i = 0; i < strlen(pl->stage[0].argv[0]); i++) { if (!isdigit(pl->stage[0].argv[0][i])) { ///if the supplied job number is not a number ///then print error killFlag = 1; fprintf(stderr, "%s: No such job.\n", pl->stage[0].argv[0]); } } if (killFlag == 0) { if (atoi(pl->stage[0].argv[0]) <= 0 || atoi(pl->stage[0].argv[0]) > jobIndex) ///if the supplied job number is not a valid job index ///then print error fprintf(stderr, "%s: No such job.\n", pl->stage[0].argv[0]); else resume(jobs[atoi(pl->stage[0].argv[0])-1]->id, atoi(pl->stage[0].argv[0])-1); } } skip = 0; } else if (strcmp(pl->stage[0].argv[0], "!") == 0) { ///reexecute the specified history command if possible if (pl->stage[0].argc > 2 || strlen(pl->stage[0].argv[1]) > 3) { fprintf(stderr, "Junk after built-in command\n"); skip = 1; } ///if the number supplied is not a valid history index ///then print error if (pl->stage[0].argv[1][0] == '0' && skip == 0) { fprintf(stderr, "%s: Event not found\n", pl->stage[0].argv[1]); skip = 1; } if (strlen(history[atoi(pl->stage[0].argv[1])]) <= 0 && skip == 0) { fprintf(stderr, "%s: Event not found\n", pl->stage[0].argv[1]); skip = 1; } int i; for (i = 0; i < strlen(pl->stage[0].argv[1]); i++) { if (!isdigit(pl->stage[0].argv[1][i]) && skip == 0) { ///if the number supplied is not a number ///then print error fprintf(stderr, "%s: Event not found\n", pl->stage[0].argv[1]); skip = 1; } } numExits = 0; if (skip == 0) { redo = 1; reNumber = atoi(pl->stage[0].argv[1]); //printf("renum: %d\n", reNumber); //pl = crack_pipeline(history[atoi(pl->stage[0].argv[1])]); //printf("%s\n", pl->cline); //lineno++; //continue; } skip = 0; } else if (strcmp(pl->stage[0].argv[0], "kill") == 0) { ///kill the specified job if possible if (pl->stage[0].argc > 2) { fprintf(stderr, "Junk after built-in command\n"); skip = 1; } numExits = 0; if (skip == 0) { int i; int killFlag = 0; for (i = 0; i < strlen(pl->stage[0].argv[1]); i++) { ///if the supplied job number is not a number ///then print error if (!isdigit(pl->stage[0].argv[1][i])) { killFlag = 1; fprintf(stderr, "%s: No such job.\n", pl->stage[0].argv[1]); } } if (killFlag == 0) { if (atoi(pl->stage[0].argv[1]) <= 0 || atoi(pl->stage[0].argv[1]) > jobIndex) ///if the supplied job number is not a valid job index ///then print error fprintf(stderr, "%s: No such job.\n", pl->stage[0].argv[1]); else killProcess(atoi(pl->stage[0].argv[1])-1, jobs[atoi(pl->stage[0].argv[1])-1]->id); } } skip = 0; } else { ///pipe/redirect as necessary numExits = 0; //int i; //for (i = 0; i < pl->length; i++) //{ //else //{ //handle backgrounding "&" //find the & int j; int andFound = 0; int pipeFound = 0; for (j = 1; j < strlen(pl->cline); j++) { if (pl->cline[j] == '|') { //fprintf(stderr, "Pipelines cannot be backgrounded\n"); pipeFound = 1; } else if (pl->cline[j] == '&') { //error if & is not the last arg, exec nothing if (pipeFound == 1) { fprintf(stderr, "Pipelines cannot be backgrounded\n"); } else if (j != strlen(pl->cline) - 1) { andFound = 1; fprintf(stderr, "Junk after '&'.\n"); } else if (pl->cline[j-1] == ' ') { andFound = 1; pl->cline[j] = '\0'; //backExec(pl->stage[0].argv[0], pl->stage[0].argv, pl->cline); back = 1; } } } if (pl->length >= 2) { ///pipe if the pipline has 2 or more stages pipeCmd(pl); } else if (pl->stage[0].outname != NULL && pl->stage[0].inname != NULL) { redirectBoth(pl->stage[0].argv, pl->stage[0].inname, pl->stage[0].outname); } else if (pl->stage[0].outname != NULL) { ///otherwise redirect output if there is an outfile redirectOutput(pl->stage[0].argv, pl->stage[0].outname, pl->cline); } else if (pl->stage[0].inname != NULL) { ///otherwise redirect input if there is an infile redirectInput(pl->stage[0].argv, pl->stage[0].inname, pl->cline); } else if (andFound == 0) { //execute if not a built-in command execute(pl->stage[0].argv[0], pl->stage[0].argv, pl->cline); } back = 0; //} //} } } free_pipeline(pl); fflush(stdout); /* also frees line */ lineno++; /* readLongString trims newlines, so increment it manually */ } if (run ) { if (script == 0) /* assuming we still want to run */ prompt(promptstr); } } return 0; }
int main (int argc, const char * argv[]) { char *line; pipeline pl; char *promptstr; initHistory(); initJobs(); /* check for the right number of arguments */ if(argc >= 2) { FILE* theFile = fopen(argv[1], "r"); if(theFile == NULL) { if(errno == ENOENT) { fprintf(stderr, "%s: Command not found.\n", argv[1]); } else { perror("fopen"); } exit(-1); } if(dup2(fileno(theFile), STDIN_FILENO) == -1) { perror("dup2"); exit(-1); } fclose(theFile); } /* set prompt */ promptstr = PROMPT; prompt(promptstr); while ( TRUE ) { if ( NULL == (line = readLongString(stdin))) { if ( feof(stdin) ) { /* end of the input file, we're done */ exit(0); } } else if(line[0] == '\0') { /* do nothing */ } else { /* line is added to history list, and freed from there */ /* copyLine is sent to pipeline, and freed from there */ /* jobs need their own copy of the command_line */ char* copyLine = newstr(line); /* We got a line, send it off to the pipeline cracker and * launch it */ pl = crack_pipeline(copyLine); if(pl != NULL) { addCommandToHistory(line); runPipeline(pl); } free_pipeline(pl); lineno++; /* readLongString trims newlines, so increment it manually */ } fflush(stdout); //tcsetpgrp(STDIN_FILENO, getpgid(0)); prompt(promptstr); } return 0; }