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