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