Skip to content

Commit 1c0049e

Browse files
committed
clapper: Make timeline insert/remove work from any thread
Detect and auto switch thread to main if done from a different one. With this, apps can still continue to implement thread switch and doing multiple insertions/deletions within single main thread invoke or simply call this function from a different thread for convenience.
1 parent 7f326e6 commit 1c0049e

5 files changed

Lines changed: 135 additions & 73 deletions

File tree

src/lib/clapper/clapper-timeline-private.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,10 @@ gboolean clapper_timeline_set_toc (ClapperTimeline *timeline, GstToc *toc, gbool
3434
G_GNUC_INTERNAL
3535
void clapper_timeline_refresh (ClapperTimeline *timeline);
3636

37+
G_GNUC_INTERNAL
38+
void clapper_timeline_insert_marker_internal (ClapperTimeline *timeline, ClapperMarker *marker);
39+
40+
G_GNUC_INTERNAL
41+
void clapper_timeline_remove_marker_internal (ClapperTimeline *timeline, ClapperMarker *marker);
42+
3743
G_END_DECLS

src/lib/clapper/clapper-timeline.c

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "clapper-player-private.h"
3131
#include "clapper-reactables-manager-private.h"
3232
#include "clapper-features-manager-private.h"
33+
#include "clapper-utils-private.h"
3334

3435
#define GST_CAT_DEFAULT clapper_timeline_debug
3536
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
@@ -187,25 +188,12 @@ _take_marker_unlocked (ClapperTimeline *self, ClapperMarker *marker)
187188
return g_sequence_iter_get_position (iter);
188189
}
189190

