I am writing an application to convert a .ogg file to an .mp4 file. My
code is below. I already have the terminal pipeline for completing this task, and I am just trying to convert the terminal pipeline into an actual c program. The pipeline seems correct to be, but when I run the application I get an error "Internal data stream error". Does anyone have any suggestions as to what is wrong with my code? Thank you in advance. #include<gst\gst.h> #include<glib-2.0\glib.h> #include<string.h> #include"Encode_File_Test.h" #include"Preprocessor_Defines.h" /* Handle messages from the pipeline bus */ static gboolean bus_call(GstBus *bus, GstMessage *msg, gpointer data) { GMainLoop *loop = (GMainLoop * ) data; switch(GST_MESSAGE_TYPE(msg)) { case GST_MESSAGE_EOS: g_print("End of stream\n"); g_main_loop_quit(loop); break; case GST_MESSAGE_ERROR: { gchar *debug; GError *error; gst_message_parse_error(msg, &error, &debug); g_free(debug); g_printerr ("Error: %s\n", error->message); g_error_free(error); g_main_loop_quit(loop); break; } default: break; } return TRUE; } /* Handles when a pad is added to the demuxer */ static void on_pad_added(GstElement *element, GstPad *pad, gpointer data) { guint result; GstPad *sinkpad; gchar* name; name = gst_pad_get_name(pad); result = g_strcasecmp(name, "serial_1fa82364"); /* This is the audio pad of the demuxer we need to link it to the decoder's audio output in the queue */ if(!result) { /* We can now link this pad with the audio decoder's sink pad */ g_print("Dynamic pad created, linking the demuxer to the audio decoder\n"); sinkpad = gst_element_get_pad(audio_queue, "sink"); gst_pad_link(pad, sinkpad); gst_object_unref(sinkpad); } result = g_strcasecmp(name, "serial_0f0678e1"); /* This is the video pad of the demuxer we need to link it to the decoder's video output in the queue */ if(!result) { /* We can now link this pad with the video decoder's sink pad */ g_print("Dynamic pad created, linking the demuxer to the video decoder\n"); sinkpad = gst_element_get_static_pad(video_queue, "sink"); gst_pad_link(pad, sinkpad); gst_object_unref(sinkpad); } } /* Connects the src pad of the audio out queue to the audio sink pad of the mxuer */ static void link_audio_to_multiplexer(GstElement *audio_output, GstElement *muxer) { GstPad *pad, *link_pad; link_pad = gst_element_get_static_pad(audio_output, "src"); pad = gst_element_get_request_pad(muxer, "audio_%d"); gst_pad_link(link_pad, pad); gst_object_unref(pad); } /* Connects the src pad of the video out queue to the video sink pad of the muxer */ static void link_video_to_multiplexer(GstElement *video_output, GstElement *muxer) { GstPad *pad, *link_pad; link_pad = gst_element_get_static_pad(video_output, "src"); pad = gst_element_get_request_pad(muxer, "video_%d"); gst_pad_link(link_pad, pad); gst_object_unref(pad); } int main (int argc, char *argv[]) { gst_init(&argc, &argv); loop = g_main_loop_new(NULL, FALSE); /* Create elements */ pipeline = gst_pipeline_new("audio-player"); /* Element for reading in a file */ source = gst_element_factory_make("filesrc", "file-source"); /* OGG elements */ oggdemuxer = gst_element_factory_make("oggdemux", "ogg-demuxer"); vorbis_decoder = gst_element_factory_make("vorbisdec", "vorbis-decoder"); theora_decoder = gst_element_factory_make("theoradec", "theora-decoder"); /* MP4 elements */ audio_encoder = gst_element_factory_make("faac", "aac-encoder"); video_encoder = gst_element_factory_make("ffenc_mpeg4", "avc-encoder"); mp4_muxer = gst_element_factory_make("qtmux", "mp4-muxer"); /* Audio Video elements */ audio_converter = gst_element_factory_make("audioconvert", "audio-converter"); video_converter = gst_element_factory_make("ffmpegcolorspace", "video-converter"); audio_resample = gst_element_factory_make("audioresample", "audio-resample"); audio_rate = gst_element_factory_make("audiorate", "audio-rate"); videosink = gst_element_factory_make("autovideosink", "video-sink"); audiosink = gst_element_factory_make("autoaudiosink", "audio-sink"); /* Queues */ video_queue = gst_element_factory_make("queue", "video-queue"); audio_queue = gst_element_factory_make("queue", "audio-queue"); video_out_queue = gst_element_factory_make("queue", "video-out-queue"); audio_out_queue = gst_element_factory_make("queue", "audio-out-queue"); /* Element to write to the file */ filesink = gst_element_factory_make("filesink", "file-sink"); /* Make sure we were able to create all of the elements*/ if(!pipeline || !source || !oggdemuxer || !vorbis_decoder || !theora_decoder || !audio_encoder || !video_encoder || !mp4_muxer || !audio_converter || !video_converter || !audio_resample || !audio_rate || !videosink || !audiosink || !video_queue || !audio_queue || !video_out_queue || !audio_out_queue || !filesink ) { g_printerr("One ore more elements could not be created. Exiting.\n"); return -1; } /* Input file */ g_object_set(G_OBJECT(source), "location", "c:\\video.ogg", NULL); g_object_set(G_OBJECT(filesink), "location", "c:\\video(encoded from ogg).mp4", NULL); /* Add a message handler from pipeline bus */ bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline)); gst_bus_add_watch(bus, bus_call, loop); gst_object_unref(bus); /* add elements to the pipeline */ gst_bin_add_many(GST_BIN(pipeline), source, oggdemuxer, video_queue, theora_decoder, video_converter, video_encoder, video_out_queue, audio_queue, vorbis_decoder, audio_converter, audio_encoder, audio_out_queue, mp4_muxer, filesink, NULL); /* link the elements together */ gst_element_link(source, oggdemuxer); /* video_queue -> theoradec -> ffmpegcolorspace -> ffenc_mpeg4 -> video_out_queue ~> qtmux */ res = gst_element_link_many(video_queue, theora_decoder, video_converter, video_encoder, video_out_queue, NULL); if(!res) { g_printerr("There was a problem linking video elements.\n"); return 1; } /* queue_audio -> vorbisdec -> audioconvert -> faac -> audio_out_queue ~> qtmux */ res = gst_element_link_many(audio_queue, vorbis_decoder, audio_converter, audio_encoder, audio_out_queue, NULL); if(!res) { g_printerr("There was a problem linking elements.\n"); return 1; } g_signal_connect(oggdemuxer, "pad-added", G_CALLBACK(on_pad_added), NULL); /* qtmux -> filesink */ res = gst_element_link(mp4_muxer, filesink); link_video_to_multiplexer(video_out_queue, mp4_muxer); link_audio_to_multiplexer(audio_out_queue, mp4_muxer); /* Set the pipeline stat to play and start the main loop*/ g_print("Starting the pipeline\n"); gst_element_set_state(pipeline, GST_STATE_PLAYING); g_main_loop_run(loop); /* We are done now, do a little bit of cleaning up */ g_print("Stopping the pipeline.\n"); gst_element_set_state(pipeline, GST_STATE_NULL); gst_object_unref(GST_OBJECT(pipeline)); return 0; } _______________________________________________ gstreamer-devel mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Am 03.06.2011 23:41, schrieb William Metcalf:
> I am writing an application to convert a .ogg file to an .mp4 file. My code is > below. I already have the terminal pipeline for completing this task, and I am > just trying to convert the terminal pipeline into an actual c program. The > pipeline seems correct to be, but when I run the application I get an error > "Internal data stream error". Does anyone have any suggestions as to what is > wrong with my code? Thank you in advance. Have a look at the debug log. You could also add a: GST_DEBUG_BIN_TO_DOT_FILE(pipeline, GST_DEBUG_GRAPH_SHOW_ALL, "myconverter") to the GST_MESSAGE_ERROR handler below and run your app using GST_DEBUG_DUMP_DOT_DIR=c:\\ myconverter This should get you a pipeline graph in dot formant, taht you can render to svg/png/.. using graphviz dot tool. There you can e.g. see easily between which elements pads are not negotiated, not linked, etc. Stefan > > #include<gst\gst.h> > #include<glib-2.0\glib.h> > #include<string.h> > #include"Encode_File_Test.h" > #include"Preprocessor_Defines.h" > > /* Handle messages from the pipeline bus */ > static gboolean bus_call(GstBus *bus, GstMessage *msg, gpointer data) > { > GMainLoop *loop = (GMainLoop * ) data; > > switch(GST_MESSAGE_TYPE(msg)) > { > case GST_MESSAGE_EOS: > g_print("End of stream\n"); > g_main_loop_quit(loop); > break; > case GST_MESSAGE_ERROR: > { > gchar *debug; > GError *error; > > gst_message_parse_error(msg, &error, &debug); > g_free(debug); > > g_printerr ("Error: %s\n", error->message); > g_error_free(error); > > g_main_loop_quit(loop); > break; > } > default: > break; > } > > return TRUE; > } > > /* Handles when a pad is added to the demuxer */ > static void on_pad_added(GstElement *element, GstPad *pad, gpointer data) > { > guint result; > GstPad *sinkpad; > gchar* name; > name = gst_pad_get_name(pad); > > result = g_strcasecmp(name, "serial_1fa82364"); > /* This is the audio pad of the demuxer we need to link it to the decoder's > audio output in the queue */ > if(!result) > { > /* We can now link this pad with the audio decoder's sink pad */ > g_print("Dynamic pad created, linking the demuxer to the audio decoder\n"); > > sinkpad = gst_element_get_pad(audio_queue, "sink"); > > gst_pad_link(pad, sinkpad); > > gst_object_unref(sinkpad); > } > > result = g_strcasecmp(name, "serial_0f0678e1"); > /* This is the video pad of the demuxer we need to link it to the decoder's > video output in the queue */ > if(!result) > { > > /* We can now link this pad with the video decoder's sink pad */ > g_print("Dynamic pad created, linking the demuxer to the video decoder\n"); > > sinkpad = gst_element_get_static_pad(video_queue, "sink"); > > gst_pad_link(pad, sinkpad); > > gst_object_unref(sinkpad); > } > } > > /* Connects the src pad of the audio out queue to the audio sink pad of the > mxuer */ > static void link_audio_to_multiplexer(GstElement *audio_output, GstElement *muxer) > { > GstPad *pad, *link_pad; > > link_pad = gst_element_get_static_pad(audio_output, "src"); > > pad = gst_element_get_request_pad(muxer, "audio_%d"); > > gst_pad_link(link_pad, pad); > > gst_object_unref(pad); > } > > /* Connects the src pad of the video out queue to the video sink pad of the > muxer */ > static void link_video_to_multiplexer(GstElement *video_output, GstElement *muxer) > { > GstPad *pad, *link_pad; > > link_pad = gst_element_get_static_pad(video_output, "src"); > > pad = gst_element_get_request_pad(muxer, "video_%d"); > > gst_pad_link(link_pad, pad); > > gst_object_unref(pad); > } > > int main (int argc, char *argv[]) > { > gst_init(&argc, &argv); > > loop = g_main_loop_new(NULL, FALSE); > > /* Create elements */ > pipeline = gst_pipeline_new("audio-player"); > > /* Element for reading in a file */ > source = gst_element_factory_make("filesrc", "file-source"); > > /* OGG elements */ > oggdemuxer = gst_element_factory_make("oggdemux", "ogg-demuxer"); > vorbis_decoder = gst_element_factory_make("vorbisdec", > "vorbis-decoder"); > theora_decoder = gst_element_factory_make("theoradec", > "theora-decoder"); > > /* MP4 elements */ > audio_encoder = gst_element_factory_make("faac", "aac-encoder"); > video_encoder = gst_element_factory_make("ffenc_mpeg4", "avc-encoder"); > mp4_muxer = gst_element_factory_make("qtmux", "mp4-muxer"); > > /* Audio Video elements */ > audio_converter = gst_element_factory_make("audioconvert", > "audio-converter"); > video_converter = gst_element_factory_make("ffmpegcolorspace", > "video-converter"); > audio_resample = gst_element_factory_make("audioresample", > "audio-resample"); > audio_rate = gst_element_factory_make("audiorate", "audio-rate"); > videosink = gst_element_factory_make("autovideosink", "video-sink"); > audiosink = gst_element_factory_make("autoaudiosink", "audio-sink"); > > /* Queues */ > video_queue = gst_element_factory_make("queue", "video-queue"); > audio_queue = gst_element_factory_make("queue", "audio-queue"); > video_out_queue = gst_element_factory_make("queue", "video-out-queue"); > audio_out_queue = gst_element_factory_make("queue", "audio-out-queue"); > > /* Element to write to the file */ > filesink = gst_element_factory_make("filesink", "file-sink"); > > /* Make sure we were able to create all of the elements*/ > if(!pipeline || !source || !oggdemuxer || !vorbis_decoder || !theora_decoder > || !audio_encoder || !video_encoder || !mp4_muxer || !audio_converter || > !video_converter || !audio_resample || !audio_rate || !videosink || !audiosink > || !video_queue || !audio_queue || !video_out_queue || !audio_out_queue || > !filesink ) > { > g_printerr("One ore more elements could not be created. Exiting.\n"); > return -1; > } > > /* Input file */ > g_object_set(G_OBJECT(source), "location", "c:\\video.ogg", NULL); > g_object_set(G_OBJECT(filesink), "location", "c:\\video(encoded from > ogg).mp4", NULL); > > /* Add a message handler from pipeline bus */ > bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline)); > gst_bus_add_watch(bus, bus_call, loop); > gst_object_unref(bus); > > /* add elements to the pipeline */ > gst_bin_add_many(GST_BIN(pipeline), source, oggdemuxer, video_queue, > theora_decoder, video_converter, video_encoder, video_out_queue, audio_queue, > vorbis_decoder, audio_converter, audio_encoder, audio_out_queue, mp4_muxer, > filesink, NULL); > > /* link the elements together */ > gst_element_link(source, oggdemuxer); > > /* video_queue -> theoradec -> ffmpegcolorspace -> ffenc_mpeg4 -> > video_out_queue ~> qtmux */ > res = gst_element_link_many(video_queue, theora_decoder, video_converter, > video_encoder, video_out_queue, NULL); > if(!res) > { > g_printerr("There was a problem linking video elements.\n"); > return 1; > } > > /* queue_audio -> vorbisdec -> audioconvert -> faac -> audio_out_queue ~> > qtmux */ > res = gst_element_link_many(audio_queue, vorbis_decoder, audio_converter, > audio_encoder, audio_out_queue, NULL); > if(!res) > { > g_printerr("There was a problem linking elements.\n"); > return 1; > } > g_signal_connect(oggdemuxer, "pad-added", G_CALLBACK(on_pad_added), NULL); > > /* qtmux -> filesink */ > res = gst_element_link(mp4_muxer, filesink); > > link_video_to_multiplexer(video_out_queue, mp4_muxer); > link_audio_to_multiplexer(audio_out_queue, mp4_muxer); > > > /* Set the pipeline stat to play and start the main loop*/ > g_print("Starting the pipeline\n"); > gst_element_set_state(pipeline, GST_STATE_PLAYING); > g_main_loop_run(loop); > > /* We are done now, do a little bit of cleaning up */ > g_print("Stopping the pipeline.\n"); > gst_element_set_state(pipeline, GST_STATE_NULL); > gst_object_unref(GST_OBJECT(pipeline)); > > return 0; > } > _______________________________________________ > gstreamer-devel mailing list > [hidden email] > http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel _______________________________________________ gstreamer-devel mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
In reply to this post by william.l.metcalf
Hi William,
When I am trying to debug this cases. - I try and simplify the pipeline as much as possible. - I would eliminate the audio or video channel and drop this to a fakesink. - confirm on_pad_added() being called? - I specifically link all items myself instead of using gst_element_link_many() to confirm each step. And log in between. - Looking at debug is also very useful, but sometimes overwhelming the first look. Cheers, Matt On Fri, Jun 3, 2011 at 1:41 PM, William Metcalf <[hidden email]> wrote: > I am writing an application to convert a .ogg file to an .mp4 file. My code > is below. I already have the terminal pipeline for completing this task, > and I am just trying to convert the terminal pipeline into an actual c > program. The pipeline seems correct to be, but when I run the application I > get an error "Internal data stream error". Does anyone have any suggestions > as to what is wrong with my code? Thank you in advance. > > #include<gst\gst.h> > #include<glib-2.0\glib.h> > #include<string.h> > #include"Encode_File_Test.h" > #include"Preprocessor_Defines.h" > > /* Handle messages from the pipeline bus */ > static gboolean bus_call(GstBus *bus, GstMessage *msg, gpointer data) > { > GMainLoop *loop = (GMainLoop * ) data; > > switch(GST_MESSAGE_TYPE(msg)) > { > case GST_MESSAGE_EOS: > g_print("End of stream\n"); > g_main_loop_quit(loop); > break; > case GST_MESSAGE_ERROR: > { > gchar *debug; > GError *error; > > gst_message_parse_error(msg, &error, &debug); > g_free(debug); > > g_printerr ("Error: %s\n", error->message); > g_error_free(error); > > g_main_loop_quit(loop); > break; > } > default: > break; > } > > return TRUE; > } > > /* Handles when a pad is added to the demuxer */ > static void on_pad_added(GstElement *element, GstPad *pad, gpointer data) > { > guint result; > GstPad *sinkpad; > gchar* name; > name = gst_pad_get_name(pad); > > result = g_strcasecmp(name, "serial_1fa82364"); > /* This is the audio pad of the demuxer we need to link it to the > decoder's audio output in the queue */ > if(!result) > { > /* We can now link this pad with the audio decoder's sink pad */ > g_print("Dynamic pad created, linking the demuxer to the audio > decoder\n"); > > sinkpad = gst_element_get_pad(audio_queue, "sink"); > > gst_pad_link(pad, sinkpad); > > gst_object_unref(sinkpad); > } > > result = g_strcasecmp(name, "serial_0f0678e1"); > /* This is the video pad of the demuxer we need to link it to the > decoder's video output in the queue */ > if(!result) > { > > /* We can now link this pad with the video decoder's sink pad */ > g_print("Dynamic pad created, linking the demuxer to the video > decoder\n"); > > sinkpad = gst_element_get_static_pad(video_queue, "sink"); > > gst_pad_link(pad, sinkpad); > > gst_object_unref(sinkpad); > } > } > > /* Connects the src pad of the audio out queue to the audio sink pad of the > mxuer */ > static void link_audio_to_multiplexer(GstElement *audio_output, GstElement > *muxer) > { > GstPad *pad, *link_pad; > > link_pad = gst_element_get_static_pad(audio_output, "src"); > > pad = gst_element_get_request_pad(muxer, "audio_%d"); > > gst_pad_link(link_pad, pad); > > gst_object_unref(pad); > } > > /* Connects the src pad of the video out queue to the video sink pad of the > muxer */ > static void link_video_to_multiplexer(GstElement *video_output, GstElement > *muxer) > { > GstPad *pad, *link_pad; > > link_pad = gst_element_get_static_pad(video_output, "src"); > > pad = gst_element_get_request_pad(muxer, "video_%d"); > > gst_pad_link(link_pad, pad); > > gst_object_unref(pad); > } > > int main (int argc, char *argv[]) > { > gst_init(&argc, &argv); > > loop = g_main_loop_new(NULL, FALSE); > > /* Create elements */ > pipeline = gst_pipeline_new("audio-player"); > > /* Element for reading in a file */ > source = gst_element_factory_make("filesrc", > "file-source"); > > /* OGG elements */ > oggdemuxer = gst_element_factory_make("oggdemux", > "ogg-demuxer"); > vorbis_decoder = gst_element_factory_make("vorbisdec", > "vorbis-decoder"); > theora_decoder = gst_element_factory_make("theoradec", > "theora-decoder"); > > /* MP4 elements */ > audio_encoder = gst_element_factory_make("faac", "aac-encoder"); > video_encoder = gst_element_factory_make("ffenc_mpeg4", > "avc-encoder"); > mp4_muxer = gst_element_factory_make("qtmux", "mp4-muxer"); > > /* Audio Video elements */ > audio_converter = gst_element_factory_make("audioconvert", > "audio-converter"); > video_converter = gst_element_factory_make("ffmpegcolorspace", > "video-converter"); > audio_resample = gst_element_factory_make("audioresample", > "audio-resample"); > audio_rate = gst_element_factory_make("audiorate", > "audio-rate"); > videosink = gst_element_factory_make("autovideosink", > "video-sink"); > audiosink = gst_element_factory_make("autoaudiosink", > "audio-sink"); > > /* Queues */ > video_queue = gst_element_factory_make("queue", > "video-queue"); > audio_queue = gst_element_factory_make("queue", > "audio-queue"); > video_out_queue = gst_element_factory_make("queue", > "video-out-queue"); > audio_out_queue = gst_element_factory_make("queue", > "audio-out-queue"); > > /* Element to write to the file */ > filesink = gst_element_factory_make("filesink", > "file-sink"); > > /* Make sure we were able to create all of the elements*/ > if(!pipeline || !source || !oggdemuxer || !vorbis_decoder || > !theora_decoder || !audio_encoder || !video_encoder || !mp4_muxer || > !audio_converter || !video_converter || !audio_resample || !audio_rate || > !videosink || !audiosink || !video_queue || !audio_queue || !video_out_queue > || !audio_out_queue || !filesink ) > { > g_printerr("One ore more elements could not be created. Exiting.\n"); > return -1; > } > > /* Input file */ > g_object_set(G_OBJECT(source), "location", "c:\\video.ogg", NULL); > g_object_set(G_OBJECT(filesink), "location", "c:\\video(encoded from > ogg).mp4", NULL); > > /* Add a message handler from pipeline bus */ > bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline)); > gst_bus_add_watch(bus, bus_call, loop); > gst_object_unref(bus); > > /* add elements to the pipeline */ > gst_bin_add_many(GST_BIN(pipeline), source, oggdemuxer, video_queue, > theora_decoder, video_converter, video_encoder, video_out_queue, > audio_queue, vorbis_decoder, audio_converter, audio_encoder, > audio_out_queue, mp4_muxer, filesink, NULL); > > /* link the elements together */ > gst_element_link(source, oggdemuxer); > > /* video_queue -> theoradec -> ffmpegcolorspace -> ffenc_mpeg4 -> > video_out_queue ~> qtmux */ > res = gst_element_link_many(video_queue, theora_decoder, video_converter, > video_encoder, video_out_queue, NULL); > if(!res) > { > g_printerr("There was a problem linking video elements.\n"); > return 1; > } > > /* queue_audio -> vorbisdec -> audioconvert -> faac -> audio_out_queue ~> > qtmux */ > res = gst_element_link_many(audio_queue, vorbis_decoder, audio_converter, > audio_encoder, audio_out_queue, NULL); > if(!res) > { > g_printerr("There was a problem linking elements.\n"); > return 1; > } > g_signal_connect(oggdemuxer, "pad-added", G_CALLBACK(on_pad_added), > NULL); > > /* qtmux -> filesink */ > res = gst_element_link(mp4_muxer, filesink); > > link_video_to_multiplexer(video_out_queue, mp4_muxer); > link_audio_to_multiplexer(audio_out_queue, mp4_muxer); > > > /* Set the pipeline stat to play and start the main loop*/ > g_print("Starting the pipeline\n"); > gst_element_set_state(pipeline, GST_STATE_PLAYING); > g_main_loop_run(loop); > > /* We are done now, do a little bit of cleaning up */ > g_print("Stopping the pipeline.\n"); > gst_element_set_state(pipeline, GST_STATE_NULL); > gst_object_unref(GST_OBJECT(pipeline)); > > return 0; > } > _______________________________________________ > gstreamer-devel mailing list > [hidden email] > http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel > gstreamer-devel mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Matt,
Thank you for the tips. It turns out that my problem was that the numbers after serial_ in the on_pad_added function were changing each time I ran the application, so my audio and video from the demuxer were not getting linked to the pads on the corresponding queues. I simply altered my string comparison and it started working perfectly. Thank you for your help, William On 6/6/2011 12:54 PM, Matt Veenstra wrote: > Hi William, > > When I am trying to debug this cases. > - I try and simplify the pipeline as much as possible. > - I would eliminate the audio or video channel and drop this to a fakesink. > - confirm on_pad_added() being called? > - I specifically link all items myself instead of using > gst_element_link_many() to confirm each step. And log in between. > - Looking at debug is also very useful, but sometimes overwhelming the > first look. > > > Cheers, > Matt > > On Fri, Jun 3, 2011 at 1:41 PM, William Metcalf<[hidden email]> wrote: >> I am writing an application to convert a .ogg file to an .mp4 file. My code >> is below. I already have the terminal pipeline for completing this task, >> and I am just trying to convert the terminal pipeline into an actual c >> program. The pipeline seems correct to be, but when I run the application I >> get an error "Internal data stream error". Does anyone have any suggestions >> as to what is wrong with my code? Thank you in advance. >> >> #include<gst\gst.h> >> #include<glib-2.0\glib.h> >> #include<string.h> >> #include"Encode_File_Test.h" >> #include"Preprocessor_Defines.h" >> >> /* Handle messages from the pipeline bus */ >> static gboolean bus_call(GstBus *bus, GstMessage *msg, gpointer data) >> { >> GMainLoop *loop = (GMainLoop * ) data; >> >> switch(GST_MESSAGE_TYPE(msg)) >> { >> case GST_MESSAGE_EOS: >> g_print("End of stream\n"); >> g_main_loop_quit(loop); >> break; >> case GST_MESSAGE_ERROR: >> { >> gchar *debug; >> GError *error; >> >> gst_message_parse_error(msg,&error,&debug); >> g_free(debug); >> >> g_printerr ("Error: %s\n", error->message); >> g_error_free(error); >> >> g_main_loop_quit(loop); >> break; >> } >> default: >> break; >> } >> >> return TRUE; >> } >> >> /* Handles when a pad is added to the demuxer */ >> static void on_pad_added(GstElement *element, GstPad *pad, gpointer data) >> { >> guint result; >> GstPad *sinkpad; >> gchar* name; >> name = gst_pad_get_name(pad); >> >> result = g_strcasecmp(name, "serial_1fa82364"); >> /* This is the audio pad of the demuxer we need to link it to the >> decoder's audio output in the queue */ >> if(!result) >> { >> /* We can now link this pad with the audio decoder's sink pad */ >> g_print("Dynamic pad created, linking the demuxer to the audio >> decoder\n"); >> >> sinkpad = gst_element_get_pad(audio_queue, "sink"); >> >> gst_pad_link(pad, sinkpad); >> >> gst_object_unref(sinkpad); >> } >> >> result = g_strcasecmp(name, "serial_0f0678e1"); >> /* This is the video pad of the demuxer we need to link it to the >> decoder's video output in the queue */ >> if(!result) >> { >> >> /* We can now link this pad with the video decoder's sink pad */ >> g_print("Dynamic pad created, linking the demuxer to the video >> decoder\n"); >> >> sinkpad = gst_element_get_static_pad(video_queue, "sink"); >> >> gst_pad_link(pad, sinkpad); >> >> gst_object_unref(sinkpad); >> } >> } >> >> /* Connects the src pad of the audio out queue to the audio sink pad of the >> mxuer */ >> static void link_audio_to_multiplexer(GstElement *audio_output, GstElement >> *muxer) >> { >> GstPad *pad, *link_pad; >> >> link_pad = gst_element_get_static_pad(audio_output, "src"); >> >> pad = gst_element_get_request_pad(muxer, "audio_%d"); >> >> gst_pad_link(link_pad, pad); >> >> gst_object_unref(pad); >> } >> >> /* Connects the src pad of the video out queue to the video sink pad of the >> muxer */ >> static void link_video_to_multiplexer(GstElement *video_output, GstElement >> *muxer) >> { >> GstPad *pad, *link_pad; >> >> link_pad = gst_element_get_static_pad(video_output, "src"); >> >> pad = gst_element_get_request_pad(muxer, "video_%d"); >> >> gst_pad_link(link_pad, pad); >> >> gst_object_unref(pad); >> } >> >> int main (int argc, char *argv[]) >> { >> gst_init(&argc,&argv); >> >> loop = g_main_loop_new(NULL, FALSE); >> >> /* Create elements */ >> pipeline = gst_pipeline_new("audio-player"); >> >> /* Element for reading in a file */ >> source = gst_element_factory_make("filesrc", >> "file-source"); >> >> /* OGG elements */ >> oggdemuxer = gst_element_factory_make("oggdemux", >> "ogg-demuxer"); >> vorbis_decoder = gst_element_factory_make("vorbisdec", >> "vorbis-decoder"); >> theora_decoder = gst_element_factory_make("theoradec", >> "theora-decoder"); >> >> /* MP4 elements */ >> audio_encoder = gst_element_factory_make("faac", "aac-encoder"); >> video_encoder = gst_element_factory_make("ffenc_mpeg4", >> "avc-encoder"); >> mp4_muxer = gst_element_factory_make("qtmux", "mp4-muxer"); >> >> /* Audio Video elements */ >> audio_converter = gst_element_factory_make("audioconvert", >> "audio-converter"); >> video_converter = gst_element_factory_make("ffmpegcolorspace", >> "video-converter"); >> audio_resample = gst_element_factory_make("audioresample", >> "audio-resample"); >> audio_rate = gst_element_factory_make("audiorate", >> "audio-rate"); >> videosink = gst_element_factory_make("autovideosink", >> "video-sink"); >> audiosink = gst_element_factory_make("autoaudiosink", >> "audio-sink"); >> >> /* Queues */ >> video_queue = gst_element_factory_make("queue", >> "video-queue"); >> audio_queue = gst_element_factory_make("queue", >> "audio-queue"); >> video_out_queue = gst_element_factory_make("queue", >> "video-out-queue"); >> audio_out_queue = gst_element_factory_make("queue", >> "audio-out-queue"); >> >> /* Element to write to the file */ >> filesink = gst_element_factory_make("filesink", >> "file-sink"); >> >> /* Make sure we were able to create all of the elements*/ >> if(!pipeline || !source || !oggdemuxer || !vorbis_decoder || >> !theora_decoder || !audio_encoder || !video_encoder || !mp4_muxer || >> !audio_converter || !video_converter || !audio_resample || !audio_rate || >> !videosink || !audiosink || !video_queue || !audio_queue || !video_out_queue >> || !audio_out_queue || !filesink ) >> { >> g_printerr("One ore more elements could not be created. Exiting.\n"); >> return -1; >> } >> >> /* Input file */ >> g_object_set(G_OBJECT(source), "location", "c:\\video.ogg", NULL); >> g_object_set(G_OBJECT(filesink), "location", "c:\\video(encoded from >> ogg).mp4", NULL); >> >> /* Add a message handler from pipeline bus */ >> bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline)); >> gst_bus_add_watch(bus, bus_call, loop); >> gst_object_unref(bus); >> >> /* add elements to the pipeline */ >> gst_bin_add_many(GST_BIN(pipeline), source, oggdemuxer, video_queue, >> theora_decoder, video_converter, video_encoder, video_out_queue, >> audio_queue, vorbis_decoder, audio_converter, audio_encoder, >> audio_out_queue, mp4_muxer, filesink, NULL); >> >> /* link the elements together */ >> gst_element_link(source, oggdemuxer); >> >> /* video_queue -> theoradec -> ffmpegcolorspace -> ffenc_mpeg4 -> >> video_out_queue ~> qtmux */ >> res = gst_element_link_many(video_queue, theora_decoder, video_converter, >> video_encoder, video_out_queue, NULL); >> if(!res) >> { >> g_printerr("There was a problem linking video elements.\n"); >> return 1; >> } >> >> /* queue_audio -> vorbisdec -> audioconvert -> faac -> audio_out_queue ~> >> qtmux */ >> res = gst_element_link_many(audio_queue, vorbis_decoder, audio_converter, >> audio_encoder, audio_out_queue, NULL); >> if(!res) >> { >> g_printerr("There was a problem linking elements.\n"); >> return 1; >> } >> g_signal_connect(oggdemuxer, "pad-added", G_CALLBACK(on_pad_added), >> NULL); >> >> /* qtmux -> filesink */ >> res = gst_element_link(mp4_muxer, filesink); >> >> link_video_to_multiplexer(video_out_queue, mp4_muxer); >> link_audio_to_multiplexer(audio_out_queue, mp4_muxer); >> >> >> /* Set the pipeline stat to play and start the main loop*/ >> g_print("Starting the pipeline\n"); >> gst_element_set_state(pipeline, GST_STATE_PLAYING); >> g_main_loop_run(loop); >> >> /* We are done now, do a little bit of cleaning up */ >> g_print("Stopping the pipeline.\n"); >> gst_element_set_state(pipeline, GST_STATE_NULL); >> gst_object_unref(GST_OBJECT(pipeline)); >> >> return 0; >> } >> _______________________________________________ >> gstreamer-devel mailing list >> [hidden email] >> http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel >> > _______________________________________________ > gstreamer-devel mailing list > [hidden email] > http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel _______________________________________________ gstreamer-devel mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Free forum by Nabble | Edit this page |