Added wav support to mediamuxer 19/52719/3
authorMahesh Kondiparthi <kd.mahesh@samsung.com>
Thu, 26 Nov 2015 06:53:57 +0000 (12:23 +0530)
committerMahesh Kondiparthi <kd.mahesh@samsung.com>
Thu, 26 Nov 2015 08:02:50 +0000 (13:32 +0530)
Updated the testsuite to add demux_wav functionality.
Applied coding rules by running the tool
Addressed review comments

Change-Id: I7d01f56725338122237f986995697a960d871158
Signed-off-by: Mahesh Kondiparthi <kd.mahesh@samsung.com>
include/mediamuxer.h
src/mediamuxer.c
src/port_gst/mediamuxer_port_gst.c
test/mediamuxer_test.c
test/mediamuxer_test_gst.c

index ee447a5..a8c09a7 100755 (executable)
@@ -79,8 +79,9 @@ typedef enum {
  * @since_tizen 3.0
  */
 typedef enum {
-       MEDIAMUXER_CONTAINER_FORMAT_MP4 = MEDIA_FORMAT_CONTAINER_MP4,       /**< The mediamuxer output format is MP4 container */
-       MEDIAMUXER_CONTAINER_FORMAT_3GP = MEDIA_FORMAT_CONTAINER_3GP       /**< The mediamuxer output format is 3GP container */
+       MEDIAMUXER_CONTAINER_FORMAT_MP4 = MEDIA_FORMAT_CONTAINER_MP4,   /**< The mediamuxer output format is MP4 container */
+       MEDIAMUXER_CONTAINER_FORMAT_3GP = MEDIA_FORMAT_CONTAINER_3GP,   /**< The mediamuxer output format is 3GP container */
+       MEDIAMUXER_CONTAINER_FORMAT_WAV = MEDIA_FORMAT_CONTAINER_WAV    /**< The mediamuxer output format is WAV container */
 } mediamuxer_output_format_e;
 
 /**
index af787cd..3568674 100644 (file)
@@ -84,7 +84,8 @@ int mediamuxer_set_data_sink(mediamuxer_h muxer, char *path, mediamuxer_output_f
        }
 
        if (format != MEDIAMUXER_CONTAINER_FORMAT_MP4
-               && format != MEDIAMUXER_CONTAINER_FORMAT_3GP) {
+               && format != MEDIAMUXER_CONTAINER_FORMAT_3GP
+               && format != MEDIAMUXER_CONTAINER_FORMAT_WAV) {
                MX_E("Unsupported Container format: %d \n", format);
                return MEDIAMUXER_ERROR_INVALID_PARAMETER;
        }
index 504edb5..3d280c1 100644 (file)
@@ -192,7 +192,9 @@ static int gst_muxer_add_track(MMHandleType pHandle,
                                && (mimetype == MEDIA_FORMAT_AAC_LC || mimetype == MEDIA_FORMAT_AAC_HE || mimetype == MEDIA_FORMAT_AAC_HE_PS))
                        || (mx_handle_gst->muxed_format == MEDIAMUXER_CONTAINER_FORMAT_3GP
                                && (mimetype == MEDIA_FORMAT_AAC_LC || mimetype == MEDIA_FORMAT_AAC_HE || mimetype == MEDIA_FORMAT_AAC_HE_PS
-                               || mimetype == MEDIA_FORMAT_AMR_NB))) {
+                               || mimetype == MEDIA_FORMAT_AMR_NB))
+                       || (mx_handle_gst->muxed_format == MEDIAMUXER_CONTAINER_FORMAT_WAV
+                               && (mimetype == MEDIA_FORMAT_PCM))) {
 
                        current->track_index = 1 + NO_OF_TRACK_TYPES*(mx_handle_gst->track_info.audio_track_cnt);
                        (mx_handle_gst->track_info.audio_track_cnt)++;
@@ -414,8 +416,9 @@ mx_ret_e _gst_create_pipeline(mxgst_handle_t *gst_handle)
        gst_handle->sink = gst_element_factory_make("filesink", "muxer filesink");
 
        if (gst_handle->muxed_format != MEDIAMUXER_CONTAINER_FORMAT_MP4
-               && gst_handle->muxed_format !=MEDIAMUXER_CONTAINER_FORMAT_3GP) {
-               MX_E("Unsupported format. Currently supports only MP4 & 3GP");
+               && gst_handle->muxed_format != MEDIAMUXER_CONTAINER_FORMAT_3GP
+               && gst_handle->muxed_format != MEDIAMUXER_CONTAINER_FORMAT_WAV) {
+               MX_E("Unsupported format. Currently supports only MP4, 3GP & WAV");
                ret = MEDIAMUXER_ERROR_INVALID_PATH;
                goto ERROR;
        } else {
@@ -426,6 +429,8 @@ mx_ret_e _gst_create_pipeline(mxgst_handle_t *gst_handle)
                        gst_handle->muxer = gst_element_factory_make("3gppmux", "3gppmux");
                        /* gst_handle->muxer = gst_element_factory_make("avmux_3gp", "avmux_3gp");*/
                        /* gst_handle->muxer = gst_element_factory_make("qtmux", "qtmux"); */
+               else if (gst_handle->muxed_format == MEDIAMUXER_CONTAINER_FORMAT_WAV)
+                       gst_handle->muxer = gst_element_factory_make("wavenc", "wavenc");
 
                if ((!gst_handle->pipeline) || (!gst_handle->muxer) || (!gst_handle->sink)) {
                        MX_E("One element could not be created. Exiting.\n");
@@ -471,7 +476,7 @@ mx_ret_e _gst_create_pipeline(mxgst_handle_t *gst_handle)
 
 #ifdef ASYCHRONOUS_WRITE
                                        /* ToDo: Use a function pointer, and create independent fucntions to each track */
-                                       MX_I("\nRegistering video callback for cur->tr_ind = %d\n",current->track_index);
+                                       MX_I("\nRegistering video callback for cur->tr_ind = %d\n", current->track_index);
                                        g_signal_connect(current->appsrc, "need-data",
                                                G_CALLBACK(_video_start_feed), current);
                                        g_signal_connect(current->appsrc, "enough-data",
@@ -513,23 +518,33 @@ mx_ret_e _gst_create_pipeline(mxgst_handle_t *gst_handle)
                                                        current->parser = gst_element_factory_make("aacparse", str_parser);
                                                else if (mimetype == MEDIA_FORMAT_AMR_NB)
                                                        current->parser = gst_element_factory_make("amrparse", str_parser);
+                                               else if (mimetype == MEDIA_FORMAT_PCM)
+                                                       MX_I("Do Nothing, as there is no need of parser for wav\n");
                                        } else {
                                                MX_E("Can't retrive mimetype for the current track. Unsupported MIME Type. Proceeding to the next track\n");
                                        }
 
-                                       if (!current->appsrc || !current->parser) {
-                                               MX_E("One element (audio_appsrc/aparse) could not be created. Exiting.\n");
+                                       if (!current->appsrc) {
+                                               MX_E("One element (audio_appsrc) could not be created. Exiting.\n");
                                                ret = MEDIAMUXER_ERROR_RESOURCE_LIMIT;
                                                goto ERROR;
                                        }
 
-                                       gst_bin_add_many(GST_BIN(gst_handle->pipeline), current->appsrc, current->parser, NULL);
+                                       gst_bin_add_many(GST_BIN(gst_handle->pipeline), current->appsrc, NULL);
+                                       if (mimetype != MEDIA_FORMAT_PCM) {
+                                               if (!current->parser) {
+                                                       MX_E("One element (audio-parser) could not be created. Exiting.\n");
+                                                       ret = MEDIAMUXER_ERROR_RESOURCE_LIMIT;
+                                                       goto ERROR;
+                                               }
+                                               gst_bin_add_many(GST_BIN(gst_handle->pipeline), current->parser, NULL);
+                                       }
                                        /* Set video caps for corresponding src elements */
                                        g_object_set(current->appsrc, "caps", gst_caps_from_string(current->caps), NULL);
 
 #ifdef ASYCHRONOUS_WRITE
                                        /* ToDo: Use a function pointer, and create independent fucntions to each track */
-                                       MX_I("\nRegistering audio callback for cur->tr_ind = %d\n",current->track_index);
+                                       MX_I("\nRegistering audio callback for cur->tr_ind = %d\n", current->track_index);
                                        g_signal_connect(current->appsrc, "need-data",
                                                G_CALLBACK(_audio_start_feed), current);
                                        g_signal_connect(current->appsrc, "enough-data",
@@ -539,19 +554,22 @@ mx_ret_e _gst_create_pipeline(mxgst_handle_t *gst_handle)
                                        gst_app_src_set_stream_type((GstAppSrc *)current->appsrc,
                                                GST_APP_STREAM_TYPE_STREAM);
 #endif
+                                       if (gst_handle->muxed_format == MEDIAMUXER_CONTAINER_FORMAT_WAV) {      /* wavenc is muxer */
+                                               gst_element_link(current->appsrc, gst_handle->muxer);
+                                       } else {
+                                               gst_element_link(current->appsrc, current->parser);
+                                               /* Link videoparse to muxer_video_pad.   Request for muxer A/V pads. */
+                                               sprintf(track_no, "audio_%.2d", aud_track_cnt++);  /* sprintf(track_no,"audio_00"); */
 
-                                       gst_element_link(current->appsrc, current->parser);
-                                       /* Link videoparse to muxer_video_pad.   Request for muxer A/V pads. */
-                                       sprintf(track_no, "audio_%.2d", aud_track_cnt++);  /* sprintf(track_no,"audio_00"); */
-
-                                       audio_pad = gst_element_get_request_pad(gst_handle->muxer, track_no);
-                                       aud_src = gst_element_get_static_pad(current->parser, "src");
+                                               audio_pad = gst_element_get_request_pad(gst_handle->muxer, track_no);
+                                               aud_src = gst_element_get_static_pad(current->parser, "src");
 
-                                       if (gst_pad_link(aud_src, audio_pad) != GST_PAD_LINK_OK)
-                                               MX_E("audio parser to muxer link failed");
+                                               if (gst_pad_link(aud_src, audio_pad) != GST_PAD_LINK_OK)
+                                                       MX_E("audio parser to muxer link failed");
 
-                                       gst_object_unref(GST_OBJECT(aud_src));
-                                       gst_object_unref(GST_OBJECT(audio_pad));
+                                               gst_object_unref(GST_OBJECT(aud_src));
+                                               gst_object_unref(GST_OBJECT(audio_pad));
+                                       }
                                }
                        }
                }
@@ -1124,8 +1142,10 @@ static int gst_muxer_close_track(MMHandleType pHandle, int track_index)
                if (current->track_index == track_index)
                        break;
 
-       if (!current || current->track_index != track_index)
+       if (!current || current->track_index != track_index) {
+               (!current) ? MX_E("Current is Null") : MX_E("Mismatched between track index[%d]\n", track_index);
                goto ERROR;
+       }
 
        MX_I("__gst_muxer_stop setting eos to sources:%p\n", gst_handle);
        if (gst_handle->pipeline != NULL) {
index 77bf053..da6440c 100644 (file)
@@ -94,6 +94,7 @@ int track_index_aud;
 int track_index_aud2;
 
 int demux_mp4();
+int demux_wav();
 void mediacodec_process_all(void);
 void input_raw_filepath(char *filename);
 void mediacodec_config_set_codec(int codecid, int flag);
@@ -138,11 +139,13 @@ int test_mediamuxer_set_data_sink()
        } else if (strncmp(data_sink, "3", 1) == 0 || strncmp(data_sink, "4", 1) == 0) {
                op_uri = "MuxTest.3gp";
                ret = mediamuxer_set_data_sink(myMuxer, op_uri, MEDIAMUXER_CONTAINER_FORMAT_3GP);
+       } else if (strncmp(data_sink, "5", 1) == 0 || strncmp(data_sink, "wav", 3) == 0) {
+               op_uri = "MuxTest.wav";
+               ret = mediamuxer_set_data_sink(myMuxer, op_uri, MEDIAMUXER_CONTAINER_FORMAT_WAV);
        }
 
-       if (ret != MEDIAMUXER_ERROR_NONE) {
+       if (ret != MEDIAMUXER_ERROR_NONE)
                g_print("mediamuxer_set_data_sink is failed\n");
-       }
        return ret;
 }
 
