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;
341 return MEDIACODEC_ERROR_NONE;
344 int mediacodec_set_input_buffer_used_cb(mediacodec_h mediacodec, mediacodec_input_buffer_used_cb callback, void *user_data)
346 MEDIACODEC_INSTANCE_CHECK(mediacodec);
347 mediacodec_s *handle = (mediacodec_s *)mediacodec;
348 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
350 handle->empty_buffer_cb = callback;
351 handle->empty_buffer_cb_userdata = user_data;
353 LOGD("set empty_buffer_cb(%p)", callback);
355 return MEDIACODEC_ERROR_NONE;
358 int mediacodec_unset_input_buffer_used_cb(mediacodec_h mediacodec)
360 MEDIACODEC_INSTANCE_CHECK(mediacodec);
361 mediacodec_s *handle = (mediacodec_s *)mediacodec;
363 handle->empty_buffer_cb = NULL;
364 handle->empty_buffer_cb_userdata = NULL;
366 return MEDIACODEC_ERROR_NONE;
370 int mediacodec_set_output_buffer_available_cb(mediacodec_h mediacodec, mediacodec_output_buffer_available_cb callback, void *user_data)
372 MEDIACODEC_INSTANCE_CHECK(mediacodec);
373 mediacodec_s *handle = (mediacodec_s *)mediacodec;
374 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
376 handle->fill_buffer_cb = callback;
377 handle->fill_buffer_cb_userdata = user_data;
379 LOGD("set fill_buffer_cb(%p)", callback);
381 return MEDIACODEC_ERROR_NONE;
385 int mediacodec_unset_output_buffer_available_cb(mediacodec_h mediacodec)
387 MEDIACODEC_INSTANCE_CHECK(mediacodec);
388 mediacodec_s *handle = (mediacodec_s *)mediacodec;
390 handle->fill_buffer_cb = NULL;
391 handle->fill_buffer_cb_userdata = NULL;
393 return MEDIACODEC_ERROR_NONE;
396 int mediacodec_set_error_cb(mediacodec_h mediacodec, mediacodec_error_cb callback, void *user_data)
398 MEDIACODEC_INSTANCE_CHECK(mediacodec);
399 mediacodec_s *handle = (mediacodec_s *)mediacodec;
400 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
402 handle->error_cb = callback;
403 handle->error_cb_userdata = user_data;
405 LOGD("set error_cb(%p)", callback);
407 return MEDIACODEC_ERROR_NONE;
411 int mediacodec_unset_error_cb(mediacodec_h mediacodec)
413 MEDIACODEC_INSTANCE_CHECK(mediacodec);
414 mediacodec_s *handle = (mediacodec_s *)mediacodec;
416 handle->error_cb = NULL;
417 handle->error_cb_userdata = NULL;
419 return MEDIACODEC_ERROR_NONE;
422 int mediacodec_set_eos_cb(mediacodec_h mediacodec, mediacodec_eos_cb callback, void *user_data)
424 MEDIACODEC_INSTANCE_CHECK(mediacodec);
425 mediacodec_s *handle = (mediacodec_s *)mediacodec;
426 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
428 handle->eos_cb = callback;
429 handle->eos_cb_userdata = user_data;
431 LOGD("set eos_cb(%p)", callback);
433 return MEDIACODEC_ERROR_NONE;
437 int mediacodec_unset_eos_cb(mediacodec_h mediacodec)
439 MEDIACODEC_INSTANCE_CHECK(mediacodec);
440 mediacodec_s *handle = (mediacodec_s *)mediacodec;
442 handle->eos_cb = NULL;
443 handle->eos_cb_userdata = NULL;
445 return MEDIACODEC_ERROR_NONE;
448 int mediacodec_set_buffer_status_cb(mediacodec_h mediacodec, mediacodec_buffer_status_cb callback, void *user_data)
450 MEDIACODEC_INSTANCE_CHECK(mediacodec);
451 mediacodec_s *handle = (mediacodec_s *)mediacodec;
452 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
454 handle->buffer_status_cb = callback;
455 handle->buffer_status_cb_userdata = user_data;
457 LOGD("set buffer_status_cb(%p)", callback);
459 return MEDIACODEC_ERROR_NONE;
463 int mediacodec_unset_buffer_status_cb(mediacodec_h mediacodec)
465 MEDIACODEC_INSTANCE_CHECK(mediacodec);
466 mediacodec_s *handle = (mediacodec_s *)mediacodec;
468 handle->buffer_status_cb = NULL;
469 handle->buffer_status_cb_userdata = NULL;
471 return MEDIACODEC_ERROR_NONE;
474 int mediacodec_foreach_supported_codec(mediacodec_h mediacodec, mediacodec_supported_codec_cb callback, void *user_data)
476 MEDIACODEC_INSTANCE_CHECK(mediacodec);
477 mediacodec_s *handle = (mediacodec_s *)mediacodec;
479 handle->supported_codec_cb = callback;
480 handle->supported_codec_cb_userdata = user_data;
482 LOGD("set supported_codec_cb(%p)", callback);
483 int ret = _mediacodec_foreach_supported_codec(callback, handle);
485 if (ret != MEDIACODEC_ERROR_NONE)
486 return __convert_error_code(ret, (char *)__FUNCTION__);
488 return MEDIACODEC_ERROR_NONE;
490 return MEDIACODEC_ERROR_NONE;
494 int mediacodec_get_packet_pool(mediacodec_h mediacodec, media_packet_pool_h *pkt_pool)
496 MEDIACODEC_INSTANCE_CHECK(mediacodec);
497 mediacodec_s *handle = (mediacodec_s *)mediacodec;
498 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_READY);
499 int ret = mc_get_packet_pool(handle->mc_handle, pkt_pool);
501 if (ret != MEDIACODEC_ERROR_NONE)
502 return MEDIACODEC_ERROR_INVALID_OPERATION;
504 return MEDIACODEC_ERROR_NONE;
507 static gboolean __mediacodec_empty_buffer_cb(media_packet_h pkt, void *user_data)
509 if (user_data == NULL || pkt == NULL)
512 mediacodec_s *handle = (mediacodec_s *)user_data;
514 if (handle->empty_buffer_cb)
515 ((mediacodec_input_buffer_used_cb)handle->empty_buffer_cb)(pkt, handle->empty_buffer_cb_userdata);
520 static gboolean __mediacodec_fill_buffer_cb(media_packet_h pkt, void *user_data)
522 if (user_data == NULL || pkt == NULL)
525 mediacodec_s *handle = (mediacodec_s *)user_data;
527 if (handle->fill_buffer_cb)
528 ((mediacodec_output_buffer_available_cb)handle->fill_buffer_cb)(pkt, handle->fill_buffer_cb_userdata);
533 static gboolean __mediacodec_error_cb(mediacodec_error_e error, void *user_data)
535 if (user_data == NULL)
538 mediacodec_s *handle = (mediacodec_s *)user_data;
540 if (handle->error_cb)
541 ((mediacodec_error_cb)handle->error_cb)(error, handle->error_cb_userdata);
546 static gboolean __mediacodec_eos_cb(void *user_data)
548 if (user_data == NULL)
551 mediacodec_s *handle = (mediacodec_s *)user_data;
554 ((mediacodec_eos_cb)handle->eos_cb)(handle->eos_cb_userdata);
559 static gboolean __mediacodec_supported_codec_cb(mediacodec_codec_type_e codec_type, void *user_data)
561 if (user_data == NULL)
564 mediacodec_s *handle = (mediacodec_s *)user_data;
566 if (handle->supported_codec_cb)
567 return ((mediacodec_supported_codec_cb)handle->supported_codec_cb)(codec_type, handle->supported_codec_cb_userdata);
572 static gboolean __mediacodec_buffer_status_cb(mediacodec_status_e status, void *user_data)
574 if (user_data == NULL)
577 mediacodec_s *handle = (mediacodec_s *)user_data;
579 if (handle->buffer_status_cb)
580 ((mediacodec_buffer_status_cb)handle->buffer_status_cb)(status, handle->buffer_status_cb_userdata);