1 /*****************************************************************
2  * gmerlin - a general purpose multimedia framework and applications
3  *
4  * Copyright (c) 2001 - 2011 Members of the Gmerlin project
5  * gmerlin-general@lists.sourceforge.net
6  * http://gmerlin.sourceforge.net
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20  * *****************************************************************/
21 
22 #include <stdio.h>
23 #include <gmerlin/player.h>
24 #include <playerprivate.h>
25 
bg_player_set_oa_plugin(bg_player_t * p,bg_plugin_handle_t * handle)26 void bg_player_set_oa_plugin(bg_player_t * p, bg_plugin_handle_t * handle)
27   {
28   bg_msg_t * msg;
29 
30   if(handle)
31     bg_plugin_ref(handle);
32 
33   msg = bg_msg_queue_lock_write(p->command_queue);
34 
35   bg_msg_set_id(msg, BG_PLAYER_CMD_SET_OA_PLUGIN);
36   bg_msg_set_arg_ptr_nocopy(msg, 0, handle);
37   bg_msg_queue_unlock_write(p->command_queue);
38   }
39 
40 
bg_player_set_ov_plugin(bg_player_t * p,bg_plugin_handle_t * handle)41 void bg_player_set_ov_plugin(bg_player_t * p, bg_plugin_handle_t * handle)
42   {
43   bg_msg_t * msg;
44   if(handle)
45     bg_plugin_ref(handle);
46 
47   msg = bg_msg_queue_lock_write(p->command_queue);
48   bg_msg_set_id(msg, BG_PLAYER_CMD_SET_OV_PLUGIN);
49   bg_msg_set_arg_ptr_nocopy(msg, 0, handle);
50   bg_msg_queue_unlock_write(p->command_queue);
51   }
52 
53 
bg_player_play(bg_player_t * p,bg_plugin_handle_t * handle,int track,int ignore_flags,const char * track_name)54 void bg_player_play(bg_player_t * p, bg_plugin_handle_t * handle,
55                     int track, int ignore_flags, const char * track_name)
56   {
57   bg_msg_t * msg;
58 
59   bg_plugin_ref(handle);
60 
61   msg = bg_msg_queue_lock_write(p->command_queue);
62   bg_msg_set_id(msg, BG_PLAYER_CMD_PLAY);
63   bg_msg_set_arg_ptr_nocopy(msg, 0, handle);
64   bg_msg_set_arg_int(msg, 1, track);
65   bg_msg_set_arg_int(msg, 2, ignore_flags);
66   bg_msg_set_arg_string(msg, 3, track_name);
67   bg_msg_queue_unlock_write(p->command_queue);
68   }
69 
bg_player_stop(bg_player_t * p)70 void bg_player_stop(bg_player_t * p)
71   {
72   bg_msg_t * msg;
73 
74   msg = bg_msg_queue_lock_write(p->command_queue);
75   bg_msg_set_id(msg, BG_PLAYER_CMD_STOP);
76   bg_msg_queue_unlock_write(p->command_queue);
77 
78   }
79 
bg_player_toggle_mute(bg_player_t * p)80 void bg_player_toggle_mute(bg_player_t * p)
81   {
82   bg_msg_t * msg;
83 
84   msg = bg_msg_queue_lock_write(p->command_queue);
85   bg_msg_set_id(msg, BG_PLAYER_CMD_TOGGLE_MUTE);
86   bg_msg_queue_unlock_write(p->command_queue);
87 
88   }
89 
90 
bg_player_pause(bg_player_t * p)91 void bg_player_pause(bg_player_t * p)
92   {
93   bg_msg_t * msg;
94   msg = bg_msg_queue_lock_write(p->command_queue);
95   bg_msg_set_id(msg, BG_PLAYER_CMD_PAUSE);
96   bg_msg_queue_unlock_write(p->command_queue);
97 
98   }
99 
bg_player_set_audio_stream(bg_player_t * p,int index)100 void bg_player_set_audio_stream(bg_player_t * p, int index)
101   {
102   bg_msg_t * msg;
103   msg = bg_msg_queue_lock_write(p->command_queue);
104   bg_msg_set_id(msg, BG_PLAYER_CMD_SET_AUDIO_STREAM);
105   bg_msg_set_arg_int(msg, 0, index);
106   bg_msg_queue_unlock_write(p->command_queue);
107   }
108 
bg_player_set_video_stream(bg_player_t * p,int index)109 void bg_player_set_video_stream(bg_player_t * p, int index)
110   {
111   bg_msg_t * msg;
112   msg = bg_msg_queue_lock_write(p->command_queue);
113   bg_msg_set_id(msg, BG_PLAYER_CMD_SET_VIDEO_STREAM);
114   bg_msg_set_arg_int(msg, 0, index);
115   bg_msg_queue_unlock_write(p->command_queue);
116   }
117 
bg_player_set_subtitle_stream(bg_player_t * p,int index)118 void bg_player_set_subtitle_stream(bg_player_t * p, int index)
119   {
120   bg_msg_t * msg;
121   msg = bg_msg_queue_lock_write(p->command_queue);
122   bg_msg_set_id(msg, BG_PLAYER_CMD_SET_SUBTITLE_STREAM);
123   bg_msg_set_arg_int(msg, 0, index);
124   bg_msg_queue_unlock_write(p->command_queue);
125   }
126 
msg_name(bg_msg_t * msg,const void * data)127 static void msg_name(bg_msg_t * msg,
128                      const void * data)
129   {
130   const char * name = (const char*)(data);
131   bg_msg_set_id(msg, BG_PLAYER_MSG_TRACK_NAME);
132   bg_msg_set_arg_string(msg, 0, name);
133   }
134 
bg_player_set_track_name(bg_player_t * p,const char * name)135 void bg_player_set_track_name(bg_player_t * p, const char * name)
136   {
137   bg_msg_queue_list_send(p->message_queues,
138                          msg_name, name);
139   }
140 
141 typedef struct
142   {
143   gavl_time_t duration;
144   int can_seek;
145   } duration_struct;
146 
msg_duration(bg_msg_t * msg,const void * data)147 static void msg_duration(bg_msg_t * msg,
148                          const void * data)
149   {
150   duration_struct * d;
151   d = (duration_struct*)data;
152   bg_msg_set_id(msg, BG_PLAYER_MSG_TRACK_DURATION);
153   bg_msg_set_arg_time(msg, 0, d->duration);
154   bg_msg_set_arg_int(msg, 1, d->can_seek);
155   }
156 
bg_player_set_duration(bg_player_t * p,gavl_time_t duration,int can_seek)157 void bg_player_set_duration(bg_player_t * p, gavl_time_t duration, int can_seek)
158   {
159   duration_struct d;
160   d.duration = duration;
161   d.can_seek = can_seek;
162   bg_msg_queue_list_send(p->message_queues,
163                          msg_duration, &d);
164   }
165 
msg_metadata(bg_msg_t * msg,const void * data)166 static void msg_metadata(bg_msg_t * msg,
167                          const void * data)
168   {
169   const gavl_metadata_t * m = data;
170   bg_msg_set_id(msg, BG_PLAYER_MSG_METADATA);
171   bg_msg_set_arg_metadata(msg, 0, m);
172   }
173 
bg_player_set_metadata(bg_player_t * p,const gavl_metadata_t * m)174 void bg_player_set_metadata(bg_player_t * p, const gavl_metadata_t * m)
175   {
176   bg_msg_queue_list_send(p->message_queues,
177                          msg_metadata, m);
178   }
179 
180 typedef struct
181   {
182   int id;
183   } key_struct;
184 
msg_accel(bg_msg_t * msg,const void * data)185 static void msg_accel(bg_msg_t * msg,
186                       const void * data)
187   {
188   const key_struct * s = (const key_struct *)(data);
189   bg_msg_set_id(msg, BG_PLAYER_MSG_ACCEL);
190   bg_msg_set_arg_int(msg, 0, s->id);
191   }
192 
bg_player_accel_pressed(bg_player_t * p,int id)193 void bg_player_accel_pressed(bg_player_t * p, int id)
194   {
195   key_struct s;
196   s.id = id;
197   bg_msg_queue_list_send(p->message_queues,
198                          msg_accel, &s);
199   }
200 
bg_player_seek(bg_player_t * p,gavl_time_t time,int scale)201 void bg_player_seek(bg_player_t * p, gavl_time_t time, int scale)
202   {
203   bg_msg_t * msg;
204 
205   msg = bg_msg_queue_lock_write(p->command_queue);
206   bg_msg_set_id(msg, BG_PLAYER_CMD_SEEK);
207   bg_msg_set_arg_time(msg, 0, time);
208   bg_msg_set_arg_int(msg, 1, scale);
209   bg_msg_queue_unlock_write(p->command_queue);
210   }
211 
bg_player_seek_rel(bg_player_t * p,gavl_time_t t)212 void bg_player_seek_rel(bg_player_t * p, gavl_time_t t)
213   {
214   bg_msg_t * msg;
215 
216   msg = bg_msg_queue_lock_write(p->command_queue);
217   bg_msg_set_id(msg, BG_PLAYER_CMD_SEEK_REL);
218   bg_msg_set_arg_time(msg, 0, t);
219   bg_msg_queue_unlock_write(p->command_queue);
220   }
221 
bg_player_set_volume(bg_player_t * p,float volume)222 void bg_player_set_volume(bg_player_t * p, float volume)
223   {
224   bg_msg_t * msg;
225 
226   msg = bg_msg_queue_lock_write(p->command_queue);
227   bg_msg_set_id(msg, BG_PLAYER_CMD_SET_VOLUME);
228   bg_msg_set_arg_float(msg, 0, volume);
229   bg_msg_queue_unlock_write(p->command_queue);
230   }
231 
bg_player_set_volume_rel(bg_player_t * p,float volume)232 void bg_player_set_volume_rel(bg_player_t * p, float volume)
233   {
234   bg_msg_t * msg;
235 
236   msg = bg_msg_queue_lock_write(p->command_queue);
237   bg_msg_set_id(msg, BG_PLAYER_CMD_SET_VOLUME_REL);
238   bg_msg_set_arg_float(msg, 0, volume);
239   bg_msg_queue_unlock_write(p->command_queue);
240   }
241 
242 
bg_player_error(bg_player_t * p)243 void bg_player_error(bg_player_t * p)
244   {
245   bg_msg_t * msg;
246 
247   msg = bg_msg_queue_lock_write(p->command_queue);
248   bg_msg_set_id(msg, BG_PLAYER_CMD_SETSTATE);
249   bg_msg_set_arg_int(msg, 0, BG_PLAYER_STATE_ERROR);
250   bg_msg_queue_unlock_write(p->command_queue);
251   }
252 
bg_player_change(bg_player_t * p,int flags)253 void bg_player_change(bg_player_t * p, int flags)
254   {
255   bg_msg_queue_t * q;
256   bg_msg_t * msg;
257 
258   q = bg_msg_queue_create();
259   bg_player_add_message_queue(p, q);
260 
261   msg = bg_msg_queue_lock_write(p->command_queue);
262   bg_msg_set_id(msg, BG_PLAYER_CMD_CHANGE);
263   bg_msg_set_arg_int(msg, 0, flags);
264 
265   bg_msg_queue_unlock_write(p->command_queue);
266 
267   while((msg = bg_msg_queue_lock_read(q)) &&
268         (bg_msg_get_id(msg) != BG_PLAYER_MSG_CLEANUP))
269     {
270     bg_msg_queue_unlock_read(q);
271     }
272   bg_player_delete_message_queue(p, q);
273   bg_msg_queue_destroy(q);
274   }
275 
bg_player_interrupt(bg_player_t * p)276 void bg_player_interrupt(bg_player_t * p)
277   {
278   bg_msg_queue_t * q;
279   bg_msg_t * msg;
280 
281   /* Create message queue and connect to player */
282   q = bg_msg_queue_create();
283   bg_player_add_message_queue(p, q);
284 
285   /* Tell player to interrupt */
286   msg = bg_msg_queue_lock_write(p->command_queue);
287   bg_msg_set_id(msg, BG_PLAYER_CMD_INTERRUPT);
288   bg_msg_queue_unlock_write(p->command_queue);
289 
290   /* Wait for confirmation */
291   while((msg = bg_msg_queue_lock_read(q)) &&
292         (bg_msg_get_id(msg) != BG_PLAYER_MSG_INTERRUPT))
293     {
294     bg_msg_queue_unlock_read(q);
295     }
296   bg_msg_queue_unlock_read(q);
297 
298   /* Cleanup */
299   bg_player_delete_message_queue(p, q);
300   bg_msg_queue_destroy(q);
301   }
302 
bg_player_interrupt_resume(bg_player_t * p)303 void bg_player_interrupt_resume(bg_player_t * p)
304   {
305   bg_msg_t * msg;
306   bg_msg_queue_t * q;
307 
308   /* Create message queue and connect to player */
309   q = bg_msg_queue_create();
310   bg_player_add_message_queue(p, q);
311 
312   /* Tell player to resume */
313   msg = bg_msg_queue_lock_write(p->command_queue);
314   bg_msg_set_id(msg, BG_PLAYER_CMD_INTERRUPT_RESUME);
315   bg_msg_queue_unlock_write(p->command_queue);
316 
317   /* Wait for confirmation */
318   while((msg = bg_msg_queue_lock_read(q)) &&
319         (bg_msg_get_id(msg) != BG_PLAYER_MSG_INTERRUPT_RESUME))
320     {
321     bg_msg_queue_unlock_read(q);
322     }
323   bg_msg_queue_unlock_read(q);
324 
325   /* Cleanup */
326   bg_player_delete_message_queue(p, q);
327   bg_msg_queue_destroy(q);
328   }
329 
bg_player_next_chapter(bg_player_t * p)330 void bg_player_next_chapter(bg_player_t * p)
331   {
332   bg_msg_t * msg;
333   msg = bg_msg_queue_lock_write(p->command_queue);
334   bg_msg_set_id(msg, BG_PLAYER_CMD_NEXT_CHAPTER);
335   bg_msg_queue_unlock_write(p->command_queue);
336   }
337 
bg_player_prev_chapter(bg_player_t * p)338 void bg_player_prev_chapter(bg_player_t * p)
339   {
340   bg_msg_t * msg;
341   msg = bg_msg_queue_lock_write(p->command_queue);
342   bg_msg_set_id(msg, BG_PLAYER_CMD_PREV_CHAPTER);
343   bg_msg_queue_unlock_write(p->command_queue);
344   }
345 
bg_player_set_chapter(bg_player_t * p,int chapter)346 void bg_player_set_chapter(bg_player_t * p, int chapter)
347   {
348   bg_msg_t * msg;
349   msg = bg_msg_queue_lock_write(p->command_queue);
350   bg_msg_set_id(msg, BG_PLAYER_CMD_SET_CHAPTER);
351   bg_msg_set_arg_int(msg, 0, chapter);
352   bg_msg_queue_unlock_write(p->command_queue);
353   }
354