1 /* 2 * Decode Reference Frameserver Archetype 3 * Copyright 2014-2020, Björn Ståhl 4 * License: 3-Clause BSD, see COPYING file in arcan source repository. 5 * Reference: http://arcan-fe.com 6 * Description: 7 * The decode frameserver takes some form of compressed / packed input 8 * and transforms it into a raw format that shmif can use or process. 9 * The idea is to consolidate all parsers into a single volatile process 10 * that can be killed off by the parent without risking corruption. It 11 * is also a profile for sandboxing, decode is never expected to write 12 * to disk, exec other processes etc. 13 */ 14 #include <arcan_shmif.h> 15 #include "decode.h" 16 17 int show_use(struct arcan_shmif_cont* cont, const char* msg) 18 { 19 if (msg) 20 fprintf(stdout, "Couldn't start decode, reason: %s\n\n", msg); 21 22 fprintf(stdout, "Environment variables: \nARCAN_CONNPATH=path_to_server\n" 23 "ARCAN_ARG=packed_args (key1=value:key2:key3=value)\n\n" 24 "General arguments:\n" 25 " key \t value \t description\n" 26 "---------\t-----------\t-----------------\n" 27 #ifdef HAVE_VLC 28 " protocol\t media \t set 'media' mode (audio, video)\n" 29 #endif 30 " protocol\t 3d \t set '3d object' mode\n" 31 " protocol\t text \t set 'text' mode\n" 32 #ifdef HAVE_PROBE 33 " protocol\t probe \t set 'probe' mode\n" 34 #endif 35 " protocol\t image \t set 'image' mode\n" 36 #ifdef HAVE_T2S 37 " protocol\t t2s \t set 'text-to-speech' mode\n" 38 #endif 39 "---------\t-----------\t----------------\n" 40 "\n" 41 #ifdef HAVE_T2S 42 " Accepted t2s arguments:\n" 43 " key \t value \t description\n" 44 "---------\t-----------\t-----------------\n" 45 " channel \t l,r, >lr< \t set output channels to left, right or both\n" 46 " list \t \t return a list of voices then terminate\n" 47 " text \t msg \t one-shot convert 'msg' to speech then terminate\n" 48 " voice \t name \t select voice by name\n" 49 " rate \t 80..450 \t set rate in words per minute\n" 50 " pitch \t 0..100 \t set base pitch, 0 low, (default=50)\n" 51 " range \t 0..100 \t voice range, 0 monotone, (default=50)\n" 52 " gap \t 0..n ms \t gap between words in miliseconds (default=10)\n" 53 " ssml \t \t interpret text as 'ssml' formatted <voice> .. \n" 54 " phonemes\t \t interpret text as 'phoneme' ([[]]) encoded\n" 55 "---------\t-----------\t----------------\n" 56 "\n" 57 #endif 58 #ifdef HAVE_PROBE 59 " Accepted probe arguments:\n" 60 " key \t value \t description\n" 61 "---------\t-----------\t-----------------\n" 62 " file \t path \t one-shot open file >path< for input \n" 63 " format \t type \t set output format (mime, long, >short<)\n" 64 "---------\t-----------\t-----------------\n" 65 "\n" 66 #endif 67 " Image protocol does not take any arguments, it operates solely \n" 68 " in a service mode where incoming BCHUNK hints are decoded as they \n" 69 " come and re-rastered on density changes.\n" 70 "\n" 71 " Accepted text arguments:\n" 72 " key \t value \t description\n" 73 "---------\t-----------\t-----------------\n" 74 " file \t path \t try to open file path for playback \n" 75 " view \t viewmode \t (ascii, >utf8<, hex) set default view\n" 76 "\n" 77 "Accepted media arguments:\n" 78 " key \t value \t description\n" 79 "---------\t-----------\t-----------------\n" 80 " file \t path \t try to open file path for playback source\n" 81 " fd \t file-no \t use inherited descriptor for playback source\n" 82 " pos \t 0..1 \t set the relative starting position \n" 83 " noaudio \t \t disable the audio output entirely \n" 84 " stream \t url \t attempt to open URL for streaming input \n" 85 " capture \t \t try to open a capture device\n" 86 " device \t number \t find capture device with specific index\n" 87 " fps \t rate \t force a specific framerate\n" 88 " width \t outw \t scale output to a specific width\n" 89 " height \t outh \t scale output to a specific height\n" 90 " loop \t \t reset playback upon completion\n" 91 #ifdef HAVE_UVC 92 "---------\t-----------\t----------------\n"); 93 uvc_append_help(stdout); 94 fprintf(stdout, 95 #endif 96 "---------\t-----------\t----------------\n" 97 ); 98 99 if (cont){ 100 if (msg) 101 arcan_shmif_last_words(cont, msg); 102 103 arcan_shmif_drop(cont); 104 } 105 106 return EXIT_FAILURE; 107 } 108 109 int wait_for_file( 110 struct arcan_shmif_cont* cont, const char* extstr, char** idstr) 111 { 112 int res = -1; 113 struct arcan_event ev; 114 115 if (idstr) 116 *idstr = NULL; 117 118 arcan_event bchunk = { 119 .ext.kind = ARCAN_EVENT(BCHUNKSTATE), 120 .category = EVENT_EXTERNAL, 121 .ext.bchunk = {.hint = true, .input = true} 122 }; 123 snprintf((char*)bchunk.ext.bchunk.extensions, 124 COUNT_OF(bchunk.ext.bchunk.extensions), "%s", extstr); 125 arcan_shmif_enqueue(cont, &bchunk); 126 127 while (arcan_shmif_wait(cont, &ev)){ 128 if (ev.category != EVENT_TARGET) 129 continue; 130 131 if (ev.tgt.kind == TARGET_COMMAND_EXIT) 132 return 0; 133 /* dup as the next call into shmif will close */ 134 else if (ev.tgt.kind == TARGET_COMMAND_BCHUNK_IN){ 135 res = arcan_shmif_dupfd(ev.tgt.ioevs[0].iv, -1, true); 136 if (idstr) 137 *idstr = strdup(ev.tgt.message); 138 break; 139 } 140 } 141 142 return res; 143 } 144 145 int afsrv_decode(struct arcan_shmif_cont* cont, struct arg_arr* args) 146 { 147 const char* type; 148 if (arg_lookup(args, "protocol", 0, &type)){ 149 } 150 else { 151 /* previously decode (vs encode, remoting, ...) used 'proto' and not protocol, 152 * as to not break applications out there, silelty support the short form */ 153 if (arg_lookup(args, "proto", 0, &type)){ 154 } 155 else 156 type = "media"; 157 } 158 159 #ifdef HAVE_PROBE 160 /* there should really be an 'auto' mode to this as well so that 161 * the results from probe is then switched to decode_(av, 3d, text, ...) */ 162 if (strcasecmp(type, "probe") == 0) 163 return decode_probe(cont, args); 164 #endif 165 166 if (strcasecmp(type, "media") == 0) 167 return decode_av(cont, args); 168 169 if (strcasecmp(type, "3d") == 0) 170 return decode_3d(cont, args); 171 172 if (strcasecmp(type, "text") == 0) 173 return decode_text(cont, args); 174 175 if (strcasecmp(type, "image") == 0) 176 return decode_image(cont, args); 177 178 #ifdef HAVE_T2S 179 if (strcasecmp(type, "t2s") == 0) 180 return decode_t2s(cont, args); 181 #endif 182 183 char errbuf[64]; 184 snprintf(errbuf, sizeof(errbuf), "unknown type argument: %s", type); 185 return show_use(cont, errbuf); 186 } 187