title: Converting an AVFrame to QImage with conversion of pixel format
body: <p>I need to extract frames of videos to images in my QT application. I don't know in advance the pixel format of the source videos/frames (yuv, rgb...), But I need to obtain a reliable image pixel format such that I can consistently handle the images later.
  I'm using the ffmpeg libraries to get the frames, which are already decoded. I'm trying to avoid using deprecated functions, and I need to optimize for speed.</p>
  <p>I tried implementing this example: <a href="https://stackoverflow.com/a/42615610/7360943">https://stackoverflow.com/a/42615610/7360943</a> which</p>
  <ol>
  <li><p>Converts the original frame to a rgb frame</p>
  </li>
  <li><p>Creates a QImage from this second frame's data.</p>
  </li>
  </ol>
  <p>However, this has two main problems: it uses the <strong>deprecated avpicture_alloc</strong> function, and also <strong>doesn't free the allocated memory</strong>, which causes my app to quickly break down, using more, and more RAM until it crashes when multiple thousand images need to be taken. I haven't found a way to solve either problem independently, for I don't know what to use instead of avpicture_alloc, and if I use avpicture_free it actually frees the data underlying the QImage, which breaks the QImage.</p>
  <p>I tried the following instead, directly passing the QImage preallocated data to sws_scale, which <strong>works great most of the time</strong>:</p>
  <pre><code>// we will convert the original color format to rgb24
  SwsContext* img_convert_ctx = sws_getContext(
                                   pFrame-&gt;width,
                                   pFrame-&gt;height,
                                   (AVPixelFormat)pFrame-&gt;format,
                                   pFrame-&gt;width,
                                   pFrame-&gt;height,
                                   AV_PIX_FMT_RGB24,
                                   SWS_BICUBIC, NULL, NULL, NULL);
  
  QImage image(pFrame-&gt;width,
               pFrame-&gt;height,
               QImage::Format_RGB888);
  
  int rgb_linesizes[8] = {0};
  rgb_linesizes[0] = 3*pFrame-&gt;width;
  
  sws_scale(img_convert_ctx,
              pFrame-&gt;data,
              pFrame-&gt;linesize, 0,
              pFrame-&gt;height,
              (uint8_t *[]){image.bits()},
              rgb_linesizes);
  
  ffmpeg::sws_freeContext(img_convert_ctx);
  </code></pre>
  <p>The problem is that <strong>for some specific videos</strong>, it outputs some weird images that look somewhat black and white (and which maybe seems to show an offset of 1 between input width and output width...? I haven't been able to fully interpret what could cause this):
  See the reference image, how it should look:</p>
  <p><a href="https://i.stack.imgur.com/D7bWt.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/D7bWt.jpg" alt="See the reference image, how it should look" /></a></p>
  <p>and the problematic grey-ish image:</p>
  <p><a href="https://i.stack.imgur.com/7nDzX.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/7nDzX.png" alt="problematic grey-is image" /></a></p>
  <p>So what's the problem in my code that causes it to behave well most of the time, but not work as intended in some specific cases? Or how could this be done otherwise?</p>