]> rtime.felk.cvut.cz Git - frescor/streamer.git/blob - streamer.c
c046e19c4da9a3ce1ae45e509e5a447d4d724e03
[frescor/streamer.git] / streamer.c
1 /*
2  *  Copyright (c) 2008 Luca Abeni
3  *
4  *  This is free software; see GPL.txt
5  */
6 #include <unistd.h>
7 #include <stdlib.h>
8 #include <signal.h>
9 #include <pthread.h>
10
11 #include <libavformat/avformat.h>
12 #include <libavdevice/avdevice.h>
13 #include <libswscale/swscale.h>
14
15 #include "input.h"
16 #include "output.h"
17 #include "codec.h"
18 #include "rt.h"
19
20 #include "streamer_config.h"
21
22 #ifdef CONFIG_OC_ULUT
23 #include <ul_log.h>
24 #include <ul_logreg.h>
25 #endif
26
27 #ifdef CONFIG_STREAMER_WITH_FRSH
28 #include <frsh.h>
29 #endif
30
31 #ifdef CONFIG_STREAMER_WITH_FRSH
32 /*temporrary solution to pass network parameters */
33 extern long int udp_budget, udp_period;
34 #endif /*CONFIG_STREAMER_WITH_FRSH*/
35
36 static const char *sdp_file = "sdp.txt";
37 static const char *vdev = "/dev/video0";
38 static const char *dst = "127.0.0.1";
39 static int dport = 20000;
40 static int width = 352;
41 static int height = 288;
42 int fps = 25;
43 static const char *impform = "video4linux2";
44 AVFormatContext *s, *os;
45
46 static void sdp_print(AVFormatContext *s, const char *fname)
47 {
48     char sdp[2048];
49     FILE *f;
50
51     f = fopen(fname, "w");
52     avf_sdp_create(&s, 1, sdp, sizeof(sdp));
53     fprintf(f, "%s\n", sdp);
54     fclose(f);
55 }
56
57 static void
58 usage(void)
59 {
60         printf("usage: streamer [ options ]\n");
61         printf("  -w <number>    send image width\n");
62         printf("  -h <number>    send image height\n");
63         printf("  -r <number>    refresh rate\n");
64         printf("  -r <path>      video device [%s]\n", vdev);
65         printf("  -m <addr>      destination IP address\n");
66         printf("  -i <string>    input video device format [%s]\n", impform);
67       #ifdef CONFIG_STREAMER_WITH_FRSH
68         printf("  -b <number>    network budget\n");
69         printf("  -p <number>    network period for given budget\n");
70       #endif /*CONFIG_STREAMER_WITH_FRSH*/
71       #ifdef CONFIG_OC_ULUT
72         printf("  -l <number>|<domain>=<number>,...\n");
73       #endif /*CONFIG_OC_ULUT*/
74 }
75
76 static int args_parse(int argc, char *argv[])
77 {
78   int v;
79
80   while ((v = getopt(argc, argv, "w:h:r:d:m:i:l:b:p:")) >= 0) {
81     switch (v) {
82       case 'w':
83         width = atoi(optarg);
84         break;
85       case 'h':
86         height = atoi(optarg);
87         break;
88       case 'r':
89         fps = atoi(optarg);
90         break;
91       case 'd':
92         vdev = optarg;
93         break;
94       case 'm':
95         dst = optarg;
96         break;
97       case 'i':
98         impform = optarg;
99         if(!strcmp(impform, "v4l"))
100           impform = "video4linux";
101         else if(!strcmp(impform, "v4l2"))
102           impform = "video4linux2";
103         break;
104       #ifdef CONFIG_STREAMER_WITH_FRSH
105       case 'b':
106         udp_budget = atol(optarg);
107         break;
108       case 'p':
109         udp_period = atol(optarg);
110         break;
111       #endif /*CONFIG_STREAMER_WITH_FRSH*/
112
113       #ifdef CONFIG_OC_ULUT
114       case 'l':
115         ul_log_domain_arg2levels(optarg);
116         break;
117       #endif /*CONFIG_OC_ULUT*/
118
119       default: /* unknown option */
120         fprintf(stderr, "%s: illegal option %c\n", argv[0], v);
121         usage();
122         exit(-1);
123     }
124   }
125
126   return 0;
127 }
128
129 int streamer_run_done_rq;
130
131 void* streamer_run(void* args)
132 {
133   int done;
134
135   done = 0;
136   while (!(done = streamer_run_done_rq)) {
137     AVPacket *pkt;
138     pkt = read_input_packet(s);
139     if (pkt == NULL) {
140       done = 1;
141     } else {
142       AVFrame *f;
143       AVPacket *opkt;
144
145       pkt->pts += s->streams[pkt->stream_index]->start_time;
146       //rt_job_start(pkt->pts);
147       f = pkt_decode(s, pkt);
148       if (f) {
149         opkt = pkt_encode(os, f);
150         if (opkt) {
151           pkt_send(os, opkt);
152         }
153       }
154       //rt_job_end();
155       av_free_packet(pkt);
156     }
157   }
158
159   return NULL;
160 }
161
162 void wait_for_ending_command(void) {
163   sigset_t sigset;
164   sigemptyset(&sigset);
165   sigaddset(&sigset, SIGINT);
166   sigaddset(&sigset, SIGTERM);
167   sigwaitinfo(&sigset, NULL);
168 }
169 static void block_signals(void) {
170   sigset_t sigset;
171   sigemptyset(&sigset);
172   sigaddset(&sigset, SIGINT);
173   sigaddset(&sigset, SIGTERM);
174   sigprocmask(SIG_BLOCK,&sigset,NULL);
175   pthread_sigmask(SIG_BLOCK,&sigset,NULL);
176 }
177
178
179 int main(int argc, char *argv[])
180 {
181
182   //long int cpu_budget, cpu_period;
183   int ret;
184
185   block_signals();
186
187 #ifdef CONFIG_STREAMER_WITH_FRSH
188   ret = frsh_init();
189   if (ret) PERROR_AND_EXIT(ret, "frsh_init1");
190
191   /* fill default network contract params */
192   udp_budget = 50000; 
193   udp_period = 500;
194 #endif /*CONFIG_STREAMER_WITH_FRSH*/
195
196   avcodec_register_all();
197   av_register_all();
198   avdevice_register_all();
199
200   args_parse(argc, argv);
201
202   s = open_input_stream(vdev, width, height, fps, impform);
203   if (s == NULL) {
204     fprintf(stderr, "Cannot open input file %s\n", vdev);
205
206     return -1;
207   }
208   codec_open(s);
209   os = open_output_stream(dst, dport, CODEC_TYPE_VIDEO);
210   if (os == NULL) {
211     fprintf(stderr, "Cannot open output stream\n");
212
213     return -1;
214   }
215   os->streams[0]->codec->width = s->streams[0]->codec->width;
216   os->streams[0]->codec->height = s->streams[0]->codec->height;
217   os->streams[0]->codec->time_base = s->streams[0]->codec->time_base;
218   codec_connect(s->streams[0]->codec, os->streams[0]->codec);
219   out_codec_open(os);
220   dump_format(os, 0, os->filename, 1);
221   sdp_print(os, sdp_file);
222
223 #if CONFIG_STREAMER_WITH_FRSH && CONFIG_AQUOSA 
224   frsh_thread_attr_t frsh_attr;
225   frsh_thread_id_t thread;
226   frsh_vres_id_t cpu_vres;
227   frsh_contract_t cpu_contract;
228   frsh_rel_time_t cpu_budget, cpu_period;
229  
230   cpu_budget = fosa_msec_to_rel_time(50);
231   cpu_period = fosa_msec_to_rel_time(100);
232   /* Contract negotiation for CPU */
233   ret = frsh_contract_init(&cpu_contract);
234   if (ret) PERROR_AND_EXIT(ret, "CPU:frsh_contract_init");
235  
236   ret = frsh_contract_set_basic_params(&cpu_contract,
237                                              &cpu_budget,
238                                              &cpu_period,
239                                              FRSH_WT_BOUNDED,
240                                              FRSH_CT_REGULAR);
241         if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_basic_params");
242         ret = frsh_contract_set_resource_and_label(&cpu_contract, 
243                         FRSH_RT_PROCESSOR, FRSH_CPU_ID_DEFAULT, "aqcpu_cont");
244         if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_resource_and_label");
245
246         ret = frsh_contract_negotiate(&cpu_contract, &cpu_vres);
247         if (ret) PERROR_AND_EXIT(ret, "frsh_contract_negotiate");
248         printf("Aqcpu vres negotiated\n");
249
250         pthread_attr_init(&frsh_attr);
251         ret = frsh_thread_create_and_bind(cpu_vres, &thread, &frsh_attr, 
252                                 streamer_run, (void*) NULL);
253         if (ret) PERROR_AND_EXIT(ret, "frsh_thread_create_and_bind");
254
255         wait_for_ending_command();
256
257         streamer_run_done_rq = 1;
258         
259         pthread_join(thread.pthread_id, (void**) NULL); 
260
261         printf("Ending contracts\n");
262
263         ret = frsh_contract_cancel(cpu_vres);
264         if (ret) PERROR_AND_EXIT(ret, "frsh_contract_cancel");
265
266         printf("Finishing\n");
267
268         close_output_stream(os);
269 #else
270         pthread_attr_t attr;
271         pthread_t streamer_th;
272
273         pthread_attr_init(&attr);
274
275         ret = pthread_create(&streamer_th, &attr, streamer_run, (void*) NULL);
276         if (ret) 
277                         printf("Failed to create streamer thread\n.");
278
279         wait_for_ending_command();
280
281         streamer_run_done_rq = 1;
282
283         pthread_join(streamer_th, (void**) NULL);
284
285         printf("Finishing\n");
286
287         close_output_stream(os);
288 #endif
289
290   return 0;
291 }
292