33 * Sets record state to GStreamer. |
33 * Sets record state to GStreamer. |
34 * @param XAAdaptationGstCtx *ctx - Adaptation context |
34 * @param XAAdaptationGstCtx *ctx - Adaptation context |
35 * XAuint32 state - Record state to be set |
35 * XAuint32 state - Record state to be set |
36 * @return XAresult ret - Success value |
36 * @return XAresult ret - Success value |
37 */ |
37 */ |
38 XAresult XARecordItfAdapt_SetRecordState(XAAdaptationGstCtx *bCtx, XAuint32 state) |
38 XAresult XARecordItfAdapt_SetRecordState(XAAdaptationGstCtx *bCtx, |
39 { |
39 XAuint32 state) |
|
40 { |
40 XAresult ret = XA_RESULT_SUCCESS; |
41 XAresult ret = XA_RESULT_SUCCESS; |
41 XAboolean closeSink = XA_BOOLEAN_FALSE; |
42 XAboolean closeSink = XA_BOOLEAN_FALSE; |
42 XAboolean requestStateChange = XA_BOOLEAN_FALSE; |
43 XAboolean requestStateChange = XA_BOOLEAN_FALSE; |
43 GstStateChangeReturn gstRet = GST_STATE_CHANGE_SUCCESS; |
44 GstStateChangeReturn gstRet = GST_STATE_CHANGE_SUCCESS; |
44 XAMediaRecorderAdaptationCtx* mCtx = NULL; |
45 XAMediaRecorderAdaptationCtx* mCtx = NULL; |
45 XAboolean recording = XA_BOOLEAN_FALSE; |
46 XAboolean recording = XA_BOOLEAN_FALSE; |
46 DEBUG_API_A1("->XARecordItfAdapt_SetRecordState %s",RECORDSTATENAME(state)); |
47 DEBUG_API_A1("->XARecordItfAdapt_SetRecordState %s",RECORDSTATENAME(state)); |
47 if(!bCtx || bCtx->baseObj.ctxId != XAMediaRecorderAdaptation) |
48 if (!bCtx || bCtx->baseObj.ctxId != XAMediaRecorderAdaptation) |
48 { |
49 { |
49 DEBUG_ERR("XA_RESULT_PARAMETER_INVALID"); |
50 DEBUG_ERR("XA_RESULT_PARAMETER_INVALID"); |
50 DEBUG_API("<-XARecordItfAdapt_SetRecordState"); |
51 DEBUG_API("<-XARecordItfAdapt_SetRecordState"); |
51 return XA_RESULT_PARAMETER_INVALID; |
52 return XA_RESULT_PARAMETER_INVALID; |
52 } |
53 } |
53 |
54 |
54 mCtx = (XAMediaRecorderAdaptationCtx*) bCtx; |
55 mCtx = (XAMediaRecorderAdaptationCtx*) bCtx; |
55 |
56 |
56 mCtx->isRecord = XA_BOOLEAN_TRUE; |
57 mCtx->isRecord = XA_BOOLEAN_TRUE; |
57 |
58 |
58 switch ( state ) |
59 switch (state) |
59 { |
60 { |
60 case XA_RECORDSTATE_STOPPED: |
61 case XA_RECORDSTATE_STOPPED: |
61 { |
62 { |
62 // Audio sourse should be stopped |
63 // Audio sourse should be stopped |
63 if ( mCtx->audiosource ) |
64 if (mCtx->audiosource) |
64 { |
65 { |
65 if ( gst_element_send_event (mCtx->audiosource, gst_event_new_eos ()) == TRUE ) |
66 if (gst_element_send_event(mCtx->audiosource, |
66 { |
67 gst_event_new_eos()) == TRUE) |
67 DEBUG_INFO ("posted eos"); |
68 { |
68 } |
69 DEBUG_INFO ("posted eos"); |
69 else |
70 } |
70 { |
71 else |
71 DEBUG_ERR("FAIL : post eos"); |
72 { |
72 } |
73 DEBUG_ERR("FAIL : post eos"); |
73 } |
74 } |
74 |
75 } |
75 if ( cameraCtx && cameraRealized && mCtx->isobjvsrc && mCtx->videosource ) |
76 |
76 { |
77 if (cameraCtx && cameraRealized && mCtx->isobjvsrc |
77 cameraCtx->recording = XA_BOOLEAN_FALSE; |
78 && mCtx->videosource) |
78 |
79 { |
79 if(!cameraCtx->playing && !cameraCtx->snapshotting) |
80 cameraCtx->recording = XA_BOOLEAN_FALSE; |
80 { |
81 |
81 /* Neither view finder or recorder is running -> pause camera */ |
82 if (!cameraCtx->playing && !cameraCtx->snapshotting) |
82 if ( GST_STATE( GST_ELEMENT(mCtx->videosource)) == GST_STATE_PLAYING ) |
83 { |
83 { |
84 /* Neither view finder or recorder is running -> pause camera */ |
84 GstStateChangeReturn gret; |
85 if (GST_STATE( GST_ELEMENT(mCtx->videosource)) |
85 DEBUG_INFO("Stop camera source"); |
86 == GST_STATE_PLAYING) |
86 gret = gst_element_set_state( GST_ELEMENT(mCtx->videosource), GST_STATE_PAUSED ); |
87 { |
87 if(gret == GST_STATE_CHANGE_SUCCESS) |
88 GstStateChangeReturn gret; |
88 gret = gst_element_get_state( GST_ELEMENT(mCtx->videosource), NULL,NULL, XA_ADAPT_ASYNC_TIMEOUT_SHORT_NSEC ); |
89 DEBUG_INFO("Stop camera source"); |
89 } |
90 gret = gst_element_set_state( |
90 } |
91 GST_ELEMENT(mCtx->videosource), |
91 } |
92 GST_STATE_PAUSED); |
|
93 if (gret == GST_STATE_CHANGE_SUCCESS) |
|
94 gret = gst_element_get_state( |
|
95 GST_ELEMENT(mCtx->videosource), NULL, |
|
96 NULL, XA_ADAPT_ASYNC_TIMEOUT_SHORT_NSEC); |
|
97 } |
|
98 } |
|
99 } |
92 |
100 |
93 bCtx->binWantedState = GST_STATE_PAUSED; |
101 bCtx->binWantedState = GST_STATE_PAUSED; |
94 closeSink = XA_BOOLEAN_TRUE; |
102 closeSink = XA_BOOLEAN_TRUE; |
95 if(mCtx->runpositiontimer > 0) |
103 if (mCtx->runpositiontimer > 0) |
96 { |
104 { |
97 g_source_remove(mCtx->runpositiontimer); |
105 g_source_remove(mCtx->runpositiontimer); |
98 mCtx->runpositiontimer=0; |
106 mCtx->runpositiontimer = 0; |
99 } |
107 } |
100 |
108 |
101 if ( mCtx->recThrCtx.bufInsufficientSem ) |
109 if (mCtx->recThrCtx.bufInsufficientSem) |
102 { |
110 { |
103 DEBUG_INFO("No buffer-insufficient received, posting record thr semaphore."); |
111 DEBUG_INFO("No buffer-insufficient received, posting record thr semaphore."); |
104 if ( XAImpl_PostSemaphore( mCtx->recThrCtx.bufInsufficientSem ) != XA_RESULT_SUCCESS) |
112 if (XAImpl_PostSemaphore(mCtx->recThrCtx.bufInsufficientSem) |
105 { |
113 != XA_RESULT_SUCCESS) |
|
114 { |
106 DEBUG_ERR("Posting buffer-insufficient semaphore FAILED!"); |
115 DEBUG_ERR("Posting buffer-insufficient semaphore FAILED!"); |
107 } |
116 } |
108 } |
117 } |
109 |
118 |
110 break; |
119 break; |
111 } |
120 } |
112 case XA_RECORDSTATE_PAUSED: |
121 case XA_RECORDSTATE_PAUSED: |
113 { |
122 { |
114 if ( cameraCtx && cameraRealized && mCtx->isobjvsrc && mCtx->videosource ) |
123 if (cameraCtx && cameraRealized && mCtx->isobjvsrc |
115 { |
124 && mCtx->videosource) |
116 cameraCtx->recording = XA_BOOLEAN_FALSE; |
125 { |
117 if(!cameraCtx->playing && !cameraCtx->snapshotting) |
126 cameraCtx->recording = XA_BOOLEAN_FALSE; |
118 { |
127 if (!cameraCtx->playing && !cameraCtx->snapshotting) |
119 /* Neither view finder or recorder is running -> pause camera */ |
128 { |
120 if ( GST_STATE( GST_ELEMENT(mCtx->videosource)) == GST_STATE_PLAYING ) |
129 /* Neither view finder or recorder is running -> pause camera */ |
121 { |
130 if (GST_STATE( GST_ELEMENT(mCtx->videosource)) |
122 GstStateChangeReturn gret; |
131 == GST_STATE_PLAYING) |
123 DEBUG_INFO("Stop camera source"); |
132 { |
124 gret = gst_element_set_state( GST_ELEMENT(mCtx->videosource), GST_STATE_PAUSED ); |
133 GstStateChangeReturn gret; |
125 if(gret == GST_STATE_CHANGE_SUCCESS) |
134 DEBUG_INFO("Stop camera source"); |
126 gret = gst_element_get_state( GST_ELEMENT(mCtx->videosource), NULL,NULL, XA_ADAPT_ASYNC_TIMEOUT_SHORT_NSEC ); |
135 gret = gst_element_set_state( |
127 } |
136 GST_ELEMENT(mCtx->videosource), |
128 } |
137 GST_STATE_PAUSED); |
129 } |
138 if (gret == GST_STATE_CHANGE_SUCCESS) |
130 |
139 gret = gst_element_get_state( |
131 if(mCtx->xaRecordState==XA_RECORDSTATE_STOPPED && mCtx->encodingchanged) |
140 GST_ELEMENT(mCtx->videosource), NULL, |
132 { |
141 NULL, XA_ADAPT_ASYNC_TIMEOUT_SHORT_NSEC); |
133 XAMediaRecorderAdapt_ChangeEncoders( mCtx ); |
142 } |
|
143 } |
|
144 } |
|
145 |
|
146 if (mCtx->xaRecordState == XA_RECORDSTATE_STOPPED |
|
147 && mCtx->encodingchanged) |
|
148 { |
|
149 XAMediaRecorderAdapt_ChangeEncoders(mCtx); |
134 mCtx->encodingchanged = XA_BOOLEAN_FALSE; |
150 mCtx->encodingchanged = XA_BOOLEAN_FALSE; |
135 } |
151 } |
136 bCtx->binWantedState = GST_STATE_PAUSED; |
152 bCtx->binWantedState = GST_STATE_PAUSED; |
137 if(mCtx->runpositiontimer > 0) |
153 if (mCtx->runpositiontimer > 0) |
138 { |
154 { |
139 g_source_remove(mCtx->runpositiontimer); |
155 g_source_remove(mCtx->runpositiontimer); |
140 mCtx->runpositiontimer=0; |
156 mCtx->runpositiontimer = 0; |
141 } |
157 } |
142 break; |
158 break; |
143 } |
159 } |
144 case XA_RECORDSTATE_RECORDING: |
160 case XA_RECORDSTATE_RECORDING: |
145 { |
161 { |
146 if ( cameraCtx && mCtx->isobjvsrc ) |
162 if (cameraCtx && mCtx->isobjvsrc) |
147 { |
163 { |
148 cameraCtx->recording = XA_BOOLEAN_TRUE; |
164 cameraCtx->recording = XA_BOOLEAN_TRUE; |
149 } |
165 } |
150 |
166 |
151 if(mCtx->xaRecordState==XA_RECORDSTATE_STOPPED && (mCtx->encodingchanged)) |
167 if (mCtx->xaRecordState == XA_RECORDSTATE_STOPPED |
152 { |
168 && (mCtx->encodingchanged)) |
153 XAMediaRecorderAdapt_ChangeEncoders( mCtx ); |
169 { |
|
170 XAMediaRecorderAdapt_ChangeEncoders(mCtx); |
154 mCtx->encodingchanged = XA_BOOLEAN_FALSE; |
171 mCtx->encodingchanged = XA_BOOLEAN_FALSE; |
155 } |
172 } |
156 |
173 |
157 if ( mCtx->recThrCtx.bufInsufficientSem ) |
174 if (mCtx->recThrCtx.bufInsufficientSem) |
158 { |
175 { |
159 /* Recording to address and recording thread semaphora is created */ |
176 /* Recording to address and recording thread semaphora is created */ |
160 if(! XAImpl_StartThread(&(mCtx->recordingEventThr),NULL, &XAMediaRecorderAdapt_RecordEventThr, (void*)mCtx )) |
177 if (!XAImpl_StartThread(&(mCtx->recordingEventThr), NULL, |
161 { |
178 &XAMediaRecorderAdapt_RecordEventThr, (void*) mCtx)) |
162 DEBUG_ERR("Start thread Failed"); |
179 { |
163 return XA_RESULT_INTERNAL_ERROR; |
180 DEBUG_ERR("Start thread Failed"); |
164 } |
181 return XA_RESULT_INTERNAL_ERROR; |
165 } |
182 } |
|
183 } |
166 |
184 |
167 bCtx->binWantedState = GST_STATE_PLAYING; |
185 bCtx->binWantedState = GST_STATE_PLAYING; |
168 recording = XA_BOOLEAN_TRUE; |
186 recording = XA_BOOLEAN_TRUE; |
169 break; |
187 break; |
170 } |
188 } |
171 default: |
189 default: |
172 DEBUG_ERR("Unhandled state"); |
190 DEBUG_ERR("Unhandled state") |
|
191 ; |
173 ret = XA_RESULT_PARAMETER_INVALID; |
192 ret = XA_RESULT_PARAMETER_INVALID; |
174 break; |
193 break; |
175 } |
194 } |
176 |
195 |
177 if( ret == XA_RESULT_SUCCESS ) |
196 if (ret == XA_RESULT_SUCCESS) |
178 { |
197 { |
179 mCtx->xaRecordState = state; |
198 mCtx->xaRecordState = state; |
180 } |
199 } |
181 |
200 |
182 /* launch Gstreamer state change only if necessary */ |
201 /* launch Gstreamer state change only if necessary */ |
183 if( GST_STATE_TARGET(bCtx->bin) == bCtx->binWantedState ) |
202 if (GST_STATE_TARGET(bCtx->bin) == bCtx->binWantedState) |
184 { |
203 { |
185 DEBUG_INFO("Gst already transitioning to wanted state!!"); |
204 DEBUG_INFO("Gst already transitioning to wanted state!!"); |
186 requestStateChange = XA_BOOLEAN_FALSE; |
205 requestStateChange = XA_BOOLEAN_FALSE; |
187 } |
206 } |
188 else |
207 else |
189 { |
208 { |
190 if( (GST_STATE(bCtx->bin) == bCtx->binWantedState) && |
209 if ((GST_STATE(bCtx->bin) == bCtx->binWantedState) |
191 (GST_STATE_PENDING(bCtx->bin) == GST_STATE_VOID_PENDING) ) |
210 && (GST_STATE_PENDING(bCtx->bin) == GST_STATE_VOID_PENDING)) |
192 { |
211 { |
193 DEBUG_ERR_A3("WARNING : gststate %d == wanted %d != gsttarget %d and no statechange pending", |
212 DEBUG_ERR_A3("WARNING : gststate %d == wanted %d != gsttarget %d and no statechange pending", |
194 GST_STATE(bCtx->bin), bCtx->binWantedState, GST_STATE_TARGET(bCtx->bin)); |
213 GST_STATE(bCtx->bin), bCtx->binWantedState, GST_STATE_TARGET(bCtx->bin)); |
195 } |
214 } |
196 requestStateChange = XA_BOOLEAN_TRUE; |
215 requestStateChange = XA_BOOLEAN_TRUE; |
197 } |
216 } |
198 |
217 |
199 if( requestStateChange ) |
218 if (requestStateChange) |
200 { |
219 { |
201 XAAdaptationGst_PrepareAsyncWait(bCtx); |
220 XAAdaptationGst_PrepareAsyncWait(bCtx); |
202 DEBUG_INFO_A1("Sending change state request to state %d", bCtx->binWantedState); |
221 DEBUG_INFO_A1("Sending change state request to state %d", bCtx->binWantedState); |
203 gstRet = gst_element_set_state( GST_ELEMENT(bCtx->bin), bCtx->binWantedState); |
222 gstRet = gst_element_set_state(GST_ELEMENT(bCtx->bin), |
204 switch ( gstRet ) |
223 bCtx->binWantedState); |
205 { |
224 switch (gstRet) |
|
225 { |
206 case GST_STATE_CHANGE_FAILURE: |
226 case GST_STATE_CHANGE_FAILURE: |
207 DEBUG_ERR_A1("FAILED to change state (target %d)",bCtx->binWantedState); |
227 DEBUG_ERR_A1("FAILED to change state (target %d)",bCtx->binWantedState) |
|
228 ; |
208 bCtx->binWantedState = GST_STATE(bCtx->bin); |
229 bCtx->binWantedState = GST_STATE(bCtx->bin); |
209 ret = XA_RESULT_INTERNAL_ERROR; |
230 ret = XA_RESULT_INTERNAL_ERROR; |
210 break; |
231 break; |
211 case GST_STATE_CHANGE_ASYNC: |
232 case GST_STATE_CHANGE_ASYNC: |
212 DEBUG_INFO_A1("Change state will happen asyncronously (target %d)",bCtx->binWantedState); |
233 DEBUG_INFO_A1("Change state will happen asyncronously (target %d)",bCtx->binWantedState); |
213 XAAdaptationGst_StartAsyncWait(bCtx); |
234 XAAdaptationGst_StartAsyncWait(bCtx); |
214 ret = XA_RESULT_SUCCESS; |
235 ret = XA_RESULT_SUCCESS; |
215 break; |
236 break; |
216 case GST_STATE_CHANGE_NO_PREROLL: |
237 case GST_STATE_CHANGE_NO_PREROLL: |
217 DEBUG_INFO("GST_STATE_CHANGE_NO_PREROLL"); |
238 DEBUG_INFO("GST_STATE_CHANGE_NO_PREROLL") |
|
239 ; |
218 /* deliberate fall-through */ |
240 /* deliberate fall-through */ |
219 case GST_STATE_CHANGE_SUCCESS: |
241 case GST_STATE_CHANGE_SUCCESS: |
220 DEBUG_INFO_A1("Successfully changed state (target %d)",bCtx->binWantedState); |
242 DEBUG_INFO_A1("Successfully changed state (target %d)",bCtx->binWantedState) |
|
243 ; |
221 ret = XA_RESULT_SUCCESS; |
244 ret = XA_RESULT_SUCCESS; |
222 break; |
245 break; |
223 default: |
246 default: |
224 DEBUG_ERR_A1("Unhandled error (%d)",gstRet); |
247 DEBUG_ERR_A1("Unhandled error (%d)",gstRet) |
|
248 ; |
225 ret = XA_RESULT_UNKNOWN_ERROR; |
249 ret = XA_RESULT_UNKNOWN_ERROR; |
226 break; |
250 break; |
227 } |
251 } |
228 bCtx->waitingasyncop = XA_BOOLEAN_FALSE; |
252 bCtx->waitingasyncop = XA_BOOLEAN_FALSE; |
|
253 } |
|
254 if ((GST_STATE(bCtx->bin) > GST_STATE_READY) && closeSink) |
|
255 { /* close the sink*/ |
|
256 gst_element_send_event(bCtx->bin, gst_event_new_flush_start()); |
|
257 gst_element_send_event(bCtx->bin, gst_event_new_flush_stop()); |
|
258 } |
|
259 |
|
260 if (recording && mCtx->isobjvsrc && mCtx->videosource) |
|
261 { |
|
262 GstPad *pad = gst_element_get_static_pad( |
|
263 GST_ELEMENT(mCtx->videosource), "MRObjSrc"); |
|
264 if (pad && gst_pad_is_linked(pad)) |
|
265 { |
|
266 DEBUG_INFO_A2("unblock element:%s pad:%s", |
|
267 gst_element_get_name(mCtx->videosource), |
|
268 gst_pad_get_name(pad)); |
|
269 gst_pad_set_blocked_async(pad, FALSE, XAAdaptationGst_PadBlockCb, |
|
270 NULL); |
|
271 } |
|
272 |
|
273 if (GST_STATE( GST_ELEMENT(mCtx->videosource)) != GST_STATE_PLAYING) |
|
274 { |
|
275 GstStateChangeReturn gret = GST_STATE_CHANGE_SUCCESS; |
|
276 DEBUG_INFO("Start camera source"); |
|
277 gret = gst_element_set_state(GST_ELEMENT(mCtx->videosource), |
|
278 GST_STATE_PLAYING); |
|
279 if (gret == GST_STATE_CHANGE_SUCCESS) |
|
280 gret = gst_element_get_state(GST_ELEMENT(mCtx->videosource), |
|
281 NULL, NULL, XA_ADAPT_ASYNC_TIMEOUT_SHORT_NSEC); |
|
282 } |
|
283 }DEBUG_API("<-XARecordItfAdapt_SetRecordState"); |
|
284 return ret; |
229 } |
285 } |
230 if( (GST_STATE(bCtx->bin) > GST_STATE_READY) && closeSink ) |
|
231 { /* close the sink*/ |
|
232 gst_element_send_event(bCtx->bin,gst_event_new_flush_start()); |
|
233 gst_element_send_event(bCtx->bin,gst_event_new_flush_stop()); |
|
234 } |
|
235 |
|
236 if ( recording && mCtx->isobjvsrc && mCtx->videosource ) |
|
237 { |
|
238 GstPad *pad = gst_element_get_static_pad( GST_ELEMENT(mCtx->videosource), "MRObjSrc"); |
|
239 if( pad && gst_pad_is_linked(pad) ) |
|
240 { |
|
241 DEBUG_INFO_A2("unblock element:%s pad:%s", |
|
242 gst_element_get_name(mCtx->videosource), |
|
243 gst_pad_get_name(pad)); |
|
244 gst_pad_set_blocked_async(pad, FALSE, XAAdaptationGst_PadBlockCb, NULL); |
|
245 } |
|
246 |
|
247 if ( GST_STATE( GST_ELEMENT(mCtx->videosource)) != GST_STATE_PLAYING ) |
|
248 { |
|
249 GstStateChangeReturn gret = GST_STATE_CHANGE_SUCCESS; |
|
250 DEBUG_INFO("Start camera source"); |
|
251 gret = gst_element_set_state( GST_ELEMENT(mCtx->videosource), GST_STATE_PLAYING ); |
|
252 if(gret == GST_STATE_CHANGE_SUCCESS) |
|
253 gret = gst_element_get_state( GST_ELEMENT(mCtx->videosource), NULL,NULL, XA_ADAPT_ASYNC_TIMEOUT_SHORT_NSEC ); |
|
254 } |
|
255 } |
|
256 DEBUG_API("<-XARecordItfAdapt_SetRecordState"); |
|
257 return ret; |
|
258 } |
|
259 |
286 |
260 /* |
287 /* |
261 * XAresult XARecordItfAdapt_GetRecordState(XAAdaptationGstCtx *bCtx, XAuint32 *state) |
288 * XAresult XARecordItfAdapt_GetRecordState(XAAdaptationGstCtx *bCtx, XAuint32 *state) |
262 * Description: Return record state |
289 * Description: Return record state |
263 */ |
290 */ |
264 XAresult XARecordItfAdapt_GetRecordState(XAAdaptationGstCtx *bCtx, XAuint32 *state) |
291 XAresult XARecordItfAdapt_GetRecordState(XAAdaptationGstCtx *bCtx, |
265 { |
292 XAuint32 *state) |
|
293 { |
266 XAMediaRecorderAdaptationCtx* mCtx = NULL; |
294 XAMediaRecorderAdaptationCtx* mCtx = NULL; |
267 DEBUG_API("->XARecordItfAdapt_GetRecordState"); |
295 DEBUG_API("->XARecordItfAdapt_GetRecordState"); |
268 |
296 |
269 if(!bCtx || bCtx->baseObj.ctxId != XAMediaRecorderAdaptation) |
297 if (!bCtx || bCtx->baseObj.ctxId != XAMediaRecorderAdaptation) |
270 { |
298 { |
271 DEBUG_ERR("XA_RESULT_PARAMETER_INVALID"); |
299 DEBUG_ERR("XA_RESULT_PARAMETER_INVALID"); |
272 DEBUG_API("<-XARecordItfAdapt_GetRecordState"); |
300 DEBUG_API("<-XARecordItfAdapt_GetRecordState"); |
273 return XA_RESULT_PARAMETER_INVALID; |
301 return XA_RESULT_PARAMETER_INVALID; |
274 } |
302 } |
275 |
303 |
276 mCtx = (XAMediaRecorderAdaptationCtx*) bCtx; |
304 mCtx = (XAMediaRecorderAdaptationCtx*) bCtx; |
277 |
305 |
278 *state = mCtx->xaRecordState; |
306 *state = mCtx->xaRecordState; |
279 |
307 |
280 DEBUG_API("<-XARecordItfAdapt_GetRecordState"); |
308 DEBUG_API("<-XARecordItfAdapt_GetRecordState"); |
281 return XA_RESULT_SUCCESS; |
309 return XA_RESULT_SUCCESS; |
282 } |
310 } |
283 |
311 |
284 /* |
312 /* |
285 * XAresult XARecordItfAdapt_GetPosition(XAAdaptationGstCtx *ctx, AdaptationContextIDS ctxIDs, XAmillisecond *pMsec) |
313 * XAresult XARecordItfAdapt_GetPosition(XAAdaptationGstCtx *ctx, AdaptationContextIDS ctxIDs, XAmillisecond *pMsec) |
286 * @param XAAdaptationGstCtx *ctx - Adaptation context, this will be casted to correct type regarding to contextID value given as 2nd parameter |
314 * @param XAAdaptationGstCtx *ctx - Adaptation context, this will be casted to correct type regarding to contextID value given as 2nd parameter |
287 * XAmillisecond *pMsec - Pointer where to store current position in stream. |
315 * XAmillisecond *pMsec - Pointer where to store current position in stream. |
288 * @return XAresult ret - Success value |
316 * @return XAresult ret - Success value |
289 */ |
317 */ |
290 XAresult XARecordItfAdapt_GetPosition(XAAdaptationGstCtx *bCtx, XAmillisecond *pMsec) |
318 XAresult XARecordItfAdapt_GetPosition(XAAdaptationGstCtx *bCtx, |
291 { |
319 XAmillisecond *pMsec) |
|
320 { |
292 XAresult ret = XA_RESULT_SUCCESS; |
321 XAresult ret = XA_RESULT_SUCCESS; |
293 |
322 |
294 gint64 position=0; |
323 gint64 position = 0; |
295 GstFormat format = GST_FORMAT_TIME; |
324 GstFormat format = GST_FORMAT_TIME; |
296 DEBUG_API("->XARecordItfAdapt_GetPosition"); |
325 DEBUG_API("->XARecordItfAdapt_GetPosition"); |
297 |
326 |
298 if(!bCtx || bCtx->baseObj.ctxId != XAMediaRecorderAdaptation) |
327 if (!bCtx || bCtx->baseObj.ctxId != XAMediaRecorderAdaptation) |
299 { |
328 { |
300 DEBUG_ERR("XA_RESULT_PARAMETER_INVALID"); |
329 DEBUG_ERR("XA_RESULT_PARAMETER_INVALID"); |
301 DEBUG_API("<-XARecordItfAdapt_GetPosition"); |
330 DEBUG_API("<-XARecordItfAdapt_GetPosition"); |
302 /* invalid parameter */ |
331 /* invalid parameter */ |
303 return XA_RESULT_PARAMETER_INVALID; |
332 return XA_RESULT_PARAMETER_INVALID; |
304 } |
333 } |
305 if ( gst_element_query_position( GST_ELEMENT(bCtx->bin), &format, &position ) ) |
334 if (gst_element_query_position(GST_ELEMENT(bCtx->bin), &format, &position)) |
306 { |
335 { |
307 ret = XA_RESULT_SUCCESS; |
336 ret = XA_RESULT_SUCCESS; |
308 *pMsec = GST_TIME_AS_MSECONDS(position); /*Warning ok due to used API specification*/ |
337 *pMsec = GST_TIME_AS_MSECONDS(position); /*Warning ok due to used API specification*/ |
309 DEBUG_INFO_A1("Gst: Position in microseconds : %u", *pMsec ); |
338 DEBUG_INFO_A1("Gst: Position in microseconds : %u", *pMsec ); |
310 } |
339 } |
311 else |
340 else |
312 { |
341 { |
313 DEBUG_ERR("WARNING: Gst: could not get position"); |
342 DEBUG_ERR("WARNING: Gst: could not get position"); |
314 /* probably not fully prerolled - safe assumption for position = 0 */ |
343 /* probably not fully prerolled - safe assumption for position = 0 */ |
315 *pMsec = 0; |
344 *pMsec = 0; |
316 ret = XA_RESULT_SUCCESS; |
345 ret = XA_RESULT_SUCCESS; |
317 } |
346 } |
318 |
347 |
319 DEBUG_API("<-XARecordItfAdapt_GetPosition"); |
348 DEBUG_API("<-XARecordItfAdapt_GetPosition"); |
320 return ret; |
349 return ret; |
321 } |
350 } |
322 |
|
323 |
351 |
324 /* |
352 /* |
325 * gboolean XARecordItfAdapt_PositionUpdate(gpointer ctx) |
353 * gboolean XARecordItfAdapt_PositionUpdate(gpointer ctx) |
326 * callback. |
354 * callback. |
327 * If position tracking enabled, periodic timer calls this method every XA_ADAPT_PU_INTERVAL msecs |
355 * If position tracking enabled, periodic timer calls this method every XA_ADAPT_PU_INTERVAL msecs |
328 * @return false to stop periodic calls |
356 * @return false to stop periodic calls |
329 */ |
357 */ |
330 gboolean XARecordItfAdapt_PositionUpdate(gpointer ctx) |
358 gboolean XARecordItfAdapt_PositionUpdate(gpointer ctx) |
331 { |
359 { |
332 XAAdaptationGstCtx *bCtx = (XAAdaptationGstCtx*) ctx; |
360 XAAdaptationGstCtx *bCtx = (XAAdaptationGstCtx*) ctx; |
333 XAMediaRecorderAdaptationCtx* mCtx = (XAMediaRecorderAdaptationCtx*) ctx; |
361 XAMediaRecorderAdaptationCtx* mCtx = (XAMediaRecorderAdaptationCtx*) ctx; |
334 DEBUG_API("->XARecordItfAdapt_PositionUpdate"); |
362 DEBUG_API("->XARecordItfAdapt_PositionUpdate"); |
335 |
363 |
336 if( mCtx && mCtx->trackpositionenabled ) |
364 if (mCtx && mCtx->trackpositionenabled) |
337 { |
365 { |
338 GstFormat format = GST_FORMAT_TIME; |
366 GstFormat format = GST_FORMAT_TIME; |
339 gint64 position = 0; |
367 gint64 position = 0; |
340 if ( gst_element_query_position( GST_ELEMENT(bCtx->bin), &format, &position ) ) |
368 if (gst_element_query_position(GST_ELEMENT(bCtx->bin), &format, |
341 { |
369 &position)) |
342 XAuint32 posMsec = GST_TIME_AS_MSECONDS(position);/*Warning ok due to used API specification*/ |
370 { |
343 XAAdaptEvent event = {XA_RECORDITFEVENTS, XA_ADAPT_POSITION_UPDATE_EVT, 1, NULL}; |
371 XAuint32 posMsec = GST_TIME_AS_MSECONDS(position); |
|
372 /*Warning ok due to used API specification*/ |
|
373 XAAdaptEvent event = |
|
374 { |
|
375 XA_RECORDITFEVENTS, XA_ADAPT_POSITION_UPDATE_EVT, 1, NULL |
|
376 }; |
344 event.data = &posMsec; |
377 event.data = &posMsec; |
345 DEBUG_API_A1("XARecordItfAdapt_PositionUpdate: pos %lu ms", posMsec); |
378 DEBUG_API_A1("XARecordItfAdapt_PositionUpdate: pos %lu ms", posMsec); |
346 /* send needed events */ |
379 /* send needed events */ |
347 XAAdaptationBase_SendAdaptEvents(&bCtx->baseObj, &event ); |
380 XAAdaptationBase_SendAdaptEvents(&bCtx->baseObj, &event); |
348 } |
381 } |
349 else |
382 else |
350 { |
383 { |
351 DEBUG_ERR("Gst: Failed to get position"); |
384 DEBUG_ERR("Gst: Failed to get position"); |
352 } |
385 } |
353 DEBUG_API_A1("<-XARecordItfAdapt_PositionUpdate: %d", mCtx->runpositiontimer); |
386 DEBUG_API_A1("<-XARecordItfAdapt_PositionUpdate: %d", mCtx->runpositiontimer); |
354 /* return false to stop timer */ |
387 /* return false to stop timer */ |
355 return( mCtx->runpositiontimer ); |
388 return (mCtx->runpositiontimer); |
|
389 } |
|
390 return FALSE; |
356 } |
391 } |
357 return FALSE; |
|
358 } |
|
359 |
392 |
360 /* |
393 /* |
361 * XAresult XARecordItfAdapt_EnablePositionTracking |
394 * XAresult XARecordItfAdapt_EnablePositionTracking |
362 * Enable/disable periodic position tracking callbacks |
395 * Enable/disable periodic position tracking callbacks |
363 */ |
396 */ |
364 XAresult XARecordItfAdapt_EnablePositionTracking(XAAdaptationGstCtx *bCtx, XAboolean enable) |
397 XAresult XARecordItfAdapt_EnablePositionTracking(XAAdaptationGstCtx *bCtx, |
365 { |
398 XAboolean enable) |
|
399 { |
366 XAMediaRecorderAdaptationCtx* mCtx = (XAMediaRecorderAdaptationCtx*) bCtx; |
400 XAMediaRecorderAdaptationCtx* mCtx = (XAMediaRecorderAdaptationCtx*) bCtx; |
367 DEBUG_API_A1("->XARecordItfAdapt_EnablePositionTracking (enable: %lu)", enable); |
401 DEBUG_API_A1("->XARecordItfAdapt_EnablePositionTracking (enable: %lu)", enable); |
368 |
402 |
369 if(!bCtx || bCtx->baseObj.ctxId != XAMediaRecorderAdaptation) |
403 if (!bCtx || bCtx->baseObj.ctxId != XAMediaRecorderAdaptation) |
370 { |
404 { |
371 DEBUG_ERR("XA_RESULT_PARAMETER_INVALID"); |
405 DEBUG_ERR("XA_RESULT_PARAMETER_INVALID"); |
372 DEBUG_API("<-XARecordItfAdapt_EnablePositionTracking"); |
406 DEBUG_API("<-XARecordItfAdapt_EnablePositionTracking"); |
373 /* invalid parameter */ |
407 /* invalid parameter */ |
374 return XA_RESULT_PARAMETER_INVALID; |
408 return XA_RESULT_PARAMETER_INVALID; |
375 } |
409 } |
376 |
|
377 |
410 |
378 /* create a timer to track position of playback */ |
411 /* create a timer to track position of playback */ |
379 if(enable && !(mCtx->trackpositionenabled)) |
412 if (enable && !(mCtx->trackpositionenabled)) |
380 { |
413 { |
381 mCtx->trackpositionenabled = XA_BOOLEAN_TRUE; |
414 mCtx->trackpositionenabled = XA_BOOLEAN_TRUE; |
382 mCtx->positionCb = &XARecordItfAdapt_PositionUpdate; |
415 mCtx->positionCb = &XARecordItfAdapt_PositionUpdate; |
383 /* if recording is already on, create a timer to track position of recording */ |
416 /* if recording is already on, create a timer to track position of recording */ |
384 if( GST_STATE(bCtx->bin) == GST_STATE_PLAYING ) |
417 if (GST_STATE(bCtx->bin) == GST_STATE_PLAYING) |
385 { |
418 { |
386 mCtx->runpositiontimer = g_timeout_add(XA_ADAPT_PU_INTERVAL, mCtx->positionCb, mCtx); |
419 mCtx->runpositiontimer = g_timeout_add(XA_ADAPT_PU_INTERVAL, |
387 } |
420 mCtx->positionCb, mCtx); |
388 } |
421 } |
|
422 } |
389 else if (!enable && (mCtx->trackpositionenabled)) |
423 else if (!enable && (mCtx->trackpositionenabled)) |
390 { |
424 { |
391 mCtx->trackpositionenabled = XA_BOOLEAN_FALSE; |
425 mCtx->trackpositionenabled = XA_BOOLEAN_FALSE; |
392 if(mCtx->runpositiontimer > 0) |
426 if (mCtx->runpositiontimer > 0) |
393 { |
427 { |
394 g_source_remove(mCtx->runpositiontimer); |
428 g_source_remove(mCtx->runpositiontimer); |
395 mCtx->runpositiontimer=0; |
429 mCtx->runpositiontimer = 0; |
396 } |
430 } |
397 } |
431 } |
398 |
432 |
399 DEBUG_API("<-XARecordItfAdapt_EnablePositionTracking"); |
433 DEBUG_API("<-XARecordItfAdapt_EnablePositionTracking"); |
400 return XA_RESULT_SUCCESS; |
434 return XA_RESULT_SUCCESS; |
401 } |
435 } |
402 |
436 |