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