root/rat/trunk/session.c @ 2765

Revision 2765, 26.5 KB (checked in by ucacoxh, 15 years ago)

- Consistency fixes for channel coder query functions.

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