khronosfws/openmax_al/src/adaptation/xaplayitfadaptation.c
changeset 12 5a06f39ad45b
equal deleted inserted replaced
0:71ca22bcf22a 12:5a06f39ad45b
       
     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 <gst.h>
       
    19 #include "unistd.h"
       
    20 #include <pthread.h>
       
    21 #include "XAMediaPlayerAdaptCtx.h"
       
    22 #include "XAPlayItfAdaptation.h"
       
    23 #include "XAAdaptation.h"
       
    24 
       
    25 extern XAboolean cameraRealized;
       
    26 extern XACameraAdaptationCtx_* cameraCtx;
       
    27 
       
    28 /*forward declaration of position updater callback*/
       
    29 gboolean XAPlayItfAdapt_PositionUpdate(gpointer ctx);
       
    30 
       
    31 /*
       
    32  * XAresult XAPlayItfAdapt_SetPlayState(XAAdaptationBaseCtx *bCtx, XAuint32 state)
       
    33  * Sets play state to GStreamer.
       
    34  * @param XAAdaptationBaseCtx *bCtx - Adaptation context, this will be casted to correct type regarding to contextID
       
    35  * XAuint32 state - Play state to be set
       
    36  * @return XAresult ret - Success value
       
    37  */
       
    38 XAresult XAPlayItfAdapt_SetPlayState(XAAdaptationBaseCtx *bCtx, XAuint32 state)
       
    39 {
       
    40     XAresult ret = XA_RESULT_SUCCESS;
       
    41     XAboolean requestStateChange = XA_BOOLEAN_FALSE;
       
    42     GstStateChangeReturn gstRet = GST_STATE_CHANGE_SUCCESS;
       
    43     XAMediaPlayerAdaptationCtx* mCtx = NULL;
       
    44     XAuint32 locType = 0;
       
    45     GstState gstOrigState = GST_STATE_PLAYING;
       
    46     GstState gstTmpState = GST_STATE_PLAYING;
       
    47     XADataLocator_Address *address = NULL;
       
    48     XAboolean playing = XA_BOOLEAN_FALSE;
       
    49     DEBUG_API_A1("->XAPlayItfAdapt_SetPlayState %s",PLAYSTATENAME(state));
       
    50 
       
    51     if(!bCtx || bCtx->ctxId != XAMediaPlayerAdaptation)
       
    52     {
       
    53         DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
       
    54         return XA_RESULT_PARAMETER_INVALID;
       
    55     }
       
    56 
       
    57     mCtx = (XAMediaPlayerAdaptationCtx*) bCtx;
       
    58     switch ( state )
       
    59     {
       
    60         case XA_PLAYSTATE_STOPPED:
       
    61         {
       
    62            	if ( cameraCtx && cameraRealized && mCtx->isobjsrc && mCtx->source  )
       
    63 			{
       
    64 				cameraCtx->playing = XA_BOOLEAN_FALSE;
       
    65 				if(!cameraCtx->recording && !cameraCtx->snapshotting)
       
    66 				{
       
    67 					/* Future improvement: We could block MPObjSrc pad from tee-eleement here, when
       
    68 					 * tee-element supports sending stream to one pad when others are blocked */
       
    69 
       
    70 					/* Neither view finder or recorder is running -> pause camera */
       
    71 					if ( GST_STATE( GST_ELEMENT(mCtx->source)) == GST_STATE_PLAYING )
       
    72 					{
       
    73 						GstStateChangeReturn gret;
       
    74 						DEBUG_INFO("Stop camera source");
       
    75 						gret = gst_element_set_state( GST_ELEMENT(mCtx->source), GST_STATE_PAUSED );
       
    76 						gret = gst_element_get_state( GST_ELEMENT(mCtx->source), NULL,NULL, XA_ADAPT_ASYNC_TIMEOUT_SHORT_NSEC );
       
    77 					}
       
    78 				}
       
    79 			}
       
    80 
       
    81             gstOrigState = GST_STATE(bCtx->bin);
       
    82             if ( gstOrigState != GST_STATE_READY )
       
    83             {
       
    84                 DEBUG_INFO("Set gst-bin to GST_STATE_READY");
       
    85                 bCtx->binWantedState = GST_STATE_READY;
       
    86                 XAAdaptationBase_PrepareAsyncWait(bCtx);
       
    87                 gstRet = gst_element_set_state( GST_ELEMENT(bCtx->bin), GST_STATE_READY);
       
    88                 switch ( gstRet )
       
    89                 {
       
    90                     case GST_STATE_CHANGE_FAILURE:
       
    91                         DEBUG_ERR_A1("FAILED to change state (target %s)",
       
    92                                       gst_element_state_get_name(bCtx->binWantedState));
       
    93                         bCtx->binWantedState = GST_STATE(bCtx->bin);
       
    94                         ret = XA_RESULT_INTERNAL_ERROR;
       
    95                         break;
       
    96                     case GST_STATE_CHANGE_ASYNC:
       
    97                         DEBUG_INFO_A1("Change state will happen asyncronously (target %s)",
       
    98                                        gst_element_state_get_name(bCtx->binWantedState));
       
    99                         XAAdaptationBase_StartAsyncWait(bCtx);
       
   100                         ret = XA_RESULT_SUCCESS;
       
   101                         break;
       
   102                     case GST_STATE_CHANGE_SUCCESS:
       
   103                         DEBUG_INFO_A1("Successfully changed state (target %s)",
       
   104                                        gst_element_state_get_name(bCtx->binWantedState));
       
   105                         break;
       
   106                     default:
       
   107                         DEBUG_ERR_A1("Unhandled error (%d)",gstRet);
       
   108                         break;
       
   109                 }
       
   110                 bCtx->waitingasyncop = XA_BOOLEAN_FALSE;
       
   111                 gstTmpState = GST_STATE(bCtx->bin);
       
   112                 DEBUG_INFO_A1("Setted gst-bin to state %s", gst_element_state_get_name(gstTmpState));
       
   113 
       
   114                 DEBUG_INFO_A1("Restoring gst-bin state to state %s", gst_element_state_get_name(gstOrigState));
       
   115                 bCtx->binWantedState = gstOrigState;
       
   116                 XAAdaptationBase_PrepareAsyncWait(bCtx);
       
   117                 gstRet = gst_element_set_state( GST_ELEMENT(bCtx->bin), gstOrigState);
       
   118                 switch ( gstRet )
       
   119                 {
       
   120                     case GST_STATE_CHANGE_FAILURE:
       
   121                         DEBUG_ERR_A1("FAILED to change state (target %s)",
       
   122                                       gst_element_state_get_name(bCtx->binWantedState));
       
   123                         bCtx->binWantedState = GST_STATE(bCtx->bin);
       
   124                         ret = XA_RESULT_INTERNAL_ERROR;
       
   125                         break;
       
   126                     case GST_STATE_CHANGE_ASYNC:
       
   127                         DEBUG_INFO_A1("Change state will happen asyncronously (target %s)",
       
   128                                        gst_element_state_get_name(bCtx->binWantedState));
       
   129                         XAAdaptationBase_StartAsyncWait(bCtx);
       
   130                         ret = XA_RESULT_SUCCESS;
       
   131                         break;
       
   132                     case GST_STATE_CHANGE_SUCCESS:
       
   133                         DEBUG_INFO_A1("Successfully changed state (target %s)",
       
   134                                        gst_element_state_get_name(bCtx->binWantedState));
       
   135                         break;
       
   136                     default:
       
   137                         DEBUG_ERR_A1("Unhandled error (%d)",gstRet);
       
   138                         break;
       
   139                 }
       
   140                 bCtx->waitingasyncop = XA_BOOLEAN_FALSE;
       
   141                 gstOrigState = GST_STATE(bCtx->bin);
       
   142                 DEBUG_INFO_A1("Restored gst-bin to state %s", gst_element_state_get_name(gstOrigState));
       
   143             }
       
   144 
       
   145 
       
   146         	if( bCtx->pipeSrcThrCtx.dataHandle )
       
   147         	{
       
   148         		XAresult retVal = XA_RESULT_SUCCESS;
       
   149 				if ( bCtx->pipeSrcThrCtx.state != CPStateNull )
       
   150 				{
       
   151 					bCtx->pipeSrcThrCtx.state = CPStateStopped;
       
   152 				}
       
   153 
       
   154 				retVal = XAImpl_PostSemaphore( bCtx->pipeSrcThrCtx.stateSem );
       
   155 				if ( retVal != XA_RESULT_SUCCESS )
       
   156 				{
       
   157 					DEBUG_ERR("Could not post content pipe semaphore!");
       
   158 				}
       
   159 
       
   160         	}
       
   161             /* stop head and drive head to beginning */
       
   162             bCtx->binWantedState = GST_STATE_PAUSED;
       
   163             if(mCtx->runpositiontimer > 0)
       
   164             {
       
   165                 g_source_remove(mCtx->runpositiontimer);
       
   166                 mCtx->runpositiontimer=0;
       
   167             }
       
   168 
       
   169             gst_element_send_event(bCtx->bin,gst_event_new_flush_start());
       
   170             gst_element_send_event(bCtx->bin,gst_event_new_flush_stop());
       
   171 
       
   172             locType = *((XAuint32*)( mCtx->xaSource->pLocator ));
       
   173             if( locType == XA_DATALOCATOR_ADDRESS )
       
   174             {
       
   175                 address = (XADataLocator_Address*)(mCtx->xaSource->pLocator);
       
   176 
       
   177                 /* init gst buffer from datalocator */
       
   178                 if( mCtx->source )
       
   179                 {
       
   180                     GstBuffer* userBuf = NULL;
       
   181 
       
   182                     /* init GST buffer from XADataLocator*/
       
   183                     userBuf = gst_buffer_new();
       
   184                     if( userBuf )
       
   185                     {
       
   186                         userBuf->size = address->length;
       
   187                         userBuf->data = address->pAddress;
       
   188                         /* push the whole buffer to appsrc so it is ready for preroll */
       
   189                         DEBUG_INFO("Pushing buffer");
       
   190                         gst_app_src_push_buffer( GST_APP_SRC(mCtx->source), userBuf );
       
   191                         DEBUG_INFO_A1("Sent buffer at 0x%x to appsrc", userBuf );
       
   192                         gst_app_src_end_of_stream( GST_APP_SRC(mCtx->source) );
       
   193                     }
       
   194                     else
       
   195                     {
       
   196                         DEBUG_ERR("Failure allocating buffer!");
       
   197                     }
       
   198                 }
       
   199             }
       
   200             break;
       
   201         }
       
   202         case XA_PLAYSTATE_PAUSED:
       
   203 
       
   204            	if ( cameraCtx && cameraRealized && mCtx->isobjsrc && mCtx->source  )
       
   205 			{
       
   206 				cameraCtx->playing = XA_BOOLEAN_FALSE;
       
   207 
       
   208 				/* Future improvement: We could block MPObjSrc pad from tee-eleement here, when
       
   209 				 * tee-element supports sending stream to one pad when others are blocked */
       
   210 
       
   211 				if(!cameraCtx->recording && !cameraCtx->snapshotting)
       
   212 				{
       
   213 					/* Neither view finder or recorder is running -> pause camera */
       
   214 					if ( GST_STATE( GST_ELEMENT(mCtx->source)) == GST_STATE_PLAYING )
       
   215 					{
       
   216 						GstStateChangeReturn gret;
       
   217 						DEBUG_INFO("Stop camera source");
       
   218 						gret = gst_element_set_state( GST_ELEMENT(mCtx->source), GST_STATE_PAUSED );
       
   219 						gret = gst_element_get_state( GST_ELEMENT(mCtx->source), NULL,NULL, XA_ADAPT_ASYNC_TIMEOUT_SHORT_NSEC );
       
   220 					}
       
   221 				}
       
   222 			}
       
   223 
       
   224             if ( bCtx->pipeSrcThrCtx.state != CPStateNull )
       
   225             {
       
   226                 bCtx->pipeSrcThrCtx.state = CPStatePaused;
       
   227             }
       
   228             bCtx->binWantedState = GST_STATE_PAUSED;
       
   229             if(mCtx->runpositiontimer > 0)
       
   230             {
       
   231                 g_source_remove(mCtx->runpositiontimer);
       
   232                 mCtx->runpositiontimer=0;
       
   233             }
       
   234             break;
       
   235         case XA_PLAYSTATE_PLAYING:
       
   236         {
       
   237         	if ( cameraCtx && mCtx->isobjsrc )
       
   238         	{
       
   239         		cameraCtx->playing = XA_BOOLEAN_TRUE;
       
   240         	}
       
   241 
       
   242         	if ( mCtx->videoppBScrbin )
       
   243         	{
       
   244         		gst_element_set_state( GST_ELEMENT(mCtx->videoppBScrbin), GST_STATE_PAUSED);
       
   245         	}
       
   246         	if  (mCtx->isobjsrc && !mCtx->cameraSinkSynced && cameraCtx )
       
   247         	{ /* create videosink now */
       
   248 				mCtx->cameraSinkSynced = XA_BOOLEAN_TRUE;
       
   249 				if ( mCtx->videosink )
       
   250 				{
       
   251 					gst_element_unlink( mCtx->filter,mCtx->videosink );
       
   252 					gst_element_set_state( GST_ELEMENT(mCtx->videosink), GST_STATE_NULL);
       
   253 					gst_bin_remove( GST_BIN(mCtx->baseObj.bin), mCtx->videosink);
       
   254 					mCtx->videosink = XAAdaptationBase_CreateGstSink( mCtx->xaVideoSink, "videosink", &(mCtx->isobjvsink) );
       
   255 					gst_bin_add(GST_BIN(mCtx->baseObj.bin), mCtx->videosink);
       
   256 					gst_element_link(mCtx->filter, mCtx->videosink);
       
   257 				}
       
   258         	}
       
   259 
       
   260             if ( bCtx->pipeSrcThrCtx.state != CPStateNull )
       
   261             {
       
   262                 XAresult retVal = XA_RESULT_SUCCESS;
       
   263 
       
   264                 if ( bCtx->pipeSrcThrCtx.state == CPStateInitialized )
       
   265                 { /* Start thread if it's not running */
       
   266                     retVal = XAImpl_StartThread( &(bCtx->pipeSrcThr), NULL, &XAAdaptationBase_ContentPipeScrThrFunc, &(bCtx->pipeSrcThrCtx) );
       
   267                     if ( retVal != XA_RESULT_SUCCESS )
       
   268                     {
       
   269                         DEBUG_ERR("Could not start content pipe thread!");
       
   270                     }
       
   271                 }
       
   272                 if ( bCtx->pipeSrcThrCtx.state == CPStatePaused ||
       
   273                      bCtx->pipeSrcThrCtx.state == CPStateInitialized ||
       
   274                      bCtx->pipeSrcThrCtx.state == CPStateStarted )
       
   275                 retVal = XAImpl_PostSemaphore( bCtx->pipeSrcThrCtx.stateSem );
       
   276                 if ( retVal != XA_RESULT_SUCCESS )
       
   277                 {
       
   278                     DEBUG_ERR("Could not post content pipe semaphore!");
       
   279                 }
       
   280             }
       
   281 
       
   282             bCtx->binWantedState = GST_STATE_PLAYING;
       
   283             if(mCtx->playrate!=1 && !mCtx->isobjsrc)
       
   284             { /*set seek element for ff, rew and slow*/
       
   285                 XAAdaptationBase_PrepareAsyncWait(bCtx);
       
   286                 DEBUG_INFO_A1("Apply new playrate %f.", mCtx->playrate);
       
   287                 if(!gst_element_seek( bCtx->bin, mCtx->playrate, GST_FORMAT_TIME,
       
   288                                     GST_SEEK_FLAG_FLUSH|GST_SEEK_FLAG_ACCURATE,
       
   289                                     GST_SEEK_TYPE_NONE, 0,
       
   290                                     GST_SEEK_TYPE_NONE, -1))
       
   291                 {
       
   292                     DEBUG_ERR("WARN: gst reports seek not handled");
       
   293                 }
       
   294                 /* flushed seeks always asynchronous */
       
   295                 XAAdaptationBase_StartAsyncWait(bCtx);
       
   296                 DEBUG_INFO("New playrate handled.");
       
   297                 bCtx->waitingasyncop = XA_BOOLEAN_FALSE;
       
   298             }
       
   299 
       
   300             playing = XA_BOOLEAN_TRUE;
       
   301             break;
       
   302         }
       
   303         default:
       
   304             ret = XA_RESULT_PARAMETER_INVALID;
       
   305             break;
       
   306     }
       
   307     /* launch Gstreamer state change only if necessary */
       
   308     if( GST_STATE_TARGET(bCtx->bin) == bCtx->binWantedState )
       
   309     {
       
   310         DEBUG_INFO("Gst already in or transitioning to wanted state");
       
   311         requestStateChange = XA_BOOLEAN_FALSE;
       
   312     }
       
   313     else
       
   314     {
       
   315         if( (GST_STATE(bCtx->bin) == bCtx->binWantedState) &&
       
   316             (GST_STATE_PENDING(bCtx->bin) == GST_STATE_VOID_PENDING) )
       
   317         {
       
   318             DEBUG_ERR_A3("WARNING : gststate %d == wanted %d != gsttarget %d and no statechange pending",
       
   319                           GST_STATE(bCtx->bin), bCtx->binWantedState, GST_STATE_TARGET(bCtx->bin));
       
   320         }
       
   321         requestStateChange = XA_BOOLEAN_TRUE;
       
   322     }
       
   323 
       
   324     if( requestStateChange )
       
   325     {
       
   326         XAAdaptationBase_PrepareAsyncWait(bCtx);
       
   327         DEBUG_INFO_A1("Sending change state request to state %d", bCtx->binWantedState);
       
   328         gstRet = gst_element_set_state( GST_ELEMENT(bCtx->bin), bCtx->binWantedState);
       
   329         switch ( gstRet )
       
   330         {
       
   331             case GST_STATE_CHANGE_FAILURE:
       
   332                 DEBUG_ERR_A1("FAILED to change state (target %s)",
       
   333                               gst_element_state_get_name(bCtx->binWantedState));
       
   334                 bCtx->binWantedState = GST_STATE(bCtx->bin);
       
   335                 ret = XA_RESULT_INTERNAL_ERROR;
       
   336                 break;
       
   337             case GST_STATE_CHANGE_ASYNC:
       
   338                 DEBUG_INFO_A1("Change state will happen asyncronously (target %s)",
       
   339                                gst_element_state_get_name(bCtx->binWantedState));
       
   340                 XAAdaptationBase_StartAsyncWait(bCtx);
       
   341                 ret = XA_RESULT_SUCCESS;
       
   342                 break;
       
   343             case GST_STATE_CHANGE_NO_PREROLL:
       
   344                 DEBUG_INFO("GST_STATE_CHANGE_NO_PREROLL");
       
   345                 /* deliberate fall-through */
       
   346             case GST_STATE_CHANGE_SUCCESS:
       
   347                 DEBUG_INFO_A1("Successfully changed state (target %s)",
       
   348                                gst_element_state_get_name(bCtx->binWantedState));
       
   349                 ret = XA_RESULT_SUCCESS;
       
   350                 break;
       
   351             default:
       
   352                 DEBUG_ERR_A1("Unhandled error (%d)",gstRet);
       
   353                 ret = XA_RESULT_UNKNOWN_ERROR;
       
   354                 break;
       
   355         }
       
   356         bCtx->waitingasyncop = XA_BOOLEAN_FALSE;
       
   357     }
       
   358 
       
   359     if (playing && mCtx->isobjsrc && cameraCtx )
       
   360     {
       
   361     	GstPad* moSrc=NULL ;
       
   362 
       
   363     	playing = XA_BOOLEAN_FALSE;
       
   364     	moSrc = gst_element_get_static_pad( mCtx->source, "MPObjSrc");
       
   365 		if( moSrc && gst_pad_is_linked(moSrc) )
       
   366 		{
       
   367 			DEBUG_INFO_A2("unblock element:%s pad:%s",
       
   368 					gst_element_get_name( mCtx->source),
       
   369 					gst_pad_get_name(moSrc));
       
   370 			gst_pad_set_blocked_async(moSrc, FALSE, XAAdaptationBase_PadBlockCb, NULL);
       
   371 		}
       
   372 
       
   373 		if ( GST_STATE( GST_ELEMENT(mCtx->source)) != GST_STATE_PLAYING )
       
   374 		{
       
   375 			GstStateChangeReturn gret;
       
   376 			DEBUG_INFO("Start camera source");
       
   377 			gret = gst_element_set_state( GST_ELEMENT(mCtx->source), GST_STATE_PLAYING );
       
   378 			gret = gst_element_get_state( GST_ELEMENT(mCtx->source), NULL,NULL, XA_ADAPT_ASYNC_TIMEOUT_SHORT_NSEC );
       
   379 		}
       
   380     }
       
   381     DEBUG_API("<-XAPlayItfAdapt_SetPlayState");
       
   382     return ret;
       
   383 }
       
   384 
       
   385 /*
       
   386  * XAresult XAPlayItfAdapt_GetDuration(XAAdaptationBaseCtx *bCtx, XAmillisecond *pMsec)
       
   387  * @param XAAdaptationBaseCtx *bCtx - Adaptation context, this will be casted to correct type regarding to contextID
       
   388  * XAmillisecond *pMsec - Pointer where to store duration of stream.
       
   389  * @return XAresult ret - Success value
       
   390  */
       
   391 XAresult XAPlayItfAdapt_GetDuration(XAAdaptationBaseCtx *bCtx, XAmillisecond *pMsec)
       
   392 {
       
   393     XAresult ret = XA_RESULT_SUCCESS;
       
   394     XAMediaPlayerAdaptationCtx* mCtx = NULL;
       
   395     GstFormat format = GST_FORMAT_TIME;
       
   396     gint64 duration;
       
   397     DEBUG_API("->XAPlayItfAdapt_GetDuration");
       
   398 
       
   399     if(!bCtx || bCtx->ctxId != XAMediaPlayerAdaptation || !pMsec)
       
   400     {
       
   401         DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
       
   402         /* invalid parameter */
       
   403         return XA_RESULT_PARAMETER_INVALID;
       
   404     }
       
   405 
       
   406     mCtx = (XAMediaPlayerAdaptationCtx*) bCtx;
       
   407 
       
   408     if( gst_element_query_duration( GST_ELEMENT(bCtx->bin), &format, &duration ) )
       
   409     {
       
   410         DEBUG_INFO_A1("Duration: %"GST_TIME_FORMAT, GST_TIME_ARGS(duration));
       
   411         ret = XA_RESULT_SUCCESS;
       
   412         *pMsec = GST_TIME_AS_MSECONDS(duration);/*Warning ok due to used API specification*/
       
   413     }
       
   414     else
       
   415     {
       
   416         DEBUG_ERR("WARNING: Gst: could not get duration");
       
   417         *pMsec = XA_TIME_UNKNOWN;
       
   418         ret = XA_RESULT_SUCCESS;
       
   419     }
       
   420 
       
   421     DEBUG_API("<-XAPlayItfAdapt_GetDuration");
       
   422     return ret;
       
   423 }
       
   424 
       
   425 /*
       
   426  * XAresult XAPlayItfAdapt_GetPosition(XAAdaptationBaseCtx *bCtx, XAmillisecond *pMsec)
       
   427  * @param XAAdaptationBaseCtx *bCtx - Adaptation context, this will be casted to correct type regarding to contextID value
       
   428  * XAmillisecond *pMsec - Pointer where to store current position in stream.
       
   429  * @return XAresult ret - Success value
       
   430  */
       
   431 XAresult XAPlayItfAdapt_GetPosition(XAAdaptationBaseCtx *bCtx, XAmillisecond *pMsec)
       
   432 {
       
   433     XAresult ret = XA_RESULT_SUCCESS;
       
   434     XAMediaPlayerAdaptationCtx* mCtx = NULL;
       
   435     gint64 position;
       
   436     GstFormat format = GST_FORMAT_TIME;
       
   437     DEBUG_API("->XAPlayItfAdapt_GetPosition");
       
   438 
       
   439     if(!bCtx || bCtx->ctxId != XAMediaPlayerAdaptation)
       
   440     {
       
   441         DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
       
   442         /* invalid parameter */
       
   443         return XA_RESULT_PARAMETER_INVALID;
       
   444     }
       
   445     mCtx = (XAMediaPlayerAdaptationCtx*) bCtx;
       
   446 
       
   447     if ( gst_element_query_position( GST_ELEMENT(bCtx->bin), &format, &position  ) )
       
   448     {
       
   449         DEBUG_INFO_A1("Current position %"GST_TIME_FORMAT, GST_TIME_ARGS(position));
       
   450         ret = XA_RESULT_SUCCESS;
       
   451         *pMsec = GST_TIME_AS_MSECONDS(position);/*Warning ok due to used API specification*/
       
   452     }
       
   453     else
       
   454     {
       
   455         DEBUG_ERR("WARNING: Gst: could not get position");
       
   456         /* probably not fully prerolled - safe assumption for position = 0 */
       
   457         *pMsec = 0;
       
   458         ret = XA_RESULT_SUCCESS;
       
   459     }
       
   460 
       
   461     DEBUG_API("<-XAPlayItfAdapt_GetPosition");
       
   462     return ret;
       
   463 }
       
   464 
       
   465 /*
       
   466  * XAresult XAPlayItfAdapt_EnablePositionTracking
       
   467  * Enable/disable periodic position tracking callbacks
       
   468  */
       
   469 XAresult XAPlayItfAdapt_EnablePositionTracking(XAAdaptationBaseCtx *bCtx, XAboolean enable)
       
   470 {
       
   471     XAMediaPlayerAdaptationCtx* mCtx;
       
   472 
       
   473     DEBUG_API_A1("->XAPlayItfAdapt_EnablePositionTracking (enable: %d)", (int)enable);
       
   474     if(!bCtx || bCtx->ctxId != XAMediaPlayerAdaptation)
       
   475     {
       
   476         DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
       
   477         /* invalid parameter */
       
   478         return XA_RESULT_PARAMETER_INVALID;
       
   479     }
       
   480     mCtx = (XAMediaPlayerAdaptationCtx*) bCtx;
       
   481     if(enable && !(mCtx->trackpositionenabled))
       
   482     {
       
   483         mCtx->trackpositionenabled = XA_BOOLEAN_TRUE;
       
   484         XAMediaPlayerAdapt_UpdatePositionCbTimer(mCtx);
       
   485     }
       
   486     else if (!enable && (mCtx->trackpositionenabled))
       
   487     {
       
   488         mCtx->trackpositionenabled = XA_BOOLEAN_FALSE;
       
   489         XAMediaPlayerAdapt_UpdatePositionCbTimer(mCtx);
       
   490     }
       
   491 
       
   492     DEBUG_API("<-XAPlayItfAdapt_EnablePositionTracking");
       
   493     return XA_RESULT_SUCCESS;
       
   494 }
       
   495