@@ -170,6 +173,9 @@ int test_mediamuxer_add_track_video()
        } else if (strncmp(data_sink, "4", 1) == 0) {
                if (media_format_set_video_mime(media_format, MEDIA_FORMAT_H263) == MEDIA_FORMAT_ERROR_INVALID_OPERATION)
                        g_print("Problem during media_format_set_audio_mime operation\n");
+       } else if (strncmp(data_sink, "5", 1) == 0) {
+               g_print("Add video track is invalid for wav\n");
+               return 1;
        }
 
        if (validate_with_codec) {
@@ -216,8 +222,12 @@ int test_mediamuxer_add_track_audio()
        } else if (strncmp(data_sink, "4", 1) == 0) {
                if (media_format_set_audio_mime(media_format_a, MEDIA_FORMAT_AMR_NB) == MEDIA_FORMAT_ERROR_INVALID_OPERATION)
                        g_print("Problem during media_format_set_audio_mime operation\n");
+       } else if (strncmp(data_sink, "5", 1) == 0) {
+               if (media_format_set_audio_mime(media_format_a, MEDIA_FORMAT_PCM) == MEDIA_FORMAT_ERROR_INVALID_OPERATION)
+                       g_print("Problem during media_format_set_audio_mime operation\n");
        }
 
+
        if (validate_with_codec) {
                if (media_format_set_audio_channel(media_format_a, channel) == MEDIA_FORMAT_ERROR_INVALID_OPERATION)
                        g_print("Problem during media_format_set_audio_channel operation\n");
@@ -271,6 +281,8 @@ int test_mediamuxer_write_sample()
        if (validate_with_codec) {
                /* Test muxer with codec */
                mediacodec_process_all();
+       } else if (strncmp(data_sink, "5", 1) == 0 || strncmp(data_sink, "wav", 3)) {
+               demux_wav();
        } else {
                demux_mp4();
        }
@@ -445,7 +457,7 @@ static void displaymenu(void)
                }
        } else if (g_menu_state == CURRENT_STATUS_DATA_SINK) {
                g_print("*** input the datasink container format:\n");
-               g_print("(1) mp4 \n(2) 3gp (h264 + AAC) \n(3) 3gp (h263 + AAC) \n(4) 3gp (h263 + AMR) \n");
+               g_print("(1) mp4 \n(2) 3gp (h264 + AAC) \n(3) 3gp (h263 + AAC) \n(4) 3gp (h263 + AMR) \n(5) wav\n");
        } else if (g_menu_state == CURRENT_STATUS_RAW_VIDEO_FILENAME) {
                g_print("*** input raw video file name");
        } else if (g_menu_state == CURRENT_STATUS_SET_VENC_INFO) {
index dfe22d5..6fc9cf0 100644 (file)
@@ -117,6 +117,17 @@ static void __audio_app_sink_callback(GstElement *sink, CustomData *data)
                                        g_print("media_format_set_audio_mime failed\n");
                                        return;
                                }
