khronosfws/openmax_al/src/gst_adaptation/xarecorditfadaptation.c
changeset 31 8dfd592727cb
parent 22 128eb6a32b84
child 28 ebf79c79991a
equal deleted inserted replaced
22:128eb6a32b84 31:8dfd592727cb
     1 /*
     1 /*
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
     2  * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     3  * All rights reserved.
     4 * This component and the accompanying materials are made available
     4  * This component and the accompanying materials are made available
     5 * under the terms of "Eclipse Public License v1.0"
     5  * under the terms of "Eclipse Public License v1.0"
     6 * which accompanies this distribution, and is available
     6  * which accompanies this distribution, and is available
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7  * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     8 *
     8  *
     9 * Initial Contributors:
     9  * Initial Contributors:
    10 * Nokia Corporation - initial contribution.
    10  * Nokia Corporation - initial contribution.
    11 *
    11  *
    12 * Contributors:
    12  * Contributors:
    13 *
    13  *
    14 * Description: 
    14  * Description: Record Itf GST adaptation
    15 *
    15  *
    16 */
    16  */
    17 
    17 
    18 #include <pthread.h>
    18 #include <pthread.h>
    19 #include <gst/gst.h>
    19 #include <gst/gst.h>
    20 #include "xamediarecorderadaptctx.h"
    20 #include "xamediarecorderadaptctx.h"
    21 #include "xarecorditfadaptation.h"
    21 #include "xarecorditfadaptation.h"
    33  * Sets record state to GStreamer.
    33  * Sets record state to GStreamer.
    34  * @param XAAdaptationGstCtx *ctx - Adaptation context
    34  * @param XAAdaptationGstCtx *ctx - Adaptation context
    35  * XAuint32 state - Record state to be set
    35  * XAuint32 state - Record state to be set
    36  * @return XAresult ret - Success value
    36  * @return XAresult ret - Success value
    37  */
    37  */
    38 XAresult XARecordItfAdapt_SetRecordState(XAAdaptationGstCtx *bCtx, XAuint32 state)
    38 XAresult XARecordItfAdapt_SetRecordState(XAAdaptationGstCtx *bCtx,
    39 {
    39         XAuint32 state)
       
    40     {
    40     XAresult ret = XA_RESULT_SUCCESS;
    41     XAresult ret = XA_RESULT_SUCCESS;
    41     XAboolean closeSink = XA_BOOLEAN_FALSE;
    42     XAboolean closeSink = XA_BOOLEAN_FALSE;
    42     XAboolean requestStateChange = XA_BOOLEAN_FALSE;
    43     XAboolean requestStateChange = XA_BOOLEAN_FALSE;
    43     GstStateChangeReturn gstRet = GST_STATE_CHANGE_SUCCESS;
    44     GstStateChangeReturn gstRet = GST_STATE_CHANGE_SUCCESS;
    44     XAMediaRecorderAdaptationCtx* mCtx = NULL;
    45     XAMediaRecorderAdaptationCtx* mCtx = NULL;
    45     XAboolean recording = XA_BOOLEAN_FALSE;
    46     XAboolean recording = XA_BOOLEAN_FALSE;
    46     DEBUG_API_A1("->XARecordItfAdapt_SetRecordState %s",RECORDSTATENAME(state));
    47     DEBUG_API_A1("->XARecordItfAdapt_SetRecordState %s",RECORDSTATENAME(state));
    47     if(!bCtx || bCtx->baseObj.ctxId != XAMediaRecorderAdaptation)
    48     if (!bCtx || bCtx->baseObj.ctxId != XAMediaRecorderAdaptation)
    48     {
    49         {
    49         DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
    50         DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
    50         DEBUG_API("<-XARecordItfAdapt_SetRecordState");
    51         DEBUG_API("<-XARecordItfAdapt_SetRecordState");
    51         return XA_RESULT_PARAMETER_INVALID;
    52         return XA_RESULT_PARAMETER_INVALID;
    52     }
    53         }
    53 
    54 
    54     mCtx = (XAMediaRecorderAdaptationCtx*) bCtx;
    55     mCtx = (XAMediaRecorderAdaptationCtx*) bCtx;
    55 
    56 
    56     mCtx->isRecord = XA_BOOLEAN_TRUE;
    57     mCtx->isRecord = XA_BOOLEAN_TRUE;
    57 
    58 
    58     switch ( state )
    59     switch (state)
    59     {
    60         {
    60         case XA_RECORDSTATE_STOPPED:
    61         case XA_RECORDSTATE_STOPPED:
    61         {
    62             {
    62                 // Audio sourse should be stopped 
    63             // Audio sourse should be stopped 
    63                 if ( mCtx->audiosource )
    64             if (mCtx->audiosource)
    64                 {
    65                 {
    65                    if ( gst_element_send_event (mCtx->audiosource, gst_event_new_eos ()) == TRUE )
    66                 if (gst_element_send_event(mCtx->audiosource,
    66                    {
    67                         gst_event_new_eos()) == TRUE)
    67                        DEBUG_INFO ("posted eos");
    68                     {
    68                    }
    69                     DEBUG_INFO ("posted eos");
    69                    else
    70                     }
    70                        {
    71                 else
    71                         DEBUG_ERR("FAIL : post eos");
    72                     {
    72                        }
    73                     DEBUG_ERR("FAIL : post eos");
    73                 }
    74                     }
    74         
    75                 }
    75         	if ( cameraCtx && cameraRealized && mCtx->isobjvsrc && mCtx->videosource  )
    76 
    76 			{
    77             if (cameraCtx && cameraRealized && mCtx->isobjvsrc
    77 				cameraCtx->recording = XA_BOOLEAN_FALSE;
    78                     && mCtx->videosource)
    78 
    79                 {
    79 	            if(!cameraCtx->playing && !cameraCtx->snapshotting)
    80                 cameraCtx->recording = XA_BOOLEAN_FALSE;
    80 	            {
    81 
    81 	            	/* Neither view finder or recorder is running -> pause camera */
    82                 if (!cameraCtx->playing && !cameraCtx->snapshotting)
    82 	            	if ( GST_STATE( GST_ELEMENT(mCtx->videosource)) == GST_STATE_PLAYING )
    83                     {
    83 	            	{
    84                     /* Neither view finder or recorder is running -> pause camera */
    84 	            		GstStateChangeReturn gret;
    85                     if (GST_STATE( GST_ELEMENT(mCtx->videosource))
    85 	        			DEBUG_INFO("Stop camera source");
    86                             == GST_STATE_PLAYING)
    86 	        			gret = gst_element_set_state( GST_ELEMENT(mCtx->videosource), GST_STATE_PAUSED );
    87                         {
    87 	        			if(gret == GST_STATE_CHANGE_SUCCESS)
    88                         GstStateChangeReturn gret;
    88 	        			    gret = gst_element_get_state( GST_ELEMENT(mCtx->videosource), NULL,NULL, XA_ADAPT_ASYNC_TIMEOUT_SHORT_NSEC );
    89                         DEBUG_INFO("Stop camera source");
    89 	            	}
    90                         gret = gst_element_set_state(
    90 	            }
    91                                 GST_ELEMENT(mCtx->videosource),
    91 			}
    92                                 GST_STATE_PAUSED);
       
    93                         if (gret == GST_STATE_CHANGE_SUCCESS)
       
    94                             gret = gst_element_get_state(
       
    95                                     GST_ELEMENT(mCtx->videosource), NULL,
       
    96                                     NULL, XA_ADAPT_ASYNC_TIMEOUT_SHORT_NSEC);
       
    97                         }
       
    98                     }
       
    99                 }
    92 
   100 
    93             bCtx->binWantedState = GST_STATE_PAUSED;
   101             bCtx->binWantedState = GST_STATE_PAUSED;
    94             closeSink = XA_BOOLEAN_TRUE;
   102             closeSink = XA_BOOLEAN_TRUE;
    95             if(mCtx->runpositiontimer > 0)
   103             if (mCtx->runpositiontimer > 0)
    96             {
   104                 {
    97                 g_source_remove(mCtx->runpositiontimer);
   105                 g_source_remove(mCtx->runpositiontimer);
    98                 mCtx->runpositiontimer=0;
   106                 mCtx->runpositiontimer = 0;
    99             }
   107                 }
   100 
   108 
   101             if ( mCtx->recThrCtx.bufInsufficientSem )
   109             if (mCtx->recThrCtx.bufInsufficientSem)
   102             {
   110                 {
   103                 DEBUG_INFO("No buffer-insufficient received, posting record thr semaphore.");
   111                 DEBUG_INFO("No buffer-insufficient received, posting record thr semaphore.");
   104                 if ( XAImpl_PostSemaphore( mCtx->recThrCtx.bufInsufficientSem ) != XA_RESULT_SUCCESS)
   112                 if (XAImpl_PostSemaphore(mCtx->recThrCtx.bufInsufficientSem)
   105                 {
   113                         != XA_RESULT_SUCCESS)
       
   114                     {
   106                     DEBUG_ERR("Posting buffer-insufficient semaphore FAILED!");
   115                     DEBUG_ERR("Posting buffer-insufficient semaphore FAILED!");
   107                 }
   116                     }
   108             }
   117                 }
   109 
   118 
   110             break;
   119             break;
   111         }
   120             }
   112         case XA_RECORDSTATE_PAUSED:
   121         case XA_RECORDSTATE_PAUSED:
   113         {
   122             {
   114         	if ( cameraCtx && cameraRealized && mCtx->isobjvsrc && mCtx->videosource  )
   123             if (cameraCtx && cameraRealized && mCtx->isobjvsrc
   115 			{
   124                     && mCtx->videosource)
   116 				cameraCtx->recording = XA_BOOLEAN_FALSE;
   125                 {
   117 				if(!cameraCtx->playing && !cameraCtx->snapshotting)
   126                 cameraCtx->recording = XA_BOOLEAN_FALSE;
   118 				{
   127                 if (!cameraCtx->playing && !cameraCtx->snapshotting)
   119 					/* Neither view finder or recorder is running -> pause camera */
   128                     {
   120 					if ( GST_STATE( GST_ELEMENT(mCtx->videosource)) == GST_STATE_PLAYING )
   129                     /* Neither view finder or recorder is running -> pause camera */
   121 					{
   130                     if (GST_STATE( GST_ELEMENT(mCtx->videosource))
   122 						GstStateChangeReturn gret;
   131                             == GST_STATE_PLAYING)
   123 						DEBUG_INFO("Stop camera source");
   132                         {
   124 						gret = gst_element_set_state( GST_ELEMENT(mCtx->videosource), GST_STATE_PAUSED );
   133                         GstStateChangeReturn gret;
   125 						if(gret == GST_STATE_CHANGE_SUCCESS)
   134                         DEBUG_INFO("Stop camera source");
   126 						    gret = gst_element_get_state( GST_ELEMENT(mCtx->videosource), NULL,NULL, XA_ADAPT_ASYNC_TIMEOUT_SHORT_NSEC );
   135                         gret = gst_element_set_state(
   127 					}
   136                                 GST_ELEMENT(mCtx->videosource),
   128 				}
   137                                 GST_STATE_PAUSED);
   129 			}
   138                         if (gret == GST_STATE_CHANGE_SUCCESS)
   130 
   139                             gret = gst_element_get_state(
   131             if(mCtx->xaRecordState==XA_RECORDSTATE_STOPPED && mCtx->encodingchanged)
   140                                     GST_ELEMENT(mCtx->videosource), NULL,
   132             {
   141                                     NULL, XA_ADAPT_ASYNC_TIMEOUT_SHORT_NSEC);
   133                 XAMediaRecorderAdapt_ChangeEncoders( mCtx );
   142                         }
       
   143                     }
       
   144                 }
       
   145 
       
   146             if (mCtx->xaRecordState == XA_RECORDSTATE_STOPPED
       
   147                     && mCtx->encodingchanged)
       
   148                 {
       
   149                 XAMediaRecorderAdapt_ChangeEncoders(mCtx);
   134                 mCtx->encodingchanged = XA_BOOLEAN_FALSE;
   150                 mCtx->encodingchanged = XA_BOOLEAN_FALSE;
   135             }
   151                 }
   136             bCtx->binWantedState = GST_STATE_PAUSED;
   152             bCtx->binWantedState = GST_STATE_PAUSED;
   137             if(mCtx->runpositiontimer > 0)
   153             if (mCtx->runpositiontimer > 0)
   138             {
   154                 {
   139                 g_source_remove(mCtx->runpositiontimer);
   155                 g_source_remove(mCtx->runpositiontimer);
   140                 mCtx->runpositiontimer=0;
   156                 mCtx->runpositiontimer = 0;
   141             }
   157                 }
   142             break;
   158             break;
   143         }
   159             }
   144         case XA_RECORDSTATE_RECORDING:
   160         case XA_RECORDSTATE_RECORDING:
   145         {
   161             {
   146         	if ( cameraCtx && mCtx->isobjvsrc )
   162             if (cameraCtx && mCtx->isobjvsrc)
   147 			{
   163                 {
   148 				cameraCtx->recording = XA_BOOLEAN_TRUE;
   164                 cameraCtx->recording = XA_BOOLEAN_TRUE;
   149 			}
   165                 }
   150 
   166 
   151             if(mCtx->xaRecordState==XA_RECORDSTATE_STOPPED && (mCtx->encodingchanged))
   167             if (mCtx->xaRecordState == XA_RECORDSTATE_STOPPED
   152             {
   168                     && (mCtx->encodingchanged))
   153                 XAMediaRecorderAdapt_ChangeEncoders( mCtx );
   169                 {
       
   170                 XAMediaRecorderAdapt_ChangeEncoders(mCtx);
   154                 mCtx->encodingchanged = XA_BOOLEAN_FALSE;
   171                 mCtx->encodingchanged = XA_BOOLEAN_FALSE;
   155             }
   172                 }
   156 
   173 
   157             if ( mCtx->recThrCtx.bufInsufficientSem )
   174             if (mCtx->recThrCtx.bufInsufficientSem)
   158             {
   175                 {
   159                 /* Recording to address and recording thread semaphora is created */
   176                 /* Recording to address and recording thread semaphora is created */
   160                 if(! XAImpl_StartThread(&(mCtx->recordingEventThr),NULL, &XAMediaRecorderAdapt_RecordEventThr, (void*)mCtx ))
   177                 if (!XAImpl_StartThread(&(mCtx->recordingEventThr), NULL,
   161                     {
   178                         &XAMediaRecorderAdapt_RecordEventThr, (void*) mCtx))
   162                         DEBUG_ERR("Start thread Failed");
   179                     {
   163 						return XA_RESULT_INTERNAL_ERROR;
   180                     DEBUG_ERR("Start thread Failed");
   164                     }
   181                     return XA_RESULT_INTERNAL_ERROR;
   165             }
   182                     }
       
   183                 }
   166 
   184 
   167             bCtx->binWantedState = GST_STATE_PLAYING;
   185             bCtx->binWantedState = GST_STATE_PLAYING;
   168             recording = XA_BOOLEAN_TRUE;
   186             recording = XA_BOOLEAN_TRUE;
   169             break;
   187             break;
   170         }
   188             }
   171         default:
   189         default:
   172             DEBUG_ERR("Unhandled state");
   190             DEBUG_ERR("Unhandled state")
       
   191             ;
   173             ret = XA_RESULT_PARAMETER_INVALID;
   192             ret = XA_RESULT_PARAMETER_INVALID;
   174             break;
   193             break;
   175     }
   194         }
   176 
   195 
   177     if( ret == XA_RESULT_SUCCESS )
   196     if (ret == XA_RESULT_SUCCESS)
   178     {
   197         {
   179         mCtx->xaRecordState = state;
   198         mCtx->xaRecordState = state;
   180     }
   199         }
   181 
   200 
   182     /* launch Gstreamer state change only if necessary */
   201     /* launch Gstreamer state change only if necessary */
   183     if( GST_STATE_TARGET(bCtx->bin) == bCtx->binWantedState )
   202     if (GST_STATE_TARGET(bCtx->bin) == bCtx->binWantedState)
   184     {
   203         {
   185         DEBUG_INFO("Gst already transitioning to wanted state!!");
   204         DEBUG_INFO("Gst already transitioning to wanted state!!");
   186         requestStateChange = XA_BOOLEAN_FALSE;
   205         requestStateChange = XA_BOOLEAN_FALSE;
   187     }
   206         }
   188     else
   207     else
   189     {
   208         {
   190         if( (GST_STATE(bCtx->bin) == bCtx->binWantedState) &&
   209         if ((GST_STATE(bCtx->bin) == bCtx->binWantedState)
   191             (GST_STATE_PENDING(bCtx->bin) == GST_STATE_VOID_PENDING) )
   210                 && (GST_STATE_PENDING(bCtx->bin) == GST_STATE_VOID_PENDING))
   192         {
   211             {
   193             DEBUG_ERR_A3("WARNING : gststate %d == wanted %d != gsttarget %d and no statechange pending",
   212             DEBUG_ERR_A3("WARNING : gststate %d == wanted %d != gsttarget %d and no statechange pending",
   194                           GST_STATE(bCtx->bin), bCtx->binWantedState, GST_STATE_TARGET(bCtx->bin));
   213                     GST_STATE(bCtx->bin), bCtx->binWantedState, GST_STATE_TARGET(bCtx->bin));
   195         }
   214             }
   196         requestStateChange = XA_BOOLEAN_TRUE;
   215         requestStateChange = XA_BOOLEAN_TRUE;
   197     }
   216         }
   198 
   217 
   199     if( requestStateChange )
   218     if (requestStateChange)
   200     {
   219         {
   201         XAAdaptationGst_PrepareAsyncWait(bCtx);
   220         XAAdaptationGst_PrepareAsyncWait(bCtx);
   202         DEBUG_INFO_A1("Sending change state request to state %d", bCtx->binWantedState);
   221         DEBUG_INFO_A1("Sending change state request to state %d", bCtx->binWantedState);
   203         gstRet = gst_element_set_state( GST_ELEMENT(bCtx->bin), bCtx->binWantedState);
   222         gstRet = gst_element_set_state(GST_ELEMENT(bCtx->bin),
   204         switch ( gstRet )
   223                 bCtx->binWantedState);
   205         {
   224         switch (gstRet)
       
   225             {
   206             case GST_STATE_CHANGE_FAILURE:
   226             case GST_STATE_CHANGE_FAILURE:
   207                 DEBUG_ERR_A1("FAILED to change state (target %d)",bCtx->binWantedState);
   227                 DEBUG_ERR_A1("FAILED to change state (target %d)",bCtx->binWantedState)
       
   228                 ;
   208                 bCtx->binWantedState = GST_STATE(bCtx->bin);
   229                 bCtx->binWantedState = GST_STATE(bCtx->bin);
   209                 ret = XA_RESULT_INTERNAL_ERROR;
   230                 ret = XA_RESULT_INTERNAL_ERROR;
   210                 break;
   231                 break;
   211             case GST_STATE_CHANGE_ASYNC:
   232             case GST_STATE_CHANGE_ASYNC:
   212                 DEBUG_INFO_A1("Change state will happen asyncronously (target %d)",bCtx->binWantedState);
   233                 DEBUG_INFO_A1("Change state will happen asyncronously (target %d)",bCtx->binWantedState);
   213                 XAAdaptationGst_StartAsyncWait(bCtx);
   234                 XAAdaptationGst_StartAsyncWait(bCtx);
   214                 ret = XA_RESULT_SUCCESS;
   235                 ret = XA_RESULT_SUCCESS;
   215                 break;
   236                 break;
   216             case GST_STATE_CHANGE_NO_PREROLL:
   237             case GST_STATE_CHANGE_NO_PREROLL:
   217                 DEBUG_INFO("GST_STATE_CHANGE_NO_PREROLL");
   238                 DEBUG_INFO("GST_STATE_CHANGE_NO_PREROLL")
       
   239                 ;
   218                 /* deliberate fall-through */
   240                 /* deliberate fall-through */
   219             case GST_STATE_CHANGE_SUCCESS:
   241             case GST_STATE_CHANGE_SUCCESS:
   220                 DEBUG_INFO_A1("Successfully changed state (target %d)",bCtx->binWantedState);
   242                 DEBUG_INFO_A1("Successfully changed state (target %d)",bCtx->binWantedState)
       
   243                 ;
   221                 ret = XA_RESULT_SUCCESS;
   244                 ret = XA_RESULT_SUCCESS;
   222                 break;
   245                 break;
   223             default:
   246             default:
   224                 DEBUG_ERR_A1("Unhandled error (%d)",gstRet);
   247                 DEBUG_ERR_A1("Unhandled error (%d)",gstRet)
       
   248                 ;
   225                 ret = XA_RESULT_UNKNOWN_ERROR;
   249                 ret = XA_RESULT_UNKNOWN_ERROR;
   226                 break;
   250                 break;
   227         }
   251             }
   228         bCtx->waitingasyncop = XA_BOOLEAN_FALSE;
   252         bCtx->waitingasyncop = XA_BOOLEAN_FALSE;
       
   253         }
       
   254     if ((GST_STATE(bCtx->bin) > GST_STATE_READY) && closeSink)
       
   255         { /* close the sink*/
       
   256         gst_element_send_event(bCtx->bin, gst_event_new_flush_start());
       
   257         gst_element_send_event(bCtx->bin, gst_event_new_flush_stop());
       
   258         }
       
   259 
       
   260     if (recording && mCtx->isobjvsrc && mCtx->videosource)
       
   261         {
       
   262         GstPad *pad = gst_element_get_static_pad(
       
   263                 GST_ELEMENT(mCtx->videosource), "MRObjSrc");
       
   264         if (pad && gst_pad_is_linked(pad))
       
   265             {
       
   266             DEBUG_INFO_A2("unblock element:%s pad:%s",
       
   267                     gst_element_get_name(mCtx->videosource),
       
   268                     gst_pad_get_name(pad));
       
   269             gst_pad_set_blocked_async(pad, FALSE, XAAdaptationGst_PadBlockCb,
       
   270                     NULL);
       
   271             }
       
   272 
       
   273         if (GST_STATE( GST_ELEMENT(mCtx->videosource)) != GST_STATE_PLAYING)
       
   274             {
       
   275             GstStateChangeReturn gret = GST_STATE_CHANGE_SUCCESS;
       
   276             DEBUG_INFO("Start camera source");
       
   277             gret = gst_element_set_state(GST_ELEMENT(mCtx->videosource),
       
   278                     GST_STATE_PLAYING);
       
   279             if (gret == GST_STATE_CHANGE_SUCCESS)
       
   280                 gret = gst_element_get_state(GST_ELEMENT(mCtx->videosource),
       
   281                         NULL, NULL, XA_ADAPT_ASYNC_TIMEOUT_SHORT_NSEC);
       
   282             }
       
   283         }DEBUG_API("<-XARecordItfAdapt_SetRecordState");
       
   284     return ret;
   229     }
   285     }
   230     if( (GST_STATE(bCtx->bin) > GST_STATE_READY) && closeSink )
       
   231     {   /* close the sink*/
       
   232         gst_element_send_event(bCtx->bin,gst_event_new_flush_start());
       
   233         gst_element_send_event(bCtx->bin,gst_event_new_flush_stop());
       
   234     }
       
   235 
       
   236     if ( recording && mCtx->isobjvsrc && mCtx->videosource )
       
   237     {
       
   238     	GstPad *pad = gst_element_get_static_pad( GST_ELEMENT(mCtx->videosource), "MRObjSrc");
       
   239 		if( pad && gst_pad_is_linked(pad) )
       
   240 		{
       
   241 			DEBUG_INFO_A2("unblock element:%s pad:%s",
       
   242 					gst_element_get_name(mCtx->videosource),
       
   243 					gst_pad_get_name(pad));
       
   244 			gst_pad_set_blocked_async(pad, FALSE, XAAdaptationGst_PadBlockCb, NULL);
       
   245 		}
       
   246 
       
   247 		if ( GST_STATE( GST_ELEMENT(mCtx->videosource)) != GST_STATE_PLAYING )
       
   248 		{
       
   249 			GstStateChangeReturn gret = GST_STATE_CHANGE_SUCCESS;
       
   250 			DEBUG_INFO("Start camera source");
       
   251 			gret = gst_element_set_state( GST_ELEMENT(mCtx->videosource), GST_STATE_PLAYING );
       
   252 			if(gret == GST_STATE_CHANGE_SUCCESS)
       
   253 			    gret = gst_element_get_state( GST_ELEMENT(mCtx->videosource), NULL,NULL, XA_ADAPT_ASYNC_TIMEOUT_SHORT_NSEC );
       
   254 		}
       
   255     }
       
   256     DEBUG_API("<-XARecordItfAdapt_SetRecordState");
       
   257     return ret;
       
   258 }
       
   259 
   286 
   260 /*
   287 /*
   261  * XAresult XARecordItfAdapt_GetRecordState(XAAdaptationGstCtx *bCtx, XAuint32 *state)
   288  * XAresult XARecordItfAdapt_GetRecordState(XAAdaptationGstCtx *bCtx, XAuint32 *state)
   262  * Description: Return record state
   289  * Description: Return record state
   263  */
   290  */
   264 XAresult XARecordItfAdapt_GetRecordState(XAAdaptationGstCtx *bCtx, XAuint32 *state)
   291 XAresult XARecordItfAdapt_GetRecordState(XAAdaptationGstCtx *bCtx,
   265 {
   292         XAuint32 *state)
       
   293     {
   266     XAMediaRecorderAdaptationCtx* mCtx = NULL;
   294     XAMediaRecorderAdaptationCtx* mCtx = NULL;
   267     DEBUG_API("->XARecordItfAdapt_GetRecordState");
   295     DEBUG_API("->XARecordItfAdapt_GetRecordState");
   268 
   296 
   269     if(!bCtx || bCtx->baseObj.ctxId != XAMediaRecorderAdaptation)
   297     if (!bCtx || bCtx->baseObj.ctxId != XAMediaRecorderAdaptation)
   270     {
   298         {
   271         DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
   299         DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
   272         DEBUG_API("<-XARecordItfAdapt_GetRecordState");
   300         DEBUG_API("<-XARecordItfAdapt_GetRecordState");
   273         return XA_RESULT_PARAMETER_INVALID;
   301         return XA_RESULT_PARAMETER_INVALID;
   274     }
   302         }
   275 
   303 
   276     mCtx = (XAMediaRecorderAdaptationCtx*) bCtx;
   304     mCtx = (XAMediaRecorderAdaptationCtx*) bCtx;
   277 
   305 
   278     *state = mCtx->xaRecordState;
   306     *state = mCtx->xaRecordState;
   279 
   307 
   280     DEBUG_API("<-XARecordItfAdapt_GetRecordState");
   308     DEBUG_API("<-XARecordItfAdapt_GetRecordState");
   281     return XA_RESULT_SUCCESS;
   309     return XA_RESULT_SUCCESS;
   282 }
   310     }
   283 
   311 
   284 /*
   312 /*
   285  * XAresult XARecordItfAdapt_GetPosition(XAAdaptationGstCtx *ctx, AdaptationContextIDS ctxIDs, XAmillisecond *pMsec)
   313  * XAresult XARecordItfAdapt_GetPosition(XAAdaptationGstCtx *ctx, AdaptationContextIDS ctxIDs, XAmillisecond *pMsec)
   286  * @param XAAdaptationGstCtx *ctx - Adaptation context, this will be casted to correct type regarding to contextID value given as 2nd parameter
   314  * @param XAAdaptationGstCtx *ctx - Adaptation context, this will be casted to correct type regarding to contextID value given as 2nd parameter
   287  * XAmillisecond *pMsec - Pointer where to store current position in stream.
   315  * XAmillisecond *pMsec - Pointer where to store current position in stream.
   288  * @return XAresult ret - Success value
   316  * @return XAresult ret - Success value
   289  */
   317  */
   290 XAresult XARecordItfAdapt_GetPosition(XAAdaptationGstCtx *bCtx, XAmillisecond *pMsec)
   318 XAresult XARecordItfAdapt_GetPosition(XAAdaptationGstCtx *bCtx,
   291 {
   319         XAmillisecond *pMsec)
       
   320     {
   292     XAresult ret = XA_RESULT_SUCCESS;
   321     XAresult ret = XA_RESULT_SUCCESS;
   293     
   322 
   294     gint64 position=0;
   323     gint64 position = 0;
   295     GstFormat format = GST_FORMAT_TIME;
   324     GstFormat format = GST_FORMAT_TIME;
   296     DEBUG_API("->XARecordItfAdapt_GetPosition");
   325     DEBUG_API("->XARecordItfAdapt_GetPosition");
   297 
   326 
   298     if(!bCtx || bCtx->baseObj.ctxId != XAMediaRecorderAdaptation)
   327     if (!bCtx || bCtx->baseObj.ctxId != XAMediaRecorderAdaptation)
   299     {
   328         {
   300         DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
   329         DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
   301         DEBUG_API("<-XARecordItfAdapt_GetPosition");
   330         DEBUG_API("<-XARecordItfAdapt_GetPosition");
   302         /* invalid parameter */
   331         /* invalid parameter */
   303         return XA_RESULT_PARAMETER_INVALID;
   332         return XA_RESULT_PARAMETER_INVALID;
   304     }
   333         }
   305     if ( gst_element_query_position( GST_ELEMENT(bCtx->bin), &format, &position  ) )
   334     if (gst_element_query_position(GST_ELEMENT(bCtx->bin), &format, &position))
   306     {
   335         {
   307         ret = XA_RESULT_SUCCESS;
   336         ret = XA_RESULT_SUCCESS;
   308         *pMsec = GST_TIME_AS_MSECONDS(position); /*Warning ok due to used API specification*/
   337         *pMsec = GST_TIME_AS_MSECONDS(position); /*Warning ok due to used API specification*/
   309         DEBUG_INFO_A1("Gst: Position in microseconds : %u", *pMsec );
   338         DEBUG_INFO_A1("Gst: Position in microseconds : %u", *pMsec );
   310     }
   339         }
   311     else
   340     else
   312     {
   341         {
   313         DEBUG_ERR("WARNING: Gst: could not get position");
   342         DEBUG_ERR("WARNING: Gst: could not get position");
   314         /* probably not fully prerolled - safe assumption for position = 0 */
   343         /* probably not fully prerolled - safe assumption for position = 0 */
   315         *pMsec = 0;
   344         *pMsec = 0;
   316         ret = XA_RESULT_SUCCESS;
   345         ret = XA_RESULT_SUCCESS;
   317     }
   346         }
   318 
   347 
   319     DEBUG_API("<-XARecordItfAdapt_GetPosition");
   348     DEBUG_API("<-XARecordItfAdapt_GetPosition");
   320     return ret;
   349     return ret;
   321 }
   350     }
   322 
       
   323 
   351 
   324 /*
   352 /*
   325  * gboolean XARecordItfAdapt_PositionUpdate(gpointer ctx)
   353  * gboolean XARecordItfAdapt_PositionUpdate(gpointer ctx)
   326  * callback.
   354  * callback.
   327  * If position tracking enabled, periodic timer calls this method every XA_ADAPT_PU_INTERVAL msecs
   355  * If position tracking enabled, periodic timer calls this method every XA_ADAPT_PU_INTERVAL msecs
   328  * @return false to stop periodic calls
   356  * @return false to stop periodic calls
   329  */
   357  */
   330 gboolean XARecordItfAdapt_PositionUpdate(gpointer ctx)
   358 gboolean XARecordItfAdapt_PositionUpdate(gpointer ctx)
   331 {
   359     {
   332     XAAdaptationGstCtx *bCtx = (XAAdaptationGstCtx*) ctx;
   360     XAAdaptationGstCtx *bCtx = (XAAdaptationGstCtx*) ctx;
   333     XAMediaRecorderAdaptationCtx* mCtx = (XAMediaRecorderAdaptationCtx*) ctx;
   361     XAMediaRecorderAdaptationCtx* mCtx = (XAMediaRecorderAdaptationCtx*) ctx;
   334     DEBUG_API("->XARecordItfAdapt_PositionUpdate");
   362     DEBUG_API("->XARecordItfAdapt_PositionUpdate");
   335 
   363 
   336     if( mCtx && mCtx->trackpositionenabled )
   364     if (mCtx && mCtx->trackpositionenabled)
   337     {
   365         {
   338         GstFormat format = GST_FORMAT_TIME;
   366         GstFormat format = GST_FORMAT_TIME;
   339         gint64 position = 0;
   367         gint64 position = 0;
   340         if ( gst_element_query_position( GST_ELEMENT(bCtx->bin), &format, &position ) )
   368         if (gst_element_query_position(GST_ELEMENT(bCtx->bin), &format,
   341         {
   369                 &position))
   342             XAuint32 posMsec = GST_TIME_AS_MSECONDS(position);/*Warning ok due to used API specification*/
   370             {
   343             XAAdaptEvent event = {XA_RECORDITFEVENTS, XA_ADAPT_POSITION_UPDATE_EVT, 1, NULL};
   371             XAuint32 posMsec = GST_TIME_AS_MSECONDS(position);
       
   372             /*Warning ok due to used API specification*/
       
   373             XAAdaptEvent event =
       
   374                 {
       
   375                 XA_RECORDITFEVENTS, XA_ADAPT_POSITION_UPDATE_EVT, 1, NULL
       
   376                 };
   344             event.data = &posMsec;
   377             event.data = &posMsec;
   345             DEBUG_API_A1("XARecordItfAdapt_PositionUpdate: pos %lu ms", posMsec);
   378             DEBUG_API_A1("XARecordItfAdapt_PositionUpdate: pos %lu ms", posMsec);
   346             /* send needed events */
   379             /* send needed events */
   347             XAAdaptationBase_SendAdaptEvents(&bCtx->baseObj, &event );
   380             XAAdaptationBase_SendAdaptEvents(&bCtx->baseObj, &event);
   348         }
   381             }
   349         else
   382         else
   350         {
   383             {
   351             DEBUG_ERR("Gst: Failed to get position");
   384             DEBUG_ERR("Gst: Failed to get position");
   352         }
   385             }
   353     DEBUG_API_A1("<-XARecordItfAdapt_PositionUpdate: %d", mCtx->runpositiontimer);
   386         DEBUG_API_A1("<-XARecordItfAdapt_PositionUpdate: %d", mCtx->runpositiontimer);
   354     /* return false to stop timer */
   387         /* return false to stop timer */
   355     return( mCtx->runpositiontimer );
   388         return (mCtx->runpositiontimer);
       
   389         }
       
   390     return FALSE;
   356     }
   391     }
   357     return FALSE;
       
   358 }
       
   359 
   392 
   360 /*
   393 /*
   361  * XAresult XARecordItfAdapt_EnablePositionTracking
   394  * XAresult XARecordItfAdapt_EnablePositionTracking
   362  * Enable/disable periodic position tracking callbacks
   395  * Enable/disable periodic position tracking callbacks
   363  */
   396  */
   364 XAresult XARecordItfAdapt_EnablePositionTracking(XAAdaptationGstCtx *bCtx, XAboolean enable)
   397 XAresult XARecordItfAdapt_EnablePositionTracking(XAAdaptationGstCtx *bCtx,
   365 {
   398         XAboolean enable)
       
   399     {
   366     XAMediaRecorderAdaptationCtx* mCtx = (XAMediaRecorderAdaptationCtx*) bCtx;
   400     XAMediaRecorderAdaptationCtx* mCtx = (XAMediaRecorderAdaptationCtx*) bCtx;
   367     DEBUG_API_A1("->XARecordItfAdapt_EnablePositionTracking (enable: %lu)", enable);
   401     DEBUG_API_A1("->XARecordItfAdapt_EnablePositionTracking (enable: %lu)", enable);
   368 
   402 
   369     if(!bCtx || bCtx->baseObj.ctxId != XAMediaRecorderAdaptation)
   403     if (!bCtx || bCtx->baseObj.ctxId != XAMediaRecorderAdaptation)
   370     {
   404         {
   371         DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
   405         DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
   372         DEBUG_API("<-XARecordItfAdapt_EnablePositionTracking");
   406         DEBUG_API("<-XARecordItfAdapt_EnablePositionTracking");
   373         /* invalid parameter */
   407         /* invalid parameter */
   374         return XA_RESULT_PARAMETER_INVALID;
   408         return XA_RESULT_PARAMETER_INVALID;
   375     }
   409         }
   376 
       
   377 
   410 
   378     /* create a timer to track position of playback */
   411     /* create a timer to track position of playback */
   379     if(enable && !(mCtx->trackpositionenabled))
   412     if (enable && !(mCtx->trackpositionenabled))
   380     {
   413         {
   381         mCtx->trackpositionenabled = XA_BOOLEAN_TRUE;
   414         mCtx->trackpositionenabled = XA_BOOLEAN_TRUE;
   382         mCtx->positionCb = &XARecordItfAdapt_PositionUpdate;
   415         mCtx->positionCb = &XARecordItfAdapt_PositionUpdate;
   383         /* if recording is already on, create a timer to track position of recording */
   416         /* if recording is already on, create a timer to track position of recording */
   384         if( GST_STATE(bCtx->bin) == GST_STATE_PLAYING )
   417         if (GST_STATE(bCtx->bin) == GST_STATE_PLAYING)
   385         {
   418             {
   386             mCtx->runpositiontimer = g_timeout_add(XA_ADAPT_PU_INTERVAL, mCtx->positionCb, mCtx);
   419             mCtx->runpositiontimer = g_timeout_add(XA_ADAPT_PU_INTERVAL,
   387         }
   420                     mCtx->positionCb, mCtx);
   388     }
   421             }
       
   422         }
   389     else if (!enable && (mCtx->trackpositionenabled))
   423     else if (!enable && (mCtx->trackpositionenabled))
   390     {
   424         {
   391         mCtx->trackpositionenabled = XA_BOOLEAN_FALSE;
   425         mCtx->trackpositionenabled = XA_BOOLEAN_FALSE;
   392         if(mCtx->runpositiontimer > 0)
   426         if (mCtx->runpositiontimer > 0)
   393         {
   427             {
   394             g_source_remove(mCtx->runpositiontimer);
   428             g_source_remove(mCtx->runpositiontimer);
   395             mCtx->runpositiontimer=0;
   429             mCtx->runpositiontimer = 0;
   396         }
   430             }
   397     }
   431         }
   398 
   432 
   399     DEBUG_API("<-XARecordItfAdapt_EnablePositionTracking");
   433     DEBUG_API("<-XARecordItfAdapt_EnablePositionTracking");
   400     return XA_RESULT_SUCCESS;
   434     return XA_RESULT_SUCCESS;
   401 }
   435     }
   402 
   436