summaryrefslogtreecommitdiff
path: root/legacy/emotion/src/modules/gstreamer/emotion_gstreamer_pipeline_cdda.c
blob: c9ab41e2d658b1ea4a1c1c9136696292928ed6c4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/*
 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
 */
#include "emotion_gstreamer.h"
#include "emotion_gstreamer_pipeline.h"


static Emotion_Audio_Sink *_emotion_audio_sink_new (Emotion_Gstreamer_Video *ev);

static void _emotion_audio_sink_free (Emotion_Gstreamer_Video *ev, Emotion_Audio_Sink *asink);

int
emotion_pipeline_cdda_build (void *video, const char * device, unsigned int track)
{
   GstElement              *cdiocddasrc;
   Emotion_Video_Sink      *vsink;
   Emotion_Audio_Sink      *asink;
   Emotion_Gstreamer_Video *ev;
/*    GstFormat                format; */
/*    gint64                  tracks_count; */

   ev = (Emotion_Gstreamer_Video *)video;
   if (!ev) return 0;

   cdiocddasrc = gst_element_factory_make ("cdiocddasrc", "src");
   if (!cdiocddasrc) {
     g_print ("cdiocddasrc element missing. Install it.\n");
     goto failure_cdiocddasrc;
   }

   if (device)
      g_object_set (G_OBJECT (cdiocddasrc), "device", device, NULL);

   g_object_set (G_OBJECT (cdiocddasrc), "track", track, NULL);

   asink = _emotion_audio_sink_new (ev);
   if (!asink)
     goto failure_emotion_sink;

   asink->sink = emotion_audio_sink_create (ev,  1);
   if (!asink->sink)
     goto failure_gstreamer_sink;

   gst_bin_add_many((GST_BIN (ev->pipeline)), cdiocddasrc, asink->sink, NULL);

   if (!gst_element_link (cdiocddasrc, asink->sink))
     goto failure_link;

   vsink = emotion_visualization_sink_create (ev, asink);
   if (!vsink) goto failure_link;

   if (!emotion_pipeline_pause (ev->pipeline))
     goto failure_gstreamer_pause;

   {
      GstQuery *query;
      GstPad   *pad;
      GstCaps  *caps;
      GstStructure *structure;

      /* should always be found */
      pad = gst_element_get_pad (cdiocddasrc, "src");

      caps = gst_pad_get_caps (pad);
      structure = gst_caps_get_structure (GST_CAPS (caps), 0);

      gst_structure_get_int (structure, "channels", &asink->channels);
      gst_structure_get_int (structure, "rate", &asink->samplerate);

      gst_caps_unref (caps);

      query = gst_query_new_duration (GST_FORMAT_TIME);
      if (gst_pad_query (pad, query)) {
         gint64 time;

         gst_query_parse_duration (query, NULL, &time);
         asink->length_time = (double)time / (double)GST_SECOND;
         vsink->length_time = asink->length_time;
      }
      gst_query_unref (query);
      gst_object_unref (GST_OBJECT (pad));
   }

   return 1;

 failure_gstreamer_pause:
   emotion_video_sink_free (ev, vsink);
 failure_link:
   gst_bin_remove (GST_BIN (ev->pipeline), asink->sink);
 failure_gstreamer_sink:
   _emotion_audio_sink_free (ev, asink);
 failure_emotion_sink:
   gst_bin_remove (GST_BIN (ev->pipeline), cdiocddasrc);
 failure_cdiocddasrc:

   return 0;
}

static Emotion_Audio_Sink *
_emotion_audio_sink_new (Emotion_Gstreamer_Video *ev)
{
   Emotion_Audio_Sink *asink;

   if (!ev) return NULL;

   asink = (Emotion_Audio_Sink *)malloc (sizeof (Emotion_Audio_Sink));
   if (!asink) return NULL;

   if (!ecore_list_append (ev->audio_sinks, asink)) {
     free (asink);
     return NULL;
   }
   return asink;
}

static void
_emotion_audio_sink_free (Emotion_Gstreamer_Video *ev, Emotion_Audio_Sink *asink)
{
   if (!ev || !asink) return;

   if (ecore_list_goto (ev->audio_sinks, asink)) {
      ecore_list_remove (ev->audio_sinks);
      free (asink);
   }
}