CC++Qt « [ffmpeg][memory-leak]течёт avcodec encode video

Не могу придумать, что делать с этой проблемой. При транскодировании большого видео(от часа) в оперативу натекает просто кошмарно, а что делать - не знаю. Дебажил, но с разными видео память выделяется разными функциями и я уже запутался, где - что. Конечно, ещё пару дней красноглазого выискивания и, возможно, всё найду, но как-то не хочется идти этим путём. Вот тут схожая проблема, но решение заключается в обёртке QtFFmpegwrapper, которая, по сути, ничем не отличается от моего кода(или я что-то пропустил).

текст моего метода ниже. То, что выделено маллоком, освобождается вне метода. Пакет тоже освобождается, всё проверено.

/** * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann * (http://qbnz.com/highlighter/ and http://geshi.org/) */ .cpp.geshi_code {font-family:monospace;} .cpp.geshi_code .imp {font-weight: bold; color: red;} .cpp.geshi_code .kw1 {color: #0000ff;} .cpp.geshi_code .kw2 {color: #0000ff;} .cpp.geshi_code .kw3 {color: #0000dd;} .cpp.geshi_code .kw4 {color: #0000ff;} .cpp.geshi_code .co1 {color: #666666;} .cpp.geshi_code .co2 {color: #339900;} .cpp.geshi_code .coMULTI {color: #ff0000; font-style: italic;} .cpp.geshi_code .es0 {color: #000099; font-weight: bold;} .cpp.geshi_code .es1 {color: #000099; font-weight: bold;} .cpp.geshi_code .es2 {color: #660099; font-weight: bold;} .cpp.geshi_code .es3 {color: #660099; font-weight: bold;} .cpp.geshi_code .es4 {color: #660099; font-weight: bold;} .cpp.geshi_code .es5 {color: #006699; font-weight: bold;} .cpp.geshi_code .br0 {color: #008000;} .cpp.geshi_code .sy0 {color: #008000;} .cpp.geshi_code .sy1 {color: #000080;} .cpp.geshi_code .sy2 {color: #000040;} .cpp.geshi_code .sy3 {color: #000040;} .cpp.geshi_code .sy4 {color: #008080;} .cpp.geshi_code .st0 {color: #FF0000;} .cpp.geshi_code .nu0 {color: #0000dd;} .cpp.geshi_code .nu6 {color: #208080;} .cpp.geshi_code .nu8 {color: #208080;} .cpp.geshi_code .nu12 {color: #208080;} .cpp.geshi_code .nu16 {color:#800080;} .cpp.geshi_code .nu17 {color:#800080;} .cpp.geshi_code .nu18 {color:#800080;} .cpp.geshi_code .nu19 {color:#800080;} .cpp.geshi_code .me1 {color: #007788;} .cpp.geshi_code .me2 {color: #007788;} .cpp.geshi_code span.xtra { display:block; }

int
Videocut::encode(
  AVStream *anOutputStream,
  AVFrame *aFrame,
  AVPacket *aPacket
)
{
  AVCodecContext *outputCodec = anOutputStream->codec;

  if (!anOutputStream ||
        !aFrame ||
        !aPacket)
  {
    return 1;
    /* NOTREACHED */
  }

  uint8_t * buffer = (uint8_t *)malloc(
    sizeof(uint8_t) * _DefaultEncodeBufferSize
    );

      if (NULL == buffer) {
          return 2;
          /* NOTREACHED */
     }

  int packetSize = avcodec_encode_video(
    outputCodec,
          buffer,
          _DefaultEncodeBufferSize,
          aFrame
    );

  if (packetSize < 0) {
    free(buffer);
    return 1;
    /* NOTREACHED */
  }

  aPacket->data = buffer;
  aPacket->size = packetSize;

  return 0;
}
 

1 ответов


Во-первых, брать anOutputStream->codec до проверки anOutputStream не слишком логично.
Во-вторых, вы передаете в avcodec_encode_video размер _DefaultEncodeBufferSize, а в malloc - sizeof(uint8_t) * _DefaultEncodeBufferSize. Теоретически ошибки не должно быть...

Да, и вот над этой строчкой из документации avcodec_encode_video:
Return value: On error a negative value is returned, on success zero or the number of bytes used from the input buffer.
я бы подумал. Вряд ли aPacket->size == 0 - это то, что вы имели в виду.