dfeb4390f35fc07317dca8d0cebb63bd1037974f
[vlc.git] / modules / gui / macosx / output.m
1 /*****************************************************************************
2  * output.m: MacOS X Output Dialog
3  *****************************************************************************
4  * Copyright (C) 2002-2003 VideoLAN
5  * $Id: output.m,v 1.11 2003/07/27 23:05:41 hartman Exp $
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_sap_name];
108
109     [o_mux_selector setAutoenablesItems: NO];
110     [self transcodeChanged:nil];
111 }
112
113 - (void)initStrings
114 {
115     NSArray *o_a_channels = [NSArray arrayWithObjects: @"1", @"2", @"4", @"6", nil];
116     NSArray *o_a_bitrates = [NSArray arrayWithObjects: @"96", @"128", @"192", @"256", @"512", nil];
117     NSArray *o_v_bitrates = [NSArray arrayWithObjects:
118         @"100", @"150", @"200", @"400", @"500", @"750", @"1000", @"2000", @"3000", nil];
119     NSArray *o_a_codecs = [NSArray arrayWithObjects:
120         @"mpga", @"mp3 ", @"a52 ", @"vorb", nil];
121     NSArray *o_v_codecs = [NSArray arrayWithObjects:
122         @"mpgv", @"mp4v", @"DIV1", @"DIV2", @"DIV3", @"H263", @"I263", @"WMV1", @"WMV2", @"MJPG", nil];
123     
124     [o_output_ckbox setTitle: _NS("Advanced output:")];
125     [o_output_settings setTitle: _NS("Settings...")];
126     [o_btn_ok setTitle: _NS("OK")];
127     
128     [o_options_lbl setTitle: _NS("Output Options")];
129     [o_display setTitle: _NS("Screen")];
130     [[o_method cellAtRow:0 column:0] setTitle: _NS("File")];
131     [[o_method cellAtRow:1 column:0] setTitle: _NS("Stream")];
132     [o_btn_browse setTitle: _NS("Browse...")]; 
133     [o_stream_address_lbl setStringValue: _NS("Address")];
134     [o_stream_port_lbl setStringValue: _NS("Port")];
135     [o_stream_ttl_lbl setStringValue: _NS("TTL")];
136     [[o_stream_type itemAtIndex: 0] setTitle: _NS("HTTP")];
137     [[o_stream_type itemAtIndex: 1] setTitle: _NS("UDP")];
138     [[o_stream_type itemAtIndex: 2] setTitle: _NS("RTP")];
139     [o_stream_type_lbl setStringValue: _NS("Type")];
140     
141     [o_mux_lbl setStringValue: _NS("Encapsulation Method")];
142     [[o_mux_selector itemAtIndex: 0] setTitle: _NS("MPEG TS")];
143     [[o_mux_selector itemAtIndex: 1] setTitle: _NS("MPEG PS")];
144     [[o_mux_selector itemAtIndex: 1] setTitle: _NS("MPEG1")];
145     [[o_mux_selector itemAtIndex: 3] setTitle: _NS("AVI")];
146     [[o_mux_selector itemAtIndex: 4] setTitle: _NS("Ogg")];
147     //[[o_mux_selector itemAtIndex: 5] setTitle: _NS("mp4")];
148     
149     [o_transcode_lbl setTitle: _NS("Transcode options")];
150     [o_transcode_video_chkbox setTitle: _NS("Video")];
151     [o_transcode_video_selector removeAllItems];
152     [o_transcode_video_selector addItemsWithTitles: o_v_codecs];
153     [o_transcode_video_bitrate_lbl setStringValue: _NS("Bitrate (kb/s)")];
154     [o_transcode_video_bitrate removeAllItems];
155     [o_transcode_video_bitrate addItemsWithObjectValues: o_v_bitrates];
156     [o_transcode_audio_chkbox setTitle: _NS("Audio")];
157     [o_transcode_audio_selector removeAllItems];
158     [o_transcode_audio_selector addItemsWithTitles: o_a_codecs];
159     [o_transcode_audio_bitrate_lbl setStringValue: _NS("Bitrate (kb/s)")];
160     [o_transcode_audio_bitrate removeAllItems];
161     [o_transcode_audio_bitrate addItemsWithObjectValues: o_a_bitrates];
162     [o_transcode_audio_channels_lbl setStringValue: _NS("Channels")];
163     [o_transcode_audio_channels removeAllItems];
164     [o_transcode_audio_channels addItemsWithObjectValues: o_a_channels];
165     
166     [o_misc_lbl setTitle: _NS("Miscellaneous Options")];
167     [o_sap_chkbox setTitle: _NS("Announce streams via SAP Channel:")];
168 }
169
170 - (IBAction)outputChanged:(id)sender;
171 {
172     if ([o_output_ckbox state] == NSOnState)
173     {
174         [o_output_settings setEnabled:YES];
175     }
176     else
177     {
178         [o_output_settings setEnabled:NO];
179     }
180 }
181
182 - (IBAction)outputSettings:(id)sender
183 {
184     [NSApp beginSheet: o_output_sheet
185         modalForWindow: o_open_panel
186         modalDelegate: self
187         didEndSelector: NULL
188         contextInfo: nil];
189 }
190
191 - (IBAction)outputCloseSheet:(id)sender
192 {
193     intf_thread_t * p_intf = [NSApp getIntf];
194     //export sout[o_mrl UTF8String]
195     
196     [o_output_sheet orderOut:sender];
197     [NSApp endSheet: o_output_sheet];
198 }
199
200 - (void)outputMethodChanged:(NSNotification *)o_notification
201 {
202     NSString *o_mode;
203     o_mode = [[o_method selectedCell] title];
204     
205     [o_sap_chkbox setEnabled: NO];
206     [o_sap_name setEnabled: NO];
207
208     if( [o_mode isEqualToString: _NS("File")] )
209     {
210         [o_file_field setEnabled: YES];
211         [o_btn_browse setEnabled: YES];
212         [o_stream_address setEnabled: NO];
213         [o_stream_port setEnabled: NO];
214         [o_stream_ttl setEnabled: NO];
215         [o_stream_port_stp setEnabled: NO];
216         [o_stream_ttl_stp setEnabled: NO];
217         [o_stream_type setEnabled: NO];
218         [o_mux_selector setEnabled: YES];
219         [[o_mux_selector itemAtIndex: 1] setEnabled: YES];
220         [[o_mux_selector itemAtIndex: 2] setEnabled: YES];
221         [[o_mux_selector itemAtIndex: 3] setEnabled: YES];
222         [[o_mux_selector itemAtIndex: 4] setEnabled: YES];
223         //[[o_mux_selector itemAtIndex: 5] setEnabled: YES];
224     }
225     else if( [o_mode isEqualToString: _NS("Stream")] )
226     {
227         [o_file_field setEnabled: NO];
228         [o_btn_browse setEnabled: NO];
229         [o_stream_port setEnabled: YES];
230         [o_stream_port_stp setEnabled: YES];
231         [o_stream_type setEnabled: YES];
232         [o_mux_selector setEnabled: YES];
233         
234         o_mode = [o_stream_type titleOfSelectedItem];
235         
236         if( [o_mode isEqualToString: _NS("HTTP")] )
237         {
238             [o_stream_address setEnabled: YES];
239             [o_stream_ttl setEnabled: NO];
240             [o_stream_ttl_stp setEnabled: NO];
241             [[o_mux_selector itemAtIndex: 1] setEnabled: YES];
242             [[o_mux_selector itemAtIndex: 2] setEnabled: YES];
243             [[o_mux_selector itemAtIndex: 3] setEnabled: NO];
244             [[o_mux_selector itemAtIndex: 4] setEnabled: YES];
245             //[[o_mux_selector itemAtIndex: 5] setEnabled: NO];
246         }
247         else if( [o_mode isEqualToString: _NS("UDP")] )
248         {
249             [o_stream_address setEnabled: YES];
250             [o_stream_ttl setEnabled: YES];
251             [o_stream_ttl_stp setEnabled: YES];
252             [[o_mux_selector itemAtIndex: 1] setEnabled: NO];
253             [[o_mux_selector itemAtIndex: 2] setEnabled: NO];
254             [[o_mux_selector itemAtIndex: 3] setEnabled: NO];
255             [[o_mux_selector itemAtIndex: 4] setEnabled: NO];
256             //[[o_mux_selector itemAtIndex: 5] setEnabled: NO];
257             [o_sap_chkbox setEnabled: YES];
258             [o_sap_name setEnabled: YES];
259         }
260         else if( [o_mode isEqualToString: _NS("RTP")] )
261         {
262             [o_stream_address setEnabled: YES];
263             [o_stream_ttl setEnabled: NO];
264             [o_stream_ttl_stp setEnabled: NO];
265             [[o_mux_selector itemAtIndex: 1] setEnabled: NO];
266             [[o_mux_selector itemAtIndex: 2] setEnabled: NO];
267             [[o_mux_selector itemAtIndex: 3] setEnabled: NO];
268             [[o_mux_selector itemAtIndex: 4] setEnabled: NO];
269             //[[o_mux_selector itemAtIndex: 5] setEnabled: NO];
270         }
271     }
272     if( ![[o_mux_selector selectedItem] isEnabled] )
273     {
274         [o_mux_selector selectItemAtIndex: 0];
275     }
276     [self outputInfoChanged: nil];
277 }
278
279 - (void)outputInfoChanged:(NSNotification *)o_notification
280 {
281     NSString *o_mode, *o_mux, *o_mux_string, *o_sap;
282     NSMutableString *o_mrl_string = [NSMutableString stringWithString:@"#"];
283
284     [o_mrl_string appendString: o_transcode];
285     if( [o_display state] == NSOnState )
286     {
287         [o_mrl_string appendString: @"duplicate{dst=display,dst="];
288     }
289
290     o_mode = [[o_method selectedCell] title];
291     o_mux = [o_mux_selector titleOfSelectedItem];
292
293     if ( [o_mux isEqualToString: _NS("AVI")] ) o_mux_string = @"avi";
294     else if ( [o_mux isEqualToString: _NS("Ogg")] ) o_mux_string = @"ogg";
295     else if ( [o_mux isEqualToString: _NS("MPEG PS")] ) o_mux_string = @"ps";
296     else if ( [o_mux isEqualToString: _NS("mp4")] ) o_mux_string = @"mp4";
297     else if ( [o_mux isEqualToString: _NS("MPEG1")] ) o_mux_string = @"mpeg1";
298     else o_mux_string = @"ts";
299
300     if( [o_mode isEqualToString: _NS("File")] )
301     {
302         [o_mrl_string appendFormat:
303                         @"std{access=file,mux=%@,url=\"%@\"}",
304                         o_mux_string, [o_file_field stringValue]];
305     }
306     else if( [o_mode isEqualToString: _NS("Stream")] )
307     {
308         o_mode = [o_stream_type titleOfSelectedItem];
309         o_sap = @"";
310         
311         if ( [o_mode isEqualToString: _NS("HTTP")] )
312             o_mode = @"http";
313         else if ( [o_mode isEqualToString: _NS("UDP")] )
314         {
315             o_mode = @"udp";
316             if( [o_sap_chkbox state] == NSOnState )
317             {
318                 o_sap = @",sap";
319                 if ( ![[o_sap_name stringValue] isEqualToString: @""] )
320                     o_sap = [NSString stringWithFormat:@",sap=%@", [o_sap_name stringValue]];
321             }
322         }
323         else if ( [o_mode isEqualToString: _NS("RTP")] )
324             o_mode = @"rtp";
325             
326         [o_mrl_string appendFormat:
327                         @"std{access=%@,mux=%@,url=\"%@:%@\"%@}",
328                         o_mode, o_mux_string, [o_stream_address stringValue],
329                         [o_stream_port stringValue], o_sap];
330     }
331     if( [o_display state] == NSOnState )
332     {
333         [o_mrl_string appendString: @"}"];
334     }
335     [self setMRL:o_mrl_string];
336 }
337
338 - (void)TTLChanged:(NSNotification *)o_notification
339 {
340     intf_thread_t * p_intf = [NSApp getIntf];
341     config_PutInt( p_intf, "ttl", [o_stream_ttl intValue] );
342 }
343
344 - (IBAction)outputFileBrowse:(id)sender
345 {
346     NSSavePanel *o_save_panel = [NSSavePanel savePanel];
347     NSString *o_mux_string;
348     if ( [[o_mux_selector titleOfSelectedItem] isEqualToString: _NS("MPEG PS")] )
349         o_mux_string = @"vob";
350     else if ( [[o_mux_selector titleOfSelectedItem] isEqualToString: _NS("MPEG1")] )
351         o_mux_string = @"mpg";
352     else if ( [[o_mux_selector titleOfSelectedItem] isEqualToString: _NS("AVI")] )
353         o_mux_string = @"avi";
354     else if ( [[o_mux_selector titleOfSelectedItem] isEqualToString: _NS("Ogg")] )
355         o_mux_string = @"ogm";
356     else if ( [[o_mux_selector titleOfSelectedItem] isEqualToString: _NS("mp4")] )
357         o_mux_string = @"mp4";
358     else
359         o_mux_string = @"ts";
360
361     NSString * o_name = [NSString stringWithFormat: @"vlc-output.%@",
362                          o_mux_string];
363
364     [o_save_panel setTitle: _NS("Save File")];
365     [o_save_panel setPrompt: _NS("Save")];
366
367     if( [o_save_panel runModalForDirectory: nil
368             file: o_name] == NSOKButton )
369     {
370         NSString *o_filename = [o_save_panel filename];
371         [o_file_field setStringValue: o_filename];
372         [self outputInfoChanged: nil];
373     }
374 }
375
376 - (IBAction)streamPortStepperChanged:(id)sender
377 {
378     [o_stream_port setIntValue: [o_stream_port_stp intValue]];
379     [self outputInfoChanged: nil];
380 }
381
382 - (IBAction)streamTTLStepperChanged:(id)sender
383 {
384     [o_stream_ttl setIntValue: [o_stream_ttl_stp intValue]];
385     [self TTLChanged:nil];
386 }
387
388 - (void)transcodeChanged:(NSNotification *)o_notification
389 {
390     if( [o_transcode_video_chkbox state] == NSOnState )
391     {
392         [o_transcode_video_selector setEnabled: YES];
393         [o_transcode_video_bitrate setEnabled: YES];
394     }
395     else
396     {
397         [o_transcode_video_selector setEnabled: NO];
398         [o_transcode_video_bitrate setEnabled: NO];
399     }
400     if( [o_transcode_audio_chkbox state] == NSOnState )
401     {
402         [o_transcode_audio_selector setEnabled: YES];
403         [o_transcode_audio_bitrate setEnabled: YES];
404         [o_transcode_audio_channels setEnabled: YES];
405     }
406     else
407     {
408         [o_transcode_audio_selector setEnabled: NO];
409         [o_transcode_audio_bitrate setEnabled: NO];
410         [o_transcode_audio_channels setEnabled: NO];
411     }
412
413     [self transcodeInfoChanged:nil];
414 }
415
416 - (void)transcodeInfoChanged:(NSNotification *)o_notification
417 {
418     NSMutableString *o_transcode_string;
419     
420     if( [o_transcode_video_chkbox state] == NSOnState ||
421         [o_transcode_audio_chkbox state] == NSOnState )
422     {
423         o_transcode_string = [NSMutableString stringWithString:@"transcode{"];
424         if ( [o_transcode_video_chkbox state] == NSOnState )
425         {
426             [o_transcode_string appendFormat: @"vcodec=\"%@\",vb=\"%@\"",
427                 [o_transcode_video_selector titleOfSelectedItem],
428                 [o_transcode_video_bitrate stringValue]];
429             if ( [o_transcode_audio_chkbox state] == NSOnState )
430             {
431                 [o_transcode_string appendString: @","];
432             }
433         }
434         if ( [o_transcode_audio_chkbox state] == NSOnState )
435         {
436             [o_transcode_string appendFormat: @"acodec=\"%@\",ab=\"%@\"",
437                 [o_transcode_audio_selector titleOfSelectedItem],
438                 [o_transcode_audio_bitrate stringValue]];
439         }
440         [o_transcode_string appendString:@"}:"];
441     }
442     else
443     {
444         o_transcode_string = [NSString stringWithString:@""];
445     }
446     [self setTranscode: o_transcode_string];
447     [self outputInfoChanged:nil];
448 }
449
450 - (IBAction)sapChanged:(id)sender
451 {
452     [o_sap_name setEnabled: [o_sap_chkbox state]];
453     [self outputInfoChanged: nil];
454 }
455
456
457
458 @end