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 static mm_resource_manager_h resource_manager;
30 static GPtrArray *mediacodec_handles;
31 static GMutex mediacodec_handles_lock;
33 static gboolean __mediacodec_empty_buffer_cb(media_packet_h pkt, void *user_data);
34 static gboolean __mediacodec_fill_buffer_cb(media_packet_h pkt, void *user_data);
35 static gboolean __mediacodec_error_cb(mediacodec_error_e error, void *user_data);
36 static gboolean __mediacodec_eos_cb(void *user_data);
37 static gboolean __mediacodec_supported_codec_cb(mediacodec_codec_type_e codec_type, void *user_data);
38 static gboolean __mediacodec_buffer_status_cb(mediacodec_status_e status, void *user_data);
39 static void __mediacodec_init_lib() __attribute__((constructor));
40 static void __mediacodec_deinit_lib() __attribute__((destructor));
41 static int __mediacodec_resource_release_cb(mm_resource_manager_h rm,
42 mm_resource_manager_res_h resource_h, void *user_data);
45 * Internal Implementation
47 int __convert_error_code(int code, char *func_name)
49 int ret = MEDIACODEC_ERROR_INVALID_OPERATION;
50 char *msg = "MEDIACOODEC_INVALID_OPERATION";
54 ret = MEDIACODEC_ERROR_NONE;
55 msg = "MEDIACODEC_ERROR_NONE";
59 ret = MEDIACODEC_ERROR_INVALID_PARAMETER;
60 msg = "MEDIACODEC_ERROR_INVALID_PARAMETER";
62 case MC_PERMISSION_DENIED:
63 ret = MEDIACODEC_ERROR_PERMISSION_DENIED;
64 msg = "MEDIACODEC_ERROR_PERMISSION_DENIED";
66 case MC_INVALID_STATUS:
67 ret = MEDIACODEC_ERROR_INVALID_STATE;
68 msg = "MEDIACODEC_ERROR_INVALID_STATE";
70 case MC_NOT_SUPPORTED:
71 ret = MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE;
72 msg = "MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE";
75 case MC_INTERNAL_ERROR:
77 ret = MEDIACODEC_ERROR_INVALID_OPERATION;
78 msg = "MEDIACODEC_ERROR_INVALID_OPERATION";
80 case MC_INVALID_STREAM:
81 ret = MEDIACODEC_ERROR_INVALID_STREAM;
82 msg = "MEDIACODEC_ERROR_INVALID_STREAM";
84 case MC_CODEC_NOT_FOUND:
85 ret = MEDIACODEC_ERROR_CODEC_NOT_FOUND;
86 msg = "MEDIACODEC_ERROR_CODEC_NOT_FOUND";
89 ret = MEDIACODEC_ERROR_DECODE;
90 msg = "MEDIACODEC_ERROR_DECODE";
92 case MC_INVALID_IN_BUF:
93 ret = MEDIACODEC_ERROR_INVALID_INBUFFER;
94 msg = "MEDIACODEC_ERROR_INVALID_INBUFFER";
96 case MC_INVALID_OUT_BUF:
97 ret = MEDIACODEC_ERROR_INVALID_OUTBUFFER;
98 msg = "MEDIACODEC_ERROR_INVALID_OUTBUFFER";
100 case MC_NOT_INITIALIZED:
101 ret = MEDIACODEC_ERROR_NOT_INITIALIZED;
102 msg = "MEDIACODEC_ERROR_NOT_INITIALIZED";
104 case MC_OUTPUT_BUFFER_EMPTY:
105 case MC_OUTPUT_BUFFER_OVERFLOW:
106 ret = MEDIACODEC_ERROR_BUFFER_NOT_AVAILABLE;
107 msg = "MEDIACODEC_ERROR_BUFFER_NOT_AVAILABLE";
109 case MC_OUT_OF_MEMORY:
110 ret = MEDIACODEC_ERROR_OUT_OF_MEMORY;
111 msg = "MEDIACODEC_ERROR_OUT_OF_MEMORY";
114 ret = MEDIACODEC_ERROR_INTERNAL;
115 msg = "MEDIACODEC_ERROR_INTERNAL";
118 LOGD("[%s] %s(0x%08x) : core fw error(0x%x)", func_name, msg, ret, code);
123 * Public Implementation
126 int mediacodec_create(mediacodec_h *mediacodec)
128 MEDIACODEC_INSTANCE_CHECK(mediacodec);
129 mediacodec_s *handle;
132 LOGD("mediacodec_create..");
134 if (resource_manager == NULL)
135 return MEDIACODEC_ERROR_INTERNAL;
137 handle = (mediacodec_s *)malloc(sizeof(mediacodec_s));
138 if (handle != NULL) {
139 memset(handle, 0 , sizeof(mediacodec_s));
141 LOGE("MEDIACODEC_ERROR_OUT_OF_MEMORY(0x%08x)", MEDIACODEC_ERROR_OUT_OF_MEMORY);
142 return MEDIACODEC_ERROR_OUT_OF_MEMORY;
145 ret = mc_create(&handle->mc_handle);
146 if (ret != MEDIACODEC_ERROR_NONE) {
147 LOGE("MEDIACODEC_ERROR_INVALID_OPERATION(0x%08x)", MEDIACODEC_ERROR_INVALID_OPERATION);
148 handle->state = MEDIACODEC_STATE_NONE;
149 g_free(handle->mc_handle);
152 return MEDIACODEC_ERROR_INVALID_OPERATION;
154 *mediacodec = (mediacodec_h)handle;
155 handle->state = MEDIACODEC_STATE_IDLE;
156 LOGD("new handle : %p", *mediacodec);
160 mc_set_empty_buffer_cb(handle->mc_handle, (mediacodec_input_buffer_used_cb)__mediacodec_empty_buffer_cb, handle);
161 mc_set_fill_buffer_cb(handle->mc_handle, (mediacodec_output_buffer_available_cb)__mediacodec_fill_buffer_cb, handle);
162 mc_set_error_cb(handle->mc_handle, (mediacodec_error_cb)__mediacodec_error_cb, handle);
163 mc_set_eos_cb(handle->mc_handle, (mediacodec_eos_cb)__mediacodec_eos_cb, handle);
164 mc_set_buffer_status_cb(handle->mc_handle, (mediacodec_buffer_status_cb)__mediacodec_buffer_status_cb, handle);
165 mc_set_supported_codec_cb(handle->mc_handle, (mediacodec_supported_codec_cb)__mediacodec_supported_codec_cb, handle);
167 g_mutex_lock(&mediacodec_handles_lock);
168 g_ptr_array_insert(mediacodec_handles, -1, *mediacodec);
169 g_mutex_unlock(&mediacodec_handles_lock);
171 return MEDIACODEC_ERROR_NONE;
175 int mediacodec_destroy(mediacodec_h mediacodec)
177 LOGD("[%s] Start, handle to destroy : %p", __FUNCTION__, mediacodec);
178 MEDIACODEC_INSTANCE_CHECK(mediacodec);
179 mediacodec_s *handle = (mediacodec_s *)mediacodec;
181 int ret = mc_destroy(handle->mc_handle);
182 if (ret != MEDIACODEC_ERROR_NONE) {
183 LOGD("MEDIACODEC_ERROR_INVALID_OPERATION(0x%08x)", MEDIACODEC_ERROR_INVALID_OPERATION);
184 return MEDIACODEC_ERROR_INVALID_OPERATION;
186 g_mutex_lock(&mediacodec_handles_lock);
187 g_ptr_array_remove_fast(mediacodec_handles, mediacodec);
188 g_mutex_unlock(&mediacodec_handles_lock);
190 handle->state = MEDIACODEC_STATE_NONE;
193 return MEDIACODEC_ERROR_NONE;
197 int mediacodec_set_codec(mediacodec_h mediacodec, mediacodec_codec_type_e codec_id, int flags)
199 MEDIACODEC_INSTANCE_CHECK(mediacodec);
200 mediacodec_s *handle = (mediacodec_s *)mediacodec;
201 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
203 int ret = mc_set_codec(handle->mc_handle, codec_id, flags);
205 if (ret != MEDIACODEC_ERROR_NONE) {
206 return __convert_error_code(ret, (char *)__FUNCTION__);
208 handle->state = MEDIACODEC_STATE_IDLE;
209 return MEDIACODEC_ERROR_NONE;
213 int mediacodec_set_vdec_info(mediacodec_h mediacodec, int width, int height)
215 MEDIACODEC_INSTANCE_CHECK(mediacodec);
216 mediacodec_s *handle = (mediacodec_s *)mediacodec;
217 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
219 int ret = mc_set_vdec_info(handle->mc_handle, width, height);
221 if (ret != MEDIACODEC_ERROR_NONE) {
222 return __convert_error_code(ret, (char *)__FUNCTION__);
224 handle->state = MEDIACODEC_STATE_IDLE;
225 return MEDIACODEC_ERROR_NONE;
229 int mediacodec_set_venc_info(mediacodec_h mediacodec, int width, int height, int fps, int target_bits)
231 MEDIACODEC_INSTANCE_CHECK(mediacodec);
232 mediacodec_s *handle = (mediacodec_s *)mediacodec;
233 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
235 int ret = mc_set_venc_info(handle->mc_handle, width, height, fps, target_bits);
237 if (ret != MEDIACODEC_ERROR_NONE) {
238 return __convert_error_code(ret, (char *)__FUNCTION__);
240 handle->state = MEDIACODEC_STATE_IDLE;
241 return MEDIACODEC_ERROR_NONE;
245 int mediacodec_set_adec_info(mediacodec_h mediacodec, int samplerate, int channel, int bit)
247 MEDIACODEC_INSTANCE_CHECK(mediacodec);
248 mediacodec_s *handle = (mediacodec_s *)mediacodec;
249 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
251 int ret = mc_set_adec_info(handle->mc_handle, samplerate, channel, bit);
253 if (ret != MEDIACODEC_ERROR_NONE) {
254 return __convert_error_code(ret, (char *)__FUNCTION__);
256 handle->state = MEDIACODEC_STATE_IDLE;
257 return MEDIACODEC_ERROR_NONE;
261 int mediacodec_set_aenc_info(mediacodec_h mediacodec, int samplerate, int channel, int bit, int bitrate)
263 MEDIACODEC_INSTANCE_CHECK(mediacodec);
264 mediacodec_s *handle = (mediacodec_s *)mediacodec;
265 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
267 int ret = mc_set_aenc_info(handle->mc_handle, samplerate, channel, bit, bitrate);
269 if (ret != MEDIACODEC_ERROR_NONE) {
270 return __convert_error_code(ret, (char *)__FUNCTION__);
272 handle->state = MEDIACODEC_STATE_IDLE;
273 return MEDIACODEC_ERROR_NONE;
277 int mediacodec_configure_from_media_format(mediacodec_h mediacodec, media_format_h format, int flags)
279 MEDIACODEC_INSTANCE_CHECK(mediacodec);
280 mediacodec_s *handle = (mediacodec_s *)mediacodec;
281 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
283 int ret = mc_configure(handle->mc_handle, format, flags);
285 if (ret != MEDIACODEC_ERROR_NONE) {
286 return __convert_error_code(ret, (char *)__FUNCTION__);
288 handle->state = MEDIACODEC_STATE_IDLE;
289 return MEDIACODEC_ERROR_NONE;
293 int mediacodec_prepare(mediacodec_h mediacodec)
295 MEDIACODEC_INSTANCE_CHECK(mediacodec);
296 mediacodec_s *handle = (mediacodec_s *)mediacodec;
297 mc_handle_t *mc_handle = (mc_handle_t *) handle->mc_handle;
298 int rm_ret = MM_RESOURCE_MANAGER_ERROR_NONE;
299 mm_resource_manager_res_h resource;
300 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
302 if (mc_handle->is_hw && mc_handle->is_video) {
304 if (handle->codec_resource) {
305 LOGE("Codec resource is tried to be acquired twice\n");
306 return MC_INTERNAL_ERROR;
311 * Currently volume of requested resource is set to 1. Default
312 * capacity for video encoder/decoder is 1 too. The actual capacity
313 * should be set in mmfw-sysconf > mmfw_resource_manager.ini.
314 * If different encode/decode operation needs different volume of
315 * video encoder/decoder, '1' in the following
316 * mm_resource_manager_mark_for_acquire function should be set to
317 * corresponding value.
318 * If that value depends on platform where it's executed,
319 * MM_RESOURCE_MANAGER_RES_TYPE_COND_* and
320 * mm_resource_manager_get_res_type_volume() can be used.
321 * Additional info can be found in doxygen comments of mm_resource_manager.h
323 rm_ret = mm_resource_manager_mark_for_acquire(resource_manager,
324 mc_handle->is_encoder ?
325 MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_ENCODER :
326 MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_DECODER,
328 if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE)
330 LOGE("Failed to acquire resource manager %x", rm_ret);
331 case MM_RESOURCE_MANAGER_ERROR_NOT_SUPPORTED:
332 return MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE;
333 case MM_RESOURCE_MANAGER_ERROR_NOT_ENOUGH:
334 return MEDIACODEC_ERROR_RESOURCE_OVERLOADED;
336 return MEDIACODEC_ERROR_INTERNAL;
339 rm_ret = mm_resource_manager_commit(resource_manager);
340 if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
341 mm_resource_manager_mark_for_release(resource_manager, resource);
342 LOGE("Failed to commit resource manager : %x", rm_ret);
343 return MEDIACODEC_ERROR_INTERNAL;
346 handle->codec_resource = resource;
349 int ret = mc_prepare(handle->mc_handle);
351 if (ret != MEDIACODEC_ERROR_NONE) {
352 return __convert_error_code(ret, (char *)__FUNCTION__);
354 handle->state = MEDIACODEC_STATE_READY;
355 return MEDIACODEC_ERROR_NONE;
359 int mediacodec_unprepare(mediacodec_h mediacodec)
361 MEDIACODEC_INSTANCE_CHECK(mediacodec);
362 mediacodec_s *handle = (mediacodec_s *)mediacodec;
363 int rm_ret = MM_RESOURCE_MANAGER_ERROR_NONE;
365 int ret = mc_unprepare(handle->mc_handle);
367 if (ret != MEDIACODEC_ERROR_NONE) {
368 return __convert_error_code(ret, (char *)__FUNCTION__);
370 if (handle->codec_resource != NULL) {
371 mm_resource_manager_mark_for_release(resource_manager,
372 handle->codec_resource);
373 handle->codec_resource = NULL;
374 rm_ret = mm_resource_manager_commit(resource_manager);
375 if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
376 mm_resource_manager_mark_for_release(resource_manager, handle->codec_resource);
378 case MM_RESOURCE_MANAGER_ERROR_LOW_PRIORITY:
379 return MEDIACODEC_ERROR_RESOURCE_OVERLOADED;
381 return MEDIACODEC_ERROR_INTERNAL;
385 LOGD("No codec resource to release. Probably resource release cb called\n");
388 handle->state = MEDIACODEC_STATE_IDLE;
389 return MEDIACODEC_ERROR_NONE;
393 int mediacodec_process_input(mediacodec_h mediacodec, media_packet_h inbuf, uint64_t timeOutUs)
395 MEDIACODEC_INSTANCE_CHECK(mediacodec);
396 mediacodec_s *handle = (mediacodec_s *)mediacodec;
397 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_READY);
399 int ret = mc_process_input(handle->mc_handle, inbuf, timeOutUs);
401 if (ret != MEDIACODEC_ERROR_NONE)
402 return __convert_error_code(ret, (char *)__FUNCTION__);
404 return MEDIACODEC_ERROR_NONE;
407 int mediacodec_get_output(mediacodec_h mediacodec, media_packet_h *outbuf, uint64_t timeOutUs)
409 MEDIACODEC_INSTANCE_CHECK(mediacodec);
410 mediacodec_s *handle = (mediacodec_s *)mediacodec;
411 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_READY);
413 int ret = mc_get_output(handle->mc_handle, outbuf, timeOutUs);
415 if (ret != MEDIACODEC_ERROR_NONE)
416 return __convert_error_code(ret, (char *)__FUNCTION__);
418 return MEDIACODEC_ERROR_NONE;
421 int mediacodec_flush_buffers(mediacodec_h mediacodec)
423 MEDIACODEC_INSTANCE_CHECK(mediacodec);
424 mediacodec_s *handle = (mediacodec_s *)mediacodec;
426 int ret = mc_flush_buffers(handle->mc_handle);
428 if (ret != MEDIACODEC_ERROR_NONE)
429 return __convert_error_code(ret, (char *)__FUNCTION__);
431 return MEDIACODEC_ERROR_NONE;
434 int mediacodec_get_supported_type(mediacodec_h mediacodec, mediacodec_codec_type_e codec_type, bool encoder, int *support_type)
436 MEDIACODEC_INSTANCE_CHECK(mediacodec);
437 mediacodec_s *handle = (mediacodec_s *)mediacodec;
438 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
440 int ret = mc_get_supported_type(handle->mc_handle, codec_type, encoder, support_type);
442 if (ret != MEDIACODEC_ERROR_NONE)
443 return __convert_error_code(ret, (char *)__FUNCTION__);
445 handle->state = MEDIACODEC_STATE_IDLE;
447 return MEDIACODEC_ERROR_NONE;
450 int mediacodec_set_input_buffer_used_cb(mediacodec_h mediacodec, mediacodec_input_buffer_used_cb callback, void *user_data)
452 MEDIACODEC_INSTANCE_CHECK(mediacodec);
453 mediacodec_s *handle = (mediacodec_s *)mediacodec;
454 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
456 handle->empty_buffer_cb = callback;
457 handle->empty_buffer_cb_userdata = user_data;
459 LOGD("set empty_buffer_cb(%p)", callback);
461 return MEDIACODEC_ERROR_NONE;
464 int mediacodec_unset_input_buffer_used_cb(mediacodec_h mediacodec)
466 MEDIACODEC_INSTANCE_CHECK(mediacodec);
467 mediacodec_s *handle = (mediacodec_s *)mediacodec;
469 handle->empty_buffer_cb = NULL;
470 handle->empty_buffer_cb_userdata = NULL;
472 return MEDIACODEC_ERROR_NONE;
476 int mediacodec_set_output_buffer_available_cb(mediacodec_h mediacodec, mediacodec_output_buffer_available_cb callback, void *user_data)
478 MEDIACODEC_INSTANCE_CHECK(mediacodec);
479 mediacodec_s *handle = (mediacodec_s *)mediacodec;
480 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
482 handle->fill_buffer_cb = callback;
483 handle->fill_buffer_cb_userdata = user_data;
485 LOGD("set fill_buffer_cb(%p)", callback);
487 return MEDIACODEC_ERROR_NONE;
491 int mediacodec_unset_output_buffer_available_cb(mediacodec_h mediacodec)
493 MEDIACODEC_INSTANCE_CHECK(mediacodec);
494 mediacodec_s *handle = (mediacodec_s *)mediacodec;
496 handle->fill_buffer_cb = NULL;
497 handle->fill_buffer_cb_userdata = NULL;
499 return MEDIACODEC_ERROR_NONE;
502 int mediacodec_set_error_cb(mediacodec_h mediacodec, mediacodec_error_cb callback, void *user_data)
504 MEDIACODEC_INSTANCE_CHECK(mediacodec);
505 mediacodec_s *handle = (mediacodec_s *)mediacodec;
506 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
508 handle->error_cb = callback;
509 handle->error_cb_userdata = user_data;
511 LOGD("set error_cb(%p)", callback);
513 return MEDIACODEC_ERROR_NONE;
517 int mediacodec_unset_error_cb(mediacodec_h mediacodec)
519 MEDIACODEC_INSTANCE_CHECK(mediacodec);
520 mediacodec_s *handle = (mediacodec_s *)mediacodec;
522 handle->error_cb = NULL;
523 handle->error_cb_userdata = NULL;
525 return MEDIACODEC_ERROR_NONE;
528 int mediacodec_set_eos_cb(mediacodec_h mediacodec, mediacodec_eos_cb callback, void *user_data)
530 MEDIACODEC_INSTANCE_CHECK(mediacodec);
531 mediacodec_s *handle = (mediacodec_s *)mediacodec;
532 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
534 handle->eos_cb = callback;
535 handle->eos_cb_userdata = user_data;
537 LOGD("set eos_cb(%p)", callback);
539 return MEDIACODEC_ERROR_NONE;
543 int mediacodec_unset_eos_cb(mediacodec_h mediacodec)
545 MEDIACODEC_INSTANCE_CHECK(mediacodec);
546 mediacodec_s *handle = (mediacodec_s *)mediacodec;
548 handle->eos_cb = NULL;
549 handle->eos_cb_userdata = NULL;
551 return MEDIACODEC_ERROR_NONE;
554 int mediacodec_set_buffer_status_cb(mediacodec_h mediacodec, mediacodec_buffer_status_cb callback, void *user_data)
556 MEDIACODEC_INSTANCE_CHECK(mediacodec);
557 mediacodec_s *handle = (mediacodec_s *)mediacodec;
558 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
560 handle->buffer_status_cb = callback;
561 handle->buffer_status_cb_userdata = user_data;
563 LOGD("set buffer_status_cb(%p)", callback);
565 return MEDIACODEC_ERROR_NONE;
569 int mediacodec_unset_buffer_status_cb(mediacodec_h mediacodec)
571 MEDIACODEC_INSTANCE_CHECK(mediacodec);
572 mediacodec_s *handle = (mediacodec_s *)mediacodec;
574 handle->buffer_status_cb = NULL;
575 handle->buffer_status_cb_userdata = NULL;
577 return MEDIACODEC_ERROR_NONE;
580 int mediacodec_foreach_supported_codec(mediacodec_h mediacodec, mediacodec_supported_codec_cb callback, void *user_data)
582 MEDIACODEC_INSTANCE_CHECK(mediacodec);
583 mediacodec_s *handle = (mediacodec_s *)mediacodec;
585 handle->supported_codec_cb = callback;
586 handle->supported_codec_cb_userdata = user_data;
588 LOGD("set supported_codec_cb(%p)", callback);
589 int ret = _mediacodec_foreach_supported_codec(callback, handle);
591 if (ret != MEDIACODEC_ERROR_NONE)
592 return __convert_error_code(ret, (char *)__FUNCTION__);
594 return MEDIACODEC_ERROR_NONE;
596 return MEDIACODEC_ERROR_NONE;
600 int mediacodec_get_packet_pool(mediacodec_h mediacodec, media_packet_pool_h *pkt_pool)
602 MEDIACODEC_INSTANCE_CHECK(mediacodec);
603 mediacodec_s *handle = (mediacodec_s *)mediacodec;
604 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_READY);
605 int ret = mc_get_packet_pool(handle->mc_handle, pkt_pool);
607 if (ret != MEDIACODEC_ERROR_NONE)
608 return MEDIACODEC_ERROR_INVALID_OPERATION;
610 return MEDIACODEC_ERROR_NONE;
613 static gboolean __mediacodec_empty_buffer_cb(media_packet_h pkt, void *user_data)
615 if (user_data == NULL || pkt == NULL)
618 mediacodec_s *handle = (mediacodec_s *)user_data;
620 if (handle->empty_buffer_cb)
621 ((mediacodec_input_buffer_used_cb)handle->empty_buffer_cb)(pkt, handle->empty_buffer_cb_userdata);
626 static gboolean __mediacodec_fill_buffer_cb(media_packet_h pkt, void *user_data)
628 if (user_data == NULL || pkt == NULL)
631 mediacodec_s *handle = (mediacodec_s *)user_data;
633 if (handle->fill_buffer_cb)
634 ((mediacodec_output_buffer_available_cb)handle->fill_buffer_cb)(pkt, handle->fill_buffer_cb_userdata);
639 static gboolean __mediacodec_error_cb(mediacodec_error_e error, void *user_data)
641 if (user_data == NULL)
644 mediacodec_s *handle = (mediacodec_s *)user_data;
646 if (handle->error_cb)
647 ((mediacodec_error_cb)handle->error_cb)(error, handle->error_cb_userdata);
652 static gboolean __mediacodec_eos_cb(void *user_data)
654 if (user_data == NULL)
657 mediacodec_s *handle = (mediacodec_s *)user_data;
660 ((mediacodec_eos_cb)handle->eos_cb)(handle->eos_cb_userdata);
665 static gboolean __mediacodec_supported_codec_cb(mediacodec_codec_type_e codec_type, void *user_data)
667 if (user_data == NULL)
670 mediacodec_s *handle = (mediacodec_s *)user_data;
672 if (handle->supported_codec_cb)
673 return ((mediacodec_supported_codec_cb)handle->supported_codec_cb)(codec_type, handle->supported_codec_cb_userdata);
678 static gboolean __mediacodec_buffer_status_cb(mediacodec_status_e status, void *user_data)
680 if (user_data == NULL)
683 mediacodec_s *handle = (mediacodec_s *)user_data;
685 if (handle->buffer_status_cb)
686 ((mediacodec_buffer_status_cb)handle->buffer_status_cb)(status, handle->buffer_status_cb_userdata);
692 static int __mediacodec_resource_release_cb(mm_resource_manager_h rm,
693 mm_resource_manager_res_h resource_h, void *user_data)
696 mediacodec_s *handle;
698 g_mutex_lock(&mediacodec_handles_lock);
699 for (i = 0; i < mediacodec_handles->len; i++) {
700 handle = g_ptr_array_index(mediacodec_handles, i);
701 if (handle->codec_resource == resource_h) {
704 * The resource release cb is asynchronous, so mediacodec_unprepare might be
705 * called in this thread and in the main thread at the same time.
706 * Mutex lock/unlock should be added in the body of mediacodec_unprepare() to
707 * avoid the race condition.
709 handle->codec_resource = NULL;
710 mediacodec_unprepare((mediacodec_h)handle);
711 __mediacodec_error_cb(MEDIACODEC_ERROR_RESOURCE_CONFLICT, handle);
715 g_mutex_unlock(&mediacodec_handles_lock);
720 static void __mediacodec_init_lib()
722 mediacodec_handles = g_ptr_array_sized_new(MC_PREALLOCATED_HANDLE_ARRAY_SIZE);
724 if (MM_RESOURCE_MANAGER_ERROR_NONE != mm_resource_manager_create(MM_RESOURCE_MANAGER_APP_CLASS_MEDIA,
725 __mediacodec_resource_release_cb, NULL, &resource_manager)) {
726 LOGE("Failed to initialize resource manager");
727 g_ptr_array_unref(mediacodec_handles);
731 static void __mediacodec_deinit_lib()
733 if (resource_manager != NULL)
734 mm_resource_manager_destroy(resource_manager);
735 g_ptr_array_unref(mediacodec_handles);