Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

cv::Mat to AvFrame

I wrote this code to convert between OpenCV frames and AVFrames.

http://pastebin.com/y572NN44

It works for converting from an AvFrame to a cv::Mat and the display appears correctly. However, when converting back from a cv::Mat to an AvFrame it appears that the colour channels are inverted. In that red is blue and blue is red.

The correct format is being used, and works on the first conversion. What am i missing here?

click to hide/show revision 2
No.2 Revision

updated 2014-07-12 00:23:21 -0600

berak gravatar image

cv::Mat to AvFrame

I wrote this code to convert between OpenCV frames and AVFrames.

http://pastebin.com/y572NN44

It works for converting from an AvFrame to a cv::Mat and the display appears correctly. However, when converting back from a cv::Mat to an AvFrame it appears that the colour channels are inverted. In that red is blue and blue is red.

The correct format is being used, and works on the first conversion. What am i missing here?


cv::Mat avframe_to_cvmat(AVFrame *frame)
{
        AVFrame dst;
        cv::Mat m;

        memset(&dst, 0, sizeof(dst));

        int w = frame->width, h = frame->height;
        m = cv::Mat(h, w, CV_8UC3);
        dst.data[0] = (uint8_t *)m.data;
        avpicture_fill( (AVPicture *)&dst, dst.data[0], PIX_FMT_BGR24, w, h);

        struct SwsContext *convert_ctx=NULL;
        enum PixelFormat src_pixfmt = (enum PixelFormat)frame->format;
        enum PixelFormat dst_pixfmt = PIX_FMT_BGR24;
        convert_ctx = sws_getContext(w, h, src_pixfmt, w, h, dst_pixfmt,
                        SWS_FAST_BILINEAR, NULL, NULL, NULL);
        sws_scale(convert_ctx, frame->data, frame->linesize, 0, h,
                        dst.data, dst.linesize);
        sws_freeContext(convert_ctx);

        return m;
}
AVFrame cvmat_to_avframe(cv::Mat* frame)
{
        AVFrame dst;
        cv::Size frameSize = frame->size();
        AVCodec *encoder = avcodec_find_encoder(AV_CODEC_ID_H264);
        AVFormatContext* outContainer = avformat_alloc_context();
        AVStream *outStream = avformat_new_stream(outContainer, encoder);
        avcodec_get_context_defaults3(outStream->codec, encoder);

        outStream->codec->pix_fmt = AV_PIX_FMT_YUV420P;
        outStream->codec->width = frame->cols;
        outStream->codec->height = frame->rows;
        avpicture_fill((AVPicture*)&dst, frame->data, PIX_FMT_BGR24, outStream->codec->width, outStream->codec->height);
        dst.width = frameSize.width;
        dst.height = frameSize.height;
        SaveFrame(&dst,dst.width,dst.height,0);
        return dst;
}