khronosfws/openmax_al/src/adaptation/xacameraadaptctx.c
changeset 12 5a06f39ad45b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/khronosfws/openmax_al/src/adaptation/xacameraadaptctx.c	Fri Apr 16 15:29:42 2010 +0300
@@ -0,0 +1,283 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+
+#include <string.h>
+#include <gst.h>
+#include "XACameraAdaptCtx.h"
+#include "XAAdaptation.h"
+#include <photography.h>
+#include "XAStaticCapsAdaptation.h"
+
+
+XAboolean cameraRealized = XA_BOOLEAN_FALSE;
+XACameraAdaptationCtx_* cameraCtx = NULL;
+
+/*
+ * gboolean XACameraAdapt_GstBusCb( GstBus *bus, GstMessage *message, gpointer data )
+ * MediaPlayer Gst-bus message handler (Callback)
+ */
+gboolean XACameraAdapt_GstBusCb( GstBus *bus, GstMessage *message, gpointer data )
+{
+    XACameraAdaptationCtx* mCtx = (XACameraAdaptationCtx*)data;
+    XAAdaptEvent event = {XA_CAMERAITFEVENTS,XA_CAMERACBEVENT_FOCUSSTATUS,1,NULL};
+    XAuint32 status;
+
+    /* only listen to pipeline messages */
+    if(GST_MESSAGE_SRC(message)==(GstObject*)(mCtx->baseObj.bin) )
+    {
+        DEBUG_API_A2("->XACameraAdapt_GstBusCb:\"%s\" from object \"%s\"",
+                        GST_MESSAGE_TYPE_NAME(message), GST_OBJECT_NAME(GST_MESSAGE_SRC(message)));
+
+        if ( GST_MESSAGE_TYPE(message)== GST_MESSAGE_ASYNC_DONE )
+        {
+            /* some async sequence ended */
+            XAAdaptationBase_CompleteAsyncWait((&mCtx->baseObj));
+        }
+        else if (strncmp(GST_MESSAGE_TYPE_NAME(message), GST_PHOTOGRAPHY_AUTOFOCUS_DONE,
+                            strlen(GST_PHOTOGRAPHY_AUTOFOCUS_DONE))==0 )
+        {
+            DEBUG_INFO("Autofocus done!.")
+            status = XA_CAMERA_FOCUSMODESTATUS_REACHED;
+            event.data = &status;
+            XAAdaptationBase_SendAdaptEvents(&(mCtx->baseObj), &event );
+        }
+        else if ( strncmp(GST_MESSAGE_TYPE_NAME(message), GST_PHOTOGRAPHY_SHAKE_RISK,
+                            strlen(GST_PHOTOGRAPHY_SHAKE_RISK)) ==0 )
+        {
+            DEBUG_INFO("Camera shake risk!")
+        }
+        DEBUG_API("<-XACameraAdapt_GstBusCb");
+    }
+    return TRUE;
+}
+
+/*
+ * XAAdaptationBaseCtx* XACameraAdapt_Create()
+ * Allocates memory for Camera Adaptation Context and makes 1st phase initialization
+ * @returns XACameraAdaptationCtx* - Pointer to created context
+ */
+XAAdaptationBaseCtx* XACameraAdapt_Create(XAuint32 deviceID)
+{
+    XACameraAdaptationCtx *pSelf = calloc(1, sizeof(XACameraAdaptationCtx));
+    DEBUG_API("->XACameraAdapt_Create");
+    if ( pSelf)
+    {
+        if( XAAdaptationBase_Init(&(pSelf->baseObj),XACameraAdaptation)
+                    != XA_RESULT_SUCCESS )
+        {
+            DEBUG_ERR("Failed to init base context!!!");
+            free(pSelf);
+            pSelf = NULL;
+        }
+        else
+        {
+            pSelf->deviceID = deviceID;
+            pSelf->curMirror = XA_VIDEOMIRROR_NONE;
+            pSelf->curRotation = 0;
+            pSelf->recording = XA_BOOLEAN_FALSE;
+            pSelf->playing = XA_BOOLEAN_FALSE;
+            pSelf->snapshotting = XA_BOOLEAN_FALSE;
+            cameraCtx = pSelf; /* Store global pointer */
+            DEBUG_INFO_A1("Stored global camera ponter to %x", cameraCtx);
+            cameraRealized = XA_BOOLEAN_FALSE;
+        }
+    }
+
+    DEBUG_API("<-XACameraAdapt_Create");
+    return (XAAdaptationBaseCtx*)pSelf;
+}
+
+/*
+ * XAresult XACameraAdapt_PostInit()
+ * 2nd phase initialization of Camera Adaptation Context
+ */
+XAresult XACameraAdapt_PostInit(XAAdaptationBaseCtx* bCtx)
+{
+    XAresult ret = XA_RESULT_SUCCESS;
+
+    XACameraAdaptationCtx* ctx = NULL;
+    DEBUG_API("->XACameraAdapt_PostInit");
+    if(bCtx == NULL || bCtx->ctxId != XACameraAdaptation)
+    {
+        DEBUG_ERR("Invalid parameter!!");
+        DEBUG_API("<-XACameraAdapt_PostInit");
+        return XA_RESULT_PARAMETER_INVALID;
+    }
+    ctx = (XACameraAdaptationCtx*)bCtx;
+
+    if ( !ctx )
+    {
+        return XA_RESULT_INTERNAL_ERROR;
+    }
+
+    XAAdaptationBase_PostInit( &(ctx->baseObj) );
+
+    ctx->baseObj.bin = gst_element_factory_make( "camerabin", "camera");
+    if ( !ctx->baseObj.bin )
+    {
+        DEBUG_ERR("Failed to create CameraBin");
+        return XA_RESULT_INTERNAL_ERROR;
+    }
+
+    /* Create Gst bus listener. */
+    ret = XAAdaptationBase_InitGstListener(&(ctx->baseObj));
+    if( ret!=XA_RESULT_SUCCESS )
+    {
+        DEBUG_ERR("Bus listener creation failed!!");
+        return ret;
+    }
+    /* Add Camera specific handler */
+    if(ctx->baseObj.bus)
+    {
+        ctx->baseObj.busCb = XACameraAdapt_GstBusCb;
+        gst_bus_add_signal_watch( ctx->baseObj.bus);
+        g_signal_connect(ctx->baseObj.bus, "message::autofocus-done", G_CALLBACK(ctx->baseObj.busCb), ctx );
+        g_signal_connect(ctx->baseObj.bus, "message::shake-risk", G_CALLBACK(ctx->baseObj.busCb), ctx );
+        g_signal_connect(ctx->baseObj.bus, "message::async-done", G_CALLBACK(ctx->baseObj.busCb), ctx );
+    }
+    else
+    {
+        DEBUG_ERR("Failed to create message bus");
+        return XA_RESULT_INTERNAL_ERROR;
+    }
+
+
+    /* SET UP CAMERABIN */
+
+    /* use test video source if set, camerabin default (v4l2src) otherwise */
+#ifdef XA_USE_TEST_PLUGINS
+    if(ctx->deviceID == XA_ADAPTID_VIDEOTESTSRC || ctx->deviceID == XA_DEFAULTDEVICEID_CAMERA )
+#else
+    if(ctx->deviceID == XA_ADAPTID_VIDEOTESTSRC )
+#endif
+    {
+        g_object_set( G_OBJECT(ctx->baseObj.bin), "videosrc", gst_element_factory_make("videotestsrc", "videotestsrc"), NULL );
+    }
+
+    /* set viewfinder element to be fake for the time of preroll.. if ghost pad added now,
+     * stupid camerabin makes circular linking...
+     */
+    g_object_set( G_OBJECT(ctx->baseObj.bin), "vfsink" ,gst_element_factory_make("fakesink", "fakevfsink"), NULL );
+
+    /* Setup camerabin to produce raw video */
+    g_object_set( G_OBJECT(ctx->baseObj.bin), "videomux",NULL, NULL );
+    g_object_set( G_OBJECT(ctx->baseObj.bin), "videoenc",NULL, NULL );
+    g_object_set( G_OBJECT(ctx->baseObj.bin), "mute", TRUE, NULL );
+    g_object_set( G_OBJECT(ctx->baseObj.bin), "async-handling", FALSE, NULL);
+	g_object_set( G_OBJECT(ctx->baseObj.bin), "mode",(gint)1, NULL);
+
+
+    /* drive camerabin to READY to create the elements inside bin */
+    gst_element_set_state( GST_ELEMENT(ctx->baseObj.bin), GST_STATE_READY);
+
+    if(ctx->deviceID == XA_ADAPTID_VIDEOTESTSRC)
+    {   /* set properties for videotestsrc */
+        GstElement *testsrc = gst_bin_get_by_name(GST_BIN(ctx->baseObj.bin), "videotestsrc");
+        g_object_set( G_OBJECT(testsrc),"is-live", TRUE, NULL);
+        g_object_set( G_OBJECT(testsrc),"do-timestamp", TRUE, NULL);
+        gst_object_unref(G_OBJECT(testsrc));
+    }
+
+    /* do some filter optimization */
+#ifdef XA_USE_TEST_PLUGINS
+    g_object_set( G_OBJECT(ctx->baseObj.bin), "filter-caps",
+                    gst_caps_new_simple("video/x-raw-yuv",
+                                        "format", GST_TYPE_FOURCC,GST_MAKE_FOURCC('I','4','2','0'),
+                                        "framerate",GST_TYPE_FRACTION_RANGE,0,1,30,1, NULL)
+                ,NULL );
+#else
+    g_object_set( G_OBJECT(ctx->baseObj.bin), "filter-caps",
+                    gst_caps_new_simple("video/x-raw-yuv",
+                                        "format", GST_TYPE_FOURCC,GST_MAKE_FOURCC('Y','U','Y','2'),
+                                        "framerate",GST_TYPE_FRACTION_RANGE,0,1,30,1, NULL)
+                ,NULL );
+#endif
+
+
+    /* now, unlink fake sink, create camera post processing pipeline and create ghost pad from it */
+    {
+        GstElement *fakesink = gst_bin_get_by_name(GST_BIN(ctx->baseObj.bin),"fakevfsink");
+        GstPad *fakepad = gst_element_get_static_pad(fakesink,"sink");
+        GstPad *linkedpad = gst_pad_get_peer(fakepad);
+        GstElement *linkedelement = gst_pad_get_parent_element(linkedpad);
+        GstElement * cameraPP = NULL;
+        GstElement * camfilter = NULL;
+        GstElement *tee = NULL;
+
+        /* Unlink fakesink */
+        gst_element_unlink(linkedelement,fakesink);
+        /* Create VideoPP pipeline for Camera object */
+        cameraPP = XAAdaptationBase_CreateVideoPP();
+        g_object_set( G_OBJECT(cameraPP),"name", "videopp_camera", NULL);
+        gst_bin_add( GST_BIN(ctx->baseObj.bin), cameraPP );
+        /*Link videoPP into camera bin last element */
+        gst_element_link( linkedelement, cameraPP );
+
+        /* Add extra filter for caps negotiable after post processing*/
+        camfilter = gst_element_factory_make("capsfilter", "camfilter");
+        gst_bin_add( GST_BIN(ctx->baseObj.bin), camfilter );
+        gst_element_link( cameraPP, camfilter );
+
+        /* Add tee element into camerabin */
+        tee = gst_element_factory_make( "tee", "CamTee");
+        gst_bin_add( GST_BIN(ctx->baseObj.bin), tee);
+        gst_element_link( camfilter, tee );
+
+		/* Unref */
+        gst_object_unref(linkedelement);
+        gst_object_unref(linkedpad);
+        gst_object_unref(fakepad);
+        gst_bin_remove(GST_BIN(ctx->baseObj.bin),fakesink);
+        gst_object_unparent(GST_OBJECT(fakesink));
+    }
+
+    if ( ret == XA_RESULT_SUCCESS )
+    {
+    	cameraRealized = XA_BOOLEAN_TRUE;
+    }
+
+    DEBUG_API("<-XACameraAdapt_PostInit");
+    return ret;
+}
+
+/*
+ * void XACameraAdapt_Destroy(XACameraAdaptationCtx* ctx)
+ * Destroys Camera Adaptation Context
+ * @param ctx - Camera Adaptation context to be destroyed
+ */
+void XACameraAdapt_Destroy(XAAdaptationBaseCtx* bCtx)
+{
+	XACameraAdaptationCtx* ctx = NULL;
+
+	DEBUG_API("->XACameraAdapt_Destroy");
+	if(bCtx == NULL || bCtx->ctxId != XACameraAdaptation )
+	{
+		DEBUG_ERR("Invalid parameter!!");
+		DEBUG_API("<-XACameraAdapt_Destroy");
+		return;
+	}
+	ctx = (XACameraAdaptationCtx*)bCtx;
+
+    XAAdaptationBase_Free(&(ctx->baseObj));
+
+    free(ctx);
+    ctx = NULL;
+    cameraCtx = NULL;
+    cameraRealized = XA_BOOLEAN_FALSE;
+    DEBUG_API("<-XACameraAdapt_Destroy");
+}
+