~ubuntu-branches/ubuntu/precise/rhythmbox/precise-201203091205

« back to all changes in this revision

Viewing changes to player/rb-recorder-gst.c

Tags: upstream-0.9.5
ImportĀ upstreamĀ versionĀ 0.9.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
2
 
/*
 
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
 
2
 *
3
3
 * arch-tag: Implementation of GStreamer recorder backend
4
4
 *
5
 
 * Copyright (C) 2004-2005 William Jon McCann <mccann@jhu.edu>
 
5
 * Copyright (C) 2004-2006 William Jon McCann <mccann@jhu.edu>
6
6
 *
7
7
 * This program is free software; you can redistribute it and/or
8
8
 * modify it under the terms of the GNU General Public License as
16
16
 *
17
17
 * You should have received a copy of the GNU General Public
18
18
 * License along with this program; if not, write to the
19
 
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20
 
 * Boston, MA 02111-1307, USA.
 
19
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 
20
 * Boston, MA 02110-1301  USA.
21
21
 */
22
22
 
23
 
#include <config.h>
 
23
#include "config.h"
 
24
 
24
25
#include <unistd.h>
25
26
#include <string.h>
26
27
#include <math.h>
32
33
 
33
34
#include <glib/gi18n.h>
34
35
#include <libgnomevfs/gnome-vfs-utils.h>
35
 
#include <nautilus-burn-recorder.h>
36
36
#include <gst/gst.h>
37
37
#ifdef HAVE_GSTREAMER_0_8
38
38
#include <gst/gconf/gconf.h>
39
39
#include <gst/play/play.h>
40
40
#endif
41
41
 
 
42
#include <nautilus-burn-drive.h>
 
43
#include <nautilus-burn-recorder.h>
 
44
#ifndef NAUTILUS_BURN_CHECK_VERSION      
 
45
#define NAUTILUS_BURN_CHECK_VERSION(a,b,c) FALSE         
 
46
#endif
 
47
 
 
48
#if NAUTILUS_BURN_CHECK_VERSION(2,15,3)
 
49
#include <nautilus-burn.h>
 
50
#endif
 
51
 
42
52
#include "rb-recorder.h"
43
 
#include "rb-recorder-marshal.h"
44
53
 
45
54
#include "rb-debug.h"
 
55
#include "rb-marshal.h"
46
56
 
47
57
#ifdef HAVE_GSTREAMER_0_8
48
58
#define gst_caps_unref gst_caps_free
52
62
#define nautilus_burn_drive_ref nautilus_burn_drive_copy
53
63
#endif
54
64
 
55
 
 
56
65
static void rb_recorder_class_init (RBRecorderClass *klass);
57
66
static void rb_recorder_init       (RBRecorder      *recorder);
58
67
static void rb_recorder_finalize   (GObject         *object);
118
127
 
119
128
static guint rb_recorder_signals [LAST_SIGNAL] = { 0 };
120
129
 
121
 
static GObjectClass *parent_class = NULL;
122
 
 
123
130
#define RB_RECORDER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_RECORDER, RBRecorderPrivate))
124
131
 
125
132
GQuark
126
133
rb_recorder_error_quark (void)
127
134
{
128
135
        static GQuark quark = 0;
129
 
        if (!quark)
 
136
        if (! quark) {
130
137
                quark = g_quark_from_static_string ("rb_recorder_error");
 
138
        }
131
139
 
132
140
        return quark;
133
141
}
139
147
{
140
148
        GObjectClass *object_class;
141
149
 
142
 
        parent_class = g_type_class_peek_parent (klass);
143
150
        object_class = (GObjectClass *) klass;
144
151
 
145
152
        object_class->finalize = rb_recorder_finalize;
159
166
                              G_SIGNAL_RUN_LAST,
160
167
                              0,
161
168
                              NULL, NULL,
162
 
                              rb_recorder_marshal_VOID__DOUBLE_LONG,
 
169
                              rb_marshal_VOID__DOUBLE_LONG,
163
170
                              G_TYPE_NONE,
164
171
                              2,
165
172
                              G_TYPE_DOUBLE,
170
177
                              G_SIGNAL_RUN_LAST,
171
178
                              0,
172
179
                              NULL, NULL,
173
 
                              rb_recorder_marshal_VOID__DOUBLE_LONG,
 
180
                              rb_marshal_VOID__DOUBLE_LONG,
174
181
                              G_TYPE_NONE,
175
182
                              2,
176
183
                              G_TYPE_DOUBLE,
191
198
                              G_SIGNAL_RUN_LAST,
192
199
                              0,
193
200
                              NULL, NULL,
194
 
                              rb_recorder_marshal_BOOLEAN__BOOLEAN_BOOLEAN_BOOLEAN,
 
201
                              rb_marshal_BOOLEAN__BOOLEAN_BOOLEAN_BOOLEAN,
195
202
                              G_TYPE_BOOLEAN,
196
203
                              3,
197
204
                              G_TYPE_BOOLEAN,
203
210
                              G_SIGNAL_RUN_LAST,
204
211
                              0,
205
212
                              NULL, NULL,
206
 
                              rb_recorder_marshal_INT__VOID,
 
213
                              rb_marshal_INT__VOID,
207
214
                              G_TYPE_INT, 0);
