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

Stefano Sabatini stefasab at gmail.com
Tue Dec 4 11:29:50 CET 2012


On date Friday 2012-11-30 23:41:15 +0000, Morduhaev, Igor (igorm at stats.com) encoded:
> 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!
> 
> P.S.
> 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);

avpicture_fill() assumes aligned data, which is not your case. Check
av_image_fill_arrays(), or simply set the linesize to the correct
value (which is 2432 if I understand correctly). Also this code is
potentially inconsistent, since you read the size from outStream
(which may be totally unrelated).

> 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);


More information about the Libav-user mailing list