libandroidplugin added
[mardrone] / mardrone / ARDrone_SDK_Version_1_8_20110726 / ARDroneLib / VP_SDK / VP_Api / vp_api.c
1 /**
2  *  @file     vp_api.c
3  *  @brief    VP Api. Pipeline definition
4  *  @author   Sylvain Gaeremynck <sylvain.gaeremynck@parrot.fr>
5  *  @author   Aurelien Morelle <aurelien.morelle@parrot.fr>
6  *  @author   Thomas Landais <thomas.landais@parrot.fr>
7  *  @author   Julien Floret <julien.floret.ext@parrot.com>
8  *  @version  2.0
9  *  @date     first release 16/03/2007
10  *  @date     modification  24/05/2007
11  */
12
13 ///////////////////////////////////////////////
14 // INCLUDES
15
16 #include <VP_Api/vp_api.h>
17 #include <VP_Api/vp_api_stage.h>
18 #include <VP_Api/vp_api_supervisor.h>
19 #include <VP_Api/vp_api_error.h>
20 #include <VP_Os/vp_os_malloc.h>
21 #include <VP_Os/vp_os_assert.h>
22 #include <VP_Os/vp_os_print.h>
23
24 ///////////////////////////////////////////////
25 // STATICS
26
27 static C_RESULT
28 vp_api_iteration(vp_api_io_pipeline_t *pipeline, vp_api_io_stage_t* previousStage, vp_api_io_stage_t* stage);
29
30
31 ///////////////////////////////////////////////
32 // CODE
33
34 C_RESULT
35 vp_api_open(vp_api_io_pipeline_t *pipeline, PIPELINE_HANDLE *handle)
36 {
37   C_RESULT res;
38
39   vp_api_io_stage_t *stage;
40   uint32_t i;
41
42   res = C_OK;
43
44   VP_OS_ASSERT(pipeline);
45   VP_OS_ASSERT(pipeline->nb_stages > 0 && pipeline->nb_stages <= VP_API_MAX_NUM_STAGES);
46   VP_OS_ASSERT(pipeline->stages);
47
48   pipeline->nb_still_running = 0;
49
50   for(i = 0 ; i < pipeline->nb_stages && VP_SUCCEEDED(res); i++)
51   {
52     stage = &pipeline->stages[i];
53
54     VP_OS_ASSERT(stage->funcs.open);
55     VP_OS_ASSERT(stage->funcs.transform);
56     VP_OS_ASSERT(stage->funcs.close);
57
58         vp_os_mutex_init(&stage->data.lock);
59         vp_os_mutex_lock(&stage->data.lock);
60
61         res = stage->funcs.open(stage->cfg);
62
63         if( VP_SUCCEEDED(res) )
64
65     {
66       // Set all data fields to 0
67         stage->data.numBuffers=0;
68         stage->data.buffers=NULL;
69         stage->data.indexBuffer=0;
70
71         stage->data.size=0;
72         stage->data.lineSize=0;
73
74         stage->data.status = VP_API_STATUS_INIT;
75         /* stage->data.lock = Be_careful_not_to_erase_it;  */
76
77         //vp_os_memset(&stage->data, 0, sizeof(vp_api_io_data_t));
78
79     }
80                 else
81                 {
82                         // To avoid problems on vp_api_close
83                         pipeline->nb_stages=i+1;
84                 }
85   }
86
87   pipeline->fifo.pbase   = (char *) vp_os_malloc(VP_API_PIPELINE_FIFO_SIZE);
88   pipeline->fifo.pget    = pipeline->fifo.pbase;
89   pipeline->fifo.ppost   = pipeline->fifo.pbase;
90   pipeline->fifo.nb_waiting = 0;
91   vp_os_memset(pipeline->fifo.pbase, 0, VP_API_PIPELINE_FIFO_SIZE);
92   vp_os_mutex_init(&pipeline->fifo.mutex);
93
94   if( VP_SUCCEEDED(res) )
95   {
96     res = vp_api_add_pipeline(pipeline, handle);
97   }
98
99   return res;
100 }
101
102
103 C_RESULT
104 vp_api_run(vp_api_io_pipeline_t *pipeline, vp_api_io_data_t *out_data)
105 {
106   vp_api_io_stage_t* previousStage = NULL;
107   vp_api_io_stage_t* currentStage = NULL;
108   C_RESULT res = VP_SUCCESS;
109   uint32_t i=0;
110
111   if(pipeline->fifo.nb_waiting > 0)
112     if(VP_FAILED(vp_api_handle_messages(pipeline)))
113       res = VP_FAILURE;
114
115   if(pipeline->nb_still_running != 0)
116   {
117     for(i = pipeline->nb_stages-1 ; pipeline->stages[i].data.status != VP_API_STATUS_STILL_RUNNING ; i--)
118     {
119       VP_OS_ASSERT(i >= 0);
120     }
121     pipeline->nb_still_running--;
122     if(i > 0)
123       currentStage = &pipeline->stages[i-1];
124   }
125
126   for(; i < pipeline->nb_stages ; i++)
127   {
128     previousStage = currentStage;
129     currentStage = &pipeline->stages[i];
130
131     RTMON_UVAL(SDK_STAGE_INDEX_UVAL, i);
132     if(VP_SUCCEEDED(res) && VP_FAILED(vp_api_iteration(pipeline, previousStage, currentStage)))
133     {
134       res = VP_FAILURE;
135     }
136
137     //do not execute next stages if no data is given
138     if(pipeline->stages[i].data.size == 0)
139     {
140       break;
141     }
142   }
143
144   if(currentStage!=NULL)
145           *out_data = currentStage->data;
146   else
147           res = VP_FAILURE;
148
149   return res;
150 }
151
152 C_RESULT
153 vp_api_flush(vp_api_io_pipeline_t *pipeline)
154 {
155   vp_api_io_data_t data;
156   C_RESULT res = VP_SUCCESS;
157
158   while(pipeline->nb_still_running != 0)
159     if(VP_FAILED(vp_api_run(pipeline, &data)))
160       res = VP_FAILURE;
161
162   return res;
163 }
164
165 C_RESULT
166 vp_api_close(vp_api_io_pipeline_t *pipeline, PIPELINE_HANDLE *handle)
167 {
168   vp_api_io_stage_t *stage;
169   C_RESULT res = VP_SUCCESS;
170   uint32_t i;
171
172   VP_OS_ASSERT(pipeline->nb_stages > 0 && pipeline->nb_stages <= VP_API_MAX_NUM_STAGES);
173
174   res = vp_api_remove_pipeline(pipeline, handle);
175
176 #ifdef DEBUG_MODE
177   if( pipeline->fifo.pbase != NULL )
178 #endif // DEBUG_MODE
179     vp_os_free(pipeline->fifo.pbase);
180
181   for(i = 0 ; i < pipeline->nb_stages ; i++)
182   {
183     stage = &pipeline->stages[i];
184     if(VP_FAILED(stage->funcs.close(stage->cfg)))
185       res = VP_FAILURE;
186
187     vp_os_mutex_unlock(&stage->data.lock);
188     vp_os_mutex_destroy(&stage->data.lock);
189   }
190
191   return res;
192 }
193
194 static C_RESULT
195 vp_api_iteration(vp_api_io_pipeline_t *pipeline, vp_api_io_stage_t* previousStage, vp_api_io_stage_t* stage)
196 {
197   C_RESULT res = VP_SUCCESS;
198   vp_api_io_data_t *previousData = NULL;
199
200   if(previousStage)
201   {
202     previousData = &previousStage->data;
203   }
204
205   vp_os_mutex_unlock(&stage->data.lock);
206   RTMON_USTART(SDK_STAGE_TRANSFORM_UEVENT);
207   res = stage->funcs.transform(stage->cfg, previousData, &stage->data);
208   RTMON_USTOP(SDK_STAGE_TRANSFORM_UEVENT);
209
210   if(stage->data.status == VP_API_STATUS_STILL_RUNNING)
211   {
212     pipeline->nb_still_running++;
213   }
214   vp_os_mutex_lock(&stage->data.lock);
215
216   return res;
217 }