root/rat/trunk/session.c @ 2756

Revision 2756, 26.9 KB (checked in by ucacoxh, 15 years ago)

- Changed repair interface to be the same as converter

(repair_get_count, repair_get_details).

- Added repair load setting and robustified.

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