From: Jinkun Jang Date: Fri, 15 Mar 2013 16:15:59 +0000 (+0900) Subject: merge with master X-Git-Tag: submit/tizen_2.1/20130424.232124~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=eba977548fa6fe7e014bd7d0e8aad9d713689d8c;p=platform%2Fcore%2Fmultimedia%2Flibmm-transcode.git merge with master --- diff --git a/packaging/libmm-transcode.spec b/packaging/libmm-transcode.spec index 5dd79aa..a9b6121 100644 --- a/packaging/libmm-transcode.spec +++ b/packaging/libmm-transcode.spec @@ -1,8 +1,8 @@ #sbs-git:slp/pkgs/l/libmm-transcode libmm-transcode 0.1 62b62e6d483557fc5750d1b4986e9a98323f1194 Name: libmm-transcode Summary: Multimedia Framework Video Transcode Library -Version: 0.7 -Release: 12 +Version: 0.8 +Release: 2 Group: System/Libraries License: Apache-2.0 Source0: %{name}-%{version}.tar.gz diff --git a/transcode/include/mm_transcode_internal.h b/transcode/include/mm_transcode_internal.h index 4384b1a..2ebfb78 100644 --- a/transcode/include/mm_transcode_internal.h +++ b/transcode/include/mm_transcode_internal.h @@ -107,61 +107,55 @@ typedef struct _handle_param_s unsigned int printed; } handle_param_s; -typedef struct _handle_s +typedef struct _handle_vidp_plugin_s { - /* pipeline element*/ - GstElement *pipeline; - GstElement *decsrcbin; - GstElement *filesrc; - GstPad *filesrcpad; - GstElement *decbin; - GstElement *decaudiobin; - GstPad *decaudiopad; - GstPad *decvideopad; - GstElement *valve; - GstElement *aconv; - GstElement *resample; - GstElement *audflt; - GstElement *audiofakesink; - GstCaps *caps; - GstElement *decsinkaudioqueue; - GstPad *decaudiosinkpad; - GstPad *decaudiosrcpad; - GstPad *audiofakesinkcpad; - GstPad *audiopad; - GstPad *sinkdecaudiopad; - GstPad *srcdecaudiopad; - GstPad *encaudiopad; - - GstElement *decsinkvideoqueue; + /* decoder video processing pipeline */ GstElement *decvideobin; + GstElement *decsinkvideoqueue; GstPad *decvideosinkpad; GstPad *decvideosrcpad; - GstPad *decxvimagesinkpad; GstElement *vidflt; GstElement *videoscale; GstElement *videorate; GstPad *videopad; GstPad *sinkdecvideopad; GstPad *srcdecvideopad; - GstPad *encvideopad; +} handle_vidp_plugin_s; +typedef struct _handle_audp_plugin_s +{ + /* decoder audio processing pipeline */ + GstElement *decaudiobin; + GstElement *decsinkaudioqueue; + GstPad *decaudiosinkpad; + GstPad *decaudiosrcpad; + GstElement *valve; + GstElement *aconv; + GstElement *resample; + GstElement *audflt; + GstElement *audiofakesink; + GstPad *sinkdecaudiopad; + GstPad *srcdecaudiopad; + GstPad *decaudiopad; + GstPad *decvideopad; +} handle_audp_plugin_s; + +typedef struct _handle_encode_s +{ + /* encode pipeline */ GstElement *encbin; + GstPad *encaudiopad; + GstPad *encvideopad; GstElement *ffmux; int use_vencqueue; int use_aencqueue; GstElement *encodepad; - GstElement *filesink; - GList *sink_elements; + GstElement *encodevideo; int encodebin_profile; - gboolean linked_vidoutbin; - gboolean linked_audoutbin; - mm_containerformat_e containerformat; - mm_videoencoder_e videoencoder; - mm_audioencoder_e audioencoder; - gboolean has_video_stream; - gboolean has_audio_stream; +} handle_encode_s; +typedef struct _handle_property_s +{ /* pipeline property */ guint bus_watcher; int AUDFLAG; @@ -192,6 +186,18 @@ typedef struct _handle_s unsigned long total_length; char sourcefile[BUFFER_SIZE]; unsigned int _MMHandle; + + mm_containerformat_e containerformat; + mm_videoencoder_e videoencoder; + mm_audioencoder_e audioencoder; + + GstCaps *caps; + GList *sink_elements; + gboolean linked_vidoutbin; + gboolean linked_audoutbin; + gboolean has_video_stream; + gboolean has_audio_stream; + /* message callback */ mm_transcode_completed_callback completed_cb; void * completed_cb_param; @@ -208,11 +214,25 @@ typedef struct _handle_s GThread* thread; gboolean repeat_thread_exit; GAsyncQueue *queue; + int seek_idx; +} handle_property_s; + +typedef struct _handle_s +{ + /* Transcode Pipeline Element*/ + GstElement *pipeline; + GstElement *filesrc; + GstElement *decodebin; + handle_vidp_plugin_s *decoder_vidp; + handle_audp_plugin_s *decoder_audp; + handle_encode_s *encodebin; + GstElement *filesink; /* seek paramerter */ handle_param_s *param; - int seek_idx; + /* pipeline property */ + handle_property_s *property; } handle_s; gboolean _mm_cb_audio_output_stream_probe(GstPad *pad, GstBuffer *buffer, gpointer user_data); diff --git a/transcode/mm_transcode.c b/transcode/mm_transcode.c index db233bb..5a8b5fe 100755 --- a/transcode/mm_transcode.c +++ b/transcode/mm_transcode.c @@ -36,17 +36,40 @@ mm_transcode_create (MMHandleType* MMHandle) /* Init Transcode */ gst_init (NULL, NULL); handle = g_new0 (handle_s, 1); /*handle = g_malloc(sizeof(handle_s));*/ - if (!handle) { debug_error("[ERROR] - handle"); return MM_ERROR_TRANSCODE_INTERNAL; } + handle->decoder_vidp= g_new0 (handle_vidp_plugin_s, 1); + if (!handle->decoder_vidp) { + debug_error("[ERROR] - handle decoder video process bin"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + + handle->decoder_audp= g_new0 (handle_audp_plugin_s, 1); + if (!handle->decoder_audp) { + debug_error("[ERROR] - handle decoder audio process bin"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + + handle->encodebin= g_new0 (handle_encode_s, 1); + if (!handle->encodebin) { + debug_error("[ERROR] - handle encodebin"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + + handle->property = g_new0 (handle_property_s, 1); + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + *MMHandle = (MMHandleType)handle; if(MMHandle) { debug_log("MMHandle: 0x%2x", handle); - handle->_MMHandle = 0; + handle->property->_MMHandle = 0; } else { debug_error("handle create Fail"); return MM_ERROR_TRANSCODE_INTERNAL; @@ -68,6 +91,11 @@ mm_audioencoder_e audioencoder) return MM_ERROR_INVALID_ARGUMENT; } + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + if((in_Filename == NULL) || (strlen (in_Filename) == 0)) { debug_error("Invalid Input file"); return MM_ERROR_INVALID_ARGUMENT; @@ -83,78 +111,77 @@ mm_audioencoder_e audioencoder) return MM_ERROR_INVALID_ARGUMENT; } - debug_log("%s== %s", handle->sourcefile, in_Filename); - if(0 == strlen(handle->sourcefile) || 0 == strcmp(handle->sourcefile, in_Filename)) { /* protect the case of changing input file during transcoding */ + debug_log("%s== %s", handle->property->sourcefile, in_Filename); + if(0 == strlen(handle->property->sourcefile) || 0 == strcmp(handle->property->sourcefile, in_Filename)) { /* protect the case of changing input file during transcoding */ /* set element*/ ret = _mm_transcode_set_handle_element(handle, in_Filename, containerformat, videoencoder, audioencoder); if(ret != MM_ERROR_NONE) { debug_error("ERROR -Set element"); return ret; - } + } - /* setup */ - ret = _mm_setup_pipeline(handle); - if(ret == MM_ERROR_NONE) { - debug_log("Success - Setup Pipeline"); - } else{ - debug_error("ERROR - Setup Pipeline"); - return ret; - } + /* setup */ + ret = _mm_setup_pipeline(handle); + if(ret == MM_ERROR_NONE) { + debug_log("Success - Setup Pipeline"); + } else{ + debug_error("ERROR - Setup Pipeline"); + return ret; + } - /* video / auido stream */ - ret = _mm_transcode_get_stream_info(handle); - if(ret == MM_ERROR_NONE) { - debug_log("Success - Get stream info"); - } else{ - debug_error("ERROR - Get stream info"); - return ret; - } + /* video / auido stream */ + ret = _mm_transcode_get_stream_info(handle); + if(ret == MM_ERROR_NONE) { + debug_log("Success - Get stream info"); + } else{ + debug_error("ERROR - Get stream info"); + return ret; + } - /* create pipeline */ - ret = _mm_transcode_create(handle); - if(ret == MM_ERROR_NONE) { - debug_log("Success - Create Pipeline"); - } else{ - debug_error("ERROR -Create Pipeline"); - return ret; - } + /* create pipeline */ + ret = _mm_transcode_create(handle); + if(ret == MM_ERROR_NONE) { + debug_log("Success - Create Pipeline"); + } else{ + debug_error("ERROR -Create Pipeline"); + return ret; + } - /*link pipeline */ - ret = _mm_transcode_link(handle); - if(ret == MM_ERROR_NONE) { - debug_log("Success - Link pipeline"); - } else{ - debug_error("ERROR - Link pipeline"); - return ret; - } + /*link pipeline */ + ret = _mm_transcode_link(handle); + if(ret == MM_ERROR_NONE) { + debug_log("Success - Link pipeline"); + } else{ + debug_error("ERROR - Link pipeline"); + return ret; + } - /* flush param */ - ret = _mm_transcode_param_flush(handle); - if(ret == MM_ERROR_NONE) { - debug_log("Success - Init parameter"); - } else{ - debug_error("ERROR - Init parameter"); - return ret; - } + /* flush param */ + ret = _mm_transcode_param_flush(handle); + if(ret == MM_ERROR_NONE) { + debug_log("Success - Init parameter"); + } else{ + debug_error("ERROR - Init parameter"); + return ret; + } - /* create thread */ - ret = _mm_transcode_thread(handle); - if(ret == MM_ERROR_NONE) { - debug_log("Success - Link pipeline"); - } else{ - debug_error("ERROR - Link pipeline"); - return ret; - } + /* create thread */ + ret = _mm_transcode_thread(handle); + if(ret == MM_ERROR_NONE) { + debug_log("Success - Link pipeline"); + } else{ + debug_error("ERROR - Link pipeline"); + return ret; + } - /* Add_watcher Transcode Bus*/ - GstBus *bus; - bus = gst_pipeline_get_bus (GST_PIPELINE (handle->pipeline)); - handle->bus_watcher = gst_bus_add_watch (bus, (GstBusFunc)_mm_cb_transcode_bus, handle); - gst_object_unref (GST_OBJECT(bus)); - debug_log("Success - gst_object_unref (bus)"); + /* Add_watcher Transcode Bus*/ + GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (handle->pipeline)); + handle->property->bus_watcher = gst_bus_add_watch (bus, (GstBusFunc)_mm_cb_transcode_bus, handle); + gst_object_unref (GST_OBJECT(bus)); + debug_log("Success - gst_object_unref (bus)"); } - handle->_MMHandle++; + handle->property->_MMHandle++; return ret; } @@ -171,6 +198,11 @@ mm_transcode (MMHandleType MMHandle, unsigned int resolution_width, unsigned int return MM_ERROR_INVALID_ARGUMENT; } + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + if(!completed_callback) { debug_error("[ERROR] - completed_callback"); return MM_ERROR_INVALID_ARGUMENT; @@ -186,15 +218,20 @@ mm_transcode (MMHandleType MMHandle, unsigned int resolution_width, unsigned int return MM_ERROR_INVALID_ARGUMENT; } - handle->progress_cb = progress_callback; - handle->progress_cb_param = user_param; - debug_log("[MMHandle] 0x%2x [progress_cb] 0x%2x [progress_cb_param] 0x%2x", MMHandle, handle->progress_cb, handle->progress_cb_param); + handle->property->progress_cb= progress_callback; + handle->property->progress_cb_param = user_param; + debug_log("[MMHandle] 0x%2x [progress_cb] 0x%2x [progress_cb_param] 0x%2x", MMHandle, handle->property->progress_cb, handle->property->progress_cb_param); - handle->completed_cb = completed_callback; - handle->completed_cb_param = user_param; - debug_log("[MMHandle] 0x%2x [completed_cb] 0x%2x [completed_cb_param] 0x%2x", MMHandle, handle->completed_cb, handle->completed_cb_param); + handle->property->completed_cb = completed_callback; + handle->property->completed_cb_param = user_param; + debug_log("[MMHandle] 0x%2x [completed_cb] 0x%2x [completed_cb_param] 0x%2x", MMHandle, handle->property->completed_cb, handle->property->completed_cb_param); - if(handle->_MMHandle == 1) { /* check if prepare is called during transcoding */ + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + + if(handle->property->_MMHandle == 1) { /* check if prepare is called during transcoding */ handle_param_s *param = g_new0 (handle_param_s, 1); if(param) { /*g_value_init (param, G_TYPE_INT);*/ @@ -216,10 +253,10 @@ mm_transcode (MMHandleType MMHandle, unsigned int resolution_width, unsigned int return ret; } - handle->is_busy = TRUE; + handle->property->is_busy = TRUE; /*push data to handle */ - g_async_queue_push (handle->queue, GINT_TO_POINTER(param)); + g_async_queue_push (handle->property->queue, GINT_TO_POINTER(param)); } return ret; @@ -237,12 +274,17 @@ mm_transcode_is_busy (MMHandleType MMHandle, bool *is_busy) return MM_ERROR_INVALID_ARGUMENT; } + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + if (!is_busy) { debug_error("[ERROR] - is_busy"); return MM_ERROR_INVALID_ARGUMENT; } - *is_busy = handle->is_busy; + *is_busy = handle->property->is_busy; debug_log("[Transcoding....] %d", *is_busy); return ret; @@ -259,7 +301,12 @@ mm_transcode_cancel (MMHandleType MMHandle) return MM_ERROR_INVALID_ARGUMENT; } - if(handle->is_busy) { + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + + if(handle->property->is_busy) { debug_log("Cancel - [IS BUSY]"); ret = _mm_transcode_state_change(handle, GST_STATE_NULL); if(ret != MM_ERROR_NONE) { @@ -272,14 +319,15 @@ mm_transcode_cancel (MMHandleType MMHandle) debug_log("[Cancel] unlink %s", handle->param->outputfile); } else { debug_error("unlink error"); + return MM_ERROR_TRANSCODE_INTERNAL; } - g_cond_signal(handle->thread_cond); + g_cond_signal(handle->property->thread_cond); debug_log("===> send completed signal <-cancel"); - g_mutex_unlock (handle->thread_mutex); + g_mutex_unlock (handle->property->thread_mutex); } - handle->is_busy = FALSE; + handle->property->is_busy = FALSE; return ret; } @@ -296,15 +344,29 @@ mm_transcode_destroy (MMHandleType MMHandle) return MM_ERROR_INVALID_ARGUMENT; } - g_mutex_lock(handle->thread_exit_mutex); - handle->repeat_thread_exit = TRUE; - handle->is_busy = FALSE; - g_mutex_unlock(handle->thread_exit_mutex); + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + + g_mutex_lock(handle->property->thread_exit_mutex); + handle->property->repeat_thread_exit = TRUE; + if(handle->property->is_busy) { + ret = mm_transcode_cancel(MMHandle); + if(ret == MM_ERROR_NONE) { + debug_log("Success - Cancel Transcode"); + } else{ + debug_error("ERROR - Cancel Transcode"); + return FALSE; + } + } + /* handle->property->is_busy = FALSE; */ + g_mutex_unlock(handle->property->thread_exit_mutex); handle_param_s *param = g_new0 (handle_param_s, 1); if(param) { debug_log("[Try to Push Last Queue]"); - g_async_queue_push (handle->queue, GINT_TO_POINTER(param)); + g_async_queue_push (handle->property->queue, GINT_TO_POINTER(param)); } else { debug_error("Fail to create Last Queue"); return MM_ERROR_INVALID_ARGUMENT; @@ -319,9 +381,9 @@ mm_transcode_destroy (MMHandleType MMHandle) } if((handle->param) && (!handle->param->completed)) { - g_cond_signal(handle->thread_cond); + g_cond_signal(handle->property->thread_cond); debug_log("===> send completed signal <-destroy"); - g_mutex_unlock (handle->thread_mutex); + g_mutex_unlock (handle->property->thread_mutex); debug_log("unlock destory"); if(strlen(handle->param->outputfile) > 0) { unlink(handle->param->outputfile); @@ -355,20 +417,31 @@ mm_transcode_get_attrs(MMHandleType MMHandle, mm_containerformat_e *containerfor return MM_ERROR_INVALID_ARGUMENT; } + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + if(!containerformat || !videoencoder ||!audioencoder || !current_pos || !duration || !resolution_width || !resolution_height) { debug_error("[ERROR] - Invalid argument pointer"); return MM_ERROR_INVALID_ARGUMENT; } - *containerformat = handle->containerformat; - *videoencoder = handle->videoencoder; - *audioencoder = handle->audioencoder; - if(handle->current_pos > handle->param->duration) { + *containerformat = handle->property->containerformat; + *videoencoder = handle->property->videoencoder; + *audioencoder = handle->property->audioencoder; + + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + + if(handle->property->current_pos > handle->param->duration) { *current_pos = handle->param->duration; } else { - *current_pos = handle->current_pos; + *current_pos = handle->property->current_pos; } - *duration = handle->real_duration; + *duration = handle->property->real_duration; *resolution_width = handle->param->resolution_width; *resolution_height = handle->param->resolution_height; diff --git a/transcode/mm_transcode_codec.c b/transcode/mm_transcode_codec.c index c25e8b5..89f43f4 100755 --- a/transcode/mm_transcode_codec.c +++ b/transcode/mm_transcode_codec.c @@ -31,36 +31,41 @@ _mm_encodebin_set_venc_aenc(handle_s *handle) return MM_ERROR_INVALID_ARGUMENT; } - handle->mux = malloc(sizeof(gchar) * ENC_BUFFER_SIZE); - if(handle->mux == NULL) { + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + + handle->property->mux = malloc(sizeof(gchar) * ENC_BUFFER_SIZE); + if(handle->property->mux == NULL) { debug_error("[NULL] mux"); return MM_ERROR_INVALID_ARGUMENT; } - handle->venc = malloc(sizeof(gchar) * ENC_BUFFER_SIZE); - if(handle->venc == NULL) { + handle->property->venc = malloc(sizeof(gchar) * ENC_BUFFER_SIZE); + if(handle->property->venc == NULL) { debug_error("[NULL] venc"); - TRANSCODE_FREE(handle->mux); + TRANSCODE_FREE(handle->property->mux); return MM_ERROR_INVALID_ARGUMENT; } - handle->aenc = malloc(sizeof(gchar) * ENC_BUFFER_SIZE); - if(handle->aenc == NULL) { + handle->property->aenc = malloc(sizeof(gchar) * ENC_BUFFER_SIZE); + if(handle->property->aenc == NULL) { debug_error("[NULL] aenc"); - TRANSCODE_FREE(handle->mux); - TRANSCODE_FREE(handle->venc); + TRANSCODE_FREE(handle->property->mux); + TRANSCODE_FREE(handle->property->venc); return MM_ERROR_INVALID_ARGUMENT; } - memset(handle->mux, 0, ENC_BUFFER_SIZE); - memset(handle->venc, 0, ENC_BUFFER_SIZE); - memset(handle->aenc, 0, ENC_BUFFER_SIZE); + memset(handle->property->mux, 0, ENC_BUFFER_SIZE); + memset(handle->property->venc, 0, ENC_BUFFER_SIZE); + memset(handle->property->aenc, 0, ENC_BUFFER_SIZE); - switch(handle->containerformat) { + switch(handle->property->containerformat) { case MM_CONTAINER_3GP : case MM_CONTAINER_MP4 : - if(handle->videoencoder == MM_VIDEOENCODER_NO_USE && handle->audioencoder == MM_AUDIOENCODER_AAC) { - strncpy(handle->mux, MUXAAC, ENC_BUFFER_SIZE-1); + if(handle->property->videoencoder == MM_VIDEOENCODER_NO_USE && handle->property->audioencoder == MM_AUDIOENCODER_AAC) { + strncpy(handle->property->mux, MUXAAC, ENC_BUFFER_SIZE-1); } else { - strncpy(handle->mux, MUX3GP, ENC_BUFFER_SIZE-1); + strncpy(handle->property->mux, MUX3GP, ENC_BUFFER_SIZE-1); } break; default : @@ -68,14 +73,14 @@ _mm_encodebin_set_venc_aenc(handle_s *handle) break; } - switch(handle->videoencoder) { + switch(handle->property->videoencoder) { case MM_VIDEOENCODER_MPEG4 : - strncpy(handle->venc, FFENCMPEG4, ENC_BUFFER_SIZE-1); - debug_log("[FFMPEG] %s", handle->venc); + strncpy(handle->property->venc, FFENCMPEG4, ENC_BUFFER_SIZE-1); + debug_log("[FFMPEG] %s", handle->property->venc); break; case MM_VIDEOENCODER_H263 : - strncpy(handle->venc, FFENCH263, ENC_BUFFER_SIZE-1); - debug_log("[FFMPEG] %s", handle->venc); + strncpy(handle->property->venc, FFENCH263, ENC_BUFFER_SIZE-1); + debug_log("[FFMPEG] %s", handle->property->venc); break; case MM_VIDEOENCODER_NO_USE : debug_log("No VIDEO"); @@ -85,14 +90,14 @@ _mm_encodebin_set_venc_aenc(handle_s *handle) break; } - switch(handle->audioencoder) { + switch(handle->property->audioencoder) { case MM_AUDIOENCODER_AAC : - strncpy(handle->aenc, AACENC, ENC_BUFFER_SIZE-1); - debug_log("[FFMPEG] %s", handle->aenc); + strncpy(handle->property->aenc, AACENC, ENC_BUFFER_SIZE-1); + debug_log("[FFMPEG] %s", handle->property->aenc); break; case MM_AUDIOENCODER_AMR : - strncpy(handle->aenc, AMRENC, ENC_BUFFER_SIZE-1); - debug_log("[FFMPEG] %s", handle->aenc); + strncpy(handle->property->aenc, AMRENC, ENC_BUFFER_SIZE-1); + debug_log("[FFMPEG] %s", handle->property->aenc); break; case MM_AUDIOENCODER_NO_USE : debug_log("No AUDIO"); diff --git a/transcode/mm_transcode_pipeline.c b/transcode/mm_transcode_pipeline.c index f71c98e..4d7bc25 100755 --- a/transcode/mm_transcode_pipeline.c +++ b/transcode/mm_transcode_pipeline.c @@ -52,59 +52,31 @@ _mm_cleanup_encodebin(handle_s *handle) return MM_ERROR_INVALID_ARGUMENT; } - /* release videopad */ - if(handle->decvideosinkpad) { - gst_object_unref(GST_OBJECT(handle->decvideosinkpad)); - handle->decvideosinkpad = NULL; - debug_log("Success - gt_object_unref (decvideosinkpad)"); - } - - if(handle->decvideosrcpad) { - gst_object_unref(GST_OBJECT(handle->decvideosrcpad)); - handle->decvideosrcpad = NULL; - debug_log("Success - gst_object_unref (decvideosrcpad)"); + if (!handle->encodebin) { + debug_error("[ERROR] - handle encodebin"); + return MM_ERROR_TRANSCODE_INTERNAL; } - if(handle->srcdecvideopad) { - gst_object_unref (GST_OBJECT(handle->srcdecvideopad)); - handle->srcdecvideopad = NULL; - debug_log("Success - gst_object_unref (srcdecvideopad)"); + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return MM_ERROR_TRANSCODE_INTERNAL; } - if(handle->encvideopad) { - gst_object_unref (GST_OBJECT(handle->encvideopad)); - handle->encvideopad = NULL; + if(handle->encodebin->encvideopad) { + gst_object_unref (GST_OBJECT(handle->encodebin->encvideopad)); + handle->encodebin->encvideopad = NULL; debug_log("Success - gst_object_unref (encvideopad)"); } - /* release audiopad */ - if(handle->decaudiosinkpad) { - gst_object_unref (GST_OBJECT(handle->decaudiosinkpad)); - handle->decaudiosinkpad=NULL; - debug_log("Success - gst_object_unref (decaudiosinkpad)"); - } - - if(handle->decaudiosrcpad) { - gst_object_unref (GST_OBJECT(handle->decaudiosrcpad)); - handle->decaudiosrcpad=NULL; - debug_log("Success - gst_object_unref (decaudiosrcpad)"); - } - - if(handle->srcdecaudiopad) { - gst_object_unref (GST_OBJECT(handle->srcdecaudiopad)); - handle->srcdecaudiopad = NULL; - debug_log("Success - gst_object_unref (srcdecaudiopad)"); - } - - if(handle->encaudiopad) { - gst_object_unref (GST_OBJECT(handle->encaudiopad)); - handle->encaudiopad = NULL; + if(handle->encodebin->encaudiopad) { + gst_object_unref (GST_OBJECT(handle->encodebin->encaudiopad)); + handle->encodebin->encaudiopad = NULL; debug_log("Success - gst_object_unref (encaudiopad)"); } - if(handle->caps) { - gst_caps_unref (handle->caps); - handle->caps = NULL; + if(handle->property->caps) { + gst_caps_unref (handle->property->caps); + handle->property->caps = NULL; debug_log("gst_caps_unref"); } @@ -121,55 +93,103 @@ _mm_cleanup_pipeline(handle_s *handle) return MM_ERROR_INVALID_ARGUMENT; } - handle->_MMHandle = 0; + if (!handle->decoder_vidp) { + debug_error("[ERROR] - handle decoder video process bin"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + + handle->property->_MMHandle = 0; /* g_thread_exit(handle->thread); */ debug_log("g_thread_exit"); - if(handle->thread) { - g_thread_join(handle->thread); + if(handle->property->thread) { + g_thread_join(handle->property->thread); debug_log("Success - join (thread)"); } /* disconnecting bus watch */ - if ( handle->bus_watcher ) { - g_source_remove(handle->bus_watcher); + if ( handle->property->bus_watcher ) { + g_source_remove(handle->property->bus_watcher); debug_log("g_source_remove"); - handle->bus_watcher = 0; + handle->property->bus_watcher = 0; } - if(handle->queue) { - g_async_queue_unref(handle->queue); - handle->queue = NULL; + if(handle->property->queue) { + g_async_queue_unref(handle->property->queue); + handle->property->queue = NULL; debug_log("Success - g_async_queue_unref(queue)"); } - if(handle->thread_mutex) { - g_mutex_free (handle->thread_mutex); - handle->thread_mutex = NULL; + if(handle->property->thread_mutex) { + g_mutex_free (handle->property->thread_mutex); + handle->property->thread_mutex = NULL; debug_log("Success - free (thread_mutex)"); } - if(handle->thread_cond) { - g_cond_free (handle->thread_cond); - handle->thread_cond = NULL; + if(handle->property->thread_cond) { + g_cond_free (handle->property->thread_cond); + handle->property->thread_cond = NULL; debug_log("Success - free (thread_cond)"); } - if(handle->thread_exit_mutex) { - g_mutex_free (handle->thread_exit_mutex); - handle->thread_exit_mutex = NULL; + if(handle->property->thread_exit_mutex) { + g_mutex_free (handle->property->thread_exit_mutex); + handle->property->thread_exit_mutex = NULL; debug_log("Success - free (thread_exit_mutex)"); } - if(handle->sinkdecvideopad) { - gst_object_unref (GST_OBJECT(handle->sinkdecvideopad)); - handle->sinkdecvideopad = NULL; + /* release videopad */ + if(handle->decoder_vidp->decvideosinkpad) { + gst_object_unref(GST_OBJECT(handle->decoder_vidp->decvideosinkpad)); + handle->decoder_vidp->decvideosinkpad = NULL; + debug_log("Success - gt_object_unref (decvideosinkpad)"); + } + + if(handle->decoder_vidp->decvideosrcpad) { + gst_object_unref(GST_OBJECT(handle->decoder_vidp->decvideosrcpad)); + handle->decoder_vidp->decvideosrcpad = NULL; + debug_log("Success - gst_object_unref (decvideosrcpad)"); + } + + if(handle->decoder_vidp->srcdecvideopad) { + gst_object_unref (GST_OBJECT(handle->decoder_vidp->srcdecvideopad)); + handle->decoder_vidp->srcdecvideopad = NULL; + debug_log("Success - gst_object_unref (srcdecvideopad)"); + } + + if(handle->decoder_vidp->sinkdecvideopad) { + gst_object_unref (GST_OBJECT(handle->decoder_vidp->sinkdecvideopad)); + handle->decoder_vidp->sinkdecvideopad = NULL; debug_log("Success - gst_object_unref (sinkdecvideopad)"); } - if(handle->sinkdecaudiopad) { - gst_object_unref (GST_OBJECT(handle->sinkdecaudiopad)); - handle->sinkdecaudiopad = NULL; + /* release audiopad */ + if(handle->decoder_audp->decaudiosinkpad) { + gst_object_unref (GST_OBJECT(handle->decoder_audp->decaudiosinkpad)); + handle->decoder_audp->decaudiosinkpad = NULL; + debug_log("Success - gst_object_unref (decaudiosinkpad)"); + } + + if(handle->decoder_audp->decaudiosrcpad) { + gst_object_unref (GST_OBJECT(handle->decoder_audp->decaudiosrcpad)); + handle->decoder_audp->decaudiosrcpad=NULL; + debug_log("Success - gst_object_unref (decaudiosrcpad)"); + } + + if(handle->decoder_audp->srcdecaudiopad) { + gst_object_unref (GST_OBJECT(handle->decoder_audp->srcdecaudiopad)); + handle->decoder_audp->srcdecaudiopad = NULL; + debug_log("Success - gst_object_unref (srcdecaudiopad)"); + } + + if(handle->decoder_audp->sinkdecaudiopad) { + gst_object_unref (GST_OBJECT(handle->decoder_audp->sinkdecaudiopad)); + handle->decoder_audp->sinkdecaudiopad = NULL; debug_log("Success - gst_object_unref (sinkdecaudiopad)"); } @@ -180,9 +200,9 @@ _mm_cleanup_pipeline(handle_s *handle) debug_log("Success -clean encodebin"); } - if(handle->sink_elements) { - g_list_free (handle->sink_elements); - handle->sink_elements = NULL; + if(handle->property->sink_elements) { + g_list_free (handle->property->sink_elements); + handle->property->sink_elements = NULL; debug_log("Success - g_list_free (sink_elements)"); } @@ -192,27 +212,31 @@ _mm_cleanup_pipeline(handle_s *handle) debug_log("Success - gst_object_unref (pipeline)"); } - if(handle->audio_cb_probe_id) { - g_source_remove (handle->audio_cb_probe_id); - handle->audio_cb_probe_id = 0; + if(handle->property->audio_cb_probe_id) { + g_source_remove (handle->property->audio_cb_probe_id); + handle->property->audio_cb_probe_id = 0; debug_log("g_source_remove (audio_cb_probe_id)"); } - if(handle->video_cb_probe_id) { - g_source_remove (handle->video_cb_probe_id); - handle->video_cb_probe_id = 0; + if(handle->property->video_cb_probe_id) { + g_source_remove (handle->property->video_cb_probe_id); + handle->property->video_cb_probe_id = 0; debug_log("g_source_remove (video_cb_probe_id)"); } - if(handle->progrss_event_id) { - g_source_remove (handle->progrss_event_id); - handle->progrss_event_id = 0; + if(handle->property->progrss_event_id) { + g_source_remove (handle->property->progrss_event_id); + handle->property->progrss_event_id = 0; debug_log("g_source_remove (progrss_event_id)"); } - TRANSCODE_FREE (handle->mux); - TRANSCODE_FREE (handle->venc); - TRANSCODE_FREE (handle->aenc); + TRANSCODE_FREE (handle->property->mux); + TRANSCODE_FREE (handle->property->venc); + TRANSCODE_FREE (handle->property->aenc); + TRANSCODE_FREE (handle->decoder_vidp); + TRANSCODE_FREE (handle->decoder_audp); + TRANSCODE_FREE (handle->encodebin); + TRANSCODE_FREE (handle->property); TRANSCODE_FREE (handle); return ret; @@ -228,61 +252,71 @@ _mm_decode_audio_output_create(handle_s *handle) return MM_ERROR_INVALID_ARGUMENT; } - handle->decaudiobin = gst_bin_new ("audiobin"); - if (!handle->decaudiobin) { + if (!handle->decoder_audp) { + debug_error("[ERROR] - handle decoder audio process bin"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + + handle->decoder_audp->decaudiobin = gst_bin_new ("audiobin"); + if (!handle->decoder_audp->decaudiobin) { debug_error("decaudiobin could not be created"); return MM_ERROR_TRANSCODE_INTERNAL; } - handle->decsinkaudioqueue = gst_element_factory_make("queue","decsinkaudioqueue"); - if (!handle->decsinkaudioqueue) { + handle->decoder_audp->decsinkaudioqueue = gst_element_factory_make("queue","decsinkaudioqueue"); + if (!handle->decoder_audp->decsinkaudioqueue) { debug_error("decsinkaudioqueue could not be created"); return MM_ERROR_TRANSCODE_INTERNAL; } - handle->decaudiosinkpad = gst_element_get_static_pad (handle->decsinkaudioqueue, "sink"); - if (!handle->decaudiosinkpad) { + handle->decoder_audp->decaudiosinkpad = gst_element_get_static_pad (handle->decoder_audp->decsinkaudioqueue, "sink"); + if (!handle->decoder_audp->decaudiosinkpad) { debug_error("decaudiosinkpad could not be created"); return MM_ERROR_TRANSCODE_INTERNAL; } - if(handle->audioencoder == MM_AUDIOENCODER_NO_USE) { + if(handle->property->audioencoder == MM_AUDIOENCODER_NO_USE) { debug_log("[MM_AUDIOENCODER_NO_USE] fakesink create"); - handle->audiofakesink = gst_element_factory_make ("fakesink", "audiofakesink"); - if (!handle->audiofakesink) { + handle->decoder_audp->audiofakesink = gst_element_factory_make ("fakesink", "audiofakesink"); + if (!handle->decoder_audp->audiofakesink) { debug_error("fakesink element could not be created"); return MM_ERROR_TRANSCODE_INTERNAL; } } else { - handle->aconv = gst_element_factory_make ("audioconvert", "aconv"); - if (!handle->aconv) { + handle->decoder_audp->aconv = gst_element_factory_make ("audioconvert", "aconv"); + if (!handle->decoder_audp->aconv) { debug_error("decaudiobin element could not be created"); return MM_ERROR_TRANSCODE_INTERNAL; } - handle->valve = gst_element_factory_make ("valve", "valve"); - if (!handle->valve) { + handle->decoder_audp->valve = gst_element_factory_make ("valve", "valve"); + if (!handle->decoder_audp->valve) { debug_error("decaudiobin element could not be created"); return MM_ERROR_TRANSCODE_INTERNAL; } - g_object_set(handle->valve,"drop", FALSE, NULL); + g_object_set(handle->decoder_audp->valve,"drop", FALSE, NULL); - handle->resample = gst_element_factory_make ("audioresample", "audioresample"); - if (!handle->resample) { + handle->decoder_audp->resample = gst_element_factory_make ("audioresample", "audioresample"); + if (!handle->decoder_audp->resample) { debug_error("decaudiobin element could not be created"); return MM_ERROR_TRANSCODE_INTERNAL; } - handle->audflt = gst_element_factory_make ("capsfilter", "afilter"); - if (!handle->audflt) { + handle->decoder_audp->audflt = gst_element_factory_make ("capsfilter", "afilter"); + if (!handle->decoder_audp->audflt) { debug_error("audflt element could not be created"); return MM_ERROR_TRANSCODE_INTERNAL; } - handle->decaudiosrcpad = gst_element_get_static_pad (handle->audflt, "src"); - if (!handle->decaudiosrcpad) { + handle->decoder_audp->decaudiosrcpad = gst_element_get_static_pad (handle->decoder_audp->audflt, "src"); + if (!handle->decoder_audp->decaudiosrcpad) { debug_error("decaudiosrcpad element could not be created"); return MM_ERROR_TRANSCODE_INTERNAL; } @@ -301,35 +335,45 @@ _mm_decode_audio_output_link(handle_s *handle) return MM_ERROR_INVALID_ARGUMENT; } - if(handle->audioencoder == MM_AUDIOENCODER_NO_USE) { + if (!handle->decoder_audp) { + debug_error("[ERROR] - handle decoder audio process bin"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + + if(handle->property->audioencoder == MM_AUDIOENCODER_NO_USE) { debug_log("[MM_AUDIOENCODER_NO_USE] fakesink pad create"); - gst_bin_add_many (GST_BIN (handle->decaudiobin), handle->decsinkaudioqueue, handle->audiofakesink, NULL); - if(!gst_element_link_many(handle->decsinkaudioqueue, handle->audiofakesink, NULL)) { + gst_bin_add_many (GST_BIN (handle->decoder_audp->decaudiobin), handle->decoder_audp->decsinkaudioqueue, handle->decoder_audp->audiofakesink, NULL); + if(!gst_element_link_many(handle->decoder_audp->decsinkaudioqueue, handle->decoder_audp->audiofakesink, NULL)) { debug_error("[Audio Output Bin] gst_element_link_many failed"); return MM_ERROR_TRANSCODE_INTERNAL; } - gst_element_add_pad (handle->decaudiobin, gst_ghost_pad_new("decbin_audiosink", handle->decaudiosinkpad)); - handle->sinkdecaudiopad = gst_element_get_static_pad (handle->decaudiobin, "decbin_audiosink"); /* get sink audiopad of decodebin */ + gst_element_add_pad (handle->decoder_audp->decaudiobin, gst_ghost_pad_new("decbin_audiosink", handle->decoder_audp->decaudiosinkpad)); + handle->decoder_audp->sinkdecaudiopad = gst_element_get_static_pad (handle->decoder_audp->decaudiobin, "decbin_audiosink"); /* get sink audiopad of decodebin */ } else { - gst_bin_add_many (GST_BIN (handle->decaudiobin), handle->decsinkaudioqueue, handle->valve, handle->aconv, handle->resample, handle->audflt, NULL); - if(!gst_element_link_many(handle->decsinkaudioqueue, handle->valve, handle->aconv, handle->resample, handle->audflt, NULL)) { + 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); + 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)) { debug_error("[Audio Output Bin] gst_element_link_many failed"); return MM_ERROR_TRANSCODE_INTERNAL; } - gst_element_add_pad (handle->decaudiobin, gst_ghost_pad_new("decbin_audiosink", handle->decaudiosinkpad)); - gst_element_add_pad (handle->decaudiobin, gst_ghost_pad_new("decbin_audiosrc", handle->decaudiosrcpad)); + gst_element_add_pad (handle->decoder_audp->decaudiobin, gst_ghost_pad_new("decbin_audiosink", handle->decoder_audp->decaudiosinkpad)); + gst_element_add_pad (handle->decoder_audp->decaudiobin, gst_ghost_pad_new("decbin_audiosrc", handle->decoder_audp->decaudiosrcpad)); - handle->sinkdecaudiopad = gst_element_get_static_pad (handle->decaudiobin, "decbin_audiosink"); /* get sink audiopad of decodebin */ - handle->srcdecaudiopad = gst_element_get_static_pad (handle->decaudiobin, "decbin_audiosrc"); /* get src audiopad of decodebin */ + handle->decoder_audp->sinkdecaudiopad = gst_element_get_static_pad (handle->decoder_audp->decaudiobin, "decbin_audiosink"); /* get sink audiopad of decodebin */ + handle->decoder_audp->srcdecaudiopad = gst_element_get_static_pad (handle->decoder_audp->decaudiobin, "decbin_audiosrc"); /* get src audiopad of decodebin */ - handle->audio_cb_probe_id = gst_pad_add_buffer_probe (handle->sinkdecaudiopad, G_CALLBACK (_mm_cb_audio_output_stream_probe), handle); - debug_log("audio_cb_probe_id: %d", handle->audio_cb_probe_id); /* must use sinkpad (sinkpad => srcpad) for normal resized video buffer*/ + handle->property->audio_cb_probe_id = gst_pad_add_buffer_probe (handle->decoder_audp->sinkdecaudiopad, G_CALLBACK (_mm_cb_audio_output_stream_probe), handle); + debug_log("audio_cb_probe_id: %d", handle->property->audio_cb_probe_id); /* must use sinkpad (sinkpad => srcpad) for normal resized video buffer*/ } - gst_bin_add (GST_BIN (handle->pipeline), handle->decaudiobin); + gst_bin_add (GST_BIN (handle->pipeline), handle->decoder_audp->decaudiobin); return ret; } @@ -343,50 +387,59 @@ _mm_decode_video_output_create(handle_s *handle) return MM_ERROR_INVALID_ARGUMENT; } - handle->decvideobin= gst_bin_new("videobin"); - if (!handle->decvideobin) { + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + + if (!handle->decoder_vidp) { + debug_error("[ERROR] - handle decoder video process bin"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + + handle->decoder_vidp->decvideobin= gst_bin_new("videobin"); + if (!handle->decoder_vidp->decvideobin) { debug_error("decvideobin could not be created. Exiting"); return MM_ERROR_TRANSCODE_INTERNAL; } - handle->decsinkvideoqueue = gst_element_factory_make("queue","decsinkvideoqueue"); - if (!handle->decsinkvideoqueue) { + handle->decoder_vidp->decsinkvideoqueue = gst_element_factory_make("queue","decsinkvideoqueue"); + if (!handle->decoder_vidp->decsinkvideoqueue) { debug_error("decsinkvideoqueue element could not be created. Exiting"); return MM_ERROR_TRANSCODE_INTERNAL; } - handle->decvideosinkpad = gst_element_get_static_pad(handle->decsinkvideoqueue,"sink"); - if (!handle->decvideosinkpad) { + handle->decoder_vidp->decvideosinkpad = gst_element_get_static_pad(handle->decoder_vidp->decsinkvideoqueue,"sink"); + if (!handle->decoder_vidp->decvideosinkpad) { debug_error("decvideosinkpad element could not be created. Exiting"); return MM_ERROR_TRANSCODE_INTERNAL; } - handle->videorate = gst_element_factory_make("videorate", "videorate"); - if (!handle->videorate) { + handle->decoder_vidp->videorate = gst_element_factory_make("videorate", "videorate"); + if (!handle->decoder_vidp->videorate) { debug_error("videorate element could not be created. Exiting"); return MM_ERROR_TRANSCODE_INTERNAL; } - g_object_set (handle->videorate, "drop-only", TRUE,"average-period", GST_SECOND/2, NULL); - g_object_set (handle->videorate, "max-rate", 30, NULL); - g_object_set (handle->videorate, "skip-to-first", TRUE, NULL); + g_object_set (handle->decoder_vidp->videorate, "drop-only", TRUE,"average-period", GST_SECOND/2, NULL); + g_object_set (handle->decoder_vidp->videorate, "max-rate", 30, NULL); - handle->videoscale = gst_element_factory_make("videoscale", "scaler"); - if (!handle->videoscale) { + handle->decoder_vidp->videoscale = gst_element_factory_make("videoscale", "scaler"); + if (!handle->decoder_vidp->videoscale) { debug_error("videoscale element could not be created. Exiting"); return MM_ERROR_TRANSCODE_INTERNAL; } /* Configure videoscale to use 4-tap scaling for higher quality */ - g_object_set (handle->videoscale, "method", 2, NULL); + g_object_set (handle->decoder_vidp->videoscale, "method", 2, NULL); - handle->vidflt = gst_element_factory_make("capsfilter", "vfilter"); - if (!handle->vidflt) { + handle->decoder_vidp->vidflt = gst_element_factory_make("capsfilter", "vfilter"); + if (!handle->decoder_vidp->vidflt) { debug_error("One element could not be created. Exiting"); return MM_ERROR_TRANSCODE_INTERNAL; } - handle->decvideosrcpad = gst_element_get_static_pad(handle->vidflt,"src"); - if (!handle->decvideosrcpad) { + handle->decoder_vidp->decvideosrcpad = gst_element_get_static_pad(handle->decoder_vidp->vidflt,"src"); + if (!handle->decoder_vidp->decvideosrcpad) { debug_error("decvideosrcpad element could not be created. Exiting"); return MM_ERROR_TRANSCODE_INTERNAL; } @@ -404,22 +457,27 @@ _mm_decode_video_output_link(handle_s *handle) return MM_ERROR_INVALID_ARGUMENT; } - gst_bin_add_many(GST_BIN(handle->decvideobin), handle->decsinkvideoqueue, handle->videoscale, handle->videorate, handle->vidflt, NULL); - if(!gst_element_link_many(handle->decsinkvideoqueue, handle->videoscale, handle->videorate, handle->vidflt, NULL)) { + if (!handle->decoder_vidp) { + debug_error("[ERROR] - handle decoder video process bin"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + + 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); + if(!gst_element_link_many(handle->decoder_vidp->decsinkvideoqueue, handle->decoder_vidp->videoscale, handle->decoder_vidp->videorate, handle->decoder_vidp->vidflt, NULL)) { debug_error("[Video Output Bin] gst_element_link_many failed"); return MM_ERROR_TRANSCODE_INTERNAL; } - gst_element_add_pad(handle->decvideobin, gst_ghost_pad_new("decbin_videosink", handle->decvideosinkpad)); - gst_element_add_pad(handle->decvideobin, gst_ghost_pad_new("decbin_videosrc", handle->decvideosrcpad)); + gst_element_add_pad(handle->decoder_vidp->decvideobin, gst_ghost_pad_new("decbin_videosink", handle->decoder_vidp->decvideosinkpad)); + gst_element_add_pad(handle->decoder_vidp->decvideobin, gst_ghost_pad_new("decbin_videosrc", handle->decoder_vidp->decvideosrcpad)); - handle->sinkdecvideopad = gst_element_get_static_pad(handle->decvideobin,"decbin_videosink"); - handle->srcdecvideopad = gst_element_get_static_pad(handle->decvideobin,"decbin_videosrc"); + handle->decoder_vidp->sinkdecvideopad = gst_element_get_static_pad(handle->decoder_vidp->decvideobin,"decbin_videosink"); + handle->decoder_vidp->srcdecvideopad = gst_element_get_static_pad(handle->decoder_vidp->decvideobin,"decbin_videosrc"); - handle->video_cb_probe_id = gst_pad_add_buffer_probe (handle->sinkdecvideopad, G_CALLBACK (_mm_cb_video_output_stream_probe), handle); - debug_log("video_cb_probe_sink_id: %d", handle->video_cb_probe_id); /* must use sinkpad (sinkpad => srcpad) */ + handle->property->video_cb_probe_id = gst_pad_add_buffer_probe (handle->decoder_vidp->sinkdecvideopad, G_CALLBACK (_mm_cb_video_output_stream_probe), handle); + debug_log("video_cb_probe_sink_id: %d", handle->property->video_cb_probe_id); /* must use sinkpad (sinkpad => srcpad) */ - gst_bin_add(GST_BIN(handle->pipeline), handle->decvideobin); + gst_bin_add(GST_BIN(handle->pipeline), handle->decoder_vidp->decvideobin); return ret; } @@ -429,15 +487,15 @@ _mm_decodebin_pipeline_create(handle_s *handle) { int ret = MM_ERROR_NONE; - handle->decbin = gst_element_factory_make ("decodebin2", "decoder"); /* autoplug-select is not worked when decodebin */ + handle->decodebin = gst_element_factory_make ("decodebin2", "decoder"); /* autoplug-select is not worked when decodebin */ - if (!handle->decbin) { + if (!handle->decodebin) { debug_error("decbin element could not be created. Exiting"); return MM_ERROR_TRANSCODE_INTERNAL; } - g_signal_connect (handle->decbin, "new-decoded-pad",G_CALLBACK(_mm_cb_decoder_newpad_encoder), handle); - g_signal_connect (handle->decbin, "autoplug-select", G_CALLBACK(_mm_cb_decode_bin_autoplug_select), handle); + g_signal_connect (handle->decodebin, "new-decoded-pad",G_CALLBACK(_mm_cb_decoder_newpad_encoder), handle); + g_signal_connect (handle->decodebin, "autoplug-select", G_CALLBACK(_mm_cb_decode_bin_autoplug_select), handle); return ret; } @@ -452,6 +510,21 @@ _mm_decodesrcbin_create(handle_s *handle) return MM_ERROR_INVALID_ARGUMENT; } + if (!handle->decoder_vidp) { + debug_error("[ERROR] - handle decoder video process bin"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + + if (!handle->decoder_audp) { + debug_error("[ERROR] - handle decoder audio process bin"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + ret = _mm_filesrc_pipeline_create(handle); if(ret == MM_ERROR_NONE) { debug_log("Success - Create filesrc pipeline"); @@ -460,20 +533,20 @@ _mm_decodesrcbin_create(handle_s *handle) return ret; } - if(handle->has_audio_stream) { + if(handle->property->has_audio_stream) { ret = _mm_decode_audio_output_create(handle); if(ret == MM_ERROR_NONE) { - debug_log("Success - Create audiobin pipeline: 0x%2x",handle->decaudiobin); + debug_log("Success - Create audiobin pipeline: 0x%2x",handle->decoder_audp->decaudiobin); } else{ debug_error("ERROR - Create audiobin pipeline"); return ret; } } - if(handle->has_video_stream) { + if(handle->property->has_video_stream) { ret = _mm_decode_video_output_create(handle); if(ret == MM_ERROR_NONE) { - debug_log("Success - Create videobin pipeline: 0x%2x",handle->decvideobin); + debug_log("Success - Create videobin pipeline: 0x%2x",handle->decoder_vidp->decvideobin); } else{ debug_error("ERROR -Create videobin pipeline"); return ret; @@ -501,6 +574,11 @@ _mm_decodesrcbin_link(handle_s *handle) return MM_ERROR_INVALID_ARGUMENT; } + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + ret=_mm_filesrc_decodebin_link(handle); if(ret == MM_ERROR_NONE) { debug_log("Success - _mm_filesrc_decodebin_link"); @@ -509,7 +587,7 @@ _mm_decodesrcbin_link(handle_s *handle) return ret; } - if(handle->has_audio_stream) { + if(handle->property->has_audio_stream) { ret = _mm_decode_audio_output_link(handle); if(ret == MM_ERROR_NONE) { debug_log("Success - _mm_decode_audio_output_link"); @@ -519,7 +597,7 @@ _mm_decodesrcbin_link(handle_s *handle) } } - if(handle->has_video_stream) { + if(handle->property->has_video_stream) { ret=_mm_decode_video_output_link(handle); if(ret == MM_ERROR_NONE) { debug_log("Success - _mm_decode_video_output_link"); @@ -542,14 +620,24 @@ _mm_encodebin_create(handle_s *handle) return MM_ERROR_INVALID_ARGUMENT; } - handle->encbin = gst_element_factory_make ("encodebin", "encodebin"); + if (!handle->encodebin) { + debug_error("[ERROR] - handle encodebin"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return MM_ERROR_TRANSCODE_INTERNAL; + } - if (!handle->encbin ) { + handle->encodebin->encbin = gst_element_factory_make ("encodebin", "encodebin"); + + if (!handle->encodebin->encbin ) { debug_error("encbin element could not be created"); return MM_ERROR_TRANSCODE_INTERNAL; } - if(handle->videoencoder != MM_VIDEOENCODER_NO_USE && handle->audioencoder != MM_AUDIOENCODER_NO_USE) { + if(handle->property->videoencoder != MM_VIDEOENCODER_NO_USE && handle->property->audioencoder != MM_AUDIOENCODER_NO_USE) { ret = _mm_encodebin_set_video_property(handle); if(ret != MM_ERROR_NONE) { debug_error("ERROR -Setup encodebin video property"); @@ -561,14 +649,14 @@ _mm_encodebin_create(handle_s *handle) debug_error("ERROR -Setup encodebin audio property"); return ret; } - } else if(handle->videoencoder != MM_VIDEOENCODER_NO_USE) { + } else if(handle->property->videoencoder != MM_VIDEOENCODER_NO_USE) { ret = _mm_encodebin_set_video_property(handle); if(ret != MM_ERROR_NONE) { debug_error("ERROR -Setup encodebin video property"); return ret; } - } else if(handle->audioencoder != MM_AUDIOENCODER_NO_USE) { - handle->encodebin_profile = 1; + } else if(handle->property->audioencoder != MM_AUDIOENCODER_NO_USE) { + handle->encodebin->encodebin_profile = 1; debug_log("[AUDIO ONLY ENCODE]"); ret = _mm_encodebin_set_audio_property(handle); if(ret != MM_ERROR_NONE) { @@ -577,7 +665,7 @@ _mm_encodebin_create(handle_s *handle) } } - debug_log("[Encodebin Profile: %d]", handle->encodebin_profile); + debug_log("[Encodebin Profile: %d]", handle->encodebin->encodebin_profile); ret = _mm_encodebin_set_property(handle); if(ret != MM_ERROR_NONE) { debug_error("ERROR -Setup encodebin property"); @@ -597,14 +685,24 @@ _mm_encodebin_link(handle_s *handle) return MM_ERROR_INVALID_ARGUMENT; } + if (!handle->encodebin) { + debug_error("[ERROR] - handle encodebin"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + /* Add encodebin to pipeline */ - gst_bin_add(GST_BIN(handle->pipeline), handle->encbin); + gst_bin_add(GST_BIN(handle->pipeline), handle->encodebin->encbin); - if(handle->has_video_stream) { - if(handle->videoencoder != MM_VIDEOENCODER_NO_USE) { - handle->encvideopad = gst_element_get_request_pad(handle->encbin, "video"); - if(handle->encvideopad) { - debug_log("encvideopad: 0x%2x", handle->encvideopad); + if(handle->property->has_video_stream) { + if(handle->property->videoencoder != MM_VIDEOENCODER_NO_USE) { + handle->encodebin->encvideopad = gst_element_get_request_pad(handle->encodebin->encbin, "video"); + if(handle->encodebin->encvideopad) { + debug_log("encvideopad: 0x%2x", handle->encodebin->encvideopad); } else { debug_error("error encvideopad"); return MM_ERROR_TRANSCODE_INTERNAL; @@ -612,11 +710,11 @@ _mm_encodebin_link(handle_s *handle) } } - if(handle->has_audio_stream) { - if(handle->audioencoder != MM_AUDIOENCODER_NO_USE) { - handle->encaudiopad = gst_element_get_request_pad(handle->encbin, "audio"); - if(handle->encaudiopad) { - debug_log("encaudiopad: 0x%2x", handle->encaudiopad); + if(handle->property->has_audio_stream) { + if(handle->property->audioencoder != MM_AUDIOENCODER_NO_USE) { + handle->encodebin->encaudiopad = gst_element_get_request_pad(handle->encodebin->encbin, "audio"); + if(handle->encodebin->encaudiopad) { + debug_log("encaudiopad: 0x%2x", handle->encodebin->encaudiopad); } else { debug_error("error encaudiopad"); return MM_ERROR_TRANSCODE_INTERNAL; @@ -637,34 +735,44 @@ _mm_encodebin_set_audio_property(handle_s* handle) return MM_ERROR_INVALID_ARGUMENT; } - if(handle->has_audio_stream) { + if (!handle->encodebin) { + debug_error("[ERROR] - handle encodebin"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + + if(handle->property->has_audio_stream) { /* Audio */ - if(g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(handle->encbin)), ARS)) { - g_object_set(G_OBJECT(handle->encbin), ARS, 0, NULL); + if(g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(handle->encodebin->encbin)), ARS)) { + g_object_set(G_OBJECT(handle->encodebin->encbin), ARS, 0, NULL); debug_log("[AUDIO RESAMPLE] encbin set auto-audio-resample"); } else { debug_error("error [AUDIO RESAMPLE] encbin set auto-audio-resample"); return MM_ERROR_TRANSCODE_INTERNAL; } - if(g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(handle->encbin)), ACON)) { - g_object_set(G_OBJECT(handle->encbin), ACON, 1, NULL); + if(g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(handle->encodebin->encbin)), ACON)) { + g_object_set(G_OBJECT(handle->encodebin->encbin), ACON, 1, NULL); debug_log("encbin set auto-audio-convert"); } else { debug_error("error encbin set auto-audio-convert"); return MM_ERROR_TRANSCODE_INTERNAL; } - if(g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(handle->encbin)), AENC)) { - g_object_set(G_OBJECT(handle->encbin), AENC, handle->aenc, NULL); - debug_log("[AUDIOENCODER] encbin set [%s: %s]",AENC, handle->aenc); + if(g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(handle->encodebin->encbin)), AENC)) { + g_object_set(G_OBJECT(handle->encodebin->encbin), AENC, handle->property->aenc, NULL); + debug_log("[AUDIOENCODER] encbin set [%s: %s]",AENC, handle->property->aenc); } else { - debug_error("error [AUDIOENCODER] encbin set [%s: %s]",AENC, handle->aenc); + debug_error("error [AUDIOENCODER] encbin set [%s: %s]",AENC, handle->property->aenc); return MM_ERROR_TRANSCODE_INTERNAL; } - g_object_get(G_OBJECT(handle->encbin), "use-aenc-queue", &(handle->use_aencqueue), NULL); - debug_log("use_aencqueue : %d", handle->use_aencqueue); + g_object_get(G_OBJECT(handle->encodebin->encbin), "use-aenc-queue", &(handle->encodebin->use_aencqueue), NULL); + debug_log("use_aencqueue : %d", handle->encodebin->use_aencqueue); } return ret; @@ -680,19 +788,29 @@ _mm_encodebin_set_property(handle_s *handle) return MM_ERROR_INVALID_ARGUMENT; } - if(g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(handle->encbin)), PROFILE)) { - g_object_set(G_OBJECT(handle->encbin), PROFILE, handle->encodebin_profile, NULL); + if (!handle->encodebin) { + debug_error("[ERROR] - handle encodebin"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + + if(g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(handle->encodebin->encbin)), PROFILE)) { + g_object_set(G_OBJECT(handle->encodebin->encbin), PROFILE, handle->encodebin->encodebin_profile, NULL); debug_log("encbin set profile"); } else { debug_error("error handle->encbin set profile"); return MM_ERROR_TRANSCODE_INTERNAL; } - if(g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(handle->encbin)), MUX)) { - g_object_set(G_OBJECT(handle->encbin), MUX, handle->mux, NULL); - debug_log("[MUX] encbin set [%s: %s]", MUX, handle->mux); + if(g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(handle->encodebin->encbin)), MUX)) { + g_object_set(G_OBJECT(handle->encodebin->encbin), MUX, handle->property->mux, NULL); + debug_log("[MUX] encbin set [%s: %s]", MUX, handle->property->mux); } else { - debug_error("error [MUX] set [%s: %s]", MUX, handle->mux); + debug_error("error [MUX] set [%s: %s]", MUX, handle->property->mux); return MM_ERROR_TRANSCODE_INTERNAL; } @@ -709,26 +827,36 @@ _mm_encodebin_set_video_property(handle_s *handle) return MM_ERROR_INVALID_ARGUMENT; } - if(handle->has_video_stream) { + if (!handle->encodebin) { + debug_error("[ERROR] - handle encodebin"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + + if(handle->property->has_video_stream) { /* Video */ - if(g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(handle->encbin)), ACS)) { - g_object_set(G_OBJECT(handle->encbin), ACS, 0, NULL); + if(g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(handle->encodebin->encbin)), ACS)) { + g_object_set(G_OBJECT(handle->encodebin->encbin), ACS, 0, NULL); debug_log("[AUTO COLORSPACE] encbin set auto-colorspace"); } else { debug_error("error [AUTO COLORSPACE] encbin set auto-colorspace"); return MM_ERROR_TRANSCODE_INTERNAL; } - if(g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(handle->encbin)), VENC)) { - g_object_set(G_OBJECT(handle->encbin), VENC, handle->venc, NULL); - debug_log("[VIDEOENCODER] encbin set [%s: %s]", VENC, handle->venc); + if(g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(handle->encodebin->encbin)), VENC)) { + g_object_set(G_OBJECT(handle->encodebin->encbin), VENC, handle->property->venc, NULL); + debug_log("[VIDEOENCODER] encbin set [%s: %s]", VENC, handle->property->venc); } else { - debug_error("error [VIDEOENCODER] set [%s: %s]", VENC, handle->venc); + debug_error("error [VIDEOENCODER] set [%s: %s]", VENC, handle->property->venc); return MM_ERROR_TRANSCODE_INTERNAL; } - g_object_get(G_OBJECT(handle->encbin), "use-venc-queue", &(handle->use_vencqueue), NULL); - debug_log("vencqueue : %d", handle->use_vencqueue); + g_object_get(G_OBJECT(handle->encodebin->encbin), "use-venc-queue", &(handle->encodebin->use_vencqueue), NULL); + debug_log("vencqueue : %d", handle->encodebin->use_vencqueue); } return ret; @@ -762,11 +890,21 @@ _mm_filesink_link(handle_s *handle) { int ret = MM_ERROR_NONE; + if (!handle) { + debug_error("[ERROR] - handle"); + return MM_ERROR_INVALID_ARGUMENT; + } + + if (!handle->encodebin) { + debug_error("[ERROR] - handle encodebin"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + /* Add encodesinkbin to pipeline */ gst_bin_add(GST_BIN(handle->pipeline), handle->filesink); /* link encodebin and filesink */ - if(!gst_element_link(handle->encbin, handle->filesink)) { + if(!gst_element_link(handle->encodebin->encbin, handle->filesink)) { debug_error("gst_element_link [encbin ! filesink] failed"); return MM_ERROR_TRANSCODE_INTERNAL; } else { @@ -788,8 +926,13 @@ _mm_filesrc_pipeline_create(handle_s *handle) return MM_ERROR_TRANSCODE_INTERNAL; } - debug_log("sourcefile: %s", handle->sourcefile); - g_object_set (G_OBJECT (handle->filesrc), "location", handle->sourcefile, NULL); + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + + debug_log("sourcefile: %s", handle->property->sourcefile); + g_object_set (G_OBJECT (handle->filesrc), "location", handle->property->sourcefile, NULL); return ret; } @@ -805,9 +948,9 @@ _mm_filesrc_decodebin_link(handle_s *handle) } /* Add element(filesrc, decodebin)*/ - gst_bin_add_many(GST_BIN(handle->pipeline), handle->filesrc, handle->decbin, NULL); + gst_bin_add_many(GST_BIN(handle->pipeline), handle->filesrc, handle->decodebin, NULL); - if(!gst_element_link_many(handle->filesrc, handle->decbin, NULL)) { + if(!gst_element_link_many(handle->filesrc, handle->decodebin, NULL)) { debug_error("gst_element_link_many src ! decbin failed"); return MM_ERROR_TRANSCODE_INTERNAL; } @@ -825,9 +968,19 @@ _mm_transcode_preset_capsfilter(handle_s *handle, unsigned int resolution_width, return MM_ERROR_INVALID_ARGUMENT; } - if (handle->vidflt) { + if (!handle->decoder_vidp) { + debug_error("[ERROR] - handle decoder video process bin"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + + if (handle->decoder_vidp->vidflt) { debug_log("[Resolution] Output Width: [%d], Output Height: [%d]", resolution_width, resolution_height); - g_object_set (G_OBJECT (handle->vidflt), "caps", gst_caps_new_simple("video/x-raw-yuv", + g_object_set (G_OBJECT (handle->decoder_vidp->vidflt), "caps", gst_caps_new_simple("video/x-raw-yuv", "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I', '4', '2', '0'), "width", G_TYPE_INT, resolution_width, "height", G_TYPE_INT, resolution_height, diff --git a/transcode/mm_transcode_seek.c b/transcode/mm_transcode_seek.c index 0144f6b..83516c9 100755 --- a/transcode/mm_transcode_seek.c +++ b/transcode/mm_transcode_seek.c @@ -36,10 +36,20 @@ _mm_cb_audio_output_stream_probe(GstPad *pad, GstBuffer *buffer, gpointer user_d { handle_s *handle = (handle_s*) user_data; + if (!handle) { + debug_error("[ERROR] - handle"); + return MM_ERROR_INVALID_ARGUMENT; + } + + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + gint64 start_pos_ts = handle->param->start_pos * G_GINT64_CONSTANT(1000000); if(GST_BUFFER_TIMESTAMP_IS_VALID (buffer)) { - if(0 == handle->AUDFLAG++) { + if(0 == handle->property->AUDFLAG++) { _mm_transcode_audio_capsfilter(gst_buffer_get_caps (buffer), handle); /* Need to audio caps converting when amrnbenc*/ /* Not drop buffer with 'return FALSE'*/ if(handle->param->seeking) { @@ -57,27 +67,37 @@ _mm_cb_decode_bin_autoplug_select(GstElement * element, GstPad * pad, GstCaps * const gchar *feature_name = gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)); const gchar *caps_str = NULL; + if (!handle) { + debug_error("[ERROR] - handle"); + return MM_ERROR_INVALID_ARGUMENT; + } + + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + caps_str = _mm_check_media_type(caps); if(g_strrstr(caps_str, "audio")) { - handle->audiodecodename = (char*)malloc(sizeof(char) * ENC_BUFFER_SIZE); - if(handle->audiodecodename == NULL) { + handle->property->audiodecodename = (char*)malloc(sizeof(char) * ENC_BUFFER_SIZE); + if(handle->property->audiodecodename == NULL) { debug_error("audiodecodename is NULL"); return GST_AUTOPLUG_SELECT_TRY; } - memset(handle->audiodecodename, 0, ENC_BUFFER_SIZE); - strncpy(handle->audiodecodename, feature_name, ENC_BUFFER_SIZE-1); - debug_log ("[audio decode name %s : %s]", caps_str, handle->audiodecodename); + memset(handle->property->audiodecodename, 0, ENC_BUFFER_SIZE); + strncpy(handle->property->audiodecodename, feature_name, ENC_BUFFER_SIZE-1); + debug_log ("[audio decode name %s : %s]", caps_str, handle->property->audiodecodename); } if(g_strrstr(caps_str, "video")) { - handle->videodecodename = (char*)malloc(sizeof(char) * ENC_BUFFER_SIZE); - if(handle->videodecodename == NULL) { + handle->property->videodecodename = (char*)malloc(sizeof(char) * ENC_BUFFER_SIZE); + if(handle->property->videodecodename == NULL) { debug_error("videodecodename is NULL"); return GST_AUTOPLUG_SELECT_TRY; } - memset(handle->videodecodename, 0, ENC_BUFFER_SIZE); - strncpy(handle->videodecodename, feature_name, ENC_BUFFER_SIZE-1); - debug_log ("[video decode name %s : %s]", caps_str, handle->videodecodename); + memset(handle->property->videodecodename, 0, ENC_BUFFER_SIZE); + strncpy(handle->property->videodecodename, feature_name, ENC_BUFFER_SIZE-1); + debug_log ("[video decode name %s : %s]", caps_str, handle->property->videodecodename); } /* Try factory. */ @@ -87,18 +107,48 @@ _mm_cb_decode_bin_autoplug_select(GstElement * element, GstPad * pad, GstCaps * void _mm_cb_decoder_newpad_encoder(GstElement *decodebin, GstPad *pad, gboolean last, handle_s *handle) { + if (!handle) { + debug_error("[ERROR] - handle"); + return; + } + + if (!handle->decoder_vidp) { + debug_error("[ERROR] - handle decoder_vidp"); + return; + } + + if (!handle->decoder_audp) { + debug_error("[ERROR] - handle decoder_audp"); + return; + } + + if (!handle->encodebin) { + debug_error("[ERROR] - handle encodebin"); + return; + } + + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return; + } + debug_log("[============ new-decoded-pad ============]"); - handle->caps = gst_pad_get_caps (pad); - const gchar *mime = _mm_check_media_type(handle->caps); + handle->property->caps = gst_pad_get_caps (pad); + const gchar *mime = _mm_check_media_type(handle->property->caps); + + if(!mime) { + debug_error("[ERROR] - mime"); + return; + } if(g_strrstr(mime,"video")) { - handle->linked_vidoutbin = TRUE; + handle->property->linked_vidoutbin = TRUE; /* link videopad */ if(gst_pad_is_linked(pad)) { debug_log("pad liked"); } else { - if(gst_pad_link(pad, (GstPad *)handle->sinkdecvideopad) != GST_PAD_LINK_OK) { + if(gst_pad_link(pad, (GstPad *)handle->decoder_vidp->sinkdecvideopad) != GST_PAD_LINK_OK) { debug_error("Error [pad - sinkdecvideopad]"); } else { debug_log("Success [pad - sinkdecvideopad]"); @@ -106,13 +156,13 @@ _mm_cb_decoder_newpad_encoder(GstElement *decodebin, GstPad *pad, gboolean last, } } else if(g_strrstr(mime,"audio")) { - handle->linked_audoutbin = TRUE; + handle->property->linked_audoutbin = TRUE; /* link audiopad */ if(gst_pad_is_linked(pad)) { debug_log("pad liked"); } else { - if(gst_pad_link(pad, (GstPad *)handle->sinkdecaudiopad) != GST_PAD_LINK_OK) { + if(gst_pad_link(pad, (GstPad *)handle->decoder_audp->sinkdecaudiopad) != GST_PAD_LINK_OK) { debug_error("Error [pad - sinkdecaudiopad]"); } else { debug_log("Success [pad - sinkdecaudiopad]"); @@ -124,25 +174,25 @@ _mm_cb_decoder_newpad_encoder(GstElement *decodebin, GstPad *pad, gboolean last, } if(last) { - if(0 == handle->seek_idx) { - if(handle->linked_vidoutbin == TRUE) { - if(handle->videoencoder != MM_VIDEOENCODER_NO_USE) { + if(0 == handle->property->seek_idx) { + if(handle->property->linked_vidoutbin == TRUE) { + if(handle->property->videoencoder != MM_VIDEOENCODER_NO_USE) { if(handle->param->seeking) { - _mm_transcode_add_sink(handle, handle->decsinkvideoqueue); + _mm_transcode_add_sink(handle, handle->decoder_vidp->decsinkvideoqueue); } - if(gst_pad_link(handle->srcdecvideopad, handle->encvideopad) != GST_PAD_LINK_OK) { + if(gst_pad_link(handle->decoder_vidp->srcdecvideopad, handle->encodebin->encvideopad) != GST_PAD_LINK_OK) { debug_error("Error [srcdecvideopad - encvideopad]"); } else { debug_log("Success [srcdecvideopad - encvideopad]"); } } } - if(handle->linked_audoutbin == TRUE) { - if(handle->audioencoder != MM_AUDIOENCODER_NO_USE) { + if(handle->property->linked_audoutbin == TRUE) { + if(handle->property->audioencoder != MM_AUDIOENCODER_NO_USE) { if(handle->param->seeking) { - _mm_transcode_add_sink(handle, handle->decsinkaudioqueue); + _mm_transcode_add_sink(handle, handle->decoder_audp->decsinkaudioqueue); } - if(gst_pad_link(handle->srcdecaudiopad, handle->encaudiopad) != GST_PAD_LINK_OK) { + if(gst_pad_link(handle->decoder_audp->srcdecaudiopad, handle->encodebin->encaudiopad) != GST_PAD_LINK_OK) { debug_error("Error [srcdecaudiopad - encaudiopad]"); } else { debug_log("Success [srcdecaudiopad - encaudiopad]"); @@ -159,34 +209,44 @@ _mm_cb_print_position(handle_s *handle) GstFormat fmt = GST_FORMAT_TIME; gint64 pos; - if(!handle->repeat_thread_exit) { /* To avoid gst_element_query_position bs */ + if (!handle) { + debug_error("[ERROR] - handle"); + return FALSE; + } + + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return FALSE; + } + + if(!handle->property->repeat_thread_exit) { /* To avoid gst_element_query_position bs */ if (gst_element_query_position (handle->pipeline, &fmt, &pos)) { unsigned long current_pos =(unsigned long)(GST_TIME_AS_MSECONDS(pos)); if(handle->param->seeking == FALSE) { - handle->current_pos = current_pos; - handle->real_duration= handle->total_length; + handle->property->current_pos = current_pos; + handle->property->real_duration= handle->property->total_length; } else if(handle->param->seeking == TRUE) { - handle->current_pos = current_pos - handle->param->start_pos; + handle->property->current_pos = current_pos - handle->param->start_pos; if(handle->param->duration != 0) { - if(handle->param->start_pos + handle->param->duration > handle->total_length) { - handle->real_duration = handle->total_length - handle->param->start_pos; + if(handle->param->start_pos + handle->param->duration > handle->property->total_length) { + handle->property->real_duration = handle->property->total_length - handle->param->start_pos; } else { - handle->real_duration = handle->param->duration; + handle->property->real_duration = handle->param->duration; } } else if(handle->param->duration == 0) { /* seek to origin file length */ - handle->real_duration = handle->total_length - handle->param->start_pos; + handle->property->real_duration = handle->property->total_length - handle->param->start_pos; } } - if(handle->current_pos <= handle->real_duration) { - if(handle->current_pos == 0 && handle->param->printed > 2) { /* 2 = 1000 / 500 minimum printed cnt for last buffer */ - handle->current_pos = handle->real_duration; + if(handle->property->current_pos <= handle->property->real_duration) { + if(handle->property->current_pos == 0 && handle->param->printed > 2) { /* 2 = 1000 / 500 minimum printed cnt for last buffer */ + handle->property->current_pos = handle->property->real_duration; } - if(handle->progress_cb) { + if(handle->property->progress_cb) { if(0 == handle->param->printed) {/* for first buffer */ - handle->current_pos = 0; + handle->property->current_pos = 0; } - handle->progress_cb(handle->current_pos, handle->real_duration, handle->progress_cb_param); + handle->property->progress_cb(handle->property->current_pos, handle->property->real_duration, handle->property->progress_cb_param); handle->param->printed++; } } @@ -201,10 +261,20 @@ _mm_cb_video_output_stream_probe(GstPad *pad, GstBuffer *buffer, gpointer user_d { handle_s *handle = (handle_s*) user_data; + if (!handle) { + debug_error("[ERROR] - handle"); + return FALSE; + } + + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return FALSE; + } + gint64 start_pos_ts = handle->param->start_pos * G_GINT64_CONSTANT(1000000); if(GST_BUFFER_TIMESTAMP_IS_VALID (buffer)) { - if(0 == handle->VIDFLAG++) { + if(0 == handle->property->VIDFLAG++) { _mm_transcode_video_capsfilter(gst_buffer_get_caps (buffer), handle); /* Not drop buffer with 'return FALSE'*/ if(handle->param->seeking) { @@ -221,6 +291,17 @@ _mm_cb_transcode_bus(GstBus * bus, GstMessage * message, gpointer userdata) { handle_s* handle = (handle_s*) userdata; int ret = MM_ERROR_NONE; + + if (!handle) { + debug_error("[ERROR] - handle"); + return FALSE; + } + + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return FALSE; + } + gint64 total_length; GstFormat fmt = GST_FORMAT_TIME; MMHandleType MMHandle = (MMHandleType) handle; @@ -232,12 +313,21 @@ _mm_cb_transcode_bus(GstBus * bus, GstMessage * message, gpointer userdata) gst_message_parse_error (message, &err, &debug); debug_error("[Source: %s] Error: %s", GST_OBJECT_NAME(GST_OBJECT_CAST(GST_ELEMENT(GST_MESSAGE_SRC (message)))), err->message); + + ret = mm_transcode_cancel(MMHandle); + if(ret == MM_ERROR_NONE) { + debug_log("Success - Cancel Transcode"); + } else{ + debug_error("ERROR - Cancel Transcode"); + return FALSE; + } + if(err) { g_error_free (err); err = NULL; } - TRANSCODE_FREE(debug); + TRANSCODE_FREE(handle->param); /* g_main_loop_quit (handle->loop); */ break; } @@ -276,13 +366,13 @@ _mm_cb_transcode_bus(GstBus * bus, GstMessage * message, gpointer userdata) debug_error("ERROR -Null Pipeline"); return FALSE; } - g_mutex_lock (handle->thread_mutex); + g_mutex_lock (handle->property->thread_mutex); debug_log("[g_mutex_lock]"); TRANSCODE_FREE(handle->param); debug_log("g_free(param)"); - g_cond_signal(handle->thread_cond); + g_cond_signal(handle->property->thread_cond); debug_log("[g_cond_signal]"); - g_mutex_unlock (handle->thread_mutex); + g_mutex_unlock (handle->property->thread_mutex); debug_log("[g_mutex_unlock]"); } } @@ -295,16 +385,16 @@ _mm_cb_transcode_bus(GstBus * bus, GstMessage * message, gpointer userdata) break; } - if(gst_element_query_duration (handle->pipeline, &fmt, &total_length) && handle->total_length == 0) { + if(gst_element_query_duration (handle->pipeline, &fmt, &total_length) && handle->property->total_length == 0) { debug_log("[GST_MESSAGE_ASYNC_DONE] Total Duration: %" GST_TIME_FORMAT " ", GST_TIME_ARGS (total_length)); - handle->total_length = (unsigned long)(GST_TIME_AS_MSECONDS(total_length)); + handle->property->total_length = (unsigned long)(GST_TIME_AS_MSECONDS(total_length)); } handle->param->async_done = TRUE; debug_log("GST_MESSAGE_ASYNC_DONE"); /* Play Transcode */ - debug_log("[Play Trancode] [%d ~ %d]", handle->param->start_pos, handle->end_pos); + debug_log("[Play Trancode] [%d ~ %d]", handle->param->start_pos, handle->property->end_pos); if(_mm_transcode_play (handle) != MM_ERROR_NONE) { debug_error("ERROR - Play Pipeline"); @@ -326,9 +416,9 @@ _mm_cb_transcode_bus(GstBus * bus, GstMessage * message, gpointer userdata) /* end-of-stream */ debug_log("[GST_MESSAGE_EOS] end-of-stream"); - debug_log("[completed] %s (Transcode ID: %d)", handle->param->outputfile, handle->seek_idx++); - handle->AUDFLAG = 0; - handle->VIDFLAG = 0; + debug_log("[completed] %s (Transcode ID: %d)", handle->param->outputfile, handle->property->seek_idx++); + handle->property->AUDFLAG = 0; + handle->property->VIDFLAG = 0; /* Null Transcode */ /* Need to fresh filesink's property*/ debug_log("[Null Trancode]"); @@ -337,28 +427,28 @@ _mm_cb_transcode_bus(GstBus * bus, GstMessage * message, gpointer userdata) return FALSE; } - if((handle->param->start_pos > handle->total_length && handle->total_length != 0 /* checkpoint once more here (eos)*/) && (handle->videoencoder != MM_VIDEOENCODER_NO_USE) /* Not unlink when Audio only */) { + if((handle->param->start_pos > handle->property->total_length && handle->property->total_length != 0 /* checkpoint once more here (eos)*/) && (handle->property->videoencoder != MM_VIDEOENCODER_NO_USE) /* Not unlink when Audio only */) { unlink(handle->param->outputfile); - debug_log("[unlink] %s %d > %d", handle->param->outputfile, handle->param->start_pos, handle->total_length); + debug_log("[unlink] %s %d > %d", handle->param->outputfile, handle->param->start_pos, handle->property->total_length); } - g_mutex_lock (handle->thread_mutex); + g_mutex_lock (handle->property->thread_mutex); g_free(handle->param); debug_log("g_free (param)"); handle->param->completed = TRUE; - handle->is_busy = FALSE; - g_cond_signal(handle->thread_cond); + handle->property->is_busy = FALSE; + g_cond_signal(handle->property->thread_cond); debug_log("===> send completed signal"); - g_mutex_unlock (handle->thread_mutex); + g_mutex_unlock (handle->property->thread_mutex); - debug_log("[MMHandle] 0x%2x [msg_cb] 0x%2x [msg_cb_param] 0x%2x", MMHandle,handle->completed_cb, handle->completed_cb_param); + debug_log("[MMHandle] 0x%2x [msg_cb] 0x%2x [msg_cb_param] 0x%2x", MMHandle,handle->property->completed_cb, handle->property->completed_cb_param); - if(handle->progress_cb) { - handle->progress_cb(handle->real_duration, handle->real_duration, handle->progress_cb_param); + if(handle->property->progress_cb) { + handle->property->progress_cb(handle->property->real_duration, handle->property->real_duration, handle->property->progress_cb_param); } - if(handle->completed_cb) { - handle->completed_cb(MM_ERROR_NONE, handle->completed_cb_param); + if(handle->property->completed_cb) { + handle->property->completed_cb(MM_ERROR_NONE, handle->property->completed_cb_param); } break; @@ -380,8 +470,13 @@ _mm_transcode_add_sink(handle_s *handle , GstElement* sink_elements) return; } + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return; + } + if(sink_elements) { - handle->sink_elements = g_list_append(handle->sink_elements, sink_elements); + handle->property->sink_elements = g_list_append(handle->property->sink_elements, sink_elements); debug_log("g_list_append"); } @@ -395,17 +490,26 @@ _mm_transcode_audio_capsfilter(GstCaps *caps, handle_s *handle) return; } - if(!caps) { + if (!handle->encodebin) { + debug_error("[ERROR] - handle encodebin"); + return; + } + + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return; + } + + if (!caps) { debug_error("[ERROR] - caps"); - TRANSCODE_FREE(handle->audiodecodename); return; } - if(!strcmp(handle->aenc, AMRENC)) { + if(!strcmp(handle->property->aenc, AMRENC)) { caps = gst_caps_new_simple("audio/x-raw-int", "rate", G_TYPE_INT, 8000, "channels", G_TYPE_INT, 1, NULL); - } else if(!strcmp(handle->aenc, AACENC)) { + } else if(!strcmp(handle->property->aenc, AACENC)) { caps = gst_caps_new_simple("audio/x-raw-int", "width", G_TYPE_INT, 16, "depth", G_TYPE_INT, 16, @@ -414,9 +518,9 @@ _mm_transcode_audio_capsfilter(GstCaps *caps, handle_s *handle) gst_caps_set_simple (caps, "bitrate", GST_TYPE_INT_RANGE, 22050, 96000, NULL); debug_log("gst_caps_set_simple"); } - TRANSCODE_FREE(handle->audiodecodename); - g_object_set(G_OBJECT(handle->encbin), ACAPS, caps, NULL); - debug_log("%s audiocaps: %s", handle->aenc, gst_caps_to_string(caps)); + TRANSCODE_FREE(handle->property->audiodecodename); + g_object_set(G_OBJECT(handle->encodebin->encbin), ACAPS, caps, NULL); + debug_log("%s audiocaps: %s", handle->property->aenc, gst_caps_to_string(caps)); } int @@ -475,16 +579,26 @@ _mm_transcode_exec(handle_s *handle, handle_param_s *param) return MM_ERROR_INVALID_ARGUMENT; } - g_mutex_lock (handle->thread_mutex); + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + + g_mutex_lock (handle->property->thread_mutex); - if(handle->repeat_thread_exit) { - g_mutex_unlock (handle->thread_mutex); + if(handle->property->repeat_thread_exit) { + g_mutex_unlock (handle->property->thread_mutex); debug_log("unlock destory"); } else { debug_log("start_pos: %d, duration: %d, seek_mode: %d output file name: %s\n", param->start_pos, param->duration, param->seek_mode, param->outputfile); handle->param = g_new0(handle_param_s, 1); /*g_value_init (handle->param, G_TYPE_INT);*/ + if (!handle->param) { + debug_error("[ERROR] - handle param"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + handle->param->resolution_width = param->resolution_width; handle->param->resolution_height = param->resolution_height; handle->param->fps_value = param->fps_value; @@ -503,14 +617,14 @@ _mm_transcode_exec(handle_s *handle, handle_param_s *param) debug_log("[SEEK: %d] width: %d height: %d fps_value: %d start_pos: %d duration: %d seek_mode: %d outputfile: %s", handle->param->seeking, handle->param->resolution_width, handle->param->resolution_height, handle->param->fps_value, handle->param->start_pos, handle->param->duration, handle->param->seek_mode, handle->param->outputfile); - if(handle->total_length != 0 && handle->param->start_pos > handle->total_length) { - debug_log("[SKIP] [%s] because out of duration [%d < %d ~ %d] ", handle->param->outputfile, handle->total_length, handle->param->start_pos, handle->param->duration); - g_mutex_unlock (handle->thread_mutex); + if(handle->property->total_length != 0 && handle->param->start_pos > handle->property->total_length) { + debug_log("[SKIP] [%s] because out of duration [%d < %d ~ %d] ", handle->param->outputfile, handle->property->total_length, handle->param->start_pos, handle->param->duration); + g_mutex_unlock (handle->property->thread_mutex); debug_log("[thread_mutex unlock]"); } else { g_object_set (G_OBJECT (handle->filesink), "location", handle->param->outputfile, NULL); debug_log("[%s] set filesink location", handle->param->outputfile); - g_object_set (G_OBJECT (handle->filesink), "preroll-queue-len", 0, NULL); + g_object_set (G_OBJECT (handle->filesink), "preroll-queue-len", 2, NULL); /* Ready Transcode */ if(strlen(handle->param->outputfile) !=0) { @@ -520,12 +634,12 @@ _mm_transcode_exec(handle_s *handle, handle_param_s *param) debug_log("Success - Ready pipeline"); } else{ debug_error("ERROR - Reay pipeline"); - g_mutex_unlock (handle->thread_mutex); + g_mutex_unlock (handle->property->thread_mutex); return ret; } } - if(0 == handle->seek_idx) { + if(0 == handle->property->seek_idx) { debug_log("Link Filesink"); /*link filesink */ ret = _mm_filesink_link(handle); @@ -533,14 +647,14 @@ _mm_transcode_exec(handle_s *handle, handle_param_s *param) debug_log("Success - Link Filesink"); } else{ debug_error("ERROR - Link Filesink"); - g_mutex_unlock (handle->thread_mutex); + g_mutex_unlock (handle->property->thread_mutex); return ret; } } - g_cond_wait(handle->thread_cond, handle->thread_mutex); + g_cond_wait(handle->property->thread_cond, handle->property->thread_mutex); debug_log("<=== get completed signal"); - g_mutex_unlock (handle->thread_mutex); + g_mutex_unlock (handle->property->thread_mutex); } } @@ -557,15 +671,20 @@ _mm_transcode_get_stream_info(handle_s *handle) return MM_ERROR_INVALID_ARGUMENT; } - if(strlen (handle->sourcefile) == 0 || strlen (handle->sourcefile) > BUFFER_SIZE) { - debug_error ("Invalid arguments [filename size: %d]\n", strlen (handle->sourcefile)); + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + + if(strlen (handle->property->sourcefile) == 0) { + debug_error ("Invalid arguments [sourcefile size 0]\n"); return MM_ERROR_INVALID_ARGUMENT; } int audio_track_num = 0; int video_track_num = 0; - ret = mm_file_get_stream_info(handle->sourcefile, &audio_track_num, &video_track_num); + ret = mm_file_get_stream_info(handle->property->sourcefile, &audio_track_num, &video_track_num); if(ret == MM_ERROR_NONE) { debug_log("Success - mm_file_get_stream_info"); } else{ @@ -574,20 +693,20 @@ _mm_transcode_get_stream_info(handle_s *handle) } if(audio_track_num) { - handle->has_audio_stream = TRUE; + handle->property->has_audio_stream = TRUE; } else{ - handle->has_audio_stream = FALSE; + handle->property->has_audio_stream = FALSE; } - debug_log ("has_audio_stream: %d", handle->has_audio_stream); + debug_log ("has_audio_stream: %d", handle->property->has_audio_stream); if(video_track_num) { - handle->has_video_stream = TRUE; + handle->property->has_video_stream = TRUE; } else{ - handle->has_video_stream = FALSE; + handle->property->has_video_stream = FALSE; } - debug_log ("has_video_stream: %d", handle->has_video_stream); + debug_log ("has_video_stream: %d", handle->property->has_video_stream); - if((handle->videoencoder != MM_VIDEOENCODER_NO_USE && !handle->has_video_stream) || (handle->audioencoder != MM_AUDIOENCODER_NO_USE && !handle->has_audio_stream)) { + if((handle->property->videoencoder != MM_VIDEOENCODER_NO_USE && !handle->property->has_video_stream) || (handle->property->audioencoder != MM_AUDIOENCODER_NO_USE && !handle->property->has_audio_stream)) { debug_error("No video || audio stream"); return MM_ERROR_INVALID_ARGUMENT; } @@ -632,9 +751,14 @@ _mm_transcode_video_capsfilter(GstCaps *caps, handle_s *handle) return; } + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return; + } + if(!caps) { debug_error("[ERROR] - caps"); - TRANSCODE_FREE(handle->videodecodename); + TRANSCODE_FREE(handle->property->videodecodename); return; } @@ -651,8 +775,8 @@ _mm_transcode_video_capsfilter(GstCaps *caps, handle_s *handle) debug_log("[Resize] resolution_width: %d, resolution_height: %d", handle->param->resolution_width, handle->param->resolution_height); if(0 == handle->param->resolution_width || 0 == handle->param->resolution_height) { debug_log("[Origin Resolution] Two resolutoin value = 0"); - handle->param->resolution_width = handle->in_width; - handle->param->resolution_height = handle->in_height; + handle->param->resolution_width = handle->property->in_width; + handle->param->resolution_height = handle->property->in_height; } if(handle->param->resolution_width < VIDEO_RESOLUTION_WIDTH_SQCIF || handle->param->resolution_height < VIDEO_RESOLUTION_HEIGHT_SQCIF) { @@ -661,29 +785,44 @@ _mm_transcode_video_capsfilter(GstCaps *caps, handle_s *handle) handle->param->resolution_height = VIDEO_RESOLUTION_HEIGHT_SQCIF; } - if(handle->in_width < handle->param->resolution_width || handle->in_height < handle->param->resolution_height) { + if(handle->property->in_width < handle->param->resolution_width || handle->property->in_height < handle->param->resolution_height) { debug_log("[Origin Resolution] resolutoin value > origin resolution"); - handle->param->resolution_width = handle->in_width; - handle->param->resolution_height = handle->in_height; + handle->param->resolution_width = handle->property->in_width; + handle->param->resolution_height = handle->property->in_height; } debug_log("[Call CapsFilter] resolution_width: %d, resolution_height: %d", handle->param->resolution_width, handle->param->resolution_height); _mm_transcode_video_capsfilter_call(handle); - TRANSCODE_FREE(handle->videodecodename); + TRANSCODE_FREE(handle->property->videodecodename); } static void _mm_transcode_video_capsfilter_call(handle_s *handle) { + if (!handle) { + debug_error("[ERROR] - handle"); + return; + } + + if (!handle->decoder_vidp) { + debug_error("[ERROR] - handle decoder video process bin"); + return; + } + + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return; + } + /* Configure videoscale to use 4-tap scaling for higher quality */ - debug_log("Input Width: [%d] Input Hieght: [%d] Output Width: [%d], Output Height: [%d]", handle->in_width, handle->in_height, handle->param->resolution_width, handle->param->resolution_height); + debug_log("Input Width: [%d] Input Hieght: [%d] Output Width: [%d], Output Height: [%d]", handle->property->in_width, handle->property->in_height, handle->param->resolution_width, handle->param->resolution_height); - g_object_set (G_OBJECT (handle->vidflt), "caps", gst_caps_new_simple(handle->mime, - "format", GST_TYPE_FOURCC, handle->fourcc, + g_object_set (G_OBJECT (handle->decoder_vidp->vidflt), "caps", gst_caps_new_simple(handle->property->mime, + "format", GST_TYPE_FOURCC, handle->property->fourcc, "width", G_TYPE_INT, handle->param->resolution_width, "height", G_TYPE_INT, handle->param->resolution_height, - "framerate", GST_TYPE_FRACTION, handle->fps_n, handle->fps_d, - "pixel-aspect-ratio", GST_TYPE_FRACTION, handle->aspect_x, handle->aspect_y, + "framerate", GST_TYPE_FRACTION, handle->property->fps_n, handle->property->fps_d, + "pixel-aspect-ratio", GST_TYPE_FRACTION, handle->property->aspect_x, handle->property->aspect_y, NULL), NULL); } @@ -697,6 +836,11 @@ _mm_transcode_video_capsfilter_set_parameter(GstCaps *caps, handle_s *handle) return; } + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return; + } + if(!caps) { debug_error("[ERROR] - caps"); return; @@ -704,50 +848,50 @@ _mm_transcode_video_capsfilter_set_parameter(GstCaps *caps, handle_s *handle) debug_log("caps: %s", gst_caps_to_string(caps)); GstStructure *_str = gst_caps_get_structure (caps, 0); - handle->mime = _mm_check_media_type(caps); - debug_log("mime: %s", handle->mime); + handle->property->mime = _mm_check_media_type(caps); + debug_log("mime: %s", handle->property->mime); - gst_structure_get_fourcc (_str, "format", &handle->fourcc); - if (GST_MAKE_FOURCC ('I', '4', '2', '0') == handle->fourcc) { + gst_structure_get_fourcc (_str, "format", &handle->property->fourcc); + if (GST_MAKE_FOURCC ('I', '4', '2', '0') == handle->property->fourcc) { debug_log("GST_MAKE_FOURCC ('I', '4', '2', '0')"); - } else if(GST_MAKE_FOURCC ('R', 'G', 'B',' ') == handle->fourcc) { + } else if(GST_MAKE_FOURCC ('R', 'G', 'B',' ') == handle->property->fourcc) { debug_log("GST_MAKE_FOURCC ('R', 'G', 'B', ' ')"); - } else if(GST_MAKE_FOURCC ('S', 'N', '1', '2') == handle->fourcc) { + } else if(GST_MAKE_FOURCC ('S', 'N', '1', '2') == handle->property->fourcc) { debug_log("GST_MAKE_FOURCC ('S', 'N', '1', '2')"); - } else if(GST_MAKE_FOURCC ('S', 'T', '1', '2') == handle->fourcc) { + } else if(GST_MAKE_FOURCC ('S', 'T', '1', '2') == handle->property->fourcc) { debug_log("GST_MAKE_FOURCC ('S', 'T', '1', '2')"); - } else if(GST_MAKE_FOURCC ('N', 'V', '1', '2') == handle->fourcc) { + } else if(GST_MAKE_FOURCC ('N', 'V', '1', '2') == handle->property->fourcc) { debug_log("GST_MAKE_FOURCC ('N', 'V', '1', '2')"); } - if(!gst_structure_get_int(_str, "width", &handle->in_width) || !gst_structure_get_int(_str, "height", &handle->in_height)) { + if(!gst_structure_get_int(_str, "width", &handle->property->in_width) || !gst_structure_get_int(_str, "height", &handle->property->in_height)) { debug_error("error gst_structure_get_int [width] [height]"); } else { - debug_log("Origin File's Width: [%u] Origin File's Hieght: [%u]", handle->in_width, handle->in_height); + debug_log("Origin File's Width: [%u] Origin File's Hieght: [%u]", handle->property->in_width, handle->property->in_height); } fps = gst_structure_get_value (_str, "framerate"); if (fps) { - handle->fps_n = gst_value_get_fraction_numerator (fps); - handle->fps_d = gst_value_get_fraction_denominator (fps); - debug_log("[Origin framerate] gst_value_get_fraction_numerator: %d, gst_value_get_fraction_denominator: %d", handle->fps_n, handle->fps_d); + handle->property->fps_n = gst_value_get_fraction_numerator (fps); + handle->property->fps_d = gst_value_get_fraction_denominator (fps); + debug_log("[Origin framerate] gst_value_get_fraction_numerator: %d, gst_value_get_fraction_denominator: %d", handle->property->fps_n, handle->property->fps_d); } - if(handle->param->fps_value>= 5 && handle->param->fps_value <= 30 && handle->param->fps_value <= handle->fps_n) { - handle->fps_n = (gint) handle->param->fps_value; - handle->fps_d = 1; + if(handle->param->fps_value>= 5 && handle->param->fps_value <= 30 && handle->param->fps_value <= handle->property->fps_n) { + handle->property->fps_n = (gint) handle->param->fps_value; + handle->property->fps_d = 1; } - debug_log("[framerate] gst_value_get_fraction_numerator: %d, gst_value_get_fraction_denominator: %d", handle->fps_n, handle->fps_d); + debug_log("[framerate] gst_value_get_fraction_numerator: %d, gst_value_get_fraction_denominator: %d", handle->property->fps_n, handle->property->fps_d); par = gst_structure_get_value (_str, "pixel-aspect-ratio"); if (par) { - handle->aspect_x= gst_value_get_fraction_numerator (par); - handle->aspect_y = gst_value_get_fraction_denominator (par); + handle->property->aspect_x= gst_value_get_fraction_numerator (par); + handle->property->aspect_y = gst_value_get_fraction_denominator (par); } else { - handle->aspect_x = handle->aspect_y = 1; + handle->property->aspect_x = handle->property->aspect_y = 1; } - debug_log("[pixel-aspect-ratio] gst_value_get_fraction_numerator: %d, gst_value_get_fraction_denominator: %d", handle->aspect_x, handle->aspect_y); + debug_log("[pixel-aspect-ratio] gst_value_get_fraction_numerator: %d, gst_value_get_fraction_denominator: %d", handle->property->aspect_x, handle->property->aspect_y); } @@ -762,6 +906,11 @@ _mm_transcode_set_handle_element(handle_s *handle, const char * in_Filename, mm_ return MM_ERROR_INVALID_ARGUMENT; } + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + if(in_Filename == NULL) { debug_error ("Invalid arguments [filename null]\n"); return MM_ERROR_INVALID_ARGUMENT; @@ -772,15 +921,15 @@ _mm_transcode_set_handle_element(handle_s *handle, const char * in_Filename, mm_ return MM_ERROR_INVALID_ARGUMENT; } - memset(handle->sourcefile, 0, BUFFER_SIZE); - strncpy(handle->sourcefile, in_Filename, strlen (in_Filename)); - debug_log("%s(%d)", handle->sourcefile, strlen (in_Filename)); + memset(handle->property->sourcefile, 0, BUFFER_SIZE); + strncpy(handle->property->sourcefile, in_Filename, strlen (in_Filename)); + debug_log("%s(%d)", handle->property->sourcefile, strlen (in_Filename)); - handle->containerformat = containerformat; - handle->videoencoder = videoencoder; - handle->audioencoder = audioencoder; + handle->property->containerformat = containerformat; + handle->property->videoencoder = videoencoder; + handle->property->audioencoder = audioencoder; - debug_log("container format: %d videoencoder:%d, audioencoder: %d", handle->containerformat, handle->videoencoder, handle->audioencoder); + debug_log("container format: %d videoencoder:%d, audioencoder: %d", handle->property->containerformat, handle->property->videoencoder, handle->property->audioencoder); return ret; } @@ -900,19 +1049,29 @@ _mm_transcode_param_flush(handle_s *handle) return MM_ERROR_INVALID_ARGUMENT; } - handle->linked_vidoutbin = FALSE; - handle->linked_audoutbin = FALSE; - handle->encodebin_profile = 0; - handle->AUDFLAG = 0; - handle->VIDFLAG = 0; + if (!handle->encodebin) { + debug_error("[ERROR] - handle encodebin"); + return MM_ERROR_TRANSCODE_INTERNAL; + } - handle->total_length = 0; - handle->repeat_thread_exit = FALSE; - handle->is_busy = FALSE; - handle->audio_cb_probe_id= 0; - handle->video_cb_probe_id= 0; - handle->progrss_event_id= 0; - handle->seek_idx = 0; + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + + handle->property->linked_vidoutbin = FALSE; + handle->property->linked_audoutbin = FALSE; + handle->encodebin->encodebin_profile = 0; + handle->property->AUDFLAG = 0; + handle->property->VIDFLAG = 0; + + handle->property->total_length = 0; + handle->property->repeat_thread_exit = FALSE; + handle->property->is_busy = FALSE; + handle->property->audio_cb_probe_id= 0; + handle->property->video_cb_probe_id= 0; + handle->property->progrss_event_id= 0; + handle->property->seek_idx = 0; return ret; } @@ -927,6 +1086,11 @@ _mm_transcode_play(handle_s *handle) return MM_ERROR_INVALID_ARGUMENT; } + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + ret = _mm_transcode_state_change(handle, GST_STATE_PLAYING); if(ret != MM_ERROR_NONE) { debug_error("ERROR -Playing Pipeline"); @@ -934,10 +1098,10 @@ _mm_transcode_play(handle_s *handle) } debug_log("[SEEK: %d] width: %d height: %d start_pos: %d duration: %d (%d) seek_mode: %d outputfile: %s",handle->param->seeking, handle->param->resolution_width, - handle->param->resolution_height, handle->param->start_pos, handle->param->duration, handle->end_pos, handle->param->seek_mode, handle->param->outputfile); + handle->param->resolution_height, handle->param->start_pos, handle->param->duration, handle->property->end_pos, handle->param->seek_mode, handle->param->outputfile); - handle->progrss_event_id = g_timeout_add (LAZY_PAUSE_TIMEOUT_MSEC, (GSourceFunc) _mm_cb_print_position, handle); - debug_log ("Timer (id=[%d], timeout=[%d ms])\n", handle->progrss_event_id, LAZY_PAUSE_TIMEOUT_MSEC); + handle->property->progrss_event_id = g_timeout_add (LAZY_PAUSE_TIMEOUT_MSEC, (GSourceFunc) _mm_cb_print_position, handle); + debug_log ("Timer (id=[%d], timeout=[%d ms])\n", handle->property->progrss_event_id, LAZY_PAUSE_TIMEOUT_MSEC); return ret; } @@ -952,25 +1116,30 @@ _mm_transcode_seek(handle_s *handle) return MM_ERROR_INVALID_ARGUMENT; } - GList *walk_element = handle->sink_elements; + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + + GList *walk_element = handle->property->sink_elements; gint64 start_pos, end_pos; gdouble rate = 1.0; GstSeekFlags _Flags = GST_SEEK_FLAG_NONE; start_pos = handle->param->start_pos * G_GINT64_CONSTANT(1000000); - handle->end_pos = handle->param->start_pos + handle->param->duration; + handle->property->end_pos = handle->param->start_pos + handle->param->duration; - if(handle->param->start_pos > handle->total_length && handle->seek_idx) { - debug_error("[%d ~ %d] out of %d", handle->param->start_pos, handle->end_pos, handle->total_length); + if(handle->param->start_pos > handle->property->total_length && handle->property->seek_idx) { + debug_error("[%d ~ %d] out of %d", handle->param->start_pos, handle->property->end_pos, handle->property->total_length); return MM_ERROR_TRANSCODE_SEEK_FAILED; } else { if(handle->param->duration != 0) { end_pos = start_pos + handle->param->duration * G_GINT64_CONSTANT(1000000); } else if(handle->param->duration == 0) { /* seek to origin file length */ - end_pos = handle->total_length * G_GINT64_CONSTANT(1000000); + end_pos = handle->property->total_length * G_GINT64_CONSTANT(1000000); } - debug_log("seek time : [ (%d msec) : (%d msec) ]\n", handle->param->start_pos, handle->end_pos); + debug_log("seek time : [ (%d msec) : (%d msec) ]\n", handle->param->start_pos, handle->property->end_pos); while (walk_element) { GstElement *seekable_element = GST_ELEMENT (walk_element->data); @@ -1010,43 +1179,48 @@ _mm_transcode_thread(handle_s *handle) return MM_ERROR_INVALID_ARGUMENT; } - if(!handle->thread_mutex) { - handle->thread_mutex = g_mutex_new(); - debug_log("create thread_mutex: 0x%2x", handle->thread_mutex); + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return MM_ERROR_TRANSCODE_INTERNAL; + } + + if(!handle->property->thread_mutex) { + handle->property->thread_mutex = g_mutex_new(); + debug_log("create thread_mutex: 0x%2x", handle->property->thread_mutex); } else { debug_error("ERROR - thread_mutex is already created"); } - if(!handle->thread_exit_mutex) { - handle->thread_exit_mutex = g_mutex_new(); - debug_log("create exit mutex: 0x%2x", handle->thread_exit_mutex); + if(!handle->property->thread_exit_mutex) { + handle->property->thread_exit_mutex = g_mutex_new(); + debug_log("create exit mutex: 0x%2x", handle->property->thread_exit_mutex); } else { debug_error("ERROR - thread_exit_mutex is already created"); } /*These are a communicator for thread*/ - if(!handle->queue) { - handle->queue = g_async_queue_new(); - debug_log("create async queue: 0x%2x", handle->queue); + if(!handle->property->queue) { + handle->property->queue = g_async_queue_new(); + debug_log("create async queue: 0x%2x", handle->property->queue); } else { debug_error("ERROR - async queue is already created"); } - if(!handle->thread_cond) { - handle->thread_cond = g_cond_new(); - debug_log("create thread cond: 0x%2x", handle->thread_cond); + if(!handle->property->thread_cond) { + handle->property->thread_cond = g_cond_new(); + debug_log("create thread cond: 0x%2x", handle->property->thread_cond); } else { debug_error("thread cond is already created"); } /*create threads*/ debug_log("create thread"); - handle->thread = g_thread_create ((GThreadFunc)_mm_transcode_thread_repeate, (gpointer)handle, TRUE, NULL); - if(!handle->thread) { + handle->property->thread = g_thread_create ((GThreadFunc)_mm_transcode_thread_repeate, (gpointer)handle, TRUE, NULL); + if(!handle->property->thread) { debug_error("ERROR - create thread"); return MM_ERROR_TRANSCODE_INTERNAL; } else { - debug_log("create thread: 0x%2x", handle->thread); + debug_log("create thread: 0x%2x", handle->property->thread); } return ret; @@ -1063,16 +1237,21 @@ _mm_transcode_thread_repeate(gpointer data) return NULL; } + if (!handle->property) { + debug_error("[ERROR] - handle property"); + return NULL; + } + while (1) { /* thread while */ - int length = g_async_queue_length(handle->queue); + int length = g_async_queue_length(handle->property->queue); if(length) { debug_log("[QUEUE #] %d", length); - handle->is_busy = TRUE; + handle->property->is_busy = TRUE; } - handle_param_s *pop_data = (handle_param_s *) g_async_queue_pop(handle->queue); + handle_param_s *pop_data = (handle_param_s *) g_async_queue_pop(handle->property->queue); - if(handle->repeat_thread_exit) { + if(handle->property->repeat_thread_exit || !handle->property->is_busy) { debug_log("[Receive Last Queue]"); debug_log("[Destroy]"); break; @@ -1090,7 +1269,7 @@ _mm_transcode_thread_repeate(gpointer data) debug_log("Success - transcode_exec"); } else{ debug_log("Destroy - transcode_exec"); - debug_log("<=== get exit (%d) signal", handle->repeat_thread_exit); + debug_log("<=== get exit (%d) signal", handle->property->repeat_thread_exit); break; } }