208
215
        rb_recorder_signals [ERROR] =
209
216
                g_signal_new ("error",
225
232
        NautilusBurnDrive *drive  = NULL;
226
233
        GList             *drives = NULL;
227
234
 
 
235
#if NAUTILUS_BURN_CHECK_VERSION(2,15,3)
 
236
        NautilusBurnDriveMonitor *monitor;
 
237
        monitor = nautilus_burn_get_drive_monitor ();
 
238
        drives = nautilus_burn_drive_monitor_get_recorder_drives (monitor);
 
239
#else
228
240
        drives = nautilus_burn_drive_get_list (TRUE, FALSE);
 
241
#endif
229
242
 
230
 
        if (drives)
 
243
        if (drives) {
231
244
                drive = nautilus_burn_drive_ref ((NautilusBurnDrive*) drives->data);
 
245
        }
232
246
 
233
247
        g_list_foreach (drives, (GFunc)nautilus_burn_drive_unref, NULL);
234
248
        g_list_free (drives);
268
282
{
269
283
        rb_debug ("Freeing rb_recorder pipeline");
270
284
 
271
 
        if (recorder->priv->pipeline == NULL)
 
285
        if (recorder->priv->pipeline == NULL) {
272
286
                return;
 
287
        }
273
288
 
274
289
        if (recorder->priv->tick_timeout_id > 0) {
275
290
                g_source_remove (recorder->priv->tick_timeout_id);
326
341
 
327
342
        track->type = NAUTILUS_BURN_RECORDER_TRACK_TYPE_AUDIO;
328
343
        track->contents.audio.filename = filename;
329
 
        if (cdtext)
 
344
        if (cdtext) {
330
345
                track->contents.audio.cdtext = g_strdup (cdtext);
 
346
        }
331
347
 
332
348
        recorder->priv->tracks = g_list_append (recorder->priv->tracks, track);
333
349
 
341
357
{
342
358
        rb_debug ("EOS");
343
359
 
344
 
        if (recorder->priv->pipeline)
 
360
        if (recorder->priv->pipeline) {
345
361
                gst_element_set_state (recorder->priv->pipeline, GST_STATE_NULL);
 
362
        }
346
363
 
347
364
        g_signal_emit (G_OBJECT (recorder), rb_recorder_signals [EOS], 0);
348
365
}
356
373
                       signal->error);
357
374
 
358
375
        /* close if not already closing */
359
 
        if (signal->object->priv->src_uri != NULL)
 
376
        if (signal->object->priv->src_uri != NULL) {
360
377
                rb_recorder_close (signal->object, NULL);
 
378
        }
361
379
 
362
380
        g_object_unref (signal->object);
363
381
        g_error_free (signal->error);
410
428
                       error);
411
429
 
412
430
        /* close if not already closing */
413
 
        if (recorder->priv->src_uri != NULL)
 
431
        if (recorder->priv->src_uri != NULL) {
414
432
                rb_recorder_close (recorder, NULL);
 
433
        }
415
434
 
416
435
        g_object_unref (recorder);
417
436
        g_error_free (error);
474
493
        /* Only link audio. */
475
494
        caps = gst_pad_get_caps (pad);
476
495
        str = gst_caps_get_structure (caps, 0);
477
 
        if (!g_strrstr (gst_structure_get_name (str), "audio")) {
 
496
        if (! g_strrstr (gst_structure_get_name (str), "audio")) {
478
497
                gst_caps_unref (caps);
479
498
                return;
480
499
        }
481
500
 
482
501
        gst_caps_unref (caps);
483
502
#ifdef HAVE_GSTREAMER_0_10
484
 
        if (gst_pad_link (pad, audio_pad))
 
503
        if (gst_pad_link (pad, audio_pad)) {
485
504
                recorder->priv->got_audio_pad = TRUE;
 
505
        }
486
506
#endif
487
507
}
488
508
 
513
533
         */
514
534
 
515
535
        recorder->priv->pipeline = gst_pipeline_new ("pipeline");
516
 
        if (!recorder->priv->pipeline) {
 
536
        if (! recorder->priv->pipeline) {
517
537
                g_set_error (error,
518
538
                             RB_RECORDER_ERROR,
519
539
                             RB_RECORDER_ERROR_GENERAL,
543
563
 
544
564
#ifdef HAVE_GSTREAMER_0_8
545
565
        recorder->priv->src_pad = gst_element_get_pad (recorder->priv->src, "src");
546
 
        g_assert (recorder->priv->src_pad); /* TODO: GError */
 
566
        if (recorder->priv->src_pad == NULL) {
 
567
                g_set_error (error,
 
568
                             RB_RECORDER_ERROR,
 
569
                             RB_RECORDER_ERROR_INTERNAL,
 
570
                             _("Could not access source pad"));
 
571
                return;
 
572
        }
547
573
#endif
548
574
 
549
575
        /* The queue */
607
633
                g_signal_connect_object (G_OBJECT (recorder->priv->pipeline), "eos",
608
634
                                         G_CALLBACK (eos_cb), recorder, 0);
609
635
#elif HAVE_GSTREAMER_0_10
610
 
        g_object_set (recorder->priv->capsfilter, "filter-caps",  filtercaps, NULL);
 
636
        g_object_set (recorder->priv->capsfilter, "caps",  filtercaps, NULL);
611
637
 
612
638
        gst_element_link_many (recorder->priv->src,
613
639
                               recorder->priv->typefind,
647
673
                                              ext - track->contents.audio.filename);
648
674
 
649
675
                if (g_file_test (track->contents.audio.filename, G_FILE_TEST_EXISTS)
650
 
                    && unlink (track->contents.audio.filename) != 0)
 
676
                    && unlink (track->contents.audio.filename) != 0) {
651
677
                        g_warning (_("Unable to unlink '%s'"), track->contents.audio.filename);
 
678
                }
 
679
 
652
680
                if (lockfile) {
653
681
                        /* remove lockfile created by mkstemp */
654
682
                        if (unlink (lockfile) != 0)
668
696
 
669
697
        rb_recorder_close (recorder, NULL);
670
698
 
671
 
        if (recorder->priv->recorder)
 
699
        if (recorder->priv->recorder != NULL) {
672
700
                nautilus_burn_recorder_cancel (recorder->priv->recorder, FALSE);
 
701
        }
673
702
 
674
703
        g_list_foreach (recorder->priv->tracks,
675
704
                        (GFunc)recorder_track_free,
676
705
                        NULL);
677
706
        g_list_free (recorder->priv->tracks);
678
707
 
679
 
        G_OBJECT_CLASS (parent_class)->finalize (object);
 
708
        G_OBJECT_CLASS (rb_recorder_parent_class)->finalize (object);
680
709
}
681
710
 
682
711
RBRecorder *
702
731
        return recorder;
703
732
}
704
733
 
705
 
static gboolean
706
 
tick_timeout_cb (RBRecorder *recorder)
707
 
{
708
 
        gint64 position, total;
709
 
        double fraction;
710
 
        double rate;
711
 
        double elapsed;
712
 
        double secs;
713
 
        GstFormat format = GST_FORMAT_BYTES;
714
 
#ifdef HAVE_GSTREAMER_0_10
 
734
#ifdef HAVE_GSTREAMER_0_8
 
735
static gboolean
 
736
tick_timeout_cb (RBRecorder *recorder)
 
737
{
 
738
        gint64 position, total;
 
739
        double fraction;
 
740
        double rate;
 
741
        double elapsed;
 
742
        double secs;
 
743
        GstFormat format = GST_FORMAT_BYTES;
 
744
 
 
745
        g_return_val_if_fail (recorder != NULL, FALSE);
 
746
        g_return_val_if_fail (RB_IS_RECORDER (recorder), FALSE);
 
747
        g_return_val_if_fail (recorder->priv != NULL, FALSE);
 
748
        g_return_val_if_fail (recorder->priv->pipeline != NULL, FALSE);
 
749
 
 
750
        if (gst_element_get_state (recorder->priv->pipeline) != GST_STATE_PLAYING) {
 
751
                recorder->priv->tick_timeout_id = 0;
 
752
                if (recorder->priv->start_timer) {
 
753
                        g_timer_destroy (recorder->priv->start_timer);
 
754
                        recorder->priv->start_timer = NULL;
 
755
                }
 
756
                return FALSE;
 
757
        }
 
758
 
 
759
        if (!gst_pad_query (recorder->priv->src_pad, GST_QUERY_POSITION, &format, &position)) {
 
760
                g_warning (_("Could not get current track position"));
 
761
                return TRUE;
 
762
        }
 
763
 
 
764
        if (!gst_pad_query (recorder->priv->src_pad, GST_QUERY_TOTAL, &format, &total)) {
 
765
                g_warning (_("Could not get current track position"));
 
766
                return TRUE;
 
767
        }
 
768
 
 
769
        if (! recorder->priv->start_timer) {
 
770
                recorder->priv->start_timer = g_timer_new ();
 
771
                recorder->priv->start_pos = position;
 
772
        }
 
773
 
 
774
        fraction = (float)position / (float)total;
 
775
 
 
776
        elapsed = g_timer_elapsed (recorder->priv->start_timer, NULL);
 
777
 
 
778
        rate = (double)(position - recorder->priv->start_pos) / elapsed;
 
779
 
 
780
        if (rate >= 1) {
 
781
                secs = ceil ((total - position) / rate);
 
782
        } else {
 
783
                secs = -1;
 
784
        }
 
785
 
 
786
        if (fraction != recorder->priv->progress) {
 
787
                recorder->priv->progress = fraction;
 
788
                g_signal_emit (G_OBJECT (recorder),
 
789
                               rb_recorder_signals [TRACK_PROGRESS_CHANGED],
 
790
                               0,
 
791
                               fraction, (long)secs);
 
792
        }
 
793
 
 
794
        /* Extra kick in the pants to keep things moving on a busy system */
 
795
        gst_bin_iterate (GST_BIN (recorder->priv->pipeline));
 
796
 
 
797
        return TRUE;
 
798
}
 
799
#elif HAVE_GSTREAMER_0_10
 
800
static gboolean
 
801
tick_timeout_cb (RBRecorder *recorder)
 
802
{
 
803
        gint64 position, total;
 
804
        double fraction;
 
805
        double rate;
 
806
        double elapsed;
 
807
        double secs;
 
808
        GstFormat format = GST_FORMAT_BYTES;
715
809
        GstState  state;
716
 
#endif
717
810
 
718
811
        g_return_val_if_fail (recorder != NULL, FALSE);
719
812
        g_return_val_if_fail (RB_IS_RECORDER (recorder), FALSE);
720
813
        g_return_val_if_fail (recorder->priv != NULL, FALSE);
721
814
        g_return_val_if_fail (recorder->priv->pipeline != NULL, FALSE);
722
815
 
723
 
#ifdef HAVE_GSTREAMER_0_8
724
 
        if (gst_element_get_state (recorder->priv->pipeline) != GST_STATE_PLAYING) {
725
 
#elif HAVE_GSTREAMER_0_10
726
816
        if (!gst_element_get_state (recorder->priv->pipeline, &state,  NULL, 3 * GST_SECOND)) {
727
817
                g_warning (_("Could not retrieve state from processing pipeline"));
728
818
                return TRUE;
729
819
        }
 
820
 
730
821
        if (state != GST_STATE_PLAYING) {               
731
 
#endif
732
822
                recorder->priv->tick_timeout_id = 0;
733
823
                if (recorder->priv->start_timer) {
734
824
                        g_timer_destroy (recorder->priv->start_timer);
737
827
                return FALSE;
738
828
        }
739
829
 
740
 
#ifdef  HAVE_GSTREAMER_0_8
741
 
        if (!gst_pad_query (recorder->priv->src_pad, GST_QUERY_POSITION, &format, &position)) {
742
 
                g_warning (_("Could not get current track position"));
743
 
                return TRUE;
744
 
        }
745
 
 
746
 
        if (!gst_pad_query (recorder->priv->src_pad, GST_QUERY_TOTAL, &format, &total)) {
747
 
#elif HAVE_GSTREAMER_0_10
748
 
                if (!gst_element_query_position (recorder->priv->src, &format, &position) || !gst_element_query_duration (recorder->priv->src, &format, &total)) {
749
 
#endif
 
830
        if (!gst_element_query_position (recorder->priv->src, &format, &position) || !gst_element_query_duration (recorder->priv->src, &format, &total)) {
750
831
                g_warning (_("Could not get current track position"));
751
832
                return TRUE;
752
833
        }
762
843
 
763
844
        rate = (double)(position - recorder->priv->start_pos) / elapsed;
764
845
 
765
 
        if (rate >= 1)
 
846
        if (rate >= 1) {
766
847
                secs = ceil ((total - position) / rate);
767
 
        else
 
848
        } else {
768
849
                secs = -1;
 
850
        }
769
851
 
770
852
        if (fraction != recorder->priv->progress) {
771
853
                recorder->priv->progress = fraction;
775
857
                               fraction, (long)secs);
776
858
        }
777
859
 
778
 
#ifdef HAVE_GSTREAMER_0_8
779
 
        /* Extra kick in the pants to keep things moving on a busy system */
780
 
        gst_bin_iterate (GST_BIN (recorder->priv->pipeline));
781
 
#endif
782
 
 
783
860
        return TRUE;
784
861
}
785
 
 
 
862
#endif
 
863
 
 
864
 
 
865
#ifdef HAVE_GSTREAMER_0_8
786
866
static gboolean
787
867
rb_recorder_sync_pipeline (RBRecorder *recorder,
788
868
                           GError    **error)
795
875
        rb_debug ("Syncing pipeline");
796
876
        if (recorder->priv->playing) {
797
877
                rb_debug ("Playing pipeline");
798
 
#ifdef HAVE_GSTREAMER_0_8
799
878
                if (gst_element_set_state (recorder->priv->pipeline, GST_STATE_PLAYING) == GST_STATE_FAILURE) {
800
 
#elif HAVE_GSTREAMER_0_10
801
 
                if (gst_element_set_state (recorder->priv->pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
802
 
#endif
803
879
                        g_set_error (error,
804
880
                                     RB_RECORDER_ERROR,
805
881
                                     RB_RECORDER_ERROR_GENERAL,
806
882
                                     _("Could not start pipeline playing"));
807
883
                        return FALSE;
808
884
                }
809
 
#ifdef HAVE_GSTREAMER_0_8
 
885
 
810
886
                recorder->priv->idle_id = g_idle_add ((GSourceFunc)gst_bin_iterate,
811
887
                                                      GST_BIN (recorder->priv->pipeline));
812
888
                recorder->priv->tick_timeout_id = g_timeout_add (200,
813
889
                                                                 (GSourceFunc)tick_timeout_cb,
814
890
                                                                 recorder);
815
 
#elif HAVE_GSTREAMER_0_10
816
 
                recorder->priv->tick_timeout_id = 
817
 
                        g_timeout_add (200, (GSourceFunc)tick_timeout_cb, recorder);
818
 
#endif
819
891
        } else {
820
892
                rb_debug ("Pausing pipeline");
821
 
#ifdef HAVE_GSTREAMER_0_8
822
893
                if (gst_element_set_state (recorder->priv->pipeline, GST_STATE_PAUSED) == GST_STATE_FAILURE) {
823
 
#elif HAVE_GSTREAMER_0_10
824
 
                if (gst_element_set_state (recorder->priv->pipeline, GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE) {
825
 
#endif
826
894
                        g_set_error (error,
827
895
                                     RB_RECORDER_ERROR,
828
896
                                     RB_RECORDER_ERROR_GENERAL,
829
897
                                     _("Could not pause playback"));
830
898
                        return FALSE;
831
899
                }
832
 
#ifdef HAVE_GSTREAMER_0_8
833
900
                if (recorder->priv->idle_id > 0) {
834
901
                        g_source_remove (recorder->priv->idle_id);
835
902
                        recorder->priv->idle_id = 0;
836
903
                }
 
904
                if (recorder->priv->tick_timeout_id > 0) {
 
905
                        g_source_remove (recorder->priv->tick_timeout_id);
 
906
                        recorder->priv->tick_timeout_id = 0;
 
907
                        if (recorder->priv->start_timer) {
 
908
                                g_timer_destroy (recorder->priv->start_timer);
 
909
                                recorder->priv->start_timer = NULL;
 
910
                        }
 
911
                }
 
912
        }
 
913
        return TRUE;
 
914
}
 
915
 
 
916
#elif HAVE_GSTREAMER_0_10
 
917
 
 
918
static gboolean
 
919
rb_recorder_sync_pipeline (RBRecorder *recorder,
 
920
                           GError    **error)
 
921
{
 
922
        g_return_val_if_fail (recorder != NULL, FALSE);
 
923
        g_return_val_if_fail (RB_IS_RECORDER (recorder), FALSE);
 
924
        g_return_val_if_fail (recorder->priv != NULL, FALSE);
 
925
        g_return_val_if_fail (recorder->priv->pipeline != NULL, FALSE);
 
926
        
 
927
        rb_debug ("Syncing pipeline");
 
928
        if (recorder->priv->playing) {
 
929
                rb_debug ("Playing pipeline");
 
930
                if (gst_element_set_state (recorder->priv->pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
 
931
                        g_set_error (error,
 
932
                                     RB_RECORDER_ERROR,
 
933
                                     RB_RECORDER_ERROR_GENERAL,
 
934
                                     _("Could not start pipeline playing"));
 
935
                        return FALSE;
 
936
                }
 
937
 
 
938
                recorder->priv->tick_timeout_id = g_timeout_add (200, (GSourceFunc)tick_timeout_cb, recorder);
 
939
        } else {
 
940
                rb_debug ("Pausing pipeline");
 
941
                if (gst_element_set_state (recorder->priv->pipeline, GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE) {
 
942
                        g_set_error (error,
 
943
                                     RB_RECORDER_ERROR,
 
944
                                     RB_RECORDER_ERROR_GENERAL,
 
945
                                     _("Could not pause playback"));
 
946
                        return FALSE;
 
947
                }
 
948
                if (recorder->priv->tick_timeout_id > 0) {
 
949
                        g_source_remove (recorder->priv->tick_timeout_id);
 
950
                        recorder->priv->tick_timeout_id = 0;
 
951
                        if (recorder->priv->start_timer) {
 
952
                                g_timer_destroy (recorder->priv->start_timer);
 
953
                                recorder->priv->start_timer = NULL;
 
954
                        }
 
955
                }
 
956
        }
 
957
        return TRUE;
 
958
}
837
959
#endif
838
 
                if (recorder->priv->tick_timeout_id > 0) {
839
 
                        g_source_remove (recorder->priv->tick_timeout_id);
840
 
                        recorder->priv->tick_timeout_id = 0;
841
 
                        if (recorder->priv->start_timer) {
842
 
                                g_timer_destroy (recorder->priv->start_timer);
843
 
                                recorder->priv->start_timer = NULL;
844
 
                        }
845
 
                }
846
 
        }
847
 
        return TRUE;
848
 
}
849
960
 
850
961
void
851
962
rb_recorder_close (RBRecorder *recorder,
866
977
        g_free (recorder->priv->dest_file);
867
978
        recorder->priv->dest_file = NULL;
868
979
 
869
 
        if (recorder->priv->pipeline == NULL)
 
980
        if (recorder->priv->pipeline == NULL) {
870
981
                return;
 
982
        }
871
983
 
872
984
        rb_recorder_gst_free_pipeline (recorder);
873
985
}
930
1042
        }
931
1043
 
932
1044
        rb_recorder_construct (recorder, src_uri, error);
933
 
        if (error && *error)
 
1045
        if (error && *error) {
934
1046
                return;
 
1047
        }
935
1048
                
936
1049
#ifdef HAVE_GSTREAMER_0_8
937
1050
        if (recorder->priv->idle_id > 0) {
961
1074
 
962
1075
        add_track (recorder, cdtext);
963
1076
 
964
 
        if (!rb_recorder_sync_pipeline (recorder, error)) {
 
1077
        if (! rb_recorder_sync_pipeline (recorder, error)) {
965
1078
                rb_recorder_close (recorder, NULL);
966
1079
        }
967
1080
}
996
1109
        g_return_if_fail (RB_IS_RECORDER (recorder));
997
1110
        g_return_if_fail (recorder->priv != NULL);
998
1111
 
999
 
        if (!recorder->priv->playing)
 
1112
        if (! recorder->priv->playing) {
1000
1113
                return;
 
1114
        }
1001
1115
 
1002
1116
        recorder->priv->playing = FALSE;
1003
1117
 
1006
1120
        rb_recorder_sync_pipeline (recorder, NULL);
1007
1121
}
1008
1122
 
 
1123
#if !NAUTILUS_BURN_CHECK_VERSION(2,15,3)
 
1124
static const char *
 
1125
nautilus_burn_drive_get_device (NautilusBurnDrive *drive)
 
1126
{
 
1127
        g_return_val_if_fail (drive != NULL, NULL);
 
1128
 
 
1129
        return drive->device;
 
1130
}
 
1131
#endif
 
1132
 
1009
1133
char *
1010
1134
rb_recorder_get_device (RBRecorder  *recorder,
1011
1135
                        GError     **error)
1015
1139
        g_return_val_if_fail (recorder != NULL, NULL);
1016
1140
        g_return_val_if_fail (RB_IS_RECORDER (recorder), NULL);
1017
1141
 
1018
 
        if (error)
 
1142
        if (error) {
1019
1143
                *error = NULL;
 
1144
        }
1020
1145
 
1021
1146
        drive = recorder->priv->drive;
1022
1147
 
1028
1153
                return NULL;
1029
1154
        }
1030
1155
 
1031
 
        return g_strdup (drive->device);
 
1156
        return g_strdup (nautilus_burn_drive_get_device (drive));
1032
1157
}
1033
1158
 
1034
1159
gboolean
1036
1161
                        const char  *device,
1037
1162
                        GError     **error)
1038
1163
{
 
1164
#if NAUTILUS_BURN_CHECK_VERSION(2,15,3)
 
1165
        NautilusBurnDriveMonitor *monitor;
 
1166
#else
1039
1167
        GList *drives;
1040
1168
        GList *tmp;
 
1169
#endif
 
1170
        int type;
1041
1171
 
1042
1172
        g_return_val_if_fail (recorder != NULL, FALSE);
1043
1173
        g_return_val_if_fail (RB_IS_RECORDER (recorder), FALSE);
1044
1174
        g_return_val_if_fail (device != NULL, FALSE);
1045
1175
 
1046
 
        if (error)
 
1176
        if (error) {
1047
1177
                *error = NULL;
 
1178
        }
1048
1179
 
1049
 
        if (recorder->priv->drive) {
 
1180
        if (recorder->priv->drive != NULL) {
1050
1181
                nautilus_burn_drive_unref (recorder->priv->drive);
1051
1182
                recorder->priv->drive = NULL;
1052
1183
        }
1053
1184
 
 
1185
        type = 0;
 
1186
 
 
1187
#if NAUTILUS_BURN_CHECK_VERSION(2,15,3)
 
1188
        monitor = nautilus_burn_get_drive_monitor ();
 
1189
        recorder->priv->drive = nautilus_burn_drive_monitor_get_drive_for_device (monitor, device);
 
1190
        if (recorder->priv->drive != NULL) {
 
1191
                type = nautilus_burn_drive_get_drive_type (recorder->priv->drive);
 
1192
        }
 
1193
#else
1054
1194
        drives = nautilus_burn_drive_get_list (TRUE, FALSE);
1055
1195
 
1056
1196
        for (tmp = drives; tmp != NULL; tmp = tmp->next) {
1065
1205
        }
1066
1206
        g_list_free (drives);
1067
1207
 
 
1208
        type = recorder->priv->drive->type;
 
1209
#endif
 
1210
 
1068
1211
        if (! recorder->priv->drive) {
1069
1212
                g_set_error (error,
1070
1213
                             RB_RECORDER_ERROR,
1074
1217
                return FALSE;
1075
1218
        }
1076
1219
 
1077
 
        if (! (recorder->priv->drive->type & NAUTILUS_BURN_DRIVE_TYPE_CD_RECORDER)) {
 
1220
        if (! (type & NAUTILUS_BURN_DRIVE_TYPE_CD_RECORDER)) {
1078
1221
                g_set_error (error,
1079
1222
                             RB_RECORDER_ERROR,
1080
1223
                             RB_RECORDER_ERROR_GENERAL,
1222
1365
        drive = rb_recorder_get_default_drive ();
1223
1366
 
1224
1367
        if (drive) {
1225
 
                device = g_strdup (drive->device);
 
1368
                device = g_strdup (nautilus_burn_drive_get_device (drive));
1226
1369
                nautilus_burn_drive_unref (drive);
1227
1370
        }
1228
1371
 
1249
1392
                return -1;
1250
1393
        }
1251
1394
 
 
1395
#if NAUTILUS_BURN_CHECK_VERSION(2,15,3)
 
1396
        size = nautilus_burn_drive_get_media_capacity (recorder->priv->drive);
 
1397
#else
1252
1398
        size = nautilus_burn_drive_get_media_size (recorder->priv->drive);
 
1399
#endif
 
1400
 
1253
1401
        if (size > 0) {
1254
1402
#ifdef NAUTILUS_BURN_DRIVE_SIZE_TO_TIME
1255
1403
                secs = NAUTILUS_BURN_DRIVE_SIZE_TO_TIME (size);
1263
1411
        return secs;
1264
1412
}
1265
1413
 
 
1414
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
 
1415
#define GNUC_PACKED                             \
 
1416
  __attribute__((packed))
 
1417
#else   /* !__GNUC__ */
 
1418
#pragma pack(2)
 
1419
#endif
 
1420
 
1266
1421
/* Copyright (C) Bastien Nocera */
1267
1422
/* From xine-lib, whoop */
1268
 
typedef struct __attribute__((__packed__)) {
 
1423
typedef struct GNUC_PACKED {
1269
1424
        gint16   wFormatTag;
1270
1425
        gint16   nChannels;
1271
1426
        gint32   nSamplesPerSec;
1274
1429
        gint16   wBitsPerSample;
1275
1430
        gint16   cbSize;
1276
1431
} waveformat;
1277
 
#ifndef ATTRIBUTE_PACKED
 
1432
 
 
1433
#ifndef GNUC_PACKED
1278
1434
#pragma pack()
1279
1435
#endif
1280
1436
 
1363
1519
        GList *l;
1364
1520
        gint64 total = 0;
1365
1521
 
1366
 
        if (!recorder->priv->tracks)
 
1522
        if (! recorder->priv->tracks) {
1367
1523
                return -1;
 
1524
        }
1368
1525
 
1369
1526
        for (l = recorder->priv->tracks; l; l = l->next) {
1370
1527
                NautilusBurnRecorderTrack *track = l->data;
1486
1643
                        msg = g_strdup (_("There was an error writing to the CD"));
1487
1644
                }
1488
1645
 
 
1646
                rb_debug ("Recorder error: %s", msg);
 
1647
 
1489
1648
                g_set_error (error,
1490
1649
                             RB_RECORDER_ERROR,
1491
1650
                             RB_RECORDER_ERROR_GENERAL,
1500
1659
        g_object_unref (cdrecorder);
1501
1660
        recorder->priv->recorder = NULL;
1502
1661
 
 
1662
        rb_debug ("Recorder done: %d", result);
 
1663
 
1503
1664
        return result;
1504
1665
}