190-
/**
191-
* clapper_timeline_insert_marker:
192-
* @timeline: a #ClapperTimeline
193-
* @marker: a #ClapperMarker
194-
*
195-
* Insert the #ClapperMarker into @timeline.
196-
*
197-
* Returns: %TRUE if inserted, %FALSE if marker was
198-
* already inserted into timeline.
199-
*/
200-
gboolean
201-
clapper_timeline_insert_marker (ClapperTimeline *self, ClapperMarker *marker)
191+
void
192+
clapper_timeline_insert_marker_internal (ClapperTimeline *self, ClapperMarker *marker)
202193
{
203194
gboolean success;
204195
gint position = 0;
205196

206-
g_return_val_if_fail (CLAPPER_IS_TIMELINE (self), FALSE);
207-
g_return_val_if_fail (CLAPPER_IS_MARKER (marker), FALSE);
208-
209197
GST_OBJECT_LOCK (self);
210198

211199
if ((success = !g_sequence_lookup (self->markers_seq, marker,
@@ -220,30 +208,34 @@ clapper_timeline_insert_marker (ClapperTimeline *self, ClapperMarker *marker)
220208

221209
clapper_timeline_post_item_updated (self);
222210
}
223-
224-
return success;
225211
}
226212

227213
/**
228-
* clapper_timeline_remove_marker:
214+
* clapper_timeline_insert_marker:
229215
* @timeline: a #ClapperTimeline
230216
* @marker: a #ClapperMarker
231217
*
232-
* Removes #ClapperMarker from the timeline.
233-
*
234-
* If marker was not in the @timeline, this function will do nothing,
235-
* so it is safe to call if unsure.
218+
* Insert the #ClapperMarker into @timeline.
236219
*/
237220
void
238-
clapper_timeline_remove_marker (ClapperTimeline *self, ClapperMarker *marker)
221+
clapper_timeline_insert_marker (ClapperTimeline *self, ClapperMarker *marker)
222+
{
223+
g_return_if_fail (CLAPPER_IS_TIMELINE (self));
224+
g_return_if_fail (CLAPPER_IS_MARKER (marker));
225+
226+
if (g_main_context_is_owner (g_main_context_default ()))
227+
clapper_timeline_insert_marker_internal (self, marker);
228+
else
229+
clapper_utils_timeline_insert_on_main_sync (self, marker);
230+
}
231+
232+
void
233+
clapper_timeline_remove_marker_internal (ClapperTimeline *self, ClapperMarker *marker)
239234
{
240235
GSequenceIter *iter;
241236
gint position = 0;
242237
gboolean success = FALSE;
243238

244-
g_return_if_fail (CLAPPER_IS_TIMELINE (self));
245-
g_return_if_fail (CLAPPER_IS_MARKER (marker));
246-
247239
GST_OBJECT_LOCK (self);
248240

249241
if ((iter = g_sequence_lookup (self->markers_seq, marker,
@@ -264,6 +256,25 @@ clapper_timeline_remove_marker (ClapperTimeline *self, ClapperMarker *marker)
264256
}
265257
}
266258

259+
/**
260+
* clapper_timeline_remove_marker:
261+
* @timeline: a #ClapperTimeline
262+
* @marker: a #ClapperMarker
263+
*
264+
* Removes #ClapperMarker from the timeline if present.
265+
*/
266+
void
267+
clapper_timeline_remove_marker (ClapperTimeline *self, ClapperMarker *marker)
268+
{
269+
g_return_if_fail (CLAPPER_IS_TIMELINE (self));
270+
g_return_if_fail (CLAPPER_IS_MARKER (marker));
271+
272+
if (g_main_context_is_owner (g_main_context_default ()))
273+
clapper_timeline_remove_marker_internal (self, marker);
274+
else
275+
clapper_utils_timeline_remove_on_main_sync (self, marker);
276+
}
277+
267278
/**
268279
* clapper_timeline_get_marker:
269280
* @timeline: a #ClapperTimeline

src/lib/clapper/clapper-timeline.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ CLAPPER_API
3838
G_DECLARE_FINAL_TYPE (ClapperTimeline, clapper_timeline, CLAPPER, TIMELINE, GstObject)
3939

4040
CLAPPER_API
41-
gboolean clapper_timeline_insert_marker (ClapperTimeline *timeline, ClapperMarker *marker);
41+
void clapper_timeline_insert_marker (ClapperTimeline *timeline, ClapperMarker *marker);
4242

4343
CLAPPER_API
4444
void clapper_timeline_remove_marker (ClapperTimeline *timeline, ClapperMarker *marker);

src/lib/clapper/clapper-utils-private.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
#include "clapper-utils.h"
2727
#include "clapper-queue.h"
2828
#include "clapper-media-item.h"
29+
#include "clapper-timeline.h"
30+
#include "clapper-marker.h"
2931

3032
G_BEGIN_DECLS
3133

@@ -44,6 +46,12 @@ void clapper_utils_queue_remove_on_main_sync (ClapperQueue *queue, ClapperMediaI
4446
G_GNUC_INTERNAL
4547
void clapper_utils_queue_clear_on_main_sync (ClapperQueue *queue);
4648

49+
G_GNUC_INTERNAL
50+
void clapper_utils_timeline_insert_on_main_sync (ClapperTimeline *timeline, ClapperMarker *marker);
51+
52+
G_GNUC_INTERNAL
53+
void clapper_utils_timeline_remove_on_main_sync (ClapperTimeline *timeline, ClapperMarker *marker);
54+
4755
G_GNUC_INTERNAL
4856
void clapper_utils_prop_notify_on_main_sync (GObject *object, GParamSpec *pspec);
4957

src/lib/clapper/clapper-utils.c

Lines changed: 83 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -17,26 +17,29 @@
1717
*/
1818

1919
#include "clapper-utils-private.h"
20+
#include "clapper-timeline-private.h"
2021
#include "../shared/clapper-shared-utils-private.h"
2122

2223
#define GST_CAT_DEFAULT clapper_utils_debug
2324
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
2425

2526
typedef enum
2627
{
27-
CLAPPER_UTILS_QUEUE_ALTER_APPEND = 1,
28-
CLAPPER_UTILS_QUEUE_ALTER_INSERT,
29-
CLAPPER_UTILS_QUEUE_ALTER_REMOVE,
30-
CLAPPER_UTILS_QUEUE_ALTER_CLEAR
31-
} ClapperUtilsQueueAlterMethod;
28+
CLAPPER_UTILS_LIST_ALTER_QUEUE_APPEND = 1,
29+
CLAPPER_UTILS_LIST_ALTER_QUEUE_INSERT,
30+
CLAPPER_UTILS_LIST_ALTER_QUEUE_REMOVE,
31+
CLAPPER_UTILS_LIST_ALTER_QUEUE_CLEAR,
32+
CLAPPER_UTILS_LIST_ALTER_TIMELINE_INSERT,
33+
CLAPPER_UTILS_LIST_ALTER_TIMELINE_REMOVE
34+
} ClapperUtilsListAlterMethod;
3235

3336
typedef struct
3437
{
35-
ClapperQueue *queue;
36-
ClapperMediaItem *item;
37-
ClapperMediaItem *after_item;
38-
ClapperUtilsQueueAlterMethod method;
39-
} ClapperUtilsQueueAlterData;
38+
GListModel *list;
39+
GObject *item;
40+
GObject *after_item;
41+
ClapperUtilsListAlterMethod method;
42+
} ClapperUtilsListAlterData;
4043

4144
typedef struct
4245
{
@@ -51,27 +54,26 @@ clapper_utils_initialize (void)
5154
"Clapper Utilities");
5255
}
5356

54-
static ClapperUtilsQueueAlterData *
55-
clapper_utils_queue_alter_data_new (ClapperQueue *queue,
56-
ClapperMediaItem *item, ClapperMediaItem *after_item,
57-
ClapperUtilsQueueAlterMethod method)
57+
static ClapperUtilsListAlterData *
58+
clapper_utils_list_alter_data_new (GListModel *list, GObject *item,
59+
GObject *after_item, ClapperUtilsListAlterMethod method)
5860
{
59-
ClapperUtilsQueueAlterData *data = g_new (ClapperUtilsQueueAlterData, 1);
61+
ClapperUtilsListAlterData *data = g_new (ClapperUtilsListAlterData, 1);
6062

61-
data->queue = queue;
63+
data->list = list;
6264
data->item = item;
6365
data->after_item = after_item;
6466
data->method = method;
6567

66-
GST_TRACE ("Created queue alter data: %p", data);
68+
GST_TRACE ("Created list alter data: %p", data);
6769

6870
return data;
6971
}
7072

7173
static void
72-
clapper_utils_queue_alter_data_free (ClapperUtilsQueueAlterData *data)
74+
clapper_utils_list_alter_data_free (ClapperUtilsListAlterData *data)
7375
{
74-
GST_TRACE ("Freeing queue alter data: %p", data);
76+
GST_TRACE ("Freeing list alter data: %p", data);
7577

7678
g_free (data);
7779
}
@@ -98,35 +100,48 @@ clapper_utils_prop_notify_data_free (ClapperUtilsPropNotifyData *data)
98100
}
99101