+                       } else if (g_str_has_prefix(new_pad_type_aud, "audio/x-wav")) { g_print("creating audio-wav\n");
+                               if (media_format_set_audio_mime(audfmt, MEDIA_FORMAT_PCM)) {
+                                       g_print("media_format_set_audio_mime failed\n");
+                                       return;
+                               }
+                               if (media_format_set_audio_bit(audfmt, 16))
+                                       g_print("wav media_format_set_audio_bit failed");
+                               if (media_format_set_audio_channel(audfmt, 2))
+                                       g_print("wav media_format_set_audio_channel failed");
+                               if (media_format_set_audio_samplerate(audfmt, 44100))
+                                       g_print("wav media_format_set_audio_samplerate failed");
                        }
 
                        if (media_packet_create(audfmt, NULL, NULL, &aud_pkt)) {
@@ -143,6 +154,12 @@ static void __audio_app_sink_callback(GstElement *sink, CustomData *data)
                                return;
                        }
 
+                       if (strncmp(data_sink, "5", 1) == 0 || strncmp(data_sink, "wav", 3) == 0) {
+                               aud_caps = "audio/x-raw, format=(string)S16LE, layout=(string)interleaved, channels=(int)2, channel-mask=(bitmask)0x0000000000000003, rate=(int)44100";
+                               /* no need to set the rest of the parameters for wav */
+                               goto SET_CAPS;
+                       }
+
                        if (media_packet_set_pts(aud_pkt, buffer->pts)) {
                                g_print("unable to set the pts\n");
                                return;
@@ -163,8 +180,9 @@ static void __audio_app_sink_callback(GstElement *sink, CustomData *data)
                                return;
                        }
 
