Initialize Tizen 2.3
[framework/multimedia/gst-plugins-ext0.10.git] / dashdemux / src / gstfragment.c
1 /* GStreamer
2  * Copyright (C) 2011 Andoni Morales Alastruey <ylatuya@gmail.com>
3  *
4  * gstfragment.c:
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 #include <glib.h>
23 #include <gst/base/gsttypefindhelper.h>
24 #include <gst/base/gstadapter.h>
25 #include "glibcompat.h"
26 #include "gstfragmented.h"
27 #include "gstfragment.h"
28
29 #define GST_CAT_DEFAULT fragmented_debug
30
31 #define GST_FRAGMENT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_FRAGMENT, GstFragmentPrivate))
32
33 enum
34 {
35   PROP_0,
36   PROP_INDEX,
37   PROP_NAME,
38   PROP_DURATION,
39   PROP_DISCONTINOUS,
40   PROP_BUFFER_LIST,
41   PROP_CAPS,
42   PROP_LAST
43 };
44
45 struct _GstFragmentPrivate
46 {
47   GstBuffer *buffer;
48   GstAdapter *adapter;
49 };
50
51 G_DEFINE_TYPE (GstFragment, gst_fragment, G_TYPE_OBJECT);
52
53 static void gst_fragment_dispose (GObject * object);
54 static void gst_fragment_finalize (GObject * object);
55
56 static void
57 gst_fragment_get_property (GObject * object,
58     guint property_id, GValue * value, GParamSpec * pspec)
59 {
60   GstFragment *fragment = GST_FRAGMENT (object);
61
62   switch (property_id) {
63     case PROP_INDEX:
64       g_value_set_uint (value, fragment->index);
65       break;
66
67     case PROP_NAME:
68       g_value_set_string (value, fragment->name);
69       break;
70
71     case PROP_DURATION:
72       g_value_set_uint64 (value, fragment->stop_time - fragment->start_time);
73       break;
74
75     case PROP_DISCONTINOUS:
76       g_value_set_boolean (value, fragment->discontinuous);
77       break;
78
79     default:
80       /* We don't have any other property... */
81       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
82       break;
83   }
84 }
85
86
87
88 static void
89 gst_fragment_class_init (GstFragmentClass * klass)
90 {
91   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
92
93   g_type_class_add_private (klass, sizeof (GstFragmentPrivate));
94
95   gobject_class->get_property = gst_fragment_get_property;
96   gobject_class->dispose = gst_fragment_dispose;
97   gobject_class->finalize = gst_fragment_finalize;
98
99   g_object_class_install_property (gobject_class, PROP_INDEX,
100       g_param_spec_uint ("index", "Index", "Index of the fragment", 0,
101           G_MAXUINT, 0, G_PARAM_READABLE));
102
103   g_object_class_install_property (gobject_class, PROP_NAME,
104       g_param_spec_string ("name", "Name",
105           "Name of the fragment (eg:fragment-12.ts)", NULL, G_PARAM_READABLE));
106
107   g_object_class_install_property (gobject_class, PROP_DISCONTINOUS,
108       g_param_spec_boolean ("discontinuous", "Discontinous",
109           "Whether this fragment has a discontinuity or not",
110           FALSE, G_PARAM_READABLE));
111
112   g_object_class_install_property (gobject_class, PROP_DURATION,
113       g_param_spec_uint64 ("duration", "Fragment duration",
114           "Duration of the fragment", 0, G_MAXUINT64, 0, G_PARAM_READABLE));
115
116 }
117
118 static void
119 gst_fragment_init (GstFragment * fragment)
120 {
121   GstFragmentPrivate *priv;
122
123   fragment->priv = priv = GST_FRAGMENT_GET_PRIVATE (fragment);
124
125   priv->adapter = gst_adapter_new ();
126   fragment->download_start_time = g_get_real_time ();
127   fragment->start_time = 0;
128   fragment->stop_time = 0;
129   fragment->index = 0;
130   fragment->name = g_strdup ("");
131   fragment->completed = FALSE;
132   fragment->discontinuous = FALSE;
133 }
134
135 GstFragment *
136 gst_fragment_new (void)
137 {
138   return GST_FRAGMENT (g_object_new (GST_TYPE_FRAGMENT, NULL));
139 }
140
141 static void
142 gst_fragment_finalize (GObject * gobject)
143 {
144   GstFragment *fragment = GST_FRAGMENT (gobject);
145
146   g_free (fragment->name);
147
148   G_OBJECT_CLASS (gst_fragment_parent_class)->finalize (gobject);
149 }
150
151 void
152 gst_fragment_dispose (GObject * object)
153 {
154   GstFragmentPrivate *priv = GST_FRAGMENT (object)->priv;
155
156   if (priv->buffer != NULL) {
157     gst_buffer_unref (priv->buffer);
158     priv->buffer = NULL;
159   }
160
161   if (priv->adapter != NULL) {
162     g_object_unref (priv->adapter);
163     priv->adapter = NULL;
164   }
165
166   G_OBJECT_CLASS (gst_fragment_parent_class)->dispose (object);
167 }
168
169 GstBuffer *
170 gst_fragment_get_buffer (GstFragment * fragment)
171 {
172   g_return_val_if_fail (fragment != NULL, NULL);
173
174   if (!fragment->completed)
175     return NULL;
176
177   if(!fragment->priv->buffer) {
178     fragment->priv->buffer = gst_adapter_take_buffer(fragment->priv->adapter,
179                               gst_adapter_available(fragment->priv->adapter));
180   }
181
182   return gst_buffer_ref(fragment->priv->buffer);
183 }
184
185 guint64
186 gst_fragment_get_total_size (GstFragment * fragment)
187 {
188   g_return_val_if_fail (fragment != NULL, 0);
189
190   if (fragment->priv->buffer)
191     return GST_BUFFER_SIZE(fragment->priv->buffer);
192
193   return gst_adapter_available(fragment->priv->adapter);
194 }
195
196
197
198 gboolean
199 gst_fragment_add_buffer (GstFragment * fragment, GstBuffer * buffer)
200 {
201   g_return_val_if_fail (fragment != NULL, FALSE);
202   g_return_val_if_fail (buffer != NULL, FALSE);
203
204   if (fragment->completed) {
205     GST_WARNING ("Fragment is completed, could not add more buffers");
206     return FALSE;
207   }
208
209   gst_adapter_push(fragment->priv->adapter, buffer);
210   return TRUE;
211 }