GStreamer application to convert a .ogg file to an .mp4 file
Stefan Kost
ensonic at hora-obscura.de
Sun Jun 5 14:18:55 PDT 2011
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
> gstreamer-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
More information about the gstreamer-devel
mailing list