title: How to create video using avcodec from jpeg images of type OpenCV::Mat?
body: <p>I have colored jpeg images of <code>OpenCV::Mat</code> type and I create from them video using <code>avcodec</code>. The video that I get is upside-down, black &amp; white and each row of each frame is shifted and I got diagonal line. What could be the reason for such output?
  Follow <a href="https://picasaweb.google.com/lh/photo/ZNQeoPw8YFBa-iFpzuYi4dMTjNZETYmyPJy0liipFm0?feat=directlink" rel="nofollow">this</a> link to watch the video I get using avcodec.
  I'm using <code>acpicture_fill</code> function to create <code>avFrame</code> from <code>cv::Mat</code> frame!</p>
  
  <p>P.S.
  Each cv::Mat cvFrame has  width=810, height=610, step=2432
  I noticed that avFrame (that is filled by acpicture_fill) has <code>linesize[0]=2430</code>
  I tried manually setting <code>avFrame-&gt;linesizep0]=2432</code> and not 2430 but it still didn't helped.</p>
  
  <p><strong>======== CODE =========================================================</strong></p>
  
  <pre><code>AVCodec *encoder = avcodec_find_encoder(AV_CODEC_ID_H264);
  AVStream *outStream = avformat_new_stream(outContainer, encoder);
  avcodec_get_context_defaults3(outStream-&gt;codec, encoder);
  
  outStream-&gt;codec-&gt;pix_fmt = AV_PIX_FMT_YUV420P;
  outStream-&gt;codec-&gt;width = 810;
  outStream-&gt;codec-&gt;height = 610;
  //...
  
  SwsContext *swsCtx = sws_getContext(outStream-&gt;codec-&gt;width, outStream-&gt;codec-&gt;height, PIX_FMT_RGB24,
                                      outStream-&gt;codec-&gt;width, outStream-&gt;codec-&gt;height,  outStream-&gt;codec-&gt;pix_fmt, SWS_BICUBIC, NULL, NULL, NULL);
  
  for (uint i=0; i &lt; 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
  
  
  1.  // create AVPicture from cv::Mat frame
  2.  avpicture_fill((AVPicture*)avFrame, cvFrame.data, PIX_FMT_RGB24, outStream-&gt;codec-&gt;width, outStream-&gt;codec-&gt;height);
  3avFrame-&gt;width = frameSize.width;
  4.  avFrame-&gt;height = frameSize.height;
  
      // rescale to outStream format
      sws_scale(swsCtx, avFrame-&gt;data, avFrame-&gt;linesize, 0, outStream-&gt;codec-&gt;height, avFrameRescaledFrame-&gt;data, avFrameRescaledFrame -&gt;linesize);
  encoderRescaledFrame-&gt;pts=i;
  avFrameRescaledFrame-&gt;width = frameSize.width;
      avFrameRescaledFrame-&gt;height = frameSize.height;
  
  av_init_packet(&amp;avEncodedPacket);
      avEncodedPacket.data = NULL;
      avEncodedPacket.size = 0;
  
      // encode rescaled frame
      if(avcodec_encode_video2(outStream-&gt;codec, &amp;avEncodedPacket, avFrameRescaledFrame, &amp;got_frame) &lt; 0) exit(1);
      if(got_frame)
      {
          if (avEncodedPacket.pts != AV_NOPTS_VALUE)
              avEncodedPacket.pts =  av_rescale_q(avEncodedPacket.pts, outStream-&gt;codec-&gt;time_base, outStream-&gt;time_base);
          if (avEncodedPacket.dts != AV_NOPTS_VALUE)
              avEncodedPacket.dts = av_rescale_q(avEncodedPacket.dts, outStream-&gt;codec-&gt;time_base, outStream-&gt;time_base);
  
          // outContainer is "mp4"
          av_write_frame(outContainer, &amp; avEncodedPacket);
  
          av_free_packet(&amp;encodedPacket);
      }
  }
  </code></pre>
  
  <p><strong>UPDATED</strong></p>
  
  <p>As @Alex suggested I changed the lines 1-4 with the code below</p>
  
  <pre><code>int width = frameSize.width, height = frameSize.height; 
  avpicture_alloc((AVPicture*)avFrame, AV_PIX_FMT_RGB24, outStream-&gt;codec-&gt;width, outStream-&gt;codec-&gt;height);
  for (int h = 0; h &lt; height; h++)
  {
       memcpy(&amp;(avFrame-&gt;data[0][h*avFrame-&gt;linesize[0]]), &amp;(cvFrame.data[h*cvFrame.step]), width*3);
  }
  </code></pre>
  
  <p>The video (<a href="https://picasaweb.google.com/103161760482140400348/2December201202#5817342583034854274" rel="nofollow">here</a>) I get now is almost perfect. It's NOT upside-down, NOT black &amp; white, BUT it seems that one of the RGB components is missing. Every brown/red colors became blue (in original images it should be vice-verse).
  What could be the problem? Could rescaling(<code>sws_scale</code>) to <code>AV_PIX_FMT_YUV420P</code> format causes this?</p>