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