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
Forum Updated to NodeBB v4.3 + New Features

QtMultimedia. Qt 5.1. QVideoFrame converting in another struct

Scheduled Pinned Locked Moved General and Desktop
6 Posts 2 Posters 2.9k 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