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