output.m
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:25k
源码类别:

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * output.m: MacOS X Output Dialog
  3.  *****************************************************************************
  4.  * Copyright (C) 2002-2003 VideoLAN
  5.  * $Id: output.m 8405 2004-08-08 14:49:46Z bigben $
  6.  *
  7.  * Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
  8.  *          Christophe Massiot <massiot@via.ecp.fr>
  9.  *          Derk-Jan Hartman <thedj@users.sourceforge.net>
  10.  *          Benjamin Pracht <bigben AT videolan DOT org>
  11.  *
  12.  * This program is free software; you can redistribute it and/or modify
  13.  * it under the terms of the GNU General Public License as published by
  14.  * the Free Software Foundation; either version 2 of the License, or
  15.  * (at your option) any later version.
  16.  *
  17.  * This program is distributed in the hope that it will be useful,
  18.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20.  * GNU General Public License for more details.
  21.  *
  22.  * You should have received a copy of the GNU General Public License
  23.  * along with this program; if not, write to the Free Software
  24.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  25.  *****************************************************************************/
  26. /*****************************************************************************
  27.  * Preamble
  28.  *****************************************************************************/
  29. #include <stdlib.h>                                      /* malloc(), free() */
  30. #include <string.h>
  31. #include "intf.h"
  32. #include "output.h"
  33. /*****************************************************************************
  34.  * VLCOutput implementation 
  35.  *****************************************************************************/
  36. @implementation VLCOutput
  37. - (id)init
  38. {
  39.     self = [super init];
  40.     o_mrl = [[NSArray alloc] init];
  41.     o_transcode = [[NSString alloc] init];
  42.     return self;
  43. }
  44. - (void)dealloc
  45. {
  46.     [o_mrl release];
  47.     [o_transcode release];
  48.     [super dealloc];
  49. }
  50. - (void)setMRL:(NSArray *)o_mrl_array
  51. {
  52.     [o_mrl autorelease];
  53.     o_mrl = [o_mrl_array copy];
  54. }
  55. - (NSArray *)getMRL
  56. {
  57.     return [o_mrl copy];
  58. }
  59. - (void)setTranscode:(NSString *)o_transcode_string
  60. {
  61.     [o_transcode autorelease];
  62.     o_transcode = [o_transcode_string copy];
  63. }
  64. - (void)awakeFromNib
  65. {
  66.     [self initStrings];
  67.     [[NSNotificationCenter defaultCenter] addObserver: self
  68.         selector: @selector(outputInfoChanged:)
  69.         name: NSControlTextDidChangeNotification
  70.         object: o_file_field];
  71.     [[NSNotificationCenter defaultCenter] addObserver: self
  72.         selector: @selector(outputInfoChanged:)
  73.         name: NSControlTextDidChangeNotification
  74.         object: o_stream_address];
  75.     [[NSNotificationCenter defaultCenter] addObserver: self
  76.         selector: @selector(outputInfoChanged:)
  77.         name: NSControlTextDidChangeNotification
  78.         object: o_stream_port];
  79.     [[NSNotificationCenter defaultCenter] addObserver: self
  80.         selector: @selector(TTLChanged:)
  81.         name: NSControlTextDidChangeNotification
  82.         object: o_stream_ttl];
  83.     [[NSNotificationCenter defaultCenter] addObserver: self
  84.         selector: @selector(transcodeInfoChanged:)
  85.         name: NSControlTextDidChangeNotification
  86.         object: o_transcode_video_bitrate];
  87.     [[NSNotificationCenter defaultCenter] addObserver: self
  88.         selector: @selector(transcodeInfoChanged:)
  89.         name: NSControlTextDidChangeNotification
  90.         object: o_transcode_video_scale];
  91.     [[NSNotificationCenter defaultCenter] addObserver: self
  92.         selector: @selector(transcodeInfoChanged:)
  93.         name: NSControlTextDidChangeNotification
  94.         object: o_transcode_audio_bitrate];
  95.     [[NSNotificationCenter defaultCenter] addObserver: self
  96.         selector: @selector(transcodeInfoChanged:)
  97.         name: NSControlTextDidChangeNotification
  98.         object: o_transcode_audio_channels];
  99.     [[NSNotificationCenter defaultCenter] addObserver: self
  100.         selector: @selector(transcodeInfoChanged:)
  101.         name: NSControlTextDidChangeNotification
  102.         object: o_channel_name];
  103.     [[NSNotificationCenter defaultCenter] addObserver: self
  104.         selector: @selector(transcodeInfoChanged:)
  105.         name: NSControlTextDidChangeNotification
  106.         object: o_sdp_url];
  107.     [o_mux_selector setAutoenablesItems: NO];
  108.     [self transcodeChanged:nil];
  109. }
  110. - (void)initStrings
  111. {
  112.     NSArray *o_muxers = [NSArray arrayWithObjects: @"MPEG TS", @"MPEG PS", @"MPEG 1",
  113.         @"Ogg", @"AVI", @"ASF", @"MPEG 4", @"Quicktime", @"Raw", nil];
  114.     NSArray *o_a_channels = [NSArray arrayWithObjects: @"1", @"2", @"4", @"6", nil];
  115.     NSArray *o_a_bitrates = [NSArray arrayWithObjects: @"16", @"32", @"64", @"96",
  116.         @"128", @"192", @"256", @"512", nil];
  117.     NSArray *o_v_bitrates = [NSArray arrayWithObjects: @"16", @"32", @"64", @"96",
  118.         @"128", @"192", @"256", @"384", @"512", @"768", @"1024", @"2048", @"3072", nil];
  119.     NSArray *o_v_scales = [NSArray arrayWithObjects: @"0.25",@"0.5",@"0.75",@"1",@"1.25",@"1.5",@"1.75",@"2",nil];
  120.     NSArray *o_a_codecs = [NSArray arrayWithObjects: @"mpga", @"mp3 ", @"mp4a", @"a52 ", @"vorb", @"flac", @"spx ", nil];
  121.     NSArray *o_v_codecs = [NSArray arrayWithObjects: @"mp1v", @"mp2v", @"mp4v", @"DIV1",
  122.         @"DIV2", @"DIV3", @"H263", @"I263", @"WMV1", @"WMV2", @"MJPG", @"theo", nil];
  123.     [o_output_ckbox setTitle: _NS("Advanced output:")];
  124.     [o_output_settings setTitle: _NS("Settings...")];
  125.     [o_btn_ok setTitle: _NS("OK")];
  126.     [o_options_lbl setTitle: _NS("Output Options")];
  127.     [o_display setTitle: _NS("Play locally")];
  128.     [[o_method cellAtRow:0 column:0] setTitle: _NS("File")];
  129.     [[o_method cellAtRow:1 column:0] setTitle: _NS("Stream")];
  130.     [o_dump_chkbox setTitle: _NS("Dump raw input")];
  131.     [o_btn_browse setTitle: _NS("Browse...")]; 
  132.     [o_stream_address_lbl setStringValue: _NS("Address")];
  133.     [o_stream_port_lbl setStringValue: _NS("Port")];
  134.     [o_stream_ttl_lbl setStringValue: @"TTL"];
  135.     [[o_stream_type itemAtIndex: 0] setTitle: @"HTTP"];
  136.     [[o_stream_type itemAtIndex: 1] setTitle: @"MMSH"];
  137.     [[o_stream_type itemAtIndex: 2] setTitle: @"UDP"];
  138.     [[o_stream_type itemAtIndex: 3] setTitle: @"RTP"];
  139.     [o_stream_type_lbl setStringValue: _NS("Type")];
  140.     [o_mux_lbl setStringValue: _NS("Encapsulation Method")];
  141.     [o_mux_selector removeAllItems];
  142.     [o_mux_selector addItemsWithTitles: o_muxers];
  143.     [o_transcode_lbl setTitle: _NS("Transcode options")];
  144.     [o_transcode_video_chkbox setTitle: _NS("Video")];
  145.     [o_transcode_video_selector removeAllItems];
  146.     [o_transcode_video_selector addItemsWithTitles: o_v_codecs];
  147.     [o_transcode_video_bitrate_lbl setStringValue: _NS("Bitrate (kb/s)")];
  148.     [o_transcode_video_bitrate removeAllItems];
  149.     [o_transcode_video_bitrate addItemsWithObjectValues: o_v_bitrates];
  150.     [o_transcode_video_scale_lbl setStringValue: _NS("Scale")];
  151.     [o_transcode_video_scale removeAllItems];
  152.     [o_transcode_video_scale addItemsWithObjectValues: o_v_scales];
  153.     [o_transcode_video_scale selectItemWithObjectValue: @"1"];
  154.     [o_transcode_audio_chkbox setTitle: _NS("Audio")];
  155.     [o_transcode_audio_selector removeAllItems];
  156.     [o_transcode_audio_selector addItemsWithTitles: o_a_codecs];
  157.     [o_transcode_audio_bitrate_lbl setStringValue: _NS("Bitrate (kb/s)")];
  158.     [o_transcode_audio_bitrate removeAllItems];
  159.     [o_transcode_audio_bitrate addItemsWithObjectValues: o_a_bitrates];
  160.     [o_transcode_audio_channels_lbl setStringValue: _NS("Channels")];
  161.     [o_transcode_audio_channels removeAllItems];
  162.     [o_transcode_audio_channels addItemsWithObjectValues: o_a_channels];
  163.     [o_misc_lbl setTitle: _NS("Stream Announcing")];
  164.     [o_sap_chkbox setTitle: _NS("SAP announce")];
  165.     [o_slp_chkbox setTitle: _NS("SLP announce")];
  166.     [o_rtsp_chkbox setTitle: _NS("RTSP announce")];
  167.     [o_http_chkbox setTitle:_NS("HTTP announce")];
  168.     [o_file_chkbox setTitle:_NS("Export SDP as file")];
  169.     [o_channel_name_lbl setStringValue: _NS("Channel Name")];
  170.     [o_sdp_url_lbl setStringValue: _NS("SDP URL")];
  171. }
  172. - (IBAction)outputChanged:(id)sender;
  173. {
  174.     if ([o_output_ckbox state] == NSOnState)
  175.     {
  176.         [o_output_settings setEnabled:YES];
  177.     }
  178.     else
  179.     {
  180.         [o_output_settings setEnabled:NO];
  181.     }
  182. }
  183. - (IBAction)outputSettings:(id)sender
  184. {
  185.     [NSApp beginSheet: o_output_sheet
  186.         modalForWindow: o_open_panel
  187.         modalDelegate: self
  188.         didEndSelector: NULL
  189.         contextInfo: nil];
  190. }
  191. - (IBAction)outputCloseSheet:(id)sender
  192. {
  193.     [o_output_sheet orderOut:sender];
  194.     [NSApp endSheet: o_output_sheet];
  195. }
  196. - (void)outputMethodChanged:(NSNotification *)o_notification
  197. {
  198.     NSString *o_mode;
  199.     o_mode = [[o_method selectedCell] title];
  200.     [o_sap_chkbox setEnabled: NO];
  201.     [o_slp_chkbox setEnabled: NO];
  202.     [o_http_chkbox setEnabled: NO];
  203.     [o_rtsp_chkbox setEnabled: NO];
  204.     [o_file_chkbox setEnabled: NO];
  205.     [o_channel_name setEnabled: NO];
  206.     [o_sdp_url setEnabled: NO];
  207.     [[o_mux_selector itemAtIndex: 0] setEnabled: YES];
  208.     if( [o_mode isEqualToString: _NS("File")] )
  209.     {
  210.         [o_file_field setEnabled: YES];
  211.         [o_btn_browse setEnabled: YES];
  212.         [o_dump_chkbox setEnabled: YES];
  213.         [o_stream_address setEnabled: NO];
  214.         [o_stream_port setEnabled: NO];
  215.         [o_stream_ttl setEnabled: NO];
  216.         [o_stream_port_stp setEnabled: NO];
  217.         [o_stream_ttl_stp setEnabled: NO];
  218.         [o_stream_type setEnabled: NO];
  219.         [o_mux_selector setEnabled: YES];
  220.         [[o_mux_selector itemAtIndex: 1] setEnabled: YES]; // MPEG PS
  221.         [[o_mux_selector itemAtIndex: 2] setEnabled: YES]; // MPEG 1
  222.         [[o_mux_selector itemAtIndex: 3] setEnabled: YES]; // Ogg
  223.         [[o_mux_selector itemAtIndex: 4] setEnabled: YES]; // AVI
  224.         [[o_mux_selector itemAtIndex: 5] setEnabled: YES]; // ASF
  225.         [[o_mux_selector itemAtIndex: 6] setEnabled: YES]; // MPEG 4
  226.         [[o_mux_selector itemAtIndex: 7] setEnabled: YES]; // QuickTime
  227.         [[o_mux_selector itemAtIndex: 8] setEnabled: YES]; // Raw
  228.     }
  229.     else if( [o_mode isEqualToString: _NS("Stream")] )
  230.     {
  231.         [o_file_field setEnabled: NO];
  232.         [o_dump_chkbox setEnabled: NO];
  233.         [o_btn_browse setEnabled: NO];
  234.         [o_stream_port setEnabled: YES];
  235.         [o_stream_port_stp setEnabled: YES];
  236.         [o_stream_type setEnabled: YES];
  237.         [o_mux_selector setEnabled: YES];
  238.         o_mode = [o_stream_type titleOfSelectedItem];
  239.         if( [o_mode isEqualToString: @"HTTP"] )
  240.         {
  241.             [o_stream_address setEnabled: YES];
  242.             [o_stream_ttl setEnabled: NO];
  243.             [o_stream_ttl_stp setEnabled: NO];
  244.             [[o_mux_selector itemAtIndex: 1] setEnabled: YES];
  245.             [[o_mux_selector itemAtIndex: 2] setEnabled: YES];
  246.             [[o_mux_selector itemAtIndex: 3] setEnabled: YES];
  247.             [[o_mux_selector itemAtIndex: 4] setEnabled: NO];
  248.             [[o_mux_selector itemAtIndex: 5] setEnabled: YES];
  249.             [[o_mux_selector itemAtIndex: 6] setEnabled: NO];
  250.             [[o_mux_selector itemAtIndex: 7] setEnabled: NO];
  251.             [[o_mux_selector itemAtIndex: 8] setEnabled: YES];
  252.         }
  253.         else if( [o_mode isEqualToString: @"MMSH"] )
  254.         {
  255.             [o_stream_address setEnabled: YES];
  256.             [o_stream_ttl setEnabled: NO];
  257.             [o_stream_ttl_stp setEnabled: NO];
  258.             [[o_mux_selector itemAtIndex: 0] setEnabled: NO];
  259.             [[o_mux_selector itemAtIndex: 1] setEnabled: NO];
  260.             [[o_mux_selector itemAtIndex: 2] setEnabled: NO];
  261.             [[o_mux_selector itemAtIndex: 3] setEnabled: NO];
  262.             [[o_mux_selector itemAtIndex: 4] setEnabled: NO];
  263.             [[o_mux_selector itemAtIndex: 5] setEnabled: YES];
  264.             [[o_mux_selector itemAtIndex: 6] setEnabled: NO];
  265.             [[o_mux_selector itemAtIndex: 7] setEnabled: NO];
  266.             [[o_mux_selector itemAtIndex: 8] setEnabled: NO];
  267.             [o_mux_selector selectItemAtIndex: 5];
  268.         }
  269.         else if( [o_mode isEqualToString: @"UDP"] )
  270.         {
  271.             [o_stream_address setEnabled: YES];
  272.             [o_stream_ttl setEnabled: YES];
  273.             [o_stream_ttl_stp setEnabled: YES];
  274.             [[o_mux_selector itemAtIndex: 1] setEnabled: NO];
  275.             [[o_mux_selector itemAtIndex: 2] setEnabled: NO];
  276.             [[o_mux_selector itemAtIndex: 3] setEnabled: NO];
  277.             [[o_mux_selector itemAtIndex: 4] setEnabled: NO];
  278.             [[o_mux_selector itemAtIndex: 5] setEnabled: NO];
  279.             [[o_mux_selector itemAtIndex: 6] setEnabled: NO];
  280.             [[o_mux_selector itemAtIndex: 7] setEnabled: NO];
  281.             [[o_mux_selector itemAtIndex: 8] setEnabled: YES];
  282.             [o_sap_chkbox setEnabled: YES];
  283.             [o_slp_chkbox setEnabled: YES];
  284.             [o_channel_name setEnabled: YES];
  285.         }
  286.         else if( [o_mode isEqualToString: @"RTP"] )
  287.         {
  288.             [o_stream_address setEnabled: YES];
  289.             [o_stream_ttl setEnabled: YES];
  290.             [o_stream_ttl_stp setEnabled: YES];
  291.             [[o_mux_selector itemAtIndex: 0] setEnabled: NO];
  292.             [[o_mux_selector itemAtIndex: 1] setEnabled: NO];
  293.             [[o_mux_selector itemAtIndex: 2] setEnabled: NO];
  294.             [[o_mux_selector itemAtIndex: 3] setEnabled: NO];
  295.             [[o_mux_selector itemAtIndex: 4] setEnabled: NO];
  296.             [[o_mux_selector itemAtIndex: 5] setEnabled: NO];
  297.             [[o_mux_selector itemAtIndex: 6] setEnabled: NO];
  298.             [[o_mux_selector itemAtIndex: 7] setEnabled: NO];
  299.             [[o_mux_selector itemAtIndex: 8] setEnabled: YES];
  300.             [o_mux_selector selectItemAtIndex: 8];
  301.             [o_sap_chkbox setEnabled: YES];
  302.             [o_slp_chkbox setEnabled: NO];
  303.             [o_rtsp_chkbox setEnabled: YES];
  304.             [o_http_chkbox setEnabled: YES];
  305.             [o_file_chkbox setEnabled: YES];
  306.             [o_channel_name setEnabled: YES];
  307.         }
  308.     }
  309.     if( ![[o_mux_selector selectedItem] isEnabled] && ![o_mode isEqualToString: @"RTP"] )
  310.     {
  311.         [o_mux_selector selectItemAtIndex: 0];
  312.     }
  313.     else if (![[o_mux_selector selectedItem] isEnabled] && [o_mode isEqualToString: @"RTP"] )
  314.     {
  315.         [o_mux_selector selectItemAtIndex: 8];
  316.     }
  317.     [self outputInfoChanged: nil];
  318. }
  319. - (void)outputInfoChanged:(NSNotification *)o_notification
  320. {
  321.     NSString *o_mode, *o_mux, *o_mux_string;
  322.     NSMutableString *o_announce = [NSMutableString stringWithString:@""];
  323.     NSMutableString *o_mrl_string = [NSMutableString stringWithString:@":sout=#"];
  324.     NSArray *o_sout_options;
  325.     [o_mrl_string appendString: o_transcode];
  326.     if( [o_display state] == NSOnState )
  327.     {
  328.         [o_mrl_string appendString: @"duplicate{dst=display,dst="];
  329.     }
  330.     o_mode = [[o_method selectedCell] title];
  331.     o_mux = [o_mux_selector titleOfSelectedItem];
  332.     if ( [o_mux isEqualToString: @"AVI"] ) o_mux_string = @"avi";
  333.     else if ( [o_mux isEqualToString: @"Ogg"] ) o_mux_string = @"ogg";
  334.     else if ( [o_mux isEqualToString: @"MPEG PS"] ) o_mux_string = @"ps";
  335.     else if ( [o_mux isEqualToString: @"MPEG 4"] ) o_mux_string = @"mp4";
  336.     else if ( [o_mux isEqualToString: @"MPEG 1"] ) o_mux_string = @"mpeg1";
  337.     else if ( [o_mux isEqualToString: @"Quicktime"] ) o_mux_string = @"mov";
  338.     else if ( [o_mux isEqualToString: @"ASF"] ) o_mux_string = @"asf";
  339.     else if ( [o_mux isEqualToString: @"Raw"] ) o_mux_string = @"raw";
  340.     else o_mux_string = @"ts";
  341.     if( [o_mode isEqualToString: _NS("File")] )
  342.     {
  343.         if( [o_dump_chkbox state] == NSOnState )
  344.         {
  345.             NSMutableArray * o_sout_options;
  346.             o_sout_options = [NSArray arrayWithObjects:
  347.                                     [NSString stringWithString:
  348.                                     @":demux=dump"],
  349.                                     [NSString stringWithFormat:
  350.                                     @":demuxdump-file=%@",
  351.                                     [o_file_field stringValue]],
  352.                                     nil];
  353.             [self setMRL:o_sout_options];
  354.             return;
  355.         }
  356.         else
  357.         {
  358.                 [o_mrl_string appendFormat:
  359.                         @"std{access=file,mux=%@,url="%@"}",
  360.                         o_mux_string, [o_file_field stringValue]];
  361.         }
  362.     }
  363.     else if( [o_mode isEqualToString: _NS("Stream")] )
  364.     {
  365.         o_mode = [o_stream_type titleOfSelectedItem];
  366.         if ( [o_mode isEqualToString: @"HTTP"] )
  367.             o_mode = @"http";
  368.         else if ( [o_mode isEqualToString: @"MMSH"] )
  369.         {
  370.             if ( [o_mux isEqualToString: @"ASF"] ) o_mux_string = @"asfh";
  371.             o_mode = @"mmsh";
  372.         }
  373.         else if ( [o_mode isEqualToString: @"UDP"] )
  374.         {
  375.             o_mode = @"udp";
  376.             if( [o_sap_chkbox state] == NSOnState )
  377.             {
  378.                 if ( ![[o_channel_name stringValue] isEqualToString: @""] )
  379.                     [o_announce appendFormat:
  380.                         @",sap,name=%@", [o_channel_name stringValue]];
  381.                 else
  382.                     [o_announce appendFormat:@",sap"];
  383.             }
  384.             if( [o_slp_chkbox state] == NSOnState )
  385.             {
  386.                if ( ![[o_channel_name stringValue] isEqualToString: @""] )
  387.                     [o_announce appendFormat:@
  388.                             "slp,name=%@",[o_channel_name stringValue]];
  389.                 else
  390.                     [o_announce appendString: @",slp"];
  391.             }
  392.         }
  393.         if ( ![o_mode isEqualToString: @"RTP"] )
  394.         {
  395.             [o_mrl_string appendFormat:
  396.                         @"std{access=%@,mux=%@,url="%@:%@"%@}",
  397.                         o_mode, o_mux_string, [o_stream_address stringValue],
  398.                         [o_stream_port stringValue], o_announce];
  399.         }
  400.         else
  401.         {
  402.             NSString * o_stream_name;
  403.             if (![[o_channel_name stringValue] isEqualToString: @""] )
  404.             {
  405.                 o_stream_name = [NSString stringWithFormat:@",name=%@",
  406.                                 [o_channel_name stringValue]];
  407.             }
  408.             else
  409.             {
  410.                 o_stream_name = @"";
  411.             }
  412.             if ( [o_sap_chkbox state] == NSOnState )
  413.             {
  414.                 [o_announce appendString: @",sdp=sap"];
  415.             }
  416.             if ([o_rtsp_chkbox state] == NSOnState )
  417.             {
  418.                 [o_announce appendFormat:@",sdp="rtsp://%@"",[o_sdp_url stringValue]];
  419.             }
  420.             if ([o_http_chkbox state] == NSOnState )
  421.             {
  422.                 [o_announce appendFormat:@",sdp="http://%@"",[o_sdp_url stringValue]];
  423.             }
  424.             if ([o_file_chkbox state] == NSOnState )
  425.             {
  426.                 [o_announce appendFormat:@",sdp="file://%@"",[o_sdp_url stringValue]];
  427.             }
  428.             [o_mrl_string appendFormat:
  429.                         @"rtp{dst="%@",port=%@%@%@}",[o_stream_address stringValue],
  430.                         [o_stream_port stringValue], o_stream_name, o_announce];
  431.         }
  432.     }
  433.     if( [o_display state] == NSOnState )
  434.     {
  435.         [o_mrl_string appendString: @"}"];
  436.     }
  437.     o_sout_options = [NSArray arrayWithObjects: o_mrl_string,nil];
  438.     [self setMRL:o_sout_options];
  439. }
  440. - (void)TTLChanged:(NSNotification *)o_notification
  441. {
  442.     intf_thread_t * p_intf = VLCIntf;
  443.     config_PutInt( p_intf, "ttl", [o_stream_ttl intValue] );
  444. }
  445. - (IBAction)outputFileBrowse:(id)sender
  446. {
  447.     NSSavePanel *o_save_panel = [NSSavePanel savePanel];
  448.     NSString *o_mux_string;
  449.     if ( [[o_mux_selector titleOfSelectedItem] isEqualToString: @"MPEG PS"] )
  450.         o_mux_string = @"vob";
  451.     else if ( [[o_mux_selector titleOfSelectedItem] isEqualToString: @"MPEG 1"] )
  452.         o_mux_string = @"mpg";
  453.     else if ( [[o_mux_selector titleOfSelectedItem] isEqualToString: @"AVI"] )
  454.         o_mux_string = @"avi";
  455.     else if ( [[o_mux_selector titleOfSelectedItem] isEqualToString: @"ASF"] )
  456.         o_mux_string = @"asf";
  457.     else if ( [[o_mux_selector titleOfSelectedItem] isEqualToString: @"Ogg"] )
  458.         o_mux_string = @"ogm";
  459.     else if ( [[o_mux_selector titleOfSelectedItem] isEqualToString: @"MPEG 4"] )
  460.         o_mux_string = @"mp4";
  461.     else if ( [[o_mux_selector titleOfSelectedItem] isEqualToString: @"Quicktime"] )
  462.         o_mux_string = @"mov";
  463.     else if ( [[o_mux_selector titleOfSelectedItem] isEqualToString: @"Raw"] )
  464.         o_mux_string = @"raw";
  465.     else
  466.         o_mux_string = @"ts";
  467.     NSString * o_name = [NSString stringWithFormat: @"vlc-output.%@",
  468.                          o_mux_string];
  469.     [o_save_panel setTitle: _NS("Save File")];
  470.     [o_save_panel setPrompt: _NS("Save")];
  471.     if( [o_save_panel runModalForDirectory: nil
  472.             file: o_name] == NSOKButton )
  473.     {
  474.         NSString *o_filename = [o_save_panel filename];
  475.         [o_file_field setStringValue: o_filename];
  476.         [self outputInfoChanged: nil];
  477.     }
  478. }
  479. - (IBAction)streamPortStepperChanged:(id)sender
  480. {
  481.     [o_stream_port setIntValue: [o_stream_port_stp intValue]];
  482.     [self outputInfoChanged: nil];
  483. }
  484. - (IBAction)streamTTLStepperChanged:(id)sender
  485. {
  486.     [o_stream_ttl setIntValue: [o_stream_ttl_stp intValue]];
  487.     [self TTLChanged:nil];
  488. }
  489. - (void)transcodeChanged:(NSNotification *)o_notification
  490. {
  491.     if( [o_transcode_video_chkbox state] == NSOnState )
  492.     {
  493.         [o_transcode_video_selector setEnabled: YES];
  494.         [o_transcode_video_bitrate setEnabled: YES];
  495.         [o_transcode_video_scale setEnabled: YES];
  496.     }
  497.     else
  498.     {
  499.         [o_transcode_video_selector setEnabled: NO];
  500.         [o_transcode_video_bitrate setEnabled: NO];
  501.         [o_transcode_video_scale setEnabled: NO];
  502.     }
  503.     if( [o_transcode_audio_chkbox state] == NSOnState )
  504.     {
  505.         [o_transcode_audio_selector setEnabled: YES];
  506.         [o_transcode_audio_bitrate setEnabled: YES];
  507.         [o_transcode_audio_channels setEnabled: YES];
  508.     }
  509.     else
  510.     {
  511.         [o_transcode_audio_selector setEnabled: NO];
  512.         [o_transcode_audio_bitrate setEnabled: NO];
  513.         [o_transcode_audio_channels setEnabled: NO];
  514.     }
  515.     [self transcodeInfoChanged:nil];
  516. }
  517. - (void)transcodeInfoChanged:(NSNotification *)o_notification
  518. {
  519.     NSMutableString *o_transcode_string;
  520.     if( [o_transcode_video_chkbox state] == NSOnState ||
  521.         [o_transcode_audio_chkbox state] == NSOnState )
  522.     {
  523.         o_transcode_string = [NSMutableString stringWithString:@"transcode{"];
  524.         if ( [o_transcode_video_chkbox state] == NSOnState )
  525.         {
  526.             [o_transcode_string appendFormat: @"vcodec="%@",vb="%@""
  527.                                                             ",scale="%@"",
  528.                 [o_transcode_video_selector titleOfSelectedItem],
  529.                 [o_transcode_video_bitrate stringValue],
  530.                 [o_transcode_video_scale stringValue]];
  531.             if ( [o_transcode_audio_chkbox state] == NSOnState )
  532.             {
  533.                 [o_transcode_string appendString: @","];
  534.             }
  535.         }
  536.         if ( [o_transcode_audio_chkbox state] == NSOnState )
  537.         {
  538.             [o_transcode_string appendFormat: @"acodec="%@",ab="%@"",
  539.                 [o_transcode_audio_selector titleOfSelectedItem],
  540.                 [o_transcode_audio_bitrate stringValue]];
  541.             if ( ![[o_transcode_audio_channels stringValue]
  542.                                             isEqualToString: @""])
  543.             {
  544.                 [o_transcode_string appendFormat: @",channels="%@"",
  545.                                    [o_transcode_audio_channels stringValue]];
  546.             }
  547.         }
  548.         [o_transcode_string appendString:@"}:"];
  549.     }
  550.     else
  551.     {
  552.         o_transcode_string = [NSString stringWithString:@""];
  553.     }
  554.     [self setTranscode: o_transcode_string];
  555.     [self outputInfoChanged:nil];
  556. }
  557. - (IBAction)announceChanged:(id)sender
  558. {
  559.     NSString *o_mode;
  560.     o_mode = [[o_stream_type selectedCell] title];
  561.     [o_channel_name setEnabled: [o_sap_chkbox state] || [o_slp_chkbox state]
  562.                 || [o_mode isEqualToString: @"RTP"]];
  563.     if ([o_mode isEqualToString: @"RTP"])
  564.     {
  565. /*        if ([[sender title] isEqualToString: _NS("SAP announce")])
  566.         {
  567.             [o_rtsp_chkbox setState:NSOffState];
  568.             [o_http_chkbox setState:NSOffState];
  569.         }*/
  570.         if ([[sender title] isEqualToString:_NS("RTSP announce")])
  571.         {
  572. //            [o_sap_chkbox setState:NSOffState];
  573.             [o_http_chkbox setState:NSOffState];
  574.             [o_file_chkbox setState:NSOffState];
  575.         }
  576.         else if ([[sender title] isEqualToString:_NS("HTTP announce")])
  577.         {
  578. //            [o_sap_chkbox setState:NSOffState];
  579.             [o_rtsp_chkbox setState:NSOffState];
  580.             [o_file_chkbox setState:NSOffState];
  581.         }
  582.         else if ([[sender title] isEqualToString:_NS("Export SDP as file")])
  583.         {
  584.             [o_rtsp_chkbox setState:NSOffState];
  585.             [o_http_chkbox setState:NSOffState];
  586.         }
  587.         if ( [o_rtsp_chkbox state] == NSOnState ||
  588.                             [o_http_chkbox state] == NSOnState ||
  589.                             [o_file_chkbox state] == NSOnState )
  590.         {
  591.             [o_sdp_url setEnabled: YES];
  592.         }
  593.         else
  594.         {
  595.             [o_sdp_url setEnabled: NO];
  596.         }
  597.     }
  598.     [self outputInfoChanged: nil];
  599. }
  600. @end