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