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_STATE_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, handle);
74 md_set_eos_cb(handle->md_handle,
75 (mediademuxer_eos_cb)_mediademuxer_eos_cb, handle);
77 handle->demux_state = MEDIADEMUXER_STATE_IDLE;
78 return MEDIADEMUXER_ERROR_NONE;
81 int mediademuxer_set_data_source(mediademuxer_h demuxer, const char *path)
83 MD_I("mediademuxer_set_data_source\n");
84 mediademuxer_error_e ret = MEDIADEMUXER_ERROR_NONE;
85 DEMUXER_INSTANCE_CHECK(demuxer);
86 mediademuxer_s *handle;
87 handle = (mediademuxer_s *)demuxer;
88 if (handle && path && handle->demux_state == MEDIADEMUXER_STATE_IDLE) {
89 ret = md_set_data_source((MMHandleType)handle->md_handle, path);
90 if (ret != MEDIADEMUXER_ERROR_NONE) {
91 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", __FUNCTION__,
92 MEDIADEMUXER_ERROR_INVALID_PATH);
93 return MEDIADEMUXER_ERROR_INVALID_PATH;
97 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
98 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_PATH);
99 return MEDIADEMUXER_ERROR_INVALID_PATH;
101 if (handle->demux_state != MEDIADEMUXER_STATE_IDLE)
102 return MEDIADEMUXER_ERROR_INVALID_STATE;
103 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
104 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
105 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
111 int mediademuxer_prepare(mediademuxer_h demuxer)
113 MD_I("mediademuxer_prepare\n");
114 mediademuxer_error_e ret = MEDIADEMUXER_ERROR_NONE;
115 DEMUXER_INSTANCE_CHECK(demuxer);
116 mediademuxer_s *handle;
117 handle = (mediademuxer_s *)demuxer;
118 if (handle && handle->demux_state == MEDIADEMUXER_STATE_IDLE && handle->eos_cb != NULL) {
119 ret = md_prepare((MMHandleType)handle->md_handle);
120 if (ret != MEDIADEMUXER_ERROR_NONE) {
121 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
122 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
123 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
125 handle->demux_state = MEDIADEMUXER_STATE_READY;
128 if (handle->demux_state != MEDIADEMUXER_STATE_IDLE)
129 return MEDIADEMUXER_ERROR_INVALID_STATE;
130 if (handle->eos_cb == NULL)
131 MD_E("EOS callback is not set\n");
132 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
133 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
134 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
139 int mediademuxer_get_track_count(mediademuxer_h demuxer, int *count)
141 MD_I("mediademuxer_get_track_count\n");
142 mediademuxer_error_e ret;
143 DEMUXER_INSTANCE_CHECK(demuxer);
144 mediademuxer_s *handle;
145 handle = (mediademuxer_s *)demuxer;
146 if (handle && handle->demux_state == MEDIADEMUXER_STATE_READY) {
147 ret = md_get_track_count((MMHandleType)handle->md_handle, count);
148 if (ret != MEDIADEMUXER_ERROR_NONE) {
149 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
150 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
151 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
154 if (handle->demux_state != MEDIADEMUXER_STATE_READY)
155 return MEDIADEMUXER_ERROR_INVALID_STATE;
156 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
157 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
158 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
163 int mediademuxer_select_track(mediademuxer_h demuxer, int track_index)
165 MD_I("mediademuxer_select_track\n");
166 mediademuxer_error_e ret;
167 DEMUXER_INSTANCE_CHECK(demuxer);
168 mediademuxer_s *handle;
169 handle = (mediademuxer_s *)demuxer;
170 if (handle && handle->demux_state == MEDIADEMUXER_STATE_READY) {
171 ret = md_select_track((MMHandleType)handle->md_handle, track_index);
172 if (ret != MEDIADEMUXER_ERROR_NONE) {
173 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
174 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
175 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
178 if (handle->demux_state != MEDIADEMUXER_STATE_READY)
179 return MEDIADEMUXER_ERROR_INVALID_STATE;
180 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
181 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
182 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
187 int mediademuxer_start(mediademuxer_h demuxer)
189 MD_I("mediademuxer_start\n");
190 mediademuxer_error_e ret;
191 DEMUXER_INSTANCE_CHECK(demuxer);
192 mediademuxer_s *handle;
193 handle = (mediademuxer_s *)demuxer;
194 if (handle && handle->demux_state == MEDIADEMUXER_STATE_READY) {
195 ret = md_start((MMHandleType)handle->md_handle);
196 if (ret != MEDIADEMUXER_ERROR_NONE) {
197 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
198 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
199 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
201 handle->demux_state = MEDIADEMUXER_STATE_DEMUXING;
204 if (handle->demux_state != MEDIADEMUXER_STATE_READY)
205 return MEDIADEMUXER_ERROR_INVALID_STATE;
206 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
207 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
208 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
213 int mediademuxer_get_track_info(mediademuxer_h demuxer, int track_index,
214 media_format_h *format)
216 MD_I("mediademuxer_get_track_info\n");
217 mediademuxer_error_e ret;
218 DEMUXER_INSTANCE_CHECK(demuxer);
219 mediademuxer_s *handle;
220 handle = (mediademuxer_s *)demuxer;
221 if (track_index < 0 || format == NULL) {
222 MD_E("Invalid input parameters\n");
223 return MEDIADEMUXER_ERROR_INVALID_PARAMETER;
225 if (handle && (handle->demux_state == MEDIADEMUXER_STATE_READY
226 || handle->demux_state == MEDIADEMUXER_STATE_DEMUXING)) {
227 ret = md_get_track_info((MMHandleType)handle->md_handle, track_index, format);
228 if (ret != MEDIADEMUXER_ERROR_NONE) {
229 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
230 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
231 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
234 if (handle->demux_state != MEDIADEMUXER_STATE_READY)
235 return MEDIADEMUXER_ERROR_INVALID_STATE;
236 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
237 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
238 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
243 int mediademuxer_read_sample(mediademuxer_h demuxer, int track_index,
244 media_packet_h *outbuf)
246 MD_I("mediademuxer_read_sample\n");
247 mediademuxer_error_e ret;
248 DEMUXER_INSTANCE_CHECK(demuxer);
249 mediademuxer_s *handle;
250 handle = (mediademuxer_s *)demuxer;
251 if (outbuf == NULL || track_index < 0)
252 return MEDIADEMUXER_ERROR_INVALID_PARAMETER;
253 if (handle && handle->demux_state == MEDIADEMUXER_STATE_DEMUXING) {
254 ret = md_read_sample((MMHandleType)handle->md_handle, track_index, outbuf);
255 if (ret != MEDIADEMUXER_ERROR_NONE) {
256 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
257 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
258 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
261 if (handle->demux_state != MEDIADEMUXER_STATE_DEMUXING)
262 return MEDIADEMUXER_ERROR_INVALID_STATE;
263 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
264 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
265 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
270 int mediademuxer_seek(mediademuxer_h demuxer, int64_t pos)
272 MD_I("mediademuxer_seek\n");
273 mediademuxer_error_e ret;
274 DEMUXER_INSTANCE_CHECK(demuxer);
275 mediademuxer_s *handle;
276 handle = (mediademuxer_s *)demuxer;
277 if (handle && handle->demux_state == MEDIADEMUXER_STATE_DEMUXING) {
278 ret = md_seek((MMHandleType)handle->md_handle, pos);
279 if (ret != MEDIADEMUXER_ERROR_NONE) {
280 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
281 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
282 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
285 if (handle->demux_state != MEDIADEMUXER_STATE_DEMUXING)
286 return MEDIADEMUXER_ERROR_INVALID_STATE;
287 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
288 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
289 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
294 int mediademuxer_unselect_track(mediademuxer_h demuxer, int track_index)
296 MD_I("mediademuxer_unselect_track\n");
297 mediademuxer_error_e ret;
298 DEMUXER_INSTANCE_CHECK(demuxer);
299 mediademuxer_s *handle;
300 handle = (mediademuxer_s *)demuxer;
301 if (handle && (handle->demux_state == MEDIADEMUXER_STATE_READY
302 || handle->demux_state == MEDIADEMUXER_STATE_DEMUXING)) {
303 ret = md_unselect_track((MMHandleType)handle->md_handle, track_index);
304 if (ret != MEDIADEMUXER_ERROR_NONE) {
305 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
306 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
307 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
310 if (handle->demux_state != MEDIADEMUXER_STATE_READY)
311 return MEDIADEMUXER_ERROR_INVALID_STATE;
312 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
313 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
314 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
319 int mediademuxer_stop(mediademuxer_h demuxer)
321 MD_I("mediademuxer_stop\n");
322 mediademuxer_error_e ret;
323 DEMUXER_INSTANCE_CHECK(demuxer);
324 mediademuxer_s *handle;
325 handle = (mediademuxer_s *)demuxer;
326 if (handle && handle->demux_state == MEDIADEMUXER_STATE_DEMUXING) {
327 ret = md_stop((MMHandleType)handle->md_handle);
328 if (ret != MEDIADEMUXER_ERROR_NONE) {
329 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
330 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
331 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
333 handle->demux_state = MEDIADEMUXER_STATE_READY;
335 if (handle->demux_state != MEDIADEMUXER_STATE_DEMUXING)
336 return MEDIADEMUXER_ERROR_INVALID_STATE;
337 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
338 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
339 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
344 int mediademuxer_unprepare(mediademuxer_h demuxer)
346 MD_I("mediademuxer_unprepare\n");
347 mediademuxer_error_e ret;
348 DEMUXER_INSTANCE_CHECK(demuxer);
349 mediademuxer_s *handle;
350 handle = (mediademuxer_s *)demuxer;
351 if (handle && handle->demux_state == MEDIADEMUXER_STATE_READY) {
352 ret = md_unprepare((MMHandleType)handle->md_handle);
353 if (ret != MEDIADEMUXER_ERROR_NONE) {
354 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
355 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
356 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
358 handle->demux_state = MEDIADEMUXER_STATE_IDLE;
360 if (handle->demux_state != MEDIADEMUXER_STATE_READY)
361 return MEDIADEMUXER_ERROR_INVALID_STATE;
362 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
363 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
364 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
369 int mediademuxer_destroy(mediademuxer_h demuxer)
371 MD_I("mediademuxer_destroy\n");
372 mediademuxer_error_e ret;
373 DEMUXER_INSTANCE_CHECK(demuxer);
374 mediademuxer_s *handle;
375 handle = (mediademuxer_s *)demuxer;
376 if (handle && handle->demux_state == MEDIADEMUXER_STATE_IDLE) {
377 ret = md_destroy((MMHandleType)handle->md_handle);
378 if (ret != MEDIADEMUXER_ERROR_NONE) {
379 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
380 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
381 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
383 MD_E("[CoreAPI][%s] destroy handle : %p", __FUNCTION__, handle);
384 handle->demux_state = MEDIADEMUXER_STATE_NONE;
389 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
390 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
391 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
393 return MEDIADEMUXER_ERROR_NONE;
396 int mediademuxer_get_state(mediademuxer_h demuxer, mediademuxer_state *state)
398 mediademuxer_error_e ret = MEDIADEMUXER_ERROR_NONE;
399 DEMUXER_INSTANCE_CHECK(demuxer);
400 mediademuxer_s *handle = (mediademuxer_s *)demuxer;
402 *state = handle->demux_state;
404 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
405 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
406 ret = MEDIADEMUXER_ERROR_INVALID_OPERATION;
411 int mediademuxer_set_error_cb(mediademuxer_h demuxer,
412 mediademuxer_error_cb callback, void *user_data)
414 DEMUXER_INSTANCE_CHECK(demuxer);
415 mediademuxer_s *handle;
416 handle = (mediademuxer_s *)demuxer;
417 if (handle->demux_state != MEDIADEMUXER_STATE_IDLE)
418 return MEDIADEMUXER_ERROR_INVALID_STATE;
419 handle->error_cb = callback;
420 handle->error_cb_userdata = user_data;
421 MD_I("set error_cb(%p)", callback);
422 return MEDIADEMUXER_ERROR_NONE;
425 int mediademuxer_unset_error_cb(mediademuxer_h demuxer)
427 DEMUXER_INSTANCE_CHECK(demuxer);
428 mediademuxer_s *handle;
429 handle = (mediademuxer_s *)demuxer;
430 if (handle->demux_state != MEDIADEMUXER_STATE_IDLE)
431 return MEDIADEMUXER_ERROR_INVALID_STATE;
432 handle->error_cb = NULL;
433 handle->error_cb_userdata = NULL;
434 MD_I("mediademuxer_unset_error_cb\n");
435 return MEDIADEMUXER_ERROR_NONE;
438 static gboolean _mediademuxer_error_cb(mediademuxer_error_e error, void *user_data)
440 if (user_data == NULL) {
441 MD_I("_mediademuxer_error_cb: ERROR %d to report. But call back is not set\n", error);
444 mediademuxer_s * handle = (mediademuxer_s *)user_data;
445 if (handle->demux_state != MEDIADEMUXER_STATE_IDLE)
446 return MEDIADEMUXER_ERROR_INVALID_STATE;
447 if (handle->error_cb)
448 ((mediademuxer_error_cb)handle->error_cb)(error, handle->error_cb_userdata);
450 MD_I("_mediademuxer_error_cb: ERROR %d to report. But call back is not set\n", error);
454 int mediademuxer_set_eos_cb(mediademuxer_h demuxer,
455 mediademuxer_eos_cb callback, void *user_data)
457 DEMUXER_INSTANCE_CHECK(demuxer);
458 mediademuxer_s *handle;
459 handle = (mediademuxer_s *)demuxer;
460 if (handle->demux_state != MEDIADEMUXER_STATE_IDLE)
461 return MEDIADEMUXER_ERROR_INVALID_STATE;
462 handle->eos_cb = callback;
463 handle->eos_cb_userdata = user_data;
464 MD_I("set eos_cb(%p)", callback);
465 return MEDIADEMUXER_ERROR_NONE;
468 int mediademuxer_unset_eos_cb(mediademuxer_h demuxer)
470 DEMUXER_INSTANCE_CHECK(demuxer);
471 mediademuxer_s *handle;
472 handle = (mediademuxer_s *)demuxer;
473 if (handle->demux_state != MEDIADEMUXER_STATE_IDLE)
474 return MEDIADEMUXER_ERROR_INVALID_STATE;
475 handle->eos_cb = NULL;
476 handle->eos_cb_userdata = NULL;
477 MD_I("mediademuxer_unset_eos_cb\n");
478 return MEDIADEMUXER_ERROR_NONE;
481 static gboolean _mediademuxer_eos_cb(int track_num, void *user_data)
483 if (user_data == NULL) {
484 MD_I("_mediademuxer_eos_cb: EOS to report. But call back is not set\n");
487 mediademuxer_s *handle = (mediademuxer_s *)user_data;
488 if (handle->demux_state != MEDIADEMUXER_STATE_DEMUXING)
489 return MEDIADEMUXER_ERROR_INVALID_STATE;
491 ((mediademuxer_eos_cb)handle->eos_cb)(track_num, handle->eos_cb_userdata);
493 MD_I("_mediademuxer_eos_cb: EOS %d to report. But call back is not set\n", track_num);