~ubuntu-branches/ubuntu/maverick/ekiga/maverick

« back to all changes in this revision

Viewing changes to src/devices/videoinput.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Eugen Dedu, Eugen Dedu, Loic Minier
  • Date: 2008-09-27 10:00:00 UTC
  • mfrom: (1.1.8 upstream)
  • mto: (1.4.1 squeeze)
  • mto: This revision was merged to the branch mainline in revision 38.
  • Revision ID: james.westby@ubuntu.com-20080927100000-l5k5werb6czr5b3h
Tags: 3.0.1-1
[ Eugen Dedu ]
* New version.  (Closes: #500089).
* Add our own changelog file in /usr/share/doc.
* Remove gnomemeeting transitional package.
* Discover new interfaces.  (Closes: #488199).
* Compile with dbus support.  (Closes: #467212).
* Numeric keypad inserts digits at correct position.  (Closes: #440159).
* Use libnotify upon call.  (Closes: #412604).
* Symlink identical GNOME help files, to reduce size.  (Closes: #505536).
* Explicitely build-depends on a few dev packages, even if they were
  pulled out anyway by the other dependencies.

[ Loic Minier ]
* Use clean:: instead of clean: in rules.
* Don't disable Uploaders: generation for control.in -> control generation
  in rules.
* Fix some tabs which were size 4 anyway.
* Generate a PO template during build by calling intltool-update -p in
  install; thanks Ubuntu and Martin Pitt; closes: #505535.
* Also let the -dbg depend on ${misc:Depends}.
* Cleanup rules; in particular, use dpkg-parsechangelog and honor
  distclean/clean failures, remove old clean rules, commented out stuff,
  gtk-only stuff.
* Pass -s to dh_* in binary-arch.
* Use debian/*.links and debian/*.manpages instead of symlink manually or
  passing files to dh_installman.
* Use ftp.gnome.org in copyright.
* Switch to quilt and fix target deps in the process; build-dep on quilt
  instead of dpatch; rename news.dpatch to 00_news.patch and refresh;
  replace 00list with series.
* Install autotools-dev config.guess and .sub after patching.

Show diffs side-by-side

added added

removed removed

Lines of Context:
36
36
 *
37
37
 */
38
38
 
39
 
 
40
 
#include "../../config.h"
 
39
#define P_FORCE_STATIC_PLUGIN
41
40
 
42
41
#include "videoinput.h"
43
42
#include "ekiga.h"
44
 
#include "misc.h"
45
 
#include "history.h"
46
 
#include "main.h"
47
 
#include "druid.h"
48
 
 
49
 
#include "gmdialog.h"
50
 
#include "gmconf.h"
51
 
 
52
 
#define new PNEW
53
 
 
54
 
 
55
 
/* The functions */
56
 
GMVideoGrabber::GMVideoGrabber (BOOL start_grabbing,
57
 
                                BOOL sync,
58
 
                                GMManager & endpoint)
59
 
  : PThread (1000, NoAutoDeleteThread), ep (endpoint)
60
 
{
61
 
  /* Variables */
62
 
  height = 0;
63
 
  width = 0;
64
 
 
65
 
  whiteness = 0;
66
 
  brightness = 0;
67
 
  colour = 0;
68
 
  contrast = 0;
69
 
 
70
 
  
71
 
  /* Internal state */
72
 
  stop = FALSE;
73
 
  is_grabbing = start_grabbing;
74
 
  synchronous = sync;
75
 
  is_opened = FALSE;
76
 
 
77
 
  
78
 
  /* Initialisation */
79
 
  display = NULL;
80
 
  grabber = NULL;
81
 
 
82
 
  if (synchronous)
83
 
    VGOpen ();
84
 
  
85
 
  /* Start the thread */
86
 
  this->Resume ();
87
 
  thread_sync_point.Wait ();
88
 
}
89
 
 
90
 
 
91
 
GMVideoGrabber::~GMVideoGrabber ()
92
 
{
93
 
  is_grabbing = FALSE;
94
 
  stop = TRUE;
95
 
 
96
 
  /* Wait for the device to be unlocked */
97
 
  PWaitAndSignal q(device_mutex);
98
 
 
99
 
  /* Wait for the Main () method to be terminated */
100
 
  PWaitAndSignal m(quit_mutex);
101
 
}
102
 
 
103
 
 
104
 
void
105
 
GMVideoGrabber::Main ()
106
 
{
107
 
  PBYTEArray frame;
108
 
 
109
 
  PWaitAndSignal m(quit_mutex);
110
 
  thread_sync_point.Signal ();
111
 
 
112
 
  if (!synchronous)
113
 
    VGOpen ();
114
 
 
115
 
  while (!stop) {
116
 
 
117
 
    var_mutex.Wait ();
118
 
    if (is_grabbing == 1) {
119
 
 
120
 
      grabber->GetFrame (frame);
121
 
      if (frame != NULL)
122
 
        display->SetFrameData (0, 0, 
123
 
                               grabber->GetFrameWidth (), 
124
 
                               grabber->GetFrameHeight (), 
125
 
                               frame);
126
 
    }
127
 
    var_mutex.Signal ();
128
 
 
129
 
    Current()->Sleep (5);
130
 
  }
131
 
 
132
 
  VGClose ();
133
 
}
134
 
 
135
 
 
136
 
void
137
 
GMVideoGrabber::StartGrabbing (void)
138
 
{
139
 
  PWaitAndSignal m(var_mutex);
140
 
  
141
 
  is_grabbing = 1;
142
 
}
143
 
 
144
 
 
145
 
void
146
 
GMVideoGrabber::StopGrabbing (void)
147
 
{
148
 
  PWaitAndSignal m(var_mutex);
149
 
 
150
 
  is_grabbing = 0;
151
 
}
152
 
 
153
 
 
154
 
BOOL
155
 
GMVideoGrabber::IsGrabbing (void)
156
 
{
157
 
  PWaitAndSignal m(var_mutex);
158
 
 
159
 
  return is_grabbing;
160
 
}
161
 
 
162
 
 
163
 
PVideoInputDevice *
164
 
GMVideoGrabber::GetInputDevice (void)
165
 
{
166
 
  PWaitAndSignal m(var_mutex);
167
 
  
168
 
  return grabber;
169
 
}
170
 
 
171
 
 
172
 
PVideoOutputDevice *
173
 
GMVideoGrabber::GetOutputDevice (void)
174
 
{
175
 
  PWaitAndSignal m(var_mutex);
176
 
  
177
 
  return display;
178
 
}
179
 
 
180
 
 
181
 
BOOL
182
 
GMVideoGrabber::SetColour (int colour)
183
 
{
184
 
  PWaitAndSignal m(var_mutex);
185
 
 
186
 
  if (grabber)
187
 
    return grabber->SetColour (colour);
188
 
 
189
 
  return FALSE;
190
 
}
191
 
 
192
 
 
193
 
BOOL
194
 
GMVideoGrabber::SetBrightness (int brightness)
195
 
{
196
 
  PWaitAndSignal m(var_mutex);
197
 
 
198
 
  if (grabber)
199
 
    return grabber->SetBrightness (brightness);
200
 
 
201
 
  return FALSE;
202
 
}
203
 
 
204
 
 
205
 
BOOL
206
 
GMVideoGrabber::SetWhiteness (int whiteness)
207
 
{
208
 
  PWaitAndSignal m(var_mutex);
209
 
 
210
 
  if (grabber)
211
 
    return grabber->SetWhiteness (whiteness);
212
 
 
213
 
  return FALSE;
214
 
}
215
 
 
216
 
 
217
 
BOOL
218
 
GMVideoGrabber::SetContrast (int constrast)
219
 
{
220
 
  PWaitAndSignal m(var_mutex);
221
 
  
222
 
  if (grabber)
223
 
    return grabber->SetContrast (constrast);
224
 
 
225
 
  return FALSE;
226
 
}
227
 
 
228
 
 
229
 
void
230
 
GMVideoGrabber::GetParameters (int *whiteness,
231
 
                               int *brightness, 
232
 
                               int *colour,
233
 
                               int *contrast)
234
 
{
235
 
  int hue = 0;
236
 
  
237
 
  PWaitAndSignal m(var_mutex);
238
 
  
239
 
  grabber->GetParameters (whiteness, brightness, colour, contrast, &hue);
240
 
 
241
 
  *whiteness = (int) *whiteness / 256;
242
 
  *brightness = (int) *brightness / 256;
243
 
  *colour = (int) *colour / 256;
244
 
  *contrast = (int) *contrast / 256;
245
 
}
246
 
 
247
 
 
248
 
void
249
 
GMVideoGrabber::Lock ()
250
 
{
251
 
  device_mutex.Wait ();
252
 
}
253
 
 
254
 
 
255
 
void
256
 
GMVideoGrabber::Unlock ()
257
 
{
258
 
  device_mutex.Signal ();
259
 
}
260
 
 
261
 
 
262
 
void
263
 
GMVideoGrabber::VGOpen (void)
264
 
{
265
 
  GtkWidget *history_window = NULL;
266
 
  GtkWidget *main_window = NULL;
267
 
 
268
 
  PString input_device;
269
 
  PString plugin;
270
 
 
271
 
  gchar *dialog_title = NULL;
272
 
  gchar *dialog_msg = NULL;
273
 
  gchar *tmp_msg = NULL;
274
 
  gchar *conf_value = NULL;
275
 
  
276
 
  int error_code = 0;
277
 
  int channel = 0;
278
 
  int size = 0;
279
 
 
280
 
  BOOL no_device_found = FALSE;
281
 
  
282
 
  PVideoDevice::VideoFormat format = PVideoDevice::PAL;
283
 
 
284
 
  history_window = GnomeMeeting::Process ()->GetHistoryWindow ();
285
 
  main_window = GnomeMeeting::Process ()->GetMainWindow ();
286
 
  
287
 
  if (!is_opened) {
288
 
    
289
 
    /* Get the video device options from the configuration database */
290
 
    gnomemeeting_threads_enter ();
291
 
 
292
 
    conf_value = gm_conf_get_string (VIDEO_DEVICES_KEY "input_device");
293
 
    input_device = conf_value;
294
 
    g_free (conf_value);
295
 
    
296
 
    conf_value = gm_conf_get_string (VIDEO_DEVICES_KEY "plugin");
297
 
    plugin = conf_value;
298
 
    g_free (conf_value);
299
 
    
300
 
    channel = gm_conf_get_int (VIDEO_DEVICES_KEY "channel");
301
 
 
302
 
    size = gm_conf_get_int (VIDEO_DEVICES_KEY "size");
303
 
 
304
 
    format =
305
 
      (PVideoDevice::VideoFormat) gm_conf_get_int (VIDEO_DEVICES_KEY "format");
306
 
 
307
 
    height = (size == 0) ? GM_QCIF_HEIGHT : GM_CIF_HEIGHT; 
308
 
    width = (size == 0) ? GM_QCIF_WIDTH : GM_CIF_WIDTH;
309
 
 
310
 
    no_device_found = (input_device == _("No device found"));
311
 
    gnomemeeting_threads_leave ();
312
 
 
313
 
 
314
 
    /* If there is no device, directly open the fake device */
315
 
    if (!no_device_found) {
316
 
 
317
 
      gnomemeeting_threads_enter ();
318
 
      gm_history_window_insert (history_window,
319
 
                                _("Opening video device %s with plugin %s"),
320
 
                                (const char *) input_device,
321
 
                                (const char *) plugin);
322
 
      gnomemeeting_threads_leave ();
323
 
 
324
 
      var_mutex.Wait ();
325
 
      grabber = 
326
 
        PVideoInputDevice::CreateOpenedDevice (plugin, input_device, FALSE);
327
 
      if (!grabber)
328
 
        error_code = 1;
329
 
      else if (!grabber->SetVideoFormat (format))
330
 
        error_code = 2;
331
 
      else if (!grabber->SetChannel (channel))
332
 
        error_code = 3;
333
 
      else if (!grabber->SetColourFormatConverter ("YUV420P"))
334
 
        error_code = 4;
335
 
      else if (!grabber->SetFrameRate (30))
336
 
        error_code = 5;
337
 
      else if (!grabber->SetFrameSizeConverter (width, height, FALSE))
338
 
        error_code = 6;
339
 
      var_mutex.Signal ();
340
 
    
341
 
 
342
 
      /* If no error */
343
 
      if (!error_code) {
344
 
 
345
 
        gnomemeeting_threads_enter ();
346
 
        gm_history_window_insert (history_window,
347
 
                                  _("Successfully opened video device %s, channel %d"),
348
 
                                  (const char *) input_device,
349
 
                                  channel);
350
 
        gnomemeeting_threads_leave ();
351
 
      }
352
 
      else {
353
 
        
354
 
        /* If we want to open the fake device for a real error, and not because
355
 
           the user chose the Picture device */
356
 
        gnomemeeting_threads_enter ();
357
 
        dialog_title =
358
 
          g_strdup_printf (_("Error while opening video device %s"),
359
 
                           (const char *) input_device);
360
 
 
361
 
        /* Translators: Do not translate MovingLogo and Picture */
362
 
        tmp_msg = g_strdup (_("A moving logo will be transmitted during calls. Notice that you can always transmit a given image or the moving logo by choosing \"Picture\" as video plugin and \"MovingLogo\" or \"StaticPicture\" as device."));
363
 
        gm_history_window_insert (history_window, 
364
 
                                  _("Couldn't open the video device"));
365
 
        switch (error_code) {
366
 
          
367
 
        case 1:
368
 
          dialog_msg = g_strconcat (tmp_msg, "\n\n", _("There was an error while opening the device. Please check your permissions and make sure that the appropriate driver is loaded."), NULL);
369
 
          break;
370
 
          
371
 
        case 2:
372
 
          dialog_msg = g_strconcat (tmp_msg, "\n\n", _("Your video driver doesn't support the requested video format."), NULL);
373
 
          break;
374
 
 
375
 
        case 3:
376
 
          dialog_msg = g_strconcat (tmp_msg, "\n\n", _("Could not open the chosen channel."), NULL);
377
 
          break;
378
 
      
379
 
        case 4:
380
 
          dialog_msg = g_strconcat (tmp_msg, "\n\n", _("Your driver doesn't seem to support any of the color formats supported by Ekiga.\n Please check your kernel driver documentation in order to determine which Palette is supported."), NULL);
381
 
          break;
382
 
          
383
 
        case 5:
384
 
          dialog_msg = g_strconcat (tmp_msg, "\n\n", _("Error while setting the frame rate."), NULL);
385
 
          break;
386
 
 
387
 
        case 6:
388
 
          dialog_msg = g_strconcat (tmp_msg, "\n\n", _("Error while setting the frame size."), NULL);
389
 
          break;
390
 
        }
391
 
 
392
 
        gnomemeeting_warning_dialog_on_widget (GTK_WINDOW (main_window),
393
 
                                               VIDEO_DEVICES_KEY "enable_preview",
394
 
                                               dialog_title,
395
 
                                               "%s", dialog_msg);
396
 
        g_free (dialog_msg);
397
 
        g_free (dialog_title);
398
 
        g_free (tmp_msg);
399
 
 
400
 
        gnomemeeting_threads_leave ();
401
 
      }
402
 
    }
403
 
      
404
 
    if (error_code || no_device_found) {
405
 
        
406
 
      /* delete the failed grabber and open the fake grabber */
407
 
      var_mutex.Wait ();
408
 
      if (grabber) {
409
 
        
410
 
        delete grabber;
411
 
        grabber = NULL;
412
 
      }
413
 
 
414
 
      grabber =
415
 
        PVideoInputDevice::CreateOpenedDevice ("Picture",
416
 
                                               "MovingLogo",
417
 
                                               FALSE);
418
 
      if (grabber) {
419
 
        
420
 
        grabber->SetColourFormatConverter ("YUV420P");
421
 
        grabber->SetVideoFormat (PVideoDevice::PAL);
422
 
        grabber->SetChannel (1);    
423
 
        grabber->SetFrameRate (6);
424
 
        grabber->SetFrameSizeConverter (width, height, FALSE);
425
 
        
426
 
        gnomemeeting_threads_enter ();
427
 
        gm_history_window_insert (history_window,
428
 
                                  _("Opened the video device using the \"Picture\" video plugin"));
429
 
        gnomemeeting_threads_leave ();
430
 
      }
431
 
      var_mutex.Signal ();
432
 
    }
433
 
   
434
 
 
435
 
    grabber->Start ();
436
 
 
437
 
    var_mutex.Wait ();
438
 
 
439
 
    display = PVideoOutputDevice::CreateDevice ("GDK");
440
 
    display->Open ("GDKIN", FALSE);
441
 
    display->SetFrameSizeConverter (width, height, FALSE);
442
 
    display->SetColourFormatConverter ("YUV420P");
443
 
 
444
 
    is_opened = TRUE;
445
 
    var_mutex.Signal ();
446
 
  
447
 
      
448
 
    /* Setup the video settings */
449
 
    GetParameters (&whiteness, &brightness, &colour, &contrast);
450
 
    if (whiteness > 0 || brightness > 0 || colour > 0 || contrast > 0) {
451
 
 
452
 
      gnomemeeting_threads_enter ();
453
 
      gm_main_window_set_video_sliders_values (main_window,
454
 
                                               whiteness,
455
 
                                               brightness,
456
 
                                               colour, 
457
 
                                               contrast);
458
 
      gnomemeeting_threads_leave ();
459
 
    }
460
 
    else {
461
 
 
462
 
      /* Driver made a reset, keep the old values */
463
 
      gnomemeeting_threads_enter ();
464
 
      gm_main_window_get_video_sliders_values (main_window,
465
 
                                               whiteness,
466
 
                                               brightness,
467
 
                                               colour,
468
 
                                               contrast);
469
 
      gnomemeeting_threads_leave ();
470
 
 
471
 
      if (whiteness > 0)
472
 
        SetWhiteness (whiteness << 8);
473
 
      if (brightness > 0)
474
 
        SetBrightness (brightness << 8);
475
 
      if (colour > 0)
476
 
        SetColour (colour << 8);
477
 
      if (contrast > 0)
478
 
        SetContrast (contrast << 8);
479
 
    }
480
 
 
481
 
      
482
 
    /* Update the GUI sensitivity if not in a call */
483
 
    if (ep.GetCallingState () == GMManager::Standby) {
484
 
 
485
 
      gnomemeeting_threads_enter ();      
486
 
      gm_main_window_update_sensitivity (main_window, TRUE, FALSE, TRUE);
487
 
      gnomemeeting_threads_leave ();
488
 
    }
489
 
  }
490
 
}
491
 
  
492
 
 
493
 
void
494
 
GMVideoGrabber::VGClose ()
495
 
{
496
 
  GtkWidget *main_window = NULL;
497
 
 
498
 
  main_window = GnomeMeeting::Process ()->GetMainWindow ();
499
 
 
500
 
  if (is_opened) {
501
 
 
502
 
    var_mutex.Wait ();
503
 
    is_grabbing = FALSE;
504
 
    var_mutex.Signal ();
505
 
 
506
 
 
507
 
    /* Update menu sensitivity if we are not in a call */
508
 
    gnomemeeting_threads_enter ();
509
 
    if (ep.GetCallingState () == GMManager::Standby
510
 
        && !gm_conf_get_bool (VIDEO_DEVICES_KEY "enable_preview")) {
511
 
 
512
 
      gm_main_window_update_sensitivity (main_window, TRUE, FALSE, FALSE);
513
 
      gm_main_window_update_logo (main_window);
514
 
    }
515
 
    
516
 
    /* Update the GUI view mode to make sure the video is shown */
517
 
    ViewMode m = 
518
 
      (ViewMode) gm_conf_get_int (USER_INTERFACE_KEY "main_window/view_mode");
519
 
    gm_main_window_set_view_mode (main_window, m);
520
 
    gnomemeeting_threads_leave ();
521
 
 
522
 
 
523
 
    /* Initialisation */
524
 
    var_mutex.Wait ();
525
 
    is_opened = FALSE;
526
 
    delete grabber;
527
 
    delete display;
528
 
    display = NULL;
529
 
    grabber = NULL;
530
 
    var_mutex.Signal ();
531
 
  }
532
 
 
533
 
  
534
 
  /* Quick Hack for buggy drivers that return from the ioctl before the device
535
 
     is really closed */
536
 
  PThread::Current ()->Sleep (1000);
537
 
}
538
 
 
539
 
 
540
 
/* The video tester class */
541
 
GMVideoTester::GMVideoTester (gchar *manager,
542
 
                              gchar *recorder)
543
 
  :PThread (1000, AutoDeleteThread)
544
 
{
545
 
  if (manager)
546
 
    video_manager = PString (manager);
547
 
  if (recorder)
548
 
    video_recorder = PString (recorder);
549
 
 
550
 
  test_dialog = NULL;
551
 
  test_label = NULL;
552
 
  
553
 
  this->Resume ();
554
 
  thread_sync_point.Wait ();
555
 
}
556
 
 
557
 
 
558
 
GMVideoTester::~GMVideoTester ()
559
 
{
560
 
 PWaitAndSignal m(quit_mutex);
561
 
}
562
 
 
563
 
 
564
 
void GMVideoTester::Main ()
565
 
{
566
 
  GtkWidget *druid_window = NULL;
567
 
 
568
 
  PVideoInputDevice *grabber = NULL;
569
 
  
570
 
  int height = GM_QCIF_HEIGHT; 
571
 
  int width = GM_QCIF_WIDTH; 
572
 
  int error_code = -1;
573
 
  int cpt = 0;
574
 
 
575
 
  gchar *dialog_msg = NULL;
576
 
  gchar *tmp = NULL;
577
 
 
578
 
  druid_window = GnomeMeeting::Process ()->GetDruidWindow (); 
579
 
  
580
 
  PWaitAndSignal m(quit_mutex);
581
 
  thread_sync_point.Signal ();
582
 
 
583
 
  if (video_recorder.IsEmpty ()
584
 
      || video_manager.IsEmpty ()
585
 
      || video_recorder == PString (_("No device found"))
586
 
      || video_recorder == PString (_("Picture")))
587
 
    return;
588
 
  
589
 
  gdk_threads_enter ();
590
 
  test_dialog =
591
 
    gtk_dialog_new_with_buttons ("Video test running",
592
 
                                 GTK_WINDOW (druid_window),
593
 
                                 (GtkDialogFlags) (GTK_DIALOG_MODAL),
594
 
                                 GTK_STOCK_OK,
595
 
                                 GTK_RESPONSE_ACCEPT,
596
 
                                 NULL);
597
 
  dialog_msg = 
598
 
    g_strdup_printf (_("Ekiga is now testing the %s video device. If you experience machine crashes, then report a bug to the video driver author."), (const char *) video_recorder);
599
 
  test_label = gtk_label_new (dialog_msg);
600
 
  gtk_label_set_line_wrap (GTK_LABEL (test_label), true);
601
 
  g_free (dialog_msg);
602
 
 
603
 
  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (test_dialog)->vbox), test_label,
604
 
                      FALSE, FALSE, 2);
605
 
  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (test_dialog)->vbox), 
606
 
                      gtk_hseparator_new (), FALSE, FALSE, 2);
607
 
 
608
 
  test_label = gtk_label_new (NULL);
609
 
  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (test_dialog)->vbox), 
610
 
                      test_label, FALSE, FALSE, 2);
611
 
 
612
 
  g_signal_connect (G_OBJECT (test_dialog), "delete-event",
613
 
                    G_CALLBACK (gtk_widget_hide_on_delete), NULL);
614
 
 
615
 
  gtk_window_set_transient_for (GTK_WINDOW (test_dialog),
616
 
                                GTK_WINDOW (druid_window));
617
 
  gtk_widget_show_all (GTK_DIALOG (test_dialog)->vbox);
618
 
  gnomemeeting_threads_dialog_show (test_dialog);
619
 
  gdk_threads_leave ();
620
 
 
621
 
  
622
 
  while (cpt < 6 && error_code == -1) {
623
 
 
624
 
    if (!video_recorder.IsEmpty ()
625
 
        && !video_manager.IsEmpty ()) {
626
 
 
627
 
      error_code = -1;
628
 
      
629
 
      grabber = 
630
 
        PVideoInputDevice::CreateOpenedDevice (video_manager,
631
 
                                               video_recorder,
632
 
                                               FALSE);
633
 
 
634
 
      if (!grabber)
635
 
        error_code = 0;
636
 
      else
637
 
        if (!grabber->SetVideoFormat (PVideoDevice::Auto))
638
 
          error_code = 2;
639
 
      else
640
 
        if (!grabber->SetChannel (0))
641
 
          error_code = 2;
642
 
      else
643
 
        if (!grabber->SetColourFormatConverter ("YUV420P"))
644
 
          error_code = 3;
645
 
      else
646
 
        if (!grabber->SetFrameRate (30))
647
 
          error_code = 4;
648
 
      else
649
 
        if (!grabber->SetFrameSizeConverter (width, height, FALSE))
650
 
          error_code = 5;
651
 
      else
652
 
        grabber->Close ();
653
 
 
654
 
      if (grabber)
655
 
        delete (grabber);
656
 
    }
657
 
 
658
 
 
659
 
    if (error_code == -1) 
660
 
      dialog_msg = g_strdup_printf (_("Test %d done"), cpt);
661
 
    else
662
 
      dialog_msg = g_strdup_printf (_("Test %d failed"), cpt);
663
 
 
664
 
    tmp = g_strdup_printf ("<b>%s</b>", dialog_msg);
665
 
    gdk_threads_enter ();
666
 
    gtk_label_set_markup (GTK_LABEL (test_label), tmp);
667
 
    gdk_threads_leave ();
668
 
    g_free (dialog_msg);
669
 
    g_free (tmp);
670
 
 
671
 
    cpt++;
672
 
    PThread::Current () ->Sleep (100);
673
 
  }
674
 
 
675
 
  
676
 
  if (error_code != - 1) {
677
 
    
678
 
    switch (error_code) {
679
 
          
680
 
    case 0:
681
 
      dialog_msg = g_strdup_printf (_("Error while opening %s."),
682
 
                             (const char *) video_recorder);
683
 
      break;
684
 
      
685
 
    case 1:
686
 
      dialog_msg = g_strdup_printf (_("Your video driver doesn't support the requested video format."));
687
 
      break;
688
 
      
689
 
    case 2:
690
 
      dialog_msg = g_strdup_printf (_("Could not open the chosen channel with the chosen video format."));
691
 
      break;
692
 
      
693
 
    case 3:
694
 
      dialog_msg = g_strdup_printf (_("Your driver doesn't support any of the color formats tried by Ekiga"));
695
 
      break;
696
 
      
697
 
    case 4:
698
 
      dialog_msg = g_strdup_printf ( _("Error with the frame rate."));
699
 
      break;
700
 
      
701
 
    case 5:
702
 
      dialog_msg = g_strdup_printf (_("Error with the frame size."));
703
 
      break;
704
 
    }
705
 
 
706
 
    gdk_threads_enter ();
707
 
    gnomemeeting_error_dialog (GTK_WINDOW (druid_window),
708
 
                               _("Failed to open the device"),
709
 
                               "%s", dialog_msg);
710
 
    gdk_threads_leave ();
711
 
    
712
 
    g_free (dialog_msg);
713
 
  }
714
 
 
715
 
  gdk_threads_enter ();
716
 
  gm_druid_window_set_test_buttons_sensitivity (druid_window, FALSE);
717
 
  if (test_dialog)
718
 
    gnomemeeting_threads_widget_destroy (test_dialog);
719
 
  gdk_threads_leave ();
 
43
 
 
44
/* Plugin definition */
 
45
class PVideoInputDevice_EKIGA_PluginServiceDescriptor 
 
46
: public PDevicePluginServiceDescriptor
 
47
{
 
48
  public:
 
49
    virtual PObject *CreateInstance (int) const 
 
50
      {
 
51
        return new PVideoInputDevice_EKIGA (*(GnomeMeeting::Process ()->GetServiceCore ())); 
 
52
      }
 
53
    
 
54
    
 
55
    virtual PStringArray GetDeviceNames(int) const 
 
56
      { 
 
57
        return PStringList("EKIGA"); 
 
58
      }
 
59
    
 
60
    virtual bool ValidateDeviceName (const PString & deviceName, 
 
61
                                     int) const 
 
62
      { 
 
63
        return deviceName.Find("EKIGA") == 0; 
 
64
      }
 
65
} PVideoInputDevice_EKIGA_descriptor;
 
66
 
 
67
PCREATE_PLUGIN(EKIGA, PVideoInputDevice, &PVideoInputDevice_EKIGA_descriptor);
 
68
 
 
69
int PVideoInputDevice_EKIGA::devices_nbr = 0;
 
70
 
 
71
PVideoInputDevice_EKIGA::PVideoInputDevice_EKIGA (Ekiga::ServiceCore & _core)
 
72
: core (_core), videoinput_core (*(dynamic_cast<Ekiga::VideoInputCore *> (_core.get ("videoinput-core"))))
 
73
{
 
74
  opened = false;
 
75
  is_active = false;
 
76
}
 
77
 
 
78
 
 
79
PVideoInputDevice_EKIGA::~PVideoInputDevice_EKIGA ()
 
80
{
 
81
  Close ();
 
82
}
 
83
 
 
84
bool
 
85
PVideoInputDevice_EKIGA::Open (const PString &/*name*/,
 
86
                               bool start_immediate)
 
87
{
 
88
  if (start_immediate) {
 
89
    if (!is_active) {
 
90
      if (devices_nbr == 0) {
 
91
        videoinput_core.set_stream_config(frameWidth, frameHeight, frameRate);
 
92
        videoinput_core.start_stream();
 
93
      }
 
94
      is_active = true;
 
95
      devices_nbr++;
 
96
    }
 
97
  }
 
98
  opened = true;
 
99
 
 
100
  return true;
 
101
}
 
102
 
 
103
 
 
104
bool
 
105
PVideoInputDevice_EKIGA::IsOpen ()
 
106
{
 
107
  return opened;
 
108
}
 
109
 
 
110
 
 
111
bool
 
112
PVideoInputDevice_EKIGA::Close ()
 
113
{
 
114
  if (is_active) {
 
115
    devices_nbr--;
 
116
    if (devices_nbr==0)
 
117
      videoinput_core.stop_stream();
 
118
    is_active = false;
 
119
  }
 
120
  opened = false;
 
121
 
 
122
  return true;
 
123
}
 
124
 
 
125
  
 
126
bool
 
127
PVideoInputDevice_EKIGA::Start ()
 
128
{
 
129
  if (!is_active) {
 
130
    if (devices_nbr == 0) {
 
131
      videoinput_core.set_stream_config(frameWidth, frameHeight, frameRate);
 
132
      videoinput_core.start_stream();
 
133
    }
 
134
    is_active = true;
 
135
    devices_nbr++;
 
136
  }
 
137
 
 
138
  return true;
 
139
}
 
140
 
 
141
  
 
142
bool
 
143
PVideoInputDevice_EKIGA::Stop ()
 
144
{
 
145
  return true;
 
146
}
 
147
 
 
148
 
 
149
bool
 
150
PVideoInputDevice_EKIGA::IsCapturing ()
 
151
{
 
152
  return IsCapturing ();
 
153
}
 
154
 
 
155
 
 
156
PStringArray
 
157
PVideoInputDevice_EKIGA::GetDeviceNames() const
 
158
{
 
159
  PStringArray  devlist;
 
160
  devlist.AppendString(GetDeviceName());
 
161
 
 
162
  return devlist;
 
163
}
 
164
 
 
165
 
 
166
bool
 
167
PVideoInputDevice_EKIGA::SetFrameSize (unsigned int width,
 
168
                                       unsigned int height)
 
169
{
 
170
  if (!PVideoDevice::SetFrameSize (width, height))
 
171
    return false;
 
172
 
 
173
  return true;
 
174
}
 
175
 
 
176
 
 
177
bool
 
178
PVideoInputDevice_EKIGA::GetFrameData (BYTE *frame,
 
179
                                       PINDEX *i)
 
180
{
 
181
  unsigned width;
 
182
  unsigned height;
 
183
  videoinput_core.get_frame_data((char*)frame, width, height);
 
184
 
 
185
  *i = width * height * 3 / 2;
 
186
 
 
187
  return true;
 
188
}
 
189
 
 
190
//FIXME
 
191
bool PVideoInputDevice_EKIGA::GetFrameDataNoDelay (BYTE *frame,
 
192
                                                   PINDEX *i)
 
193
{
 
194
  unsigned width;
 
195
  unsigned height;
 
196
  videoinput_core.get_frame_data((char*)frame, width, height);
 
197
 
 
198
  *i = width * height * 3 / 2;
 
199
  return true;
 
200
}
 
201
 
 
202
 
 
203
bool
 
204
PVideoInputDevice_EKIGA::TestAllFormats ()
 
205
{
 
206
  return true;
 
207
}
 
208
 
 
209
 
 
210
PINDEX
 
211
PVideoInputDevice_EKIGA::GetMaxFrameBytes ()
 
212
{
 
213
  return CalculateFrameBytes (frameWidth, frameHeight, colourFormat);
 
214
}
 
215
 
 
216
 
 
217
bool
 
218
PVideoInputDevice_EKIGA::SetVideoFormat (VideoFormat newFormat)
 
219
{
 
220
  return PVideoDevice::SetVideoFormat (newFormat);
 
221
}
 
222
 
 
223
 
 
224
int
 
225
PVideoInputDevice_EKIGA::GetNumChannels()
 
226
{
 
227
  return 1;
 
228
}
 
229
 
 
230
 
 
231
bool
 
232
PVideoInputDevice_EKIGA::SetChannel (int /*newChannel*/)
 
233
{
 
234
  return true;
 
235
}
 
236
 
 
237
 
 
238
bool
 
239
PVideoInputDevice_EKIGA::SetColourFormat (const PString &newFormat)
 
240
{
 
241
  if (newFormat == "YUV420P") 
 
242
    return PVideoDevice::SetColourFormat (newFormat);
 
243
 
 
244
  return false;  
 
245
}
 
246
 
 
247
 
 
248
bool
 
249
PVideoInputDevice_EKIGA::SetFrameRate (unsigned rate)
 
250
{
 
251
  PVideoDevice::SetFrameRate (rate);
 
252
 
 
253
  return true;
 
254
}
 
255
 
 
256
 
 
257
bool
 
258
PVideoInputDevice_EKIGA::GetFrameSizeLimits (unsigned & minWidth,
 
259
                                               unsigned & minHeight,
 
260
                                               unsigned & maxWidth,
 
261
                                               unsigned & maxHeight)
 
262
{
 
263
  minWidth  = 10;
 
264
  minHeight = 10;
 
265
  maxWidth  = 1000;
 
266
  maxHeight =  800;
 
267
 
 
268
  return true;
 
269
}
 
270
 
 
271
 
 
272
bool PVideoInputDevice_EKIGA::GetParameters (int *whiteness,
 
273
                                               int *brightness,
 
274
                                               int *colour,
 
275
                                               int *contrast,
 
276
                                               int *hue)
 
277
{
 
278
  *whiteness = 0;
 
279
  *brightness = 0;
 
280
  *colour = 0;
 
281
  *contrast = 0;
 
282
  *hue = 0;
 
283
 
 
284
  return true;
720
285
}