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 static gboolean __mediacodec_empty_buffer_cb(media_packet_h pkt, void *user_data);
28 static gboolean __mediacodec_fill_buffer_cb(media_packet_h pkt, void *user_data);
29 static gboolean __mediacodec_error_cb(mediacodec_error_e error, void *user_data);
30 static gboolean __mediacodec_eos_cb(void *user_data);
31 static gboolean __mediacodec_supported_codec_cb(mediacodec_codec_type_e codec_type, void *user_data);
32 static int __mediacodec_check_system_info_feature_supported();
33 static gboolean __mediacodec_buffer_status_cb(mediacodec_status_e status, void *user_data);
37 * Internal Implementation
39 int __convert_error_code(int code, char* func_name)
41 int ret = MEDIACODEC_ERROR_INVALID_OPERATION;
42 char* msg = "MEDIACOODEC_INVALID_OPERATION";
46 ret = MEDIACODEC_ERROR_NONE;
47 msg = "MEDIACODEC_ERROR_NONE";
51 ret = MEDIACODEC_ERROR_INVALID_PARAMETER;
52 msg = "MEDIACODEC_ERROR_INVALID_PARAMETER";
54 case MC_PERMISSION_DENIED:
55 ret = MEDIACODEC_ERROR_PERMISSION_DENIED;
56 msg = "MEDIACODEC_ERROR_PERMISSION_DENIED";
58 case MC_INVALID_STATUS:
59 ret = MEDIACODEC_ERROR_INVALID_STATE;
60 msg = "MEDIACODEC_ERROR_INVALID_STATE";
62 case MC_NOT_SUPPORTED:
63 ret = MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE;
64 msg = "MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE";
67 case MC_INTERNAL_ERROR:
69 ret = MEDIACODEC_ERROR_INVALID_OPERATION;
70 msg = "MEDIACODEC_ERROR_INVALID_OPERATION";
72 case MC_INVALID_STREAM:
73 ret = MEDIACODEC_ERROR_INVALID_STREAM;
74 msg = "MEDIACODEC_ERROR_INVALID_STREAM";
76 case MC_CODEC_NOT_FOUND:
77 ret = MEDIACODEC_ERROR_CODEC_NOT_FOUND;
78 msg = "MEDIACODEC_ERROR_CODEC_NOT_FOUND";
81 ret = MEDIACODEC_ERROR_DECODE;
82 msg = "MEDIACODEC_ERROR_DECODE";
84 case MC_INVALID_IN_BUF:
85 ret = MEDIACODEC_ERROR_INVALID_INBUFFER;
86 msg = "MEDIACODEC_ERROR_INVALID_INBUFFER";
88 case MC_INVALID_OUT_BUF:
89 ret = MEDIACODEC_ERROR_INVALID_OUTBUFFER;
90 msg = "MEDIACODEC_ERROR_INVALID_OUTBUFFER";
92 case MC_NOT_INITIALIZED:
93 ret = MEDIACODEC_ERROR_NOT_INITIALIZED;
94 msg = "MEDIACODEC_ERROR_NOT_INITIALIZED";
96 case MC_OUTPUT_BUFFER_EMPTY:
97 case MC_OUTPUT_BUFFER_OVERFLOW:
98 ret = MEDIACODEC_ERROR_BUFFER_NOT_AVAILABLE;
99 msg = "MEDIACODEC_ERROR_BUFFER_NOT_AVAILABLE";
102 ret = MEDIACODEC_ERROR_INTERNAL;
103 msg = "MEDIACODEC_ERROR_INTERNAL";
106 LOGD("[%s] %s(0x%08x) : core fw error(0x%x)", func_name, msg, ret, code);
110 bool __mediacodec_state_validate(mediacodec_h mediacodec, mediacodec_state_e threshold)
112 mediacodec_s * handle = (mediacodec_s *) mediacodec;
114 if(handle->state < threshold)
119 static int __mediacodec_check_system_info_feature_supported()
124 nRetVal = system_info_get_platform_bool("http://tizen.org/feature/mediacodec", &bValue);
126 if ( nRetVal != SYSTEM_INFO_ERROR_NONE )
128 LOGE("[%s] SYSTEM_INFO_ERROR : ", __FUNCTION__);
132 if ( false == bValue )
134 LOGI("system_info_get_platform_bool returned Unsupported feature capability\n");
138 LOGI("system_info_get_platform_bool returned Supported status feature\n");
145 * Public Implementation
148 int mediacodec_create(mediacodec_h *mediacodec)
150 MEDIACODEC_INSTANCE_CHECK(mediacodec);
151 mediacodec_s *handle;
154 LOGD ("mediacodec_create..\n");
156 handle = (mediacodec_s*)malloc( sizeof(mediacodec_s));
159 memset(handle, 0 , sizeof(mediacodec_s));
163 LOGE("MEDIACODEC_ERROR_OUT_OF_MEMORY(0x%08x)", MEDIACODEC_ERROR_OUT_OF_MEMORY);
164 return MEDIACODEC_ERROR_OUT_OF_MEMORY;
167 ret = mc_create(&handle->mc_handle);
168 if (ret != MEDIACODEC_ERROR_NONE)
170 LOGE("MEDIACODEC_ERROR_INVALID_OPERATION(0x%08x)", MEDIACODEC_ERROR_INVALID_OPERATION);
171 handle->state = MEDIACODEC_STATE_NONE;
174 return MEDIACODEC_ERROR_INVALID_OPERATION;
178 *mediacodec = (mediacodec_h) handle;
179 handle->state = MEDIACODEC_STATE_IDLE;
180 LOGD("new handle : %p", *mediacodec);
184 mc_set_empty_buffer_cb(handle->mc_handle, (mediacodec_input_buffer_used_cb)__mediacodec_empty_buffer_cb, handle);
185 mc_set_fill_buffer_cb(handle->mc_handle, (mediacodec_output_buffer_available_cb)__mediacodec_fill_buffer_cb, handle);
186 mc_set_error_cb(handle->mc_handle, (mediacodec_error_cb)__mediacodec_error_cb, handle);
187 mc_set_eos_cb(handle->mc_handle, (mediacodec_eos_cb)__mediacodec_eos_cb, handle);
188 mc_set_buffer_status_cb(handle->mc_handle, (mediacodec_buffer_status_cb)__mediacodec_buffer_status_cb, handle);
189 mc_set_supported_codec_cb(handle->mc_handle, (mediacodec_supported_codec_cb)__mediacodec_supported_codec_cb, handle);
191 return MEDIACODEC_ERROR_NONE;
195 int mediacodec_destroy(mediacodec_h mediacodec)
197 LOGD ("[%s] Start, handle to destroy : %p", __FUNCTION__, mediacodec);
198 MEDIACODEC_INSTANCE_CHECK(mediacodec);
199 mediacodec_s * handle = (mediacodec_s *) mediacodec;
201 int ret = mc_destroy(handle->mc_handle);
202 if (ret != MEDIACODEC_ERROR_NONE) {
203 LOGD("MEDIACODEC_ERROR_INVALID_OPERATION(0x%08x)", MEDIACODEC_ERROR_INVALID_OPERATION);
204 return MEDIACODEC_ERROR_INVALID_OPERATION;
208 handle->state = MEDIACODEC_STATE_NONE;
211 return MEDIACODEC_ERROR_NONE;
215 int mediacodec_set_codec(mediacodec_h mediacodec, mediacodec_codec_type_e codec_id, mediacodec_support_type_e flags)
217 MEDIACODEC_INSTANCE_CHECK(mediacodec);
218 mediacodec_s * handle = (mediacodec_s *) mediacodec;
219 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
221 int ret = mc_set_codec(handle->mc_handle, codec_id, flags);
223 if (ret != MEDIACODEC_ERROR_NONE)
225 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)
244 return __convert_error_code(ret,(char*)__FUNCTION__);
248 handle->state = MEDIACODEC_STATE_IDLE;
249 return MEDIACODEC_ERROR_NONE;
253 int mediacodec_set_venc_info(mediacodec_h mediacodec, int width, int height, int fps, int target_bits)
255 MEDIACODEC_INSTANCE_CHECK(mediacodec);
256 mediacodec_s * handle = (mediacodec_s *) mediacodec;
257 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
259 int ret = mc_set_venc_info(handle->mc_handle, width, height, fps, target_bits);
261 if (ret != MEDIACODEC_ERROR_NONE)
263 return __convert_error_code(ret,(char*)__FUNCTION__);
267 handle->state = MEDIACODEC_STATE_IDLE;
268 return MEDIACODEC_ERROR_NONE;
272 int mediacodec_set_adec_info(mediacodec_h mediacodec, int samplerate, int channel, int bit)
274 MEDIACODEC_INSTANCE_CHECK(mediacodec);
275 mediacodec_s * handle = (mediacodec_s *) mediacodec;
276 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
278 int ret = mc_set_adec_info(handle->mc_handle, samplerate, channel, bit);
280 if (ret != MEDIACODEC_ERROR_NONE)
282 return __convert_error_code(ret,(char*)__FUNCTION__);
286 handle->state = MEDIACODEC_STATE_IDLE;
287 return MEDIACODEC_ERROR_NONE;
291 int mediacodec_set_aenc_info(mediacodec_h mediacodec, int samplerate, int channel, int bit, int bitrate)
293 MEDIACODEC_INSTANCE_CHECK(mediacodec);
294 mediacodec_s * handle = (mediacodec_s *) mediacodec;
295 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
297 int ret = mc_set_aenc_info(handle->mc_handle, samplerate, channel, bit, bitrate);
299 if (ret != MEDIACODEC_ERROR_NONE)
301 return __convert_error_code(ret,(char*)__FUNCTION__);
305 handle->state = MEDIACODEC_STATE_IDLE;
306 return MEDIACODEC_ERROR_NONE;
310 int mediacodec_prepare(mediacodec_h mediacodec)
312 MEDIACODEC_INSTANCE_CHECK(mediacodec);
313 mediacodec_s * handle = (mediacodec_s *) mediacodec;
314 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
316 int ret = mc_prepare(handle->mc_handle);
318 if (ret != MEDIACODEC_ERROR_NONE)
320 return __convert_error_code(ret,(char*)__FUNCTION__);
324 handle->state = MEDIACODEC_STATE_READY;
325 return MEDIACODEC_ERROR_NONE;
329 int mediacodec_unprepare(mediacodec_h mediacodec)
331 MEDIACODEC_INSTANCE_CHECK(mediacodec);
332 mediacodec_s * handle = (mediacodec_s *) mediacodec;
334 int ret = mc_unprepare(handle->mc_handle);
336 if (ret != MEDIACODEC_ERROR_NONE)
338 return __convert_error_code(ret,(char*)__FUNCTION__);
342 handle->state = MEDIACODEC_STATE_IDLE;
343 return MEDIACODEC_ERROR_NONE;
347 int mediacodec_process_input(mediacodec_h mediacodec, media_packet_h inbuf, uint64_t timeOutUs)
349 MEDIACODEC_INSTANCE_CHECK(mediacodec);
350 mediacodec_s * handle = (mediacodec_s *) mediacodec;
351 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_READY);
353 int ret = mc_process_input(handle->mc_handle, inbuf, timeOutUs);
355 if (ret != MEDIACODEC_ERROR_NONE)
357 return __convert_error_code(ret,(char*)__FUNCTION__);
361 return MEDIACODEC_ERROR_NONE;
365 int mediacodec_get_output(mediacodec_h mediacodec, media_packet_h *outbuf, uint64_t timeOutUs)
367 MEDIACODEC_INSTANCE_CHECK(mediacodec);
368 mediacodec_s * handle = (mediacodec_s *) mediacodec;
369 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_READY);
371 int ret = mc_get_output(handle->mc_handle, outbuf, timeOutUs);
373 if (ret != MEDIACODEC_ERROR_NONE)
375 return __convert_error_code(ret,(char*)__FUNCTION__);
379 return MEDIACODEC_ERROR_NONE;
383 int mediacodec_flush_buffers (mediacodec_h mediacodec)
385 MEDIACODEC_INSTANCE_CHECK(mediacodec);
386 mediacodec_s * handle = (mediacodec_s *) mediacodec;
388 int ret = mc_flush_buffers(handle->mc_handle);
390 if (ret != MEDIACODEC_ERROR_NONE)
392 return __convert_error_code(ret,(char*)__FUNCTION__);
396 handle->state = MEDIACODEC_STATE_IDLE;
397 return MEDIACODEC_ERROR_NONE;
401 int mediacodec_get_supported_type(mediacodec_h mediacodec, mediacodec_codec_type_e codec_type, bool encoder, int *support_type)
403 MEDIACODEC_INSTANCE_CHECK(mediacodec);
404 mediacodec_s * handle = (mediacodec_s *) mediacodec;
405 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
407 int ret = mc_get_supported_type(handle->mc_handle, codec_type, encoder, support_type);
409 if (ret != MEDIACODEC_ERROR_NONE)
411 return __convert_error_code(ret,(char*)__FUNCTION__);
415 handle->state = MEDIACODEC_STATE_IDLE;
416 return MEDIACODEC_ERROR_NONE;
420 int mediacodec_set_input_buffer_used_cb(mediacodec_h mediacodec, mediacodec_input_buffer_used_cb callback, void* user_data)
422 MEDIACODEC_INSTANCE_CHECK(mediacodec);
423 mediacodec_s * handle = (mediacodec_s *) mediacodec;
424 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
426 handle->empty_buffer_cb = callback;
427 handle->empty_buffer_cb_userdata = user_data;
429 LOGD("set empty_buffer_cb(%p)", callback);
431 return MEDIACODEC_ERROR_NONE;
434 int mediacodec_unset_input_buffer_used_cb(mediacodec_h mediacodec)
436 MEDIACODEC_INSTANCE_CHECK(mediacodec);
437 mediacodec_s * handle = (mediacodec_s *) mediacodec;
439 handle->empty_buffer_cb = NULL;
440 handle->empty_buffer_cb_userdata = NULL;
442 return MEDIACODEC_ERROR_NONE;
446 int mediacodec_set_output_buffer_available_cb(mediacodec_h mediacodec, mediacodec_output_buffer_available_cb callback, void* user_data)
448 MEDIACODEC_INSTANCE_CHECK(mediacodec);
449 mediacodec_s * handle = (mediacodec_s *) mediacodec;
450 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
452 handle->fill_buffer_cb = callback;
453 handle->fill_buffer_cb_userdata = user_data;
455 LOGD("set fill_buffer_cb(%p)", callback);
457 return MEDIACODEC_ERROR_NONE;
461 int mediacodec_unset_output_buffer_available_cb(mediacodec_h mediacodec)
463 MEDIACODEC_INSTANCE_CHECK(mediacodec);
464 mediacodec_s * handle = (mediacodec_s *) mediacodec;
466 handle->fill_buffer_cb = NULL;
467 handle->fill_buffer_cb_userdata = NULL;
469 return MEDIACODEC_ERROR_NONE;
472 int mediacodec_set_error_cb(mediacodec_h mediacodec, mediacodec_error_cb callback, void* user_data)
474 MEDIACODEC_INSTANCE_CHECK(mediacodec);
475 mediacodec_s * handle = (mediacodec_s *) mediacodec;
476 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
478 handle->error_cb = callback;
479 handle->error_cb_userdata = user_data;
481 LOGD("set error_cb(%p)", callback);
483 return MEDIACODEC_ERROR_NONE;
487 int mediacodec_unset_error_cb(mediacodec_h mediacodec)
489 MEDIACODEC_INSTANCE_CHECK(mediacodec);
490 mediacodec_s * handle = (mediacodec_s *) mediacodec;
492 handle->error_cb = NULL;
493 handle->error_cb_userdata = NULL;
495 return MEDIACODEC_ERROR_NONE;
498 int mediacodec_set_eos_cb(mediacodec_h mediacodec, mediacodec_eos_cb callback, void* user_data)
500 MEDIACODEC_INSTANCE_CHECK(mediacodec);
501 mediacodec_s * handle = (mediacodec_s *) mediacodec;
502 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
504 handle->eos_cb = callback;
505 handle->eos_cb_userdata = user_data;
507 LOGD("set eos_cb(%p)", callback);
509 return MEDIACODEC_ERROR_NONE;
513 int mediacodec_unset_eos_cb(mediacodec_h mediacodec)
515 MEDIACODEC_INSTANCE_CHECK(mediacodec);
516 mediacodec_s * handle = (mediacodec_s *) mediacodec;
518 handle->eos_cb = NULL;
519 handle->eos_cb_userdata = NULL;
521 return MEDIACODEC_ERROR_NONE;
524 int mediacodec_set_buffer_status_cb(mediacodec_h mediacodec, mediacodec_buffer_status_cb callback, void* user_data)
526 MEDIACODEC_INSTANCE_CHECK(mediacodec);
527 mediacodec_s * handle = (mediacodec_s *) mediacodec;
528 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
530 handle->buffer_status_cb = callback;
531 handle->buffer_status_cb_userdata = user_data;
533 LOGD("set buffer_status_cb(%p)", callback);
535 return MEDIACODEC_ERROR_NONE;
539 int mediacodec_unset_buffer_status_cb(mediacodec_h mediacodec)
541 MEDIACODEC_INSTANCE_CHECK(mediacodec);
542 mediacodec_s * handle = (mediacodec_s *) mediacodec;
544 handle->buffer_status_cb = NULL;
545 handle->buffer_status_cb_userdata = NULL;
547 return MEDIACODEC_ERROR_NONE;
550 int mediacodec_foreach_supported_codec(mediacodec_h mediacodec, mediacodec_supported_codec_cb callback, void *user_data)
552 MEDIACODEC_INSTANCE_CHECK(mediacodec);
553 mediacodec_s * handle = (mediacodec_s *) mediacodec;
554 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
556 handle->supported_codec_cb = callback;
557 handle->supported_codec_cb_userdata = user_data;
559 LOGD("set supported_codec_cb(%p)", callback);
560 _mediacodec_foreach_supported_codec(handle->mc_handle, callback, handle);
562 return MEDIACODEC_ERROR_NONE;
566 static gboolean __mediacodec_empty_buffer_cb(media_packet_h pkt, void *user_data)
568 if(user_data == NULL || pkt == NULL)
571 mediacodec_s * handle = (mediacodec_s *) user_data;
573 if ( handle->empty_buffer_cb )
575 ((mediacodec_input_buffer_used_cb)handle->empty_buffer_cb)(pkt, handle->empty_buffer_cb_userdata);
581 static gboolean __mediacodec_fill_buffer_cb(media_packet_h pkt, void *user_data)
583 if(user_data == NULL || pkt == NULL)
586 mediacodec_s * handle = (mediacodec_s *) user_data;
588 if ( handle->fill_buffer_cb )
590 ((mediacodec_output_buffer_available_cb)handle->fill_buffer_cb)(pkt, handle->fill_buffer_cb_userdata);
596 static gboolean __mediacodec_error_cb(mediacodec_error_e error, void *user_data)
598 if(user_data == NULL)
601 mediacodec_s * handle = (mediacodec_s *) user_data;
603 if ( handle->error_cb )
605 ((mediacodec_error_cb)handle->error_cb)(error, handle->error_cb_userdata);
611 static gboolean __mediacodec_eos_cb(void *user_data)
613 if(user_data == NULL)
616 mediacodec_s * handle = (mediacodec_s *) user_data;
618 if ( handle->eos_cb )
620 ((mediacodec_eos_cb)handle->eos_cb)(handle->eos_cb_userdata);
626 static gboolean __mediacodec_supported_codec_cb(mediacodec_codec_type_e codec_type, void *user_data)
628 if(user_data == NULL)
631 mediacodec_s * handle = (mediacodec_s *) user_data;
633 if ( handle->supported_codec_cb )
635 return ((mediacodec_supported_codec_cb)handle->supported_codec_cb)(codec_type, handle->supported_codec_cb_userdata);
640 static gboolean __mediacodec_buffer_status_cb(mediacodec_status_e status, void *user_data)
642 if(user_data == NULL)
645 mediacodec_s * handle = (mediacodec_s *) user_data;
647 if ( handle->buffer_status_cb )
649 ((mediacodec_buffer_status_cb)handle->buffer_status_cb)(status, handle->buffer_status_cb_userdata);