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. QtMultimedia. Qt 5.1. QVideoFrame converting in another struct

QtMultimedia. Qt 5.1. QVideoFrame converting in another struct

Scheduled Pinned Locked Moved General and Desktop
6 Posts 2 Posters 3.0k Views 1 Watching
  • 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.
  • D Offline
    D Offline
    dimanx
    wrote on last edited by
    #1

    Hi, all.

    I need to create h264 stream from camera. Unfortunately, QVideoProbe::setSource( some_QMediaRecorder ) always return false (both in Windows and Linux) and I can't get already encoded frames.
    I inherit QAbstractVideoSurface, make QCamera::setViewFinder for my class and now I give all QVideoFrame's from camera in YUV420P format. I need to encode its and will use x264. For encoding I should convert QVideoFrame into x264_image_t.

    @typedef struct
    {
    int i_csp; /* Colorspace /
    int i_plane; /
    Number of image planes /
    int i_stride[4]; /
    Strides for each plane */
    uint8_t plane[4]; / Pointers to each plane */
    } x264_image_t;@

    Does the QVideoFrame::bits() method return pointer to plain buffer, contains all plains of picture? How I can convert it? x264 expects YUV420P and I need just copy frame.

    1 Reply Last reply
    0
    • J Offline
      J Offline
      jmimi
      wrote on last edited by
      #2

      Hi
      I have the same problem.
      Do you find any solution?

      1 Reply Last reply
      0
      • D Offline
        D Offline
        dimanx
        wrote on last edited by
        #3

        [quote author="jmimi" date="1387821006"]Hi
        I have the same problem.
        Do you find any solution?[/quote]

        Yes. I use avpicture_fill(...) for copy QVideoFrame into AVPicture and sws_scale(...) for converting this picture into x_264_picture_t with YUV420P colorspace.

        @void H264Encoder::encodeFrame(const QVideoFrame& frame)
        {
        if (!frame.isReadable() || !frame.isMapped())
        return;
        //m_in_pixel_format = avcodec::AV_PIX_FMT_RGB32;
        if (m_in_pixel_format == PIX_FMT_NONE)
        {
        if ( !this->set_pix_fmt(frame) )
        return;
        }

        size_t in_width = frame.width();
        size_t in_height = frame.height();

        if (!m_sws_ctx)
        {
        m_sws_ctx = sws_getContext(in_width, in_height, m_in_pixel_format,
        m_out_width, m_out_height, m_out_pixel_format, SWS_FAST_BILINEAR, NULL, NULL, NULL);
        if (!m_sws_ctx)
        {
        qDebug() << "libswscale: Error creating sws context!";
        return;
        }
        }

        //copy frame from QVideoFrame into m_pic_raw
        int bytes_copied = avpicture_fill(&m_pic_raw, const_cast<uint8_t*>(frame.bits()),
        m_in_pixel_format, in_width, in_height);

        if (bytes_copied < 0)
        {
        qDebug() << "H264Encoder: error calling avpicture_fill(...)!";
        return;
        }

        //convert img into m_out_format and save in m_in_pic
        int scaled_img_height = sws_scale(m_sws_ctx, m_pic_raw.data, m_pic_raw.linesize, 0, in_height,
        m_in_pic->img.plane, m_in_pic->img.i_stride);

        if ( scaled_img_height < 0 || (size_t)scaled_img_height != m_out_height )
        {
        qDebug() << "Scaling failed!";
        return;
        }

        m_in_pic->i_pts = m_pts++;

        int res = x264_encoder_encode(m_encoder, &m_nals, &m_num_nals, m_in_pic, m_out_pic);
        if (res < 0)
        {
        qDebug() << "x264_encode error!";
        return;
        }

        m_last_frame_sz = res;

            //create frame_t for every NAL unit
        

        std::vector<Frame_t> result;
        this->get_encoded_frame(result);
        for (auto i = result.cbegin(); i != result.cend(); i++)
        {
        SharedEncodedFrame shared_result;
        shared_result << *i;
        emit newEncodedFrame(shared_result);
        }
        }

        bool H264Encoder::get_encoded_frame( std::vector<Frame_t>& buf )const
        {
        if (!m_last_frame_sz)
        return false;

        buf.clear();
        buf.resize(m_num_nals);

        for (int i = 0; i < m_num_nals; i++)
        {
        std::copy((const char*)m_nals[i].p_payload + 4, (const char*)m_nals[i].p_payload +
        m_nals[i].i_payload, std::back_inserter(buf[i]));
        }

        return true;
        }
        @

        where I have next members:
        @x264_param_t* m_params;

        x264_t* m_encoder;

        x264_picture_t *m_in_pic, *m_out_pic;

        PixelFormat m_in_pixel_format;
        PixelFormat m_out_pixel_format;

        size_t m_out_height;
        size_t m_out_width;

        size_t m_fps;

        //input frame;
        AVPicture m_pic_raw;

        x264_nal_t* m_nals;
        int m_num_nals;
        size_t m_last_frame_sz;

        int m_pts;
        SwsContext* m_sws_ctx;@

        1 Reply Last reply
        0
        • J Offline
          J Offline
          jmimi
          wrote on last edited by
          #4

          Oh, thanks for code.
          How you trap frames to ?
          @void H264Encoder::encodeFrame(const QVideoFrame& frame)
          ..@

          1 Reply Last reply
          0
          • D Offline
            D Offline
            dimanx
            wrote on last edited by
            #5

            I create subclass of QAbstractVideoSurface and set it as a viewfinder in QCamera.
            MySurface have method present(QVideoFrame) which call H264Encoder::encodeFrame(...).

            1 Reply Last reply
            0
            • J Offline
              J Offline
              jmimi
              wrote on last edited by
              #6

              Thanks dimanx.
              QAbstractVideoSurface is the point.

              1 Reply Last reply
              0

              • Login

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