GStreamer application to convert a .ogg file to an .mp4 file

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

GStreamer application to convert a .ogg file to an .mp4 file

william.l.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.

#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
Reply | Threaded
Open this post in threaded view
|

Re: GStreamer application to convert a .ogg file to an .mp4 file

Stefan Sauer
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
Reply | Threaded
Open this post in threaded view
|

Re: GStreamer application to convert a .ogg file to an .mp4 file

Matt Veenstra
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
Reply | Threaded
Open this post in threaded view
|

Re: GStreamer application to convert a .ogg file to an .mp4 file

william.l.metcalf
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