ArDrone SDK 1.8 added
[mardrone] / mardrone / ARDrone_SDK_Version_1_8_20110726 / ARDroneLib / VP_SDK / VP_Api / vp_api.c
diff --git a/mardrone/ARDrone_SDK_Version_1_8_20110726/ARDroneLib/VP_SDK/VP_Api/vp_api.c b/mardrone/ARDrone_SDK_Version_1_8_20110726/ARDroneLib/VP_SDK/VP_Api/vp_api.c
new file mode 100644 (file)
index 0000000..cd3ada5
--- /dev/null
@@ -0,0 +1,217 @@
+/**
+ *  @file     vp_api.c
+ *  @brief    VP Api. Pipeline definition
+ *  @author   Sylvain Gaeremynck <sylvain.gaeremynck@parrot.fr>
+ *  @author   Aurelien Morelle <aurelien.morelle@parrot.fr>
+ *  @author   Thomas Landais <thomas.landais@parrot.fr>
+ *  @author   Julien Floret <julien.floret.ext@parrot.com>
+ *  @version  2.0
+ *  @date     first release 16/03/2007
+ *  @date     modification  24/05/2007
+ */
+
+///////////////////////////////////////////////
+// INCLUDES
+
+#include <VP_Api/vp_api.h>
+#include <VP_Api/vp_api_stage.h>
+#include <VP_Api/vp_api_supervisor.h>
+#include <VP_Api/vp_api_error.h>
+#include <VP_Os/vp_os_malloc.h>
+#include <VP_Os/vp_os_assert.h>
+#include <VP_Os/vp_os_print.h>
+
+///////////////////////////////////////////////
+// STATICS
+
+static C_RESULT
+vp_api_iteration(vp_api_io_pipeline_t *pipeline, vp_api_io_stage_t* previousStage, vp_api_io_stage_t* stage);
+
+
+///////////////////////////////////////////////
+// CODE
+
+C_RESULT
+vp_api_open(vp_api_io_pipeline_t *pipeline, PIPELINE_HANDLE *handle)
+{
+  C_RESULT res;
+
+  vp_api_io_stage_t *stage;
+  uint32_t i;
+
+  res = C_OK;
+
+  VP_OS_ASSERT(pipeline);
+  VP_OS_ASSERT(pipeline->nb_stages > 0 && pipeline->nb_stages <= VP_API_MAX_NUM_STAGES);
+  VP_OS_ASSERT(pipeline->stages);
+
+  pipeline->nb_still_running = 0;
+
+  for(i = 0 ; i < pipeline->nb_stages && VP_SUCCEEDED(res); i++)
+  {
+    stage = &pipeline->stages[i];
+
+    VP_OS_ASSERT(stage->funcs.open);
+    VP_OS_ASSERT(stage->funcs.transform);
+    VP_OS_ASSERT(stage->funcs.close);
+
+       vp_os_mutex_init(&stage->data.lock);
+       vp_os_mutex_lock(&stage->data.lock);
+
+       res = stage->funcs.open(stage->cfg);
+
+       if( VP_SUCCEEDED(res) )
+
+    {
+      // Set all data fields to 0
+        stage->data.numBuffers=0;
+        stage->data.buffers=NULL;
+        stage->data.indexBuffer=0;
+
+        stage->data.size=0;
+        stage->data.lineSize=0;
+
+        stage->data.status = VP_API_STATUS_INIT;
+        /* stage->data.lock = Be_careful_not_to_erase_it;  */
+
+        //vp_os_memset(&stage->data, 0, sizeof(vp_api_io_data_t));
+
+    }
+               else
+               {
+                       // To avoid problems on vp_api_close
+                       pipeline->nb_stages=i+1;
+               }
+  }
+
+  pipeline->fifo.pbase   = (char *) vp_os_malloc(VP_API_PIPELINE_FIFO_SIZE);
+  pipeline->fifo.pget    = pipeline->fifo.pbase;
+  pipeline->fifo.ppost   = pipeline->fifo.pbase;
+  pipeline->fifo.nb_waiting = 0;
+  vp_os_memset(pipeline->fifo.pbase, 0, VP_API_PIPELINE_FIFO_SIZE);
+  vp_os_mutex_init(&pipeline->fifo.mutex);
+
+  if( VP_SUCCEEDED(res) )
+  {
+    res = vp_api_add_pipeline(pipeline, handle);
+  }
+
+  return res;
+}
+
+
+C_RESULT
+vp_api_run(vp_api_io_pipeline_t *pipeline, vp_api_io_data_t *out_data)
+{
+  vp_api_io_stage_t* previousStage = NULL;
+  vp_api_io_stage_t* currentStage = NULL;
+  C_RESULT res = VP_SUCCESS;
+  uint32_t i=0;
+
+  if(pipeline->fifo.nb_waiting > 0)
+    if(VP_FAILED(vp_api_handle_messages(pipeline)))
+      res = VP_FAILURE;
+
+  if(pipeline->nb_still_running != 0)
+  {
+    for(i = pipeline->nb_stages-1 ; pipeline->stages[i].data.status != VP_API_STATUS_STILL_RUNNING ; i--)
+    {
+      VP_OS_ASSERT(i >= 0);
+    }
+    pipeline->nb_still_running--;
+    if(i > 0)
+      currentStage = &pipeline->stages[i-1];
+  }
+
+  for(; i < pipeline->nb_stages ; i++)
+  {
+    previousStage = currentStage;
+    currentStage = &pipeline->stages[i];
+
+    RTMON_UVAL(SDK_STAGE_INDEX_UVAL, i);
+    if(VP_SUCCEEDED(res) && VP_FAILED(vp_api_iteration(pipeline, previousStage, currentStage)))
+    {
+      res = VP_FAILURE;
+    }
+
+    //do not execute next stages if no data is given
+    if(pipeline->stages[i].data.size == 0)
+    {
+      break;
+    }
+  }
+
+  if(currentStage!=NULL)
+         *out_data = currentStage->data;
+  else
+         res = VP_FAILURE;
+
+  return res;
+}
+
+C_RESULT
+vp_api_flush(vp_api_io_pipeline_t *pipeline)
+{
+  vp_api_io_data_t data;
+  C_RESULT res = VP_SUCCESS;
+
+  while(pipeline->nb_still_running != 0)
+    if(VP_FAILED(vp_api_run(pipeline, &data)))
+      res = VP_FAILURE;
+
+  return res;
+}
+
+C_RESULT
+vp_api_close(vp_api_io_pipeline_t *pipeline, PIPELINE_HANDLE *handle)
+{
+  vp_api_io_stage_t *stage;
+  C_RESULT res = VP_SUCCESS;
+  uint32_t i;
+
+  VP_OS_ASSERT(pipeline->nb_stages > 0 && pipeline->nb_stages <= VP_API_MAX_NUM_STAGES);
+
+  res = vp_api_remove_pipeline(pipeline, handle);
+
+#ifdef DEBUG_MODE
+  if( pipeline->fifo.pbase != NULL )
+#endif // DEBUG_MODE
+    vp_os_free(pipeline->fifo.pbase);
+
+  for(i = 0 ; i < pipeline->nb_stages ; i++)
+  {
+    stage = &pipeline->stages[i];
+    if(VP_FAILED(stage->funcs.close(stage->cfg)))
+      res = VP_FAILURE;
+
+    vp_os_mutex_unlock(&stage->data.lock);
+    vp_os_mutex_destroy(&stage->data.lock);
+  }
+
+  return res;
+}
+
+static C_RESULT
+vp_api_iteration(vp_api_io_pipeline_t *pipeline, vp_api_io_stage_t* previousStage, vp_api_io_stage_t* stage)
+{
+  C_RESULT res = VP_SUCCESS;
+  vp_api_io_data_t *previousData = NULL;
+
+  if(previousStage)
+  {
+    previousData = &previousStage->data;
+  }
+
+  vp_os_mutex_unlock(&stage->data.lock);
+  RTMON_USTART(SDK_STAGE_TRANSFORM_UEVENT);
+  res = stage->funcs.transform(stage->cfg, previousData, &stage->data);
+  RTMON_USTOP(SDK_STAGE_TRANSFORM_UEVENT);
+
+  if(stage->data.status == VP_API_STATUS_STILL_RUNNING)
+  {
+    pipeline->nb_still_running++;
+  }
+  vp_os_mutex_lock(&stage->data.lock);
+
+  return res;
+}