804a7cb05d1e4538572dd361fd72722d281f85d7
[platform/core/api/mediacodec.git] / src / media_codec_port.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20
21 #include <dlog.h>
22
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>
29
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);
32
33 int mc_create(MMHandleType *mediacodec)
34 {
35         mc_handle_t *new_mediacodec = NULL;
36         int ret = MC_ERROR_NONE;
37
38         /* alloc mediacodec structure */
39         new_mediacodec = (mc_handle_t *)g_malloc(sizeof(mc_handle_t));
40
41         if (!new_mediacodec) {
42                 LOGE("Cannot allocate memory for mediacodec");
43                 ret = MC_ERROR;
44                 goto ERROR;
45         }
46         memset(new_mediacodec, 0, sizeof(mc_handle_t));
47
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;
53
54         new_mediacodec->ports[0] = NULL;
55         new_mediacodec->ports[1] = NULL;
56
57         new_mediacodec->num_supported_decoder = 0;
58         new_mediacodec->num_supported_encoder = 0;
59
60         new_mediacodec->core = NULL;
61         new_mediacodec->ini = &mc_ini;
62
63         /* load ini files */
64         if (!mc_ini.loaded) {
65                 ret = mc_ini_load(&mc_ini);
66                 if (ret != MC_ERROR_NONE)
67                         goto ERROR;
68
69                 mc_ini.loaded = TRUE;
70         }
71
72         _mc_create_codec_map_from_ini(new_mediacodec, spec_emul);
73
74         /* create decoder map from ini */
75         _mc_create_decoder_map_from_ini(new_mediacodec);
76
77         /* create encoder map from ini */
78         _mc_create_encoder_map_from_ini(new_mediacodec);
79
80         *mediacodec = (MMHandleType)new_mediacodec;
81
82         return ret;
83
84 ERROR:
85         g_free(new_mediacodec);
86         return MC_INVALID_ARG;
87 }
88
89 int mc_destroy(MMHandleType mediacodec)
90 {
91         int ret = MC_ERROR_NONE;
92         mc_handle_t *mc_handle = (mc_handle_t *) mediacodec;
93
94         if (!mc_handle) {
95                 LOGE("fail invaild param\n");
96                 return MC_INVALID_ARG;
97         }
98
99         LOGD("mediacodec : %p", mediacodec);
100
101         if (mc_handle->core != NULL) {
102                 if (mc_gst_unprepare(mc_handle) != MC_ERROR_NONE) {
103                         LOGE("mc_gst_unprepare() failed");
104                         return MC_ERROR;
105                 }
106         }
107
108         mc_handle->is_prepared = false;
109
110         /* free mediacodec structure */
111         if (mc_handle) {
112                 g_free((void *)mc_handle);
113                 mc_handle = NULL;
114         }
115
116         return ret;
117 }
118
119 int mc_set_codec(MMHandleType mediacodec, mediacodec_codec_type_e codec_id, int flags)
120 {
121         int ret = MC_ERROR_NONE;
122         mc_handle_t *mc_handle = (mc_handle_t *) mediacodec;
123         int i;
124
125         if (!mc_handle) {
126                 LOGE("fail invaild param");
127                 return MC_INVALID_ARG;
128         }
129
130         /* Mandatory setting */
131         if (!GET_IS_ENCODER(flags) && !GET_IS_DECODER(flags)) {
132                 LOGE("should be encoder or decoder");
133                 return MC_PARAM_ERROR;
134         }
135
136         /* if user doesn't set codec-type, s/w codec would be set */
137         if (!GET_IS_HW(flags) && !GET_IS_SW(flags))
138                 flags |= MEDIACODEC_SUPPORT_TYPE_SW;
139
140         for (i = 0; i < mc_handle->ini->num_supported_codecs; i++) {
141                 if ((codec_id == spec_emul[i].codec_id) && (flags == spec_emul[i].codec_type))
142                         break;
143         }
144         LOGD("support_list : %d, i : %d", mc_handle->ini->num_supported_codecs, i);
145
146         if (i == mc_handle->ini->num_supported_codecs)
147                 return MC_NOT_SUPPORTED;
148
149         mc_handle->port_type = spec_emul[i].port_type;
150
151         mc_handle->is_encoder = GET_IS_ENCODER(flags) ? 1 : 0;
152         mc_handle->is_hw = GET_IS_HW(flags) ? 1 : 0;
153         mc_handle->codec_id = codec_id;
154         mc_handle->is_video = CHECK_BIT(codec_id, 13);
155
156         mc_handle->is_prepared = false;
157
158         LOGD("encoder : %d, hardware : %d, codec_id : %x, video : %d",
159                         mc_handle->is_encoder, mc_handle->is_hw, mc_handle->codec_id, mc_handle->is_video);
160
161         return ret;
162 }
163
164 int mc_set_vdec_info(MMHandleType mediacodec, int width, int height)
165 {
166         int ret = MC_ERROR_NONE;
167         mc_handle_t* mc_handle = (mc_handle_t *)mediacodec;
168
169         if (!mc_handle) {
170                 LOGE("fail invaild param\n");
171                 return MC_INVALID_ARG;
172         }
173
174         if (!_check_support_video_info(mc_handle->codec_id, width, height))
175                 return MC_PARAM_ERROR;
176
177         MEDIACODEC_CHECK_CONDITION(mc_handle->codec_id && mc_handle->is_video && !mc_handle->is_encoder,
178                         MC_INVALID_ARG, "MEDIACODEC_ERROR_INVALID_PARAMETER");
179
180         mc_handle->info.video.width = width;
181         mc_handle->info.video.height = height;
182
183         mc_handle->is_prepared = true;
184
185         return ret;
186 }
187
188 int mc_set_venc_info(MMHandleType mediacodec, int width, int height, int fps, int target_bits)
189 {
190         int ret = MC_ERROR_NONE;
191         mc_handle_t *mc_handle = (mc_handle_t *) mediacodec;
192
193         if (!mc_handle) {
194                 LOGE("fail invaild param\n");
195                 return MC_INVALID_ARG;
196         }
197
198         if (!_check_support_video_info(mc_handle->codec_id, width, height) || fps < 0 || target_bits < 0)
199                 return MC_PARAM_ERROR;
200
201         MEDIACODEC_CHECK_CONDITION(mc_handle->codec_id && mc_handle->is_video && mc_handle->is_encoder,
202                         MC_INVALID_ARG, "MEDIACODEC_ERROR_INVALID_PARAMETER");
203
204         mc_handle->info.video.width = width;
205         mc_handle->info.video.height = height;
206         mc_handle->info.video.framerate = fps;
207         mc_handle->info.video.bitrate = target_bits * 1000;
208         mc_handle->is_prepared = true;
209
210         return ret;
211 }
212
213 int mc_set_adec_info(MMHandleType mediacodec, int samplerate, int channel, int bit)
214 {
215         int ret = MC_ERROR_NONE;
216         mc_handle_t *mc_handle = (mc_handle_t *) mediacodec;
217
218         if (!mc_handle) {
219                 LOGE("fail invaild param\n");
220                 return MC_INVALID_ARG;
221         }
222
223         if (!_check_support_audio_info(mc_handle->codec_id, samplerate, channel, bit))
224                 return MC_PARAM_ERROR;
225
226         MEDIACODEC_CHECK_CONDITION(mc_handle->codec_id && !mc_handle->is_video && !mc_handle->is_encoder,
227                         MC_INVALID_ARG, "MEDIACODEC_ERROR_INVALID_PARAMETER");
228
229         mc_handle->info.audio.samplerate = samplerate;
230         mc_handle->info.audio.channel = channel;
231         mc_handle->info.audio.bit_depth = bit;
232         mc_handle->is_prepared = true;
233
234         return ret;
235 }
236
237 int mc_set_aenc_info(MMHandleType mediacodec, int samplerate, int channel, int bit, int bitrate)
238 {
239         int ret = MC_ERROR_NONE;
240         mc_handle_t * mc_handle = (mc_handle_t *) mediacodec;
241
242         if (!mc_handle) {
243                 LOGE("fail invaild param\n");
244                 return MC_INVALID_ARG;
245         }
246
247         if (!_check_support_audio_info(mc_handle->codec_id, samplerate, channel, bit))
248                 return MC_PARAM_ERROR;
249
250         MEDIACODEC_CHECK_CONDITION(mc_handle->codec_id && !mc_handle->is_video && mc_handle->is_encoder,
251                         MC_INVALID_ARG, "MEDIACODEC_ERROR_INVALID_PARAMETER");
252
253         mc_handle->info.audio.samplerate = samplerate;
254         mc_handle->info.audio.channel = channel;
255         mc_handle->info.audio.bit_depth = bit;
256         mc_handle->info.audio.bitrate = bitrate * 1000;
257
258         mc_handle->is_prepared = true;
259
260         return ret;
261 }
262
263 int mc_configure(MMHandleType mediacodec, media_format_h format, int flags)
264 {
265         int ret = MC_ERROR_NONE;
266         mc_handle_t *mc_handle = (mc_handle_t *) mediacodec;
267         int i;
268         const int codec_mask = 0xFFF0;
269         int codec_id = 0;
270         int channel = 0;
271         int samplerate = 0;
272         int bit = 0;
273         int bitrate = 0;
274         int width = 0;
275         int height = 0;
276         int fps = 0;
277         media_format_type_e type;
278         media_format_mimetype_e mimetype;
279
280         if (!mc_handle) {
281                 LOGE("fail invaild param");
282                 return MC_INVALID_ARG;
283         }
284
285         if (media_format_get_type(format, &type) != MEDIA_FORMAT_ERROR_NONE) {
286                 LOGE("failed to retrieve type");
287                 return MC_INVALID_ARG;
288         }
289
290         if (type == MEDIA_FORMAT_AUDIO) {
291                 media_format_get_audio_info(format, &mimetype, &channel, &samplerate, &bit, &bitrate);
292
293                 codec_id = mimetype & codec_mask;
294
295                 if (GET_IS_ENCODER(flags)) {
296                         if (!_check_support_audio_info(codec_id, samplerate, channel, bit)) {
297                                 LOGE("invalid pram is set : samplerate : %d, channel : %d, bit : %d, bitrate : %d",
298                                         samplerate, channel, bit, bitrate);
299                                 return MC_PARAM_ERROR;
300                         }
301
302                         mc_handle->info.audio.samplerate = samplerate;
303                         mc_handle->info.audio.channel = channel;
304                         mc_handle->info.audio.bit_depth = bit;
305                         mc_handle->info.audio.bitrate = bitrate * 1000;
306                 } else if (GET_IS_DECODER(flags)) {
307                         if (!_check_support_audio_info(codec_id, samplerate, channel, bit)) {
308                                 LOGE("invalid pram is set : samplerate : %d, channel : %d, bit : %d",
309                                         samplerate, channel, bit);
310                                 return MC_PARAM_ERROR;
311                         }
312                         mc_handle->info.audio.samplerate = samplerate;
313                         mc_handle->info.audio.channel = channel;
314                         mc_handle->info.audio.bit_depth = bit;
315                 } else {
316                         LOGE("either an encoder or a decoder must be set");
317                         return MC_PARAM_ERROR;
318                 }
319         } else if (type == MEDIA_FORMAT_VIDEO) {
320                 media_format_get_video_info(format, &mimetype, &width, &height, &bitrate, NULL);
321                 media_format_get_video_frame_rate(format, &fps);
322                 codec_id = mimetype & codec_mask;
323
324                 if (GET_IS_ENCODER(flags)) {
325                         if (!_check_support_video_info(codec_id, width, height) || fps <= 0 || bitrate <= 0) {
326                                 LOGE("invalid pram is set : width : %d, height : %d, bitrate : %d, fps : %d",
327                                         width, height, bitrate, fps);
328                                 return MC_PARAM_ERROR;
329                         }
330
331                         mc_handle->info.video.width = width;
332                         mc_handle->info.video.height = height;
333                         mc_handle->info.video.framerate = fps;
334                         mc_handle->info.video.bitrate = bitrate * 1000;
335                 } else if (GET_IS_DECODER(flags)) {
336                         if (!_check_support_video_info(codec_id, width, height)) {
337                                 LOGE("invalid pram is set : width : %d, height : %d",
338                                         width, height);
339                                 return MC_PARAM_ERROR;
340                         }
341
342                         mc_handle->info.video.width = width;
343                         mc_handle->info.video.height = height;
344                 } else {
345                         LOGE("either an encoder or a decoder must be set");
346                         return MC_PARAM_ERROR;
347                 }
348         } else {
349                 LOGE("invalid format type is set");
350                 return MC_PARAM_ERROR;
351         }
352
353         if (!GET_IS_HW(flags) && !GET_IS_SW(flags))
354                 flags |= MEDIACODEC_SUPPORT_TYPE_SW;
355
356         for (i = 0; i < mc_handle->ini->num_supported_codecs; i++) {
357                 if ((codec_id == spec_emul[i].codec_id) && (flags == spec_emul[i].codec_type))
358                         break;
359         }
360         LOGD("support_list : %d, i : %d", mc_handle->ini->num_supported_codecs, i);
361
362         if (i == mc_handle->ini->num_supported_codecs)
363                 return MC_CODEC_NOT_FOUND;
364
365         mc_handle->port_type = spec_emul[i].port_type;
366
367         mc_handle->is_encoder = GET_IS_ENCODER(flags) ? 1 : 0;
368         mc_handle->is_hw = GET_IS_HW(flags) ? 1 : 0;
369         mc_handle->codec_id = codec_id;
370         mc_handle->is_video = CHECK_BIT(codec_id, 13);
371
372         mc_handle->is_prepared = true;
373
374         LOGD("encoder : %d, hardware : %d, codec_id : %x, video : %d",
375                         mc_handle->is_encoder, mc_handle->is_hw, mc_handle->codec_id, mc_handle->is_video);
376
377         return ret;
378 }
379
380 int mc_prepare(MMHandleType mediacodec)
381 {
382         int ret = MC_ERROR_NONE;
383         mc_handle_t *mc_handle = (mc_handle_t *) mediacodec;
384
385         if (!mc_handle) {
386                 LOGE("fail invaild param\n");
387                 return MC_INVALID_ARG;
388         }
389
390         if (!mc_handle->is_prepared)
391                 return MC_NOT_INITIALIZED;
392
393         /* setting core details */
394         switch (mc_handle->port_type) {
395         case MEDIACODEC_PORT_TYPE_GENERAL:
396                 break;
397
398         case MEDIACODEC_PORT_TYPE_OMX:
399                 break;
400
401         case MEDIACODEC_PORT_TYPE_GST:
402                 mc_gst_prepare(mc_handle);
403                 break;
404
405         default:
406                 break;
407         }
408
409         return ret;
410 }
411
412 int mc_unprepare(MMHandleType mediacodec)
413 {
414         int ret = MC_ERROR_NONE;
415         mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
416
417         if (!mc_handle) {
418                 LOGE("fail invaild param\n");
419                 return MC_INVALID_ARG;
420         }
421
422         /* deinit core details */
423         switch (mc_handle->port_type) {
424         case MEDIACODEC_PORT_TYPE_GENERAL:
425                 break;
426
427         case MEDIACODEC_PORT_TYPE_OMX:
428                 break;
429
430         case MEDIACODEC_PORT_TYPE_GST:
431                 ret = mc_gst_unprepare(mc_handle);
432                 break;
433
434         default:
435                 break;
436         }
437
438         return ret;
439 }
440
441 int mc_process_input(MMHandleType mediacodec, media_packet_h inbuf, uint64_t timeOutUs)
442 {
443         int ret = MC_ERROR_NONE;
444
445         mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
446
447         if (!mc_handle) {
448                 LOGE("fail invaild param");
449                 return MC_INVALID_ARG;
450         }
451
452         if (!inbuf) {
453                 LOGE("invaild input buffer");
454                 return MC_INVALID_IN_BUF;
455         }
456
457         switch (mc_handle->port_type) {
458         case MEDIACODEC_PORT_TYPE_GENERAL:
459                 break;
460
461         case MEDIACODEC_PORT_TYPE_OMX:
462                 break;
463
464         case MEDIACODEC_PORT_TYPE_GST:
465                 ret = mc_gst_process_input(mc_handle, inbuf, timeOutUs);
466                 break;
467
468         default:
469                 break;
470         }
471
472         return ret;
473 }
474
475 int mc_get_output(MMHandleType mediacodec, media_packet_h *outbuf, uint64_t timeOutUs)
476 {
477         int ret = MC_ERROR_NONE;
478         mc_handle_t *mc_handle = (mc_handle_t *) mediacodec;
479
480         if (!mc_handle) {
481                 LOGE("fail invaild param\n");
482                 return MC_INVALID_ARG;
483         }
484
485         /* setting core details */
486         switch (mc_handle->port_type) {
487         case MEDIACODEC_PORT_TYPE_GENERAL:
488                 break;
489
490         case MEDIACODEC_PORT_TYPE_OMX:
491                 break;
492
493         case MEDIACODEC_PORT_TYPE_GST:
494                 ret = mc_gst_get_output(mc_handle, outbuf, timeOutUs);
495                 break;
496
497         default:
498                 break;
499         }
500
501         return ret;
502 }
503
504 int mc_flush_buffers(MMHandleType mediacodec)
505 {
506         int ret = MC_ERROR_NONE;
507         mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
508
509         if (!mc_handle) {
510                 LOGE("fail invaild param\n");
511                 return MC_INVALID_ARG;
512         }
513
514         /* setting core details */
515         switch (mc_handle->port_type) {
516         case MEDIACODEC_PORT_TYPE_GENERAL:
517                 break;
518
519         case MEDIACODEC_PORT_TYPE_OMX:
520                 break;
521
522         case MEDIACODEC_PORT_TYPE_GST:
523                 ret = mc_gst_flush_buffers(mc_handle);
524                 break;
525
526         default:
527                 break;
528         }
529
530         return ret;
531 }
532
533 int mc_get_supported_type(MMHandleType mediacodec, mediacodec_codec_type_e codec_type, bool encoder, int *support_type)
534 {
535         int ret = MC_ERROR_NONE;
536         mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
537         mc_codec_map_t *codec_map;
538         int num_supported_codec = 0;
539         int i;
540
541         *support_type = 0;
542
543         if (!mc_handle) {
544                 LOGE("fail invaild param\n");
545                 return MC_INVALID_ARG;
546         }
547
548         codec_map = encoder ? mc_handle->encoder_map : mc_handle->decoder_map;
549         num_supported_codec = encoder ? mc_handle->num_supported_encoder : mc_handle->num_supported_decoder;
550
551         for (i = 0; i < num_supported_codec; i++) {
552                 if (codec_map[i].id == codec_type) {
553                         if (codec_map[i].hardware)
554                                 *support_type |= MEDIACODEC_SUPPORT_TYPE_HW;
555                         else
556                                 *support_type |= MEDIACODEC_SUPPORT_TYPE_SW;
557                 }
558         }
559
560         return ret;
561 }
562
563 int mc_set_empty_buffer_cb(MMHandleType mediacodec, mediacodec_input_buffer_used_cb callback, void *user_data)
564 {
565         int ret = MC_ERROR_NONE;
566         mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
567
568         if (!mc_handle) {
569                 LOGE("fail invaild param\n");
570                 return MC_INVALID_ARG;
571         }
572
573         if (mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER]) {
574                 LOGE("Already set mediacodec_empty_buffer_cb");
575                 return MC_PARAM_ERROR;
576         } else {
577                 if (!callback)
578                         return MC_INVALID_ARG;
579
580                 LOGD("Set empty buffer callback(cb = %p, data = %p)", callback, user_data);
581
582                 mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER] = (mc_empty_buffer_cb) callback;
583                 mc_handle->user_data[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER] = user_data;
584
585                 return MC_ERROR_NONE;
586         }
587
588         return ret;
589 }
590
591 int mc_unset_empty_buffer_cb(MMHandleType mediacodec)
592 {
593         mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
594
595         if (!mc_handle) {
596                 LOGE("fail invaild param\n");
597                 return MC_INVALID_ARG;
598         }
599
600         mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER] = NULL;
601         mc_handle->user_data[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER] = NULL;
602
603         return MC_ERROR_NONE;
604 }
605
606 int mc_set_fill_buffer_cb(MMHandleType mediacodec, mediacodec_output_buffer_available_cb callback, void *user_data)
607 {
608         int ret = MC_ERROR_NONE;
609         mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
610
611         if (!mc_handle) {
612                 LOGE("fail invaild param\n");
613                 return MC_INVALID_ARG;
614         }
615
616         if (mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_FILLBUFFER]) {
617                 LOGE("Already set mediacodec_fill_buffer_cb");
618                 return MC_PARAM_ERROR;
619         } else {
620                 if (!callback)
621                         return MC_INVALID_ARG;
622
623                 LOGD("Set fill buffer callback(cb = %p, data = %p)", callback, user_data);
624
625                 mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_FILLBUFFER] = (mc_fill_buffer_cb) callback;
626                 mc_handle->user_data[_MEDIACODEC_EVENT_TYPE_FILLBUFFER] = user_data;
627                 return MC_ERROR_NONE;
628         }
629
630         return ret;
631 }
632
633 int mc_unset_fill_buffer_cb(MMHandleType mediacodec)
634 {
635         mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
636
637         if (!mc_handle) {
638                 LOGE("fail invaild param\n");
639                 return MC_INVALID_ARG;
640         }
641
642         mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_FILLBUFFER] = NULL;
643         mc_handle->user_data[_MEDIACODEC_EVENT_TYPE_FILLBUFFER] = NULL;
644
645         return MC_ERROR_NONE;
646 }
647
648 int mc_set_error_cb(MMHandleType mediacodec, mediacodec_error_cb callback, void *user_data)
649 {
650         int ret = MC_ERROR_NONE;
651         mc_handle_t *mc_handle = (mc_handle_t *) mediacodec;
652
653         if (!mc_handle) {
654                 LOGE("fail invaild param\n");
655                 return MC_INVALID_ARG;
656         }
657
658         if (mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_ERROR]) {
659                 LOGE("Already set mediacodec_fill_buffer_cb\n");
660                 return MC_PARAM_ERROR;
661         } else {
662                 if (!callback)
663                         return MC_INVALID_ARG;
664
665                 LOGD("Set event handler callback(cb = %p, data = %p)\n", callback, user_data);
666
667                 mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_ERROR] = (mc_error_cb) callback;
668                 mc_handle->user_data[_MEDIACODEC_EVENT_TYPE_ERROR] = user_data;
669                 return MC_ERROR_NONE;
670         }
671
672         return ret;
673 }
674
675 int mc_unset_error_cb(MMHandleType mediacodec)
676 {
677         mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
678
679         if (!mc_handle) {
680                 LOGE("fail invaild param");
681                 return MC_INVALID_ARG;
682         }
683
684         mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_ERROR] = NULL;
685         mc_handle->user_data[_MEDIACODEC_EVENT_TYPE_ERROR] = NULL;
686
687         return MC_ERROR_NONE;
688 }
689
690 int mc_set_eos_cb(MMHandleType mediacodec, mediacodec_eos_cb callback, void *user_data)
691 {
692         int ret = MC_ERROR_NONE;
693         mc_handle_t *mc_handle = (mc_handle_t *) mediacodec;
694
695         if (!mc_handle) {
696                 LOGE("fail invaild param\n");
697                 return MC_INVALID_ARG;
698         }
699
700         if (mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_EOS]) {
701                 LOGE("Already set mediacodec_fill_buffer_cb");
702                 return MC_PARAM_ERROR;
703         } else {
704                 if (!callback)
705                         return MC_INVALID_ARG;
706
707                 LOGD("Set event handler callback(cb = %p, data = %p)\n", callback, user_data);
708
709                 mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_EOS] = (mc_eos_cb) callback;
710                 mc_handle->user_data[_MEDIACODEC_EVENT_TYPE_EOS] = user_data;
711                 return MC_ERROR_NONE;
712         }
713
714         return ret;
715 }
716
717 int mc_unset_eos_cb(MMHandleType mediacodec)
718 {
719         mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
720
721         if (!mc_handle) {
722                 LOGE("fail invaild param\n");
723                 return MC_INVALID_ARG;
724         }
725
726         mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_EOS] = NULL;
727         mc_handle->user_data[_MEDIACODEC_EVENT_TYPE_EOS] = NULL;
728
729         return MC_ERROR_NONE;
730 }
731
732 int mc_set_buffer_status_cb(MMHandleType mediacodec, mediacodec_buffer_status_cb callback, void *user_data)
733 {
734         int ret = MC_ERROR_NONE;
735         mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
736
737         if (!mc_handle) {
738                 LOGE("fail invaild param\n");
739                 return MC_INVALID_ARG;
740         }
741
742         if (mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS]) {
743                 LOGE("Already set mediacodec_need_data_cb\n");
744                 return MC_PARAM_ERROR;
745         } else {
746                 if (!callback)
747                         return MC_INVALID_ARG;
748
749                 LOGD("Set start feed callback(cb = %p, data = %p)\n", callback, user_data);
750
751                 mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS] = (mc_buffer_status_cb) callback;
752                 mc_handle->user_data[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS] = user_data;
753                 return MC_ERROR_NONE;
754         }
755
756         return ret;
757 }
758
759 int mc_unset_buffer_status_cb(MMHandleType mediacodec)
760 {
761         mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
762
763         if (!mc_handle) {
764                 LOGE("fail invaild param\n");
765                 return MC_INVALID_ARG;
766         }
767
768         mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS] = NULL;
769         mc_handle->user_data[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS] = NULL;
770
771         return MC_ERROR_NONE;
772 }
773
774 int mc_set_supported_codec_cb(MMHandleType mediacodec, mediacodec_supported_codec_cb callback, void *user_data)
775 {
776         int ret = MC_ERROR_NONE;
777         mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
778
779         if (!mc_handle) {
780                 LOGE("fail invaild param\n");
781                 return MC_INVALID_ARG;
782         }
783
784         if (mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_SUPPORTED_CODEC]) {
785                 LOGE("Already set mediacodec_supported_codec_cb\n");
786                 return MC_PARAM_ERROR;
787         } else {
788                 if (!callback)
789                         return MC_INVALID_ARG;
790
791                 LOGD("Set event handler callback(cb = %p, data = %p)", callback, user_data);
792
793                 mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_SUPPORTED_CODEC] = (mc_supported_codec_cb) callback;
794                 mc_handle->user_data[_MEDIACODEC_EVENT_TYPE_SUPPORTED_CODEC] = user_data;
795                 return MC_ERROR_NONE;
796         }
797
798         return ret;
799 }
800
801 int _mediacodec_foreach_supported_codec(mediacodec_supported_codec_cb callback, void *user_data)
802 {
803         int ret = MEDIACODEC_NONE;
804         int i;
805         int index;
806
807         gboolean codec[CODEC_NR_ITEMS] = {0,};
808
809         for (i = 0; i < mc_ini.num_supported_codecs; i++) {
810                 index = (int)codec_type_to_simple_enumeration(spec_emul[i].codec_id);
811                 codec[index] = TRUE;
812         }
813
814         for (i = 0; i < CODEC_NR_ITEMS; i++) {
815                 if (codec[i]) {
816                         index = (int)simple_to_codec_type_enumeration(i);
817                         if (!callback(index, user_data))
818                                 goto CALLBACK_ERROR;
819                 }
820         }
821
822         if (!callback(-1, user_data)) {
823                 ret = MEDIACODEC_ERROR_INTERNAL;
824                 goto CALLBACK_ERROR;
825         }
826
827 CALLBACK_ERROR:
828         LOGD("foreach callback returned error");
829         return ret;
830 }
831
832 int mc_get_packet_pool(MMHandleType mediacodec, media_packet_pool_h *pool)
833 {
834         int ret = MC_ERROR_NONE;
835         mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
836
837         if (!mc_handle) {
838                 LOGE("fail invaild param\n");
839                 return MC_INVALID_ARG;
840         }
841
842         /* setting core details */
843         switch (mc_handle->port_type) {
844         case MEDIACODEC_PORT_TYPE_GENERAL:
845                 break;
846
847         case MEDIACODEC_PORT_TYPE_OMX:
848                 break;
849
850         case MEDIACODEC_PORT_TYPE_GST:
851                 ret = mc_gst_get_packet_pool(mc_handle, pool);
852                 break;
853
854         default:
855                 break;
856         }
857
858         return ret;
859 }
860
861 void _mc_create_decoder_map_from_ini(mc_handle_t *mediacodec)
862 {
863         int indx = 0, count = 0;
864         int codec_list = mediacodec->ini->codec_list;
865         for (indx = 0; indx < codec_list; indx++) {
866                 if (strcmp(mediacodec->ini->codec[indx].codec_info[0].name, "")) {
867                         mediacodec->decoder_map[count].id = mediacodec->ini->codec[indx].codec_id;
868                         mediacodec->decoder_map[count].hardware = 1; /* hardware */
869                         mediacodec->decoder_map[count].type.factory_name = mediacodec->ini->codec[indx].codec_info[0].name;
870                         mediacodec->decoder_map[count].type.mime = mediacodec->ini->codec[indx].codec_info[0].mime;
871                         mediacodec->decoder_map[count].type.out_format =
872                                 _mc_convert_media_format_str_to_int(mediacodec->ini->codec[indx].codec_info[0].format);
873                         count++;
874                 }
875
876                 if (strcmp(mediacodec->ini->codec[indx].codec_info[2].name, "")) {
877                         mediacodec->decoder_map[count].id = mediacodec->ini->codec[indx].codec_id;
878                         mediacodec->decoder_map[count].hardware = 0; /* software */
879                         mediacodec->decoder_map[count].type.factory_name = mediacodec->ini->codec[indx].codec_info[2].name;
880                         mediacodec->decoder_map[count].type.mime = mediacodec->ini->codec[indx].codec_info[2].mime;
881                         mediacodec->decoder_map[count].type.out_format =
882                                 _mc_convert_media_format_str_to_int(mediacodec->ini->codec[indx].codec_info[2].format);
883                         count++;
884                 }
885         }
886         mediacodec->num_supported_decoder = count;
887         return;
888
889 }
890
891 void _mc_create_encoder_map_from_ini(mc_handle_t *mediacodec)
892 {
893         int indx = 0, count = 0;
894         int codec_list = mediacodec->ini->codec_list;
895
896         for (indx = 0; indx < codec_list; indx++) {
897                 if (strcmp(mediacodec->ini->codec[indx].codec_info[1].name, "")) {
898                         mediacodec->encoder_map[count].id = mediacodec->ini->codec[indx].codec_id;
899                         mediacodec->encoder_map[count].hardware = 1;
900                         mediacodec->encoder_map[count].type.factory_name = mediacodec->ini->codec[indx].codec_info[1].name;
901                         mediacodec->encoder_map[count].type.mime = mediacodec->ini->codec[indx].codec_info[1].mime;
902                         mediacodec->encoder_map[count].type.out_format =
903                                 _mc_convert_media_format_str_to_int(mediacodec->ini->codec[indx].codec_info[1].format);
904                         count++;
905                 }
906
907                 if (strcmp(mediacodec->ini->codec[indx].codec_info[3].name, "")) {
908                         mediacodec->encoder_map[count].id = mediacodec->ini->codec[indx].codec_id;
909                         mediacodec->encoder_map[count].hardware = 0;
910                         mediacodec->encoder_map[count].type.factory_name = mediacodec->ini->codec[indx].codec_info[3].name;
911                         mediacodec->encoder_map[count].type.mime = mediacodec->ini->codec[indx].codec_info[3].mime;
912                         mediacodec->encoder_map[count].type.out_format =
913                                 _mc_convert_media_format_str_to_int(mediacodec->ini->codec[indx].codec_info[3].format);
914                         count++;
915                 }
916         }
917         mediacodec->num_supported_encoder = count;
918         return;
919
920 }
921 void _mc_create_codec_map_from_ini(mc_handle_t *mediacodec, mc_codec_spec_t *spec_emul)
922 {
923         int indx = 0, count = 0;
924         int codec_list = mediacodec->ini->codec_list;
925
926         for (indx = 0; indx < codec_list; indx++) {
927                 if (strcmp(mediacodec->ini->codec[indx].codec_info[0].name, "")) {
928                         spec_emul[count].codec_id = mediacodec->ini->codec[indx].codec_id;
929                         spec_emul[count].codec_type =  MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_HW;
930                         spec_emul[count].port_type =  MEDIACODEC_PORT_TYPE_GST;
931                         count++;
932                 }
933                 if (strcmp(mediacodec->ini->codec[indx].codec_info[1].name, "")) {
934                         spec_emul[count].codec_id = mediacodec->ini->codec[indx].codec_id;
935                         spec_emul[count].codec_type =  MEDIACODEC_ENCODER | MEDIACODEC_SUPPORT_TYPE_HW;
936                         spec_emul[count].port_type =  MEDIACODEC_PORT_TYPE_GST;
937                         count++;
938                 }
939                 if (strcmp(mediacodec->ini->codec[indx].codec_info[2].name, "")) {
940                         spec_emul[count].codec_id = mediacodec->ini->codec[indx].codec_id;
941                         spec_emul[count].codec_type =  MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_SW;
942                         spec_emul[count].port_type =  MEDIACODEC_PORT_TYPE_GST;
943                         count++;
944                 }
945                 if (strcmp(mediacodec->ini->codec[indx].codec_info[3].name, "")) {
946                         spec_emul[count].codec_id = mediacodec->ini->codec[indx].codec_id;
947                         spec_emul[count].codec_type =  MEDIACODEC_ENCODER | MEDIACODEC_SUPPORT_TYPE_SW;
948                         spec_emul[count].port_type =  MEDIACODEC_PORT_TYPE_GST;
949                         count++;
950                 }
951         }
952
953         mediacodec->ini->num_supported_codecs = count;
954         LOGE("supported codecs :%d", count);
955         return;
956 }
957
958 void _mc_create_codec_map_from_ini_static(mc_ini_t *ini, mc_codec_spec_t *spec_emul)
959 {
960         int indx = 0, count = 0;
961         int codec_list = ini->codec_list;
962
963         for (indx = 0; indx < codec_list; indx++) {
964                 if (strcmp(ini->codec[indx].codec_info[0].name, "")) {
965                         spec_emul[count].codec_id = ini->codec[indx].codec_id;
966                         spec_emul[count].codec_type =  MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_HW;
967                         spec_emul[count].port_type =  MEDIACODEC_PORT_TYPE_GST;
968                         count++;
969                 }
970                 if (strcmp(ini->codec[indx].codec_info[1].name, "")) {
971                         spec_emul[count].codec_id = ini->codec[indx].codec_id;
972                         spec_emul[count].codec_type =  MEDIACODEC_ENCODER | MEDIACODEC_SUPPORT_TYPE_HW;
973                         spec_emul[count].port_type =  MEDIACODEC_PORT_TYPE_GST;
974                         count++;
975                 }
976                 if (strcmp(ini->codec[indx].codec_info[2].name, "")) {
977                         spec_emul[count].codec_id = ini->codec[indx].codec_id;
978                         spec_emul[count].codec_type =  MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_SW;
979                         spec_emul[count].port_type =  MEDIACODEC_PORT_TYPE_GST;
980                         count++;
981                 }
982                 if (strcmp(ini->codec[indx].codec_info[3].name, "")) {
983                         spec_emul[count].codec_id = ini->codec[indx].codec_id;
984                         spec_emul[count].codec_type =  MEDIACODEC_ENCODER | MEDIACODEC_SUPPORT_TYPE_SW;
985                         spec_emul[count].port_type =  MEDIACODEC_PORT_TYPE_GST;
986                         count++;
987                 }
988         }
989
990         ini->num_supported_codecs = count;
991         LOGE("supported codecs :%d", count);
992         return;
993 }
994
995 codec_type_e codec_type_to_simple_enumeration(mediacodec_codec_type_e media_codec_id)
996 {
997         guint media_codec_id_u = (guint)media_codec_id;
998
999         switch (media_codec_id_u) {
1000         case MEDIACODEC_L16:
1001                 return L16;
1002         case MEDIACODEC_ALAW:
1003                 return ALAW;
1004         case MEDIACODEC_ULAW:
1005                 return ULAW;
1006         case MEDIACODEC_AMR_NB:
1007                 return AMR_NB;
1008         case MEDIACODEC_AMR_WB:
1009                 return AMR_WB;
1010         case MEDIACODEC_G729:
1011                 return G729;
1012         case MEDIACODEC_AAC_LC:
1013                 return AAC_LC;
1014         case MEDIACODEC_AAC_HE:
1015                 return AAC_HE;
1016         case MEDIACODEC_AAC_HE_PS:
1017                 return AAC_HE_PS;
1018         case MEDIACODEC_MP3:
1019                 return MP3;
1020         case MEDIACODEC_VORBIS:
1021                 return VORBIS;
1022         case MEDIACODEC_FLAC:
1023                 return FLAC;
1024         case MEDIACODEC_WMAV1:
1025                 return WMAV1;
1026         case MEDIACODEC_WMAV2:
1027                 return WMAV2;
1028         case MEDIACODEC_WMAPRO:
1029                 return WMAPRO;
1030         case MEDIACODEC_WMALSL:
1031                 return WMALSL;
1032         case MEDIACODEC_H261:
1033                 return H261;
1034         case MEDIACODEC_H263:
1035                 return H263;
1036         case MEDIACODEC_H264:
1037                 return H264;
1038         case MEDIACODEC_MJPEG:
1039                 return MJPEG;
1040         case MEDIACODEC_MPEG1:
1041                 return MPEG1;
1042         case MEDIACODEC_MPEG2:
1043                 return MPEG2;
1044         case MEDIACODEC_MPEG4:
1045                 return MPEG4;
1046         case MEDIACODEC_HEVC:
1047                 return HEVC;
1048         case MEDIACODEC_VP8:
1049                 return VP8;
1050         case MEDIACODEC_VP9:
1051                 return VP9;
1052         case MEDIACODEC_VC1:
1053                 return VC1;
1054         default:
1055                 return NONE;
1056         }
1057 }
1058
1059 mediacodec_codec_type_e simple_to_codec_type_enumeration(codec_type_e codec_id)
1060 {
1061         guint codec_id_u = (guint)codec_id;
1062
1063         switch (codec_id_u) {
1064         case L16:
1065                 return MEDIACODEC_L16;
1066         case ALAW:
1067                 return MEDIACODEC_ALAW;
1068         case ULAW:
1069                 return MEDIACODEC_ULAW;
1070         case AMR_NB:
1071                 return MEDIACODEC_AMR_NB;
1072         case AMR_WB:
1073                 return MEDIACODEC_AMR_WB;
1074         case G729:
1075                 return MEDIACODEC_G729;
1076         case AAC_LC:
1077                 return MEDIACODEC_AAC_LC;
1078         case AAC_HE:
1079                 return MEDIACODEC_AAC_HE;
1080         case AAC_HE_PS:
1081                 return MEDIACODEC_AAC_HE_PS;
1082         case MP3:
1083                 return MEDIACODEC_MP3;
1084         case VORBIS:
1085                 return MEDIACODEC_VORBIS;
1086         case FLAC:
1087                 return MEDIACODEC_FLAC;
1088         case WMAV1:
1089                 return MEDIACODEC_WMAV1;
1090         case WMAV2:
1091                 return MEDIACODEC_WMAV2;
1092         case WMAPRO:
1093                 return MEDIACODEC_WMAPRO;
1094         case WMALSL:
1095                 return MEDIACODEC_WMALSL;
1096         case H261:
1097                 return MEDIACODEC_H261;
1098         case H263:
1099                 return MEDIACODEC_H263;
1100         case H264:
1101                 return MEDIACODEC_H264;
1102         case MJPEG:
1103                 return MEDIACODEC_MJPEG;
1104         case MPEG1:
1105                 return MEDIACODEC_MPEG1;
1106         case MPEG2:
1107                 return MEDIACODEC_MPEG2;
1108         case MPEG4:
1109                 return MEDIACODEC_MPEG4;
1110         case HEVC:
1111                 return MEDIACODEC_HEVC;
1112         case VP8:
1113                 return MEDIACODEC_VP8;
1114         case VP9:
1115                 return MEDIACODEC_VP9;
1116         case VC1:
1117                 return MEDIACODEC_VC1;
1118         default:
1119                 return NONE;
1120         }
1121 }
1122
1123 gboolean _check_support_audio_info(mediacodec_codec_type_e codec_id, int samplerate, int channel, int bit_depth)
1124 {
1125         gint i = 0;
1126         gint maxchannels = 2;
1127         gint n_rates = 0;
1128         gint s_bit_depth = 32;
1129
1130         switch (codec_id) {
1131         case MEDIACODEC_AMR_NB:
1132         {
1133                 const static gint l_rates[] = { 8000 };
1134                 maxchannels = 1;
1135                 n_rates = G_N_ELEMENTS(l_rates);
1136                 s_bit_depth = 16;       /* NOTE: amrnbenc/amrnbdec surpports S16LE as format*/
1137
1138                 while (i < n_rates) {
1139                         if (l_rates[i] == samplerate)
1140                                 break;
1141                         i++;
1142                 }
1143
1144                 if (i == n_rates) {
1145                         LOGE("Invalid samplerate set");
1146                         return false;
1147                 }
1148                 break;
1149         }
1150         case MEDIACODEC_AAC_LC:
1151         case MEDIACODEC_AAC_HE:
1152         {
1153                 const static gint l_rates[] = { 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350 };
1154                 maxchannels = 6;
1155                 n_rates = G_N_ELEMENTS(l_rates);
1156                 s_bit_depth = 32;       /* NOTE: avdec_aac/avenc_aac surpports S32LE as format*/
1157
1158                 while (i < n_rates) {
1159                         if (l_rates[i] == samplerate)
1160                                 break;
1161                         i++;
1162                 }
1163
1164                 if (i == n_rates) {
1165                         LOGE("Invalid samplerate set");
1166                         return false;
1167                 }
1168                 break;
1169         }
1170         case MEDIACODEC_MP3:
1171         {
1172                 s_bit_depth = 16;       /* NOTE: amrenc/amrnbdec surpports S16LE as format*/
1173                 break;
1174         }
1175         case MEDIACODEC_VORBIS:
1176         {
1177                 s_bit_depth = 32;       /* NOTE:  vorbisenc/vorbisdec surpports S32LE as format */
1178                 break;
1179         }
1180         case MEDIACODEC_FLAC:
1181         {
1182                 s_bit_depth = 32;       /* NOTE: avdec_flac surpports S32LE as format */
1183                 break;
1184         }
1185         default:
1186                 break;
1187         }
1188
1189         if (channel < 0 || channel > maxchannels) {
1190                 LOGE("Invalid channel set");
1191                 return false;
1192         }
1193
1194         if (bit_depth != s_bit_depth) {
1195                 LOGE("Invalid bit set");
1196                 return false;
1197         }
1198
1199         return true;
1200 }
1201
1202 gboolean _check_support_video_info(mediacodec_codec_type_e codec_id, int width, int height)
1203 {
1204         gint i = 0;
1205         gint n_sizes = 0;
1206
1207         if (width <= 0 || height <= 0) {
1208                 LOGE("Invalid resolution set");
1209                 return false;
1210         }
1211
1212         switch (codec_id) {
1213         case MEDIACODEC_H261:
1214         {
1215                 const static gint widths[] = { 352, 176 };
1216                 const static gint heights[] = { 288, 144 };
1217                 n_sizes = G_N_ELEMENTS(widths);
1218
1219                 while (i < n_sizes) {
1220                         if ((widths[i] == width) && (heights[i] == height))
1221                                 break;
1222                         i++;
1223                 }
1224
1225                 if (i == n_sizes) {
1226                         LOGE("Invalid resolution set");
1227                         return false;
1228                 }
1229                 break;
1230         }
1231         case MEDIACODEC_H263:
1232         {
1233                 const static gint widths[] = { 352, 704, 176, 1408, 128 };
1234                 const static gint heights[] = { 288, 576, 144, 1152, 96 };
1235                 n_sizes = G_N_ELEMENTS(widths);
1236
1237                 while (i < n_sizes) {
1238                         if ((widths[i] == width) && (heights[i] == height))
1239                                 break;
1240                         i++;
1241                 }
1242
1243                 if (i == n_sizes) {
1244                         LOGE("Invalid resolution set");
1245                         return false;
1246                 }
1247                 break;
1248         }
1249         default:
1250                 break;
1251         }
1252
1253         return true;
1254 }