2 * Copyright (c) 2011 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.
20 #include <media_codec.h>
21 #include <media_codec_private.h>
22 #include <media_codec_port.h>
23 #include <system_info.h>
27 #define MC_PREALLOCATED_HANDLE_ARRAY_SIZE 16
29 #ifdef USE_MM_RESOURCE_MANAGER
30 static mm_resource_manager_h g_mc_resource_manager;
31 static GPtrArray *g_mediacodec_handles;
32 static GMutex g_mediacodec_lock;
35 static gboolean __mediacodec_empty_buffer_cb(media_packet_h pkt, void *user_data);
36 static gboolean __mediacodec_fill_buffer_cb(media_packet_h pkt, void *user_data);
37 static gboolean __mediacodec_error_cb(mediacodec_error_e error, void *user_data);
38 static gboolean __mediacodec_eos_cb(void *user_data);
39 static gboolean __mediacodec_buffer_status_cb(mediacodec_status_e status, void *user_data);
40 #ifdef USE_MM_RESOURCE_MANAGER
41 static void __mediacodec_init_lib() __attribute__((constructor));
42 static void __mediacodec_deinit_lib() __attribute__((destructor));
43 static int __mediacodec_resource_release_cb(mm_resource_manager_h rm,
44 mm_resource_manager_res_h resource_h, void *user_data);
48 * Internal Implementation
50 int __convert_error_code(int code, char *func_name)
52 int ret = MEDIACODEC_ERROR_INVALID_OPERATION;
53 char *msg = "MEDIACOODEC_INVALID_OPERATION";
57 ret = MEDIACODEC_ERROR_NONE;
58 msg = "MEDIACODEC_ERROR_NONE";
62 ret = MEDIACODEC_ERROR_INVALID_PARAMETER;
63 msg = "MEDIACODEC_ERROR_INVALID_PARAMETER";
65 case MC_PERMISSION_DENIED:
66 ret = MEDIACODEC_ERROR_PERMISSION_DENIED;
67 msg = "MEDIACODEC_ERROR_PERMISSION_DENIED";
69 case MC_INVALID_STATUS:
70 ret = MEDIACODEC_ERROR_INVALID_STATE;
71 msg = "MEDIACODEC_ERROR_INVALID_STATE";
73 case MC_NOT_SUPPORTED:
74 ret = MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE;
75 msg = "MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE";
78 case MC_INTERNAL_ERROR:
80 ret = MEDIACODEC_ERROR_INVALID_OPERATION;
81 msg = "MEDIACODEC_ERROR_INVALID_OPERATION";
83 case MC_INVALID_STREAM:
84 ret = MEDIACODEC_ERROR_INVALID_STREAM;
85 msg = "MEDIACODEC_ERROR_INVALID_STREAM";
87 case MC_CODEC_NOT_FOUND:
88 ret = MEDIACODEC_ERROR_CODEC_NOT_FOUND;
89 msg = "MEDIACODEC_ERROR_CODEC_NOT_FOUND";
92 ret = MEDIACODEC_ERROR_DECODE;
93 msg = "MEDIACODEC_ERROR_DECODE";
95 case MC_INVALID_IN_BUF:
96 ret = MEDIACODEC_ERROR_INVALID_INBUFFER;
97 msg = "MEDIACODEC_ERROR_INVALID_INBUFFER";
99 case MC_INVALID_OUT_BUF:
100 ret = MEDIACODEC_ERROR_INVALID_OUTBUFFER;
101 msg = "MEDIACODEC_ERROR_INVALID_OUTBUFFER";
103 case MC_NOT_INITIALIZED:
104 ret = MEDIACODEC_ERROR_NOT_INITIALIZED;
105 msg = "MEDIACODEC_ERROR_NOT_INITIALIZED";
107 case MC_OUTPUT_BUFFER_EMPTY:
108 case MC_OUTPUT_BUFFER_OVERFLOW:
109 ret = MEDIACODEC_ERROR_BUFFER_NOT_AVAILABLE;
110 msg = "MEDIACODEC_ERROR_BUFFER_NOT_AVAILABLE";
112 case MC_OUT_OF_MEMORY:
113 ret = MEDIACODEC_ERROR_OUT_OF_MEMORY;
114 msg = "MEDIACODEC_ERROR_OUT_OF_MEMORY";
117 ret = MEDIACODEC_ERROR_INTERNAL;
118 msg = "MEDIACODEC_ERROR_INTERNAL";
121 LOGD("[%s] %s(0x%08x) : core fw error(0x%x)", func_name, msg, ret, code);
126 * Public Implementation
129 int mediacodec_create(mediacodec_h *mediacodec)
131 MEDIACODEC_INSTANCE_CHECK(mediacodec);
132 mediacodec_s *handle;
135 LOGD("mediacodec_create..");
137 #ifdef USE_MM_RESOURCE_MANAGER
138 g_mutex_lock(&g_mediacodec_lock);
140 if (!g_mc_resource_manager) {
141 int mm_ret = mm_resource_manager_create(MM_RESOURCE_MANAGER_APP_CLASS_MEDIA,
142 __mediacodec_resource_release_cb, NULL, &g_mc_resource_manager);
143 if (mm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
144 g_mutex_unlock(&g_mediacodec_lock);
145 LOGE("mm_resource_manager_create failed 0x%x", mm_ret);
146 return MEDIACODEC_ERROR_INTERNAL;
150 g_mutex_unlock(&g_mediacodec_lock);
153 handle = (mediacodec_s *)malloc(sizeof(mediacodec_s));
154 if (handle != NULL) {
155 memset(handle, 0 , sizeof(mediacodec_s));
157 LOGE("MEDIACODEC_ERROR_OUT_OF_MEMORY(0x%08x)", MEDIACODEC_ERROR_OUT_OF_MEMORY); //LCOV_EXCL_LINE
158 return MEDIACODEC_ERROR_OUT_OF_MEMORY;
161 ret = mc_create(&handle->mc_handle);
162 if (ret != MEDIACODEC_ERROR_NONE) {
163 LOGE("MEDIACODEC_ERROR_INVALID_OPERATION(0x%08x)", MEDIACODEC_ERROR_INVALID_OPERATION); //LCOV_EXCL_LINE
164 handle->state = MEDIACODEC_STATE_NONE;
165 g_free(handle->mc_handle);
168 return MEDIACODEC_ERROR_INVALID_OPERATION;
170 *mediacodec = (mediacodec_h)handle;
171 handle->state = MEDIACODEC_STATE_IDLE;
172 LOGD("new handle : %p", *mediacodec);
176 mc_set_empty_buffer_cb(handle->mc_handle, (mediacodec_input_buffer_used_cb)__mediacodec_empty_buffer_cb, handle);
177 mc_set_fill_buffer_cb(handle->mc_handle, (mediacodec_output_buffer_available_cb)__mediacodec_fill_buffer_cb, handle);
178 mc_set_error_cb(handle->mc_handle, (mediacodec_error_cb)__mediacodec_error_cb, handle);
179 mc_set_eos_cb(handle->mc_handle, (mediacodec_eos_cb)__mediacodec_eos_cb, handle);
180 mc_set_buffer_status_cb(handle->mc_handle, (mediacodec_buffer_status_cb)__mediacodec_buffer_status_cb, handle);
182 #ifdef USE_MM_RESOURCE_MANAGER
183 g_mutex_lock(&g_mediacodec_lock);
184 g_ptr_array_insert(g_mediacodec_handles, -1, *mediacodec);
185 g_mutex_unlock(&g_mediacodec_lock);
188 return MEDIACODEC_ERROR_NONE;
192 int mediacodec_destroy(mediacodec_h mediacodec)
194 LOGD("[%s] Start, handle to destroy : %p", __FUNCTION__, mediacodec);
195 MEDIACODEC_INSTANCE_CHECK(mediacodec);
196 mediacodec_s *handle = (mediacodec_s *)mediacodec;
198 int ret = mc_destroy(handle->mc_handle);
199 if (ret != MEDIACODEC_ERROR_NONE) {
200 LOGD("MEDIACODEC_ERROR_INVALID_OPERATION(0x%08x)", MEDIACODEC_ERROR_INVALID_OPERATION); //LCOV_EXCL_LINE
201 return MEDIACODEC_ERROR_INVALID_OPERATION;
203 #ifdef USE_MM_RESOURCE_MANAGER
204 g_mutex_lock(&g_mediacodec_lock);
205 g_ptr_array_remove_fast(g_mediacodec_handles, mediacodec);
206 g_mutex_unlock(&g_mediacodec_lock);
209 handle->state = MEDIACODEC_STATE_NONE;
212 return MEDIACODEC_ERROR_NONE;
216 int mediacodec_set_codec(mediacodec_h mediacodec, mediacodec_codec_type_e codec_id, int flags)
218 MEDIACODEC_INSTANCE_CHECK(mediacodec);
219 mediacodec_s *handle = (mediacodec_s *)mediacodec;
220 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
222 int ret = mc_set_codec(handle->mc_handle, codec_id, flags);
224 if (ret != MEDIACODEC_ERROR_NONE) {
225 return __convert_error_code(ret, (char *)__FUNCTION__);
227 handle->state = MEDIACODEC_STATE_IDLE;
228 return MEDIACODEC_ERROR_NONE;
232 int mediacodec_set_vdec_info(mediacodec_h mediacodec, int width, int height)
234 MEDIACODEC_INSTANCE_CHECK(mediacodec);
235 mediacodec_s *handle = (mediacodec_s *)mediacodec;
236 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
238 int ret = mc_set_vdec_info(handle->mc_handle, width, height);
240 if (ret != MEDIACODEC_ERROR_NONE) {
241 return __convert_error_code(ret, (char *)__FUNCTION__);
243 handle->state = MEDIACODEC_STATE_IDLE;
244 return MEDIACODEC_ERROR_NONE;
248 int mediacodec_set_venc_info(mediacodec_h mediacodec, int width, int height, int fps, int target_bits)
250 MEDIACODEC_INSTANCE_CHECK(mediacodec);
251 mediacodec_s *handle = (mediacodec_s *)mediacodec;
252 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
254 int ret = mc_set_venc_info(handle->mc_handle, width, height, fps, target_bits);
256 if (ret != MEDIACODEC_ERROR_NONE) {
257 return __convert_error_code(ret, (char *)__FUNCTION__);
259 handle->state = MEDIACODEC_STATE_IDLE;
260 return MEDIACODEC_ERROR_NONE;
264 int mediacodec_set_adec_info(mediacodec_h mediacodec, int samplerate, int channel, int bit)
266 MEDIACODEC_INSTANCE_CHECK(mediacodec);
267 mediacodec_s *handle = (mediacodec_s *)mediacodec;
268 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
270 int ret = mc_set_adec_info(handle->mc_handle, samplerate, channel, bit);
272 if (ret != MEDIACODEC_ERROR_NONE) {
273 return __convert_error_code(ret, (char *)__FUNCTION__);
275 handle->state = MEDIACODEC_STATE_IDLE;
276 return MEDIACODEC_ERROR_NONE;
280 int mediacodec_set_aenc_info(mediacodec_h mediacodec, int samplerate, int channel, int bit, int bitrate)
282 MEDIACODEC_INSTANCE_CHECK(mediacodec);
283 mediacodec_s *handle = (mediacodec_s *)mediacodec;
284 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
286 int ret = mc_set_aenc_info(handle->mc_handle, samplerate, channel, bit, bitrate);
288 if (ret != MEDIACODEC_ERROR_NONE) {
289 return __convert_error_code(ret, (char *)__FUNCTION__);
291 handle->state = MEDIACODEC_STATE_IDLE;
292 return MEDIACODEC_ERROR_NONE;
296 int mediacodec_configure_from_media_format(mediacodec_h mediacodec, media_format_h format, int flags)
298 MEDIACODEC_INSTANCE_CHECK(mediacodec);
299 mediacodec_s *handle = (mediacodec_s *)mediacodec;
300 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
302 int ret = mc_configure(handle->mc_handle, format, flags);
304 if (ret != MEDIACODEC_ERROR_NONE) {
305 return __convert_error_code(ret, (char *)__FUNCTION__);
307 handle->state = MEDIACODEC_STATE_IDLE;
308 return MEDIACODEC_ERROR_NONE;
312 int mediacodec_prepare(mediacodec_h mediacodec)
314 MEDIACODEC_INSTANCE_CHECK(mediacodec);
315 mediacodec_s *handle = (mediacodec_s *)mediacodec;
316 #ifdef USE_MM_RESOURCE_MANAGER
317 mc_handle_t *mc_handle = (mc_handle_t *) handle->mc_handle;
318 int rm_ret = MM_RESOURCE_MANAGER_ERROR_NONE;
319 mm_resource_manager_res_h resource;
321 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
323 #ifdef USE_MM_RESOURCE_MANAGER
324 if (mc_handle->is_hw && mc_handle->is_video) {
326 if (handle->codec_resource) {
327 LOGE("Codec resource is tried to be acquired twice\n"); //LCOV_EXCL_LINE
328 return MC_INTERNAL_ERROR;
333 * Currently volume of requested resource is set to 1. Default
334 * capacity for video encoder/decoder is 1 too. The actual capacity
335 * should be set in mmfw-sysconf > mmfw_resource_manager.ini.
336 * If different encode/decode operation needs different volume of
337 * video encoder/decoder, '1' in the following
338 * mm_resource_manager_mark_for_acquire function should be set to
339 * corresponding value.
340 * If that value depends on platform where it's executed,
341 * MM_RESOURCE_MANAGER_RES_TYPE_COND_* and
342 * mm_resource_manager_get_res_type_volume() can be used.
343 * Additional info can be found in doxygen comments of mm_resource_manager.h
346 rm_ret = mm_resource_manager_mark_for_acquire(g_mc_resource_manager,
347 mc_handle->is_encoder ?
348 MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_ENCODER :
349 MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_DECODER,
351 if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
352 LOGE("Failed to acquire resource manager %x", rm_ret);
354 case MM_RESOURCE_MANAGER_ERROR_NOT_SUPPORTED:
355 return MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE;
356 case MM_RESOURCE_MANAGER_ERROR_NOT_ENOUGH:
357 return MEDIACODEC_ERROR_RESOURCE_OVERLOADED;
359 return MEDIACODEC_ERROR_INTERNAL;
363 rm_ret = mm_resource_manager_commit(g_mc_resource_manager);
364 if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
365 mm_resource_manager_mark_for_release(g_mc_resource_manager, resource);
366 LOGE("Failed to commit resource manager : %x", rm_ret);
367 return MEDIACODEC_ERROR_INTERNAL;
369 handle->codec_resource = resource;
374 int ret = mc_prepare(handle->mc_handle);
376 if (ret != MEDIACODEC_ERROR_NONE) {
377 return __convert_error_code(ret, (char *)__FUNCTION__);
379 handle->state = MEDIACODEC_STATE_READY;
380 return MEDIACODEC_ERROR_NONE;
384 int mediacodec_unprepare(mediacodec_h mediacodec)
386 MEDIACODEC_INSTANCE_CHECK(mediacodec);
387 mediacodec_s *handle = (mediacodec_s *)mediacodec;
388 #ifdef USE_MM_RESOURCE_MANAGER
389 int rm_ret = MM_RESOURCE_MANAGER_ERROR_NONE;
392 int ret = mc_unprepare(handle->mc_handle);
394 if (ret != MEDIACODEC_ERROR_NONE) {
395 return __convert_error_code(ret, (char *)__FUNCTION__);
397 #ifdef USE_MM_RESOURCE_MANAGER
398 if (handle->codec_resource != NULL) {
400 mm_resource_manager_mark_for_release(g_mc_resource_manager,
401 handle->codec_resource);
402 handle->codec_resource = NULL;
403 rm_ret = mm_resource_manager_commit(g_mc_resource_manager);
404 if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
405 mm_resource_manager_mark_for_release(g_mc_resource_manager, handle->codec_resource);
407 case MM_RESOURCE_MANAGER_ERROR_LOW_PRIORITY:
408 return MEDIACODEC_ERROR_RESOURCE_OVERLOADED;
410 return MEDIACODEC_ERROR_INTERNAL;
415 LOGD("No codec resource to release. Probably resource release cb called\n");
419 handle->state = MEDIACODEC_STATE_IDLE;
420 return MEDIACODEC_ERROR_NONE;
424 int mediacodec_process_input(mediacodec_h mediacodec, media_packet_h inbuf, uint64_t timeOutUs)
426 MEDIACODEC_INSTANCE_CHECK(mediacodec);
427 mediacodec_s *handle = (mediacodec_s *)mediacodec;
428 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_READY);
430 int ret = mc_process_input(handle->mc_handle, inbuf, timeOutUs);
432 if (ret != MEDIACODEC_ERROR_NONE)
433 return __convert_error_code(ret, (char *)__FUNCTION__);
435 return MEDIACODEC_ERROR_NONE;
438 int mediacodec_get_output(mediacodec_h mediacodec, media_packet_h *outbuf, uint64_t timeOutUs)
440 MEDIACODEC_INSTANCE_CHECK(mediacodec);
441 mediacodec_s *handle = (mediacodec_s *)mediacodec;
442 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_READY);
444 int ret = mc_get_output(handle->mc_handle, outbuf, timeOutUs);
446 if (ret != MEDIACODEC_ERROR_NONE)
447 return __convert_error_code(ret, (char *)__FUNCTION__);
449 return MEDIACODEC_ERROR_NONE;
452 int mediacodec_flush_buffers(mediacodec_h mediacodec)
454 MEDIACODEC_INSTANCE_CHECK(mediacodec);
455 mediacodec_s *handle = (mediacodec_s *)mediacodec;
457 int ret = mc_flush_buffers(handle->mc_handle);
459 if (ret != MEDIACODEC_ERROR_NONE)
460 return __convert_error_code(ret, (char *)__FUNCTION__);
462 return MEDIACODEC_ERROR_NONE;
465 int mediacodec_get_supported_type(mediacodec_h mediacodec, mediacodec_codec_type_e codec_type, bool encoder, int *support_type)
467 MEDIACODEC_INSTANCE_CHECK(mediacodec);
468 mediacodec_s *handle = (mediacodec_s *)mediacodec;
469 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
471 int ret = mc_get_supported_type(handle->mc_handle, codec_type, encoder, support_type);
473 if (ret != MEDIACODEC_ERROR_NONE)
474 return __convert_error_code(ret, (char *)__FUNCTION__);
476 handle->state = MEDIACODEC_STATE_IDLE;
478 return MEDIACODEC_ERROR_NONE;
481 int mediacodec_set_input_buffer_used_cb(mediacodec_h mediacodec, mediacodec_input_buffer_used_cb callback, void *user_data)
483 MEDIACODEC_INSTANCE_CHECK(mediacodec);
484 mediacodec_s *handle = (mediacodec_s *)mediacodec;
485 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
487 handle->empty_buffer_cb = callback;
488 handle->empty_buffer_cb_userdata = user_data;
490 LOGD("set empty_buffer_cb(%p)", callback);
492 return MEDIACODEC_ERROR_NONE;
495 int mediacodec_unset_input_buffer_used_cb(mediacodec_h mediacodec)
497 MEDIACODEC_INSTANCE_CHECK(mediacodec);
498 mediacodec_s *handle = (mediacodec_s *)mediacodec;
500 handle->empty_buffer_cb = NULL;
501 handle->empty_buffer_cb_userdata = NULL;
503 return MEDIACODEC_ERROR_NONE;
507 int mediacodec_set_output_buffer_available_cb(mediacodec_h mediacodec, mediacodec_output_buffer_available_cb callback, void *user_data)
509 MEDIACODEC_INSTANCE_CHECK(mediacodec);
510 mediacodec_s *handle = (mediacodec_s *)mediacodec;
511 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
513 handle->fill_buffer_cb = callback;
514 handle->fill_buffer_cb_userdata = user_data;
516 LOGD("set fill_buffer_cb(%p)", callback);
518 return MEDIACODEC_ERROR_NONE;
522 int mediacodec_unset_output_buffer_available_cb(mediacodec_h mediacodec)
524 MEDIACODEC_INSTANCE_CHECK(mediacodec);
525 mediacodec_s *handle = (mediacodec_s *)mediacodec;
527 handle->fill_buffer_cb = NULL;
528 handle->fill_buffer_cb_userdata = NULL;
530 return MEDIACODEC_ERROR_NONE;
533 int mediacodec_set_error_cb(mediacodec_h mediacodec, mediacodec_error_cb callback, void *user_data)
535 MEDIACODEC_INSTANCE_CHECK(mediacodec);
536 mediacodec_s *handle = (mediacodec_s *)mediacodec;
537 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
539 handle->error_cb = callback;
540 handle->error_cb_userdata = user_data;
542 LOGD("set error_cb(%p)", callback);
544 return MEDIACODEC_ERROR_NONE;
548 int mediacodec_unset_error_cb(mediacodec_h mediacodec)
550 MEDIACODEC_INSTANCE_CHECK(mediacodec);
551 mediacodec_s *handle = (mediacodec_s *)mediacodec;
553 handle->error_cb = NULL;
554 handle->error_cb_userdata = NULL;
556 return MEDIACODEC_ERROR_NONE;
559 int mediacodec_set_eos_cb(mediacodec_h mediacodec, mediacodec_eos_cb callback, void *user_data)
561 MEDIACODEC_INSTANCE_CHECK(mediacodec);
562 mediacodec_s *handle = (mediacodec_s *)mediacodec;
563 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
565 handle->eos_cb = callback;
566 handle->eos_cb_userdata = user_data;
568 LOGD("set eos_cb(%p)", callback);
570 return MEDIACODEC_ERROR_NONE;
574 int mediacodec_unset_eos_cb(mediacodec_h mediacodec)
576 MEDIACODEC_INSTANCE_CHECK(mediacodec);
577 mediacodec_s *handle = (mediacodec_s *)mediacodec;
579 handle->eos_cb = NULL;
580 handle->eos_cb_userdata = NULL;
582 return MEDIACODEC_ERROR_NONE;
585 int mediacodec_set_buffer_status_cb(mediacodec_h mediacodec, mediacodec_buffer_status_cb callback, void *user_data)
587 MEDIACODEC_INSTANCE_CHECK(mediacodec);
588 mediacodec_s *handle = (mediacodec_s *)mediacodec;
589 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
591 handle->buffer_status_cb = callback;
592 handle->buffer_status_cb_userdata = user_data;
594 LOGD("set buffer_status_cb(%p)", callback);
596 return MEDIACODEC_ERROR_NONE;
600 int mediacodec_unset_buffer_status_cb(mediacodec_h mediacodec)
602 MEDIACODEC_INSTANCE_CHECK(mediacodec);
603 mediacodec_s *handle = (mediacodec_s *)mediacodec;
605 handle->buffer_status_cb = NULL;
606 handle->buffer_status_cb_userdata = NULL;
608 return MEDIACODEC_ERROR_NONE;
611 int mediacodec_foreach_supported_codec(mediacodec_h mediacodec, mediacodec_supported_codec_cb callback, void *user_data)
613 MEDIACODEC_INSTANCE_CHECK(mediacodec);
614 mediacodec_s *handle = (mediacodec_s *)mediacodec;
616 handle->supported_codec_cb = callback;
617 handle->supported_codec_cb_userdata = user_data;
619 LOGD("set supported_codec_cb(%p)", callback);
620 int ret = _mediacodec_foreach_supported_codec(callback, handle);
622 if (ret != MEDIACODEC_ERROR_NONE)
623 return __convert_error_code(ret, (char *)__FUNCTION__);
625 return MEDIACODEC_ERROR_NONE;
627 return MEDIACODEC_ERROR_NONE;
631 int mediacodec_get_packet_pool(mediacodec_h mediacodec, media_packet_pool_h *pkt_pool)
633 MEDIACODEC_INSTANCE_CHECK(mediacodec);
634 mediacodec_s *handle = (mediacodec_s *)mediacodec;
635 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_READY);
636 int ret = mc_get_packet_pool(handle->mc_handle, pkt_pool);
638 if (ret != MEDIACODEC_ERROR_NONE)
639 return MEDIACODEC_ERROR_INVALID_OPERATION;
641 return MEDIACODEC_ERROR_NONE;
644 static gboolean __mediacodec_empty_buffer_cb(media_packet_h pkt, void *user_data)
646 if (user_data == NULL || pkt == NULL)
649 mediacodec_s *handle = (mediacodec_s *)user_data;
651 if (handle->empty_buffer_cb)
652 ((mediacodec_input_buffer_used_cb)handle->empty_buffer_cb)(pkt, handle->empty_buffer_cb_userdata);
657 static gboolean __mediacodec_fill_buffer_cb(media_packet_h pkt, void *user_data)
659 if (user_data == NULL || pkt == NULL)
662 mediacodec_s *handle = (mediacodec_s *)user_data;
664 if (handle->fill_buffer_cb)
665 ((mediacodec_output_buffer_available_cb)handle->fill_buffer_cb)(pkt, handle->fill_buffer_cb_userdata);
670 static gboolean __mediacodec_error_cb(mediacodec_error_e error, void *user_data)
672 if (user_data == NULL)
675 mediacodec_s *handle = (mediacodec_s *)user_data;
677 if (handle->error_cb)
678 ((mediacodec_error_cb)handle->error_cb)(error, handle->error_cb_userdata);
683 static gboolean __mediacodec_eos_cb(void *user_data)
685 if (user_data == NULL)
688 mediacodec_s *handle = (mediacodec_s *)user_data;
691 ((mediacodec_eos_cb)handle->eos_cb)(handle->eos_cb_userdata);
696 static gboolean __mediacodec_buffer_status_cb(mediacodec_status_e status, void *user_data)
698 if (user_data == NULL)
701 mediacodec_s *handle = (mediacodec_s *)user_data;
703 if (handle->buffer_status_cb)
704 ((mediacodec_buffer_status_cb)handle->buffer_status_cb)(status, handle->buffer_status_cb_userdata);
709 #ifdef USE_MM_RESOURCE_MANAGER
711 static int __mediacodec_resource_release_cb(mm_resource_manager_h rm,
712 mm_resource_manager_res_h resource_h, void *user_data)
715 mediacodec_s *handle;
717 g_mutex_lock(&g_mediacodec_lock);
718 for (i = 0; i < g_mediacodec_handles->len; i++) {
719 handle = g_ptr_array_index(g_mediacodec_handles, i);
720 if (handle->codec_resource == resource_h) {
723 * The resource release cb is asynchronous, so mediacodec_unprepare might be
724 * called in this thread and in the main thread at the same time.
725 * Mutex lock/unlock should be added in the body of mediacodec_unprepare() to
726 * avoid the race condition.
728 handle->codec_resource = NULL;
729 mediacodec_unprepare((mediacodec_h)handle);
730 __mediacodec_error_cb(MEDIACODEC_ERROR_RESOURCE_CONFLICT, handle);
734 g_mutex_unlock(&g_mediacodec_lock);
741 static void __mediacodec_init_lib()
745 g_mutex_init(&g_mediacodec_lock);
746 g_mediacodec_handles = g_ptr_array_sized_new(MC_PREALLOCATED_HANDLE_ARRAY_SIZE);
751 static void __mediacodec_deinit_lib()
755 if (g_mc_resource_manager != NULL)
756 mm_resource_manager_destroy(g_mc_resource_manager);
758 g_ptr_array_unref(g_mediacodec_handles);
759 g_mutex_clear(&g_mediacodec_lock);