100102
static gpointer
101-
clapper_utils_queue_alter_on_main (ClapperUtilsQueueAlterData *data)
103+
clapper_utils_list_alter_on_main (ClapperUtilsListAlterData *data)
102104
{
103105
GST_DEBUG ("Queue alter invoked");
104106

105107
switch (data->method) {
106-
case CLAPPER_UTILS_QUEUE_ALTER_APPEND:
107-
clapper_queue_add_item (data->queue, data->item);
108+
case CLAPPER_UTILS_LIST_ALTER_QUEUE_APPEND:
109+
clapper_queue_add_item (CLAPPER_QUEUE_CAST (data->list),
110+
CLAPPER_MEDIA_ITEM_CAST (data->item));
108111
break;
109-
case CLAPPER_UTILS_QUEUE_ALTER_INSERT:{
112+
case CLAPPER_UTILS_LIST_ALTER_QUEUE_INSERT:{
110113
guint index;
111114

112115
/* If we have "after_item" then we need to insert after it, otherwise prepend */
113116
if (data->after_item) {
114-
if (clapper_queue_find_item (data->queue, data->after_item, &index))
117+
if (clapper_queue_find_item (CLAPPER_QUEUE_CAST (data->list),
118+
CLAPPER_MEDIA_ITEM_CAST (data->after_item), &index)) {
115119
index++;
116-
else // If not found, just append at the end
117-
index = -1;
120+
} else {
121+
index = -1; // if not found, just append at the end
122+
}
118123
} else {
119124
index = 0;
120125
}
121126

122-
clapper_queue_insert_item (data->queue, data->item, index);
127+
clapper_queue_insert_item (CLAPPER_QUEUE_CAST (data->list),
128+
CLAPPER_MEDIA_ITEM_CAST (data->item), index);
123129
break;
124130
}
125-
case CLAPPER_UTILS_QUEUE_ALTER_REMOVE:
126-
clapper_queue_remove_item (data->queue, data->item);
131+
case CLAPPER_UTILS_LIST_ALTER_QUEUE_REMOVE:
132+
clapper_queue_remove_item (CLAPPER_QUEUE_CAST (data->list),
133+
CLAPPER_MEDIA_ITEM_CAST (data->item));
127134
break;
128-
case CLAPPER_UTILS_QUEUE_ALTER_CLEAR:
129-
clapper_queue_clear (data->queue);
135+
case CLAPPER_UTILS_LIST_ALTER_QUEUE_CLEAR:
136+
clapper_queue_clear (CLAPPER_QUEUE_CAST (data->list));
137+
break;
138+
case CLAPPER_UTILS_LIST_ALTER_TIMELINE_INSERT:
139+
clapper_timeline_insert_marker_internal (CLAPPER_TIMELINE_CAST (data->list),
140+
CLAPPER_MARKER_CAST (data->item));
141+
break;
142+
case CLAPPER_UTILS_LIST_ALTER_TIMELINE_REMOVE:
143+
clapper_timeline_remove_marker_internal (CLAPPER_TIMELINE_CAST (data->list),
144+
CLAPPER_MARKER_CAST (data->item));
130145
break;
131146
default:
132147
g_assert_not_reached ();
@@ -146,48 +161,70 @@ clapper_utils_prop_notify_on_main (ClapperUtilsPropNotifyData *data)
146161
}
147162

148163
static inline void
149-
clapper_utils_queue_alter_invoke_on_main_sync_take (ClapperUtilsQueueAlterData *data)
164+
clapper_utils_list_alter_invoke_on_main_sync_take (ClapperUtilsListAlterData *data)
150165
{
151166
GST_DEBUG ("Invoking queue alter on main...");
152167

153168
clapper_shared_utils_context_invoke_sync_full (g_main_context_default (),
154-
(GThreadFunc) clapper_utils_queue_alter_on_main, data,
155-
(GDestroyNotify) clapper_utils_queue_alter_data_free);
169+
(GThreadFunc) clapper_utils_list_alter_on_main, data,
170+
(GDestroyNotify) clapper_utils_list_alter_data_free);
156171

157172
GST_DEBUG ("Queue alter invoke finished");
158173
}
159174

160175
void
161176
clapper_utils_queue_append_on_main_sync (ClapperQueue *queue, ClapperMediaItem *item)
162177
{
163-
ClapperUtilsQueueAlterData *data = clapper_utils_queue_alter_data_new (queue,
164-
item, NULL, CLAPPER_UTILS_QUEUE_ALTER_APPEND);
165-
clapper_utils_queue_alter_invoke_on_main_sync_take (data);
178+
ClapperUtilsListAlterData *data = clapper_utils_list_alter_data_new (
179+
(GListModel *) queue, (GObject *) item, NULL,
180+
CLAPPER_UTILS_LIST_ALTER_QUEUE_APPEND);
181+
clapper_utils_list_alter_invoke_on_main_sync_take (data);
166182
}
167183

168184
void
169185
clapper_utils_queue_insert_on_main_sync (ClapperQueue *queue,
170186
ClapperMediaItem *item, ClapperMediaItem *after_item)
171187
{
172-
ClapperUtilsQueueAlterData *data = clapper_utils_queue_alter_data_new (queue,
173-
item, after_item, CLAPPER_UTILS_QUEUE_ALTER_INSERT);
174-
clapper_utils_queue_alter_invoke_on_main_sync_take (data);
188+
ClapperUtilsListAlterData *data = clapper_utils_list_alter_data_new (
189+
(GListModel *) queue, (GObject *) item, (GObject *) after_item,
190+
CLAPPER_UTILS_LIST_ALTER_QUEUE_INSERT);
191+
clapper_utils_list_alter_invoke_on_main_sync_take (data);
175192
}
176193

177194
void
178195
clapper_utils_queue_remove_on_main_sync (ClapperQueue *queue, ClapperMediaItem *item)
179196
{
180-
ClapperUtilsQueueAlterData *data = clapper_utils_queue_alter_data_new (queue,
181-
item, NULL, CLAPPER_UTILS_QUEUE_ALTER_REMOVE);
182-
clapper_utils_queue_alter_invoke_on_main_sync_take (data);
197+
ClapperUtilsListAlterData *data = clapper_utils_list_alter_data_new (
198+
(GListModel *) queue, (GObject *) item, NULL,
199+
CLAPPER_UTILS_LIST_ALTER_QUEUE_REMOVE);
200+
clapper_utils_list_alter_invoke_on_main_sync_take (data);
183201
}
184202

185203
void
186204
clapper_utils_queue_clear_on_main_sync (ClapperQueue *queue)
187205
{
188-
ClapperUtilsQueueAlterData *data = clapper_utils_queue_alter_data_new (queue,
189-
NULL, NULL, CLAPPER_UTILS_QUEUE_ALTER_CLEAR);
190-
clapper_utils_queue_alter_invoke_on_main_sync_take (data);
206+
ClapperUtilsListAlterData *data = clapper_utils_list_alter_data_new (
207+
(GListModel *) queue, NULL, NULL,
208+
CLAPPER_UTILS_LIST_ALTER_QUEUE_CLEAR);
209+
clapper_utils_list_alter_invoke_on_main_sync_take (data);
210+
}
211+
212+
void
213+
clapper_utils_timeline_insert_on_main_sync (ClapperTimeline *timeline, ClapperMarker *marker)
214+
{
215+
ClapperUtilsListAlterData *data = clapper_utils_list_alter_data_new (
216+
(GListModel *) timeline, (GObject *) marker, NULL,
217+
CLAPPER_UTILS_LIST_ALTER_TIMELINE_INSERT);
218+
clapper_utils_list_alter_invoke_on_main_sync_take (data);
219+
}
220+
221+
void
222+
clapper_utils_timeline_remove_on_main_sync (ClapperTimeline *timeline, ClapperMarker *marker)
223+
{
224+
ClapperUtilsListAlterData *data = clapper_utils_list_alter_data_new (
225+
(GListModel *) timeline, (GObject *) marker, NULL,
226+
CLAPPER_UTILS_LIST_ALTER_TIMELINE_REMOVE);
227+
clapper_utils_list_alter_invoke_on_main_sync_take (data);
191228
}
192229

193230
void

0 commit comments

Comments
 (0)