[Libav-user] How to create video using avcodec from OpenCV::Mat?

Morduhaev, Igor (igorm@stats.com) igorm at stats.com
Sat Dec 1 00:41:15 CET 2012

I get colored jpeg images of OpenCV::Mat type and I create from them video using avcodec. The video that I get is upside-down, black & white and each row of each frame is shifted and I got diagonal line. What could be the reason for such output?
Follow this link (https://picasaweb.google.com/lh/photo/ZNQeoPw8YFBa-iFpzuYi4dMTjNZETYmyPJy0liipFm0?feat=directlink) to watch the video I get using  avcodec.
I'm using acpicture_fill to create avFrame from cv::Mat frame!

Each cv::Mat cvFrame has  width=810, height=610, step=2432
I noticed that avFrame (that is filled by acpicture_fill) has linesize[0]=2430
I tried manually setting avFrame->linesizep0]=2432 and not 2430 but it still didn't helped.

======== CODE =========================================================

AVCodec *encoder = avcodec_find_encoder(AV_CODEC_ID_H264);
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 = 810;
outStream->codec->height = 610;

SwsContext *swsCtx = sws_getContext(outStream->codec->width, outStream->codec->height, PIX_FMT_RGB24,
       outStream->codec->width, outStream->codec->height,  outStream->codec->pix_fmt, SWS_BICUBIC, NULL, NULL, NULL);

for (uint i=0; i < frameNums; i++)
// get frame at location I using OpenCV
       cv::Mat cvFrame;
       myReader.getFrame(cvFrame, i);
       cv::Size frameSize = cvFrame.size();
//Each cv::Mat cvFrame has  width=810, height=610, step=2432

       // create AVPicture from cv::Mat frame
       avpicture_fill((AVPicture*)avFrame, cvFrame.data, PIX_FMT_BGR24, outStream->codec->width, outStream->codec->height);
avFrame->width = frameSize.width;
       avFrame->height = frameSize.height;

// rescale to outStream format
       sws_scale(swsCtx, avFrame->data, avFrame->linesize, 0, outStream->codec->height, avFrameRescaledFrame->data, avFrameRescaledFrame ->linesize);
avFrameRescaledFrame->width = frameSize.width;
       avFrameRescaledFrame->height = frameSize.height;

       avEncodedPacket.data = NULL;
       avEncodedPacket.size = 0;

       // encode rescaled frame
       if(avcodec_encode_video2(outStream->codec, &avEncodedPacket, avFrameRescaledFrame, &got_frame) < 0) exit(1);
              if (avEncodedPacket.pts != AV_NOPTS_VALUE)
                     avEncodedPacket.pts =  av_rescale_q(avEncodedPacket.pts, outStream->codec->time_base, outStream->time_base);
              if (avEncodedPacket.dts != AV_NOPTS_VALUE)
                     avEncodedPacket.dts = av_rescale_q(avEncodedPacket.dts, outStream->codec->time_base, outStream->time_base);

              // outContainer is "mp4"
              av_write_frame(outContainer, & avEncodedPacket);


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20121130/4c306ce7/attachment.html>

More information about the Libav-user mailing list