Results 1 to 8 of 8

Thread: QLabel does not repaint QPixmap

  1. #1
    Join Date
    Feb 2017
    Posts
    5
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default QLabel does not repaint QPixmap

    Hello!

    I'm using QT5.7.
    I have 2 labels that's used for video frame representation. For each label i pass frames correctly and it works with code below.
    I just simply get new frames from my external source, than i convert them to Pixmap and call setPixmap(map);
    Code looks like this :

    QImage image = QImage(frame.data, frame.width, frame.height, QImage::Format_RGB888);
    image = image.scaledToWidth(320, Qt::SmoothTransformation);
    QPixmap map = QPixmap::fromImage(image);
    QLabel *label = (QLabel *)ui->streamPlayerTable->cellWidget(x,y)->findChild<QLabel*>();
    label->setPixmap(map);

    Both videos goes correctly for 1min, 5min, sometimes 30min. But sometimes one of those videos just stop. Seemingly with no reason!! I see that new pixmaps are created for both labels. Frames are coming, gdb does not show any suspicious thread exiting messages, memory usage is constant and cpu is not very high at the moment when some video stops, also no console messages.

    It seems that pixmap are stuck in some repaint request. But as i don't know a lot of QT framework internals, i please to help me to understand what might cause such behaviour.

    Is there any way to force label to repaint pixmap with no crashes ?

    If anyone had experienced in such behaviour on QT please share ideas to solve it.

    Thanks in advance!
    Last edited by __Emanuel; 4th February 2017 at 23:30.

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,229
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QLabel does not repaint QPixmap

    You do not show enough of the context in which this code is running, so it isn't possible to give you an answer.

    I don't know how you retrieve the frames from the external source, but you could have a race condition. The fact that your freezes occur sort of randomly implies some timing issue like this.

    Instead of calling findChild() every time you want to update the pixmap, why don't you simply save the QLabel's pointer when you create it?
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  3. #3
    Join Date
    Feb 2017
    Posts
    5
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: QLabel does not repaint QPixmap

    Quote Originally Posted by d_stranz View Post
    why don't you simply save the QLabel's pointer when you create it?
    Yes, this is a good point! I am going to do this to perform a little better. But i have doubt that it may help. You think it could ?
    I also though how to make more optimisation, but unfortunately, i get those buffers in api thread.

    Can you tell me more about that race condition, please! I though that all label content internally gets rendered in to one api thread. So it's not like that ?

    I get the frames by signal from library that provides me with new frames. I see that those frames are coming smooth, because when i manually just resize the main window, both videos are playing smoothly. But i would like not do that in order to see both videos. But if i don't do this, the one who stuck keeps being stuck.

  4. #4
    Join Date
    Feb 2017
    Posts
    5
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: QLabel does not repaint QPixmap

    Yes, but if it's race condition and timing issue, than why it's possible to get smooth playback on both videos if manually change main window resize. As long as i change it, it repaints both label frames and nothing stucks. Once i stop changing size, the same label that was stopped previously, stop again. Though that timing issue should keep blocked forever even if i resize it.

    I am definit that the race condition is not in frame receiving. I monitor the frame receiving on the place where setPixmap used. And it shows that frames are coming consequently to both. But highly possible on QT repaint. Maybe it stuck on update specific label. If i set pixmap on one label, is it true, that it can affect the state of other label context ?
    Last edited by __Emanuel; 5th February 2017 at 14:10.

  5. #5
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,229
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QLabel does not repaint QPixmap

    You access "frame.data" when creating your QImage. If filling this "frame" with information from your video receiving thread is not protected by a mutex or some other thread synchronization mechanism, then the contents of "frame" could be changing at the exact time that you are accessing the same data to build the image.

    But like I said, describing your code in words isn't enough to get you an answer. Insisting that you're doing it right doesn't mean you are. Just because you get smooth playback most of the time doesn't mean you aren't doing something wrong, it just means that most of the time what you've done wrong doesn't affect the playback. But then it freezes.

    Changing one label should not affect a different label, but since you don't show any code for that either, who knows?
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  6. #6
    Join Date
    Feb 2017
    Posts
    5
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: QLabel does not repaint QPixmap

    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.

  7. #7
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QLabel does not repaint QPixmap

    My guess would be a threading issue.

    Have you checked that MainWindow::show_frame() is executed by the main thread?

    If it is not then prepare_frame() could call show_frame() via QMetaObject::invokeMethod() with Qt::QueuedConnection as the connection type.

    Cheers,
    _

  8. #8
    Join Date
    Feb 2017
    Posts
    5
    Qt products
    Qt5
    Platforms
    Unix/X11

    Thumbs up Re: QLabel does not repaint QPixmap

    Unless i did not find the way to determine if show_frame executed in main thread, i made the way you told me to do.
    I am testing 4 concurrent videos and 30min cant see any stall of any video.
    And there is no strange crashes. All is smooth.

    If i will got some problems, i will come back. But i hope it wont be necessary.

    d_stranz && anda_skoa, i am sending virtual candies
    Many, thanks!
    Last edited by __Emanuel; 11th February 2017 at 18:14.

Similar Threads

  1. Pan/Move QPixmap in QLabel
    By ashtray4241 in forum Qt Programming
    Replies: 5
    Last Post: 14th August 2014, 09:50
  2. QPixmap and QLabel performance
    By mass85 in forum Qt Programming
    Replies: 10
    Last Post: 13th December 2010, 11:19
  3. QLabel, QPixmap and ScaledContents
    By mhbeyle in forum Qt Programming
    Replies: 3
    Last Post: 28th November 2009, 10:11
  4. DrawLine over QPixmap within Qlabel
    By Qt Coder in forum Qt Programming
    Replies: 8
    Last Post: 26th March 2009, 13:21
  5. Rotate QPixmap set on QLabel
    By Qt Coder in forum Qt Programming
    Replies: 1
    Last Post: 18th March 2009, 13:08

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.