Applied Error handling guidelines.
[platform/core/api/mediademuxer.git] / src / mediademuxer.c
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <dlog.h>
21
22 #include <mediademuxer.h>
23 #include <mediademuxer_private.h>
24 #include <mediademuxer_port.h>
25
26 #ifndef USE_TASK_QUEUE
27 #define USE_TASK_QUEUE
28 #endif
29
30 /*
31 * Public Implementation
32 */
33 static gboolean _mediademuxer_error_cb(mediademuxer_error_e error, void *user_data);
34 static gboolean _mediademuxer_eos_cb(int track_num, void *user_data);
35
36 int mediademuxer_create(mediademuxer_h *demuxer)
37 {
38         MD_I("mediademuxer_create\n");
39         mediademuxer_error_e ret;
40         DEMUXER_INSTANCE_CHECK(demuxer);
41
42         mediademuxer_s *handle;
43         if (*demuxer == NULL) {
44                 handle = (mediademuxer_s *) g_malloc(sizeof(mediademuxer_s));
45                 if (handle != NULL) {
46                         memset(handle, 0, sizeof(mediademuxer_s));
47                         handle->demux_state = MEDIADEMUXER_NONE;
48                 } else {
49                         MD_E("[CoreAPI][%s] DEMUXER_ERROR_OUT_OF_MEMORY(0x%08x)",
50                                 __FUNCTION__, MEDIADEMUXER_ERROR_OUT_OF_MEMORY);
51                         return MEDIADEMUXER_ERROR_OUT_OF_MEMORY;
52                 }
53         } else {
54                 MD_E("Already created the instance\n");
55                 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
56         }
57
58         ret = md_create(&handle->md_handle);
59
60         if (ret != MEDIADEMUXER_ERROR_NONE) {
61                 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
62                         __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
63                 free(handle);
64                 handle = NULL;
65                 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
66         } else {
67                 *demuxer = (mediademuxer_h) handle;
68                 handle->is_stopped = false;
69                 MD_I("[CoreAPI][%s] new handle : %p", __FUNCTION__, *demuxer);
70         }
71         /* set callback */
72         md_set_error_cb(handle->md_handle,
73                         (mediademuxer_error_cb) _mediademuxer_error_cb,
74                         handle);
75         md_set_eos_cb(handle->md_handle,
76                         (mediademuxer_eos_cb) _mediademuxer_eos_cb,
77                         handle);
78
79         handle->demux_state = MEDIADEMUXER_IDLE;
80         return MEDIADEMUXER_ERROR_NONE;
81 }
82
83 int mediademuxer_set_data_source(mediademuxer_h demuxer, const char *path)
84 {
85         MD_I("mediademuxer_set_data_source\n");
86         mediademuxer_error_e ret = MEDIADEMUXER_ERROR_NONE;
87         DEMUXER_INSTANCE_CHECK(demuxer);
88         mediademuxer_s *handle;
89         handle = (mediademuxer_s *)(demuxer);
90         if (handle && path && handle->demux_state == MEDIADEMUXER_IDLE) {
91                 ret = md_set_data_source((MMHandleType) (handle->md_handle), path);
92                 if (ret != MEDIADEMUXER_ERROR_NONE) {
93                         MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", __FUNCTION__,
94                                 MEDIADEMUXER_ERROR_INVALID_PATH);
95                         return MEDIADEMUXER_ERROR_INVALID_PATH;
96                 }
97         } else {
98                 if (!path) {
99                         MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
100                                 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_PATH);
101                         return MEDIADEMUXER_ERROR_INVALID_PATH;
102                 } else {
103                         if (handle->demux_state != MEDIADEMUXER_IDLE)
104                                 return MEDIADEMUXER_ERROR_INVALID_STATE;
105                         MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
106                                 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
107                         return MEDIADEMUXER_ERROR_INVALID_OPERATION;
108                 }
109         }
110         return ret;
111 }
112
113 int mediademuxer_prepare(mediademuxer_h demuxer)
114 {
115         MD_I("mediademuxer_prepare\n");
116         mediademuxer_error_e ret = MEDIADEMUXER_ERROR_NONE;
117         DEMUXER_INSTANCE_CHECK(demuxer);
118         mediademuxer_s *handle;
119         handle = (mediademuxer_s *)(demuxer);
120         if (handle && handle->demux_state == MEDIADEMUXER_IDLE) {
121                 ret = md_prepare((MMHandleType) (handle->md_handle));
122                 if (ret != MEDIADEMUXER_ERROR_NONE) {
123                         MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
124                                 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
125                         return MEDIADEMUXER_ERROR_INVALID_OPERATION;
126                 } else
127                         handle->demux_state = MEDIADEMUXER_READY;
128         } else {
129                 if (handle->demux_state != MEDIADEMUXER_IDLE)
130                         return MEDIADEMUXER_ERROR_INVALID_STATE;
131                 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
132                         __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
133                 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
134         }
135         return ret;
136 }
137
138 int mediademuxer_get_track_count(mediademuxer_h demuxer, int *count)
139 {
140         MD_I("mediademuxer_get_track_count\n");
141         mediademuxer_error_e ret;
142         DEMUXER_INSTANCE_CHECK(demuxer);
143         mediademuxer_s *handle;
144         handle = (mediademuxer_s *)(demuxer);
145         if (handle && handle->demux_state == MEDIADEMUXER_READY) {
146                 ret = md_get_track_count((MMHandleType) (handle->md_handle), count);
147                 if (ret != MEDIADEMUXER_ERROR_NONE) {
148                         MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
149                                 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
150                         return MEDIADEMUXER_ERROR_INVALID_OPERATION;
151                 }
152         } else {
153                 if (handle->demux_state != MEDIADEMUXER_READY)
154                         return MEDIADEMUXER_ERROR_INVALID_STATE;
155                 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
156                         __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
157                 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
158         }
159         return ret;
160 }
161
162 int mediademuxer_select_track(mediademuxer_h demuxer, int track_index)
163 {
164         MD_I("mediademuxer_select_track\n");
165         mediademuxer_error_e ret;
166         DEMUXER_INSTANCE_CHECK(demuxer);
167         mediademuxer_s *handle;
168         handle = (mediademuxer_s *)(demuxer);
169         if (handle && handle->demux_state == MEDIADEMUXER_READY) {
170                 ret = md_select_track((MMHandleType) (handle->md_handle), track_index);
171                 if (ret != MEDIADEMUXER_ERROR_NONE) {
172                         MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
173                                 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
174                         return MEDIADEMUXER_ERROR_INVALID_OPERATION;
175                 }
176         } else {
177                 if (handle->demux_state != MEDIADEMUXER_READY)
178                         return MEDIADEMUXER_ERROR_INVALID_STATE;
179                 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
180                         __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
181                 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
182         }
183         return ret;
184 }
185
186 int mediademuxer_start(mediademuxer_h demuxer)
187 {
188         MD_I("mediademuxer_start\n");
189         mediademuxer_error_e ret;
190         DEMUXER_INSTANCE_CHECK(demuxer);
191         mediademuxer_s *handle;
192         handle = (mediademuxer_s *)(demuxer);
193         if (handle && handle->demux_state == MEDIADEMUXER_READY) {
194                 ret = md_start((MMHandleType) (handle->md_handle));
195                 if (ret != MEDIADEMUXER_ERROR_NONE) {
196                         MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
197                                 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
198                         return MEDIADEMUXER_ERROR_INVALID_OPERATION;
199                 } else
200                         handle->demux_state = MEDIADEMUXER_DEMUXING;
201         } else {
202                 if (handle->demux_state != MEDIADEMUXER_READY)
203                         return MEDIADEMUXER_ERROR_INVALID_STATE;
204                 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
205                         __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
206                 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
207         }
208         return ret;
209 }
210
211 int mediademuxer_get_track_info(mediademuxer_h demuxer, int track_index,
212                                                         media_format_h *format)
213 {
214         MD_I("mediademuxer_get_track_info\n");
215         mediademuxer_error_e ret;
216         DEMUXER_INSTANCE_CHECK(demuxer);
217         mediademuxer_s *handle;
218         handle = (mediademuxer_s *)(demuxer);
219         if (track_index < 0 || format == NULL) {
220                 MD_E("Invalid input parameters\n");
221                 return MEDIADEMUXER_ERROR_INVALID_PARAMETER;
222         }
223         if (handle && (handle->demux_state == MEDIADEMUXER_READY
224                 || handle->demux_state == MEDIADEMUXER_DEMUXING)) {
225                 ret = md_get_track_info((MMHandleType) (handle->md_handle), track_index, format);
226                 if (ret != MEDIADEMUXER_ERROR_NONE) {
227                         MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
228                                 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
229                         return MEDIADEMUXER_ERROR_INVALID_OPERATION;
230                 }
231         } else {
232                 if (handle->demux_state != MEDIADEMUXER_READY)
233                         return MEDIADEMUXER_ERROR_INVALID_STATE;
234                 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
235                         __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
236                 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
237         }
238         return ret;
239 }
240
241 int mediademuxer_read_sample(mediademuxer_h demuxer, int track_index,
242                                                         media_packet_h *outbuf)
243 {
244         MD_I("mediademuxer_read_sample\n");
245         mediademuxer_error_e ret;
246         DEMUXER_INSTANCE_CHECK(demuxer);
247         mediademuxer_s *handle;
248         handle = (mediademuxer_s *)(demuxer);
249         if (outbuf == NULL || track_index < 0)
250                 return MEDIADEMUXER_ERROR_INVALID_PARAMETER;
251         if (handle && handle->demux_state == MEDIADEMUXER_DEMUXING) {
252                 ret = md_read_sample((MMHandleType) (handle->md_handle), track_index, outbuf);
253                 if (ret != MEDIADEMUXER_ERROR_NONE) {
254                         MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
255                                 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
256                         return MEDIADEMUXER_ERROR_INVALID_OPERATION;
257                 }
258         } else {
259                 if (handle->demux_state != MEDIADEMUXER_DEMUXING)
260                         return MEDIADEMUXER_ERROR_INVALID_STATE;
261                 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
262                         __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
263                 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
264         }
265         return ret;
266 }
267
268 int mediademuxer_seek(mediademuxer_h demuxer, int64_t pos)
269 {
270         MD_I("mediademuxer_seek\n");
271         mediademuxer_error_e ret;
272         DEMUXER_INSTANCE_CHECK(demuxer);
273         mediademuxer_s *handle;
274         handle = (mediademuxer_s *)(demuxer);
275         if (handle && handle->demux_state == MEDIADEMUXER_DEMUXING) {
276                 ret = md_seek((MMHandleType) (handle->md_handle), pos);
277                 if (ret != MEDIADEMUXER_ERROR_NONE) {
278                         MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
279                                 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
280                         return MEDIADEMUXER_ERROR_INVALID_OPERATION;
281                 }
282         } else {
283                 if (handle->demux_state != MEDIADEMUXER_DEMUXING)
284                         return MEDIADEMUXER_ERROR_INVALID_STATE;
285                 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
286                         __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
287                 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
288         }
289         return ret;
290 }
291
292 int mediademuxer_unselect_track(mediademuxer_h demuxer, int track_index)
293 {
294         MD_I("mediademuxer_unselect_track\n");
295         mediademuxer_error_e ret;
296         DEMUXER_INSTANCE_CHECK(demuxer);
297         mediademuxer_s *handle;
298         handle = (mediademuxer_s *)(demuxer);
299         if (handle && (handle->demux_state == MEDIADEMUXER_READY
300                 || handle->demux_state == MEDIADEMUXER_DEMUXING)) {
301                 ret = md_unselect_track((MMHandleType) (handle->md_handle), track_index);
302                 if (ret != MEDIADEMUXER_ERROR_NONE) {
303                         MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
304                                 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
305                         return MEDIADEMUXER_ERROR_INVALID_OPERATION;
306                 }
307         } else {
308                 if (handle->demux_state != MEDIADEMUXER_READY)
309                         return MEDIADEMUXER_ERROR_INVALID_STATE;
310                 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
311                         __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
312                 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
313         }
314         return ret;
315 }
316
317 int mediademuxer_stop(mediademuxer_h demuxer)
318 {
319         MD_I("mediademuxer_stop\n");
320         mediademuxer_error_e ret;
321         DEMUXER_INSTANCE_CHECK(demuxer);
322         mediademuxer_s *handle;
323         handle = (mediademuxer_s *)(demuxer);
324         if (handle && handle->demux_state == MEDIADEMUXER_DEMUXING) {
325                 ret = md_stop((MMHandleType) (handle->md_handle));
326                 if (ret != MEDIADEMUXER_ERROR_NONE) {
327                         MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
328                                 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
329                         return MEDIADEMUXER_ERROR_INVALID_OPERATION;
330                 } else
331                         handle->demux_state = MEDIADEMUXER_READY;
332         } else {
333                 if (handle->demux_state != MEDIADEMUXER_DEMUXING)
334                         return MEDIADEMUXER_ERROR_INVALID_STATE;
335                 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
336                         __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
337                 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
338         }
339         return ret;
340 }
341
342 int mediademuxer_unprepare(mediademuxer_h demuxer)
343 {
344         MD_I("mediademuxer_unprepare\n");
345         mediademuxer_error_e ret;
346         DEMUXER_INSTANCE_CHECK(demuxer);
347         mediademuxer_s *handle;
348         handle = (mediademuxer_s *)(demuxer);
349         if (handle && handle->demux_state == MEDIADEMUXER_READY) {
350                 ret = md_unprepare((MMHandleType) (handle->md_handle));
351                 if (ret != MEDIADEMUXER_ERROR_NONE) {
352                         MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
353                                 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
354                         return MEDIADEMUXER_ERROR_INVALID_OPERATION;
355                 } else
356                         handle->demux_state = MEDIADEMUXER_IDLE;
357         } else {
358                 if (handle->demux_state != MEDIADEMUXER_READY)
359                         return MEDIADEMUXER_ERROR_INVALID_STATE;
360                 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
361                         __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
362                 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
363         }
364         return ret;
365 }
366
367 int mediademuxer_destroy(mediademuxer_h demuxer)
368 {
369         MD_I("mediademuxer_destroy\n");
370         mediademuxer_error_e ret;
371         DEMUXER_INSTANCE_CHECK(demuxer);
372         mediademuxer_s *handle;
373         handle = (mediademuxer_s *)(demuxer);
374         if (handle && handle->demux_state == MEDIADEMUXER_IDLE) {
375                 ret = md_destroy(handle->md_handle);
376                 if (ret != MEDIADEMUXER_ERROR_NONE) {
377                         MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
378                                 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
379                         return MEDIADEMUXER_ERROR_INVALID_OPERATION;
380                 } else {
381                         MD_E("[CoreAPI][%s] destroy handle : %p", __FUNCTION__,
382                              handle);
383                 }
384         } else {
385                 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
386                                  __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
387                 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
388         }
389         handle->demux_state = MEDIADEMUXER_NONE;
390         return MEDIADEMUXER_ERROR_NONE;
391 }
392
393 int mediademuxer_get_state(mediademuxer_h demuxer, mediademuxer_state *state)
394 {
395         MD_I("mediademuxer_get_state\n");
396         mediademuxer_error_e ret = MEDIADEMUXER_ERROR_NONE;
397         DEMUXER_INSTANCE_CHECK(demuxer);
398         mediademuxer_s *handle = (mediademuxer_s *)(demuxer);
399         if (state != NULL) {
400                 *state = handle->demux_state;
401         } else {
402                 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
403                         __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
404                 ret = MEDIADEMUXER_ERROR_INVALID_OPERATION;
405         }
406         return ret;
407 }
408
409 int mediademuxer_set_error_cb(mediademuxer_h demuxer,
410                         mediademuxer_error_cb callback, void *user_data)
411 {
412         DEMUXER_INSTANCE_CHECK(demuxer);
413         mediademuxer_s *handle;
414         handle = (mediademuxer_s *)(demuxer);
415         if (handle->demux_state != MEDIADEMUXER_IDLE)
416                 return MEDIADEMUXER_ERROR_INVALID_STATE;
417         handle->error_cb = callback;
418         handle->error_cb_userdata = user_data;
419         MD_I("set error_cb(%p)", callback);
420         return MEDIADEMUXER_ERROR_NONE;
421 }
422
423 int mediademuxer_unset_error_cb(mediademuxer_h demuxer)
424 {
425         DEMUXER_INSTANCE_CHECK(demuxer);
426         mediademuxer_s *handle;
427         handle = (mediademuxer_s *)(demuxer);
428         if (handle->demux_state != MEDIADEMUXER_IDLE)
429                 return MEDIADEMUXER_ERROR_INVALID_STATE;
430         handle->error_cb = NULL;
431         handle->error_cb_userdata = NULL;
432         MD_I("mediademuxer_unset_error_cb\n");
433         return MEDIADEMUXER_ERROR_NONE;
434 }
435
436 static gboolean _mediademuxer_error_cb(mediademuxer_error_e error, void *user_data)
437 {
438         if (user_data == NULL) {
439                 MD_I("_mediademuxer_error_cb: ERROR %d to report. But call back is not set\n", error);
440                 return 0;
441         }
442         mediademuxer_s * handle = (mediademuxer_s *) user_data;
443         if (handle->demux_state != MEDIADEMUXER_IDLE)
444                 return MEDIADEMUXER_ERROR_INVALID_STATE;
445         if (handle->error_cb)
446                 ((mediademuxer_error_cb)handle->error_cb)(error, handle->error_cb_userdata);
447         else
448                 MD_I("_mediademuxer_error_cb: ERROR %d to report. But call back is not set\n", error);
449         return 0;
450 }
451
452 int mediademuxer_set_eos_cb(mediademuxer_h demuxer,
453                         mediademuxer_eos_cb callback, void *user_data)
454 {
455         DEMUXER_INSTANCE_CHECK(demuxer);
456         mediademuxer_s *handle;
457         handle = (mediademuxer_s *)(demuxer);
458         if (handle->demux_state != MEDIADEMUXER_IDLE)
459                 return MEDIADEMUXER_ERROR_INVALID_STATE;
460         handle->eos_cb = callback;
461         handle->eos_cb_userdata = user_data;
462         MD_I("set eos_cb(%p)", callback);
463         return MEDIADEMUXER_ERROR_NONE;
464 }
465
466 int mediademuxer_unset_eos_cb(mediademuxer_h demuxer)
467 {
468         DEMUXER_INSTANCE_CHECK(demuxer);
469         mediademuxer_s *handle;
470         handle = (mediademuxer_s *)(demuxer);
471         if (handle->demux_state != MEDIADEMUXER_IDLE)
472                 return MEDIADEMUXER_ERROR_INVALID_STATE;
473         handle->eos_cb = NULL;
474         handle->eos_cb_userdata = NULL;
475         MD_I("mediademuxer_unset_eos_cb\n");
476         return MEDIADEMUXER_ERROR_NONE;
477 }
478
479 static gboolean _mediademuxer_eos_cb(int track_num, void *user_data)
480 {
481         if (user_data == NULL) {
482                 MD_I("_mediademuxer_eos_cb: EOS to report. But call back is not set\n");
483                 return 0;
484         }
485         mediademuxer_s *handle = (mediademuxer_s *)user_data;
486         if (handle->demux_state != MEDIADEMUXER_DEMUXING)
487                 return MEDIADEMUXER_ERROR_INVALID_STATE;
488         if (handle->eos_cb)
489                 ((mediademuxer_eos_cb)handle->eos_cb)(track_num, handle->eos_cb_userdata);
490         else
491                 MD_I("_mediademuxer_eos_cb: EOS %d to report. But call back is not set\n", track_num);
492         return 0;
493 }