我正在尝试使用libavcodec对视频进行转码。 在转码大视频文件(小时或更长时间)时,我在avcodec_encode_video中获得了巨大的内存泄漏。我试图调试它,但是对于不同的视频文件,不同的功能会产生泄漏,我对此有点困惑:)。这里FFMPEG with QT memory leak和我有同样的问题,但我不知道那个人怎么解决它。 QtFFmpegwrapper似乎和我做的一样(或者我错过了一些东西)。
我的方法较低。我用av_free和av_free_packet来处理aFrame和aPacket。
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;
}
答案 0 :(得分:1)
如果可以,第一步是尝试在Linux机器上的Valgrind下重现您的问题。
ffmpeg编码器和解码器通常不动态分配内存;他们在呼叫之间重用缓冲。泄漏通常会出现在某处的框架中。
请注意,如果数据包具有析构函数,av_free_packet
将仅释放动态分配的缓冲区!
了解如何在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;
}
}
如果没有pkt->destruct
功能,则不进行清理!