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);
36 * Internal Implementation
38 int __convert_error_code(int code, char *func_name)
40 int ret = MEDIACODEC_ERROR_INVALID_OPERATION;
41 char *msg = "MEDIACOODEC_INVALID_OPERATION";
45 ret = MEDIACODEC_ERROR_NONE;
46 msg = "MEDIACODEC_ERROR_NONE";
50 ret = MEDIACODEC_ERROR_INVALID_PARAMETER;
51 msg = "MEDIACODEC_ERROR_INVALID_PARAMETER";
53 case MC_PERMISSION_DENIED:
54 ret = MEDIACODEC_ERROR_PERMISSION_DENIED;
55 msg = "MEDIACODEC_ERROR_PERMISSION_DENIED";
57 case MC_INVALID_STATUS:
58 ret = MEDIACODEC_ERROR_INVALID_STATE;
59 msg = "MEDIACODEC_ERROR_INVALID_STATE";
61 case MC_NOT_SUPPORTED:
62 ret = MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE;
63 msg = "MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE";
66 case MC_INTERNAL_ERROR:
68 ret = MEDIACODEC_ERROR_INVALID_OPERATION;
69 msg = "MEDIACODEC_ERROR_INVALID_OPERATION";
71 case MC_INVALID_STREAM:
72 ret = MEDIACODEC_ERROR_INVALID_STREAM;
73 msg = "MEDIACODEC_ERROR_INVALID_STREAM";
75 case MC_CODEC_NOT_FOUND:
76 ret = MEDIACODEC_ERROR_CODEC_NOT_FOUND;
77 msg = "MEDIACODEC_ERROR_CODEC_NOT_FOUND";
80 ret = MEDIACODEC_ERROR_DECODE;
81 msg = "MEDIACODEC_ERROR_DECODE";
83 case MC_INVALID_IN_BUF:
84 ret = MEDIACODEC_ERROR_INVALID_INBUFFER;
85 msg = "MEDIACODEC_ERROR_INVALID_INBUFFER";
87 case MC_INVALID_OUT_BUF:
88 ret = MEDIACODEC_ERROR_INVALID_OUTBUFFER;
89 msg = "MEDIACODEC_ERROR_INVALID_OUTBUFFER";
91 case MC_NOT_INITIALIZED:
92 ret = MEDIACODEC_ERROR_NOT_INITIALIZED;
93 msg = "MEDIACODEC_ERROR_NOT_INITIALIZED";
95 case MC_OUTPUT_BUFFER_EMPTY:
96 case MC_OUTPUT_BUFFER_OVERFLOW:
97 ret = MEDIACODEC_ERROR_BUFFER_NOT_AVAILABLE;
98 msg = "MEDIACODEC_ERROR_BUFFER_NOT_AVAILABLE";
101 ret = MEDIACODEC_ERROR_INTERNAL;
102 msg = "MEDIACODEC_ERROR_INTERNAL";
105 LOGD("[%s] %s(0x%08x) : core fw error(0x%x)", func_name, msg, ret, code);
110 * Public Implementation
113 int mediacodec_create(mediacodec_h *mediacodec)
115 MEDIACODEC_INSTANCE_CHECK(mediacodec);
116 mediacodec_s *handle;
119 LOGD("mediacodec_create..");
121 handle = (mediacodec_s *)malloc(sizeof(mediacodec_s));
122 if (handle != NULL) {
123 memset(handle, 0 , sizeof(mediacodec_s));
125 LOGE("MEDIACODEC_ERROR_OUT_OF_MEMORY(0x%08x)", MEDIACODEC_ERROR_OUT_OF_MEMORY);
126 return MEDIACODEC_ERROR_OUT_OF_MEMORY;
129 ret = mc_create(&handle->mc_handle);
130 if (ret != MEDIACODEC_ERROR_NONE) {
131 LOGE("MEDIACODEC_ERROR_INVALID_OPERATION(0x%08x)", MEDIACODEC_ERROR_INVALID_OPERATION);
132 handle->state = MEDIACODEC_STATE_NONE;
135 return MEDIACODEC_ERROR_INVALID_OPERATION;
137 *mediacodec = (mediacodec_h)handle;
138 handle->state = MEDIACODEC_STATE_IDLE;
139 LOGD("new handle : %p", *mediacodec);
143 mc_set_empty_buffer_cb(handle->mc_handle, (mediacodec_input_buffer_used_cb)__mediacodec_empty_buffer_cb, handle);
144 mc_set_fill_buffer_cb(handle->mc_handle, (mediacodec_output_buffer_available_cb)__mediacodec_fill_buffer_cb, handle);
145 mc_set_error_cb(handle->mc_handle, (mediacodec_error_cb)__mediacodec_error_cb, handle);
146 mc_set_eos_cb(handle->mc_handle, (mediacodec_eos_cb)__mediacodec_eos_cb, handle);
147 mc_set_buffer_status_cb(handle->mc_handle, (mediacodec_buffer_status_cb)__mediacodec_buffer_status_cb, handle);
148 mc_set_supported_codec_cb(handle->mc_handle, (mediacodec_supported_codec_cb)__mediacodec_supported_codec_cb, handle);
150 return MEDIACODEC_ERROR_NONE;
154 int mediacodec_destroy(mediacodec_h mediacodec)
156 LOGD("[%s] Start, handle to destroy : %p", __FUNCTION__, mediacodec);
157 MEDIACODEC_INSTANCE_CHECK(mediacodec);
158 mediacodec_s *handle = (mediacodec_s *)mediacodec;
160 int ret = mc_destroy(handle->mc_handle);
161 if (ret != MEDIACODEC_ERROR_NONE) {
162 LOGD("MEDIACODEC_ERROR_INVALID_OPERATION(0x%08x)", MEDIACODEC_ERROR_INVALID_OPERATION);
163 return MEDIACODEC_ERROR_INVALID_OPERATION;
165 handle->state = MEDIACODEC_STATE_NONE;
168 return MEDIACODEC_ERROR_NONE;
172 int mediacodec_set_codec(mediacodec_h mediacodec, mediacodec_codec_type_e codec_id, mediacodec_support_type_e flags)
174 MEDIACODEC_INSTANCE_CHECK(mediacodec);
175 mediacodec_s *handle = (mediacodec_s *)mediacodec;
176 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
178 int ret = mc_set_codec(handle->mc_handle, codec_id, flags);
180 if (ret != MEDIACODEC_ERROR_NONE) {
181 return __convert_error_code(ret, (char *)__FUNCTION__);
183 handle->state = MEDIACODEC_STATE_IDLE;
184 return MEDIACODEC_ERROR_NONE;
188 int mediacodec_set_vdec_info(mediacodec_h mediacodec, int width, int height)
190 MEDIACODEC_INSTANCE_CHECK(mediacodec);
191 mediacodec_s *handle = (mediacodec_s *)mediacodec;
192 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
194 int ret = mc_set_vdec_info(handle->mc_handle, width, height);
196 if (ret != MEDIACODEC_ERROR_NONE) {
197 return __convert_error_code(ret, (char *)__FUNCTION__);
199 handle->state = MEDIACODEC_STATE_IDLE;
200 return MEDIACODEC_ERROR_NONE;
204 int mediacodec_set_venc_info(mediacodec_h mediacodec, int width, int height, int fps, int target_bits)
206 MEDIACODEC_INSTANCE_CHECK(mediacodec);
207 mediacodec_s *handle = (mediacodec_s *)mediacodec;
208 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
210 int ret = mc_set_venc_info(handle->mc_handle, width, height, fps, target_bits);
212 if (ret != MEDIACODEC_ERROR_NONE) {
213 return __convert_error_code(ret, (char *)__FUNCTION__);
215 handle->state = MEDIACODEC_STATE_IDLE;
216 return MEDIACODEC_ERROR_NONE;
220 int mediacodec_set_adec_info(mediacodec_h mediacodec, int samplerate, int channel, int bit)
222 MEDIACODEC_INSTANCE_CHECK(mediacodec);
223 mediacodec_s *handle = (mediacodec_s *)mediacodec;
224 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
226 int ret = mc_set_adec_info(handle->mc_handle, samplerate, channel, bit);
228 if (ret != MEDIACODEC_ERROR_NONE) {
229 return __convert_error_code(ret, (char *)__FUNCTION__);
231 handle->state = MEDIACODEC_STATE_IDLE;
232 return MEDIACODEC_ERROR_NONE;
236 int mediacodec_set_aenc_info(mediacodec_h mediacodec, int samplerate, int channel, int bit, int bitrate)
238 MEDIACODEC_INSTANCE_CHECK(mediacodec);
239 mediacodec_s *handle = (mediacodec_s *)mediacodec;
240 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
242 int ret = mc_set_aenc_info(handle->mc_handle, samplerate, channel, bit, bitrate);
244 if (ret != MEDIACODEC_ERROR_NONE) {
245 return __convert_error_code(ret, (char *)__FUNCTION__);
247 handle->state = MEDIACODEC_STATE_IDLE;
248 return MEDIACODEC_ERROR_NONE;
252 int mediacodec_prepare(mediacodec_h mediacodec)
254 MEDIACODEC_INSTANCE_CHECK(mediacodec);
255 mediacodec_s *handle = (mediacodec_s *)mediacodec;
256 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
258 int ret = mc_prepare(handle->mc_handle);
260 if (ret != MEDIACODEC_ERROR_NONE) {
261 return __convert_error_code(ret, (char *)__FUNCTION__);
263 handle->state = MEDIACODEC_STATE_READY;
264 return MEDIACODEC_ERROR_NONE;
268 int mediacodec_unprepare(mediacodec_h mediacodec)
270 MEDIACODEC_INSTANCE_CHECK(mediacodec);
271 mediacodec_s *handle = (mediacodec_s *)mediacodec;
273 int ret = mc_unprepare(handle->mc_handle);
275 if (ret != MEDIACODEC_ERROR_NONE) {
276 return __convert_error_code(ret, (char *)__FUNCTION__);
278 handle->state = MEDIACODEC_STATE_IDLE;
279 return MEDIACODEC_ERROR_NONE;
283 int mediacodec_process_input(mediacodec_h mediacodec, media_packet_h inbuf, uint64_t timeOutUs)
285 MEDIACODEC_INSTANCE_CHECK(mediacodec);
286 mediacodec_s *handle = (mediacodec_s *)mediacodec;
287 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_READY);
289 int ret = mc_process_input(handle->mc_handle, inbuf, timeOutUs);
291 if (ret != MEDIACODEC_ERROR_NONE) {
292 return __convert_error_code(ret, (char *)__FUNCTION__);
294 return MEDIACODEC_ERROR_NONE;
298 int mediacodec_get_output(mediacodec_h mediacodec, media_packet_h *outbuf, uint64_t timeOutUs)
300 MEDIACODEC_INSTANCE_CHECK(mediacodec);
301 mediacodec_s *handle = (mediacodec_s *)mediacodec;
302 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_READY);
304 int ret = mc_get_output(handle->mc_handle, outbuf, timeOutUs);
306 if (ret != MEDIACODEC_ERROR_NONE) {
307 return __convert_error_code(ret, (char *)__FUNCTION__);
309 return MEDIACODEC_ERROR_NONE;
313 int mediacodec_flush_buffers(mediacodec_h mediacodec)
315 MEDIACODEC_INSTANCE_CHECK(mediacodec);
316 mediacodec_s *handle = (mediacodec_s *)mediacodec;
318 int ret = mc_flush_buffers(handle->mc_handle);
320 if (ret != MEDIACODEC_ERROR_NONE) {
321 return __convert_error_code(ret, (char *)__FUNCTION__);
323 return MEDIACODEC_ERROR_NONE;
327 int mediacodec_get_supported_type(mediacodec_h mediacodec, mediacodec_codec_type_e codec_type, bool encoder, int *support_type)
329 MEDIACODEC_INSTANCE_CHECK(mediacodec);
330 mediacodec_s *handle = (mediacodec_s *)mediacodec;
331 MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
333 int ret = mc_get_supported_type(handle->mc_handle, codec_type, encoder, support_type);
335 if (ret != MEDIACODEC_ERROR_NONE) {
336 return __convert_error_code(ret, (char *)__FUNCTION__);
338 handle->state = MEDIACODEC_STATE_IDLE;
339 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(handle->mc_handle, callback, handle);
484 if (ret != MEDIACODEC_ERROR_NONE) {
485 return __convert_error_code(ret, (char *)__FUNCTION__);
487 return MEDIACODEC_ERROR_NONE;
490 return MEDIACODEC_ERROR_NONE;
494 static gboolean __mediacodec_empty_buffer_cb(media_packet_h pkt, void *user_data)
496 if (user_data == NULL || pkt == NULL)
499 mediacodec_s *handle = (mediacodec_s *)user_data;
501 if (handle->empty_buffer_cb) {
502 ((mediacodec_input_buffer_used_cb)handle->empty_buffer_cb)(pkt, handle->empty_buffer_cb_userdata);
508 static gboolean __mediacodec_fill_buffer_cb(media_packet_h pkt, void *user_data)
510 if (user_data == NULL || pkt == NULL)
513 mediacodec_s *handle = (mediacodec_s *)user_data;
515 if (handle->fill_buffer_cb) {
516 ((mediacodec_output_buffer_available_cb)handle->fill_buffer_cb)(pkt, handle->fill_buffer_cb_userdata);
522 static gboolean __mediacodec_error_cb(mediacodec_error_e error, void *user_data)
524 if (user_data == NULL)
527 mediacodec_s *handle = (mediacodec_s *)user_data;
529 if (handle->error_cb) {
530 ((mediacodec_error_cb)handle->error_cb)(error, handle->error_cb_userdata);
536 static gboolean __mediacodec_eos_cb(void *user_data)
538 if (user_data == NULL)
541 mediacodec_s *handle = (mediacodec_s *)user_data;
543 if (handle->eos_cb) {
544 ((mediacodec_eos_cb)handle->eos_cb)(handle->eos_cb_userdata);
550 static gboolean __mediacodec_supported_codec_cb(mediacodec_codec_type_e codec_type, void *user_data)
552 if (user_data == NULL)
555 mediacodec_s *handle = (mediacodec_s *)user_data;
557 if (handle->supported_codec_cb) {
558 return ((mediacodec_supported_codec_cb)handle->supported_codec_cb)(codec_type, handle->supported_codec_cb_userdata);
563 static gboolean __mediacodec_buffer_status_cb(mediacodec_status_e status, void *user_data)
565 if (user_data == NULL)
568 mediacodec_s *handle = (mediacodec_s *)user_data;
570 if (handle->buffer_status_cb) {
571 ((mediacodec_buffer_status_cb)handle->buffer_status_cb)(status, handle->buffer_status_cb_userdata);