Re: gstmm add element to pipeline test



José Alburquerque wrote:
The issue I pointed out about the Bus not being destroyed left me a bit inquisitive so I tested again (by using a custom destructor for Gst::Bus) and I found that for the signal version of the ogg player, the bus is destroyed, however if the last line before the return in main() ("bus->remove_signal_watch()") is removed, the bus is not destroyed. The bus is not destroyed for the slot version of the player. To test use the "bus-message-custom-destructor.diff". I get the feeling that this is not something to be concerned about, but I wanted to point it out in case it is an issue. Thanks.


I'm sorry! My logic was flawed. The reason the Bus is not destroyed in the slot version of the player is that I forgot to "return false" from the "callback" once it was time to disconnect the slot. This new slot version works exactly as the signal version (the Bus is indeed destroyed). At least I learned to trust existing code a little more. :-)

-Jose
#include <iostream>
#include <gstmm.h>

using namespace Glib;
using namespace Gst;
using namespace std;

bool process_bus_message(const RefPtr<Bus>& bus, const RefPtr<Message>& message,
RefPtr<MainLoop> mainLoop)
{
  switch (message->get_type()) {
    case MESSAGE_EOS:
      cout << "End of stream" << endl;
      mainLoop->quit();
      return false;
    case MESSAGE_ERROR:
      cerr << "Error." << endl;
      mainLoop->quit();
      return false;
    default:
      break;
  }
  return true;
}

void parser_pad_added(const RefPtr<Pad>& newPad, RefPtr<Element> decoder)
{
  cout << "Dynamic pad created, linking parser/decoder." << endl;
  RefPtr<Pad> sinkPad = decoder->get_pad("sink");
  newPad->link(sinkPad);
}

int main(int argc, char* argv[]) {
  if (argc != 2) {
    cout << "Usage: " << argv[0] << " <Ogg/Vorbis filename>" << endl;
    return -1;
  }

  Gst::init(argc, argv);
  RefPtr<MainLoop> mainLoop = Glib::MainLoop::create();

  /* create elements */
  RefPtr<Pipeline> pipeline = Gst::Pipeline::create("audio-player");
  RefPtr<Element> source = Gst::Element::create("filesrc", "file-source");
  RefPtr<Element> parser = Gst::Element::create("oggdemux", "ogg-parser");
  RefPtr<Element> decoder = Gst::Element::create("vorbisdec", "vorbis-decoder");
  RefPtr<Element> conv = Gst::Element::create("audioconvert", "converter");
  RefPtr<Element> sink = Gst::Element::create("alsasink", "alsa-output");

  if (!pipeline || !source || !parser || !decoder || !conv || !sink) {
    cerr << "One element could not be created." << endl;
    return -1;
  }

  /* set filename property on the file source. Also add a message
   * handler. */
  source->set_property("location", (string) argv[1]);

  RefPtr<Bus> bus = pipeline->get_bus();
  Bus::SlotWatch slot(sigc::bind< RefPtr<MainLoop> >( sigc::ptr_fun(&process_bus_message), mainLoop) );
  bus->add_watch(slot);

  /* put all elements in a bin */
  pipeline->add(source)->add(parser)->add(decoder)->add(conv)->add(sink);

  /* link together - note that we cannot link the parser and
   * decoder yet, becuse the parser uses dynamic pads. For that,
   * we set a pad-added signal handler. */
  source->link(parser);
  decoder->link(conv)->link(sink);

  parser->signal_pad_added().connect(sigc::bind< RefPtr<Element> >(
    sigc::ptr_fun(&parser_pad_added), decoder) );

  /* Now set to playing and iterate. */
  cout << "Setting to PLAYING." << endl;
  pipeline->set_state(STATE_PLAYING);
  cout << "Running." << endl;
  mainLoop->run();

  /* clean up nicely */
  cout << "Returned, stopping playback." << endl;
  pipeline->set_state(STATE_NULL);

  return 0;
}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]