0
votes

I'm trying to transcode a video with help of libavcodec. On transcoding big video files(hour or more) i get huge memory leaks in avcodec_encode_video. I have tried to debug it, but with different video files different functions produce leaks, i have got a little bit confused about that :). Here FFMPEG with QT memory leak is the same issue that i have, but i have no idea how did that person solve it. QtFFmpegwrapper seems to do the same i do(or i missed something).

my method is lower. I took care about aFrame and aPacket outside with av_free and av_free_packet.

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

1 Answers

1
votes

The first step would be to try to reproduce your problem under Valgrind on a Linux box, if you can.

ffmpeg encoders and decoders usually not dynamically allocate memory; they reuse buffers between calls. Leaks are usually going to be in the frames somewhere.

Note that av_free_packet will only free your dynamically allocated buffer if the packet has a destructor function!

Look at how the function is defined in libavcodec/avpacket.c:

void av_free_packet(AVPacket *pkt)
{
    if (pkt) {
        if (pkt->destruct) pkt->destruct(pkt);
        pkt->data = NULL; pkt->size = 0;
        pkt->side_data       = NULL;
        pkt->side_data_elems = 0;
    }
}

If there is no pkt->destruct function, no clean up takes place!