Qt Code:
  1. // mainwindow.h
  2. std::map<std::string, std::unique_ptr<PGCapture>>captures;
  3.  
  4. // mycaptures.h
  5. class MyCaptures : public sigc::trackable {
  6. // all other members
  7. sigc::signal<void, Buffer> new_frame; // i create instance of buffer in new_sample method in pipeline.cpp so that i can send frame of pipeline.cpp new_sample to prepare frame on mainwindow.cpp
  8. Pipeline streamer; // this object does all the streaming to new_sample in pipeline.cpp. MyCapture just wrap it with additional logic
  9. }
  10.  
  11. //main.cpp
  12. int main(int argc, char *argv[])
  13. {
  14. QApplication a(argc, argv);
  15.  
  16. Gst::init(argc, argv);
  17.  
  18. MainWindow w;
  19. w.show();
  20.  
  21. return a.exec();
  22. }
  23.  
  24. // mainwindow.cpp
  25. MainWindow::MainWindow(QWidget *parent) :
  26. QMainWindow(parent),
  27. ui(new Ui::MainWindow)
  28. {
  29. connect(ui->managePlay, SIGNAL(pressed()), this, SLOT(open_file()));
  30. // alot of other connections
  31. }
  32.  
  33. void MainWindow::open_player() {
  34. ui->stackedWidget->setCurrentWidget(ui->playerMenu);
  35. }
  36.  
  37. void MainWindow::open_file() {
  38. std::map<std::string, std::string> inst_settings = {
  39. {"rtspsrc.location", "rtsp://192.xxx.x.yy:554/H.264/media.smp"}
  40. };
  41.  
  42. this->set_capture(file, "cam00", "h264ip_appsink", inst_settings);
  43. inst_settings["rtspsrc.location"] = "rtsp://192.xxx.x.xx:554/H.264/media.smp";
  44. this->set_capture(file, "cam01", "h264ip_appsink", inst_settings);
  45. }
  46.  
  47. void MainWindow::set_capture(... // settings) {
  48. this->captures[cap_name] = std::unique_ptr<MyCapture>(new MyCapture());
  49. this->captures[cap_name]->setup_stream(this->get_default_settings(file, cap_name, stream_config, settings));
  50. this->captures[cap_name]->new_frame.connect(sigc::mem_fun(*this, &MainWindow::prepare_frame)); //sigc signal included to connect new frame and prepare_frame
  51. }
  52.  
  53. // here comes buffers from all concurent streams
  54. void MainWindow::prepare_frame(gstpg::PGBuffer buffer) {
  55. QImage image = QImage(buffer.data, buffer.width, buffer.height, QImage::Format_RGB888);
  56. image = image.scaledToWidth(320, Qt::SmoothTransformation);
  57. if (!image.isNull()) {
  58. if (buffer.id == "cam00") {
  59. this->show_frame(buffer.id, image,0,0);
  60. }
  61. if (buffer.id == "cam01") {
  62. this->show_frame(buffer.id,image,0,1);
  63. }
  64. }
  65.  
  66. void MainWindow::show_frame(const std::string &cap_name, const QImage & image, const int x, const int y)
  67. {
  68. QPixmap map = QPixmap::fromImage(image);
  69. QLabel *pixmap = (QLabel *)ui->streamPlayerTable->cellWidget(x,y)->findChild<QLabel*>();
  70. pixmap->setPixmap(map);
  71. }
  72.  
  73. // pipeline.cpp
  74.  
  75. void Pipeline::set_appsink(const Glib::ustring &name)
  76. {
  77. g_signal_connect(appsink->gobj(), "new-sample", G_CALLBACK(&Pipeline::on_new_sample), (gpointer)this);
  78. }
  79.  
  80. GstFlowReturn Pipeline::on_new_sample(GstAppSink* sink, gpointer gSelf)
  81. {
  82. auto sample = gst_app_sink_pull_sample(GST_APP_SINK(sink));
  83. if (sample != NULL) {
  84. auto self = reinterpret_cast<Pipeline*>(gSelf);
  85. if (self->sample != NULL) {
  86. gst_sample_unref(self->sample);
  87. }
  88. self->sample = sample;
  89. GstBuffer* gst_buffer = gst_sample_get_buffer(self->sample);
  90. if (gst_buffer != NULL) {
  91. GstCaps *caps = gst_sample_get_caps(sample);
  92. if (GST_IS_CAPS (caps) && gst_caps_is_fixed (caps)) {
  93. GstMapInfo info;
  94. GstStructure *structure = gst_caps_get_structure (caps, 0);
  95.  
  96. int w = 0;
  97. int h = 0;
  98.  
  99. // // add all possible stuff here. Check if they exists
  100. gst_structure_get_int (structure, "width", &w);
  101. gst_structure_get_int (structure, "height", &h);
  102.  
  103. gst_buffer_map (gst_buffer, &info, GST_MAP_READ);
  104. self->buffer.width = w;
  105. self->buffer.height = h;
  106. self->buffer.data = info.data;
  107. self->buffer.id = self->settings.stream_id;
  108.  
  109. gst_buffer_unmap(gst_buffer, &info);
  110. self->frame_formated.emit(self->buffer);
  111. }
  112. }
  113. }
  114.  
  115. return GST_FLOW_OK;
  116. }
To copy to clipboard, switch view to plain text mode 

I cant provide even more code. As a result result i have a stackview of multiple streaming labels. Each of them shows frames of separate streams. All the other story you know. I got random stalls of some window.