2012-03-29 5 views
0

libavcodec의 도움으로 비디오를 코드 변환하려고합니다. 큰 비디오 파일 (시간 이상)을 트랜스 코딩 할 때 avcodec_encode_video에서 막대한 메모리 누수가 발생합니다. 나는 그것을 디버깅하려했지만 서로 다른 비디오 파일을 가지고 서로 다른 함수가 누수를 일으켰다. 나는 그것에 대해 조금 혼란스러워했다. :) 여기 FFMPEG with QT memory leak은 내가 가진 동일한 문제이지만, 나는 그 사람이 그것을 어떻게 해결했는지 전혀 모른다. QtFFmpegwrapper는 내가하는 것을 똑같이하는 것처럼 보입니다 (또는 나는 뭔가를 놓쳤습니다).ffmpeg (libavcodec). avcodec_encode_video에서 메모리 누수가 발생했습니다.

내 방법이 더 낮습니다. 나는 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

첫 번째 단계는 가능한 경우 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 기능이없는 경우, 정리가 일어나지 않습니다!