khronosfws/openmax_al/src/gst_adaptation/xacameraadaptctx.c
changeset 42 1fa3fb47b1e3
parent 32 94fc26b6e006
child 47 c2e43643db4c
equal deleted inserted replaced
32:94fc26b6e006 42:1fa3fb47b1e3
     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 <string.h>
       
    19 #include <gst/gst.h>
       
    20 #include "xacameraadaptctx.h"
       
    21 #include "xaadaptationgst.h"
       
    22 #include <gst/interfaces/photography.h>
       
    23 //#include "XAStaticCapsAdaptation.h"
       
    24 
       
    25 
       
    26 XAboolean cameraRealized = XA_BOOLEAN_FALSE;
       
    27 XACameraAdaptationCtx_* cameraCtx = NULL;
       
    28 
       
    29 /*
       
    30  * gboolean XACameraAdapt_GstBusCb( GstBus *bus, GstMessage *message, gpointer data )
       
    31  * MediaPlayer Gst-bus message handler (Callback)
       
    32  */
       
    33 gboolean XACameraAdapt_GstBusCb( GstBus *bus, GstMessage *message, gpointer data )
       
    34 {
       
    35     XACameraAdaptationCtx* mCtx = (XACameraAdaptationCtx*)data;
       
    36     XAAdaptEvent event = {XA_CAMERAITFEVENTS,XA_CAMERACBEVENT_FOCUSSTATUS,1,NULL};
       
    37     XAuint32 status;
       
    38 
       
    39     /* only listen to pipeline messages */
       
    40     if(GST_MESSAGE_SRC(message)==(GstObject*)(mCtx->baseObj.bin) )
       
    41     {
       
    42         DEBUG_API_A2("->XACameraAdapt_GstBusCb:\"%s\" from object \"%s\"",
       
    43                         GST_MESSAGE_TYPE_NAME(message), GST_OBJECT_NAME(GST_MESSAGE_SRC(message)));
       
    44 
       
    45         if ( GST_MESSAGE_TYPE(message)== GST_MESSAGE_ASYNC_DONE )
       
    46         {
       
    47             /* some async sequence ended */
       
    48             XAAdaptationGst_CompleteAsyncWait((&mCtx->baseObj));
       
    49         }
       
    50         else if (strncmp(GST_MESSAGE_TYPE_NAME(message), GST_PHOTOGRAPHY_AUTOFOCUS_DONE,
       
    51                             strlen(GST_PHOTOGRAPHY_AUTOFOCUS_DONE))==0 )
       
    52         {
       
    53             DEBUG_INFO("Autofocus done!.")
       
    54             status = XA_CAMERA_FOCUSMODESTATUS_REACHED;
       
    55             event.data = &status;
       
    56             XAAdaptationBase_SendAdaptEvents(&(mCtx->baseObj.baseObj), &event );
       
    57         }
       
    58         else if ( strncmp(GST_MESSAGE_TYPE_NAME(message), GST_PHOTOGRAPHY_SHAKE_RISK,
       
    59                             strlen(GST_PHOTOGRAPHY_SHAKE_RISK)) ==0 )
       
    60         {
       
    61             DEBUG_INFO("Camera shake risk!")
       
    62         }
       
    63         DEBUG_API("<-XACameraAdapt_GstBusCb");
       
    64     }
       
    65     return TRUE;
       
    66 }
       
    67 
       
    68 /*
       
    69  * XAAdaptationGstCtx* XACameraAdapt_Create()
       
    70  * Allocates memory for Camera Adaptation Context and makes 1st phase initialization
       
    71  * @returns XACameraAdaptationCtx* - Pointer to created context
       
    72  */
       
    73 XAAdaptationBaseCtx* XACameraAdapt_Create(XAuint32 deviceID)
       
    74 {
       
    75     XACameraAdaptationCtx *pSelf = (XACameraAdaptationCtx*) calloc(1, sizeof(XACameraAdaptationCtx));
       
    76     DEBUG_API("->XACameraAdapt_Create");
       
    77     if ( pSelf)
       
    78     {
       
    79         if( XAAdaptationGst_Init(&(pSelf->baseObj),XACameraAdaptation)
       
    80                     != XA_RESULT_SUCCESS )
       
    81         {
       
    82             DEBUG_ERR("Failed to init base context!!!");
       
    83             free(pSelf);
       
    84             pSelf = NULL;
       
    85         }
       
    86         else
       
    87         {
       
    88             pSelf->deviceID = deviceID;
       
    89             pSelf->curMirror = XA_VIDEOMIRROR_NONE;
       
    90             pSelf->curRotation = 0;
       
    91             pSelf->recording = XA_BOOLEAN_FALSE;
       
    92             pSelf->playing = XA_BOOLEAN_FALSE;
       
    93             pSelf->snapshotting = XA_BOOLEAN_FALSE;
       
    94             cameraCtx = pSelf; /* Store global pointer */
       
    95             DEBUG_INFO_A1("Stored global camera ponter to %x", cameraCtx);
       
    96             cameraRealized = XA_BOOLEAN_FALSE;
       
    97         }
       
    98     }
       
    99 
       
   100     DEBUG_API("<-XACameraAdapt_Create");
       
   101     return (XAAdaptationBaseCtx*)&pSelf->baseObj;
       
   102 }
       
   103 
       
   104 /*
       
   105  * XAresult XACameraAdapt_PostInit()
       
   106  * 2nd phase initialization of Camera Adaptation Context
       
   107  */
       
   108 XAresult XACameraAdapt_PostInit(XAAdaptationBaseCtx* bCtx)
       
   109 {
       
   110     XAresult ret = XA_RESULT_SUCCESS;
       
   111 
       
   112     XACameraAdaptationCtx* ctx = NULL;
       
   113     DEBUG_API("->XACameraAdapt_PostInit");
       
   114     if(bCtx == NULL || bCtx->ctxId != XACameraAdaptation)
       
   115     {
       
   116         DEBUG_ERR("Invalid parameter!!");
       
   117         DEBUG_API("<-XACameraAdapt_PostInit");
       
   118         return XA_RESULT_PARAMETER_INVALID;
       
   119     }
       
   120     ctx = (XACameraAdaptationCtx*)bCtx;
       
   121 
       
   122     if ( !ctx )
       
   123     {
       
   124         return XA_RESULT_INTERNAL_ERROR;
       
   125     }
       
   126 
       
   127     XAAdaptationGst_PostInit( &(ctx->baseObj) );
       
   128 
       
   129     ctx->baseObj.bin = gst_element_factory_make( "camerabin", "camera");
       
   130     if ( !ctx->baseObj.bin )
       
   131     {
       
   132         DEBUG_ERR("Failed to create CameraBin");
       
   133         return XA_RESULT_INTERNAL_ERROR;
       
   134     }
       
   135 
       
   136     /* Create Gst bus listener. */
       
   137     ret = XAAdaptationGst_InitGstListener(&(ctx->baseObj));
       
   138     if( ret!=XA_RESULT_SUCCESS )
       
   139     {
       
   140         DEBUG_ERR("Bus listener creation failed!!");
       
   141         return ret;
       
   142     }
       
   143     /* Add Camera specific handler */
       
   144     if(ctx->baseObj.bus)
       
   145     {
       
   146         ctx->baseObj.busCb = XACameraAdapt_GstBusCb;
       
   147         gst_bus_add_signal_watch( ctx->baseObj.bus);
       
   148         g_signal_connect(ctx->baseObj.bus, "message::autofocus-done", G_CALLBACK(ctx->baseObj.busCb), ctx );
       
   149         g_signal_connect(ctx->baseObj.bus, "message::shake-risk", G_CALLBACK(ctx->baseObj.busCb), ctx );
       
   150         g_signal_connect(ctx->baseObj.bus, "message::async-done", G_CALLBACK(ctx->baseObj.busCb), ctx );
       
   151     }
       
   152     else
       
   153     {
       
   154         DEBUG_ERR("Failed to create message bus");
       
   155         return XA_RESULT_INTERNAL_ERROR;
       
   156     }
       
   157 
       
   158 
       
   159     /* SET UP CAMERABIN */
       
   160 
       
   161     /* use test video source if set, camerabin default (v4l2src) otherwise */
       
   162 #ifdef XA_USE_TEST_PLUGINS
       
   163     if(ctx->deviceID == XA_ADAPTID_VIDEOTESTSRC || ctx->deviceID == XA_DEFAULTDEVICEID_CAMERA )
       
   164 #else
       
   165     if(ctx->deviceID == XA_ADAPTID_VIDEOTESTSRC )
       
   166 #endif
       
   167     {
       
   168         g_object_set( G_OBJECT(ctx->baseObj.bin), "videosrc", gst_element_factory_make("videotestsrc", "videotestsrc"), NULL );
       
   169     }
       
   170 
       
   171     /* set viewfinder element to be fake for the time of preroll.. if ghost pad added now,
       
   172      * stupid camerabin makes circular linking...
       
   173      */
       
   174     g_object_set( G_OBJECT(ctx->baseObj.bin), "vfsink" ,gst_element_factory_make("fakesink", "fakevfsink"), NULL );
       
   175 
       
   176     /* Setup camerabin to produce raw video */
       
   177     g_object_set( G_OBJECT(ctx->baseObj.bin), "videomux",NULL, NULL );
       
   178     g_object_set( G_OBJECT(ctx->baseObj.bin), "videoenc",NULL, NULL );
       
   179     g_object_set( G_OBJECT(ctx->baseObj.bin), "mute", TRUE, NULL );
       
   180     g_object_set( G_OBJECT(ctx->baseObj.bin), "async-handling", FALSE, NULL);
       
   181 	g_object_set( G_OBJECT(ctx->baseObj.bin), "mode",(gint)1, NULL);
       
   182 
       
   183 
       
   184     /* drive camerabin to READY to create the elements inside bin */
       
   185     gst_element_set_state( GST_ELEMENT(ctx->baseObj.bin), GST_STATE_READY);
       
   186 
       
   187     if(ctx->deviceID == XA_ADAPTID_VIDEOTESTSRC)
       
   188     {   /* set properties for videotestsrc */
       
   189         GstElement *testsrc = gst_bin_get_by_name(GST_BIN(ctx->baseObj.bin), "videotestsrc");
       
   190         g_object_set( G_OBJECT(testsrc),"is-live", TRUE, NULL);
       
   191         g_object_set( G_OBJECT(testsrc),"do-timestamp", TRUE, NULL);
       
   192         gst_object_unref(G_OBJECT(testsrc));
       
   193     }
       
   194 
       
   195     /* do some filter optimization */
       
   196 #ifdef XA_USE_TEST_PLUGINS
       
   197     g_object_set( G_OBJECT(ctx->baseObj.bin), "filter-caps",
       
   198                     gst_caps_new_simple("video/x-raw-yuv",
       
   199                                         "format", GST_TYPE_FOURCC,GST_MAKE_FOURCC('I','4','2','0'),
       
   200                                         "framerate",GST_TYPE_FRACTION_RANGE,0,1,30,1, NULL)
       
   201                 ,NULL );
       
   202 #else
       
   203     g_object_set( G_OBJECT(ctx->baseObj.bin), "filter-caps",
       
   204                     gst_caps_new_simple("video/x-raw-yuv",
       
   205                                         "format", GST_TYPE_FOURCC,GST_MAKE_FOURCC('Y','U','Y','2'),
       
   206                                         "framerate",GST_TYPE_FRACTION_RANGE,0,1,30,1, NULL)
       
   207                 ,NULL );
       
   208 
       
   209 #endif
       
   210 
       
   211     /* now, unlink fake sink, create camera post processing pipeline and create ghost pad from it */
       
   212     {
       
   213         GstElement *fakesink = gst_bin_get_by_name(GST_BIN(ctx->baseObj.bin),"fakevfsink");
       
   214         GstPad *fakepad = gst_element_get_static_pad(fakesink,"sink");
       
   215         GstPad *linkedpad = gst_pad_get_peer(fakepad);
       
   216         GstElement *linkedelement = gst_pad_get_parent_element(linkedpad);
       
   217         GstElement * cameraPP = NULL;
       
   218         GstElement * camfilter = NULL;
       
   219         GstElement *tee = NULL;
       
   220 
       
   221         /* Unlink fakesink */
       
   222         gst_element_unlink(linkedelement,fakesink);
       
   223         /* Create VideoPP pipeline for Camera object */
       
   224         cameraPP = XAAdaptationGst_CreateVideoPP();
       
   225         g_object_set( G_OBJECT(cameraPP),"name", "videopp_camera", NULL);
       
   226         gst_bin_add( GST_BIN(ctx->baseObj.bin), cameraPP );
       
   227         /*Link videoPP into camera bin last element */
       
   228         if (! gst_element_link( linkedelement, cameraPP ))
       
   229             {
       
   230                  DEBUG_ERR("Could not link VideoPP to Camera bin!!");
       
   231                  return XA_RESULT_INTERNAL_ERROR;
       
   232             }
       
   233 
       
   234         /* Add extra filter for caps negotiable after post processing*/
       
   235         camfilter = gst_element_factory_make("capsfilter", "camfilter");
       
   236         gst_bin_add( GST_BIN(ctx->baseObj.bin), camfilter );
       
   237         if(! gst_element_link( cameraPP, camfilter ))
       
   238             {
       
   239                  DEBUG_ERR("Could not link camera bin  to camerafilter!!");
       
   240                  return XA_RESULT_INTERNAL_ERROR;
       
   241             }
       
   242 
       
   243         /* Add tee element into camerabin */
       
   244         tee = gst_element_factory_make( "tee", "CamTee");
       
   245         gst_bin_add( GST_BIN(ctx->baseObj.bin), tee);
       
   246         if (! gst_element_link( camfilter, tee ))
       
   247             {
       
   248                  DEBUG_ERR("Could not link camera filter  to tee element!!");
       
   249                  return XA_RESULT_INTERNAL_ERROR;
       
   250             }
       
   251 		/* Unref */
       
   252         gst_object_unref(linkedelement);
       
   253         gst_object_unref(linkedpad);
       
   254         gst_object_unref(fakepad);
       
   255         gst_bin_remove(GST_BIN(ctx->baseObj.bin),fakesink);
       
   256         gst_object_unparent(GST_OBJECT(fakesink));
       
   257     }
       
   258 
       
   259     if ( ret == XA_RESULT_SUCCESS )
       
   260     {
       
   261     	cameraRealized = XA_BOOLEAN_TRUE;
       
   262     }
       
   263 
       
   264     DEBUG_API("<-XACameraAdapt_PostInit");
       
   265     return ret;
       
   266 }
       
   267 
       
   268 /*
       
   269  * void XACameraAdapt_Destroy(XACameraAdaptationCtx* ctx)
       
   270  * Destroys Camera Adaptation Context
       
   271  * @param ctx - Camera Adaptation context to be destroyed
       
   272  */
       
   273 void XACameraAdapt_Destroy(XAAdaptationBaseCtx* bCtx)
       
   274 {
       
   275 	XACameraAdaptationCtx* ctx = NULL;
       
   276 
       
   277 	DEBUG_API("->XACameraAdapt_Destroy");
       
   278 	if(bCtx == NULL || bCtx->ctxId != XACameraAdaptation )
       
   279 	{
       
   280 		DEBUG_ERR("Invalid parameter!!");
       
   281 		DEBUG_API("<-XACameraAdapt_Destroy");
       
   282 		return;
       
   283 	}
       
   284 	ctx = (XACameraAdaptationCtx*)bCtx;
       
   285 
       
   286     XAAdaptationGst_Free(&(ctx->baseObj));
       
   287 
       
   288     free(ctx);
       
   289     ctx = NULL;
       
   290     cameraCtx = NULL;
       
   291     cameraRealized = XA_BOOLEAN_FALSE;
       
   292     DEBUG_API("<-XACameraAdapt_Destroy");
       
   293 }
       
   294