<div style="line-height:1.7;color:#000000;font-size:14px;font-family:arial"><DIV>About the Gobject system,</DIV>
<DIV>Why Gobject not C++ ? </DIV>
<DIV> It designed for cross language programming.</DIV>
<DIV> Please read "Inside the C++ Object Mode", It will help you understand all of the OO programming language.</DIV>
<DIV> For other things, You just need a KDE and trying to debug Gstreamer sample step by step, and look at the call stack.</DIV>
<DIV><BR>At 2012-05-02 04:55:59,"Dave Mateer" <dave_mateer@ntm.org> wrote:<BR>>I'm brand new to gstreamer, but am pretty sure it is going to be the right library for an application we are working on. I am very impressed with the feature set that the library implements. I have a proof-of-concept application that reads a video file and then plays the audio on the computer and displays the video in a Qt widget. I was wondering if some of the more experienced devs would mind offering a critique--I'm sure I'm doing a bunch of things The Wrong Way, but there are a lot of new things for me here: the gstreamer API itself, C (I'm more of a C++ guy), the GObject system, etc.<BR>><BR>>Among other things, the fact that I'm testing for audio vs. video pad by comparing a string prefix seems fragile and smelly. That can't be right. Also, it seems like I'm leaking memory in the call to gst_bin_get_by_name because the docs say that transfers ownership (not just a reference count?). Not sure about that one. I'm sure there are many other things as well.<BR>><BR>>I appreciate any help anyone could offer. It's my first attempt, so I know it's bad, so be honest! I stripped out some of the more Qt-specific stuff.<BR>><BR>>static void on_pad_added(GstElement *element,<BR>> GstPad *new_pad,<BR>> gpointer user_data) {<BR>> GstCaps *caps = gst_pad_get_caps_reffed(new_pad);<BR>> gchar *name = gst_caps_to_string(caps);<BR>> GstBin *pipeline = (GstBin*)user_data;<BR>><BR>> if (g_str_has_prefix(name, "audio")) {<BR>> g_print("audio\n");<BR>><BR>> // Leaking memory?? gst_bin_get_by_name transfers ownership?<BR>> GstElement *audio_sink = gst_bin_get_by_name(pipeline, "audio-sink");<BR>> if (!audio_sink) {<BR>> throw std::runtime_error("Could not extract audio sink from pipeline");<BR>> }<BR>><BR>> GstPad *sink_pad = gst_element_get_static_pad(audio_sink, "sink");<BR>> if (!sink_pad) {<BR>> throw std::runtime_error("Could not get sink pad from audio element.");<BR>> }<BR>><BR>> if (GST_PAD_LINK_FAILED(gst_pad_link(new_pad, sink_pad))) {<BR>> throw std::runtime_error("Failed to link audio src and sink");<BR>> }<BR>><BR>> gst_object_unref(sink_pad);<BR>> } else {<BR>> g_print("video\n");<BR>><BR>> // Leaking memory?? gst_bin_get_by_name transfers ownership?<BR>> GstElement *video_sink = gst_bin_get_by_name(pipeline, "video-sink");<BR>> if (!video_sink) {<BR>> throw std::runtime_error("Could not extract video sink from pipeline");<BR>> }<BR>><BR>> GstPad *sink_pad = gst_element_get_static_pad(video_sink, "sink");<BR>> if (!sink_pad) {<BR>> throw std::runtime_error("Could not get sink pad from video element.");<BR>> }<BR>><BR>> if (GST_PAD_LINK_FAILED(gst_pad_link(new_pad, sink_pad))) {<BR>> throw std::runtime_error("Failed to link video src and sink");<BR>> }<BR>><BR>> gst_object_unref(sink_pad);<BR>> }<BR>><BR>> g_free(name);<BR>> gst_caps_unref(caps);<BR>>}<BR>><BR>>MainWindow::MainWindow(QWidget *parent)<BR>> : QMainWindow(parent),<BR>> ui(new Ui::MainWindow) {<BR>> ui->setupUi(this);<BR>><BR>> // Create the top-level pipeline.<BR>> pipeline_ = gst_pipeline_new(NULL);<BR>> if (!pipeline_) {<BR>> throw std::runtime_error("Could not create pipeline");<BR>> }<BR>><BR>> // Create the decode bin for our video source.<BR>> GstElement *src = gst_element_factory_make("uridecodebin", NULL);<BR>> if (!src) {<BR>> throw std::runtime_error("Could not create uridecodebin");<BR>> }<BR>> g_object_set(src, "uri", "file:///path/to/media.ogg", NULL);<BR>><BR>> // Add the decode bin to the pipeline.<BR>> if (!gst_bin_add(GST_BIN(pipeline_), src)) {<BR>> throw std::runtime_error("Could not add uridecodebin to pipeline");<BR>> }<BR>><BR>> // Create the video sink. This will be linked in the pad-added signal handler.<BR>> GstElement *video_sink = gst_element_factory_make("xvimagesink",<BR>> "video-sink");<BR>> if (!video_sink) {<BR>> throw std::runtime_error("Could not create xvimagesink");<BR>> }<BR>> if (!gst_bin_add(GST_BIN(pipeline_), video_sink)) {<BR>> throw std::runtime_error("Could not add video sink to pipeline");<BR>> }<BR>> WId id = ui->video_widget->winId();<BR>> gst_x_overlay_set_window_handle(GST_X_OVERLAY(video_sink), id);<BR>> qApp->syncX();<BR>><BR>> // Create the audio sink. This will be linked in the pad-added signal handler.<BR>> GstElement *audio_sink = gst_element_factory_make("autoaudiosink",<BR>> "audio-sink");<BR>> if (!audio_sink) {<BR>> throw std::runtime_error("Could not create autoaudiosink");<BR>> }<BR>> if (!gst_bin_add(GST_BIN(pipeline_), audio_sink)) {<BR>> throw std::runtime_error("Could not add audio sink to pipeline");<BR>> }<BR>><BR>> // Register our interest in the pad-added signal so we can connect our sinks.<BR>> g_signal_connect(src, "pad-added", G_CALLBACK(on_pad_added), pipeline_);<BR>><BR>> // Start the playback.<BR>> gst_element_set_state(pipeline_, GST_STATE_PLAYING);<BR>>}<BR>><BR>>MainWindow::~MainWindow() {<BR>> gst_element_set_state (pipeline_, GST_STATE_NULL);<BR>> gst_object_unref(pipeline_);<BR>> delete ui;<BR>>}<BR>><BR>><BR>>_______________________________________________<BR>>gstreamer-devel mailing list<BR>>gstreamer-devel@lists.freedesktop.org<BR>>http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel<BR></DIV></div><br><br><span title="neteasefooter"><span id="netease_mail_footer"></span></span>