|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 #include <stdio.h> |
|
19 #include <stdlib.h> |
|
20 #include <assert.h> |
|
21 |
|
22 #include "xaplayitf.h" |
|
23 #ifdef _GSTREAMER_BACKEND_ |
|
24 #include "XAPlayItfAdaptation.h" |
|
25 #endif |
|
26 #include "xaplayitfadaptationmmf.h" |
|
27 #include "xathreadsafety.h" |
|
28 #include <string.h> |
|
29 |
|
30 void* vfHandle; |
|
31 |
|
32 /* XAPlayItfImpl* GetImpl |
|
33 * Description: Validate interface pointer and cast it to implementation pointer. |
|
34 */ |
|
35 static XAPlayItfImpl* GetImpl(XAPlayItf self) |
|
36 { |
|
37 if(self) |
|
38 { |
|
39 XAPlayItfImpl* impl = (XAPlayItfImpl*)(*self); |
|
40 if(impl && impl == impl->self) |
|
41 { |
|
42 return impl; |
|
43 } |
|
44 } |
|
45 return NULL; |
|
46 } |
|
47 |
|
48 /** |
|
49 * Base interface XAPlayItf implementation |
|
50 */ |
|
51 |
|
52 /** |
|
53 * XAresult XAPlayItfImpl_SetPlayState(XAPlayItf self, XAuint32 state) |
|
54 * Description: Requests a transition of the player into the given play state. |
|
55 **/ |
|
56 XAresult XAPlayItfImpl_SetPlayState(XAPlayItf self, XAuint32 state) |
|
57 { |
|
58 XAresult ret = XA_RESULT_SUCCESS; |
|
59 XAPlayItfImpl* impl = GetImpl(self); |
|
60 DEBUG_API_A1("->XAPlayItfImpl_SetPlayState %s",PLAYSTATENAME(state)); |
|
61 XA_IMPL_THREAD_SAFETY_ENTRY( XATSMediaPlayer ); |
|
62 |
|
63 if( !impl || state < XA_PLAYSTATE_STOPPED || state > XA_PLAYSTATE_PLAYING ) |
|
64 { |
|
65 /* invalid parameter */ |
|
66 XA_IMPL_THREAD_SAFETY_EXIT( XATSMediaPlayer ); |
|
67 DEBUG_ERR("XA_RESULT_PARAMETER_INVALID"); |
|
68 DEBUG_API("<-XAPlayItfImpl_SetPlayState"); |
|
69 return XA_RESULT_PARAMETER_INVALID; |
|
70 } |
|
71 |
|
72 /* check is play state changed, if not do nothing */ |
|
73 if(state != impl->playbackState) |
|
74 { |
|
75 if(state == XA_PLAYSTATE_PLAYING) |
|
76 { |
|
77 #ifdef _GSTREAMER_BACKEND_ |
|
78 XAPlayItfAdapt_GetPosition(impl->adapCtx, &(impl->lastPosition)); |
|
79 #endif |
|
80 } |
|
81 if(impl->isMMFPlayback) |
|
82 { |
|
83 ret = XAPlayItfAdaptMMF_SetPlayState(impl->adaptCtxMMF, state); |
|
84 } |
|
85 else |
|
86 { |
|
87 #ifdef _GSTREAMER_BACKEND_ |
|
88 ret = XAPlayItfAdapt_SetPlayState(impl->adapCtx, state); |
|
89 #endif |
|
90 } |
|
91 |
|
92 if(ret == XA_RESULT_SUCCESS) |
|
93 { |
|
94 impl->playbackState = state; |
|
95 if(state == XA_PLAYSTATE_STOPPED || state == XA_PLAYSTATE_PAUSED) |
|
96 { |
|
97 impl->isMarkerPosCbSend = XA_BOOLEAN_FALSE; |
|
98 impl->lastPosition = 0; |
|
99 } |
|
100 } |
|
101 } |
|
102 |
|
103 XA_IMPL_THREAD_SAFETY_EXIT( XATSMediaPlayer ); |
|
104 DEBUG_API("<-XAPlayItfImpl_SetPlayState"); |
|
105 return ret; |
|
106 } |
|
107 |
|
108 /** |
|
109 * XAresult XAPlayItfImpl_GetPlayState(XAPlayItf self, XAuint32 *pState) |
|
110 * Description: Gets the player's current play state. |
|
111 **/ |
|
112 XAresult XAPlayItfImpl_GetPlayState(XAPlayItf self, XAuint32 *pState) |
|
113 { |
|
114 XAresult ret = XA_RESULT_SUCCESS; |
|
115 XAPlayItfImpl* impl = GetImpl(self); |
|
116 DEBUG_API("->XAPlayItfImpl_GetPlayState"); |
|
117 |
|
118 if(!impl || !pState) |
|
119 { |
|
120 DEBUG_ERR("XA_RESULT_PARAMETER_INVALID"); |
|
121 DEBUG_API("<-XAPlayItfImpl_GetPlayState"); |
|
122 /* invalid parameter */ |
|
123 return XA_RESULT_PARAMETER_INVALID; |
|
124 } |
|
125 |
|
126 *pState = impl->playbackState; |
|
127 |
|
128 DEBUG_API_A1("<-XAPlayItfImpl_GetPlayState: %s",PLAYSTATENAME(impl->playbackState)); |
|
129 return ret; |
|
130 } |
|
131 |
|
132 /** |
|
133 * XAresult XAPlayItfImpl_GetDuration(XAPlayItf self, XAmillisecond *pMsec) |
|
134 * Description: Gets the duration of the current content, in milliseconds. |
|
135 **/ |
|
136 XAresult XAPlayItfImpl_GetDuration(XAPlayItf self, XAmillisecond *pMsec) |
|
137 { |
|
138 XAresult ret = XA_RESULT_SUCCESS; |
|
139 XAPlayItfImpl* impl = GetImpl(self); |
|
140 DEBUG_API("->XAPlayItfImpl_GetDuration"); |
|
141 XA_IMPL_THREAD_SAFETY_ENTRY( XATSMediaPlayer ); |
|
142 |
|
143 if(!impl || !pMsec) |
|
144 { |
|
145 /* invalid parameter */ |
|
146 XA_IMPL_THREAD_SAFETY_EXIT( XATSMediaPlayer ); |
|
147 DEBUG_ERR("XA_RESULT_PARAMETER_INVALID"); |
|
148 DEBUG_API("<-XAPlayItfImpl_GetDuration"); |
|
149 return XA_RESULT_PARAMETER_INVALID; |
|
150 } |
|
151 #ifdef _GSTREAMER_BACKEND_ |
|
152 ret = XAPlayItfAdapt_GetDuration(impl->adapCtx, pMsec); |
|
153 #endif |
|
154 XA_IMPL_THREAD_SAFETY_EXIT( XATSMediaPlayer ); |
|
155 DEBUG_API("<-XAPlayItfImpl_GetDuration"); |
|
156 return ret; |
|
157 } |
|
158 |
|
159 /** |
|
160 * XAresult XAPlayItfImpl_GetPosition(XAPlayItf self, XAmillisecond *pMsec) |
|
161 * Description: Returns the current position of the playback head relative |
|
162 * to the beginning of the content. |
|
163 **/ |
|
164 XAresult XAPlayItfImpl_GetPosition(XAPlayItf self, XAmillisecond *pMsec) |
|
165 { |
|
166 XAresult ret = XA_RESULT_SUCCESS; |
|
167 XAPlayItfImpl* impl = GetImpl(self); |
|
168 DEBUG_API("->XAPlayItfImpl_GetPosition"); |
|
169 XA_IMPL_THREAD_SAFETY_ENTRY( XATSMediaPlayer ); |
|
170 if(!impl || !pMsec) |
|
171 { |
|
172 /* invalid parameter */ |
|
173 XA_IMPL_THREAD_SAFETY_EXIT( XATSMediaPlayer ); |
|
174 DEBUG_ERR("XA_RESULT_PARAMETER_INVALID"); |
|
175 DEBUG_API("<-XAPlayItfImpl_GetPosition"); |
|
176 return XA_RESULT_PARAMETER_INVALID; |
|
177 } |
|
178 |
|
179 if ( impl->playbackState == XA_PLAYSTATE_STOPPED ) |
|
180 { |
|
181 *pMsec = 0; |
|
182 DEBUG_API("<-XAPlayItfImpl_GetPosition"); |
|
183 XA_IMPL_THREAD_SAFETY_EXIT( XATSMediaPlayer ); |
|
184 return XA_RESULT_SUCCESS; |
|
185 } |
|
186 #ifdef _GSTREAMER_BACKEND_ |
|
187 ret = XAPlayItfAdapt_GetPosition(impl->adapCtx, pMsec); |
|
188 #endif |
|
189 XA_IMPL_THREAD_SAFETY_EXIT( XATSMediaPlayer ); |
|
190 DEBUG_API("<-XAPlayItfImpl_GetPosition"); |
|
191 return ret; |
|
192 } |
|
193 |
|
194 /** |
|
195 * XAresult XAPlayItfImpl_RegisterCallback(XAPlayItf self, xaPlayCallback callback, |
|
196 * void *pContext) |
|
197 * Description: Sets the playback callback function. |
|
198 **/ |
|
199 XAresult XAPlayItfImpl_RegisterCallback(XAPlayItf self, xaPlayCallback callback, |
|
200 void *pContext) |
|
201 { |
|
202 XAresult ret = XA_RESULT_SUCCESS; |
|
203 XAPlayItfImpl* impl = GetImpl(self); |
|
204 |
|
205 DEBUG_API("->XAPlayItfImpl_RegisterCallback"); |
|
206 if(!impl) |
|
207 { |
|
208 DEBUG_ERR("XA_RESULT_PARAMETER_INVALID"); |
|
209 DEBUG_API("<-XAPlayItfImpl_RegisterCallback"); |
|
210 /* invalid parameter */ |
|
211 return XA_RESULT_PARAMETER_INVALID; |
|
212 } |
|
213 |
|
214 /* callback may be NULL (to remove callback) */ |
|
215 impl->callback = callback; |
|
216 impl->cbcontext = pContext; |
|
217 impl->cbPtrToSelf = self; |
|
218 |
|
219 DEBUG_API("<-XAPlayItfImpl_RegisterCallback"); |
|
220 return ret; |
|
221 } |
|
222 |
|
223 /** |
|
224 * XAresult XAPlayItfImpl_SetCallbackEventsMask(XAPlayItf self, XAuint32 eventFlags) |
|
225 * Description: Enables/disables notification of playback events. |
|
226 **/ |
|
227 XAresult XAPlayItfImpl_SetCallbackEventsMask(XAPlayItf self, XAuint32 eventFlags) |
|
228 { |
|
229 XAresult ret = XA_RESULT_SUCCESS; |
|
230 XAPlayItfImpl* impl = GetImpl(self); |
|
231 |
|
232 DEBUG_API("->XAPlayItfImpl_SetCallbackEventsMask"); |
|
233 XA_IMPL_THREAD_SAFETY_ENTRY( XATSMediaPlayer ); |
|
234 |
|
235 if(!impl || ( eventFlags > (XA_PLAYEVENT_HEADATEND | XA_PLAYEVENT_HEADATMARKER | |
|
236 XA_PLAYEVENT_HEADATNEWPOS | XA_PLAYEVENT_HEADMOVING | XA_PLAYEVENT_HEADSTALLED) ) ) |
|
237 { |
|
238 /* invalid parameter */ |
|
239 XA_IMPL_THREAD_SAFETY_EXIT( XATSMediaPlayer ); |
|
240 DEBUG_ERR("XA_RESULT_PARAMETER_INVALID"); |
|
241 DEBUG_API("<-XAPlayItfImpl_SetCallbackEventsMask"); |
|
242 return XA_RESULT_PARAMETER_INVALID; |
|
243 } |
|
244 |
|
245 impl->eventFlags = eventFlags; |
|
246 #ifdef _GSTREAMER_BACKEND_ |
|
247 /* enable position tracking if client wants so */ |
|
248 if( (eventFlags & (XA_PLAYEVENT_HEADATMARKER | XA_PLAYEVENT_HEADATNEWPOS)) |
|
249 && impl->adapCtx && !impl->positionupdateOn) |
|
250 { |
|
251 ret = XAPlayItfAdapt_EnablePositionTracking(impl->adapCtx, XA_BOOLEAN_TRUE); |
|
252 if( ret == XA_RESULT_SUCCESS ) |
|
253 { |
|
254 impl->positionupdateOn = XA_BOOLEAN_TRUE; |
|
255 } |
|
256 } |
|
257 else if( !(eventFlags & (XA_PLAYEVENT_HEADATMARKER | XA_PLAYEVENT_HEADATNEWPOS)) |
|
258 && impl->adapCtx && impl->positionupdateOn) |
|
259 { |
|
260 ret = XAPlayItfAdapt_EnablePositionTracking(impl->adapCtx, XA_BOOLEAN_FALSE); |
|
261 if( ret == XA_RESULT_SUCCESS ) |
|
262 { |
|
263 impl->positionupdateOn = XA_BOOLEAN_FALSE; |
|
264 } |
|
265 } |
|
266 #endif |
|
267 XA_IMPL_THREAD_SAFETY_EXIT( XATSMediaPlayer ); |
|
268 DEBUG_API("<-XAPlayItfImpl_SetCallbackEventsMask"); |
|
269 return ret; |
|
270 } |
|
271 |
|
272 /** |
|
273 * XAresult XAPlayItfImpl_GetCallbackEventsMask(XAPlayItf self, XAuint32 *pEventFlags) |
|
274 * Description: Queries for the notification state (enabled/disabled) of playback events. |
|
275 **/ |
|
276 XAresult XAPlayItfImpl_GetCallbackEventsMask(XAPlayItf self, XAuint32 *pEventFlags) |
|
277 { |
|
278 XAresult ret = XA_RESULT_SUCCESS; |
|
279 XAPlayItfImpl* impl = GetImpl(self); |
|
280 |
|
281 DEBUG_API("->XAPlayItfImpl_GetCallbackEventsMask"); |
|
282 if(!impl || !pEventFlags) |
|
283 { |
|
284 DEBUG_ERR("XA_RESULT_PARAMETER_INVALID"); |
|
285 DEBUG_API("<-XAPlayItfImpl_GetCallbackEventsMask"); |
|
286 /* invalid parameter */ |
|
287 return XA_RESULT_PARAMETER_INVALID; |
|
288 } |
|
289 |
|
290 *pEventFlags = impl->eventFlags; |
|
291 |
|
292 DEBUG_API("<-XAPlayItfImpl_GetCallbackEventsMask"); |
|
293 return ret; |
|
294 } |
|
295 |
|
296 /** |
|
297 * XAresult XAPlayItfImpl_SetMarkerPosition(XAPlayItf self, XAmillisecond mSec) |
|
298 * Description: Sets the position of the playback marker. |
|
299 **/ |
|
300 XAresult XAPlayItfImpl_SetMarkerPosition(XAPlayItf self, XAmillisecond mSec) |
|
301 { |
|
302 XAresult ret = XA_RESULT_SUCCESS; |
|
303 XAmillisecond duration = 0; |
|
304 XAPlayItfImpl* impl = NULL; |
|
305 |
|
306 |
|
307 DEBUG_API_A1("->XAPlayItfImpl_SetMarkerPosition: %lu ms", mSec); |
|
308 /* Get duration of the content */ |
|
309 if(XAPlayItfImpl_GetDuration(self, &duration) != XA_RESULT_SUCCESS) |
|
310 { |
|
311 DEBUG_ERR("XA_RESULT_PARAMETER_INVALID"); |
|
312 DEBUG_API("<-XAPlayItfImpl_SetMarkerPosition"); |
|
313 /* invalid parameter */ |
|
314 return XA_RESULT_PARAMETER_INVALID; |
|
315 } |
|
316 |
|
317 impl = GetImpl(self); |
|
318 |
|
319 if(!impl || mSec > duration) |
|
320 { |
|
321 DEBUG_ERR("XA_RESULT_PARAMETER_INVALID"); |
|
322 DEBUG_API("<-XAPlayItfImpl_SetMarkerPosition"); |
|
323 /* invalid parameter */ |
|
324 return XA_RESULT_PARAMETER_INVALID; |
|
325 } |
|
326 impl->markerPosition = mSec; |
|
327 impl->isMarkerPosCbSend = XA_BOOLEAN_FALSE; |
|
328 |
|
329 DEBUG_API("<-XAPlayItfImpl_SetMarkerPosition"); |
|
330 return ret; |
|
331 } |
|
332 |
|
333 /** |
|
334 * XAresult XAPlayItfImpl_ClearMarkerPosition(XAPlayItf self) |
|
335 * Description: Clears marker. |
|
336 **/ |
|
337 XAresult XAPlayItfImpl_ClearMarkerPosition(XAPlayItf self) |
|
338 { |
|
339 XAresult ret = XA_RESULT_SUCCESS; |
|
340 XAPlayItfImpl* impl = GetImpl(self); |
|
341 |
|
342 DEBUG_API("->XAPlayItfImpl_ClearMarkerPosition"); |
|
343 if(!impl) |
|
344 { |
|
345 DEBUG_ERR("XA_RESULT_PARAMETER_INVALID"); |
|
346 DEBUG_API("<-XAPlayItfImpl_ClearMarkerPosition"); |
|
347 /* invalid parameter */ |
|
348 return XA_RESULT_PARAMETER_INVALID; |
|
349 } |
|
350 impl->isMarkerPosCbSend = XA_BOOLEAN_FALSE; |
|
351 impl->markerPosition = NO_POSITION; |
|
352 |
|
353 DEBUG_API("<-XAPlayItfImpl_ClearMarkerPosition"); |
|
354 return ret; |
|
355 } |
|
356 |
|
357 /** |
|
358 * XAresult XAPlayItfImpl_GetMarkerPosition(XAPlayItf self, XAmillisecond *pMsec) |
|
359 * Description: Queries the position of playback marker. |
|
360 **/ |
|
361 XAresult XAPlayItfImpl_GetMarkerPosition(XAPlayItf self, XAmillisecond *pMsec) |
|
362 { |
|
363 XAresult ret = XA_RESULT_SUCCESS; |
|
364 XAPlayItfImpl* impl = GetImpl(self); |
|
365 |
|
366 DEBUG_API("->XAPlayItfImpl_GetMarkerPosition"); |
|
367 if(!impl || !pMsec) |
|
368 { |
|
369 DEBUG_ERR("XA_RESULT_PARAMETER_INVALID"); |
|
370 DEBUG_API("<-XAPlayItfImpl_GetMarkerPosition"); |
|
371 /* invalid parameter */ |
|
372 return XA_RESULT_PARAMETER_INVALID; |
|
373 } |
|
374 |
|
375 if(impl->markerPosition == NO_POSITION) |
|
376 { |
|
377 DEBUG_ERR("XA_RESULT_PRECONDITIONS_VIOLATED"); |
|
378 DEBUG_API("<-XAPlayItfImpl_GetMarkerPosition"); |
|
379 /*marker is not set */ |
|
380 return XA_RESULT_PRECONDITIONS_VIOLATED; |
|
381 } |
|
382 |
|
383 *pMsec = impl->markerPosition; |
|
384 |
|
385 DEBUG_API("<-XAPlayItfImpl_GetMarkerPosition"); |
|
386 return ret; |
|
387 } |
|
388 |
|
389 /** |
|
390 * XAresult XAPlayItfImpl_SetPositionUpdatePeriod(XAPlayItf self, XAmillisecond mSec) |
|
391 * Description: Sets the interval between periodic position notifications. |
|
392 **/ |
|
393 XAresult XAPlayItfImpl_SetPositionUpdatePeriod(XAPlayItf self, XAmillisecond mSec) |
|
394 { |
|
395 XAresult ret = XA_RESULT_SUCCESS; |
|
396 XAPlayItfImpl* impl = GetImpl(self); |
|
397 |
|
398 DEBUG_API_A1("->XAPlayItfImpl_SetPositionUpdatePeriod, %lu mSec", mSec); |
|
399 if(!impl ) |
|
400 { |
|
401 DEBUG_ERR("XA_RESULT_PARAMETER_INVALID"); |
|
402 DEBUG_API("<-XAPlayItfImpl_SetPositionUpdatePeriod"); |
|
403 /* invalid parameter */ |
|
404 return XA_RESULT_PARAMETER_INVALID; |
|
405 } |
|
406 impl->positionUpdatePeriod = mSec; |
|
407 |
|
408 DEBUG_API("<-XAPlayItfImpl_SetPositionUpdatePeriod"); |
|
409 return ret; |
|
410 } |
|
411 |
|
412 /** |
|
413 * XAresult XAPlayItfImpl_GetPositionUpdatePeriod(XAPlayItf self, XAmillisecond *pMsec) |
|
414 * Description: Queries the interval between periodic position notifications. |
|
415 **/ |
|
416 XAresult XAPlayItfImpl_GetPositionUpdatePeriod(XAPlayItf self, XAmillisecond *pMsec) |
|
417 { |
|
418 XAresult ret = XA_RESULT_SUCCESS; |
|
419 XAPlayItfImpl* impl = GetImpl(self); |
|
420 |
|
421 DEBUG_API("->XAPlayItfImpl_GetPositionUpdatePeriod"); |
|
422 if(!impl || !pMsec) |
|
423 { |
|
424 DEBUG_ERR("XA_RESULT_PARAMETER_INVALID"); |
|
425 DEBUG_API("<-XAPlayItfImpl_GetPositionUpdatePeriod"); |
|
426 /* invalid parameter */ |
|
427 return XA_RESULT_PARAMETER_INVALID; |
|
428 } |
|
429 |
|
430 *pMsec = impl->positionUpdatePeriod; |
|
431 |
|
432 DEBUG_API("<-XAPlayItfImpl_GetPositionUpdatePeriod"); |
|
433 return ret; |
|
434 } |
|
435 |
|
436 |
|
437 /** |
|
438 * XAPlayItfImpl -specific methods |
|
439 **/ |
|
440 |
|
441 /** |
|
442 * XAPlayItfImpl* XAPlayItfImpl_Create() |
|
443 * Description: Allocate and initialize PlayItfImpl |
|
444 **/ |
|
445 XAPlayItfImpl* XAPlayItfImpl_Create( |
|
446 #ifdef _GSTREAMER_BACKEND_ |
|
447 XAAdaptationBaseCtx *adapCtx, |
|
448 #endif |
|
449 XAAdaptationBaseMMFCtx *adaptationCtxMMF ) |
|
450 { |
|
451 XAPlayItfImpl *self; |
|
452 |
|
453 DEBUG_API("->XAPlayItfImpl_Create"); |
|
454 self = (XAPlayItfImpl*)calloc(1,sizeof(XAPlayItfImpl)); |
|
455 if(self) |
|
456 { |
|
457 /* init itf default implementation */ |
|
458 self->itf.ClearMarkerPosition = XAPlayItfImpl_ClearMarkerPosition; |
|
459 self->itf.GetCallbackEventsMask = XAPlayItfImpl_GetCallbackEventsMask; |
|
460 self->itf.GetDuration = XAPlayItfImpl_GetDuration; |
|
461 self->itf.GetMarkerPosition = XAPlayItfImpl_GetMarkerPosition; |
|
462 self->itf.GetPlayState = XAPlayItfImpl_GetPlayState; |
|
463 self->itf.GetPosition = XAPlayItfImpl_GetPosition; |
|
464 self->itf.GetPositionUpdatePeriod = XAPlayItfImpl_GetPositionUpdatePeriod; |
|
465 self->itf.RegisterCallback = XAPlayItfImpl_RegisterCallback; |
|
466 self->itf.SetCallbackEventsMask = XAPlayItfImpl_SetCallbackEventsMask; |
|
467 self->itf.SetMarkerPosition = XAPlayItfImpl_SetMarkerPosition; |
|
468 self->itf.SetPlayState = XAPlayItfImpl_SetPlayState; |
|
469 self->itf.SetPositionUpdatePeriod = XAPlayItfImpl_SetPositionUpdatePeriod; |
|
470 |
|
471 /* init variables */ |
|
472 self->callback = NULL; |
|
473 self->cbcontext = NULL; |
|
474 self->playbackState = XA_PLAYSTATE_STOPPED; |
|
475 self->eventFlags = 0; |
|
476 self->markerPosition = NO_POSITION; |
|
477 self->positionUpdatePeriod = PLAYITF_DEFAULT_UPDATE_PERIOD; |
|
478 self->lastPosition = START_POSITION; |
|
479 #ifdef _GSTREAMER_BACKEND_ |
|
480 self->adapCtx = adapCtx; |
|
481 #endif |
|
482 self->adaptCtxMMF = adaptationCtxMMF; |
|
483 self->cbPtrToSelf = NULL; |
|
484 self->isMarkerPosCbSend = XA_BOOLEAN_FALSE; |
|
485 |
|
486 #ifdef _GSTREAMER_BACKEND_ |
|
487 XAAdaptationBase_AddEventHandler( adapCtx, &XAPlayItfImpl_AdaptCb, XA_PLAYITFEVENTS, self ); |
|
488 #endif |
|
489 |
|
490 self->self = self; |
|
491 } |
|
492 |
|
493 DEBUG_API("<-XAPlayItfImpl_Create"); |
|
494 return self; |
|
495 } |
|
496 |
|
497 /* void XAPlayItfImpl_Free(XAPlayItfImpl* self) |
|
498 * Description: Free all resources reserved at XAPlayItfImpl_Create |
|
499 */ |
|
500 void XAPlayItfImpl_Free(XAPlayItfImpl* self) |
|
501 { |
|
502 DEBUG_API("->XAPlayItfImpl_Free"); |
|
503 assert(self==self->self); |
|
504 #ifdef _GSTREAMER_BACKEND_ |
|
505 XAAdaptationBase_RemoveEventHandler( self->adapCtx, &XAPlayItfImpl_AdaptCb ); |
|
506 #endif |
|
507 free(self); |
|
508 DEBUG_API("<-XAPlayItfImpl_Free"); |
|
509 } |
|
510 |
|
511 #ifdef _GSTREAMER_BACKEND_ |
|
512 |
|
513 /* void XAPlayItfImpl_AdaptCb |
|
514 * Description: Listen changes in adaptation |
|
515 */ |
|
516 void XAPlayItfImpl_AdaptCb( void *pHandlerCtx, XAAdaptEvent *event ) |
|
517 { |
|
518 XAPlayItfImpl* impl = (XAPlayItfImpl*)pHandlerCtx; |
|
519 XAuint32 newpos = 0; |
|
520 |
|
521 DEBUG_API("->XAPlayItfImpl_AdaptCb"); |
|
522 XA_IMPL_THREAD_SAFETY_ENTRY_FOR_VOID_FUNCTIONS( XATSMediaPlayer ); |
|
523 if(!impl) |
|
524 { |
|
525 DEBUG_ERR("XAPlayItfImpl_AdaptCb, invalid context pointer!"); |
|
526 DEBUG_API("<-XAPlayItfImpl_AdaptCb"); |
|
527 XA_IMPL_THREAD_SAFETY_EXIT_FOR_VOID_FUNCTIONS( XATSMediaPlayer ); |
|
528 return; |
|
529 } |
|
530 assert(event); |
|
531 /* check position update events */ |
|
532 if( event->eventid == XA_ADAPT_POSITION_UPDATE_EVT ) |
|
533 { |
|
534 assert(event->data); |
|
535 newpos = *((XAuint32*)(event->data)); |
|
536 DEBUG_API_A1("Position update from adaptation: new position %lu ms",newpos); |
|
537 |
|
538 /* Check is looping start file playing before marker position */ |
|
539 if(newpos < impl->markerPosition || impl->lastPosition > newpos) |
|
540 { |
|
541 DEBUG_INFO("Restart looping, clear marker position callback flag."); |
|
542 impl->isMarkerPosCbSend = XA_BOOLEAN_FALSE; |
|
543 } |
|
544 |
|
545 /* check if marker passed and callback needed */ |
|
546 if( (impl->markerPosition != NO_POSITION) && |
|
547 (impl->eventFlags & XA_PLAYEVENT_HEADATMARKER) ) |
|
548 { |
|
549 if( impl->callback && |
|
550 ( |
|
551 ((impl->lastPosition < impl->markerPosition) && |
|
552 (newpos > impl->markerPosition)) |
|
553 || |
|
554 (newpos == impl->markerPosition) |
|
555 ) |
|
556 ) |
|
557 { |
|
558 /* Check is callback already send */ |
|
559 if( impl->isMarkerPosCbSend != XA_BOOLEAN_TRUE ) |
|
560 { |
|
561 impl->callback(impl->cbPtrToSelf, impl->cbcontext, XA_PLAYEVENT_HEADATMARKER); |
|
562 impl->isMarkerPosCbSend = XA_BOOLEAN_TRUE; |
|
563 } |
|
564 } |
|
565 } |
|
566 /* check if update period passed and callback needed */ |
|
567 if( (impl->positionUpdatePeriod > 0) && |
|
568 (impl->eventFlags & XA_PLAYEVENT_HEADATNEWPOS) && |
|
569 impl->callback ) |
|
570 { |
|
571 if( (XAuint32)((impl->lastPosition)/(impl->positionUpdatePeriod )) < |
|
572 (XAuint32)(newpos/(impl->positionUpdatePeriod )) ) |
|
573 { |
|
574 impl->callback(impl->cbPtrToSelf, impl->cbcontext, XA_PLAYEVENT_HEADATNEWPOS); |
|
575 } |
|
576 } |
|
577 /* store position */ |
|
578 impl->lastPosition = newpos; |
|
579 } |
|
580 |
|
581 /* check other events */ |
|
582 else if( event->eventid == XA_PLAYEVENT_HEADATEND ) |
|
583 { |
|
584 impl->playbackState = XA_PLAYSTATE_STOPPED; |
|
585 impl->lastPosition=0; |
|
586 /* send callback if needed */ |
|
587 if( (XA_PLAYEVENT_HEADATEND & impl->eventFlags) && impl->callback ) |
|
588 { |
|
589 impl->callback(impl->cbPtrToSelf, impl->cbcontext, XA_PLAYEVENT_HEADATEND); |
|
590 } |
|
591 } |
|
592 else if( event->eventid == XA_PLAYEVENT_HEADSTALLED ) |
|
593 { |
|
594 impl->playbackState = XA_PLAYSTATE_PAUSED; |
|
595 XAPlayItfAdapt_GetPosition(impl->adapCtx, &(impl->lastPosition)); |
|
596 /* send callback if needed */ |
|
597 if( (XA_PLAYEVENT_HEADSTALLED & impl->eventFlags) && impl->callback ) |
|
598 { |
|
599 impl->callback(impl->cbPtrToSelf, impl->cbcontext, XA_PLAYEVENT_HEADSTALLED); |
|
600 } |
|
601 } |
|
602 else if( event->eventid == XA_PLAYEVENT_HEADMOVING ) |
|
603 { |
|
604 impl->playbackState = XA_PLAYSTATE_PLAYING; |
|
605 /* send callback if needed */ |
|
606 if( (XA_PLAYEVENT_HEADMOVING & impl->eventFlags) && impl->callback ) |
|
607 { |
|
608 impl->callback(impl->cbPtrToSelf, impl->cbcontext, XA_PLAYEVENT_HEADMOVING); |
|
609 } |
|
610 } |
|
611 else |
|
612 { |
|
613 /* do nothing */ |
|
614 } |
|
615 |
|
616 DEBUG_API("<-XAPlayItfImpl_AdaptCb"); |
|
617 XA_IMPL_THREAD_SAFETY_EXIT_FOR_VOID_FUNCTIONS( XATSMediaPlayer ); |
|
618 } |
|
619 #endif |
|
620 |
|
621 XAresult XAPlayItfImpl_DeterminePlaybackEngine(XAPlayItf self, XADataLocator_URI *uri) |
|
622 { |
|
623 |
|
624 XAresult ret = XA_RESULT_SUCCESS; |
|
625 |
|
626 char* tempPtr = NULL; |
|
627 char extension[5]; |
|
628 |
|
629 XAPlayItfImpl* impl = (XAPlayItfImpl*)(self); |
|
630 DEBUG_API("->XAPlayItfImpl_DeterminePlaybackEngine"); |
|
631 |
|
632 //need to move to configuration file and add more in final class |
|
633 |
|
634 impl->isMMFPlayback = XA_BOOLEAN_TRUE; |
|
635 |
|
636 tempPtr = strchr((char*)(uri->URI), '.'); |
|
637 strcpy(extension, tempPtr); |
|
638 |
|
639 if(!strcmp(extension, ".wav")) |
|
640 { |
|
641 impl->isMMFPlayback = XA_BOOLEAN_FALSE; |
|
642 } |
|
643 |
|
644 return ret; |
|
645 |
|
646 DEBUG_API("<-XAPlayItfImpl_DeterminePlaybackEngine"); |
|
647 } |