Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Qt and ffmpeg: image display delay.
Forum Update on Monday, May 27th 2025

Qt and ffmpeg: image display delay.

Scheduled Pinned Locked Moved Solved General and Desktop
6 Posts 2 Posters 1.1k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    Mikeeeeee
    wrote on 16 Apr 2020, 20:07 last edited by
    #1

    Good afternoon.
    I use ffmpeg to read videos, split them into frames, and try to display images on the label.
    For some reason, only the last image begins to be displayed and only after the function is completed, while the previous images are not displayed, although debag says that the drawing function works.
    Please tell me what the rendering bug might be related to and how to fix it.

    void MainWindow::test2()
    {
        static struct SwsContext *img_convert_ctx;
        int videoStream, i, numBytes;
        int ret, got_picture;
     
        avformat_network_init();   //初始化FFmpeg网络模块
        av_register_all();  //初始化FFMPEG  调用了这个才能正常适用编码器和解码器
     
     
        AVFormatContext *pFormatCtx = NULL;
        //Allocate an AVFormatContext.
        pFormatCtx = avformat_alloc_context();
     
        // Open video file
        if(avformat_open_input(&pFormatCtx, "./Wildlife.wmv", 0, 0) != 0)
            qDebug()<<"Couldn't open file";
     
        if(avformat_find_stream_info(pFormatCtx, NULL) < 0)
         qDebug()<<"Couldn't find stream information";
     
        av_dump_format(pFormatCtx, 0, "./Wildlife.wmv", 0);//information abaut file
     
        AVCodecContext *pCodecCtxOrig = NULL;
        AVCodecContext *pCodecCtx = NULL;
     
        // Find the first video stream
        videoStream = -1;
        for(i=0; i<pFormatCtx->nb_streams; i++)
            if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) {
                videoStream=i;
                break;
            }
        if(videoStream == -1)
            qDebug()<<"Didn't find a video stream";
     
        // Get a pointer to the codec context for the video stream
        pCodecCtx=pFormatCtx->streams[videoStream]->codec;
     
        AVCodec *pCodec = NULL;
     
        // Find the decoder for the video stream
        pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
        if(pCodec == NULL) {
         fprintf(stderr, "Unsupported codec!\n");
         qDebug()<<"Codec not found";
        }
     
        // Copy context
        //pCodecCtx = avcodec_alloc_context3(pCodec);
    //    if(avcodec_copy_context(pCodecCtx, pCodecCtxOrig) != 0) {  //not work!!!!!!!!!!!!!!!!!!!!!
    //     qDebug()<<"Error copying codec context";
    //    }
        // Open codec
        AVDictionary *aVDictionary;
        if(avcodec_open2(pCodecCtx, pCodec, NULL) < 0)
            qDebug()<<"Could not open codec";
     
        // Выделить видеокадр // Allocate video frame
        AVFrame *pFrame = NULL;
        pFrame = av_frame_alloc();
     
        // Allocate an AVFrame structure
        AVFrame *pFrameRGB;
        pFrameRGB = av_frame_alloc();
        if(pFrameRGB == NULL)
            qDebug()<<"pFrameRGB == NULL";
     
        uint8_t *buffer = NULL;
        numBytes;
        // Determine required buffer size and allocate buffer
        numBytes=avpicture_get_size(AV_PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
        buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));
     
        // Assign appropriate parts of buffer to image planes in pFrameRGB
        // Note that pFrameRGB is an AVFrame, but AVFrame is a superset
        // of AVPicture
        avpicture_fill((AVPicture *)pFrameRGB, buffer, AV_PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
     
        struct SwsContext *sws_ctx = NULL;
        int frameFinished;
        AVPacket packet;
        // initialize SWS context for software scaling
        sws_ctx = sws_getContext(pCodecCtx->width,
            pCodecCtx->height,
            pCodecCtx->pix_fmt,
            pCodecCtx->width,
            pCodecCtx->height,
            AV_PIX_FMT_RGB24,
            SWS_BILINEAR,
            NULL,
            NULL,
            NULL
            );
     
        i=0;
        while(av_read_frame(pFormatCtx, &packet)>=0) {
          // Is this a packet from the video stream?
          if(packet.stream_index==videoStream) {
            // Decode video frame
            avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);
     
            // Did we get a video frame?
            if(frameFinished) {
            // Convert the image from its native format to RGB
                sws_scale(sws_ctx, (uint8_t const * const *)pFrame->data,
                  pFrame->linesize, 0, pCodecCtx->height,
                  pFrameRGB->data, pFrameRGB->linesize);
     
                // view image on label
                //if(++i<=20) //first 20 images view on label
                {
                    qDebug()<<"view image on label";
                    QImage image( pCodecCtx->width, pCodecCtx->height, QImage::Format_RGB888 );
                    for( int y = 0; y < pCodecCtx->height; ++y ){
                       memcpy( image.scanLine(y), pFrameRGB->data[0]+y * pFrameRGB->linesize[0], pCodecCtx->width * 3 );
                    }
                    //ui->label->setPixmap(QPixmap::fromImage(image,Qt::AutoColor));
                    paintImageOnLabel(image);
                    qDebug()<<"view image on label222";
                }
            }
          }
     
          // Free the packet that was allocated by av_read_frame
          av_free_packet(&packet);
        }
     
        // Free the RGB image
        av_free(buffer);
        av_frame_free(&pFrameRGB);
     
        // Free the YUV frame
        av_frame_free(&pFrame);
     
        // Close the codecs
        avcodec_close(pCodecCtx);
        avcodec_close(pCodecCtxOrig);
     
        // Close the video file
        avformat_close_input(&pFormatCtx);
    }
    void MainWindow::paintImageOnLabel(QImage image)
    {
        qDebug()<<"paintImageOnLabel()";
        ui->label->update();
        ui->label->setPixmap(QPixmap::fromImage(image,Qt::AutoColor));
        ui->label->update();
        //QThread::sleep(1);
    }
    

    The image is drawn in this section of the code

                    qDebug()<<"view image on label";
                    QImage image( pCodecCtx->width, pCodecCtx->height, QImage::Format_RGB888 );
                    for( int y = 0; y < pCodecCtx->height; ++y ){
                       memcpy( image.scanLine(y), pFrameRGB->data[0]+y * pFrameRGB->linesize[0], pCodecCtx->width * 3 );
                    }
                    //ui->label->setPixmap(QPixmap::fromImage(image,Qt::AutoColor));
                    paintImageOnLabel(image);
                    qDebug()<<"view image on label222";
    
    1 Reply Last reply
    0
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 16 Apr 2020, 20:10 last edited by
      #2

      Hi,

      You are basically using a blocking loop to show your images, therefore you do not allows Qt's event loop to run and update the GUI.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      1
      • M Offline
        M Offline
        Mikeeeeee
        wrote on 17 Apr 2020, 05:36 last edited by
        #3

        The while loop blocks the display of images? How do I display images during this logic?

        1 Reply Last reply
        0
        • S Offline
          S Offline
          SGaist
          Lifetime Qt Champion
          wrote on 17 Apr 2020, 05:53 last edited by
          #4

          As I said before, don't do that that way, you are blocking the event loop.

          One way is to use a QTimer to read the file at the interval defined by its frame rate.

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          1
          • M Offline
            M Offline
            Mikeeeeee
            wrote on 17 Apr 2020, 07:25 last edited by
            #5

            But how do I add QTimer to the file reading? Tell me please.

            1 Reply Last reply
            0
            • S Offline
              S Offline
              SGaist
              Lifetime Qt Champion
              wrote on 17 Apr 2020, 18:38 last edited by
              #6

              Encapsulate the file handling properly in a QObject based class.

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              1

              1/6

              16 Apr 2020, 20:07

              • Login

              • Login or register to search.
              1 out of 6
              • First post
                1/6
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved