Remove dead codes
[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 _mediacodec_foreach_supported_codec(mediacodec_supported_codec_cb callback, void *user_data)
783 {
784         int i;
785         int index;
786
787         gboolean codec[CODEC_NR_ITEMS] = {0,};
788
789         for (i = 0; i < mc_ini.num_supported_codecs; i++) {
790                 index = (int)codec_type_to_simple_enumeration(spec_emul[i].codec_id);
791                 codec[index] = TRUE;
792         }
793
794         for (i = 0; i < CODEC_NR_ITEMS; i++) {
795                 if (codec[i]) {
796                         index = (int)simple_to_codec_type_enumeration(i);
797                         if (!callback(index, user_data)) {
798                                 LOGW("stop foreach callback");
799                                 break;
800                         }
801                 }
802         }
803
804         LOGD("done");
805
806         return MEDIACODEC_ERROR_NONE;
807 }
808
809 int mc_get_packet_pool(MMHandleType mediacodec, media_packet_pool_h *pool)
810 {
811         int ret = MC_ERROR_NONE;
812         mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
813
814         if (!mc_handle) {
815                 LOGE("fail invaild param\n");
816                 return MC_INVALID_ARG;
817         }
818
819         /* setting core details */
820         switch (mc_handle->port_type) {
821         case MEDIACODEC_PORT_TYPE_GENERAL:
822                 break;
823
824         case MEDIACODEC_PORT_TYPE_OMX:
825                 break;
826
827         case MEDIACODEC_PORT_TYPE_GST:
828                 ret = mc_gst_get_packet_pool(mc_handle, pool);
829                 break;
830
831         default:
832                 break;
833         }
834
835         return ret;
836 }
837
838 void _mc_create_decoder_map_from_ini(mc_handle_t *mediacodec)
839 {
840         int indx = 0, count = 0;
841         int codec_list = mediacodec->ini->codec_list;
842         for (indx = 0; indx < codec_list; indx++) {
843                 if (strcmp(mediacodec->ini->codec[indx].codec_info[0].name, "")) {
844                         mediacodec->decoder_map[count].id = mediacodec->ini->codec[indx].codec_id;
845                         mediacodec->decoder_map[count].hardware = 1; /* hardware */
846                         mediacodec->decoder_map[count].type.factory_name = mediacodec->ini->codec[indx].codec_info[0].name;
847                         mediacodec->decoder_map[count].type.mime = mediacodec->ini->codec[indx].codec_info[0].mime;
848                         mediacodec->decoder_map[count].type.out_format =
849                                 _mc_convert_media_format_str_to_int(mediacodec->ini->codec[indx].codec_info[0].format);
850                         count++;
851                 }
852
853                 if (strcmp(mediacodec->ini->codec[indx].codec_info[2].name, "")) {
854                         mediacodec->decoder_map[count].id = mediacodec->ini->codec[indx].codec_id;
855                         mediacodec->decoder_map[count].hardware = 0; /* software */
856                         mediacodec->decoder_map[count].type.factory_name = mediacodec->ini->codec[indx].codec_info[2].name;
857                         mediacodec->decoder_map[count].type.mime = mediacodec->ini->codec[indx].codec_info[2].mime;
858                         mediacodec->decoder_map[count].type.out_format =
859                                 _mc_convert_media_format_str_to_int(mediacodec->ini->codec[indx].codec_info[2].format);
860                         count++;
861                 }
862         }
863         mediacodec->num_supported_decoder = count;
864         return;
865
866 }
867
868 void _mc_create_encoder_map_from_ini(mc_handle_t *mediacodec)
869 {
870         int indx = 0, count = 0;
871         int codec_list = mediacodec->ini->codec_list;
872
873         for (indx = 0; indx < codec_list; indx++) {
874                 if (strcmp(mediacodec->ini->codec[indx].codec_info[1].name, "")) {
875                         mediacodec->encoder_map[count].id = mediacodec->ini->codec[indx].codec_id;
876                         mediacodec->encoder_map[count].hardware = 1;
877                         mediacodec->encoder_map[count].type.factory_name = mediacodec->ini->codec[indx].codec_info[1].name;
878                         mediacodec->encoder_map[count].type.mime = mediacodec->ini->codec[indx].codec_info[1].mime;
879                         mediacodec->encoder_map[count].type.out_format =
880                                 _mc_convert_media_format_str_to_int(mediacodec->ini->codec[indx].codec_info[1].format);
881                         count++;
882                 }
883
884                 if (strcmp(mediacodec->ini->codec[indx].codec_info[3].name, "")) {
885                         mediacodec->encoder_map[count].id = mediacodec->ini->codec[indx].codec_id;
886                         mediacodec->encoder_map[count].hardware = 0;
887                         mediacodec->encoder_map[count].type.factory_name = mediacodec->ini->codec[indx].codec_info[3].name;
888                         mediacodec->encoder_map[count].type.mime = mediacodec->ini->codec[indx].codec_info[3].mime;
889                         mediacodec->encoder_map[count].type.out_format =
890                                 _mc_convert_media_format_str_to_int(mediacodec->ini->codec[indx].codec_info[3].format);
891                         count++;
892                 }
893         }
894         mediacodec->num_supported_encoder = count;
895         return;
896
897 }
898 void _mc_create_codec_map_from_ini(mc_handle_t *mediacodec, mc_codec_spec_t *spec_emul)
899 {
900         int indx = 0, count = 0;
901         int codec_list = mediacodec->ini->codec_list;
902
903         for (indx = 0; indx < codec_list; indx++) {
904                 if (strcmp(mediacodec->ini->codec[indx].codec_info[0].name, "")) {
905                         spec_emul[count].codec_id = mediacodec->ini->codec[indx].codec_id;
906                         spec_emul[count].codec_type =  MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_HW;
907                         spec_emul[count].port_type =  MEDIACODEC_PORT_TYPE_GST;
908                         count++;
909                 }
910                 if (strcmp(mediacodec->ini->codec[indx].codec_info[1].name, "")) {
911                         spec_emul[count].codec_id = mediacodec->ini->codec[indx].codec_id;
912                         spec_emul[count].codec_type =  MEDIACODEC_ENCODER | MEDIACODEC_SUPPORT_TYPE_HW;
913                         spec_emul[count].port_type =  MEDIACODEC_PORT_TYPE_GST;
914                         count++;
915                 }
916                 if (strcmp(mediacodec->ini->codec[indx].codec_info[2].name, "")) {
917                         spec_emul[count].codec_id = mediacodec->ini->codec[indx].codec_id;
918                         spec_emul[count].codec_type =  MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_SW;
919                         spec_emul[count].port_type =  MEDIACODEC_PORT_TYPE_GST;
920                         count++;
921                 }
922                 if (strcmp(mediacodec->ini->codec[indx].codec_info[3].name, "")) {
923                         spec_emul[count].codec_id = mediacodec->ini->codec[indx].codec_id;
924                         spec_emul[count].codec_type =  MEDIACODEC_ENCODER | MEDIACODEC_SUPPORT_TYPE_SW;
925                         spec_emul[count].port_type =  MEDIACODEC_PORT_TYPE_GST;
926                         count++;
927                 }
928         }
929
930         mediacodec->ini->num_supported_codecs = count;
931         LOGE("supported codecs :%d", count);
932         return;
933 }
934
935 void _mc_create_codec_map_from_ini_static(mc_ini_t *ini, mc_codec_spec_t *spec_emul)
936 {
937         int indx = 0, count = 0;
938         int codec_list = ini->codec_list;
939
940         for (indx = 0; indx < codec_list; indx++) {
941                 if (strcmp(ini->codec[indx].codec_info[0].name, "")) {
942                         spec_emul[count].codec_id = ini->codec[indx].codec_id;
943                         spec_emul[count].codec_type =  MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_HW;
944                         spec_emul[count].port_type =  MEDIACODEC_PORT_TYPE_GST;
945                         count++;
946                 }
947                 if (strcmp(ini->codec[indx].codec_info[1].name, "")) {
948                         spec_emul[count].codec_id = ini->codec[indx].codec_id;
949                         spec_emul[count].codec_type =  MEDIACODEC_ENCODER | MEDIACODEC_SUPPORT_TYPE_HW;
950                         spec_emul[count].port_type =  MEDIACODEC_PORT_TYPE_GST;
951                         count++;
952                 }
953                 if (strcmp(ini->codec[indx].codec_info[2].name, "")) {
954                         spec_emul[count].codec_id = ini->codec[indx].codec_id;
955                         spec_emul[count].codec_type =  MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_SW;
956                         spec_emul[count].port_type =  MEDIACODEC_PORT_TYPE_GST;
957                         count++;
958                 }
959                 if (strcmp(ini->codec[indx].codec_info[3].name, "")) {
960                         spec_emul[count].codec_id = ini->codec[indx].codec_id;
961                         spec_emul[count].codec_type =  MEDIACODEC_ENCODER | MEDIACODEC_SUPPORT_TYPE_SW;
962                         spec_emul[count].port_type =  MEDIACODEC_PORT_TYPE_GST;
963                         count++;
964                 }
965         }
966
967         ini->num_supported_codecs = count;
968         LOGE("supported codecs :%d", count);
969         return;
970 }
971
972 codec_type_e codec_type_to_simple_enumeration(mediacodec_codec_type_e media_codec_id)
973 {
974         guint media_codec_id_u = (guint)media_codec_id;
975
976         switch (media_codec_id_u) {
977         case MEDIACODEC_L16:
978                 return L16;
979         case MEDIACODEC_ALAW:
980                 return ALAW;
981         case MEDIACODEC_ULAW:
982                 return ULAW;
983         case MEDIACODEC_AMR_NB:
984                 return AMR_NB;
985         case MEDIACODEC_AMR_WB:
986                 return AMR_WB;
987         case MEDIACODEC_G729:
988                 return G729;
989         case MEDIACODEC_AAC_LC:
990                 return AAC_LC;
991         case MEDIACODEC_AAC_HE:
992                 return AAC_HE;
993         case MEDIACODEC_AAC_HE_PS:
994                 return AAC_HE_PS;
995         case MEDIACODEC_MP3:
996                 return MP3;
997         case MEDIACODEC_VORBIS:
998                 return VORBIS;
999         case MEDIACODEC_FLAC:
1000                 return FLAC;
1001         case MEDIACODEC_WMAV1:
1002                 return WMAV1;
1003         case MEDIACODEC_WMAV2:
1004                 return WMAV2;
1005         case MEDIACODEC_WMAPRO:
1006                 return WMAPRO;
1007         case MEDIACODEC_WMALSL:
1008                 return WMALSL;
1009         case MEDIACODEC_H261:
1010                 return H261;
1011         case MEDIACODEC_H263:
1012                 return H263;
1013         case MEDIACODEC_H264:
1014                 return H264;
1015         case MEDIACODEC_MJPEG:
1016                 return MJPEG;
1017         case MEDIACODEC_MPEG1:
1018                 return MPEG1;
1019         case MEDIACODEC_MPEG2:
1020                 return MPEG2;
1021         case MEDIACODEC_MPEG4:
1022                 return MPEG4;
1023         case MEDIACODEC_HEVC:
1024                 return HEVC;
1025         case MEDIACODEC_VP8:
1026                 return VP8;
1027         case MEDIACODEC_VP9:
1028                 return VP9;
1029         case MEDIACODEC_VC1:
1030                 return VC1;
1031         case MEDIACODEC_OPUS:
1032                 return OPUS;
1033         default:
1034                 return NONE;
1035         }
1036 }
1037
1038 mediacodec_codec_type_e simple_to_codec_type_enumeration(codec_type_e codec_id)
1039 {
1040         guint codec_id_u = (guint)codec_id;
1041
1042         switch (codec_id_u) {
1043         case L16:
1044                 return MEDIACODEC_L16;
1045         case ALAW:
1046                 return MEDIACODEC_ALAW;
1047         case ULAW:
1048                 return MEDIACODEC_ULAW;
1049         case AMR_NB:
1050                 return MEDIACODEC_AMR_NB;
1051         case AMR_WB:
1052                 return MEDIACODEC_AMR_WB;
1053         case G729:
1054                 return MEDIACODEC_G729;
1055         case AAC_LC:
1056                 return MEDIACODEC_AAC_LC;
1057         case AAC_HE:
1058                 return MEDIACODEC_AAC_HE;
1059         case AAC_HE_PS:
1060                 return MEDIACODEC_AAC_HE_PS;
1061         case MP3:
1062                 return MEDIACODEC_MP3;
1063         case VORBIS:
1064                 return MEDIACODEC_VORBIS;
1065         case FLAC:
1066                 return MEDIACODEC_FLAC;
1067         case WMAV1:
1068                 return MEDIACODEC_WMAV1;
1069         case WMAV2:
1070                 return MEDIACODEC_WMAV2;
1071         case WMAPRO:
1072                 return MEDIACODEC_WMAPRO;
1073         case WMALSL:
1074                 return MEDIACODEC_WMALSL;
1075         case H261:
1076                 return MEDIACODEC_H261;
1077         case H263:
1078                 return MEDIACODEC_H263;
1079         case H264:
1080                 return MEDIACODEC_H264;
1081         case MJPEG:
1082                 return MEDIACODEC_MJPEG;
1083         case MPEG1:
1084                 return MEDIACODEC_MPEG1;
1085         case MPEG2:
1086                 return MEDIACODEC_MPEG2;
1087         case MPEG4:
1088                 return MEDIACODEC_MPEG4;
1089         case HEVC:
1090                 return MEDIACODEC_HEVC;
1091         case VP8:
1092                 return MEDIACODEC_VP8;
1093         case VP9:
1094                 return MEDIACODEC_VP9;
1095         case VC1:
1096                 return MEDIACODEC_VC1;
1097         case OPUS:
1098                 return MEDIACODEC_OPUS;
1099         default:
1100                 return NONE;
1101         }
1102 }
1103
1104 gboolean _check_support_audio_info(mediacodec_codec_type_e codec_id, int samplerate, int channel, int bit_depth)
1105 {
1106         gint i = 0;
1107         gint maxchannels = 2;
1108         gint n_rates = 0;
1109         gint s_bit_depth = 32;
1110
1111         switch (codec_id) {
1112         case MEDIACODEC_AMR_NB:
1113         {
1114                 const static gint l_rates[] = { 8000 };
1115                 maxchannels = 1;
1116                 n_rates = G_N_ELEMENTS(l_rates);
1117                 s_bit_depth = 16;       /* NOTE: amrnbenc/amrnbdec surpports S16LE as format*/
1118
1119                 while (i < n_rates) {
1120                         if (l_rates[i] == samplerate)
1121                                 break;
1122                         i++;
1123                 }
1124
1125                 if (i == n_rates) {
1126                         LOGE("Invalid samplerate set");
1127                         return false;
1128                 }
1129                 break;
1130         }
1131         case MEDIACODEC_AAC_LC:
1132         case MEDIACODEC_AAC_HE:
1133         {
1134                 const static gint l_rates[] = { 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350 };
1135                 maxchannels = 6;
1136                 n_rates = G_N_ELEMENTS(l_rates);
1137                 s_bit_depth = 32;       /* NOTE: avdec_aac/avenc_aac surpports S32LE as format*/
1138
1139                 while (i < n_rates) {
1140                         if (l_rates[i] == samplerate)
1141                                 break;
1142                         i++;
1143                 }
1144
1145                 if (i == n_rates) {
1146                         LOGE("Invalid samplerate set");
1147                         return false;
1148                 }
1149                 break;
1150         }
1151         case MEDIACODEC_MP3:
1152         {
1153                 s_bit_depth = 16;       /* NOTE: amrenc/amrnbdec surpports S16LE as format*/
1154                 break;
1155         }
1156         case MEDIACODEC_VORBIS:
1157         {
1158                 s_bit_depth = 32;       /* NOTE:  vorbisenc/vorbisdec surpports S32LE as format */
1159                 break;
1160         }
1161         case MEDIACODEC_FLAC:
1162         {
1163                 s_bit_depth = 32;       /* NOTE: avdec_flac surpports S32LE as format */
1164                 break;
1165         }
1166         case MEDIACODEC_OPUS:
1167         {
1168                 s_bit_depth = 16;       /* NOTE: opusenc/ opusdec support S16LE as format according to opus specification*/
1169                 break;
1170         }
1171         default:
1172                 break;
1173         }
1174
1175         if (channel < 0 || channel > maxchannels) {
1176                 LOGE("Invalid channel set");
1177                 return false;
1178         }
1179
1180         if (bit_depth != s_bit_depth) {
1181                 LOGE("Invalid bit set");
1182                 return false;
1183         }
1184
1185         return true;
1186 }
1187
1188 gboolean _check_support_video_info(mediacodec_codec_type_e codec_id, int width, int height)
1189 {
1190         gint i = 0;
1191         gint n_sizes = 0;
1192
1193         if (width <= 0 || height <= 0) {
1194                 LOGE("Invalid resolution set");
1195                 return false;
1196         }
1197
1198         switch (codec_id) {
1199         case MEDIACODEC_H261:
1200         {
1201                 const static gint widths[] = { 352, 176 };
1202                 const static gint heights[] = { 288, 144 };
1203                 n_sizes = G_N_ELEMENTS(widths);
1204
1205                 while (i < n_sizes) {
1206                         if ((widths[i] == width) && (heights[i] == height))
1207                                 break;
1208                         i++;
1209                 }
1210
1211                 if (i == n_sizes) {
1212                         LOGE("Invalid resolution set");
1213                         return false;
1214                 }
1215                 break;
1216         }
1217         case MEDIACODEC_H263:
1218         {
1219                 const static gint widths[] = { 352, 704, 176, 1408, 128 };
1220                 const static gint heights[] = { 288, 576, 144, 1152, 96 };
1221                 n_sizes = G_N_ELEMENTS(widths);
1222
1223                 while (i < n_sizes) {
1224                         if ((widths[i] == width) && (heights[i] == height))
1225                                 break;
1226                         i++;
1227                 }
1228
1229                 if (i == n_sizes) {
1230                         LOGE("Invalid resolution set");
1231                         return false;
1232                 }
1233                 break;
1234         }
1235         default:
1236                 break;
1237         }
1238
1239         return true;
1240 }