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.
23 #include <media_codec.h>
24 #include <media_codec_private.h>
25 #include <media_codec_port.h>
26 #include <media_codec_port_gst.h>
27 #include <media_codec_spec_emul.h>
28 #include <media_codec_ini.h>
30 static gboolean _check_support_audio_info(mediacodec_codec_type_e codec_id, int samplerate, int channel, int bit_depth);
31 static gboolean _check_support_video_info(mediacodec_codec_type_e codec_id, int width, int height);
33 int mc_create(MMHandleType *mediacodec)
35 mc_handle_t *new_mediacodec = NULL;
36 int ret = MC_ERROR_NONE;
38 /* alloc mediacodec structure */
39 new_mediacodec = (mc_handle_t *)g_malloc(sizeof(mc_handle_t));
41 if (!new_mediacodec) {
42 LOGE("Cannot allocate memory for mediacodec");
46 memset(new_mediacodec, 0, sizeof(mc_handle_t));
48 new_mediacodec->is_encoder = false;
49 new_mediacodec->is_video = false;
50 new_mediacodec->is_hw = true;
51 new_mediacodec->is_prepared = false;
52 new_mediacodec->codec_id = MEDIACODEC_NONE;
54 new_mediacodec->ports[0] = NULL;
55 new_mediacodec->ports[1] = NULL;
57 new_mediacodec->num_supported_decoder = 0;
58 new_mediacodec->num_supported_encoder = 0;
60 new_mediacodec->core = NULL;
61 new_mediacodec->ini = &mc_ini;
65 ret = mc_ini_load(&mc_ini);
66 if (ret != MC_ERROR_NONE)
72 _mc_create_codec_map_from_ini(new_mediacodec, spec_emul);
74 /* create decoder map from ini */
75 _mc_create_decoder_map_from_ini(new_mediacodec);
77 /* create encoder map from ini */
78 _mc_create_encoder_map_from_ini(new_mediacodec);
80 *mediacodec = (MMHandleType)new_mediacodec;
85 g_free(new_mediacodec);
86 return MC_INVALID_ARG;
89 int mc_destroy(MMHandleType mediacodec)
91 int ret = MC_ERROR_NONE;
92 mc_handle_t *mc_handle = (mc_handle_t *) mediacodec;
95 LOGE("fail invaild param\n");
96 return MC_INVALID_ARG;
99 LOGD("mediacodec : %p", mediacodec);
101 if (mc_handle->core != NULL) {
102 if (mc_gst_unprepare(mc_handle) != MC_ERROR_NONE) {
103 LOGE("mc_gst_unprepare() failed");
108 mc_handle->is_prepared = false;
110 if (mc_handle->extra_converter.name) {
111 g_free(mc_handle->extra_converter.name);
112 mc_handle->extra_converter.name = NULL;
115 g_free((void *)mc_handle);
120 int mc_set_codec(MMHandleType mediacodec, mediacodec_codec_type_e codec_id, int flags)
122 int ret = MC_ERROR_NONE;
123 mc_handle_t *mc_handle = (mc_handle_t *) mediacodec;
127 LOGE("fail invaild param");
128 return MC_INVALID_ARG;
131 /* Mandatory setting */
132 if (!GET_IS_ENCODER(flags) && !GET_IS_DECODER(flags)) {
133 LOGE("should be encoder or decoder");
134 return MC_PARAM_ERROR;
137 /* if user doesn't set codec-type, s/w codec would be set */
138 if (!GET_IS_HW(flags) && !GET_IS_SW(flags))
139 flags |= MEDIACODEC_SUPPORT_TYPE_SW;
141 for (i = 0; i < mc_handle->ini->num_supported_codecs; i++) {
142 if ((codec_id == spec_emul[i].codec_id) && (flags == spec_emul[i].codec_type))
145 LOGD("support_list : %d, i : %d", mc_handle->ini->num_supported_codecs, i);
147 if (i == mc_handle->ini->num_supported_codecs)
148 return MC_NOT_SUPPORTED;
150 mc_handle->port_type = spec_emul[i].port_type;
152 mc_handle->is_encoder = GET_IS_ENCODER(flags) ? 1 : 0;
153 mc_handle->is_hw = GET_IS_HW(flags) ? 1 : 0;
154 mc_handle->codec_id = codec_id;
155 mc_handle->is_video = CHECK_BIT(codec_id, 13);
157 mc_handle->is_prepared = false;
159 LOGD("encoder : %d, hardware : %d, codec_id : %x, video : %d",
160 mc_handle->is_encoder, mc_handle->is_hw, mc_handle->codec_id, mc_handle->is_video);
165 int mc_set_vdec_info(MMHandleType mediacodec, int width, int height)
167 int ret = MC_ERROR_NONE;
168 mc_handle_t* mc_handle = (mc_handle_t *)mediacodec;
171 LOGE("fail invaild param\n");
172 return MC_INVALID_ARG;
175 if (!_check_support_video_info(mc_handle->codec_id, width, height)) {
176 LOGE("invaild param[res %dx%d]", width, height);
177 return MC_PARAM_ERROR;
180 MEDIACODEC_CHECK_CONDITION(mc_handle->codec_id && mc_handle->is_video && !mc_handle->is_encoder,
181 MC_INVALID_ARG, "MEDIACODEC_ERROR_INVALID_PARAMETER");
183 mc_handle->info.video.width = width;
184 mc_handle->info.video.height = height;
186 mc_handle->is_prepared = true;
191 int mc_set_venc_info(MMHandleType mediacodec, int width, int height, int fps, int target_bits)
193 int ret = MC_ERROR_NONE;
194 mc_handle_t *mc_handle = (mc_handle_t *) mediacodec;
197 LOGE("fail invaild param\n");
198 return MC_INVALID_ARG;
201 if (!_check_support_video_info(mc_handle->codec_id, width, height) || fps < 0 || target_bits < 0) {
202 LOGE("invaild param[res %dx%d, fps %d, target_bits %d]", width, height, fps, target_bits);
203 return MC_PARAM_ERROR;
206 MEDIACODEC_CHECK_CONDITION(mc_handle->codec_id && mc_handle->is_video && mc_handle->is_encoder,
207 MC_INVALID_ARG, "MEDIACODEC_ERROR_INVALID_PARAMETER");
209 mc_handle->info.video.width = width;
210 mc_handle->info.video.height = height;
211 mc_handle->info.video.framerate = fps;
212 mc_handle->info.video.bitrate = target_bits * 1000;
213 mc_handle->is_prepared = true;
218 int mc_set_adec_info(MMHandleType mediacodec, int samplerate, int channel, int bit)
220 int ret = MC_ERROR_NONE;
221 mc_handle_t *mc_handle = (mc_handle_t *) mediacodec;
224 LOGE("fail invaild param\n");
225 return MC_INVALID_ARG;
228 if (!_check_support_audio_info(mc_handle->codec_id, samplerate, channel, bit)) {
229 LOGE("invaild param[samplerate %d, channel %d, bit %d]", samplerate, channel, bit);
230 return MC_PARAM_ERROR;
233 MEDIACODEC_CHECK_CONDITION(mc_handle->codec_id && !mc_handle->is_video && !mc_handle->is_encoder,
234 MC_INVALID_ARG, "MEDIACODEC_ERROR_INVALID_PARAMETER");
236 mc_handle->info.audio.samplerate = samplerate;
237 mc_handle->info.audio.channel = channel;
238 mc_handle->info.audio.bit_depth = bit;
239 mc_handle->is_prepared = true;
244 int mc_set_aenc_info(MMHandleType mediacodec, int samplerate, int channel, int bit, int bitrate)
246 int ret = MC_ERROR_NONE;
247 mc_handle_t * mc_handle = (mc_handle_t *) mediacodec;
250 LOGE("fail invaild param\n");
251 return MC_INVALID_ARG;
254 if (!_check_support_audio_info(mc_handle->codec_id, samplerate, channel, bit) || bitrate < 0) {
255 LOGE("invaild param[samplerate %d, channel %d, bit %d, bitrate %d]", samplerate, channel, bit, bitrate);
256 return MC_PARAM_ERROR;
259 MEDIACODEC_CHECK_CONDITION(mc_handle->codec_id && !mc_handle->is_video && mc_handle->is_encoder,
260 MC_INVALID_ARG, "MEDIACODEC_ERROR_INVALID_PARAMETER");
262 mc_handle->info.audio.samplerate = samplerate;
263 mc_handle->info.audio.channel = channel;
264 mc_handle->info.audio.bit_depth = bit;
265 mc_handle->info.audio.bitrate = bitrate * 1000;
267 mc_handle->is_prepared = true;
272 int mc_configure(MMHandleType mediacodec, media_format_h format, int flags)
274 int ret = MEDIA_FORMAT_ERROR_NONE;
275 mc_handle_t *mc_handle = (mc_handle_t *) mediacodec;
277 const int codec_mask = 0xFFF0;
286 media_format_type_e type;
287 media_format_mimetype_e mimetype;
290 LOGE("fail invaild param");
291 return MC_INVALID_ARG;
294 if (media_format_get_type(format, &type) != MEDIA_FORMAT_ERROR_NONE) {
295 LOGE("failed to retrieve type");
296 return MC_INVALID_ARG;
299 if (type == MEDIA_FORMAT_AUDIO) {
300 ret = media_format_get_audio_info(format, &mimetype, &channel, &samplerate, &bit, &bitrate);
301 if (ret != MEDIA_FORMAT_ERROR_NONE) {
302 LOGE("get audio info failed[0x%x]", ret);
303 return MC_INVALID_ARG;
306 codec_id = mimetype & codec_mask;
308 if (GET_IS_ENCODER(flags)) {
309 if (!_check_support_audio_info(codec_id, samplerate, channel, bit)) {
310 LOGE("invalid pram is set : samplerate : %d, channel : %d, bit : %d, bitrate : %d",
311 samplerate, channel, bit, bitrate);
312 return MC_PARAM_ERROR;
315 mc_handle->info.audio.samplerate = samplerate;
316 mc_handle->info.audio.channel = channel;
317 mc_handle->info.audio.bit_depth = bit;
318 mc_handle->info.audio.bitrate = bitrate * 1000;
319 } else if (GET_IS_DECODER(flags)) {
320 if (!_check_support_audio_info(codec_id, samplerate, channel, bit)) {
321 LOGE("invalid pram is set : samplerate : %d, channel : %d, bit : %d",
322 samplerate, channel, bit);
323 return MC_PARAM_ERROR;
325 mc_handle->info.audio.samplerate = samplerate;
326 mc_handle->info.audio.channel = channel;
327 mc_handle->info.audio.bit_depth = bit;
329 LOGE("either an encoder or a decoder must be set");
330 return MC_PARAM_ERROR;
332 } else if (type == MEDIA_FORMAT_VIDEO) {
333 ret = media_format_get_video_info(format, &mimetype, &width, &height, &bitrate, NULL);
334 ret |= media_format_get_video_frame_rate(format, &fps);
335 if (ret != MEDIA_FORMAT_ERROR_NONE) {
336 LOGE("get video info/frame_rate failed[0x%x]", ret);
337 return MC_INVALID_ARG;
340 codec_id = mimetype & codec_mask;
342 if (GET_IS_ENCODER(flags)) {
343 if (!_check_support_video_info(codec_id, width, height) || fps <= 0 || bitrate <= 0) {
344 LOGE("invalid pram is set : width : %d, height : %d, bitrate : %d, fps : %d",
345 width, height, bitrate, fps);
346 return MC_PARAM_ERROR;
349 mc_handle->info.video.width = width;
350 mc_handle->info.video.height = height;
351 mc_handle->info.video.framerate = fps;
352 mc_handle->info.video.bitrate = bitrate * 1000;
353 } else if (GET_IS_DECODER(flags)) {
354 if (!_check_support_video_info(codec_id, width, height)) {
355 LOGE("invalid pram is set : width : %d, height : %d",
357 return MC_PARAM_ERROR;
360 mc_handle->info.video.width = width;
361 mc_handle->info.video.height = height;
363 LOGE("either an encoder or a decoder must be set");
364 return MC_PARAM_ERROR;
367 LOGE("invalid format type is set");
368 return MC_PARAM_ERROR;
371 if (!GET_IS_HW(flags) && !GET_IS_SW(flags))
372 flags |= MEDIACODEC_SUPPORT_TYPE_SW;
374 for (i = 0; i < mc_handle->ini->num_supported_codecs; i++) {
375 if ((codec_id == spec_emul[i].codec_id) && (flags == spec_emul[i].codec_type))
378 LOGD("support_list : %d, i : %d", mc_handle->ini->num_supported_codecs, i);
380 if (i == mc_handle->ini->num_supported_codecs)
381 return MC_CODEC_NOT_FOUND;
383 mc_handle->port_type = spec_emul[i].port_type;
385 mc_handle->is_encoder = GET_IS_ENCODER(flags) ? 1 : 0;
386 mc_handle->is_hw = GET_IS_HW(flags) ? 1 : 0;
387 mc_handle->codec_id = codec_id;
388 mc_handle->is_video = CHECK_BIT(codec_id, 13);
390 mc_handle->is_prepared = true;
392 LOGD("encoder : %d, hardware : %d, codec_id : %x, video : %d",
393 mc_handle->is_encoder, mc_handle->is_hw, mc_handle->codec_id, mc_handle->is_video);
395 return MC_ERROR_NONE;
398 int mc_prepare(MMHandleType mediacodec)
400 int ret = MC_ERROR_NONE;
401 mc_handle_t *mc_handle = (mc_handle_t *) mediacodec;
404 LOGE("fail invaild param\n");
405 return MC_INVALID_ARG;
408 if (!mc_handle->is_prepared)
409 return MC_NOT_INITIALIZED;
411 /* setting core details */
412 switch (mc_handle->port_type) {
413 case MEDIACODEC_PORT_TYPE_GENERAL:
416 case MEDIACODEC_PORT_TYPE_OMX:
419 case MEDIACODEC_PORT_TYPE_GST:
420 ret = mc_gst_prepare(mc_handle);
430 int mc_unprepare(MMHandleType mediacodec)
432 int ret = MC_ERROR_NONE;
433 mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
436 LOGE("fail invaild param\n");
437 return MC_INVALID_ARG;
440 /* deinit core details */
441 switch (mc_handle->port_type) {
442 case MEDIACODEC_PORT_TYPE_GENERAL:
445 case MEDIACODEC_PORT_TYPE_OMX:
448 case MEDIACODEC_PORT_TYPE_GST:
449 ret = mc_gst_unprepare(mc_handle);
459 int mc_process_input(MMHandleType mediacodec, media_packet_h inbuf, uint64_t timeOutUs)
461 int ret = MC_ERROR_NONE;
463 mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
466 LOGE("fail invaild param");
467 return MC_INVALID_ARG;
471 LOGE("invaild input buffer");
472 return MC_INVALID_IN_BUF;
475 switch (mc_handle->port_type) {
476 case MEDIACODEC_PORT_TYPE_GENERAL:
479 case MEDIACODEC_PORT_TYPE_OMX:
482 case MEDIACODEC_PORT_TYPE_GST:
483 ret = mc_gst_process_input(mc_handle, inbuf, timeOutUs);
493 int mc_get_output(MMHandleType mediacodec, media_packet_h *outbuf, uint64_t timeOutUs)
495 int ret = MC_ERROR_NONE;
496 mc_handle_t *mc_handle = (mc_handle_t *) mediacodec;
499 LOGE("fail invaild param\n");
500 return MC_INVALID_ARG;
504 LOGE("invaild outbuf buffer");
505 return MC_INVALID_OUT_BUF;
508 /* setting core details */
509 switch (mc_handle->port_type) {
510 case MEDIACODEC_PORT_TYPE_GENERAL:
513 case MEDIACODEC_PORT_TYPE_OMX:
516 case MEDIACODEC_PORT_TYPE_GST:
517 ret = mc_gst_get_output(mc_handle, outbuf, timeOutUs);
527 int mc_flush_buffers(MMHandleType mediacodec)
529 int ret = MC_ERROR_NONE;
530 mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
533 LOGE("fail invaild param\n");
534 return MC_INVALID_ARG;
537 /* setting core details */
538 switch (mc_handle->port_type) {
539 case MEDIACODEC_PORT_TYPE_GENERAL:
542 case MEDIACODEC_PORT_TYPE_OMX:
545 case MEDIACODEC_PORT_TYPE_GST:
546 ret = mc_gst_flush_buffers(mc_handle);
556 int mc_get_supported_type(MMHandleType mediacodec, mediacodec_codec_type_e codec_type, bool encoder, int *support_type)
558 int ret = MC_ERROR_NONE;
559 mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
560 mc_codec_map_t *codec_map;
561 int num_supported_codec = 0;
567 LOGE("fail invaild param\n");
568 return MC_INVALID_ARG;
571 codec_map = encoder ? mc_handle->encoder_map : mc_handle->decoder_map;
572 num_supported_codec = encoder ? mc_handle->num_supported_encoder : mc_handle->num_supported_decoder;
574 for (i = 0; i < num_supported_codec; i++) {
575 if (codec_map[i].id == codec_type) {
576 if (codec_map[i].hardware)
577 *support_type |= MEDIACODEC_SUPPORT_TYPE_HW;
579 *support_type |= MEDIACODEC_SUPPORT_TYPE_SW;
586 int mc_set_empty_buffer_cb(MMHandleType mediacodec, mediacodec_input_buffer_used_cb callback, void *user_data)
588 int ret = MC_ERROR_NONE;
589 mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
592 LOGE("fail invaild param\n");
593 return MC_INVALID_ARG;
596 if (mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER]) {
597 LOGE("Already set mediacodec_empty_buffer_cb");
598 return MC_PARAM_ERROR;
601 return MC_INVALID_ARG;
603 LOGD("Set empty buffer callback(cb = %p, data = %p)", callback, user_data);
605 mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER] = (mc_empty_buffer_cb) callback;
606 mc_handle->user_data[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER] = user_data;
608 return MC_ERROR_NONE;
614 int mc_unset_empty_buffer_cb(MMHandleType mediacodec)
616 mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
619 LOGE("fail invaild param\n");
620 return MC_INVALID_ARG;
623 mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER] = NULL;
624 mc_handle->user_data[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER] = NULL;
626 return MC_ERROR_NONE;
629 int mc_set_fill_buffer_cb(MMHandleType mediacodec, mediacodec_output_buffer_available_cb callback, void *user_data)
631 int ret = MC_ERROR_NONE;
632 mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
635 LOGE("fail invaild param\n");
636 return MC_INVALID_ARG;
639 if (mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_FILLBUFFER]) {
640 LOGE("Already set mediacodec_fill_buffer_cb");
641 return MC_PARAM_ERROR;
644 return MC_INVALID_ARG;
646 LOGD("Set fill buffer callback(cb = %p, data = %p)", callback, user_data);
648 mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_FILLBUFFER] = (mc_fill_buffer_cb) callback;
649 mc_handle->user_data[_MEDIACODEC_EVENT_TYPE_FILLBUFFER] = user_data;
650 return MC_ERROR_NONE;
656 int mc_unset_fill_buffer_cb(MMHandleType mediacodec)
658 mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
661 LOGE("fail invaild param\n");
662 return MC_INVALID_ARG;
665 mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_FILLBUFFER] = NULL;
666 mc_handle->user_data[_MEDIACODEC_EVENT_TYPE_FILLBUFFER] = NULL;
668 return MC_ERROR_NONE;
671 int mc_set_error_cb(MMHandleType mediacodec, mediacodec_error_cb callback, void *user_data)
673 int ret = MC_ERROR_NONE;
674 mc_handle_t *mc_handle = (mc_handle_t *) mediacodec;
677 LOGE("fail invaild param\n");
678 return MC_INVALID_ARG;
681 if (mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_ERROR]) {
682 LOGE("Already set mediacodec_fill_buffer_cb\n");
683 return MC_PARAM_ERROR;
686 return MC_INVALID_ARG;
688 LOGD("Set event handler callback(cb = %p, data = %p)\n", callback, user_data);
690 mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_ERROR] = (mc_error_cb) callback;
691 mc_handle->user_data[_MEDIACODEC_EVENT_TYPE_ERROR] = user_data;
692 return MC_ERROR_NONE;
698 int mc_unset_error_cb(MMHandleType mediacodec)
700 mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
703 LOGE("fail invaild param");
704 return MC_INVALID_ARG;
707 mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_ERROR] = NULL;
708 mc_handle->user_data[_MEDIACODEC_EVENT_TYPE_ERROR] = NULL;
710 return MC_ERROR_NONE;
713 int mc_set_eos_cb(MMHandleType mediacodec, mediacodec_eos_cb callback, void *user_data)
715 int ret = MC_ERROR_NONE;
716 mc_handle_t *mc_handle = (mc_handle_t *) mediacodec;
719 LOGE("fail invaild param\n");
720 return MC_INVALID_ARG;
723 if (mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_EOS]) {
724 LOGE("Already set mediacodec_fill_buffer_cb");
725 return MC_PARAM_ERROR;
728 return MC_INVALID_ARG;
730 LOGD("Set event handler callback(cb = %p, data = %p)\n", callback, user_data);
732 mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_EOS] = (mc_eos_cb) callback;
733 mc_handle->user_data[_MEDIACODEC_EVENT_TYPE_EOS] = user_data;
734 return MC_ERROR_NONE;
740 int mc_unset_eos_cb(MMHandleType mediacodec)
742 mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
745 LOGE("fail invaild param\n");
746 return MC_INVALID_ARG;
749 mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_EOS] = NULL;
750 mc_handle->user_data[_MEDIACODEC_EVENT_TYPE_EOS] = NULL;
752 return MC_ERROR_NONE;
755 int mc_set_buffer_status_cb(MMHandleType mediacodec, mediacodec_buffer_status_cb callback, void *user_data)
757 int ret = MC_ERROR_NONE;
758 mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
761 LOGE("fail invaild param\n");
762 return MC_INVALID_ARG;
765 if (mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS]) {
766 LOGE("Already set mediacodec_need_data_cb\n");
767 return MC_PARAM_ERROR;
770 return MC_INVALID_ARG;
772 LOGD("Set start feed callback(cb = %p, data = %p)\n", callback, user_data);
774 mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS] = (mc_buffer_status_cb) callback;
775 mc_handle->user_data[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS] = user_data;
776 return MC_ERROR_NONE;
782 int mc_unset_buffer_status_cb(MMHandleType mediacodec)
784 mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
787 LOGE("fail invaild param\n");
788 return MC_INVALID_ARG;
791 mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS] = NULL;
792 mc_handle->user_data[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS] = NULL;
794 return MC_ERROR_NONE;
797 int mc_enable_extra_video_converter(MMHandleType mediacodec, gboolean enable, const char *converter_name, int crop_x, int crop_y, int crop_w, int crop_h)
799 mc_handle_t *mc_handle = (mc_handle_t *) mediacodec;
802 LOGE("fail invaild param\n");
803 return MC_INVALID_ARG;
806 if (enable && !converter_name) {
807 LOGE("It's enabled, but converter name is NULL");
808 return MC_INVALID_ARG;
811 LOGI("enable: %d", enable);
812 mc_handle->extra_converter.enable = enable;
815 if (mc_handle->extra_converter.name) {
816 LOGI("free converter name old[%s]", mc_handle->extra_converter.name);
817 g_free(mc_handle->extra_converter.name);
818 mc_handle->extra_converter.name = NULL;
821 LOGI("element name: %s", converter_name);
822 mc_handle->extra_converter.name = g_strdup(converter_name);
824 LOGI("crop[%d,%d,%dx%d]", crop_x, crop_y, crop_w, crop_h);
825 mc_handle->extra_converter.crop_x = crop_x;
826 mc_handle->extra_converter.crop_y = crop_y;
827 mc_handle->extra_converter.crop_w = crop_w;
828 mc_handle->extra_converter.crop_h = crop_h;
831 return MC_ERROR_NONE;
834 int _mediacodec_foreach_supported_codec(mediacodec_supported_codec_cb callback, void *user_data)
839 gboolean codec[CODEC_NR_ITEMS] = {0,};
841 for (i = 0; i < mc_ini.num_supported_codecs; i++) {
842 index = (int)codec_type_to_simple_enumeration(spec_emul[i].codec_id);
846 for (i = 0; i < CODEC_NR_ITEMS; i++) {
848 index = (int)simple_to_codec_type_enumeration(i);
849 if (!callback(index, user_data)) {
850 LOGW("stop foreach callback");
858 return MEDIACODEC_ERROR_NONE;
861 int mc_get_packet_pool(MMHandleType mediacodec, media_packet_pool_h *pool)
863 int ret = MC_ERROR_NONE;
864 mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
867 LOGE("fail invaild param\n");
868 return MC_INVALID_ARG;
871 /* setting core details */
872 switch (mc_handle->port_type) {
873 case MEDIACODEC_PORT_TYPE_GENERAL:
876 case MEDIACODEC_PORT_TYPE_OMX:
879 case MEDIACODEC_PORT_TYPE_GST:
880 ret = mc_gst_get_packet_pool(mc_handle, pool);
890 void _mc_create_decoder_map_from_ini(mc_handle_t *mediacodec)
892 int indx = 0, count = 0;
893 int codec_list = mediacodec->ini->codec_list;
894 for (indx = 0; indx < codec_list; indx++) {
895 if (strcmp(mediacodec->ini->codec[indx].codec_info[MEDIA_CODEC_ROLE_HW_DECODER].name, "")) {
896 mediacodec->decoder_map[count].id = mediacodec->ini->codec[indx].codec_id;
897 mediacodec->decoder_map[count].hardware = 1; /* hardware */
898 mediacodec->decoder_map[count].type.factory_name = mediacodec->ini->codec[indx].codec_info[MEDIA_CODEC_ROLE_HW_DECODER].name;
899 mediacodec->decoder_map[count].type.mime = mediacodec->ini->codec[indx].codec_info[MEDIA_CODEC_ROLE_HW_DECODER].mime;
900 mediacodec->decoder_map[count].type.out_format =
901 _mc_convert_media_format_str_to_int(mediacodec->ini->codec[indx].codec_info[MEDIA_CODEC_ROLE_HW_DECODER].format);
902 mediacodec->decoder_map[count].type.property = &mediacodec->ini->codec[indx].codec_info[MEDIA_CODEC_ROLE_HW_DECODER].property;
906 if (strcmp(mediacodec->ini->codec[indx].codec_info[MEDIA_CODEC_ROLE_SW_DECODER].name, "")) {
907 mediacodec->decoder_map[count].id = mediacodec->ini->codec[indx].codec_id;
908 mediacodec->decoder_map[count].hardware = 0; /* software */
909 mediacodec->decoder_map[count].type.factory_name = mediacodec->ini->codec[indx].codec_info[MEDIA_CODEC_ROLE_SW_DECODER].name;
910 mediacodec->decoder_map[count].type.mime = mediacodec->ini->codec[indx].codec_info[MEDIA_CODEC_ROLE_SW_DECODER].mime;
911 mediacodec->decoder_map[count].type.out_format =
912 _mc_convert_media_format_str_to_int(mediacodec->ini->codec[indx].codec_info[MEDIA_CODEC_ROLE_SW_DECODER].format);
913 mediacodec->decoder_map[count].type.property = &mediacodec->ini->codec[indx].codec_info[MEDIA_CODEC_ROLE_SW_DECODER].property;
917 mediacodec->num_supported_decoder = count;
922 void _mc_create_encoder_map_from_ini(mc_handle_t *mediacodec)
924 int indx = 0, count = 0;
925 int codec_list = mediacodec->ini->codec_list;
927 for (indx = 0; indx < codec_list; indx++) {
928 if (strcmp(mediacodec->ini->codec[indx].codec_info[MEDIA_CODEC_ROLE_HW_ENCODER].name, "")) {
929 mediacodec->encoder_map[count].id = mediacodec->ini->codec[indx].codec_id;
930 mediacodec->encoder_map[count].hardware = 1;
931 mediacodec->encoder_map[count].type.factory_name = mediacodec->ini->codec[indx].codec_info[MEDIA_CODEC_ROLE_HW_ENCODER].name;
932 mediacodec->encoder_map[count].type.mime = mediacodec->ini->codec[indx].codec_info[MEDIA_CODEC_ROLE_HW_ENCODER].mime;
933 mediacodec->encoder_map[count].type.out_format =
934 _mc_convert_media_format_str_to_int(mediacodec->ini->codec[indx].codec_info[MEDIA_CODEC_ROLE_HW_ENCODER].format);
935 mediacodec->encoder_map[count].type.property = &mediacodec->ini->codec[indx].codec_info[MEDIA_CODEC_ROLE_HW_ENCODER].property;
939 if (strcmp(mediacodec->ini->codec[indx].codec_info[MEDIA_CODEC_ROLE_SW_ENCODER].name, "")) {
940 mediacodec->encoder_map[count].id = mediacodec->ini->codec[indx].codec_id;
941 mediacodec->encoder_map[count].hardware = 0;
942 mediacodec->encoder_map[count].type.factory_name = mediacodec->ini->codec[indx].codec_info[MEDIA_CODEC_ROLE_SW_ENCODER].name;
943 mediacodec->encoder_map[count].type.mime = mediacodec->ini->codec[indx].codec_info[MEDIA_CODEC_ROLE_SW_ENCODER].mime;
944 mediacodec->encoder_map[count].type.out_format =
945 _mc_convert_media_format_str_to_int(mediacodec->ini->codec[indx].codec_info[MEDIA_CODEC_ROLE_SW_ENCODER].format);
946 mediacodec->encoder_map[count].type.property = &mediacodec->ini->codec[indx].codec_info[MEDIA_CODEC_ROLE_SW_ENCODER].property;
950 mediacodec->num_supported_encoder = count;
954 void _mc_create_codec_map_from_ini(mc_handle_t *mediacodec, mc_codec_spec_t *spec_emul)
956 int indx = 0, count = 0;
957 int codec_list = mediacodec->ini->codec_list;
959 for (indx = 0; indx < codec_list; indx++) {
960 if (strcmp(mediacodec->ini->codec[indx].codec_info[MEDIA_CODEC_ROLE_HW_DECODER].name, "")) {
961 spec_emul[count].codec_id = mediacodec->ini->codec[indx].codec_id;
962 spec_emul[count].codec_type = MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_HW;
963 spec_emul[count].port_type = MEDIACODEC_PORT_TYPE_GST;
966 if (strcmp(mediacodec->ini->codec[indx].codec_info[MEDIA_CODEC_ROLE_HW_ENCODER].name, "")) {
967 spec_emul[count].codec_id = mediacodec->ini->codec[indx].codec_id;
968 spec_emul[count].codec_type = MEDIACODEC_ENCODER | MEDIACODEC_SUPPORT_TYPE_HW;
969 spec_emul[count].port_type = MEDIACODEC_PORT_TYPE_GST;
972 if (strcmp(mediacodec->ini->codec[indx].codec_info[MEDIA_CODEC_ROLE_SW_DECODER].name, "")) {
973 spec_emul[count].codec_id = mediacodec->ini->codec[indx].codec_id;
974 spec_emul[count].codec_type = MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_SW;
975 spec_emul[count].port_type = MEDIACODEC_PORT_TYPE_GST;
978 if (strcmp(mediacodec->ini->codec[indx].codec_info[MEDIA_CODEC_ROLE_SW_ENCODER].name, "")) {
979 spec_emul[count].codec_id = mediacodec->ini->codec[indx].codec_id;
980 spec_emul[count].codec_type = MEDIACODEC_ENCODER | MEDIACODEC_SUPPORT_TYPE_SW;
981 spec_emul[count].port_type = MEDIACODEC_PORT_TYPE_GST;
986 mediacodec->ini->num_supported_codecs = count;
987 LOGE("supported codecs :%d", count);
991 void _mc_create_codec_map_from_ini_static(mc_ini_t *ini, mc_codec_spec_t *spec_emul)
993 int indx = 0, count = 0;
994 int codec_list = ini->codec_list;
996 for (indx = 0; indx < codec_list; indx++) {
997 if (strcmp(ini->codec[indx].codec_info[MEDIA_CODEC_ROLE_HW_DECODER].name, "")) {
998 spec_emul[count].codec_id = ini->codec[indx].codec_id;
999 spec_emul[count].codec_type = MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_HW;
1000 spec_emul[count].port_type = MEDIACODEC_PORT_TYPE_GST;
1003 if (strcmp(ini->codec[indx].codec_info[MEDIA_CODEC_ROLE_HW_ENCODER].name, "")) {
1004 spec_emul[count].codec_id = ini->codec[indx].codec_id;
1005 spec_emul[count].codec_type = MEDIACODEC_ENCODER | MEDIACODEC_SUPPORT_TYPE_HW;
1006 spec_emul[count].port_type = MEDIACODEC_PORT_TYPE_GST;
1009 if (strcmp(ini->codec[indx].codec_info[MEDIA_CODEC_ROLE_SW_DECODER].name, "")) {
1010 spec_emul[count].codec_id = ini->codec[indx].codec_id;
1011 spec_emul[count].codec_type = MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_SW;
1012 spec_emul[count].port_type = MEDIACODEC_PORT_TYPE_GST;
1015 if (strcmp(ini->codec[indx].codec_info[MEDIA_CODEC_ROLE_SW_ENCODER].name, "")) {
1016 spec_emul[count].codec_id = ini->codec[indx].codec_id;
1017 spec_emul[count].codec_type = MEDIACODEC_ENCODER | MEDIACODEC_SUPPORT_TYPE_SW;
1018 spec_emul[count].port_type = MEDIACODEC_PORT_TYPE_GST;
1023 ini->num_supported_codecs = count;
1024 LOGE("supported codecs :%d", count);
1028 codec_type_e codec_type_to_simple_enumeration(mediacodec_codec_type_e media_codec_id)
1030 guint media_codec_id_u = (guint)media_codec_id;
1032 switch (media_codec_id_u) {
1033 case MEDIACODEC_L16:
1035 case MEDIACODEC_ALAW:
1037 case MEDIACODEC_ULAW:
1039 case MEDIACODEC_AMR_NB:
1041 case MEDIACODEC_AMR_WB:
1043 case MEDIACODEC_G729:
1045 case MEDIACODEC_AAC_LC:
1047 case MEDIACODEC_AAC_HE:
1049 case MEDIACODEC_AAC_HE_PS:
1051 case MEDIACODEC_MP3:
1053 case MEDIACODEC_VORBIS:
1055 case MEDIACODEC_FLAC:
1057 case MEDIACODEC_WMAV1:
1059 case MEDIACODEC_WMAV2:
1061 case MEDIACODEC_WMAPRO:
1063 case MEDIACODEC_WMALSL:
1065 case MEDIACODEC_H261:
1067 case MEDIACODEC_H263:
1069 case MEDIACODEC_H264:
1071 case MEDIACODEC_MJPEG:
1073 case MEDIACODEC_MPEG1:
1075 case MEDIACODEC_MPEG2:
1077 case MEDIACODEC_MPEG4:
1079 case MEDIACODEC_HEVC:
1081 case MEDIACODEC_VP8:
1083 case MEDIACODEC_VP9:
1085 case MEDIACODEC_VC1:
1087 case MEDIACODEC_OPUS:
1094 mediacodec_codec_type_e simple_to_codec_type_enumeration(codec_type_e codec_id)
1096 guint codec_id_u = (guint)codec_id;
1098 switch (codec_id_u) {
1100 return MEDIACODEC_L16;
1102 return MEDIACODEC_ALAW;
1104 return MEDIACODEC_ULAW;
1106 return MEDIACODEC_AMR_NB;
1108 return MEDIACODEC_AMR_WB;
1110 return MEDIACODEC_G729;
1112 return MEDIACODEC_AAC_LC;
1114 return MEDIACODEC_AAC_HE;
1116 return MEDIACODEC_AAC_HE_PS;
1118 return MEDIACODEC_MP3;
1120 return MEDIACODEC_VORBIS;
1122 return MEDIACODEC_FLAC;
1124 return MEDIACODEC_WMAV1;
1126 return MEDIACODEC_WMAV2;
1128 return MEDIACODEC_WMAPRO;
1130 return MEDIACODEC_WMALSL;
1132 return MEDIACODEC_H261;
1134 return MEDIACODEC_H263;
1136 return MEDIACODEC_H264;
1138 return MEDIACODEC_MJPEG;
1140 return MEDIACODEC_MPEG1;
1142 return MEDIACODEC_MPEG2;
1144 return MEDIACODEC_MPEG4;
1146 return MEDIACODEC_HEVC;
1148 return MEDIACODEC_VP8;
1150 return MEDIACODEC_VP9;
1152 return MEDIACODEC_VC1;
1154 return MEDIACODEC_OPUS;
1160 gboolean _check_support_audio_info(mediacodec_codec_type_e codec_id, int samplerate, int channel, int bit_depth)
1163 gint maxchannels = 2;
1165 gint s_bit_depth = 32;
1168 case MEDIACODEC_AMR_NB:
1170 const static gint l_rates[] = { 8000 };
1172 n_rates = G_N_ELEMENTS(l_rates);
1173 s_bit_depth = 16; /* NOTE: amrnbenc/amrnbdec surpports S16LE as format*/
1175 while (i < n_rates) {
1176 if (l_rates[i] == samplerate)
1182 LOGE("Invalid samplerate set");
1187 case MEDIACODEC_AAC_LC:
1188 case MEDIACODEC_AAC_HE:
1190 const static gint l_rates[] = { 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350 };
1192 n_rates = G_N_ELEMENTS(l_rates);
1193 s_bit_depth = 32; /* NOTE: avdec_aac/avenc_aac surpports S32LE as format*/
1195 while (i < n_rates) {
1196 if (l_rates[i] == samplerate)
1202 LOGE("Invalid samplerate set");
1207 case MEDIACODEC_MP3:
1209 s_bit_depth = 16; /* NOTE: amrenc/amrnbdec surpports S16LE as format*/
1212 case MEDIACODEC_VORBIS:
1214 s_bit_depth = 32; /* NOTE: vorbisenc/vorbisdec surpports S32LE as format */
1217 case MEDIACODEC_FLAC:
1219 s_bit_depth = 32; /* NOTE: avdec_flac surpports S32LE as format */
1222 case MEDIACODEC_OPUS:
1224 s_bit_depth = 16; /* NOTE: opusenc/ opusdec support S16LE as format according to opus specification*/
1231 if (channel < 0 || channel > maxchannels) {
1232 LOGE("Invalid channel set");
1236 if (bit_depth != s_bit_depth) {
1237 LOGE("Invalid bit set");
1244 gboolean _check_support_video_info(mediacodec_codec_type_e codec_id, int width, int height)
1249 if (width <= 0 || height <= 0) {
1250 LOGE("Invalid resolution set");
1255 case MEDIACODEC_H261:
1257 const static gint widths[] = { 352, 176 };
1258 const static gint heights[] = { 288, 144 };
1259 n_sizes = G_N_ELEMENTS(widths);
1261 while (i < n_sizes) {
1262 if ((widths[i] == width) && (heights[i] == height))
1268 LOGE("Invalid resolution set");
1273 case MEDIACODEC_H263:
1275 const static gint widths[] = { 352, 704, 176, 1408, 128 };
1276 const static gint heights[] = { 288, 576, 144, 1152, 96 };
1277 n_sizes = G_N_ELEMENTS(widths);
1279 while (i < n_sizes) {
1280 if ((widths[i] == width) && (heights[i] == height))
1286 LOGE("Invalid resolution set");