Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

[Multimedia] create QVideoFrame for YUV420p



  • Hello,

    I'm making a bridge between OpenTok (video call library) and Qt, for mobile platforms only (Android & iOS).
    It works fine on Android, now I'm working on iOS part.

    The pixel format used is YUV420p (i450)
    But it looks like I get only Y plane, because at the end the image is visible but green like this > https://i.imgur.com/FzLx2Cc.jpg

    I have 3 planes for each Y U V, then I concat them, then I send buffer to Qt.

    Objective-C part (almost like C++) :

    - (void)renderVideoFrame:(OTVideoFrame*) frame
    {
        __block OTVideoFrame *frameToRender = frame;
        dispatch_sync(self.renderQueue, ^{
            
            uint8_t* y = (uint8_t*)[frameToRender.planes pointerAtIndex:0];
            uint8_t* u = (uint8_t*)[frameToRender.planes pointerAtIndex:1];
            uint8_t* v = (uint8_t*)[frameToRender.planes pointerAtIndex:2];
            
            // concat Y U V
            size_t pixelNb = frameToRender.format.imageHeight * frameToRender.format.imageWidth;
            size_t pSize = pixelNb * sizeof(uint8_t);
            uint8_t* buffer = (uint8_t*)malloc(pixelNb * sizeof(uint8_t) * 6);
            memcpy(buffer, y, pSize*4);
            memcpy(buffer+pSize*4, u, pSize);
            memcpy(buffer+pSize*5, v, pSize);
            
            QVideoFrame::PixelFormat pixelFormat = QVideoFrame::Format_YUV420P; // correspond to i420
            
            // C++ call
            TokHandler::instance()->newFrame(self._id, buffer, frameToRender.format.imageWidth, frameToRender.format.imageHeight, frame.format.imageWidth, pixelFormat);
        });
    }
    

    In Qt (C++) I create QFrame like this :

    void TokHandler::newFrame(int _id, uint8_t* buffer, int width, int height, int bpl, QVideoFrame::PixelFormat format)
    {
        QByteArray bytes(reinterpret_cast<const char*>(buffer), bpl*height);
    
        QVideoFrame frame(new QMemoryVideoBuffer(bytes, bpl), QSize(width, height), format);
        frame.setStartTime(0);
    
        TokHandler::instance()->getRenderer(_id)->newFrame(frame);
    }
    

    An idea ? Thanks


Log in to reply