2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #include <mediademuxer.h>
23 #include <mediademuxer_private.h>
24 #include <mediademuxer_port.h>
26 #ifndef USE_TASK_QUEUE
27 #define USE_TASK_QUEUE
31 * Public Implementation
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);
36 int mediademuxer_create(mediademuxer_h *demuxer)
38 MD_I("mediademuxer_create\n");
39 mediademuxer_error_e ret;
40 DEMUXER_INSTANCE_CHECK(demuxer);
42 mediademuxer_s *handle;
43 if (*demuxer == NULL) {
44 handle = (mediademuxer_s *) g_malloc(sizeof(mediademuxer_s));
46 memset(handle, 0, sizeof(mediademuxer_s));
47 handle->demux_state = MEDIADEMUXER_NONE;
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;
54 MD_E("Already created the instance\n");
55 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
58 ret = md_create(&handle->md_handle);
60 if (ret != MEDIADEMUXER_ERROR_NONE) {
61 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
62 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
65 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
67 *demuxer = (mediademuxer_h) handle;
68 handle->is_stopped = false;
69 MD_I("[CoreAPI][%s] new handle : %p", __FUNCTION__, *demuxer);
72 md_set_error_cb(handle->md_handle,
73 (mediademuxer_error_cb) _mediademuxer_error_cb,
75 md_set_eos_cb(handle->md_handle,
76 (mediademuxer_eos_cb) _mediademuxer_eos_cb,
79 handle->demux_state = MEDIADEMUXER_IDLE;
80 return MEDIADEMUXER_ERROR_NONE;
83 int mediademuxer_set_data_source(mediademuxer_h demuxer, const char *path)
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;
99 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
100 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_PATH);
101 return MEDIADEMUXER_ERROR_INVALID_PATH;
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;
113 int mediademuxer_prepare(mediademuxer_h demuxer)
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;
127 handle->demux_state = MEDIADEMUXER_READY;
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;
141 int mediademuxer_get_track_count(mediademuxer_h demuxer, int *count)
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;
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;
165 int mediademuxer_select_track(mediademuxer_h demuxer, int track_index)
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;
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;
189 int mediademuxer_start(mediademuxer_h demuxer)
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;
203 handle->demux_state = MEDIADEMUXER_DEMUXING;
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;
215 int mediademuxer_get_track_info(mediademuxer_h demuxer, int track_index,
216 media_format_h *format)
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;
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;
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;
245 int mediademuxer_read_sample(mediademuxer_h demuxer, int track_index,
246 media_packet_h *outbuf)
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;
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;
272 int mediademuxer_seek(mediademuxer_h demuxer, int64_t pos)
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;
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;
296 int mediademuxer_unselect_track(mediademuxer_h demuxer, int track_index)
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;
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;
321 int mediademuxer_stop(mediademuxer_h demuxer)
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;
335 handle->demux_state = MEDIADEMUXER_READY;
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;
346 int mediademuxer_unprepare(mediademuxer_h demuxer)
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;
360 handle->demux_state = MEDIADEMUXER_IDLE;
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;
371 int mediademuxer_destroy(mediademuxer_h demuxer)
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;
385 MD_E("[CoreAPI][%s] destroy handle : %p", __FUNCTION__, handle);
386 handle->demux_state = MEDIADEMUXER_NONE;
391 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
392 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
393 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
395 return MEDIADEMUXER_ERROR_NONE;
398 int mediademuxer_get_state(mediademuxer_h demuxer, mediademuxer_state *state)
400 mediademuxer_error_e ret = MEDIADEMUXER_ERROR_NONE;
401 DEMUXER_INSTANCE_CHECK(demuxer);
402 mediademuxer_s *handle = (mediademuxer_s *)(demuxer);
404 *state = handle->demux_state;
406 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
407 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
408 ret = MEDIADEMUXER_ERROR_INVALID_OPERATION;
413 int mediademuxer_set_error_cb(mediademuxer_h demuxer,
414 mediademuxer_error_cb callback, void *user_data)
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;
427 int mediademuxer_unset_error_cb(mediademuxer_h demuxer)
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;
440 static gboolean _mediademuxer_error_cb(mediademuxer_error_e error, void *user_data)
442 if (user_data == NULL) {
443 MD_I("_mediademuxer_error_cb: ERROR %d to report. But call back is not set\n", error);
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);
452 MD_I("_mediademuxer_error_cb: ERROR %d to report. But call back is not set\n", error);
456 int mediademuxer_set_eos_cb(mediademuxer_h demuxer,
457 mediademuxer_eos_cb callback, void *user_data)
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;
470 int mediademuxer_unset_eos_cb(mediademuxer_h demuxer)
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;
483 static gboolean _mediademuxer_eos_cb(int track_num, void *user_data)
485 if (user_data == NULL) {
486 MD_I("_mediademuxer_eos_cb: EOS to report. But call back is not set\n");
489 mediademuxer_s *handle = (mediademuxer_s *)user_data;
490 if (handle->demux_state != MEDIADEMUXER_DEMUXING)
491 return MEDIADEMUXER_ERROR_INVALID_STATE;
493 ((mediademuxer_eos_cb)handle->eos_cb)(track_num, handle->eos_cb_userdata);
495 MD_I("_mediademuxer_eos_cb: EOS %d to report. But call back is not set\n", track_num);