4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: YoungHun Kim <yh8004.kim@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
21 #include "mm_transcode.h"
22 #include "mm_transcode_internal.h"
24 static int _mm_decode_audio_output_create(handle_s *handle);
25 static int _mm_decode_audio_output_link(handle_s *handle);
26 static int _mm_decode_video_output_create(handle_s *handle);
27 static int _mm_decode_video_output_link(handle_s *handle);
28 static int _mm_decodebin_pipeline_create(handle_s *handle);
29 static int _mm_encodebin_set_audio_property(handle_s *handle);
30 static int _mm_encodebin_set_property(handle_s *handle);
31 static int _mm_encodebin_set_video_property(handle_s *handle);
32 static int _mm_filesrc_pipeline_create(handle_s *handle);
33 static int _mm_filesrc_decodebin_link(handle_s *handle);
35 const gchar *_mm_check_media_type(GstCaps *caps)
37 /* check media type */
38 GstStructure *_str = gst_caps_get_structure(caps, 0);
39 const gchar *mime = gst_structure_get_name(_str);
44 int _mm_cleanup_encodebin(handle_s *handle)
46 int ret = MM_ERROR_NONE;
49 LOGE("[ERROR] - handle");
50 return MM_ERROR_INVALID_ARGUMENT;
53 if (!handle->encodebin) {
54 LOGE("[ERROR] - handle encodebin");
55 return MM_ERROR_TRANSCODE_INTERNAL;
58 if (!handle->property) {
59 LOGE("[ERROR] - handle property");
60 return MM_ERROR_TRANSCODE_INTERNAL;
63 if (handle->encodebin->encvideopad) {
64 gst_object_unref(GST_OBJECT(handle->encodebin->encvideopad));
65 handle->encodebin->encvideopad = NULL;
66 LOGD("Success - gst_object_unref (encvideopad)");
69 if (handle->encodebin->encaudiopad) {
70 gst_object_unref(GST_OBJECT(handle->encodebin->encaudiopad));
71 handle->encodebin->encaudiopad = NULL;
72 LOGD("Success - gst_object_unref (encaudiopad)");
75 if (handle->property->caps) {
76 gst_caps_unref(handle->property->caps);
77 handle->property->caps = NULL;
78 LOGD("gst_caps_unref");
84 int _mm_cleanup_signal(handle_s *handle)
86 int ret = MM_ERROR_NONE;
89 LOGE("[ERROR] - handle");
90 return MM_ERROR_INVALID_ARGUMENT;
93 if (!handle->property) {
94 LOGE("[ERROR] - handle property");
95 return MM_ERROR_TRANSCODE_INTERNAL;
98 if (handle->property->progress_cb) {
99 handle->property->progress_cb = NULL;
100 handle->property->progress_cb_param = NULL;
103 if (handle->property->completed_cb) {
104 handle->property->completed_cb = NULL;
105 handle->property->completed_cb_param = NULL;
108 if (handle->property->audio_cb_probe_id) {
109 g_source_remove(handle->property->audio_cb_probe_id);
110 handle->property->audio_cb_probe_id = 0;
111 LOGD("g_source_remove (audio_cb_probe_id)");
114 if (handle->property->video_cb_probe_id) {
115 g_source_remove(handle->property->video_cb_probe_id);
116 handle->property->video_cb_probe_id = 0;
117 LOGD("g_source_remove (video_cb_probe_id)");
120 if (handle->property->progress_event_id) {
121 g_source_remove(handle->property->progress_event_id);
122 handle->property->progress_event_id = 0;
123 LOGD("g_source_remove (progress_event_id)");
126 if (handle->encodebin->audio_event_probe_id) {
127 g_source_remove(handle->encodebin->audio_event_probe_id);
128 handle->encodebin->audio_event_probe_id = 0;
129 LOGD("g_source_remove (audio_event_probe_id)");
132 if (handle->encodebin->video_event_probe_id) {
133 g_source_remove(handle->encodebin->video_event_probe_id);
134 handle->encodebin->video_event_probe_id = 0;
135 LOGD("g_source_remove (video_event_probe_id)");
142 int _mm_cleanup_pipeline(handle_s *handle)
144 int ret = MM_ERROR_NONE;
147 LOGE("[ERROR] - handle");
148 return MM_ERROR_INVALID_ARGUMENT;
151 if (!handle->property) {
152 LOGE("[ERROR] - handle property");
153 return MM_ERROR_TRANSCODE_INTERNAL;
156 handle->property->_MMHandle = 0;
158 /* g_thread_exit(handle->thread); */
159 LOGD("g_thread_exit");
160 if (handle->property->thread) {
161 g_thread_join(handle->property->thread);
162 LOGD("Success - join (thread)");
165 /* disconnecting bus watch */
166 if (handle->property->bus_watcher) {
167 g_source_remove(handle->property->bus_watcher);
168 LOGD("g_source_remove");
169 handle->property->bus_watcher = 0;
172 if (handle->property->queue) {
173 g_async_queue_unref(handle->property->queue);
174 handle->property->queue = NULL;
175 LOGD("Success - g_async_queue_unref(queue)");
178 if (handle->property->thread_mutex) {
179 g_mutex_clear(handle->property->thread_mutex);
180 g_free(handle->property->thread_mutex);
181 handle->property->thread_mutex = NULL;
182 LOGD("Success - free (thread_mutex)");
185 if (handle->property->thread_cond) {
186 g_cond_clear(handle->property->thread_cond);
187 g_free(handle->property->thread_cond);
188 handle->property->thread_cond = NULL;
189 LOGD("Success - free (thread_cond)");
192 if (handle->property->thread_exit_mutex) {
193 g_mutex_clear(handle->property->thread_exit_mutex);
194 g_free(handle->property->thread_exit_mutex);
195 handle->property->thread_exit_mutex = NULL;
196 LOGD("Success - free (thread_exit_mutex)");
199 /* release videopad */
200 if (handle->decoder_vidp) {
201 if (handle->decoder_vidp->decvideosinkpad) {
202 gst_object_unref(GST_OBJECT(handle->decoder_vidp->decvideosinkpad));
203 handle->decoder_vidp->decvideosinkpad = NULL;
204 LOGD("Success - gt_object_unref (decvideosinkpad)");
207 if (handle->decoder_vidp->decvideosrcpad) {
208 gst_object_unref(GST_OBJECT(handle->decoder_vidp->decvideosrcpad));
209 handle->decoder_vidp->decvideosrcpad = NULL;
210 LOGD("Success - gst_object_unref (decvideosrcpad)");
213 if (handle->decoder_vidp->srcdecvideopad) {
214 gst_object_unref(GST_OBJECT(handle->decoder_vidp->srcdecvideopad));
215 handle->decoder_vidp->srcdecvideopad = NULL;
216 LOGD("Success - gst_object_unref (srcdecvideopad)");
219 if (handle->decoder_vidp->sinkdecvideopad) {
220 gst_object_unref(GST_OBJECT(handle->decoder_vidp->sinkdecvideopad));
221 handle->decoder_vidp->sinkdecvideopad = NULL;
222 LOGD("Success - gst_object_unref (sinkdecvideopad)");
226 /* release audiopad */
227 if (handle->decoder_audp) {
228 if (handle->decoder_audp->decaudiosinkpad) {
229 gst_object_unref(GST_OBJECT(handle->decoder_audp->decaudiosinkpad));
230 handle->decoder_audp->decaudiosinkpad = NULL;
231 LOGD("Success - gst_object_unref (decaudiosinkpad)");
234 if (handle->decoder_audp->decaudiosrcpad) {
235 gst_object_unref(GST_OBJECT(handle->decoder_audp->decaudiosrcpad));
236 handle->decoder_audp->decaudiosrcpad = NULL;
237 LOGD("Success - gst_object_unref (decaudiosrcpad)");
240 if (handle->decoder_audp->srcdecaudiopad) {
241 gst_object_unref(GST_OBJECT(handle->decoder_audp->srcdecaudiopad));
242 handle->decoder_audp->srcdecaudiopad = NULL;
243 LOGD("Success - gst_object_unref (srcdecaudiopad)");
246 if (handle->decoder_audp->sinkdecaudiopad) {
247 gst_object_unref(GST_OBJECT(handle->decoder_audp->sinkdecaudiopad));
248 handle->decoder_audp->sinkdecaudiopad = NULL;
249 LOGD("Success - gst_object_unref (sinkdecaudiopad)");
253 if (_mm_cleanup_encodebin(handle) != MM_ERROR_NONE) {
254 LOGE("ERROR -Play Pipeline");
257 LOGD("Success -clean encodebin");
260 if (handle->property->sink_elements) {
261 g_list_free(handle->property->sink_elements);
262 handle->property->sink_elements = NULL;
263 LOGD("Success - g_list_free (sink_elements)");
266 if (handle->pipeline) {
267 gst_object_unref(handle->pipeline);
268 handle->pipeline = NULL;
269 LOGD("Success - gst_object_unref (pipeline)");
272 TRANSCODE_FREE(handle->property->mux);
273 TRANSCODE_FREE(handle->property->venc);
274 TRANSCODE_FREE(handle->property->aenc);
275 TRANSCODE_FREE(handle->decoder_vidp);
276 TRANSCODE_FREE(handle->decoder_audp);
277 TRANSCODE_FREE(handle->encodebin);
278 TRANSCODE_FREE(handle->property);
279 TRANSCODE_FREE(handle);
284 static void _mm_decode_add_sink(handle_s *handle, GstElement *sink_elements)
288 LOGE("[ERROR] - handle");
292 if (!handle->property) {
293 LOGE("[ERROR] - handle property");
298 handle->property->sink_elements = g_list_append(handle->property->sink_elements, sink_elements);
299 LOGD("g_list_append");
304 static int _mm_decode_audio_output_create(handle_s *handle)
306 int ret = MM_ERROR_NONE;
309 LOGE("[ERROR] - handle");
310 return MM_ERROR_INVALID_ARGUMENT;
313 if (!handle->decoder_audp) {
314 LOGE("[ERROR] - handle decoder audio process bin");
315 return MM_ERROR_TRANSCODE_INTERNAL;
318 if (!handle->property) {
319 LOGE("[ERROR] - handle property");
320 return MM_ERROR_TRANSCODE_INTERNAL;
323 handle->decoder_audp->decaudiobin = gst_bin_new("audiobin");
324 if (!handle->decoder_audp->decaudiobin) {
325 LOGE("decaudiobin could not be created");
326 return MM_ERROR_TRANSCODE_INTERNAL;
329 handle->decoder_audp->decsinkaudioqueue = gst_element_factory_make("queue", "decsinkaudioqueue");
330 if (!handle->decoder_audp->decsinkaudioqueue) {
331 LOGE("decsinkaudioqueue could not be created");
332 return MM_ERROR_TRANSCODE_INTERNAL;
335 _mm_decode_add_sink(handle, handle->decoder_audp->decsinkaudioqueue);
337 handle->decoder_audp->decaudiosinkpad = gst_element_get_static_pad(handle->decoder_audp->decsinkaudioqueue, "sink");
338 if (!handle->decoder_audp->decaudiosinkpad) {
339 LOGE("decaudiosinkpad could not be created");
340 return MM_ERROR_TRANSCODE_INTERNAL;
343 if (handle->property->audioencoder == MM_AUDIOENCODER_NO_USE) {
344 LOGD("[MM_AUDIOENCODER_NO_USE] fakesink create");
346 handle->decoder_audp->audiofakesink = gst_element_factory_make("fakesink", "audiofakesink");
347 if (!handle->decoder_audp->audiofakesink) {
348 LOGE("fakesink element could not be created");
349 return MM_ERROR_TRANSCODE_INTERNAL;
352 handle->decoder_audp->aconv = gst_element_factory_make("audioconvert", "aconv");
353 if (!handle->decoder_audp->aconv) {
354 LOGE("decaudiobin element could not be created");
355 return MM_ERROR_TRANSCODE_INTERNAL;
358 handle->decoder_audp->valve = gst_element_factory_make("valve", "valve");
359 if (!handle->decoder_audp->valve) {
360 LOGE("decaudiobin element could not be created");
361 return MM_ERROR_TRANSCODE_INTERNAL;
364 g_object_set(handle->decoder_audp->valve, "drop", FALSE, NULL);
366 handle->decoder_audp->resample = gst_element_factory_make("audioresample", "audioresample");
367 if (!handle->decoder_audp->resample) {
368 LOGE("decaudiobin element could not be created");
369 return MM_ERROR_TRANSCODE_INTERNAL;
372 handle->decoder_audp->audflt = gst_element_factory_make("capsfilter", "afilter");
373 if (!handle->decoder_audp->audflt) {
374 LOGE("audflt element could not be created");
375 return MM_ERROR_TRANSCODE_INTERNAL;
378 handle->decoder_audp->decaudiosrcpad = gst_element_get_static_pad(handle->decoder_audp->audflt, "src");
379 if (!handle->decoder_audp->decaudiosrcpad) {
380 LOGE("decaudiosrcpad element could not be created");
381 return MM_ERROR_TRANSCODE_INTERNAL;
388 static int _mm_decode_audio_output_link(handle_s *handle)
390 int ret = MM_ERROR_NONE;
393 LOGE("[ERROR] - handle");
394 return MM_ERROR_INVALID_ARGUMENT;
397 if (!handle->decoder_audp) {
398 LOGE("[ERROR] - handle decoder audio process bin");
399 return MM_ERROR_TRANSCODE_INTERNAL;
402 if (!handle->property) {
403 LOGE("[ERROR] - handle property");
404 return MM_ERROR_TRANSCODE_INTERNAL;
407 if (handle->property->audioencoder == MM_AUDIOENCODER_NO_USE) {
408 LOGD("[MM_AUDIOENCODER_NO_USE] fakesink pad create");
410 gst_bin_add_many(GST_BIN(handle->decoder_audp->decaudiobin), handle->decoder_audp->decsinkaudioqueue, handle->decoder_audp->audiofakesink, NULL);
411 if (!gst_element_link_many(handle->decoder_audp->decsinkaudioqueue, handle->decoder_audp->audiofakesink, NULL)) {
412 LOGE("[Audio Output Bin] gst_element_link_many failed");
413 return MM_ERROR_TRANSCODE_INTERNAL;
416 gst_element_add_pad(handle->decoder_audp->decaudiobin, gst_ghost_pad_new("decbin_audiosink", handle->decoder_audp->decaudiosinkpad));
417 /* get sink audiopad of decodebin */
418 handle->decoder_audp->sinkdecaudiopad = gst_element_get_static_pad(handle->decoder_audp->decaudiobin, "decbin_audiosink");
420 gst_bin_add_many(GST_BIN(handle->decoder_audp->decaudiobin), handle->decoder_audp->decsinkaudioqueue, handle->decoder_audp->valve, handle->decoder_audp->aconv, handle->decoder_audp->resample, handle->decoder_audp->audflt, NULL);
421 if (!gst_element_link_many(handle->decoder_audp->decsinkaudioqueue, handle->decoder_audp->valve, handle->decoder_audp->aconv, handle->decoder_audp->resample, handle->decoder_audp->audflt, NULL)) {
422 LOGE("[Audio Output Bin] gst_element_link_many failed");
423 return MM_ERROR_TRANSCODE_INTERNAL;
426 gst_element_add_pad(handle->decoder_audp->decaudiobin, gst_ghost_pad_new("decbin_audiosink", handle->decoder_audp->decaudiosinkpad));
427 gst_element_add_pad(handle->decoder_audp->decaudiobin, gst_ghost_pad_new("decbin_audiosrc", handle->decoder_audp->decaudiosrcpad));
429 /* get sink audiopad of decodebin */
430 handle->decoder_audp->sinkdecaudiopad = gst_element_get_static_pad(handle->decoder_audp->decaudiobin, "decbin_audiosink");
431 /* get src audiopad of decodebin */
432 handle->decoder_audp->srcdecaudiopad = gst_element_get_static_pad(handle->decoder_audp->decaudiobin, "decbin_audiosrc");
434 handle->property->audio_cb_probe_id = gst_pad_add_probe(handle->decoder_audp->sinkdecaudiopad, GST_PAD_PROBE_TYPE_BUFFER, _mm_cb_audio_output_stream_probe, handle, NULL);
435 /* must use sinkpad (sinkpad => srcpad) for normal resized video buffer */
436 LOGD("audio_cb_probe_id: %lu", handle->property->audio_cb_probe_id);
439 gst_bin_add(GST_BIN(handle->pipeline), handle->decoder_audp->decaudiobin);
443 static int _mm_decode_video_output_create(handle_s *handle)
445 int ret = MM_ERROR_NONE;
448 LOGE("[ERROR] - handle");
449 return MM_ERROR_INVALID_ARGUMENT;
452 if (!handle->property) {
453 LOGE("[ERROR] - handle property");
454 return MM_ERROR_TRANSCODE_INTERNAL;
457 if (!handle->decoder_vidp) {
458 LOGE("[ERROR] - handle decoder video process bin");
459 return MM_ERROR_TRANSCODE_INTERNAL;
462 handle->decoder_vidp->decvideobin = gst_bin_new("videobin");
463 if (!handle->decoder_vidp->decvideobin) {
464 LOGE("decvideobin could not be created. Exiting");
465 return MM_ERROR_TRANSCODE_INTERNAL;
468 handle->decoder_vidp->decsinkvideoqueue = gst_element_factory_make("queue", "decsinkvideoqueue");
469 if (!handle->decoder_vidp->decsinkvideoqueue) {
470 LOGE("decsinkvideoqueue element could not be created. Exiting");
471 return MM_ERROR_TRANSCODE_INTERNAL;
474 _mm_decode_add_sink(handle, handle->decoder_vidp->decsinkvideoqueue);
476 handle->decoder_vidp->decvideosinkpad = gst_element_get_static_pad(handle->decoder_vidp->decsinkvideoqueue, "sink");
477 if (!handle->decoder_vidp->decvideosinkpad) {
478 LOGE("decvideosinkpad element could not be created. Exiting");
479 return MM_ERROR_TRANSCODE_INTERNAL;
482 handle->decoder_vidp->videorate = gst_element_factory_make("videorate", "videorate");
483 if (!handle->decoder_vidp->videorate) {
484 LOGE("videorate element could not be created. Exiting");
485 return MM_ERROR_TRANSCODE_INTERNAL;
488 g_object_set(handle->decoder_vidp->videorate, "average-period", GST_SECOND / 2, NULL);
489 g_object_set(handle->decoder_vidp->videorate, "max-rate", 30, NULL);
491 handle->decoder_vidp->videoscale = gst_element_factory_make("videoscale", "scaler");
492 if (!handle->decoder_vidp->videoscale) {
493 LOGE("videoscale element could not be created. Exiting");
494 return MM_ERROR_TRANSCODE_INTERNAL;
496 /* Configure videoscale to use 4-tap scaling for higher quality */
497 g_object_set(handle->decoder_vidp->videoscale, "method", 2, NULL);
499 handle->decoder_vidp->vidflt = gst_element_factory_make("capsfilter", "vfilter");
500 if (!handle->decoder_vidp->vidflt) {
501 LOGE("One element could not be created. Exiting");
502 return MM_ERROR_TRANSCODE_INTERNAL;
505 handle->decoder_vidp->decvideosrcpad = gst_element_get_static_pad(handle->decoder_vidp->vidflt, "src");
506 if (!handle->decoder_vidp->decvideosrcpad) {
507 LOGE("decvideosrcpad element could not be created. Exiting");
508 return MM_ERROR_TRANSCODE_INTERNAL;
514 static int _mm_decode_video_output_link(handle_s *handle)
516 int ret = MM_ERROR_NONE;
519 LOGE("[ERROR] - handle");
520 return MM_ERROR_INVALID_ARGUMENT;
523 if (!handle->decoder_vidp) {
524 LOGE("[ERROR] - handle decoder video process bin");
525 return MM_ERROR_TRANSCODE_INTERNAL;
528 gst_bin_add_many(GST_BIN(handle->decoder_vidp->decvideobin), handle->decoder_vidp->decsinkvideoqueue, handle->decoder_vidp->videoscale, handle->decoder_vidp->videorate, handle->decoder_vidp->vidflt, NULL);
529 if (!gst_element_link_many(handle->decoder_vidp->decsinkvideoqueue, handle->decoder_vidp->videoscale, handle->decoder_vidp->videorate, handle->decoder_vidp->vidflt, NULL)) {
530 LOGE("[Video Output Bin] gst_element_link_many failed");
531 return MM_ERROR_TRANSCODE_INTERNAL;
534 gst_element_add_pad(handle->decoder_vidp->decvideobin, gst_ghost_pad_new("decbin_videosink", handle->decoder_vidp->decvideosinkpad));
535 gst_element_add_pad(handle->decoder_vidp->decvideobin, gst_ghost_pad_new("decbin_videosrc", handle->decoder_vidp->decvideosrcpad));
537 handle->decoder_vidp->sinkdecvideopad = gst_element_get_static_pad(handle->decoder_vidp->decvideobin, "decbin_videosink");
538 handle->decoder_vidp->srcdecvideopad = gst_element_get_static_pad(handle->decoder_vidp->decvideobin, "decbin_videosrc");
540 handle->property->video_cb_probe_id = gst_pad_add_probe(handle->decoder_vidp->sinkdecvideopad, GST_PAD_PROBE_TYPE_BUFFER, _mm_cb_video_output_stream_probe, handle, NULL);
541 /* must use sinkpad (sinkpad => srcpad) */
542 LOGD("video_cb_probe_sink_id: %lu", handle->property->video_cb_probe_id);
544 gst_bin_add(GST_BIN(handle->pipeline), handle->decoder_vidp->decvideobin);
549 static int _mm_decodebin_pipeline_create(handle_s *handle)
551 int ret = MM_ERROR_NONE;
553 /* autoplug-select is not worked when decodebin */
554 handle->decodebin = gst_element_factory_make("decodebin", "decoder");
556 if (!handle->decodebin) {
557 LOGE("decbin element could not be created. Exiting");
558 return MM_ERROR_TRANSCODE_INTERNAL;
561 g_signal_connect(handle->decodebin, "pad-added", G_CALLBACK(_mm_cb_decoder_newpad_encoder), handle);
562 g_signal_connect(handle->decodebin, "autoplug-select", G_CALLBACK(_mm_cb_decode_bin_autoplug_select), handle);
567 int _mm_decodesrcbin_create(handle_s *handle)
569 int ret = MM_ERROR_NONE;
572 LOGE("[ERROR] - handle");
573 return MM_ERROR_INVALID_ARGUMENT;
576 if (!handle->decoder_vidp) {
577 LOGE("[ERROR] - handle decoder video process bin");
578 return MM_ERROR_TRANSCODE_INTERNAL;
581 if (!handle->decoder_audp) {
582 LOGE("[ERROR] - handle decoder audio process bin");
583 return MM_ERROR_TRANSCODE_INTERNAL;
586 if (!handle->property) {
587 LOGE("[ERROR] - handle property");
588 return MM_ERROR_TRANSCODE_INTERNAL;
591 ret = _mm_filesrc_pipeline_create(handle);
592 if (ret == MM_ERROR_NONE) {
593 LOGD("Success - Create filesrc pipeline");
595 LOGE("ERROR -Create filesrc pipeline");
599 if (handle->property->has_audio_stream) {
600 ret = _mm_decode_audio_output_create(handle);
601 if (ret == MM_ERROR_NONE) {
602 LOGD("Success - Create audiobin pipeline: %p", handle->decoder_audp->decaudiobin);
604 LOGE("ERROR - Create audiobin pipeline");
609 if (handle->property->has_video_stream) {
610 ret = _mm_decode_video_output_create(handle);
611 if (ret == MM_ERROR_NONE) {
612 LOGD("Success - Create videobin pipeline: %p", handle->decoder_vidp->decvideobin);
614 LOGE("ERROR -Create videobin pipeline");
619 ret = _mm_decodebin_pipeline_create(handle);
620 if (ret == MM_ERROR_NONE) {
621 LOGD("Success - Create decodebin pipeline");
623 LOGE("ERROR - Create decodebin pipeline");
630 int _mm_decodesrcbin_link(handle_s *handle)
632 int ret = MM_ERROR_NONE;
635 LOGE("[ERROR] - handle");
636 return MM_ERROR_INVALID_ARGUMENT;
639 if (!handle->property) {
640 LOGE("[ERROR] - handle property");
641 return MM_ERROR_TRANSCODE_INTERNAL;
644 ret = _mm_filesrc_decodebin_link(handle);
645 if (ret == MM_ERROR_NONE) {
646 LOGD("Success - _mm_filesrc_decodebin_link");
648 LOGE("ERROR - _mm_filesrc_decodebin_link");
652 if (handle->property->has_audio_stream) {
653 ret = _mm_decode_audio_output_link(handle);
654 if (ret == MM_ERROR_NONE) {
655 LOGD("Success - _mm_decode_audio_output_link");
657 LOGE("ERROR - _mm_decode_audio_output_link");
662 if (handle->property->has_video_stream) {
663 ret = _mm_decode_video_output_link(handle);
664 if (ret == MM_ERROR_NONE) {
665 LOGD("Success - _mm_decode_video_output_link");
667 LOGE("ERROR - _mm_decode_video_output_link");
675 int _mm_encodebin_create(handle_s *handle)
677 int ret = MM_ERROR_NONE;
680 LOGE("[ERROR] - handle");
681 return MM_ERROR_INVALID_ARGUMENT;
684 if (!handle->encodebin) {
685 LOGE("[ERROR] - handle encodebin");
686 return MM_ERROR_TRANSCODE_INTERNAL;
689 if (!handle->property) {
690 LOGE("[ERROR] - handle property");
691 return MM_ERROR_TRANSCODE_INTERNAL;
694 handle->encodebin->encbin = gst_element_factory_make("encodebin", "encodebin");
696 if (!handle->encodebin->encbin) {
697 LOGE("encbin element could not be created");
698 return MM_ERROR_TRANSCODE_INTERNAL;
701 if (handle->property->videoencoder != MM_VIDEOENCODER_NO_USE && handle->property->audioencoder != MM_AUDIOENCODER_NO_USE) {
702 ret = _mm_encodebin_set_video_property(handle);
703 if (ret != MM_ERROR_NONE) {
704 LOGE("ERROR -Setup encodebin video property");
708 ret = _mm_encodebin_set_audio_property(handle);
709 if (ret != MM_ERROR_NONE) {
710 LOGE("ERROR -Setup encodebin audio property");
713 } else if (handle->property->videoencoder != MM_VIDEOENCODER_NO_USE) {
714 ret = _mm_encodebin_set_video_property(handle);
715 if (ret != MM_ERROR_NONE) {
716 LOGE("ERROR -Setup encodebin video property");
719 } else if (handle->property->audioencoder != MM_AUDIOENCODER_NO_USE) {
720 handle->encodebin->encodebin_profile = 1;
721 LOGD("[AUDIO ONLY ENCODE]");
722 ret = _mm_encodebin_set_audio_property(handle);
723 if (ret != MM_ERROR_NONE) {
724 LOGE("ERROR -Setup encodebin video property");
729 LOGD("[Encodebin Profile: %d]", handle->encodebin->encodebin_profile);
730 ret = _mm_encodebin_set_property(handle);
731 if (ret != MM_ERROR_NONE) {
732 LOGE("ERROR -Setup encodebin property");
739 int _mm_encodebin_link(handle_s *handle)
741 int ret = MM_ERROR_NONE;
744 LOGE("[ERROR] - handle");
745 return MM_ERROR_INVALID_ARGUMENT;
748 if (!handle->encodebin) {
749 LOGE("[ERROR] - handle encodebin");
750 return MM_ERROR_TRANSCODE_INTERNAL;
753 if (!handle->property) {
754 LOGE("[ERROR] - handle property");
755 return MM_ERROR_TRANSCODE_INTERNAL;
758 /* Add encodebin to pipeline */
759 gst_bin_add(GST_BIN(handle->pipeline), handle->encodebin->encbin);
761 if (handle->property->has_video_stream) {
762 if (handle->property->videoencoder != MM_VIDEOENCODER_NO_USE) {
763 handle->encodebin->encvideopad = gst_element_get_request_pad(handle->encodebin->encbin, "video");
764 if (handle->encodebin->encvideopad) {
765 LOGD("encvideopad: %p", handle->encodebin->encvideopad);
766 gst_pad_link(handle->decoder_vidp->srcdecvideopad, handle->encodebin->encvideopad);
767 handle->encodebin->audio_event_probe_id = gst_pad_add_probe(handle->encodebin->encvideopad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, _mm_cb_encodebin_sinkpad_event_probe, handle, NULL);
769 LOGE("error encvideopad");
770 return MM_ERROR_TRANSCODE_INTERNAL;
775 if (handle->property->has_audio_stream) {
776 if (handle->property->audioencoder != MM_AUDIOENCODER_NO_USE) {
777 handle->encodebin->encaudiopad = gst_element_get_request_pad(handle->encodebin->encbin, "audio");
778 if (handle->encodebin->encaudiopad) {
779 LOGD("encaudiopad: %p", handle->encodebin->encaudiopad);
780 gst_pad_link(handle->decoder_audp->srcdecaudiopad, handle->encodebin->encaudiopad);
781 handle->encodebin->audio_event_probe_id = gst_pad_add_probe(handle->encodebin->encaudiopad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, _mm_cb_encodebin_sinkpad_event_probe, handle, NULL);
783 LOGE("error encaudiopad");
784 return MM_ERROR_TRANSCODE_INTERNAL;
792 static int _mm_encodebin_set_audio_property(handle_s *handle)
794 int ret = MM_ERROR_NONE;
797 LOGE("[ERROR] - handle");
798 return MM_ERROR_INVALID_ARGUMENT;
801 if (!handle->encodebin) {
802 LOGE("[ERROR] - handle encodebin");
803 return MM_ERROR_TRANSCODE_INTERNAL;
806 if (!handle->property) {
807 LOGE("[ERROR] - handle property");
808 return MM_ERROR_TRANSCODE_INTERNAL;
811 if (handle->property->has_audio_stream) {
813 if (g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(handle->encodebin->encbin)), ARS)) {
814 g_object_set(G_OBJECT(handle->encodebin->encbin), ARS, 0, NULL);
815 LOGD("[AUDIO RESAMPLE] encbin set auto-audio-resample");
817 LOGE("error [AUDIO RESAMPLE] encbin set auto-audio-resample");
818 return MM_ERROR_TRANSCODE_INTERNAL;
821 if (g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(handle->encodebin->encbin)), ACON)) {
822 g_object_set(G_OBJECT(handle->encodebin->encbin), ACON, 1, NULL);
823 LOGD("encbin set auto-audio-convert");
825 LOGE("error encbin set auto-audio-convert");
826 return MM_ERROR_TRANSCODE_INTERNAL;
829 if (g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(handle->encodebin->encbin)), AENC)) {
830 g_object_set(G_OBJECT(handle->encodebin->encbin), AENC, handle->property->aenc, NULL);
831 LOGD("[AUDIOENCODER] encbin set [%s: %s]", AENC, handle->property->aenc);
833 LOGE("error [AUDIOENCODER] encbin set [%s: %s]", AENC, handle->property->aenc);
834 return MM_ERROR_TRANSCODE_INTERNAL;
837 if (g_strcmp0(handle->property->aenc, AACENC) == 0)
838 g_object_set(G_OBJECT(gst_bin_get_by_name(GST_BIN(handle->encodebin->encbin), "audio_encode")), AACCOMPLIANCE, AACCOMPLIANCELEVEL, NULL);
840 g_object_get(G_OBJECT(handle->encodebin->encbin), "use-aenc-queue", &(handle->encodebin->aencqueue), NULL);
841 LOGD("aencqueue : %s", GST_ELEMENT_NAME(handle->encodebin->aencqueue));
847 static int _mm_encodebin_set_property(handle_s *handle)
849 int ret = MM_ERROR_NONE;
852 LOGE("[ERROR] - handle");
853 return MM_ERROR_INVALID_ARGUMENT;
856 if (!handle->encodebin) {
857 LOGE("[ERROR] - handle encodebin");
858 return MM_ERROR_TRANSCODE_INTERNAL;
861 if (!handle->property) {
862 LOGE("[ERROR] - handle property");
863 return MM_ERROR_TRANSCODE_INTERNAL;
866 if (g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(handle->encodebin->encbin)), PROFILE)) {
867 g_object_set(G_OBJECT(handle->encodebin->encbin), PROFILE, handle->encodebin->encodebin_profile, NULL);
868 LOGD("encbin set profile");
870 LOGE("error handle->encbin set profile");
871 return MM_ERROR_TRANSCODE_INTERNAL;
874 if (g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(handle->encodebin->encbin)), MUX)) {
875 g_object_set(G_OBJECT(handle->encodebin->encbin), MUX, handle->property->mux, NULL);
876 LOGD("[MUX] encbin set [%s: %s]", MUX, handle->property->mux);
878 LOGE("error [MUX] set [%s: %s]", MUX, handle->property->mux);
879 return MM_ERROR_TRANSCODE_INTERNAL;
885 static int _mm_encodebin_set_video_property(handle_s *handle)
887 int ret = MM_ERROR_NONE;
890 LOGE("[ERROR] - handle");
891 return MM_ERROR_INVALID_ARGUMENT;
894 if (!handle->encodebin) {
895 LOGE("[ERROR] - handle encodebin");
896 return MM_ERROR_TRANSCODE_INTERNAL;
899 if (!handle->property) {
900 LOGE("[ERROR] - handle property");
901 return MM_ERROR_TRANSCODE_INTERNAL;
904 if (handle->property->has_video_stream) {
906 if (g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(handle->encodebin->encbin)), ACS)) {
907 g_object_set(G_OBJECT(handle->encodebin->encbin), ACS, 0, NULL);
908 LOGD("[AUTO COLORSPACE] encbin set auto-colorspace");
910 LOGE("error [AUTO COLORSPACE] encbin set auto-colorspace");
911 return MM_ERROR_TRANSCODE_INTERNAL;
914 if (g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(handle->encodebin->encbin)), VENC)) {
915 g_object_set(G_OBJECT(handle->encodebin->encbin), VENC, handle->property->venc, NULL);
916 LOGD("[VIDEOENCODER] encbin set [%s: %s]", VENC, handle->property->venc);
918 LOGE("error [VIDEOENCODER] set [%s: %s]", VENC, handle->property->venc);
919 return MM_ERROR_TRANSCODE_INTERNAL;
922 g_object_get(G_OBJECT(handle->encodebin->encbin), "use-venc-queue", &(handle->encodebin->vencqueue), NULL);
923 LOGD("vencqueue : %s", GST_ELEMENT_NAME(handle->encodebin->vencqueue));
929 int _mm_filesink_create(handle_s *handle)
931 int ret = MM_ERROR_NONE;
934 LOGE("[ERROR] - handle");
935 return MM_ERROR_INVALID_ARGUMENT;
938 handle->filesink = gst_element_factory_make("filesink", "filesink");
940 if (!handle->filesink) {
941 LOGE("filesink element could not be created");
942 return MM_ERROR_TRANSCODE_INTERNAL;
946 g_object_set(G_OBJECT(handle->filesink), "sync", TRUE, NULL);
947 g_object_set(G_OBJECT(handle->filesink), "async", FALSE, NULL);
952 int _mm_filesink_link(handle_s *handle)
954 int ret = MM_ERROR_NONE;
957 LOGE("[ERROR] - handle");
958 return MM_ERROR_INVALID_ARGUMENT;
961 if (!handle->encodebin) {
962 LOGE("[ERROR] - handle encodebin");
963 return MM_ERROR_TRANSCODE_INTERNAL;
966 /* Add encodesinkbin to pipeline */
967 gst_bin_add(GST_BIN(handle->pipeline), handle->filesink);
969 /* link encodebin and filesink */
970 if (!gst_element_link(handle->encodebin->encbin, handle->filesink)) {
971 LOGE("gst_element_link [encbin ! filesink] failed");
972 return MM_ERROR_TRANSCODE_INTERNAL;
974 LOGD("gst_element_link [encbin ! filesink]");
980 static int _mm_filesrc_pipeline_create(handle_s *handle)
982 int ret = MM_ERROR_NONE;
984 handle->filesrc = gst_element_factory_make("filesrc", "source");
986 if (!handle->filesrc) {
987 LOGE("filesrc element could not be created. Exiting");
988 return MM_ERROR_TRANSCODE_INTERNAL;
991 if (!handle->property) {
992 LOGE("[ERROR] - handle property");
993 return MM_ERROR_TRANSCODE_INTERNAL;
996 LOGD("sourcefile: %s", handle->property->sourcefile);
997 g_object_set(G_OBJECT(handle->filesrc), "location", handle->property->sourcefile, NULL);
1002 static int _mm_filesrc_decodebin_link(handle_s *handle)
1004 int ret = MM_ERROR_NONE;
1007 LOGE("[ERROR] - handle");
1008 return MM_ERROR_INVALID_ARGUMENT;
1011 /* Add element(filesrc, decodebin) */
1012 gst_bin_add_many(GST_BIN(handle->pipeline), handle->filesrc, handle->decodebin, NULL);
1014 if (!gst_element_link_many(handle->filesrc, handle->decodebin, NULL)) {
1015 LOGE("gst_element_link_many src ! decbin failed");
1016 return MM_ERROR_TRANSCODE_INTERNAL;
1022 int _mm_transcode_preset_capsfilter(handle_s *handle, unsigned int resolution_width, unsigned int resolution_height)
1024 int ret = MM_ERROR_NONE;
1027 LOGE("[ERROR] - handle");
1028 return MM_ERROR_INVALID_ARGUMENT;
1031 if (!handle->decoder_vidp) {
1032 LOGE("[ERROR] - handle decoder video process bin");
1033 return MM_ERROR_TRANSCODE_INTERNAL;
1036 if (!handle->property) {
1037 LOGE("[ERROR] - handle property");
1038 return MM_ERROR_TRANSCODE_INTERNAL;
1041 if (handle->decoder_vidp->vidflt) {
1042 LOGD("[Resolution] Output Width: [%d], Output Height: [%d]", resolution_width, resolution_height);
1044 if (resolution_width == 0 || resolution_height == 0)
1045 g_object_set(G_OBJECT(handle->decoder_vidp->vidflt), "caps", gst_caps_new_simple("video/x-raw", "format", G_TYPE_STRING, "I420", NULL), NULL);
1047 g_object_set(G_OBJECT(handle->decoder_vidp->vidflt), "caps", gst_caps_new_simple("video/x-raw", "format", G_TYPE_STRING, "I420", "width", G_TYPE_INT, resolution_width, "height", G_TYPE_INT, resolution_height, NULL), NULL);
1053 int _mm_setup_pipeline(handle_s *handle)
1055 int ret = MM_ERROR_NONE;
1058 LOGE("[ERROR] - handle");
1059 return MM_ERROR_INVALID_ARGUMENT;
1062 handle->pipeline = gst_pipeline_new("TransCode");
1063 LOGD("Success - pipeline");
1065 if (!handle->pipeline) {
1066 LOGE("pipeline could not be created. Exiting");
1067 return MM_ERROR_TRANSCODE_INTERNAL;