Sync with tizen_2.4
[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
28 #include <media_codec_spec_emul.h>
29
30 static int sort(gpointer p1, gpointer p2)
31 {
32     int a, b;
33
34     a = GPOINTER_TO_INT(p1);
35     b = GPOINTER_TO_INT(p2);
36
37     return (a > b ? 1 : a == b ? 0 : 1);
38 }
39
40 int mc_create(MMHandleType *mediacodec)
41 {
42     mc_handle_t* new_mediacodec = NULL;
43     int ret = MC_ERROR_NONE;
44     int i;
45     int support_list = sizeof(spec_emul) / sizeof(spec_emul[0]);
46     GList *list = NULL;
47
48     /* alloc mediacodec structure */
49     new_mediacodec = (mc_handle_t*)g_malloc(sizeof(mc_handle_t));
50     if ( ! new_mediacodec )
51     {
52         LOGE("Cannot allocate memory for player\n");
53         ret = MC_ERROR;
54         goto ERROR;
55     }
56     memset(new_mediacodec, 0, sizeof(mc_handle_t));
57
58     new_mediacodec->is_encoder = false;
59     new_mediacodec->is_video = false;
60     new_mediacodec->is_hw = true;
61     new_mediacodec->is_prepared = false;
62     new_mediacodec->codec_id = MEDIACODEC_NONE;
63
64     new_mediacodec->ports[0] = NULL;
65     new_mediacodec->ports[1] = NULL;
66
67     new_mediacodec->core = NULL;
68
69     for(i=0; i<support_list; i++)
70     {
71         new_mediacodec->supported_codecs = g_list_append(new_mediacodec->supported_codecs, GINT_TO_POINTER(spec_emul[i].codec_id));
72     }
73     new_mediacodec->supported_codecs = g_list_sort(new_mediacodec->supported_codecs, sort);
74
75     gpointer p1;
76     for(i=0; i<support_list; i++)
77     {
78         p1 = g_list_nth_data(list, i);
79         LOGD("list_sort :%d(%x)",i, GPOINTER_TO_INT(p1));
80     }
81
82
83     g_mutex_init(&new_mediacodec->cmd_lock);
84
85     *mediacodec = (MMHandleType)new_mediacodec;
86
87     return ret;
88
89 ERROR:
90     if ( new_mediacodec )
91     {
92         free(new_mediacodec);
93         new_mediacodec = NULL;
94     }
95
96     return MC_INVALID_ARG;
97 }
98
99 int mc_destroy(MMHandleType mediacodec)
100 {
101     int ret = MC_ERROR_NONE;
102     mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
103
104     if (!mc_handle)
105     {
106         LOGE("fail invaild param\n");
107         return MC_INVALID_ARG;
108     }
109
110     MEDIACODEC_CMD_LOCK( mediacodec );
111
112     LOGD("mediacodec : %p", mediacodec);
113
114     if(mc_handle->core != NULL)
115     {
116         if(mc_gst_unprepare(mc_handle) != MC_ERROR_NONE)
117         {
118             LOGE("mc_gst_unprepare() failed");
119             return MC_ERROR;
120         }
121     }
122
123     mc_handle->is_prepared = false;
124     g_list_free(mc_handle->supported_codecs);
125
126     MEDIACODEC_CMD_UNLOCK( mediacodec );
127
128     /* free mediacodec structure */
129     if(mc_handle) {
130         g_free( (void*)mc_handle );
131         mc_handle = NULL;
132     }
133     return ret;
134 }
135
136 int mc_set_codec(MMHandleType mediacodec, mediacodec_codec_type_e codec_id, mediacodec_support_type_e flags)
137 {
138     int ret = MC_ERROR_NONE;
139     mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
140     static const int support_list = sizeof(spec_emul) / sizeof(spec_emul[0]);
141     int i;
142
143     if (!mc_handle)
144     {
145         LOGE("fail invaild param\n");
146         return MC_INVALID_ARG;
147     }
148
149     /* Mandatory setting */
150     if ( !GET_IS_ENCODER(flags) && !GET_IS_DECODER(flags) )
151     {
152         LOGE("should be encoder or decoder\n");
153         return MC_PARAM_ERROR;
154     }
155
156     for(i = 0; i < support_list; i++)
157     {
158         if((codec_id == spec_emul[i].codec_id) && (flags == spec_emul[i].codec_type))
159         {
160             break;
161         }
162     }
163
164     LOGD("support_list : %d, i : %d", support_list, i);
165
166     if(i == support_list)
167         return MC_NOT_SUPPORTED;
168
169     mc_handle->port_type = spec_emul[i].port_type;
170
171     mc_handle->is_encoder = GET_IS_ENCODER(flags) ? 1 : 0;
172     mc_handle->is_hw = GET_IS_HW(flags) ? 1 : 0;
173     mc_handle->codec_id = codec_id;
174     mc_handle->is_video = CHECK_BIT(codec_id, 13);
175
176     mc_handle->is_prepared = false;
177
178     LOGD("encoder : %d, hardware : %d, codec_id : %x, video : %d",
179         mc_handle->is_encoder, mc_handle->is_hw, mc_handle->codec_id, mc_handle->is_video);
180
181     return ret;
182 }
183
184 int mc_set_vdec_info(MMHandleType mediacodec, int width, int height)
185 {
186     int ret = MC_ERROR_NONE;
187     mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
188
189     if (!mc_handle)
190     {
191         LOGE("fail invaild param\n");
192         return MC_INVALID_ARG;
193     }
194
195     if ((width <= 0) || (height <= 0))
196         return MC_PARAM_ERROR;
197
198     MEDIACODEC_CHECK_CONDITION(mc_handle->codec_id && mc_handle->is_video && !mc_handle->is_encoder,
199             MEDIACODEC_ERROR_INVALID_PARAMETER,"MEDIACODEC_ERROR_INVALID_PARAMETER");
200
201     mc_handle->info.decoder.width = width;
202     mc_handle->info.decoder.height = height;
203
204     mc_handle->is_prepared = true;
205
206     switch ( mc_handle->codec_id )
207     {
208         case MEDIACODEC_H264:
209             mc_sniff_bitstream = mc_sniff_h264_bitstream;
210             LOGD("mc_sniff_h264_bitstream");
211             break;
212         case MEDIACODEC_MPEG4:
213             mc_sniff_bitstream = mc_sniff_mpeg4_bitstream;
214             break;
215         case MEDIACODEC_H263:
216             mc_sniff_bitstream = mc_sniff_h263_bitstream;
217             break;
218         default:
219             LOGE("NOT SUPPORTED!!!!");
220             break;
221     }
222
223     return ret;
224 }
225
226 int mc_set_venc_info(MMHandleType mediacodec, int width, int height, int fps, int target_bits)
227 {
228     int ret = MC_ERROR_NONE;
229     mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
230
231     if (!mc_handle)
232     {
233         LOGE("fail invaild param\n");
234         return MC_INVALID_ARG;
235     }
236
237     if ((width <= 0) || (height <= 0))
238         return MC_PARAM_ERROR;
239
240     MEDIACODEC_CHECK_CONDITION(mc_handle->codec_id && mc_handle->is_video && mc_handle->is_encoder,
241                         MEDIACODEC_ERROR_INVALID_PARAMETER, "MEDIACODEC_ERROR_INVALID_PARAMETER");
242
243     mc_handle->info.encoder.width = width;
244     mc_handle->info.encoder.height = height;
245     mc_handle->info.encoder.fps = fps;
246     mc_handle->info.encoder.bitrate = target_bits;
247
248     mc_handle->is_prepared = true;
249
250     mc_sniff_bitstream = mc_sniff_yuv;
251     return ret;
252 }
253
254 int mc_set_adec_info(MMHandleType mediacodec, int samplerate, int channel, int bit)
255 {
256     int ret = MC_ERROR_NONE;
257     mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
258
259     if (!mc_handle)
260     {
261         LOGE("fail invaild param\n");
262         return MC_INVALID_ARG;
263     }
264
265     if ((samplerate <= 0) || (channel <= 0) || (bit <= 0))
266         return MC_PARAM_ERROR;
267
268     MEDIACODEC_CHECK_CONDITION(mc_handle->codec_id && !mc_handle->is_video && !mc_handle->is_encoder,
269             MEDIACODEC_ERROR_INVALID_PARAMETER, "MEDIACODEC_ERROR_INVALID_PARAMETER");
270
271     mc_handle->info.decoder.samplerate = samplerate;
272     mc_handle->info.decoder.channel = channel;
273     mc_handle->info.decoder.bit = bit;
274
275     mc_handle->is_prepared = true;
276
277     return ret;
278 }
279
280 int mc_set_aenc_info(MMHandleType mediacodec, int samplerate, int channel, int bit,  int bitrate)
281 {
282     int ret = MC_ERROR_NONE;
283     mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
284
285     if (!mc_handle)
286     {
287         LOGE("fail invaild param\n");
288         return MC_INVALID_ARG;
289     }
290
291     if ((samplerate <= 0) || (channel <= 0) || (bit <= 0))
292         return MC_PARAM_ERROR;
293
294     MEDIACODEC_CHECK_CONDITION(mc_handle->codec_id && !mc_handle->is_video && mc_handle->is_encoder,
295                         MEDIACODEC_ERROR_INVALID_PARAMETER, "MEDIACODEC_ERROR_INVALID_PARAMETER");
296
297     mc_handle->info.encoder.samplerate = samplerate;
298     mc_handle->info.encoder.channel = channel;
299     mc_handle->info.encoder.bit = bit;
300     mc_handle->info.encoder.bitrate = bitrate;
301
302     mc_handle->is_prepared = true;
303
304     return ret;
305 }
306
307 int mc_prepare(MMHandleType mediacodec)
308 {
309     int ret = MC_ERROR_NONE;
310     mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
311
312     if (!mc_handle)
313     {
314         LOGE("fail invaild param\n");
315         return MC_INVALID_ARG;
316     }
317
318     if(!mc_handle->is_prepared)
319         return MC_NOT_INITIALIZED;
320
321     MEDIACODEC_CMD_LOCK( mediacodec );
322
323     /* setting core details */
324     switch ( mc_handle->port_type )
325     {
326         case MEDIACODEC_PORT_TYPE_GENERAL:
327         {
328         }
329         break;
330
331         case MEDIACODEC_PORT_TYPE_OMX:
332         {
333         }
334         break;
335
336         case MEDIACODEC_PORT_TYPE_GST:
337         {
338             mc_gst_prepare(mc_handle);
339         }
340         break;
341
342         default:
343         break;
344     }
345
346     MEDIACODEC_CMD_UNLOCK( mediacodec );
347
348     return ret;
349 }
350
351 int mc_unprepare(MMHandleType mediacodec)
352 {
353     int ret = MC_ERROR_NONE;
354     mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
355
356     if (!mc_handle)
357     {
358         LOGE("fail invaild param\n");
359         return MC_INVALID_ARG;
360     }
361
362     MEDIACODEC_CMD_LOCK( mediacodec );
363
364     /* deinit core details */
365     switch ( mc_handle->port_type )
366     {
367         case MEDIACODEC_PORT_TYPE_GENERAL:
368         {
369         }
370         break;
371
372         case MEDIACODEC_PORT_TYPE_OMX:
373         {
374         }
375         break;
376
377         case MEDIACODEC_PORT_TYPE_GST:
378         {
379             ret = mc_gst_unprepare(mc_handle);
380         }
381         break;
382
383         default:
384             break;
385     }
386
387     MEDIACODEC_CMD_UNLOCK( mediacodec );
388
389     return ret;
390 }
391
392 int mc_process_input(MMHandleType mediacodec, media_packet_h inbuf, uint64_t timeOutUs )
393 {
394     int ret = MC_ERROR_NONE;
395     uint64_t buf_size = 0;
396     void *buf_data = NULL;
397     bool eos = false;
398
399     mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
400
401
402     if (!mc_handle) {
403         LOGE("fail invaild param\n");
404         return MC_INVALID_ARG;
405     }
406 #if 1
407     if ( mc_handle->is_video) {
408         if ((ret = mc_sniff_bitstream(mc_handle, inbuf)) != MC_ERROR_NONE ) {
409             return MC_INVALID_IN_BUF;
410         }
411     }
412 #else
413     ret = media_packet_get_buffer_size(inbuf, &buf_size);
414     if (ret != MEDIA_PACKET_ERROR_NONE)
415     {
416         LOGE("invaild input buffer");
417         return MC_INVALID_IN_BUF;
418     }
419
420     ret = media_packet_get_buffer_data_ptr(inbuf, &buf_data);
421     if (ret != MEDIA_PACKET_ERROR_NONE)
422     {
423         LOGE("invaild input buffer");
424         return MC_INVALID_IN_BUF;
425     }
426
427     ret = media_packet_is_end_of_stream(inbuf, &eos);
428     if (ret != MEDIA_PACKET_ERROR_NONE)
429     {
430         LOGE("invaild input buffer");
431         return MC_INVALID_IN_BUF;
432     }
433
434     if(!eos)
435     {
436         if((buf_data == NULL) || (buf_size == 0))
437         {
438             LOGE("invaild input buffer");
439             return MC_INVALID_IN_BUF;
440         }
441     }
442 #endif
443     MEDIACODEC_CMD_LOCK( mediacodec );
444
445     switch ( mc_handle->port_type )
446     {
447         case MEDIACODEC_PORT_TYPE_GENERAL:
448         break;
449
450         case MEDIACODEC_PORT_TYPE_OMX:
451         break;
452
453         case MEDIACODEC_PORT_TYPE_GST:
454         {
455             ret = mc_gst_process_input(mc_handle, inbuf, timeOutUs);
456         }
457         break;
458
459         default:
460             break;
461     }
462
463     MEDIACODEC_CMD_UNLOCK( mediacodec );
464
465     return ret;
466 }
467
468 int mc_get_output(MMHandleType mediacodec, media_packet_h *outbuf, uint64_t timeOutUs)
469 {
470     int ret = MC_ERROR_NONE;
471     mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
472
473     if (!mc_handle)
474     {
475         LOGE("fail invaild param\n");
476         return MC_INVALID_ARG;
477     }
478
479     MEDIACODEC_CMD_LOCK( mediacodec );
480
481     /* setting core details */
482     switch ( mc_handle->port_type )
483     {
484         case MEDIACODEC_PORT_TYPE_GENERAL:
485         break;
486
487         case MEDIACODEC_PORT_TYPE_OMX:
488         break;
489
490         case MEDIACODEC_PORT_TYPE_GST:
491         {
492             ret = mc_gst_get_output(mc_handle, outbuf, timeOutUs);
493         }
494         break;
495
496         default:
497             break;
498     }
499
500     MEDIACODEC_CMD_UNLOCK( mediacodec );
501
502     return ret;
503 }
504
505 int mc_flush_buffers(MMHandleType mediacodec)
506 {
507     int ret = MC_ERROR_NONE;
508     mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
509
510     if (!mc_handle)
511     {
512         LOGE("fail invaild param\n");
513         return MC_INVALID_ARG;
514     }
515
516     MEDIACODEC_CMD_LOCK( mediacodec );
517
518     /* setting core details */
519     switch ( mc_handle->port_type )
520     {
521         case MEDIACODEC_PORT_TYPE_GENERAL:
522         break;
523
524         case MEDIACODEC_PORT_TYPE_OMX:
525         break;
526
527         case MEDIACODEC_PORT_TYPE_GST:
528         {
529             ret = mc_gst_flush_buffers(mc_handle);
530         }
531         break;
532
533         default:
534             break;
535     }
536
537     MEDIACODEC_CMD_UNLOCK( mediacodec );
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     static const mc_codec_map_t *codec_map;
546     int i;
547
548     *support_type = 0;
549
550     if (!mc_handle)
551     {
552         LOGE("fail invaild param\n");
553         return MC_INVALID_ARG;
554     }
555
556     const int codec_list = encoder ? (sizeof(encoder_map) / sizeof(encoder_map[0])) : (sizeof(decoder_map) / sizeof(decoder_map[0]));
557
558     codec_map = encoder ? encoder_map : decoder_map;
559
560
561     for(i = 0; i < codec_list; i++)
562     {
563         if(codec_type == codec_map[i].id)
564         {
565             if(codec_map[i].hardware)
566                 *support_type |=MEDIACODEC_SUPPORT_TYPE_HW;
567             else
568                 *support_type |=MEDIACODEC_SUPPORT_TYPE_SW;
569         }
570
571     }
572
573     return ret;
574 }
575
576 int mc_set_empty_buffer_cb(MMHandleType mediacodec, mediacodec_input_buffer_used_cb callback, void* user_data)
577 {
578     int ret = MC_ERROR_NONE;
579     mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
580
581     if (!mc_handle)
582     {
583         LOGE("fail invaild param\n");
584         return MC_INVALID_ARG;
585     }
586
587     if(mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER])
588     {
589         LOGE("Already set mediacodec_empty_buffer_cb\n");
590         return MC_PARAM_ERROR;
591     }
592     else
593     {
594         if (!callback)
595         {
596             return MC_INVALID_ARG;
597         }
598
599         LOGD("Set empty buffer callback(cb = %p, data = %p)\n", callback, user_data);
600
601         mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER] = (mc_empty_buffer_cb) callback;
602         mc_handle->user_data[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER] = user_data;
603         return MC_ERROR_NONE;
604     }
605
606     return ret;
607 }
608
609 int mc_unset_empty_buffer_cb(MMHandleType mediacodec)
610 {
611     mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
612
613     if (!mc_handle)
614     {
615         LOGE("fail invaild param\n");
616         return MC_INVALID_ARG;
617     }
618
619     mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER] = NULL;
620     mc_handle->user_data[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER] = NULL;
621
622     return MC_ERROR_NONE;
623 }
624
625 int mc_set_fill_buffer_cb(MMHandleType mediacodec, mediacodec_output_buffer_available_cb callback, void* user_data)
626 {
627     int ret = MC_ERROR_NONE;
628     mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
629
630     if (!mc_handle)
631     {
632         LOGE("fail invaild param\n");
633         return MC_INVALID_ARG;
634     }
635
636     if(mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_FILLBUFFER])
637     {
638         LOGE("Already set mediacodec_fill_buffer_cb\n");
639         return MC_PARAM_ERROR;
640     }
641     else
642     {
643         if (!callback) {
644             return MC_INVALID_ARG;
645         }
646
647         LOGD("Set fill buffer callback(cb = %p, data = %p)\n", callback, user_data);
648
649         mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_FILLBUFFER] = (mc_fill_buffer_cb) callback;
650         mc_handle->user_data[_MEDIACODEC_EVENT_TYPE_FILLBUFFER] = user_data;
651         return MC_ERROR_NONE;
652     }
653
654     return ret;
655 }
656
657 int mc_unset_fill_buffer_cb(MMHandleType mediacodec)
658 {
659     mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
660
661     if (!mc_handle)
662     {
663         LOGE("fail invaild param\n");
664         return MC_INVALID_ARG;
665     }
666
667     mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_FILLBUFFER] = NULL;
668     mc_handle->user_data[_MEDIACODEC_EVENT_TYPE_FILLBUFFER] = NULL;
669
670     return MC_ERROR_NONE;
671 }
672
673 int mc_set_error_cb(MMHandleType mediacodec, mediacodec_error_cb callback, void* user_data)
674 {
675     int ret = MC_ERROR_NONE;
676     mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
677
678     if (!mc_handle)
679     {
680         LOGE("fail invaild param\n");
681         return MC_INVALID_ARG;
682     }
683
684     if(mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_ERROR])
685     {
686         LOGE("Already set mediacodec_fill_buffer_cb\n");
687         return MC_PARAM_ERROR;
688     }
689     else
690     {
691         if (!callback) {
692             return MC_INVALID_ARG;
693         }
694
695         LOGD("Set event handler callback(cb = %p, data = %p)\n", callback, user_data);
696
697         mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_ERROR] = (mc_error_cb) callback;
698         mc_handle->user_data[_MEDIACODEC_EVENT_TYPE_ERROR] = user_data;
699         return MC_ERROR_NONE;
700     }
701
702     return ret;
703 }
704
705 int mc_unset_error_cb(MMHandleType mediacodec)
706 {
707     mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
708
709     if (!mc_handle)
710     {
711         LOGE("fail invaild param\n");
712         return MC_INVALID_ARG;
713     }
714
715     mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_ERROR] = NULL;
716     mc_handle->user_data[_MEDIACODEC_EVENT_TYPE_ERROR] = NULL;
717
718     return MC_ERROR_NONE;
719 }
720
721 int mc_set_eos_cb(MMHandleType mediacodec, mediacodec_eos_cb callback, void* user_data)
722 {
723     int ret = MC_ERROR_NONE;
724     mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
725
726     if (!mc_handle)
727     {
728         LOGE("fail invaild param\n");
729         return MC_INVALID_ARG;
730     }
731
732     if(mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_EOS])
733     {
734         LOGE("Already set mediacodec_fill_buffer_cb\n");
735         return MC_PARAM_ERROR;
736     }
737     else
738     {
739         if (!callback) {
740             return MC_INVALID_ARG;
741         }
742
743         LOGD("Set event handler callback(cb = %p, data = %p)\n", callback, user_data);
744
745         mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_EOS] = (mc_eos_cb) callback;
746         mc_handle->user_data[_MEDIACODEC_EVENT_TYPE_EOS] = user_data;
747         return MC_ERROR_NONE;
748     }
749
750     return ret;
751 }
752
753 int mc_unset_eos_cb(MMHandleType mediacodec)
754 {
755     mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
756
757     if (!mc_handle)
758     {
759         LOGE("fail invaild param\n");
760         return MC_INVALID_ARG;
761     }
762
763     mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_EOS] = NULL;
764     mc_handle->user_data[_MEDIACODEC_EVENT_TYPE_EOS] = NULL;
765
766     return MC_ERROR_NONE;
767 }
768
769 int mc_set_buffer_status_cb(MMHandleType mediacodec, mediacodec_buffer_status_cb callback, void* user_data)
770 {
771     int ret = MC_ERROR_NONE;
772     mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
773
774     if (!mc_handle)
775     {
776         LOGE("fail invaild param\n");
777         return MC_INVALID_ARG;
778     }
779
780     if(mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS])
781     {
782         LOGE("Already set mediacodec_need_data_cb\n");
783         return MC_PARAM_ERROR;
784     }
785     else
786     {
787         if (!callback) {
788             return MC_INVALID_ARG;
789         }
790
791         LOGD("Set start feed callback(cb = %p, data = %p)\n", callback, user_data);
792
793         mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS] = (mc_buffer_status_cb) callback;
794         mc_handle->user_data[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS] = user_data;
795         return MC_ERROR_NONE;
796     }
797
798     return ret;
799 }
800
801 int mc_unset_buffer_status_cb(MMHandleType mediacodec)
802 {
803     mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
804
805     if (!mc_handle)
806     {
807         LOGE("fail invaild param\n");
808         return MC_INVALID_ARG;
809     }
810
811     mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS] = NULL;
812     mc_handle->user_data[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS] = NULL;
813
814     return MC_ERROR_NONE;
815 }
816
817 int mc_set_supported_codec_cb(MMHandleType mediacodec, mediacodec_supported_codec_cb callback, void* user_data)
818 {
819     int ret = MC_ERROR_NONE;
820     mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
821
822     if (!mc_handle)
823     {
824         LOGE("fail invaild param\n");
825         return MC_INVALID_ARG;
826     }
827
828     if(mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_SUPPORTED_CODEC])
829     {
830         LOGE("Already set mediacodec_supported_codec_cb\n");
831         return MC_PARAM_ERROR;
832     }
833     else
834     {
835         if (!callback) {
836             return MC_INVALID_ARG;
837         }
838
839         LOGD("Set event handler callback(cb = %p, data = %p)\n", callback, user_data);
840
841         mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_SUPPORTED_CODEC] = (mc_supported_codec_cb) callback;
842         mc_handle->user_data[_MEDIACODEC_EVENT_TYPE_SUPPORTED_CODEC] = user_data;
843         return MC_ERROR_NONE;
844     }
845
846     return MC_ERROR_NONE;
847 }
848
849 int _mediacodec_foreach_supported_codec(MMHandleType mediacodec, mediacodec_supported_codec_cb callback, void* user_data)
850 {
851     int ret = MC_ERROR_NONE;
852     mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
853     int codecs_num;
854     gpointer tmp;
855
856     if (!mc_handle)
857     {
858         LOGE("fail invaild param\n");
859         return MC_INVALID_ARG;
860     }
861
862     if(mc_handle->supported_codecs)
863     {
864         codecs_num = g_list_length(mc_handle->supported_codecs);
865         LOGD("supported_codecs : %d", codecs_num);
866
867         while(codecs_num)
868         {
869             tmp = g_list_nth_data(mc_handle->supported_codecs, codecs_num -1);
870             if(tmp)
871             {
872                 if(!callback(GPOINTER_TO_INT(tmp), user_data))
873                 {
874                     ret = MEDIACODEC_ERROR_INTERNAL;
875                     goto CALLBACK_ERROR;
876                 }
877             }
878             codecs_num--;
879         }
880
881         if(!callback(-1, user_data))
882         {
883             ret = MEDIACODEC_ERROR_INTERNAL;
884             goto CALLBACK_ERROR;
885         }
886     }
887
888 CALLBACK_ERROR:
889     LOGD("foreach callback returned error");
890     return ret;
891 }
892
893 int mc_sniff_h264_bitstream(mc_handle_t *handle, media_packet_h pkt)
894 {
895     int ret = MC_ERROR_NONE;
896     void *buf_data = NULL;
897     void *codec_data = NULL;
898     int codec_data_size = 0;
899     uint64_t buf_size = 0;
900     bool eos = false;
901     bool codec_config = false;
902
903     media_packet_get_buffer_size(pkt, &buf_size);
904     media_packet_get_buffer_data_ptr(pkt, &buf_data);
905     media_packet_get_codec_data(pkt, &codec_data, &codec_data_size);
906     media_packet_is_end_of_stream(pkt, &eos);
907     media_packet_is_codec_config(pkt, &codec_config);
908
909     LOGD("codec_data_size : %d, buf_size : %d, codec_config : %d, eos : %d",
910         codec_data_size, (int)buf_size, codec_config, eos);
911
912     if ( codec_config ) {
913         if ( codec_data_size == 0 )
914           ret = _mc_check_bytestream (pkt, buf_data, (int)buf_size, NULL, NULL);
915     }
916
917     return ret;
918 }
919
920 int mc_sniff_mpeg4_bitstream(mc_handle_t *handle, media_packet_h pkt)
921 {
922     int ret = MC_ERROR_NONE;
923     return ret;
924 }
925
926 int mc_sniff_h263_bitstream(mc_handle_t *handle, media_packet_h pkt)
927 {
928     int ret = MC_ERROR_NONE;
929     return ret;
930 }
931
932 int mc_sniff_yuv(mc_handle_t *handle, media_packet_h pkt)
933 {
934     int ret = MC_ERROR_NONE;
935
936 #if 0 /* libtbm, media-tool should be updated */
937     uint64_t buf_size = 0;
938     int plane_num = 0;
939     int padded_width = 0;
940     int padded_height = 0;
941     int allocated_buffer = 0;
942     int index;
943
944     media_packet_get_buffer_size(pkt, &buf_size);
945     media_packet_get_video_number_of_planes(pkt, &plane_num);
946
947     for ( index = 0; index < plane_num; index++) {
948         media_packet_get_video_stride_width(pkt, index, &padded_width);
949         media_packet_get_video_stride_height(pkt, index, &padded_height);
950         allocated_buffer += padded_width * padded_height;
951
952         LOGD("%d plane size : %d", padded_width * padded_height);
953     }
954
955     if ( buf_size > allocated_buffer ) {
956         LOGE("Buffer exceeds maximum size [buf_size: %d, allocated_size :%d", (int)buf_size, allocated_buffer);
957         ret = MC_INVALID_IN_BUF;
958     }
959 #endif
960     return ret;
961 }
962