Statistics
| Branch: | Revision:

chunker-player / chunker_player / chunker_player.c @ e8699fac

History | View | Annotate | Download (10 KB)

1 10c75ef7 GiuseppeTropea
#include <stdio.h>
2
#include <unistd.h>
3
#include <SDL.h>
4
#include <SDL_mutex.h>
5
#include "player_defines.h"
6
#include <confuse.h>
7
#include "http_default_urls.h"
8
#include "player_defines.h"
9
#include "chunker_player.h"
10
#include "player_gui.h"
11 1e69ae95 GiuseppeTropea
12 10c75ef7 GiuseppeTropea
int main(int argc, char *argv[])
13
{
14
        // some initializations
15
        SilentMode = 0;
16
        queue_filling_threshold = 0;
17
        SaveYUV = 0;
18
        quit = 0;
19
        QueueFillingMode=1;
20
        P2PProcessID = -1;
21
        NChannels = 0;
22
        SelectedChannel = -1;
23 19b05fc0 GiuseppeTropea
        char firstChannelName[255];
24
        int firstChannelIndex;
25 78068e21 GiuseppeTropea
        
26 10c75ef7 GiuseppeTropea
        memset((void*)Channels, 0, (MAX_CHANNELS_NUM*sizeof(SChannel)));
27 1e69ae95 GiuseppeTropea
28 10c75ef7 GiuseppeTropea
        HttpPort = -1;
29 3a240a99 GiuseppeTropea
        struct MHD_Daemon *daemon = NULL;
30 1e69ae95 GiuseppeTropea
        SDL_Event event;
31 10c75ef7 GiuseppeTropea
        OverlayMutex = SDL_CreateMutex();
32 e810bf7b GiuseppeTropea
33 cf26d11f GiuseppeTropea
        FILE *fp;
34 1e69ae95 GiuseppeTropea
                
35 19b05fc0 GiuseppeTropea
        if(argc<6) {
36
                printf("chunker_player queue_thresh httpd_port silentMode LossTracesFilenameSuffix ChannelName <YUVFilename>\n");
37 1e69ae95 GiuseppeTropea
                exit(1);
38
        }
39 cf26d11f GiuseppeTropea
        sscanf(argv[1],"%d",&queue_filling_threshold);
40 10c75ef7 GiuseppeTropea
        sscanf(argv[2],"%d",&HttpPort);
41
        sscanf(argv[3],"%d",&SilentMode);
42 31e4e8ba GiuseppeTropea
        sscanf(argv[4],"%s",LossTracesFilename);
43 19b05fc0 GiuseppeTropea
        sscanf(argv[5],"%s",firstChannelName);
44 20de09cd GiuseppeTropea
        
45 19b05fc0 GiuseppeTropea
        if(argc==7)
46 aba1367c GiuseppeTropea
        {
47 19b05fc0 GiuseppeTropea
                sscanf(argv[6],"%s",YUVFileName);
48 aba1367c GiuseppeTropea
                printf("YUVFile: %s\n",YUVFileName);
49 10c75ef7 GiuseppeTropea
                fp=fopen(YUVFileName, "wb");
50 aba1367c GiuseppeTropea
                if(fp)
51
                {
52
                        SaveYUV=1;
53
                        fclose(fp);
54
                }
55
                else
56
                        printf("ERROR: Unable to create YUVFile\n");
57
        }
58 78068e21 GiuseppeTropea
        
59 31e4e8ba GiuseppeTropea
        char filename[255];
60
        sprintf(filename, "audio_%s", LossTracesFilename);
61
        fp=fopen(filename, "wb");
62
        if(fp)
63
        {
64
                fclose(fp);
65
                sprintf(filename, "video_%s", LossTracesFilename);
66
                fp=fopen(filename, "wb");
67
                if(fp)
68
                        fclose(fp);
69
                else
70
                {
71
                        printf("ERROR: Unable to create loss trace files\n");
72
                        exit(1);
73
                }
74
        }
75
        else
76
        {
77
                printf("ERROR: Unable to create loss trace files\n");
78
                exit(1);
79
        }
80 dae4a53f GiuseppeTropea
81
        //this thread fetches chunks from the network by listening to the following path, port
82
        daemon = (struct MHD_Daemon*)initChunkPuller(UL_DEFAULT_EXTERNALPLAYER_PATH, HttpPort);
83
        if(daemon == NULL)
84
        {
85
                printf("CANNOT START MICROHTTPD SERVICE, EXITING...\n");
86
//                KILLALL("offerstreamer");
87
                exit(2);
88
        }
89
90 19b05fc0 GiuseppeTropea
        if(!SilentMode)
91
        {
92
                if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {
93
                        fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
94
                        return -1;
95
                }
96
        }
97
        else
98
        {
99
                if(SDL_Init(SDL_INIT_TIMER)) {
100
                        fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
101
                        return -1;
102
                }
103 1e69ae95 GiuseppeTropea
        }
104 3a240a99 GiuseppeTropea
        
105 10c75ef7 GiuseppeTropea
        if(ParseConf())
106 3a240a99 GiuseppeTropea
        {
107 10c75ef7 GiuseppeTropea
                printf("ERROR: Cannot parse configuration file, exit...\n");
108 3a240a99 GiuseppeTropea
                exit(1);
109 1e69ae95 GiuseppeTropea
        }
110 3a240a99 GiuseppeTropea
        
111 19b05fc0 GiuseppeTropea
        firstChannelIndex = -1;
112
        int it;
113
        for(it = 0; it < NChannels; it++)
114
        {
115
                if(!strcmp(Channels[it].Title, firstChannelName))
116
                {
117
                        firstChannelIndex = it;
118
                        break;
119
                }
120
        }
121
        
122
        if(firstChannelIndex < 0)
123
        {
124
                printf("Cannot find the specified channel (%s) into the configuration file (channels.conf), exiting\n");
125
                exit(0);
126
        }
127
        
128 10c75ef7 GiuseppeTropea
        if(ChunkerPlayerGUI_Init())
129 aba1367c GiuseppeTropea
        {
130 10c75ef7 GiuseppeTropea
                printf("ERROR: Cannot init player gui, exit...\n");
131
                exit(1);
132 aba1367c GiuseppeTropea
        }
133 10c75ef7 GiuseppeTropea
        
134 19b05fc0 GiuseppeTropea
        SelectedChannel = firstChannelIndex;
135 dae4a53f GiuseppeTropea
136 10c75ef7 GiuseppeTropea
        SwitchChannel(&(Channels[SelectedChannel]));
137 1e69ae95 GiuseppeTropea
138
        // Wait for user input
139 f126ff44 GiuseppeTropea
        while(!quit) {
140 34149271 GiuseppeTropea
                if(QueueFillingMode) {
141 1e69ae95 GiuseppeTropea
                        SDL_WM_SetCaption("Filling buffer...", NULL);
142 34149271 GiuseppeTropea
143 31e4e8ba GiuseppeTropea
                        if(ChunkerPlayerCore_AudioEnded())
144 10c75ef7 GiuseppeTropea
                                ChunkerPlayerCore_ResetAVQueues();
145 34149271 GiuseppeTropea
146
#ifdef DEBUG_QUEUE
147 f126ff44 GiuseppeTropea
                        //printf("QUEUE: MAIN audio:%d video:%d audiolastframe:%d videolastframe:%d\n", audioq.nb_packets, videoq.nb_packets, audioq.last_frame_extracted, videoq.last_frame_extracted);
148 34149271 GiuseppeTropea
#endif
149
                }
150 1e69ae95 GiuseppeTropea
                else
151
                        SDL_WM_SetCaption("NAPA-Wine Player", NULL);
152 34149271 GiuseppeTropea
153 f126ff44 GiuseppeTropea
                //listen for key and mouse
154
                while(SDL_PollEvent(&event)) {
155 aba1367c GiuseppeTropea
                        switch(event.type) {
156
                                case SDL_QUIT:
157
                                        quit=1;
158
                                break;
159
                                case SDL_VIDEORESIZE:
160 31e4e8ba GiuseppeTropea
                                        if(SilentMode)
161
                                                break;
162 10c75ef7 GiuseppeTropea
                                        // printf("\tSDL_VIDEORESIZE event received!! \n");
163
                                        if(!FullscreenMode)
164
                                                ChunkerPlayerGUI_HandleResize(event.resize.w, event.resize.h);
165
                                        else
166
                                                ChunkerPlayerGUI_HandleResize(FullscreenWidth, FullscreenHeight);
167 aba1367c GiuseppeTropea
                                break;
168
                                case SDL_ACTIVEEVENT:
169 31e4e8ba GiuseppeTropea
                                        if(SilentMode)
170
                                                break;
171
                                                
172 aba1367c GiuseppeTropea
                                        // if the window was iconified or restored
173 3a240a99 GiuseppeTropea
                                        if(event.active.state & SDL_APPACTIVE)
174 aba1367c GiuseppeTropea
                                        {
175
                                                //If the application is being reactivated
176
                                                if( event.active.gain != 0 )
177
                                                {
178 10c75ef7 GiuseppeTropea
                                                        ChunkerPlayerGUI_HandleGetFocus();
179 aba1367c GiuseppeTropea
                                                }
180
                                        }
181 a8be2526 GiuseppeTropea
182 aba1367c GiuseppeTropea
                                        //If something happened to the keyboard focus
183
                                        else if( event.active.state & SDL_APPINPUTFOCUS )
184
                                        {
185
                                                //If the application gained keyboard focus
186
                                                if( event.active.gain != 0 )
187
                                                {
188 10c75ef7 GiuseppeTropea
                                                        ChunkerPlayerGUI_HandleGetFocus();
189 aba1367c GiuseppeTropea
                                                }
190
                                        }
191
                                        //If something happened to the mouse focus
192
                                        else if( event.active.state & SDL_APPMOUSEFOCUS )
193
                                        {
194
                                                //If the application gained mouse focus
195
                                                if( event.active.gain != 0 )
196
                                                {
197 10c75ef7 GiuseppeTropea
                                                        ChunkerPlayerGUI_HandleGetFocus();
198 aba1367c GiuseppeTropea
                                                }
199 3a240a99 GiuseppeTropea
                                        }
200 f126ff44 GiuseppeTropea
                                        break;
201 aba1367c GiuseppeTropea
                                case SDL_MOUSEMOTION:
202 31e4e8ba GiuseppeTropea
                                        if(SilentMode)
203
                                                break;
204
                                                
205 10c75ef7 GiuseppeTropea
                                        ChunkerPlayerGUI_HandleMouseMotion(event.motion.x, event.motion.y);
206 aba1367c GiuseppeTropea
                                break;
207
                                case SDL_MOUSEBUTTONUP:
208 31e4e8ba GiuseppeTropea
                                        if(SilentMode)
209
                                                break;
210
                                                
211 aba1367c GiuseppeTropea
                                        if( event.button.button != SDL_BUTTON_LEFT )
212 78068e21 GiuseppeTropea
                                                break;
213 10c75ef7 GiuseppeTropea
214
                                        ChunkerPlayerGUI_HandleLButton(event.motion.x, event.motion.y);
215 aba1367c GiuseppeTropea
                                break;
216
                        }
217 10c75ef7 GiuseppeTropea
                        ChunkerPlayerGUI_HandleKey();
218 1e69ae95 GiuseppeTropea
                }
219 34149271 GiuseppeTropea
                usleep(120000);
220 1e69ae95 GiuseppeTropea
        }
221 fc014e26 GiuseppeTropea
        
222
        if(P2PProcessID > 0)
223
                KILL_PROCESS(P2PProcessID);
224 f9cf0a8d GiuseppeTropea
225 f126ff44 GiuseppeTropea
        //TERMINATE
226 10c75ef7 GiuseppeTropea
        ChunkerPlayerCore_Stop();
227
        if(YUVOverlay != NULL)
228
                SDL_FreeYUVOverlay(YUVOverlay);
229
        
230
        ChunkerPlayerGUI_Close();
231
        SDL_DestroyMutex(OverlayMutex);
232 26379a77 GiuseppeTropea
        SDL_Quit();
233 e810bf7b GiuseppeTropea
        finalizeChunkPuller(daemon);
234 1e69ae95 GiuseppeTropea
        return 0;
235
}
236
237 10c75ef7 GiuseppeTropea
int ParseConf()
238 78068e21 GiuseppeTropea
{
239
        int j;
240
        
241
        // PARSING CONF FILE
242
        cfg_opt_t channel_opts[] =
243
        {
244
                CFG_STR("Title", "", CFGF_NONE),
245
                CFG_STR("LaunchString", "", CFGF_NONE),
246 3a240a99 GiuseppeTropea
                CFG_INT("AudioChannels", 2, CFGF_NONE),
247
                CFG_INT("SampleRate", 48000, CFGF_NONE),
248
                CFG_INT("Width", 176, CFGF_NONE),
249
                CFG_INT("Height", 144, CFGF_NONE),
250
                CFG_FLOAT("Ratio", 1.22, CFGF_NONE),
251 78068e21 GiuseppeTropea
                CFG_END()
252
        };
253
        cfg_opt_t opts[] =
254
        {
255 569b286f GiuseppeTropea
                CFG_STR("PeerExecName", DEFAULT_CHANNEL_EXEC_NAME, CFGF_NONE),
256 78068e21 GiuseppeTropea
                CFG_SEC("Channel", channel_opts, CFGF_TITLE | CFGF_MULTI),
257
                CFG_END()
258
        };
259
        cfg_t *cfg, *cfg_channel;
260
        cfg = cfg_init(opts, CFGF_NONE);
261
        if(cfg_parse(cfg, DEFAULT_CONF_FILENAME) == CFG_PARSE_ERROR)
262
        {
263 fc014e26 GiuseppeTropea
                printf("Error while parsing configuration file, exiting...\n");
264
                return 1;
265
        }
266
        
267
        if(cfg_parse(cfg, DEFAULT_CONF_FILENAME) == CFG_FILE_ERROR)
268
        {
269
                printf("Error trying parsing configuration file. '%s' file couldn't be opened for reading\n", DEFAULT_CONF_FILENAME);
270 78068e21 GiuseppeTropea
                return 1;
271
        }
272 fc014e26 GiuseppeTropea
        
273 569b286f GiuseppeTropea
        sprintf(OfferStreamerFilename, "%s", cfg_getstr(cfg, "PeerExecName"));
274
        
275
        FILE * tmp_file;
276
        if(tmp_file = fopen(OfferStreamerFilename, "r"))
277
    {
278
        fclose(tmp_file);
279
    }
280
    else
281
        {
282
                printf("Could not find peer application (named '%s') into the current folder, please copy or link it into the player folder, then retry\n\n", OfferStreamerFilename);
283
                exit(1);
284
        }
285
        
286 78068e21 GiuseppeTropea
        for(j = 0; j < cfg_size(cfg, "Channel"); j++)
287
        {
288
                cfg_channel = cfg_getnsec(cfg, "Channel", j);
289
                sprintf(Channels[j].Title, "%s", cfg_title(cfg_channel));
290 cf26d11f GiuseppeTropea
                strcpy(Channels[j].LaunchString, cfg_getstr(cfg_channel, "LaunchString"));
291 3a240a99 GiuseppeTropea
                Channels[j].Width = cfg_getint(cfg_channel, "Width");
292
                Channels[j].Height = cfg_getint(cfg_channel, "Height");
293
                Channels[j].AudioChannels = cfg_getint(cfg_channel, "AudioChannels");
294
                Channels[j].SampleRate = cfg_getint(cfg_channel, "SampleRate");
295
                Channels[j].Ratio = cfg_getfloat(cfg_channel, "Ratio");
296 10c75ef7 GiuseppeTropea
                Channels[j].Index = j+1;
297 78068e21 GiuseppeTropea
                NChannels++;
298
        }
299
        cfg_free(cfg);
300
301 10c75ef7 GiuseppeTropea
        return 0;
302 78068e21 GiuseppeTropea
}
303
304 10c75ef7 GiuseppeTropea
int SwitchChannel(SChannel* channel)
305 78068e21 GiuseppeTropea
{
306 dae4a53f GiuseppeTropea
        int i=0;
307 10c75ef7 GiuseppeTropea
#ifdef RESTORE_SCREEN_ON_ZAPPING
308
        int was_fullscreen = FullscreenMode;
309
        int old_width = window_width, old_height = window_height;
310
#endif
311
        
312
        if(ChunkerPlayerCore_IsRunning())
313
                ChunkerPlayerCore_Stop();
314 3a240a99 GiuseppeTropea
315 fc014e26 GiuseppeTropea
        if(P2PProcessID > 0)
316
                KILL_PROCESS(P2PProcessID);
317 10c75ef7 GiuseppeTropea
        
318 e8699fac GiuseppeTropea
        ratio = channel->Ratio;
319 10c75ef7 GiuseppeTropea
        ChunkerPlayerGUI_SetChannelTitle(channel->Title);
320
        ChunkerPlayerGUI_ForceResize(channel->Width, channel->Height);
321
        
322
        ChunkerPlayerCore_SetupOverlay(channel->Width, channel->Height);
323 e8699fac GiuseppeTropea
        //ChunkerPlayerGUI_SetupOverlayRect(channel);
324 10c75ef7 GiuseppeTropea
        
325
        ChunkerPlayerCore_InitCodecs(channel->Width, channel->Height, channel->SampleRate, channel->AudioChannels);
326 3a240a99 GiuseppeTropea
                
327 78068e21 GiuseppeTropea
        char* parameters_vector[255];
328 cf26d11f GiuseppeTropea
        char argv0[255], parameters_string[511];
329 569b286f GiuseppeTropea
        sprintf(argv0, "%s", OfferStreamerFilename);
330 78068e21 GiuseppeTropea
        
331 19b05fc0 GiuseppeTropea
        sprintf(parameters_string, "%s %s %s %s %s %d %s %d", argv0, channel->LaunchString, "-C", channel->Title, "-P", (HttpPort+channel->Index), "-F", HttpPort);
332 10c75ef7 GiuseppeTropea
        
333
        printf("EXECUTING %s\n", parameters_string);
334 78068e21 GiuseppeTropea
        
335
        int par_count=0;
336
        
337
        // split parameters and count them
338
        char* pch = strtok (parameters_string, " ");
339
        
340
        while (pch != NULL)
341
        {
342
                if(par_count > 255) break;
343 cf26d11f GiuseppeTropea
                // printf ("\tpch=%s\n",pch);
344
                parameters_vector[par_count] = (char*) malloc(sizeof(char)*(strlen(pch)+1));
345 78068e21 GiuseppeTropea
                strcpy(parameters_vector[par_count], pch);
346
                pch = strtok (NULL, " ");
347
                par_count++;
348
        }
349
        parameters_vector[par_count] = NULL;
350
351 dae4a53f GiuseppeTropea
        //reset quality info
352
        channel->startTime = time(NULL);
353
        channel->instant_score = 0.0;
354
        channel->average_score = 0.0;
355
        channel->history_index = 0;
356
        for(i=0; i<CHANNEL_SCORE_HISTORY_SIZE; i++)
357
                channel->score_history[i] = -1;
358
        sprintf(channel->quality, "EVALUATING...");
359
360 78068e21 GiuseppeTropea
#ifdef __LINUX__
361
362
        int d;
363
        int stdoutS, stderrS;
364
        FILE* stream;
365
        stream = fopen("/dev/null", "a+");
366
        d = fileno(stream);
367
368
        // create backup descriptors for the current stdout and stderr devices
369
        stdoutS = dup(STDOUT_FILENO);
370
        stderrS = dup(STDERR_FILENO);
371
        
372
        // redirect child output to /dev/null
373
        dup2(d, STDOUT_FILENO);
374
        dup2(d, STDERR_FILENO);
375
376
        int pid = fork();
377
        if(pid == 0)
378 10c75ef7 GiuseppeTropea
        {
379 78068e21 GiuseppeTropea
                execv(argv0, parameters_vector);
380 10c75ef7 GiuseppeTropea
                printf("ERROR, COULD NOT LAUNCH OFFERSTREAMER\n");
381
                exit(2);
382
        }
383 78068e21 GiuseppeTropea
        else
384 fc014e26 GiuseppeTropea
                P2PProcessID = pid;
385 78068e21 GiuseppeTropea
        
386
        // restore backup descriptors in the parent process
387
        dup2(stdoutS, STDOUT_FILENO);
388
        dup2(stderrS, STDERR_FILENO);
389
        
390
        for(i=0; i<par_count; i++)
391
                free(parameters_vector[i]);
392 10c75ef7 GiuseppeTropea
                
393 cf26d11f GiuseppeTropea
        fclose(stream);
394 10c75ef7 GiuseppeTropea
395
#ifdef RESTORE_SCREEN_ON_ZAPPING
396
        if(was_fullscreen)
397
                ChunkerPlayerGUI_ToggleFullscreen();
398 cf26d11f GiuseppeTropea
        else
399 10c75ef7 GiuseppeTropea
        {
400
                ChunkerPlayerGUI_HandleResize(old_width, old_height);
401
        }
402 cf26d11f GiuseppeTropea
#endif
403
        
404 10c75ef7 GiuseppeTropea
        ChunkerPlayerCore_Play();
405 fc014e26 GiuseppeTropea
        
406 78068e21 GiuseppeTropea
        return 0;
407
#endif
408
409
        return 1;
410
}
411
412 10c75ef7 GiuseppeTropea
void ZapDown()
413 fc014e26 GiuseppeTropea
{
414 10c75ef7 GiuseppeTropea
        SelectedChannel = ((SelectedChannel+1) %NChannels);
415
        SwitchChannel(&(Channels[SelectedChannel]));
416 fc014e26 GiuseppeTropea
}
417
418 10c75ef7 GiuseppeTropea
void ZapUp()
419 3a240a99 GiuseppeTropea
{
420 10c75ef7 GiuseppeTropea
        SelectedChannel--;
421
        if(SelectedChannel < 0)
422
                SelectedChannel = NChannels-1;
423 3a240a99 GiuseppeTropea
424 10c75ef7 GiuseppeTropea
        SwitchChannel(&(Channels[SelectedChannel]));
425 3a240a99 GiuseppeTropea
}
426
427 10c75ef7 GiuseppeTropea
int enqueueBlock(const uint8_t *block, const int block_size)
428 3a240a99 GiuseppeTropea
{
429 10c75ef7 GiuseppeTropea
        return ChunkerPlayerCore_EnqueueBlocks(block, block_size);
430 3a240a99 GiuseppeTropea
}