niXman
niXman

Reputation: 71

ffmpeg, swscale, ARGB -> NV12, wrong NV12 image

I am getting ARGB frames and I need to convert them to NV12 format. I am using the code below but the result seems to be the wrong picture because I cannot view it using ImageMagick's display tool and cannot convert to png using ffmpeg (ffmpeg -s 320x240 -pix_fmt nv12 -i 12-11- 13.473.nv12 -f image2 -pix_fmt rgb24 captdump.png) because of error: 12-11-13.473.nv12: Invalid data found when processing input

to get swcontext:

        m_scale_context = ::sws_getContext(
             m_width
            ,m_height
            ,AV_PIX_FMT_ARGB
            ,m_width
            ,m_height
            ,AV_PIX_FMT_NV12
            ,SWS_FAST_BILINEAR
            ,NULL
            ,NULL
            ,NULL
        );

to convert:

    QByteArray encode(QByteArray src) {
        QByteArray dst;

        int size_in_bytes = ::av_image_get_buffer_size(AV_PIX_FMT_NV12, m_width, m_height, 32);
        dst.resize(size_in_bytes);

        AVFrame *frame = ::av_frame_alloc();
        frame->width = m_width;
        frame->height = m_height;
        frame->format = AV_PIX_FMT_NV12;
        ::av_frame_get_buffer(frame, 32);

        int srcStride[AV_NUM_DATA_POINTERS] = { static_cast<int>(m_width) * 4, 0 };
        quint8 *srcPtr[AV_NUM_DATA_POINTERS] = { reinterpret_cast<quint8 *>(src.data()), nullptr };
        ::sws_scale(
             m_scale_context
            ,srcPtr
            ,srcStride
            ,0
            ,m_height
            ,frame->data
            ,frame->linesize
        );

        int res = ::av_image_copy_to_buffer(
             reinterpret_cast<quint8 *>(dst.data())
            ,dst.size()
            ,(const uint8_t* const *)frame->data
            ,(const int*)frame->linesize
            ,AV_PIX_FMT_NV12
            ,frame->width
            ,frame->height
            ,32
        );

        qDebug().nospace().noquote()
            << "encoderNV12::encode(): width=" << m_width
            << ", height=" << m_height
            << ", bytes=" << size_in_bytes
            << ", writen=" << res
        ;

        ::av_frame_free(&frame);

#if 1
        auto dt = QDateTime::currentDateTime();
        QString fname = dt.toString("hh:mm:ss.zzz");
        fname.replace(":", "-");
        fname += ".nv12";
        QFile file(fname);
        file.open(QIODevice::WriteOnly);
        file.write(dst);
#endif

        return dst;
    }

the output looks like this:

encoderNV12::encode(): w=320, h=240, bytes=115200, writen=115200

what am I doing wrong?

best!

Upvotes: 1

Views: 203

Answers (0)

Related Questions