| | 95 | }; |
|---|
| | 96 | |
|---|
| | 97 | class SoutMrl |
|---|
| | 98 | { |
|---|
| | 99 | public: |
|---|
| | 100 | SoutMrl( const QString head = "") |
|---|
| | 101 | { |
|---|
| | 102 | mrl = head; |
|---|
| | 103 | b_first = true; |
|---|
| | 104 | b_has_bracket = false; |
|---|
| | 105 | } |
|---|
| | 106 | |
|---|
| | 107 | QString getMrl() |
|---|
| | 108 | { |
|---|
| | 109 | return mrl; |
|---|
| | 110 | } |
|---|
| | 111 | |
|---|
| | 112 | void begin( QString module ) |
|---|
| | 113 | { |
|---|
| | 114 | if( !b_first ) |
|---|
| | 115 | mrl += ":"; |
|---|
| | 116 | b_first = false; |
|---|
| | 117 | |
|---|
| | 118 | mrl += module; |
|---|
| | 119 | b_has_bracket = false; |
|---|
| | 120 | } |
|---|
| | 121 | void end() |
|---|
| | 122 | { |
|---|
| | 123 | if( b_has_bracket ) |
|---|
| | 124 | mrl += "}"; |
|---|
| | 125 | } |
|---|
| | 126 | void option( const QString option, const QString value = "" ) |
|---|
| | 127 | { |
|---|
| | 128 | if( !b_has_bracket ) |
|---|
| | 129 | mrl += "{"; |
|---|
| | 130 | else |
|---|
| | 131 | mrl += ","; |
|---|
| | 132 | b_has_bracket = true; |
|---|
| | 133 | |
|---|
| | 134 | mrl += option; |
|---|
| | 135 | |
|---|
| | 136 | if( !value.isEmpty() ) |
|---|
| | 137 | { |
|---|
| | 138 | char *psz = config_StringEscape( qta(value) ); |
|---|
| | 139 | if( psz ) |
|---|
| | 140 | { |
|---|
| | 141 | QString v = QString( psz ); |
|---|
| | 142 | |
|---|
| | 143 | mrl += "=\"" + v + "\""; |
|---|
| | 144 | |
|---|
| | 145 | free( psz ); |
|---|
| | 146 | } |
|---|
| | 147 | } |
|---|
| | 148 | } |
|---|
| | 149 | void option( const QString name, const int i_value, const int i_precision = 10 ) |
|---|
| | 150 | { |
|---|
| | 151 | option( name, QString::number( i_value, i_precision ) ); |
|---|
| | 152 | } |
|---|
| | 153 | void option( const QString name, const double f_value ) |
|---|
| | 154 | { |
|---|
| | 155 | option( name, QString::number( f_value ) ); |
|---|
| | 156 | } |
|---|
| | 157 | |
|---|
| | 158 | void option( const QString name, const QString base, const int i_value, const int i_precision = 10 ) |
|---|
| | 159 | { |
|---|
| | 160 | option( name, base + ":" + QString::number( i_value, i_precision ) ); |
|---|
| | 161 | } |
|---|
| | 162 | |
|---|
| | 163 | private: |
|---|
| | 164 | QString mrl; |
|---|
| | 165 | bool b_has_bracket; |
|---|
| | 166 | bool b_first; |
|---|
| 456 | | mrl = ":sout=#transcode{"; |
|---|
| 457 | | mrl.append( "vcodec=" ); |
|---|
| 458 | | mrl.append( sout.psz_vcodec ); |
|---|
| 459 | | mrl.append( "," ); |
|---|
| 460 | | mrl.append( "vb=" ); |
|---|
| 461 | | mrl.append( QString::number( sout.i_vb,10 ) ); |
|---|
| 462 | | mrl.append( "," ); |
|---|
| 463 | | mrl.append( "scale=" ); |
|---|
| 464 | | mrl.append( QString::number( sout.f_scale ) ); |
|---|
| | 532 | smrl.option( "vcodec", sout.psz_vcodec ); |
|---|
| | 533 | smrl.option( "vb", sout.i_vb ); |
|---|
| | 534 | smrl.option( "scale", sout.f_scale ); |
|---|
| 470 | | if ( trans ) |
|---|
| | 540 | smrl.option( "acodec", sout.psz_acodec ); |
|---|
| | 541 | smrl.option( "ab", sout.i_ab ); |
|---|
| | 542 | smrl.option( "channels", sout.i_channels ); |
|---|
| | 543 | trans = true; |
|---|
| | 544 | } |
|---|
| | 545 | |
|---|
| | 546 | smrl.end(); |
|---|
| | 547 | |
|---|
| | 548 | mrl = smrl.getMrl(); |
|---|
| | 549 | } |
|---|
| | 550 | |
|---|
| | 551 | /* Special case for demuxdump */ |
|---|
| | 552 | if ( sout.b_file && sout.b_dump ) |
|---|
| | 553 | { |
|---|
| | 554 | mrl = ":demux=dump :demuxdump-file="; |
|---|
| | 555 | mrl.append( sout.psz_file ); |
|---|
| | 556 | } |
|---|
| | 557 | else |
|---|
| | 558 | |
|---|
| | 559 | |
|---|
| | 560 | /* Protocol output */ |
|---|
| | 561 | if ( sout.b_local || sout.b_file || sout.b_http || |
|---|
| | 562 | sout.b_mms || sout.b_rtp || sout.b_udp || sout.b_icecast ) |
|---|
| | 563 | { |
|---|
| | 564 | if( counter > 1 ) |
|---|
| | 565 | smrl.begin( "duplicate" ); |
|---|
| | 566 | |
|---|
| | 567 | #define ADD(m) do { if( counter > 1 ) { \ |
|---|
| | 568 | smrl.option( "dst", m.getMrl() ); \ |
|---|
| | 569 | } else { \ |
|---|
| | 570 | smrl.begin( m.getMrl() ); \ |
|---|
| | 571 | smrl.end(); \ |
|---|
| | 572 | } } while(0) |
|---|
| | 573 | |
|---|
| | 574 | if ( sout.b_local ) |
|---|
| | 575 | { |
|---|
| | 576 | SoutMrl m; |
|---|
| | 577 | m.begin( "display" ); |
|---|
| | 578 | m.end(); |
|---|
| | 579 | |
|---|
| | 580 | ADD( m ); |
|---|
| | 581 | more = true; |
|---|
| | 582 | } |
|---|
| | 583 | |
|---|
| | 584 | if ( sout.b_file ) |
|---|
| | 585 | { |
|---|
| | 586 | SoutMrl m; |
|---|
| | 587 | |
|---|
| | 588 | m.begin( "std" ); |
|---|
| | 589 | m.option( "access", "file" ); |
|---|
| | 590 | if( sout.psz_mux ) |
|---|
| | 591 | m.option( "mux", sout.psz_mux ); |
|---|
| | 592 | m.option( "dst", sout.psz_file ); |
|---|
| | 593 | m.end(); |
|---|
| | 594 | |
|---|
| | 595 | ADD( m ); |
|---|
| | 596 | more = true; |
|---|
| | 597 | } |
|---|
| | 598 | |
|---|
| | 599 | if ( sout.b_http ) |
|---|
| | 600 | { |
|---|
| | 601 | SoutMrl m; |
|---|
| | 602 | |
|---|
| | 603 | m.begin( "std" ); |
|---|
| | 604 | m.option( "access", "http" ); |
|---|
| | 605 | if( sout.psz_mux ) |
|---|
| | 606 | m.option( "mux", sout.psz_mux ); |
|---|
| | 607 | m.option( "dst", sout.psz_http, sout.i_http ); |
|---|
| | 608 | m.end(); |
|---|
| | 609 | |
|---|
| | 610 | ADD( m ); |
|---|
| | 611 | more = true; |
|---|
| | 612 | } |
|---|
| | 613 | |
|---|
| | 614 | if ( sout.b_mms ) |
|---|
| | 615 | { |
|---|
| | 616 | SoutMrl m; |
|---|
| | 617 | |
|---|
| | 618 | m.begin( "std" ); |
|---|
| | 619 | m.option( "access", "mmsh" ); |
|---|
| | 620 | m.option( "mux", "asfh" ); |
|---|
| | 621 | m.option( "dst", sout.psz_mms, sout.i_mms ); |
|---|
| | 622 | m.end(); |
|---|
| | 623 | |
|---|
| | 624 | ADD( m ); |
|---|
| | 625 | more = true; |
|---|
| | 626 | } |
|---|
| | 627 | |
|---|
| | 628 | if ( sout.b_rtp ) |
|---|
| | 629 | { |
|---|
| | 630 | SoutMrl m; |
|---|
| | 631 | if ( sout.b_udp ) |
|---|
| 476 | | mrl = ":sout=#transcode{"; |
|---|
| 477 | | } |
|---|
| 478 | | mrl.append( "acodec=" ); |
|---|
| 479 | | mrl.append( sout.psz_acodec ); |
|---|
| 480 | | mrl.append( "," ); |
|---|
| 481 | | mrl.append( "ab=" ); |
|---|
| 482 | | mrl.append( QString::number( sout.i_ab,10 ) ); |
|---|
| 483 | | mrl.append( "," ); |
|---|
| 484 | | mrl.append( "channels=" ); |
|---|
| 485 | | mrl.append( QString::number( sout.i_channels,10 ) ); |
|---|
| 486 | | trans = true; |
|---|
| 487 | | } |
|---|
| 488 | | mrl.append( "}" ); |
|---|
| 489 | | } |
|---|
| 490 | | |
|---|
| 491 | | /* Special case for demuxdump */ |
|---|
| 492 | | if ( sout.b_file && sout.b_dump ) |
|---|
| 493 | | { |
|---|
| 494 | | mrl = ":demux=dump :demuxdump-file="; |
|---|
| 495 | | mrl.append( sout.psz_file ); |
|---|
| 496 | | } |
|---|
| 497 | | else |
|---|
| 498 | | |
|---|
| 499 | | |
|---|
| 500 | | /* Protocol output */ |
|---|
| 501 | | if ( sout.b_local || sout.b_file || sout.b_http || |
|---|
| 502 | | sout.b_mms || sout.b_rtp || sout.b_udp || sout.b_icecast ) |
|---|
| 503 | | { |
|---|
| 504 | | |
|---|
| 505 | | #define ISMORE() if ( more ) mrl.append( "," ) |
|---|
| 506 | | #define ATLEASTONE() if ( counter ) mrl.append( "dst=" ) |
|---|
| 507 | | |
|---|
| 508 | | #define CHECKMUX() \ |
|---|
| 509 | | if( sout.psz_mux ) \ |
|---|
| 510 | | { \ |
|---|
| 511 | | mrl.append( ",mux=");\ |
|---|
| 512 | | mrl.append( sout.psz_mux ); \ |
|---|
| 513 | | } |
|---|
| 514 | | |
|---|
| 515 | | if ( trans ) |
|---|
| 516 | | mrl.append( ":" ); |
|---|
| 517 | | else |
|---|
| 518 | | mrl = ":sout=#"; |
|---|
| 519 | | |
|---|
| 520 | | if ( counter ) |
|---|
| 521 | | mrl.append( "duplicate{" ); |
|---|
| 522 | | |
|---|
| 523 | | if ( sout.b_local ) |
|---|
| 524 | | { |
|---|
| 525 | | ISMORE(); |
|---|
| 526 | | ATLEASTONE(); |
|---|
| 527 | | mrl.append( "display" ); |
|---|
| 528 | | more = true; |
|---|
| 529 | | } |
|---|
| 530 | | |
|---|
| 531 | | if ( sout.b_file ) |
|---|
| 532 | | { |
|---|
| 533 | | ISMORE(); |
|---|
| 534 | | ATLEASTONE(); |
|---|
| 535 | | mrl.append( "std{access=file" ); |
|---|
| 536 | | CHECKMUX(); |
|---|
| 537 | | mrl.append( ",dst=" ); |
|---|
| 538 | | mrl.append( sout.psz_file ); |
|---|
| 539 | | mrl.append( "}" ); |
|---|
| 540 | | more = true; |
|---|
| 541 | | } |
|---|
| 542 | | |
|---|
| 543 | | if ( sout.b_http ) |
|---|
| 544 | | { |
|---|
| 545 | | ISMORE(); |
|---|
| 546 | | ATLEASTONE(); |
|---|
| 547 | | mrl.append( "std{access=http" ); |
|---|
| 548 | | CHECKMUX(); |
|---|
| 549 | | mrl.append( ",dst=" ); |
|---|
| 550 | | mrl.append( sout.psz_http ); |
|---|
| 551 | | mrl.append( ":" ); |
|---|
| 552 | | mrl.append( QString::number( sout.i_http,10 ) ); |
|---|
| 553 | | mrl.append( "}" ); |
|---|
| 554 | | more = true; |
|---|
| 555 | | } |
|---|
| 556 | | |
|---|
| 557 | | if ( sout.b_mms ) |
|---|
| 558 | | { |
|---|
| 559 | | ISMORE(); |
|---|
| 560 | | ATLEASTONE(); |
|---|
| 561 | | mrl.append( "std{access=mmsh" ); |
|---|
| 562 | | CHECKMUX(); |
|---|
| 563 | | mrl.append( ",dst=" ); |
|---|
| 564 | | mrl.append( sout.psz_mms ); |
|---|
| 565 | | mrl.append( ":" ); |
|---|
| 566 | | mrl.append( QString::number( sout.i_mms,10 ) ); |
|---|
| 567 | | mrl.append( "}" ); |
|---|
| 568 | | more = true; |
|---|
| 569 | | } |
|---|
| 570 | | |
|---|
| 571 | | if ( sout.b_rtp ) |
|---|
| 572 | | { |
|---|
| 573 | | ISMORE(); |
|---|
| 574 | | ATLEASTONE(); |
|---|
| 575 | | if ( sout.b_udp ) |
|---|
| 576 | | { |
|---|
| 577 | | mrl.append( "std{access=udp" ); |
|---|
| 578 | | CHECKMUX(); |
|---|
| 579 | | mrl.append( ",dst=" ); |
|---|
| 580 | | mrl.append( sout.psz_udp ); |
|---|
| 581 | | mrl.append( ":" ); |
|---|
| 582 | | mrl.append( QString::number( sout.i_udp,10 ) ); |
|---|
| 583 | | } |
|---|
| 584 | | else |
|---|
| 585 | | { |
|---|
| 586 | | mrl.append( "rtp{" ); |
|---|
| 587 | | mrl.append( "dst=" ); |
|---|
| 588 | | mrl.append( sout.psz_rtp ); |
|---|
| 589 | | CHECKMUX(); |
|---|
| 590 | | mrl.append( ",port=" ); |
|---|
| 591 | | mrl.append( QString::number( sout.i_rtp,10 ) ); |
|---|
| | 641 | m.begin( "rtp" ); |
|---|
| | 642 | |
|---|
| | 643 | if( sout.psz_rtp && *sout.psz_rtp ) |
|---|
| | 644 | m.option( "dst", sout.psz_rtp ); |
|---|
| | 645 | if( sout.psz_mux ) |
|---|
| | 646 | m.option( "mux", sout.psz_mux ); |
|---|
| | 647 | |
|---|
| | 648 | m.option( "port", sout.i_rtp ); |
|---|
| 594 | | mrl.append( ",port-audio=" ); |
|---|
| 595 | | mrl.append( QString::number( sout.i_rtp_audio, 10 ) ); |
|---|
| 596 | | mrl.append( ",port-video=" ); |
|---|
| 597 | | mrl.append( QString::number( sout.i_rtp_video, 10 ) ); |
|---|
| | 651 | m.option( "port-audio", sout.i_rtp_audio ); |
|---|
| | 652 | m.option( "port-video", sout.i_rtp_video ); |
|---|
| 619 | | ISMORE(); |
|---|
| 620 | | ATLEASTONE(); |
|---|
| 621 | | mrl.append( "std{access=shout,mux=ogg" ); |
|---|
| 622 | | mrl.append( ",dst=" ); |
|---|
| 623 | | mrl.append( sout.sa_icecast.psz_username ); |
|---|
| 624 | | mrl.append( "@" ); |
|---|
| 625 | | mrl.append( sout.psz_icecast ); |
|---|
| 626 | | mrl.append( ":" ); |
|---|
| 627 | | mrl.append( QString::number( sout.i_icecast, 10 ) ); |
|---|
| 628 | | mrl.append( "/" ); |
|---|
| 629 | | mrl.append( sout.psz_icecast_mountpoint ); |
|---|
| 630 | | mrl.append( "}" ); |
|---|
| | 671 | SoutMrl m; |
|---|
| | 672 | QString url; |
|---|
| | 673 | |
|---|
| | 674 | url = QString(sout.sa_icecast.psz_username) + "@" + sout.psz_icecast + ":" + |
|---|
| | 675 | QString::number( sout.i_icecast, 10 ) + "/" + sout.psz_icecast_mountpoint; |
|---|
| | 676 | |
|---|
| | 677 | m.begin( "std" ); |
|---|
| | 678 | m.option( "access", "shout" ); |
|---|
| | 679 | m.option( "mux", "ogg" ); |
|---|
| | 680 | m.option( "dst", url ); |
|---|
| | 681 | m.end(); |
|---|
| | 682 | |
|---|
| | 683 | ADD( m ); |
|---|