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 gboolean __mediacodec_buffer_status_cb(mediacodec_status_e status, void *user_data);
35 * Internal Implementation
37 int __convert_error_code(int code, char *func_name)
39 int ret = MEDIACODEC_ERROR_INVALID_OPERATION;
40 char *msg = "MEDIACOODEC_INVALID_OPERATION";
44 ret = MEDIACODEC_ERROR_NONE;
45 msg = "MEDIACODEC_ERROR_NONE";
49 ret = MEDIACODEC_ERROR_INVALID_PARAMETER;
50 msg = "MEDIACODEC_ERROR_INVALID_PARAMETER";
52 case MC_PERMISSION_DENIED:
53 ret = MEDIACODEC_ERROR_PERMISSION_DENIED;
54 msg = "MEDIACODEC_ERROR_PERMISSION_DENIED";
56 case MC_INVALID_STATUS:
57 ret = MEDIACODEC_ERROR_INVALID_STATE;
58 msg = "MEDIACODEC_ERROR_INVALID_STATE";
60 case MC_NOT_SUPPORTED:
61 ret = MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE;
62 msg = "MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE";
65 case MC_INTERNAL_ERROR:
67 ret = MEDIACODEC_ERROR_INVALID_OPERATION;
68 msg = "MEDIACODEC_ERROR_INVALID_OPERATION";
70 case MC_INVALID_STREAM:
71 ret = MEDIACODEC_ERROR_INVALID_STREAM;
72 msg = "MEDIACODEC_ERROR_INVALID_STREAM";
74 case MC_CODEC_NOT_FOUND:
75 ret = MEDIACODEC_ERROR_CODEC_NOT_FOUND;
76 msg = "MEDIACODEC_ERROR_CODEC_NOT_FOUND";
79 ret = MEDIACODEC_ERROR_DECODE;
80 msg = "MEDIACODEC_ERROR_DECODE";
82 case MC_INVALID_IN_BUF:
83 ret = MEDIACODEC_ERROR_INVALID_INBUFFER;
84 msg = "MEDIACODEC_ERROR_INVALID_INBUFFER";
86 case MC_INVALID_OUT_BUF:
87 ret = MEDIACODEC_ERROR_INVALID_OUTBUFFER;
88 msg = "MEDIACODEC_ERROR_INVALID_OUTBUFFER";
90 case MC_NOT_INITIALIZED:
91 ret = MEDIACODEC_ERROR_NOT_INITIALIZED;
92 msg = "MEDIACODEC_ERROR_NOT_INITIALIZED";
94 case MC_OUTPUT_BUFFER_EMPTY:
95 case MC_OUTPUT_BUFFER_OVERFLOW:
96 ret = MEDIACODEC_ERROR_BUFFER_NOT_AVAILABLE;
97 msg = "MEDIACODEC_ERROR_BUFFER_NOT_AVAILABLE";
99 case MC_OUT_OF_MEMORY:
100 ret = MEDIACODEC_ERROR_OUT_OF_MEMORY;
101 msg = "MEDIACODEC_ERROR_OUT_OF_MEMORY";
104 ret = MEDIACODEC_ERROR_INTERNAL;
105 msg = "MEDIACODEC_ERROR_INTERNAL";
108 LOGD("[%s] %s(0x%08x) : core fw error(0x%x)", func_name, msg, ret, code);
113 * Public Implementation
116 int mediacodec_create(mediacodec_h *mediacodec)
118 MEDIACODEC_INSTANCE_CHECK(mediacodec);
119 mediacodec_s *handle;
122 LOGD("mediacodec_create..");
124 handle = (mediacodec_s *)malloc(sizeof(mediacodec_s));
125 if (handle != NULL) {
126 memset(handle, 0 , sizeof(mediacodec_s));
128 LOGE("MEDIACODEC_ERROR_OUT_OF_MEMORY(0x%08x)", MEDIACODEC_ERROR_OUT_OF_MEMORY);
129 return MEDIACODEC_ERROR_OUT_OF_MEMORY;
132 ret = mc_create(&handle->mc_handle);
133 if (ret != MEDIACODEC_ERROR_NONE) {
134 LOGE("MEDIACODEC_ERROR_INVALID_OPERATION(0x%08x)", MEDIACODEC_ERROR_INVALID_OPERATION);
135 handle->state = MEDIACODEC_STATE_NONE;
136 g_free(handle->mc_handle);
139 return MEDIACODEC_ERROR_INVALID_OPERATION;
141 *mediacodec = (mediacodec_h)handle;
142 handle->state = MEDIACODEC_STATE_IDLE;
143 LOGD("new handle : %p", *mediacodec);
147 mc_set_empty_buffer_cb(handle->mc_handle, (mediacodec_input_buffer_used_cb)__mediacodec_empty_buffer_cb, handle);
148 mc_set_fill_buffer_cb(handle->mc_handle, (mediacodec_output_buffer_available_cb)__mediacodec_fill_buffer_cb, handle);
149 mc_set_error_cb(handle->mc_handle, (mediacodec_error_cb)__mediacodec_error_cb, handle);
150 mc_set_eos_cb(handle->mc_handle, (mediacodec_eos_cb)__mediacodec_eos_cb, handle);
151 mc_set_buffer_status_cb(handle->mc_handle, (mediacodec_buffer_status_cb)__mediacodec_buffer_status_cb, handle);
152 mc_set_supported_codec_cb(handle->mc_handle, (mediacodec_supported_codec_cb)__mediacodec_supported_codec_cb, handle);
154 return MEDIACODEC_ERROR_NONE;
158 int mediacodec_destroy(mediacodec_h mediacodec)
160 LOGD("[%s] Start, handle to destroy : %p", __FUNCTION__, mediacodec);
161 MEDIACODEC_INSTANCE_CHECK(mediacodec);
162 mediacodec_s *handle = (mediacodec_s *)mediacodec;
164 int ret = mc_destroy(handle->mc_handle);
165 if (ret != MEDIACODEC_ERROR_NONE) {
166 LOGD("MEDIACODEC_ERROR_INVALID_OPERATION(0x%08x)", MEDIACODEC_ERROR_INVALID_OPERATION);
167 return MEDIACODEC_ERROR_INVALID_OPERATION;
169 handle->state = MEDIACODEC_STATE_NONE;
172 return MEDIACODEC_ERROR_NONE;
176 int mediacodec_set_codec(mediacodec_h mediacodec, mediacodec_codec_type_e codec_id, int flags)
178 MEDIACODEC_INSTANCE_CHECK(mediacodec);
179 mediacodec_s *handle = (mediacodec_s *)mediacodec;
180 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
182 int ret = mc_set_codec(handle->mc_handle, codec_id, flags);
184 if (ret != MEDIACODEC_ERROR_NONE) {
185 return __convert_error_code(ret, (char *)__FUNCTION__);
187 handle->state = MEDIACODEC_STATE_IDLE;
188 return MEDIACODEC_ERROR_NONE;
192 int mediacodec_set_vdec_info(mediacodec_h mediacodec, int width, int height)
194 MEDIACODEC_INSTANCE_CHECK(mediacodec);
195 mediacodec_s *handle = (mediacodec_s *)mediacodec;
196 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
198 int ret = mc_set_vdec_info(handle->mc_handle, width, height);
200 if (ret != MEDIACODEC_ERROR_NONE) {
201 return __convert_error_code(ret, (char *)__FUNCTION__);
203 handle->state = MEDIACODEC_STATE_IDLE;
204 return MEDIACODEC_ERROR_NONE;
208 int mediacodec_set_venc_info(mediacodec_h mediacodec, int width, int height, int fps, int target_bits)
210 MEDIACODEC_INSTANCE_CHECK(mediacodec);
211 mediacodec_s *handle = (mediacodec_s *)mediacodec;
212 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
214 int ret = mc_set_venc_info(handle->mc_handle, width, height, fps, target_bits);
216 if (ret != MEDIACODEC_ERROR_NONE) {
217 return __convert_error_code(ret, (char *)__FUNCTION__);
219 handle->state = MEDIACODEC_STATE_IDLE;
220 return MEDIACODEC_ERROR_NONE;
224 int mediacodec_set_adec_info(mediacodec_h mediacodec, int samplerate, int channel, int bit)
226 MEDIACODEC_INSTANCE_CHECK(mediacodec);
227 mediacodec_s *handle = (mediacodec_s *)mediacodec;
228 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
230 int ret = mc_set_adec_info(handle->mc_handle, samplerate, channel, bit);
232 if (ret != MEDIACODEC_ERROR_NONE) {
233 return __convert_error_code(ret, (char *)__FUNCTION__);
235 handle->state = MEDIACODEC_STATE_IDLE;
236 return MEDIACODEC_ERROR_NONE;
240 int mediacodec_set_aenc_info(mediacodec_h mediacodec, int samplerate, int channel, int bit, int bitrate)
242 MEDIACODEC_INSTANCE_CHECK(mediacodec);
243 mediacodec_s *handle = (mediacodec_s *)mediacodec;
244 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
246 int ret = mc_set_aenc_info(handle->mc_handle, samplerate, channel, bit, bitrate);
248 if (ret != MEDIACODEC_ERROR_NONE) {
249 return __convert_error_code(ret, (char *)__FUNCTION__);
251 handle->state = MEDIACODEC_STATE_IDLE;
252 return MEDIACODEC_ERROR_NONE;
256 int mediacodec_prepare(mediacodec_h mediacodec)
258 MEDIACODEC_INSTANCE_CHECK(mediacodec);
259 mediacodec_s *handle = (mediacodec_s *)mediacodec;
260 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
262 int ret = mc_prepare(handle->mc_handle);
264 if (ret != MEDIACODEC_ERROR_NONE) {
265 return __convert_error_code(ret, (char *)__FUNCTION__);
267 handle->state = MEDIACODEC_STATE_READY;
268 return MEDIACODEC_ERROR_NONE;
272 int mediacodec_unprepare(mediacodec_h mediacodec)
274 MEDIACODEC_INSTANCE_CHECK(mediacodec);
275 mediacodec_s *handle = (mediacodec_s *)mediacodec;
277 int ret = mc_unprepare(handle->mc_handle);
279 if (ret != MEDIACODEC_ERROR_NONE) {
280 return __convert_error_code(ret, (char *)__FUNCTION__);
282 handle->state = MEDIACODEC_STATE_IDLE;
283 return MEDIACODEC_ERROR_NONE;
287 int mediacodec_process_input(mediacodec_h mediacodec, media_packet_h inbuf, uint64_t timeOutUs)
289 MEDIACODEC_INSTANCE_CHECK(mediacodec);
290 mediacodec_s *handle = (mediacodec_s *)mediacodec;
291 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_READY);
293 int ret = mc_process_input(handle->mc_handle, inbuf, timeOutUs);
295 if (ret != MEDIACODEC_ERROR_NONE)
296 return __convert_error_code(ret, (char *)__FUNCTION__);
298 return MEDIACODEC_ERROR_NONE;
301 int mediacodec_get_output(mediacodec_h mediacodec, media_packet_h *outbuf, uint64_t timeOutUs)
303 MEDIACODEC_INSTANCE_CHECK(mediacodec);
304 mediacodec_s *handle = (mediacodec_s *)mediacodec;
305 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_READY);
307 int ret = mc_get_output(handle->mc_handle, outbuf, timeOutUs);
309 if (ret != MEDIACODEC_ERROR_NONE)
310 return __convert_error_code(ret, (char *)__FUNCTION__);
312 return MEDIACODEC_ERROR_NONE;
315 int mediacodec_flush_buffers(mediacodec_h mediacodec)
317 MEDIACODEC_INSTANCE_CHECK(mediacodec);
318 mediacodec_s *handle = (mediacodec_s *)mediacodec;
320 int ret = mc_flush_buffers(handle->mc_handle);
322 if (ret != MEDIACODEC_ERROR_NONE)
323 return __convert_error_code(ret, (char *)__FUNCTION__);
325 return MEDIACODEC_ERROR_NONE;
328 int mediacodec_get_supported_type(mediacodec_h mediacodec, mediacodec_codec_type_e codec_type, bool encoder, int *support_type)
330 MEDIACODEC_INSTANCE_CHECK(mediacodec);
331 mediacodec_s *handle = (mediacodec_s *)mediacodec;
332 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
334 int ret = mc_get_supported_type(handle->mc_handle, codec_type, encoder, support_type);
336 if (ret != MEDIACODEC_ERROR_NONE)
337 return __convert_error_code(ret, (char *)__FUNCTION__);
339 handle->state = MEDIACODEC_STATE_IDLE;
340 return MEDIACODEC_ERROR_NONE;
343 int mediacodec_set_input_buffer_used_cb(mediacodec_h mediacodec, mediacodec_input_buffer_used_cb callback, void *user_data)
345 MEDIACODEC_INSTANCE_CHECK(mediacodec);
346 mediacodec_s *handle = (mediacodec_s *)mediacodec;
347 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
349 handle->empty_buffer_cb = callback;
350 handle->empty_buffer_cb_userdata = user_data;
352 LOGD("set empty_buffer_cb(%p)", callback);
354 return MEDIACODEC_ERROR_NONE;
357 int mediacodec_unset_input_buffer_used_cb(mediacodec_h mediacodec)
359 MEDIACODEC_INSTANCE_CHECK(mediacodec);
360 mediacodec_s *handle = (mediacodec_s *)mediacodec;
362 handle->empty_buffer_cb = NULL;
363 handle->empty_buffer_cb_userdata = NULL;
365 return MEDIACODEC_ERROR_NONE;
369 int mediacodec_set_output_buffer_available_cb(mediacodec_h mediacodec, mediacodec_output_buffer_available_cb callback, void *user_data)
371 MEDIACODEC_INSTANCE_CHECK(mediacodec);
372 mediacodec_s *handle = (mediacodec_s *)mediacodec;
373 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
375 handle->fill_buffer_cb = callback;
376 handle->fill_buffer_cb_userdata = user_data;
378 LOGD("set fill_buffer_cb(%p)", callback);
380 return MEDIACODEC_ERROR_NONE;
384 int mediacodec_unset_output_buffer_available_cb(mediacodec_h mediacodec)
386 MEDIACODEC_INSTANCE_CHECK(mediacodec);
387 mediacodec_s *handle = (mediacodec_s *)mediacodec;
389 handle->fill_buffer_cb = NULL;
390 handle->fill_buffer_cb_userdata = NULL;
392 return MEDIACODEC_ERROR_NONE;
395 int mediacodec_set_error_cb(mediacodec_h mediacodec, mediacodec_error_cb callback, void *user_data)
397 MEDIACODEC_INSTANCE_CHECK(mediacodec);
398 mediacodec_s *handle = (mediacodec_s *)mediacodec;
399 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
401 handle->error_cb = callback;
402 handle->error_cb_userdata = user_data;
404 LOGD("set error_cb(%p)", callback);
406 return MEDIACODEC_ERROR_NONE;
410 int mediacodec_unset_error_cb(mediacodec_h mediacodec)
412 MEDIACODEC_INSTANCE_CHECK(mediacodec);
413 mediacodec_s *handle = (mediacodec_s *)mediacodec;
415 handle->error_cb = NULL;
416 handle->error_cb_userdata = NULL;
418 return MEDIACODEC_ERROR_NONE;
421 int mediacodec_set_eos_cb(mediacodec_h mediacodec, mediacodec_eos_cb callback, void *user_data)
423 MEDIACODEC_INSTANCE_CHECK(mediacodec);
424 mediacodec_s *handle = (mediacodec_s *)mediacodec;
425 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
427 handle->eos_cb = callback;
428 handle->eos_cb_userdata = user_data;
430 LOGD("set eos_cb(%p)", callback);
432 return MEDIACODEC_ERROR_NONE;
436 int mediacodec_unset_eos_cb(mediacodec_h mediacodec)
438 MEDIACODEC_INSTANCE_CHECK(mediacodec);
439 mediacodec_s *handle = (mediacodec_s *)mediacodec;
441 handle->eos_cb = NULL;
442 handle->eos_cb_userdata = NULL;
444 return MEDIACODEC_ERROR_NONE;
447 int mediacodec_set_buffer_status_cb(mediacodec_h mediacodec, mediacodec_buffer_status_cb callback, void *user_data)
449 MEDIACODEC_INSTANCE_CHECK(mediacodec);
450 mediacodec_s *handle = (mediacodec_s *)mediacodec;
451 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
453 handle->buffer_status_cb = callback;
454 handle->buffer_status_cb_userdata = user_data;
456 LOGD("set buffer_status_cb(%p)", callback);
458 return MEDIACODEC_ERROR_NONE;
462 int mediacodec_unset_buffer_status_cb(mediacodec_h mediacodec)
464 MEDIACODEC_INSTANCE_CHECK(mediacodec);
465 mediacodec_s *handle = (mediacodec_s *)mediacodec;
467 handle->buffer_status_cb = NULL;
468 handle->buffer_status_cb_userdata = NULL;
470 return MEDIACODEC_ERROR_NONE;
473 int mediacodec_foreach_supported_codec(mediacodec_h mediacodec, mediacodec_supported_codec_cb callback, void *user_data)
475 MEDIACODEC_INSTANCE_CHECK(mediacodec);
476 mediacodec_s *handle = (mediacodec_s *)mediacodec;
478 handle->supported_codec_cb = callback;
479 handle->supported_codec_cb_userdata = user_data;
481 LOGD("set supported_codec_cb(%p)", callback);
482 int ret = _mediacodec_foreach_supported_codec(callback, handle);
484 if (ret != MEDIACODEC_ERROR_NONE)
485 return __convert_error_code(ret, (char *)__FUNCTION__);
487 return MEDIACODEC_ERROR_NONE;
489 return MEDIACODEC_ERROR_NONE;
493 int mediacodec_get_packet_pool(mediacodec_h mediacodec, media_packet_pool_h *pkt_pool)
495 MEDIACODEC_INSTANCE_CHECK(mediacodec);
496 mediacodec_s *handle = (mediacodec_s *)mediacodec;
497 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_READY);
498 int ret = mc_get_packet_pool(handle->mc_handle, pkt_pool);
500 if (ret != MEDIACODEC_ERROR_NONE)
501 return MEDIACODEC_ERROR_INVALID_OPERATION;
503 return MEDIACODEC_ERROR_NONE;
506 static gboolean __mediacodec_empty_buffer_cb(media_packet_h pkt, void *user_data)
508 if (user_data == NULL || pkt == NULL)
511 mediacodec_s *handle = (mediacodec_s *)user_data;
513 if (handle->empty_buffer_cb)
514 ((mediacodec_input_buffer_used_cb)handle->empty_buffer_cb)(pkt, handle->empty_buffer_cb_userdata);
519 static gboolean __mediacodec_fill_buffer_cb(media_packet_h pkt, void *user_data)
521 if (user_data == NULL || pkt == NULL)
524 mediacodec_s *handle = (mediacodec_s *)user_data;
526 if (handle->fill_buffer_cb)
527 ((mediacodec_output_buffer_available_cb)handle->fill_buffer_cb)(pkt, handle->fill_buffer_cb_userdata);
532 static gboolean __mediacodec_error_cb(mediacodec_error_e error, void *user_data)
534 if (user_data == NULL)
537 mediacodec_s *handle = (mediacodec_s *)user_data;
539 if (handle->error_cb)
540 ((mediacodec_error_cb)handle->error_cb)(error, handle->error_cb_userdata);
545 static gboolean __mediacodec_eos_cb(void *user_data)
547 if (user_data == NULL)
550 mediacodec_s *handle = (mediacodec_s *)user_data;
553 ((mediacodec_eos_cb)handle->eos_cb)(handle->eos_cb_userdata);
558 static gboolean __mediacodec_supported_codec_cb(mediacodec_codec_type_e codec_type, void *user_data)
560 if (user_data == NULL)
563 mediacodec_s *handle = (mediacodec_s *)user_data;
565 if (handle->supported_codec_cb)
566 return ((mediacodec_supported_codec_cb)handle->supported_codec_cb)(codec_type, handle->supported_codec_cb_userdata);
571 static gboolean __mediacodec_buffer_status_cb(mediacodec_status_e status, void *user_data)
573 if (user_data == NULL)
576 mediacodec_s *handle = (mediacodec_s *)user_data;
578 if (handle->buffer_status_cb)
579 ((mediacodec_buffer_status_cb)handle->buffer_status_cb)(status, handle->buffer_status_cb_userdata);