+SET_CAPS:
                        if (media_packet_set_extra(aud_pkt, aud_caps)) {
-                               g_print("unable to set the audio codec data e\n");
+                               g_print("unable to set the audio codec data \n");
                                return;
                        }
 
@@ -417,6 +435,79 @@ static gboolean __bus_call(GstBus *bus, GstMessage *mesg, gpointer data)
        return TRUE;
 }
 
+
+/* Demux wav file and generate raw data */
+int demux_wav()
+{
+       CustomData data;
+       GMainLoop *loop_dmx;
+       GstBus *bus;
+       guint watch_id_for_bus;
+
+       g_print("Start of _demux_wav()\n");
+
+       if (access(file_mp4, F_OK) == -1) {
+               /* wav file doesn't exist */
+               g_print("Invalid wav file path.");
+               return -1;
+       }
+
+       gst_init(NULL, NULL);
+       loop_dmx = g_main_loop_new(NULL, FALSE);
+       data.loop = loop_dmx;
+       new_pad_type_aud = "audio/x-wav"; /* Update to aid cb. */
+       /* Create gstreamer elements for demuxer*/
+       data.pipeline = gst_pipeline_new("DemuxerPipeline");
+       data.source = gst_element_factory_make("filesrc", "file-source");
+       data.demuxer = gst_element_factory_make("wavparse", "wavparse");
+       data.audioqueue = gst_element_factory_make("queue", "audio-queue");
+       data.audio_appsink = gst_element_factory_make("appsink", "encoded_audio_appsink");
+
+       if (!data.pipeline || !data.source || !data.demuxer || !data.audioqueue || !data.audio_appsink) {
+               g_print("Test-Suite: One gst-element can't be created. Exiting\n");
+               return -1;
+       }
+
+       /* Add msg-handler */
+       bus = gst_pipeline_get_bus(GST_PIPELINE(data.pipeline));
+       watch_id_for_bus = gst_bus_add_watch(bus, __bus_call, loop_dmx);
+       gst_object_unref(bus);
+
+       /* Add gstreamer-elements into gst-pipeline */
+       gst_bin_add_many(GST_BIN(data.pipeline), data.source, data.demuxer, data.audioqueue, data.audio_appsink, NULL);
+
+       /* we set the input filename to the source element */
+       g_object_set(G_OBJECT(data.source), "location", file_mp4, NULL);
+
+       /* we link the elements together */
+       if (!gst_element_link_many(data.source, data.demuxer, data.audioqueue, data.audio_appsink, NULL)) {
+               g_print("Demuxer pipeline link failed");
+               return -1;
+       }
+
+       g_object_set(data.audio_appsink, "emit-signals", TRUE, NULL);
+       g_signal_connect(data.audio_appsink, "new-sample", G_CALLBACK(__audio_app_sink_callback), &data);
+       g_signal_connect(data.audio_appsink, "eos", G_CALLBACK(__audio_app_sink_eos_callback), &data);
+
+       /* No demuxer callback for wav, playing the pipeline*/
+       g_print("Now playing: %s\n", file_mp4);
+       gst_element_set_state(data.pipeline, GST_STATE_PLAYING);
+
+       /* Run the loop till quit */
+       g_print("gst-wav-pipeline - Running...\n");
+       g_main_loop_run(loop_dmx);
+
+       /* Done with gst-loop. Free resources */
+       gst_element_set_state(data.pipeline, GST_STATE_NULL);
+
+       g_print("gst-wav-pipeline - Unreferencing...\n");
+       gst_object_unref(GST_OBJECT(data.pipeline));
+       g_source_remove(watch_id_for_bus);
+       g_main_loop_unref(loop_dmx);
+       g_print("End of demux_wav()\n");
+       return 0;
+}
+
 /* Demux an mp4 file and generate encoded streams and extra data  */
 int demux_mp4()
 {