Fix memory leak
[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 && handle->eos_cb != NULL) {
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                 }
129         } else {
130                 if (handle->demux_state != MEDIADEMUXER_IDLE)
131                         return MEDIADEMUXER_ERROR_INVALID_STATE;
132                 if (handle->eos_cb == NULL)
133                         MD_E("EOS callback is not set\n");
134                 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
135                         __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
136                 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
137         }
138         return ret;
139 }
140
141 int mediademuxer_get_track_count(mediademuxer_h demuxer, int *count)
142 {
143         MD_I("mediademuxer_get_track_count\n");
144         mediademuxer_error_e ret;
145         DEMUXER_INSTANCE_CHECK(demuxer);
146         mediademuxer_s *handle;
147         handle = (mediademuxer_s *)(demuxer);
148         if (handle && handle->demux_state == MEDIADEMUXER_READY) {
149                 ret = md_get_track_count((MMHandleType) (handle->md_handle), count);
150                 if (ret != MEDIADEMUXER_ERROR_NONE) {
151                         MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
152                                 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
153                         return MEDIADEMUXER_ERROR_INVALID_OPERATION;
154                 }
155         } else {
156                 if (handle->demux_state != MEDIADEMUXER_READY)
157                         return MEDIADEMUXER_ERROR_INVALID_STATE;
158                 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
159                         __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
160                 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
161         }
162         return ret;
163 }
164
165 int mediademuxer_select_track(mediademuxer_h demuxer, int track_index)
166 {
167         MD_I("mediademuxer_select_track\n");
168         mediademuxer_error_e ret;
169         DEMUXER_INSTANCE_CHECK(demuxer);
170         mediademuxer_s *handle;
171         handle = (mediademuxer_s *)(demuxer);
172         if (handle && handle->demux_state == MEDIADEMUXER_READY) {
173                 ret = md_select_track((MMHandleType) (handle->md_handle), track_index);
174                 if (ret != MEDIADEMUXER_ERROR_NONE) {
175                         MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
176                                 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
177                         return MEDIADEMUXER_ERROR_INVALID_OPERATION;
178                 }
179         } else {
180                 if (handle->demux_state != MEDIADEMUXER_READY)
181                         return MEDIADEMUXER_ERROR_INVALID_STATE;
182                 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
183                         __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
184                 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
185         }
186         return ret;
187 }
188
189 int mediademuxer_start(mediademuxer_h demuxer)
190 {
191         MD_I("mediademuxer_start\n");
192         mediademuxer_error_e ret;
193         DEMUXER_INSTANCE_CHECK(demuxer);
194         mediademuxer_s *handle;
195         handle = (mediademuxer_s *)(demuxer);
196         if (handle && handle->demux_state == MEDIADEMUXER_READY) {
197                 ret = md_start((MMHandleType) (handle->md_handle));
198                 if (ret != MEDIADEMUXER_ERROR_NONE) {
199                         MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
200                                 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
201                         return MEDIADEMUXER_ERROR_INVALID_OPERATION;
202                 } else {
203                         handle->demux_state = MEDIADEMUXER_DEMUXING;
204                 }
205         } else {
206                 if (handle->demux_state != MEDIADEMUXER_READY)
207                         return MEDIADEMUXER_ERROR_INVALID_STATE;
208                 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
209                         __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
210                 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
211         }
212         return ret;
213 }
214
215 int mediademuxer_get_track_info(mediademuxer_h demuxer, int track_index,
216                                                         media_format_h *format)
217 {
218         MD_I("mediademuxer_get_track_info\n");
219         mediademuxer_error_e ret;
220         DEMUXER_INSTANCE_CHECK(demuxer);
221         mediademuxer_s *handle;
222         handle = (mediademuxer_s *)(demuxer);
223         if (track_index < 0 || format == NULL) {
224                 MD_E("Invalid input parameters\n");
225                 return MEDIADEMUXER_ERROR_INVALID_PARAMETER;
226         }
227         if (handle && (handle->demux_state == MEDIADEMUXER_READY
228                 || handle->demux_state == MEDIADEMUXER_DEMUXING)) {
229                 ret = md_get_track_info((MMHandleType) (handle->md_handle), track_index, format);
230                 if (ret != MEDIADEMUXER_ERROR_NONE) {
231                         MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
232                                 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
233                         return MEDIADEMUXER_ERROR_INVALID_OPERATION;
234                 }
235         } else {
236                 if (handle->demux_state != MEDIADEMUXER_READY)
237                         return MEDIADEMUXER_ERROR_INVALID_STATE;
238                 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
239                         __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
240                 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
241         }
242         return ret;
243 }
244
245 int mediademuxer_read_sample(mediademuxer_h demuxer, int track_index,
246                                                         media_packet_h *outbuf)
247 {
248         MD_I("mediademuxer_read_sample\n");
249         mediademuxer_error_e ret;
250         DEMUXER_INSTANCE_CHECK(demuxer);
251         mediademuxer_s *handle;
252         handle = (mediademuxer_s *)(demuxer);
253         if (outbuf == NULL || track_index < 0)
254                 return MEDIADEMUXER_ERROR_INVALID_PARAMETER;
255         if (handle && handle->demux_state == MEDIADEMUXER_DEMUXING) {
256                 ret = md_read_sample((MMHandleType) (handle->md_handle), track_index, outbuf);
257                 if (ret != MEDIADEMUXER_ERROR_NONE) {
258                         MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
259                                 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
260                         return MEDIADEMUXER_ERROR_INVALID_OPERATION;
261                 }
262         } else {
263                 if (handle->demux_state != MEDIADEMUXER_DEMUXING)
264                         return MEDIADEMUXER_ERROR_INVALID_STATE;
265                 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
266                         __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
267                 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
268         }
269         return ret;
270 }
271
272 int mediademuxer_seek(mediademuxer_h demuxer, int64_t pos)
273 {
274         MD_I("mediademuxer_seek\n");
275         mediademuxer_error_e ret;
276         DEMUXER_INSTANCE_CHECK(demuxer);
277         mediademuxer_s *handle;
278         handle = (mediademuxer_s *)(demuxer);
279         if (handle && handle->demux_state == MEDIADEMUXER_DEMUXING) {
280                 ret = md_seek((MMHandleType) (handle->md_handle), pos);
281                 if (ret != MEDIADEMUXER_ERROR_NONE) {
282                         MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
283                                 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
284                         return MEDIADEMUXER_ERROR_INVALID_OPERATION;
285                 }
286         } else {
287                 if (handle->demux_state != MEDIADEMUXER_DEMUXING)
288                         return MEDIADEMUXER_ERROR_INVALID_STATE;
289                 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
290                         __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
291                 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
292         }
293         return ret;
294 }
295
296 int mediademuxer_unselect_track(mediademuxer_h demuxer, int track_index)
297 {
298         MD_I("mediademuxer_unselect_track\n");
299         mediademuxer_error_e ret;
300         DEMUXER_INSTANCE_CHECK(demuxer);
301         mediademuxer_s *handle;
302         handle = (mediademuxer_s *)(demuxer);
303         if (handle && (handle->demux_state == MEDIADEMUXER_READY
304                 || handle->demux_state == MEDIADEMUXER_DEMUXING)) {
305                 ret = md_unselect_track((MMHandleType) (handle->md_handle), track_index);
306                 if (ret != MEDIADEMUXER_ERROR_NONE) {
307                         MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
308                                 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
309                         return MEDIADEMUXER_ERROR_INVALID_OPERATION;
310                 }
311         } else {
312                 if (handle->demux_state != MEDIADEMUXER_READY)
313                         return MEDIADEMUXER_ERROR_INVALID_STATE;
314                 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
315                         __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
316                 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
317         }
318         return ret;
319 }
320
321 int mediademuxer_stop(mediademuxer_h demuxer)
322 {
323         MD_I("mediademuxer_stop\n");
324         mediademuxer_error_e ret;
325         DEMUXER_INSTANCE_CHECK(demuxer);
326         mediademuxer_s *handle;
327         handle = (mediademuxer_s *)(demuxer);
328         if (handle && handle->demux_state == MEDIADEMUXER_DEMUXING) {
329                 ret = md_stop((MMHandleType) (handle->md_handle));
330                 if (ret != MEDIADEMUXER_ERROR_NONE) {
331                         MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
332                                 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
333                         return MEDIADEMUXER_ERROR_INVALID_OPERATION;
334                 } else
335                         handle->demux_state = MEDIADEMUXER_READY;
336         } else {
337                 if (handle->demux_state != MEDIADEMUXER_DEMUXING)
338                         return MEDIADEMUXER_ERROR_INVALID_STATE;
339                 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
340                         __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
341                 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
342         }
343         return ret;
344 }
345
346 int mediademuxer_unprepare(mediademuxer_h demuxer)
347 {
348         MD_I("mediademuxer_unprepare\n");
349         mediademuxer_error_e ret;
350         DEMUXER_INSTANCE_CHECK(demuxer);
351         mediademuxer_s *handle;
352         handle = (mediademuxer_s *)(demuxer);
353         if (handle && handle->demux_state == MEDIADEMUXER_READY) {
354                 ret = md_unprepare((MMHandleType) (handle->md_handle));
355                 if (ret != MEDIADEMUXER_ERROR_NONE) {
356                         MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
357                                 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
358                         return MEDIADEMUXER_ERROR_INVALID_OPERATION;
359                 } else
360                         handle->demux_state = MEDIADEMUXER_IDLE;
361         } else {
362                 if (handle->demux_state != MEDIADEMUXER_READY)
363                         return MEDIADEMUXER_ERROR_INVALID_STATE;
364                 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
365                         __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
366                 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
367         }
368         return ret;
369 }
370
371 int mediademuxer_destroy(mediademuxer_h demuxer)
372 {
373         MD_I("mediademuxer_destroy\n");
374         mediademuxer_error_e ret;
375         DEMUXER_INSTANCE_CHECK(demuxer);
376         mediademuxer_s *handle;
377         handle = (mediademuxer_s *)(demuxer);
378         if (handle && handle->demux_state == MEDIADEMUXER_IDLE) {
379                 ret = md_destroy(handle->md_handle);
380                 if (ret != MEDIADEMUXER_ERROR_NONE) {
381                         MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
382                                 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
383                         return MEDIADEMUXER_ERROR_INVALID_OPERATION;
384                 } else {
385                         MD_E("[CoreAPI][%s] destroy handle : %p", __FUNCTION__, handle);
386                         handle->demux_state = MEDIADEMUXER_NONE;
387                         g_free(handle);
388                         handle = NULL;
389                 }
390         } else {
391                 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
392                                  __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
393                 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
394         }
395         return MEDIADEMUXER_ERROR_NONE;
396 }
397
398 int mediademuxer_get_state(mediademuxer_h demuxer, mediademuxer_state *state)
399 {
400         mediademuxer_error_e ret = MEDIADEMUXER_ERROR_NONE;
401         DEMUXER_INSTANCE_CHECK(demuxer);
402         mediademuxer_s *handle = (mediademuxer_s *)(demuxer);
403         if (state != NULL) {
404                 *state = handle->demux_state;
405         } else {
406                 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
407                         __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
408                 ret = MEDIADEMUXER_ERROR_INVALID_OPERATION;
409         }
410         return ret;
411 }
412
413 int mediademuxer_set_error_cb(mediademuxer_h demuxer,
414                         mediademuxer_error_cb callback, void *user_data)
415 {
416         DEMUXER_INSTANCE_CHECK(demuxer);
417         mediademuxer_s *handle;
418         handle = (mediademuxer_s *)(demuxer);
419         if (handle->demux_state != MEDIADEMUXER_IDLE)
420                 return MEDIADEMUXER_ERROR_INVALID_STATE;
421         handle->error_cb = callback;
422         handle->error_cb_userdata = user_data;
423         MD_I("set error_cb(%p)", callback);
424         return MEDIADEMUXER_ERROR_NONE;
425 }
426
427 int mediademuxer_unset_error_cb(mediademuxer_h demuxer)
428 {
429         DEMUXER_INSTANCE_CHECK(demuxer);
430         mediademuxer_s *handle;
431         handle = (mediademuxer_s *)(demuxer);
432         if (handle->demux_state != MEDIADEMUXER_IDLE)
433                 return MEDIADEMUXER_ERROR_INVALID_STATE;
434         handle->error_cb = NULL;
435         handle->error_cb_userdata = NULL;
436         MD_I("mediademuxer_unset_error_cb\n");
437         return MEDIADEMUXER_ERROR_NONE;
438 }
439
440 static gboolean _mediademuxer_error_cb(mediademuxer_error_e error, void *user_data)
441 {
442         if (user_data == NULL) {
443                 MD_I("_mediademuxer_error_cb: ERROR %d to report. But call back is not set\n", error);
444                 return 0;
445         }
446         mediademuxer_s * handle = (mediademuxer_s *) user_data;
447         if (handle->demux_state != MEDIADEMUXER_IDLE)
448                 return MEDIADEMUXER_ERROR_INVALID_STATE;
449         if (handle->error_cb)
450                 ((mediademuxer_error_cb)handle->error_cb)(error, handle->error_cb_userdata);
451         else
452                 MD_I("_mediademuxer_error_cb: ERROR %d to report. But call back is not set\n", error);
453         return 0;
454 }
455
456 int mediademuxer_set_eos_cb(mediademuxer_h demuxer,
457                         mediademuxer_eos_cb callback, void *user_data)
458 {
459         DEMUXER_INSTANCE_CHECK(demuxer);
460         mediademuxer_s *handle;
461         handle = (mediademuxer_s *)(demuxer);
462         if (handle->demux_state != MEDIADEMUXER_IDLE)
463                 return MEDIADEMUXER_ERROR_INVALID_STATE;
464         handle->eos_cb = callback;
465         handle->eos_cb_userdata = user_data;
466         MD_I("set eos_cb(%p)", callback);
467         return MEDIADEMUXER_ERROR_NONE;
468 }
469
470 int mediademuxer_unset_eos_cb(mediademuxer_h demuxer)
471 {
472         DEMUXER_INSTANCE_CHECK(demuxer);
473         mediademuxer_s *handle;
474         handle = (mediademuxer_s *)(demuxer);
475         if (handle->demux_state != MEDIADEMUXER_IDLE)
476                 return MEDIADEMUXER_ERROR_INVALID_STATE;
477         handle->eos_cb = NULL;
478         handle->eos_cb_userdata = NULL;
479         MD_I("mediademuxer_unset_eos_cb\n");
480         return MEDIADEMUXER_ERROR_NONE;
481 }
482
483 static gboolean _mediademuxer_eos_cb(int track_num, void *user_data)
484 {
485         if (user_data == NULL) {
486                 MD_I("_mediademuxer_eos_cb: EOS to report. But call back is not set\n");
487                 return 0;
488         }
489         mediademuxer_s *handle = (mediademuxer_s *)user_data;
490         if (handle->demux_state != MEDIADEMUXER_DEMUXING)
491                 return MEDIADEMUXER_ERROR_INVALID_STATE;
492         if (handle->eos_cb)
493                 ((mediademuxer_eos_cb)handle->eos_cb)(track_num, handle->eos_cb_userdata);
494         else
495                 MD_I("_mediademuxer_eos_cb: EOS %d to report. But call back is not set\n", track_num);
496         return 0;
497 }