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_supported_codec_cb(mediacodec_codec_type_e codec_type, void *user_data);
40 static gboolean __mediacodec_buffer_status_cb(mediacodec_status_e status, void *user_data);
41 #ifdef USE_MM_RESOURCE_MANAGER
42 static void __mediacodec_init_lib() __attribute__((constructor));
43 static void __mediacodec_deinit_lib() __attribute__((destructor));
44 static int __mediacodec_resource_release_cb(mm_resource_manager_h rm,
45 mm_resource_manager_res_h resource_h, void *user_data);
49 * Internal Implementation
51 int __convert_error_code(int code, char *func_name)
53 int ret = MEDIACODEC_ERROR_INVALID_OPERATION;
54 char *msg = "MEDIACOODEC_INVALID_OPERATION";
58 ret = MEDIACODEC_ERROR_NONE;
59 msg = "MEDIACODEC_ERROR_NONE";
63 ret = MEDIACODEC_ERROR_INVALID_PARAMETER;
64 msg = "MEDIACODEC_ERROR_INVALID_PARAMETER";
66 case MC_PERMISSION_DENIED:
67 ret = MEDIACODEC_ERROR_PERMISSION_DENIED;
68 msg = "MEDIACODEC_ERROR_PERMISSION_DENIED";
70 case MC_INVALID_STATUS:
71 ret = MEDIACODEC_ERROR_INVALID_STATE;
72 msg = "MEDIACODEC_ERROR_INVALID_STATE";
74 case MC_NOT_SUPPORTED:
75 ret = MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE;
76 msg = "MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE";
79 case MC_INTERNAL_ERROR:
81 ret = MEDIACODEC_ERROR_INVALID_OPERATION;
82 msg = "MEDIACODEC_ERROR_INVALID_OPERATION";
84 case MC_INVALID_STREAM:
85 ret = MEDIACODEC_ERROR_INVALID_STREAM;
86 msg = "MEDIACODEC_ERROR_INVALID_STREAM";
88 case MC_CODEC_NOT_FOUND:
89 ret = MEDIACODEC_ERROR_CODEC_NOT_FOUND;
90 msg = "MEDIACODEC_ERROR_CODEC_NOT_FOUND";
93 ret = MEDIACODEC_ERROR_DECODE;
94 msg = "MEDIACODEC_ERROR_DECODE";
96 case MC_INVALID_IN_BUF:
97 ret = MEDIACODEC_ERROR_INVALID_INBUFFER;
98 msg = "MEDIACODEC_ERROR_INVALID_INBUFFER";
100 case MC_INVALID_OUT_BUF:
101 ret = MEDIACODEC_ERROR_INVALID_OUTBUFFER;
102 msg = "MEDIACODEC_ERROR_INVALID_OUTBUFFER";
104 case MC_NOT_INITIALIZED:
105 ret = MEDIACODEC_ERROR_NOT_INITIALIZED;
106 msg = "MEDIACODEC_ERROR_NOT_INITIALIZED";
108 case MC_OUTPUT_BUFFER_EMPTY:
109 case MC_OUTPUT_BUFFER_OVERFLOW:
110 ret = MEDIACODEC_ERROR_BUFFER_NOT_AVAILABLE;
111 msg = "MEDIACODEC_ERROR_BUFFER_NOT_AVAILABLE";
113 case MC_OUT_OF_MEMORY:
114 ret = MEDIACODEC_ERROR_OUT_OF_MEMORY;
115 msg = "MEDIACODEC_ERROR_OUT_OF_MEMORY";
118 ret = MEDIACODEC_ERROR_INTERNAL;
119 msg = "MEDIACODEC_ERROR_INTERNAL";
122 LOGD("[%s] %s(0x%08x) : core fw error(0x%x)", func_name, msg, ret, code);
127 * Public Implementation
130 int mediacodec_create(mediacodec_h *mediacodec)
132 MEDIACODEC_INSTANCE_CHECK(mediacodec);
133 mediacodec_s *handle;
136 LOGD("mediacodec_create..");
138 #ifdef USE_MM_RESOURCE_MANAGER
139 g_mutex_lock(&g_mediacodec_lock);
141 if (!g_mc_resource_manager) {
142 int mm_ret = mm_resource_manager_create(MM_RESOURCE_MANAGER_APP_CLASS_MEDIA,
143 __mediacodec_resource_release_cb, NULL, &g_mc_resource_manager);
144 if (mm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
145 g_mutex_unlock(&g_mediacodec_lock);
146 LOGE("mm_resource_manager_create failed 0x%x", mm_ret);
147 return MEDIACODEC_ERROR_INTERNAL;
151 g_mutex_unlock(&g_mediacodec_lock);
154 handle = (mediacodec_s *)malloc(sizeof(mediacodec_s));
155 if (handle != NULL) {
156 memset(handle, 0 , sizeof(mediacodec_s));
158 LOGE("MEDIACODEC_ERROR_OUT_OF_MEMORY(0x%08x)", MEDIACODEC_ERROR_OUT_OF_MEMORY); //LCOV_EXCL_LINE
159 return MEDIACODEC_ERROR_OUT_OF_MEMORY;
162 ret = mc_create(&handle->mc_handle);
163 if (ret != MEDIACODEC_ERROR_NONE) {
164 LOGE("MEDIACODEC_ERROR_INVALID_OPERATION(0x%08x)", MEDIACODEC_ERROR_INVALID_OPERATION); //LCOV_EXCL_LINE
165 handle->state = MEDIACODEC_STATE_NONE;
166 g_free(handle->mc_handle);
169 return MEDIACODEC_ERROR_INVALID_OPERATION;
171 *mediacodec = (mediacodec_h)handle;
172 handle->state = MEDIACODEC_STATE_IDLE;
173 LOGD("new handle : %p", *mediacodec);
177 mc_set_empty_buffer_cb(handle->mc_handle, (mediacodec_input_buffer_used_cb)__mediacodec_empty_buffer_cb, handle);
178 mc_set_fill_buffer_cb(handle->mc_handle, (mediacodec_output_buffer_available_cb)__mediacodec_fill_buffer_cb, handle);
179 mc_set_error_cb(handle->mc_handle, (mediacodec_error_cb)__mediacodec_error_cb, handle);
180 mc_set_eos_cb(handle->mc_handle, (mediacodec_eos_cb)__mediacodec_eos_cb, handle);
181 mc_set_buffer_status_cb(handle->mc_handle, (mediacodec_buffer_status_cb)__mediacodec_buffer_status_cb, handle);
182 mc_set_supported_codec_cb(handle->mc_handle, (mediacodec_supported_codec_cb)__mediacodec_supported_codec_cb, handle);
184 #ifdef USE_MM_RESOURCE_MANAGER
185 g_mutex_lock(&g_mediacodec_lock);
186 g_ptr_array_insert(g_mediacodec_handles, -1, *mediacodec);
187 g_mutex_unlock(&g_mediacodec_lock);
190 return MEDIACODEC_ERROR_NONE;
194 int mediacodec_destroy(mediacodec_h mediacodec)
196 LOGD("[%s] Start, handle to destroy : %p", __FUNCTION__, mediacodec);
197 MEDIACODEC_INSTANCE_CHECK(mediacodec);
198 mediacodec_s *handle = (mediacodec_s *)mediacodec;
200 int ret = mc_destroy(handle->mc_handle);
201 if (ret != MEDIACODEC_ERROR_NONE) {
202 LOGD("MEDIACODEC_ERROR_INVALID_OPERATION(0x%08x)", MEDIACODEC_ERROR_INVALID_OPERATION); //LCOV_EXCL_LINE
203 return MEDIACODEC_ERROR_INVALID_OPERATION;
205 #ifdef USE_MM_RESOURCE_MANAGER
206 g_mutex_lock(&g_mediacodec_lock);
207 g_ptr_array_remove_fast(g_mediacodec_handles, mediacodec);
208 g_mutex_unlock(&g_mediacodec_lock);
211 handle->state = MEDIACODEC_STATE_NONE;
214 return MEDIACODEC_ERROR_NONE;
218 int mediacodec_set_codec(mediacodec_h mediacodec, mediacodec_codec_type_e codec_id, int flags)
220 MEDIACODEC_INSTANCE_CHECK(mediacodec);
221 mediacodec_s *handle = (mediacodec_s *)mediacodec;
222 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
224 int ret = mc_set_codec(handle->mc_handle, codec_id, flags);
226 if (ret != MEDIACODEC_ERROR_NONE) {
227 return __convert_error_code(ret, (char *)__FUNCTION__);
229 handle->state = MEDIACODEC_STATE_IDLE;
230 return MEDIACODEC_ERROR_NONE;
234 int mediacodec_set_vdec_info(mediacodec_h mediacodec, int width, int height)
236 MEDIACODEC_INSTANCE_CHECK(mediacodec);
237 mediacodec_s *handle = (mediacodec_s *)mediacodec;
238 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
240 int ret = mc_set_vdec_info(handle->mc_handle, width, height);
242 if (ret != MEDIACODEC_ERROR_NONE) {
243 return __convert_error_code(ret, (char *)__FUNCTION__);
245 handle->state = MEDIACODEC_STATE_IDLE;
246 return MEDIACODEC_ERROR_NONE;
250 int mediacodec_set_venc_info(mediacodec_h mediacodec, int width, int height, int fps, int target_bits)
252 MEDIACODEC_INSTANCE_CHECK(mediacodec);
253 mediacodec_s *handle = (mediacodec_s *)mediacodec;
254 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
256 int ret = mc_set_venc_info(handle->mc_handle, width, height, fps, target_bits);
258 if (ret != MEDIACODEC_ERROR_NONE) {
259 return __convert_error_code(ret, (char *)__FUNCTION__);
261 handle->state = MEDIACODEC_STATE_IDLE;
262 return MEDIACODEC_ERROR_NONE;
266 int mediacodec_set_adec_info(mediacodec_h mediacodec, int samplerate, int channel, int bit)
268 MEDIACODEC_INSTANCE_CHECK(mediacodec);
269 mediacodec_s *handle = (mediacodec_s *)mediacodec;
270 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
272 int ret = mc_set_adec_info(handle->mc_handle, samplerate, channel, bit);
274 if (ret != MEDIACODEC_ERROR_NONE) {
275 return __convert_error_code(ret, (char *)__FUNCTION__);
277 handle->state = MEDIACODEC_STATE_IDLE;
278 return MEDIACODEC_ERROR_NONE;
282 int mediacodec_set_aenc_info(mediacodec_h mediacodec, int samplerate, int channel, int bit, int bitrate)
284 MEDIACODEC_INSTANCE_CHECK(mediacodec);
285 mediacodec_s *handle = (mediacodec_s *)mediacodec;
286 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
288 int ret = mc_set_aenc_info(handle->mc_handle, samplerate, channel, bit, bitrate);
290 if (ret != MEDIACODEC_ERROR_NONE) {
291 return __convert_error_code(ret, (char *)__FUNCTION__);
293 handle->state = MEDIACODEC_STATE_IDLE;
294 return MEDIACODEC_ERROR_NONE;
298 int mediacodec_configure_from_media_format(mediacodec_h mediacodec, media_format_h format, int flags)
300 MEDIACODEC_INSTANCE_CHECK(mediacodec);
301 mediacodec_s *handle = (mediacodec_s *)mediacodec;
302 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
304 int ret = mc_configure(handle->mc_handle, format, flags);
306 if (ret != MEDIACODEC_ERROR_NONE) {
307 return __convert_error_code(ret, (char *)__FUNCTION__);
309 handle->state = MEDIACODEC_STATE_IDLE;
310 return MEDIACODEC_ERROR_NONE;
314 int mediacodec_prepare(mediacodec_h mediacodec)
316 MEDIACODEC_INSTANCE_CHECK(mediacodec);
317 mediacodec_s *handle = (mediacodec_s *)mediacodec;
318 #ifdef USE_MM_RESOURCE_MANAGER
319 mc_handle_t *mc_handle = (mc_handle_t *) handle->mc_handle;
320 int rm_ret = MM_RESOURCE_MANAGER_ERROR_NONE;
321 mm_resource_manager_res_h resource;
323 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
325 #ifdef USE_MM_RESOURCE_MANAGER
326 if (mc_handle->is_hw && mc_handle->is_video) {
328 if (handle->codec_resource) {
329 LOGE("Codec resource is tried to be acquired twice\n"); //LCOV_EXCL_LINE
330 return MC_INTERNAL_ERROR;
335 * Currently volume of requested resource is set to 1. Default
336 * capacity for video encoder/decoder is 1 too. The actual capacity
337 * should be set in mmfw-sysconf > mmfw_resource_manager.ini.
338 * If different encode/decode operation needs different volume of
339 * video encoder/decoder, '1' in the following
340 * mm_resource_manager_mark_for_acquire function should be set to
341 * corresponding value.
342 * If that value depends on platform where it's executed,
343 * MM_RESOURCE_MANAGER_RES_TYPE_COND_* and
344 * mm_resource_manager_get_res_type_volume() can be used.
345 * Additional info can be found in doxygen comments of mm_resource_manager.h
348 rm_ret = mm_resource_manager_mark_for_acquire(g_mc_resource_manager,
349 mc_handle->is_encoder ?
350 MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_ENCODER :
351 MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_DECODER,
353 if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
354 LOGE("Failed to acquire resource manager %x", rm_ret);
356 case MM_RESOURCE_MANAGER_ERROR_NOT_SUPPORTED:
357 return MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE;
358 case MM_RESOURCE_MANAGER_ERROR_NOT_ENOUGH:
359 return MEDIACODEC_ERROR_RESOURCE_OVERLOADED;
361 return MEDIACODEC_ERROR_INTERNAL;
365 rm_ret = mm_resource_manager_commit(g_mc_resource_manager);
366 if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
367 mm_resource_manager_mark_for_release(g_mc_resource_manager, resource);
368 LOGE("Failed to commit resource manager : %x", rm_ret);
369 return MEDIACODEC_ERROR_INTERNAL;
371 handle->codec_resource = resource;
376 int ret = mc_prepare(handle->mc_handle);
378 if (ret != MEDIACODEC_ERROR_NONE) {
379 return __convert_error_code(ret, (char *)__FUNCTION__);
381 handle->state = MEDIACODEC_STATE_READY;
382 return MEDIACODEC_ERROR_NONE;
386 int mediacodec_unprepare(mediacodec_h mediacodec)
388 MEDIACODEC_INSTANCE_CHECK(mediacodec);
389 mediacodec_s *handle = (mediacodec_s *)mediacodec;
390 #ifdef USE_MM_RESOURCE_MANAGER
391 int rm_ret = MM_RESOURCE_MANAGER_ERROR_NONE;
394 int ret = mc_unprepare(handle->mc_handle);
396 if (ret != MEDIACODEC_ERROR_NONE) {
397 return __convert_error_code(ret, (char *)__FUNCTION__);
399 #ifdef USE_MM_RESOURCE_MANAGER
400 if (handle->codec_resource != NULL) {
402 mm_resource_manager_mark_for_release(g_mc_resource_manager,
403 handle->codec_resource);
404 handle->codec_resource = NULL;
405 rm_ret = mm_resource_manager_commit(g_mc_resource_manager);
406 if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
407 mm_resource_manager_mark_for_release(g_mc_resource_manager, handle->codec_resource);
409 case MM_RESOURCE_MANAGER_ERROR_LOW_PRIORITY:
410 return MEDIACODEC_ERROR_RESOURCE_OVERLOADED;
412 return MEDIACODEC_ERROR_INTERNAL;
417 LOGD("No codec resource to release. Probably resource release cb called\n");
421 handle->state = MEDIACODEC_STATE_IDLE;
422 return MEDIACODEC_ERROR_NONE;
426 int mediacodec_process_input(mediacodec_h mediacodec, media_packet_h inbuf, uint64_t timeOutUs)
428 MEDIACODEC_INSTANCE_CHECK(mediacodec);
429 mediacodec_s *handle = (mediacodec_s *)mediacodec;
430 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_READY);
432 int ret = mc_process_input(handle->mc_handle, inbuf, timeOutUs);
434 if (ret != MEDIACODEC_ERROR_NONE)
435 return __convert_error_code(ret, (char *)__FUNCTION__);
437 return MEDIACODEC_ERROR_NONE;
440 int mediacodec_get_output(mediacodec_h mediacodec, media_packet_h *outbuf, uint64_t timeOutUs)
442 MEDIACODEC_INSTANCE_CHECK(mediacodec);
443 mediacodec_s *handle = (mediacodec_s *)mediacodec;
444 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_READY);
446 int ret = mc_get_output(handle->mc_handle, outbuf, timeOutUs);
448 if (ret != MEDIACODEC_ERROR_NONE)
449 return __convert_error_code(ret, (char *)__FUNCTION__);
451 return MEDIACODEC_ERROR_NONE;
454 int mediacodec_flush_buffers(mediacodec_h mediacodec)
456 MEDIACODEC_INSTANCE_CHECK(mediacodec);
457 mediacodec_s *handle = (mediacodec_s *)mediacodec;
459 int ret = mc_flush_buffers(handle->mc_handle);
461 if (ret != MEDIACODEC_ERROR_NONE)
462 return __convert_error_code(ret, (char *)__FUNCTION__);
464 return MEDIACODEC_ERROR_NONE;
467 int mediacodec_get_supported_type(mediacodec_h mediacodec, mediacodec_codec_type_e codec_type, bool encoder, int *support_type)
469 MEDIACODEC_INSTANCE_CHECK(mediacodec);
470 mediacodec_s *handle = (mediacodec_s *)mediacodec;
471 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
473 int ret = mc_get_supported_type(handle->mc_handle, codec_type, encoder, support_type);
475 if (ret != MEDIACODEC_ERROR_NONE)
476 return __convert_error_code(ret, (char *)__FUNCTION__);
478 handle->state = MEDIACODEC_STATE_IDLE;
480 return MEDIACODEC_ERROR_NONE;
483 int mediacodec_set_input_buffer_used_cb(mediacodec_h mediacodec, mediacodec_input_buffer_used_cb callback, void *user_data)
485 MEDIACODEC_INSTANCE_CHECK(mediacodec);
486 mediacodec_s *handle = (mediacodec_s *)mediacodec;
487 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
489 handle->empty_buffer_cb = callback;
490 handle->empty_buffer_cb_userdata = user_data;
492 LOGD("set empty_buffer_cb(%p)", callback);
494 return MEDIACODEC_ERROR_NONE;
497 int mediacodec_unset_input_buffer_used_cb(mediacodec_h mediacodec)
499 MEDIACODEC_INSTANCE_CHECK(mediacodec);
500 mediacodec_s *handle = (mediacodec_s *)mediacodec;
502 handle->empty_buffer_cb = NULL;
503 handle->empty_buffer_cb_userdata = NULL;
505 return MEDIACODEC_ERROR_NONE;
509 int mediacodec_set_output_buffer_available_cb(mediacodec_h mediacodec, mediacodec_output_buffer_available_cb callback, void *user_data)
511 MEDIACODEC_INSTANCE_CHECK(mediacodec);
512 mediacodec_s *handle = (mediacodec_s *)mediacodec;
513 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
515 handle->fill_buffer_cb = callback;
516 handle->fill_buffer_cb_userdata = user_data;
518 LOGD("set fill_buffer_cb(%p)", callback);
520 return MEDIACODEC_ERROR_NONE;
524 int mediacodec_unset_output_buffer_available_cb(mediacodec_h mediacodec)
526 MEDIACODEC_INSTANCE_CHECK(mediacodec);
527 mediacodec_s *handle = (mediacodec_s *)mediacodec;
529 handle->fill_buffer_cb = NULL;
530 handle->fill_buffer_cb_userdata = NULL;
532 return MEDIACODEC_ERROR_NONE;
535 int mediacodec_set_error_cb(mediacodec_h mediacodec, mediacodec_error_cb callback, void *user_data)
537 MEDIACODEC_INSTANCE_CHECK(mediacodec);
538 mediacodec_s *handle = (mediacodec_s *)mediacodec;
539 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
541 handle->error_cb = callback;
542 handle->error_cb_userdata = user_data;
544 LOGD("set error_cb(%p)", callback);
546 return MEDIACODEC_ERROR_NONE;
550 int mediacodec_unset_error_cb(mediacodec_h mediacodec)
552 MEDIACODEC_INSTANCE_CHECK(mediacodec);
553 mediacodec_s *handle = (mediacodec_s *)mediacodec;
555 handle->error_cb = NULL;
556 handle->error_cb_userdata = NULL;
558 return MEDIACODEC_ERROR_NONE;
561 int mediacodec_set_eos_cb(mediacodec_h mediacodec, mediacodec_eos_cb callback, void *user_data)
563 MEDIACODEC_INSTANCE_CHECK(mediacodec);
564 mediacodec_s *handle = (mediacodec_s *)mediacodec;
565 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
567 handle->eos_cb = callback;
568 handle->eos_cb_userdata = user_data;
570 LOGD("set eos_cb(%p)", callback);
572 return MEDIACODEC_ERROR_NONE;
576 int mediacodec_unset_eos_cb(mediacodec_h mediacodec)
578 MEDIACODEC_INSTANCE_CHECK(mediacodec);
579 mediacodec_s *handle = (mediacodec_s *)mediacodec;
581 handle->eos_cb = NULL;
582 handle->eos_cb_userdata = NULL;
584 return MEDIACODEC_ERROR_NONE;
587 int mediacodec_set_buffer_status_cb(mediacodec_h mediacodec, mediacodec_buffer_status_cb callback, void *user_data)
589 MEDIACODEC_INSTANCE_CHECK(mediacodec);
590 mediacodec_s *handle = (mediacodec_s *)mediacodec;
591 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
593 handle->buffer_status_cb = callback;
594 handle->buffer_status_cb_userdata = user_data;
596 LOGD("set buffer_status_cb(%p)", callback);
598 return MEDIACODEC_ERROR_NONE;
602 int mediacodec_unset_buffer_status_cb(mediacodec_h mediacodec)
604 MEDIACODEC_INSTANCE_CHECK(mediacodec);
605 mediacodec_s *handle = (mediacodec_s *)mediacodec;
607 handle->buffer_status_cb = NULL;
608 handle->buffer_status_cb_userdata = NULL;
610 return MEDIACODEC_ERROR_NONE;
613 int mediacodec_foreach_supported_codec(mediacodec_h mediacodec, mediacodec_supported_codec_cb callback, void *user_data)
615 MEDIACODEC_INSTANCE_CHECK(mediacodec);
616 mediacodec_s *handle = (mediacodec_s *)mediacodec;
618 handle->supported_codec_cb = callback;
619 handle->supported_codec_cb_userdata = user_data;
621 LOGD("set supported_codec_cb(%p)", callback);
622 int ret = _mediacodec_foreach_supported_codec(callback, handle);
624 if (ret != MEDIACODEC_ERROR_NONE)
625 return __convert_error_code(ret, (char *)__FUNCTION__);
627 return MEDIACODEC_ERROR_NONE;
629 return MEDIACODEC_ERROR_NONE;
633 int mediacodec_get_packet_pool(mediacodec_h mediacodec, media_packet_pool_h *pkt_pool)
635 MEDIACODEC_INSTANCE_CHECK(mediacodec);
636 mediacodec_s *handle = (mediacodec_s *)mediacodec;
637 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_READY);
638 int ret = mc_get_packet_pool(handle->mc_handle, pkt_pool);
640 if (ret != MEDIACODEC_ERROR_NONE)
641 return MEDIACODEC_ERROR_INVALID_OPERATION;
643 return MEDIACODEC_ERROR_NONE;
646 static gboolean __mediacodec_empty_buffer_cb(media_packet_h pkt, void *user_data)
648 if (user_data == NULL || pkt == NULL)
651 mediacodec_s *handle = (mediacodec_s *)user_data;
653 if (handle->empty_buffer_cb)
654 ((mediacodec_input_buffer_used_cb)handle->empty_buffer_cb)(pkt, handle->empty_buffer_cb_userdata);
659 static gboolean __mediacodec_fill_buffer_cb(media_packet_h pkt, void *user_data)
661 if (user_data == NULL || pkt == NULL)
664 mediacodec_s *handle = (mediacodec_s *)user_data;
666 if (handle->fill_buffer_cb)
667 ((mediacodec_output_buffer_available_cb)handle->fill_buffer_cb)(pkt, handle->fill_buffer_cb_userdata);
672 static gboolean __mediacodec_error_cb(mediacodec_error_e error, void *user_data)
674 if (user_data == NULL)
677 mediacodec_s *handle = (mediacodec_s *)user_data;
679 if (handle->error_cb)
680 ((mediacodec_error_cb)handle->error_cb)(error, handle->error_cb_userdata);
685 static gboolean __mediacodec_eos_cb(void *user_data)
687 if (user_data == NULL)
690 mediacodec_s *handle = (mediacodec_s *)user_data;
693 ((mediacodec_eos_cb)handle->eos_cb)(handle->eos_cb_userdata);
698 static gboolean __mediacodec_supported_codec_cb(mediacodec_codec_type_e codec_type, void *user_data)
700 if (user_data == NULL)
703 mediacodec_s *handle = (mediacodec_s *)user_data;
705 if (handle->supported_codec_cb)
706 return ((mediacodec_supported_codec_cb)handle->supported_codec_cb)(codec_type, handle->supported_codec_cb_userdata);
711 static gboolean __mediacodec_buffer_status_cb(mediacodec_status_e status, void *user_data)
713 if (user_data == NULL)
716 mediacodec_s *handle = (mediacodec_s *)user_data;
718 if (handle->buffer_status_cb)
719 ((mediacodec_buffer_status_cb)handle->buffer_status_cb)(status, handle->buffer_status_cb_userdata);
724 #ifdef USE_MM_RESOURCE_MANAGER
726 static int __mediacodec_resource_release_cb(mm_resource_manager_h rm,
727 mm_resource_manager_res_h resource_h, void *user_data)
730 mediacodec_s *handle;
732 g_mutex_lock(&g_mediacodec_lock);
733 for (i = 0; i < g_mediacodec_handles->len; i++) {
734 handle = g_ptr_array_index(g_mediacodec_handles, i);
735 if (handle->codec_resource == resource_h) {
738 * The resource release cb is asynchronous, so mediacodec_unprepare might be
739 * called in this thread and in the main thread at the same time.
740 * Mutex lock/unlock should be added in the body of mediacodec_unprepare() to
741 * avoid the race condition.
743 handle->codec_resource = NULL;
744 mediacodec_unprepare((mediacodec_h)handle);
745 __mediacodec_error_cb(MEDIACODEC_ERROR_RESOURCE_CONFLICT, handle);
749 g_mutex_unlock(&g_mediacodec_lock);
756 static void __mediacodec_init_lib()
760 g_mutex_init(&g_mediacodec_lock);
761 g_mediacodec_handles = g_ptr_array_sized_new(MC_PREALLOCATED_HANDLE_ARRAY_SIZE);
766 static void __mediacodec_deinit_lib()
770 if (g_mc_resource_manager != NULL)
771 mm_resource_manager_destroy(g_mc_resource_manager);
773 g_ptr_array_unref(g_mediacodec_handles);
774 g_mutex_clear(&g_mediacodec_lock);