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) {
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;
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;
138 int mediademuxer_get_track_count(mediademuxer_h demuxer, int *count)
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;
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;
162 int mediademuxer_select_track(mediademuxer_h demuxer, int track_index)
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;
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;
186 int mediademuxer_start(mediademuxer_h demuxer)
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;
200 handle->demux_state = MEDIADEMUXER_DEMUXING;
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;
211 int mediademuxer_get_track_info(mediademuxer_h demuxer, int track_index,
212 media_format_h *format)
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;
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;
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;
241 int mediademuxer_read_sample(mediademuxer_h demuxer, int track_index,
242 media_packet_h *outbuf)
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;
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;
268 int mediademuxer_seek(mediademuxer_h demuxer, int64_t pos)
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;
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;
292 int mediademuxer_unselect_track(mediademuxer_h demuxer, int track_index)
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;
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;
317 int mediademuxer_stop(mediademuxer_h demuxer)
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;
331 handle->demux_state = MEDIADEMUXER_READY;
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;
342 int mediademuxer_unprepare(mediademuxer_h demuxer)
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;
356 handle->demux_state = MEDIADEMUXER_IDLE;
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;
367 int mediademuxer_destroy(mediademuxer_h demuxer)
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;
381 MD_E("[CoreAPI][%s] destroy handle : %p", __FUNCTION__,
385 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
386 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
387 return MEDIADEMUXER_ERROR_INVALID_OPERATION;
389 handle->demux_state = MEDIADEMUXER_NONE;
390 return MEDIADEMUXER_ERROR_NONE;
393 int mediademuxer_get_state(mediademuxer_h demuxer, mediademuxer_state *state)
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);
400 *state = handle->demux_state;
402 MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)",
403 __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION);
404 ret = MEDIADEMUXER_ERROR_INVALID_OPERATION;
409 int mediademuxer_set_error_cb(mediademuxer_h demuxer,
410 mediademuxer_error_cb callback, void *user_data)
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;
423 int mediademuxer_unset_error_cb(mediademuxer_h demuxer)
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;
436 static gboolean _mediademuxer_error_cb(mediademuxer_error_e error, void *user_data)
438 if (user_data == NULL) {
439 MD_I("_mediademuxer_error_cb: ERROR %d to report. But call back is not set\n", error);
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);
448 MD_I("_mediademuxer_error_cb: ERROR %d to report. But call back is not set\n", error);
452 int mediademuxer_set_eos_cb(mediademuxer_h demuxer,
453 mediademuxer_eos_cb callback, void *user_data)
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;
466 int mediademuxer_unset_eos_cb(mediademuxer_h demuxer)
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;
479 static gboolean _mediademuxer_eos_cb(int track_num, void *user_data)
481 if (user_data == NULL) {
482 MD_I("_mediademuxer_eos_cb: EOS to report. But call back is not set\n");
485 mediademuxer_s *handle = (mediademuxer_s *)user_data;
486 if (handle->demux_state != MEDIADEMUXER_DEMUXING)
487 return MEDIADEMUXER_ERROR_INVALID_STATE;
489 ((mediademuxer_eos_cb)handle->eos_cb)(track_num, handle->eos_cb_userdata);
491 MD_I("_mediademuxer_eos_cb: EOS %d to report. But call back is not set\n", track_num);