root/rat/trunk/session.c @ 2874

Revision 2874, 25.5 KB (checked in by ucaccsp, 15 years ago)

Implement "-f codec" option in the controller. Need to update the media
engine before it'll work.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2 * FILE:    session.c
3 * PROGRAM: RAT
4 * AUTHORS: Vicky Hardman + Isidor Kouvelas + Colin Perkins + Orion Hodson
5 *
6 * $Revision$
7 * $Date$
8 *
9 * Copyright (c) 1995-98 University College London
10 * All rights reserved.
11 *
12 */
13
14#include "config_unix.h"
15#include "config_win32.h"
16#include "debug.h"
17#include "memory.h"
18#include "version.h"
19#include "session.h"
20#include "timers.h"
21#include "repair.h"
22#include "codec_types.h"
23#include "codec.h"
24#include "channel_types.h"
25#include "channel.h"
26#include "converter.h"
27#include "parameters.h"
28#include "audio.h"
29#include "pdb.h"
30#include "ui.h"
31#include "rtp.h"
32#include "source.h"
33#include "channel_types.h"
34#include "channel.h"
35
36#define PCKT_QUEUE_RTP_LEN  24
37#define PCKT_QUEUE_RTCP_LEN 12
38
39/* sanity_check_payloads checks for overlapping payload maps between
40 * channel coders and codecs.  Necessary because I don't trust myself
41 * to not overlap payloads, and other people should not have to worry
42 * about it either. [oth]
43 */
44
45static int
46sanity_check_payloads(void)
47{
48        u_int32 i, j, n_codecs, n_channels;
49        codec_id_t cid;
50        const codec_format_t *cf  = NULL;
51        const cc_details_t   *ccd = NULL;
52        cc_id_t    ccid;
53
54        u_char pt;
55
56        n_codecs = codec_get_number_of_codecs();
57        n_channels = channel_get_coder_count();
58        for(i = 0; i < n_codecs; i++) {
59                cid = codec_get_codec_number(i);
60                cf  = codec_get_format(cid);
61                pt  = codec_get_payload(cid);
62                if (pt != CODEC_PAYLOAD_DYNAMIC) {
63                        ccid = channel_coder_get_by_payload(pt);
64                        for(j = 0; j < n_channels; j++) {
65                                ccd = channel_get_coder_details(j);
66                                if (ccd == channel_get_null_coder()) {
67                                        continue;
68                                }
69                                if (ccd->descriptor == ccid) {
70                                        debug_msg("clash with %s %s payload (%d)\n", cf->long_name, ccd->name, pt);
71                                        return FALSE;
72                                }
73                        }
74                } else {
75                        /* codec is not mapped into codec space so ignore */
76                }
77        }
78        return TRUE;
79}
80
81void
82session_init(session_t *sp)
83{
84        codec_id_t                cid;
85        const codec_format_t      *cf   = NULL;
86        const converter_details_t *conv = NULL;
87        const cc_details_t        *ccd  = NULL;
88        u_int8                     i;
89
90        memset(sp, 0, sizeof(session_t));
91
92        codec_init();
93        sanity_check_payloads();
94        vu_table_init();
95
96        cid = codec_get_by_name("DVI-8K-Mono");
97        assert(cid);
98        cf  = codec_get_format(cid);
99        sp->encodings[0]                = codec_get_payload(cid);               /* user chosen encoding for primary */
100        sp->num_encodings               = 1;                                    /* Number of encodings applied */
101
102        ccd = channel_get_null_coder();
103        channel_encoder_create(ccd->descriptor, &sp->channel_coder);
104
105        conv                            = converter_get_details(0);
106        sp->converter                   = conv->id;
107        sp->clock                       = new_fast_time(GLOBAL_CLOCK_FREQ); /* this is the global clock */
108        assert(!(GLOBAL_CLOCK_FREQ % cf->format.sample_rate));               /* just in case someone adds weird freq codecs */
109        sp->mode                        = AUDIO_TOOL;   
110        sp->rtp_session_count           = 0;
111        for (i = 0; i < MAX_LAYERS; i++) {
112                sp->rx_rtp_port[i] = sp->tx_rtp_port[i] = PORT_UNINIT;
113                sp->rtp_session[i] = NULL;
114        }
115        sp->rx_rtp_port[0] = 5004; /* Default ports per:             */
116        sp->tx_rtp_port[0] = 5004; /* draft-ietf-avt-profile-new-00  */
117        sp->rx_rtcp_port   = 5005;
118        sp->tx_rtcp_port   = 5005;
119        sp->ttl                         = 16;
120        sp->filter_loopback             = TRUE;
121        sp->playing_audio               = TRUE;
122        sp->lecture                     = FALSE;
123        sp->auto_lecture                = 0;
124        sp->receive_audit_required      = FALSE;
125        sp->detect_silence              = TRUE;
126        sp->sync_on                     = FALSE;
127        sp->agc_on                      = FALSE;
128        sp->ui_on                       = TRUE;
129        sp->ui_addr                     = NULL;
130        sp->meter                       = TRUE;                                 /* Powermeter operation */
131        sp->in_file                     = NULL;
132        sp->out_file                    = NULL;
133        sp->mbus_engine_addr            = NULL;
134        sp->mbus_engine                 = NULL;
135        sp->mbus_ui_addr                = NULL;
136        sp->mbus_ui                     = NULL;
137        sp->mbus_video_addr             = "(media:video module:engine)";
138        sp->min_playout                 = 0;
139        sp->max_playout                 = 1000;
140        sp->last_depart_ts              = 1;
141        sp->loopback_gain               = 0;
142        sp->layers                      = 1;
143        sp->ui_activated                = FALSE;
144
145        source_list_create(&sp->active_sources);
146
147        sp->title = "Untitled session";
148        strcpy(sp->asc_address[0], "127.0.0.3");        /* Yeuch! This value should never be used! */
149}
150
151void
152session_exit(session_t *sp)
153{
154        codec_exit();
155        free_fast_time(sp->clock);
156        if (sp->device_clock) {
157                xfree(sp->device_clock);
158                sp->device_clock = NULL;
159        }
160        channel_encoder_destroy(&sp->channel_coder);
161        source_list_destroy(&sp->active_sources);
162}
163
164/**************************************************************************************************/
165#ifdef NDEF 
166
167static void 
168usage(void)
169{
170#ifdef WIN32
171        char win_usage[] = "\
172RAT is a multicast (or unicast) audio tool. It is best to start it\n\
173using a multicast directory tool, like sdr or multikit. If desired RAT\n\
174can be launched from the command line using:\n\n\
175rat <address>/<port>\n\n\
176where <address> is machine name, or a multicast IP address, and <port> is\n\
177the connection identifier (a number between 1024-65536).\n\n\
178For more details see:\n\n\
179http://www-mice.cs.ucl.ac.uk/multimedia/software/rat/FAQ.html\
180";
181        MessageBox(NULL, win_usage, "RAT Usage", MB_ICONINFORMATION | MB_OK);
182        WSACleanup();
183#else
184        printf("Usage: rat [options] -t <ttl> <addr>/<port>\n");
185#endif
186        exit(1);
187}
188
189
190static int 
191session_parse_early_options_common(int argc, char *argv[], session_t *sp[], int num_sessions)
192{
193        /* Parse command-line options common to all the modes of
194         * operation.  Variables: i scans through the options, s scans
195         * through the sessions This is for options set initially,
196         * before the main initialisation is done. For example, the UI
197         * is not yet setup, and anything initialised there will
198         * overwrite changes made here...  */
199
200        int lasti, i, s, args_processed = 0;
201        lasti = 0;
202        for (i = 1; i < argc; i++) {
203                if ((strcmp(argv[i], "-ui") == 0) && (argc > i+1)) {
204                        for(s = 0; s < num_sessions; s++) {
205                                sp[s]->ui_on   = FALSE;
206                                sp[s]->ui_addr = (char *) strdup(argv[i+1]);
207                        }
208                } else if (strcmp(argv[i], "-allowloopback") == 0 || strcmp(argv[i], "-allow_loopback") == 0) {
209                        for(s = 0; s < num_sessions; s++) {
210                                sp[s]->filter_loopback = FALSE;
211                        }
212                } else  if ((strcmp(argv[i], "-C") == 0) && (argc > i+1)) {
213                        for(s = 0; s < num_sessions; s++) {
214                                strncpy(sp[s]->title, argv[i+1], SESSION_TITLE_LEN);
215                        }
216                        i++;
217                } else if ((strcmp(argv[i], "-t") == 0) && (argc > i+1)) {
218                        int ttl = atoi(argv[i + 1]);
219                        if (ttl > 255) {
220                                fprintf(stderr, "ttl must be in the range 0 to 255.\n");
221                                usage();
222                        }
223                        debug_msg("Set TTL to %d\n", ttl);
224                        for(s = 0; s < num_sessions; s++) {
225                                sp[s]->ttl = ttl;
226                        }
227                        i++;
228                } else if ((strcmp(argv[i], "-p") == 0) && (argc > i+1)) {
229                        if ((thread_pri = atoi(argv[i + 1])) > 3) {
230                                usage();
231                        }
232                        i++;
233                } else if (strcmp(argv[i], "-seed") == 0) {
234                        srand48(atoi(argv[++i]));
235                } else if (strcmp(argv[i], "-codecs") == 0) {
236                        const codec_format_t *cf;
237                        codec_id_t            cid;
238                        u_int32     n_codecs, idx;
239                        u_char      pt;
240                        n_codecs = codec_get_number_of_codecs();
241                        printf("# <name> <rate> <channels> <payload>\n");
242                        for(idx = 0; idx < n_codecs; idx++) {
243                                cid = codec_get_codec_number(idx);
244                                cf  = codec_get_format(cid);
245                                pt = codec_get_payload(cid);
246                                printf("%-32s %5d %d %3d\n",
247                                       cf->long_name,
248                                       cf->format.sample_rate,
249                                       cf->format.channels,
250                                       pt);
251                        }
252                        exit(0);
253                } else if ((strcmp(argv[i], "-pt") == 0) && (argc > i+1)) {
254  /* Dynamic payload type mapping. Format: "-pt pt/codec/clock/channels" */
255  /* pt/codec must be specified. clock and channels are optional.        */
256  /* At present we only support "-pt .../redundancy"                     */
257                        int              pt  = atoi((char *) strtok(argv[i + 1], "/"));
258                        char            *t   = (char *) strtok(NULL, "/");
259                        codec_id_t       cid = codec_get_by_name(t);
260                        if (cid != 0) {
261                                codec_map_payload(cid, (u_char)pt);
262                                if (codec_get_payload(cid) != pt) {
263                                        printf("Payload %d either in use or invalid.\n", pt);
264                                }
265                        } else {
266                                printf("Codec %s not recognized, check name.\n", t);
267                        }
268                        i++;
269                } else if ((strcmp(argv[i], "-l") == 0) && (argc > i+1)) {
270                        /* Layering. Format: "-l num_layers" */
271                        int lay = atoi(argv[i+1]);
272                        if(lay > MAX_LAYERS) {
273                                debug_msg("%d is too many layers - maximum is %d.\n", lay, MAX_LAYERS);
274                                usage();
275                        }
276                        debug_msg("Configuring %d layers\n", lay);
277                        for(s = 0; s < num_sessions; s++) {
278                                sp[s]->layers = lay;
279                        }
280                        i++;
281                } else {
282                        continue;
283                }
284                args_processed += i - lasti;
285                lasti = i;
286        }
287        debug_msg("Processed %d / %d args\n", args_processed, argc);
288        return args_processed;
289}
290
291static void 
292session_parse_early_options_audio_tool(int argc, char *argv[], session_t *sp)
293{
294        /* Parse command-line options specific to the audio tool */
295        char *p;
296        u_int8 i, j;
297        u_short port[2];
298
299        if((sp->layers > 1) && (argc < 3 + sp->layers)) { /* rat -l layers address/port address/port... */
300                usage();
301        }
302
303        for (i=0; i<sp->layers; i++) {
304                p = (char *) strtok(argv[argc + i - sp->layers], "/");
305                strcpy(sp->asc_address[i], p);
306                if((p = (char *) strtok(NULL, "/")) != NULL) {
307                        sp->rx_rtp_port[i] = atoi(p);
308                        sp->rx_rtp_port[i] &= ~1;
309                       
310                        sp->tx_rtp_port[i]  = sp->rx_rtp_port[i];
311                }
312                else {
313                        usage();
314                }
315                if ((p = (char *) strtok(NULL, "/")) != NULL) {
316                        sp->tx_rtp_port[i] = atoi(p);
317                        sp->tx_rtp_port[i] &= ~1;
318                }
319                debug_msg("rx_rtp_port[%d] = %d, tx_rtp_port[%d] = %d\n", i, sp->rx_rtp_port[i], i, sp->tx_rtp_port[i]);
320        }
321        sp->rx_rtcp_port = sp->rx_rtp_port[0] + 1;
322        sp->tx_rtcp_port = sp->tx_rtp_port[0] + 1;
323
324        /* Check for conflicts */
325
326        for (i=0; i<sp->layers; i++) {
327                port[0] = sp->rx_rtp_port[i];
328                port[1] = sp->tx_rtp_port[i];
329                if(port[0] > 0xfffe || port[1] > 0xfffe) {
330#ifdef WIN32
331                        char win_err[255];
332                        sprintf(win_err, "Port should be in the range (1024-65535)");
333                        MessageBox(NULL, win_err,  "RAT - Command line error", MB_OK | MB_ICONERROR);
334#else
335                        fprintf(stderr, "Port should be in the range (1024-65535)\n");
336#endif
337
338                        exit(-1);
339                }
340                for(j=0;j<sp->layers;j++)
341                {
342                        if(i!=j && (port[0]==sp->rx_rtp_port[j] || port[0]==sp->rx_rtcp_port || port[1]==sp->tx_rtp_port[j] || port[1]==sp->tx_rtcp_port)) {
343#ifdef WIN32
344                                char win_err[255];
345                                sprintf(win_err, "Ports collide - don't forget to leave space for RTCP");
346                                MessageBox(NULL, win_err, "RAT - Command line error", MB_OK | MB_ICONERROR);
347#else
348                                fprintf(stderr, "Ports collide; don't forget to leave a space for RTCP.\n");
349#endif
350                                exit(-1);
351                        }
352                }
353        }
354}
355
356static void 
357session_parse_early_options_transcoder(int argc, char *argv[], session_t *sp[])
358{
359        /* Parse command-line options specific to the transcoder */
360        int   i, j;
361        char *p;
362
363        if (argc < 4) {
364                usage();
365        }
366
367        for (i = 0; i < 2; i++) {
368                /* addr */
369                p = (char *) strtok(argv[argc-i-1], "/");
370                strcpy(sp[i]->asc_address[0], p);
371                /* port */
372                if ((p = (char *) strtok(NULL, "/")) != NULL) {
373                        sp[i]->rx_rtp_port[0]  = atoi(p);
374                        sp[i]->rx_rtp_port[0] &= ~1;
375                        sp[i]->rx_rtcp_port = sp[i]->rx_rtp_port[0] + 1;
376
377                        sp[i]->tx_rtp_port[0]  = sp[i]->rx_rtp_port[0];
378                        sp[i]->tx_rtcp_port = sp[i]->rx_rtcp_port;
379                } else {
380                        continue;
381                }
382                /* ttl */
383                if ((p = (char *) strtok(NULL, "/")) != NULL) {
384                        sp[i]->ttl = atoi(p);
385                } else {
386                        continue;
387                }
388                /* encoding */
389                j = 0;
390                while ((p = (char *) strtok(NULL, "/")) != NULL) {
391                        codec_id_t cid;
392                        char *pu;
393                        for (pu = p; *pu; pu++)
394                                        *pu = toupper(*pu);
395                        if ((cid = codec_get_by_name(p)) == 0)
396                                usage();
397                        else {
398                                sp[i]->encodings[j]  = codec_get_payload(cid);
399                                sp[i]->num_encodings = ++j;
400                        }
401                }
402        }
403}
404
405int
406session_parse_early_options(int argc, char *argv[], session_t *sp[])
407{
408        int     i, j, num_sessions = 0;
409
410        if (argc < 2) {
411                usage();
412        }
413        /* Set the mode of operation, and number of valid sessions, based on the first command line option. */
414        if (strcmp(argv[1], "-version") == 0) {
415                printf("%s\n", RAT_VERSION);
416                exit(0);
417        } else if (strcmp(argv[1], "-T") == 0) {
418                sp[0]->mode = TRANSCODER;
419                sp[1]->mode = TRANSCODER;
420                num_sessions= 2;
421        } else {
422                sp[0]->mode = AUDIO_TOOL;
423                num_sessions= 1;
424        }
425
426        if (session_parse_early_options_common(argc, argv, sp, num_sessions) > argc - 2) {
427                /* session_parse_early_options commmon returns number of args processed.
428                 * At least two argv[0] (the appname) and argv[argc - 1] (address)
429                 * should not be processed.  Other args may not be processed, but
430                 * these should be picked up by parse_late_* or the audiotool/transcoder
431                 * specific bits.  Hopefully more people will RTFM.
432                 */
433                usage();
434        }
435
436        switch (sp[0]->mode) {
437                case AUDIO_TOOL: session_parse_early_options_audio_tool(argc, argv, sp[0]);
438                                 break;
439                case TRANSCODER: session_parse_early_options_transcoder(argc, argv, sp);
440                                 break;
441                default        : abort();
442        }
443
444        for (i=0; i<num_sessions; i++) {
445                for(j=0; j<sp[i]->layers; j++) {
446                        if (sp[i]->rx_rtp_port[j] == 0) {
447                                usage();
448                        }
449                }
450        }
451        return num_sessions;
452}
453
454/************************************************************************************************************/
455/************************************************************************************************************/
456
457static void 
458session_parse_late_options_common(int argc, char *argv[], session_t *sp[], int sp_size)
459{
460        /* Parse command-line options common to all the modes of operation.     */
461        /* Variables: i scans through the options, s scans through the sessions */
462        /* This is the final chance to set any options, before the main program */
463        /* starts. In particular, it is done after the UI has been configured.  */
464        /* Remember: if anything here changes the state of the system, you must */
465        /* update the UI too!                                                   */
466        int i, s;
467
468        for (i = 1; i < argc; i++) {
469                for (s = 0; s < sp_size; s++) {
470                        if (strcmp(argv[i], "-K") == 0) {
471                                argv[i] = "-crypt";
472                        }
473                        if ((strcmp(argv[i], "-crypt") == 0) && (argc > i+1)) {
474                                int z = 0;
475                                for(z = 0; z < sp[s]->rtp_session_count; z++) {
476                                        rtp_set_encryption_key(sp[s]->rtp_session[z], argv[i+1]);
477                                }
478                                ui_update_key(sp[s], argv[i+1]);
479                                i++;
480                        }
481                        if (strcmp(argv[i], "-sync") == 0) {
482                                sp[s]->sync_on = TRUE;
483                        }
484                        if ((strcmp(argv[i], "-agc") == 0) && (argc > i+1)) {
485                                if (strcmp(argv[i+1], "on") == 0) {
486                                        sp[s]->agc_on = TRUE;
487                                        i++;
488                                } else if (strcmp(argv[i+1], "off") == 0) {
489                                        sp[s]->agc_on = FALSE;
490                                        i++;
491                                } else {
492                                        printf("Unrecognized -agc option.\n");
493                                }
494                        }
495                        if ((strcmp(argv[i], "-silence") == 0) && (argc > i+1)) {
496                                if (strcmp(argv[i+1], "on") == 0) {
497                                        sp[s]->detect_silence = TRUE;
498                                        i++;
499                                } else if (strcmp(argv[i+1], "off") == 0) {
500                                        sp[s]->detect_silence = FALSE;
501                                        i++;
502                                } else {
503                                        printf("Unrecognized -silence option.\n");
504                                }
505                        }       
506                        if ((strcmp(argv[i], "-repair") == 0) && (argc > i+1)) {
507                                const repair_details_t* rd;
508                                u_int16 r, nr = repair_get_count();
509                                for(r = 0; r < nr; r++) {
510                                        rd = repair_get_details(r);
511                                        if (strcasecmp(argv[i+1], rd->name) == 0) {
512                                                sp[s]->repair = rd->id;
513                                        }
514                                }
515                                i++;
516                        }
517                        if ((strcmp(argv[i], "-interleave") == 0) && (argc > i+1)) {
518                                printf("%s: not supported in this release\n", argv[i]);
519                                i++;
520                        }
521                        if ((strcmp(argv[i], "-redundancy") == 0) && (argc > i+1)) {
522                                printf("%s: not supported in this release\n", argv[i]);
523                                i++;
524                        }
525                        if ((strcmp(argv[i], "-f") == 0) && (argc > i+1)) {
526                                codec_id_t primary_cid, secondary_cid;
527                                const cc_details_t *ccd;
528                                const char *primary_name, *secondary_name;
529                                u_int16 upp, num_channel_coders, idx;
530
531                                primary_name = (char *) strtok(argv[i+1], "/");
532                                primary_cid = codec_get_by_name(primary_name);
533                                if (!primary_cid) {
534                                        debug_msg("%s\n", primary_name);
535                                        primary_name = rat3codec_to_rat4codec(primary_name);
536                                        primary_cid  = codec_get_by_name(primary_name);
537                                        debug_msg("%s\n", primary_name);
538                                }
539
540                                if (primary_cid) {
541                                        sp[s]->encodings[0] = codec_get_payload(primary_cid);
542                                }
543                               
544                                secondary_name = (char *) strtok(NULL, "/");
545                                /* increment argument counter here since if we bail out
546                                 * early because of issues with secondary we need
547                                 * argument counter to be in the right place.
548                                 */
549                                i++;           
550
551                                if (secondary_name == NULL) {
552                                        /* Nothing was specified as a secondary
553                                         * save state might be redundant so...
554                                         */
555                                        upp = channel_encoder_get_units_per_packet(sp[s]->channel_coder);
556                                        ccd = channel_get_null_coder();
557                                        channel_encoder_destroy(&sp[s]->channel_coder);
558                                        channel_encoder_create(ccd->descriptor, &sp[s]->channel_coder);
559                                        channel_encoder_set_units_per_packet(sp[s]->channel_coder, upp);
560                                }
561                               
562                                secondary_cid = codec_get_by_name(secondary_name);
563
564                                if (!secondary_cid) {
565                                        debug_msg("%s\n", secondary_name);
566                                        secondary_name = rat3codec_to_rat4codec(secondary_name);
567                                        secondary_cid  = codec_get_by_name(secondary_name);
568                                        debug_msg("%s\n", secondary_name);
569                                }
570                               
571                                if (!secondary_cid) {
572                                        /* specified secondary does not exist */
573                                        debug_msg("Secondary does not exist\n");
574                                        continue;
575                                }
576                               
577                                upp = channel_encoder_get_units_per_packet(sp[s]->channel_coder);
578                                num_channel_coders = (u_int16)channel_get_coder_count();
579                                for(idx = 0; idx < num_channel_coders; idx++) {
580                                        ccd = channel_get_coder_details(idx);
581                                        /* Redundant channel coder is the only that begins with an 'r' */
582                                        if (tolower(ccd->name[0]) == 'r') {
583                                                char *cmd;
584                                                channel_encoder_destroy(&sp[s]->channel_coder);
585                                                channel_encoder_create(ccd->descriptor, &sp[s]->channel_coder);
586                                                channel_encoder_set_units_per_packet(sp[s]->channel_coder, upp);
587                                                cmd = (char*)xmalloc(2 * (CODEC_LONG_NAME_LEN + 4));
588                                                sprintf(cmd, "%s/%d/%s/%d",
589                                                        primary_name,
590                                                        0,
591                                                        secondary_name,
592                                                        1);
593                                                if (channel_encoder_set_parameters(sp[s]->channel_coder, cmd) == 0) {
594                                                        debug_msg("Red command failed: %s\n", cmd);
595                                                }
596                                                xfree(cmd);
597                                                sp[s]->num_encodings = 2;
598                                                sp[s]->encodings[1] = codec_get_payload(secondary_cid);
599                                        }
600                                }
601                        }
602                }
603        }
604}
605
606static void session_parse_late_options_audio_tool(int argc, char *argv[], session_t *sp)
607{
608        /* Audio tool specific late setup... */
609        UNUSED(argc);
610        UNUSED(argv);
611        UNUSED(sp);
612}
613
614static void session_parse_late_options_transcoder(int argc, char *argv[], session_t *sp[])
615{
616        /* Transcoder specific late setup... */
617        int     i;
618
619        UNUSED(argc);
620        UNUSED(argv);
621
622        for (i = 0; i < 2; i++) {
623                sp[i]->playing_audio = TRUE;
624                sp[i]->agc_on        = FALSE;
625        }
626}
627
628void session_parse_late_options(int argc, char *argv[], session_t *sp[])
629{
630        int     i, j, num_sessions = 0;
631
632        if (argc < 2) {
633                usage();
634        }
635        /* Set the mode of operation, and number of valid sessions, based on the first command line option. */
636        if (strcmp(argv[1], "-T") == 0) {
637                sp[0]->mode = TRANSCODER;
638                sp[1]->mode = TRANSCODER;
639                num_sessions= 2;
640        } else {
641                sp[0]->mode = AUDIO_TOOL;
642                num_sessions= 1;
643        }
644        session_parse_late_options_common(argc, argv, sp, num_sessions);
645        switch (sp[0]->mode) {
646                case AUDIO_TOOL: session_parse_late_options_audio_tool(argc, argv, sp[0]);
647                                 break;
648                case TRANSCODER: session_parse_late_options_transcoder(argc, argv, sp);
649                                 break;
650                default        : abort();
651        }
652        for (i=0; i<num_sessions; i++) {
653                for(j=0; j<sp[i]->layers; j++) {
654                        if (sp[i]->rx_rtp_port[j] == 0) {
655                                usage();
656                        }
657                }
658        }
659}
660#endif
Note: See TracBrowser for help on using the browser.