mpegts udp mutlicast 스트림에서 자막 트랙을 디코딩 할 때 avcodec_decode_subtitle2를 사용하여 메모리 누수가 발생합니다. 오디오 및 비디오 스트림은 문제가 없습니다. 그리고 세 개의 모든 스트림은 모든 버퍼를 미리 할당함으로써 수동으로 메모리 관리됩니다.FFMpeg DVB 자막 메모리 누수
정보가 거의 없지만 어딘가에 패치가 있다고 생각합니다.
저는 현재 안드로이드 용 armv7-a 용으로 컴파일 된 ffmpeg 2.0.4를 사용하고 있습니다.
나는 비디오 스트림이 비디오의 오버레이로 별도로 자막을 렌더링하고 있기 때문에 지금은 중요하지 않은 720x576 또는 576x576과 같은 다른 해상도 인 것으로 나타났습니다. (별도의 오버레이를 렌더링하는 변화) 내 원래 디코딩 기능은 다음과 같습니다
void ffProcessSubtitlePacket(AVPacket *pkt)
{
//LOGI("NATIVE FFMPEG SUBTITLE - Decoding subtitle packet");
int got = 0;
avcodec_decode_subtitle2(ffSubtitleContext, &ffSubtitleFrame, &got, pkt);
if (got)
{
//LOGI("NATIVE FFMPEG SUBTITLE - Got subtitle frame");
//LOGI("NATIVE FFMPEG SUBTITLE - Format = %d, Start = %d, End = %d, Rects = %d, PTS = %llu, AudioPTS = %llu, PacketPTS = %llu",
// ffSubtitleFrame.format, ffSubtitleFrame.start_display_time,
// ffSubtitleFrame.end_display_time, ffSubtitleFrame.num_rects,
// ffSubtitleFrame.pts, ffAudioGetPTS(), pkt->pts);
// now add the subtitle data to the list ready
for (int s = 0; s < ffSubtitleFrame.num_rects; s++)
{
ffSubtitle *sub = (ffSubtitle*)mmAlloc(sizeof(ffSubtitle)); //new ffSubtitle;
if (sub)
{
AVSubtitleRect *r = ffSubtitleFrame.rects[s];
AVPicture *p = &r->pict;
// set main data
sub->startPTS = pkt->pts + (uint64_t)ffSubtitleFrame.start_display_time;
sub->endPTS = pkt->pts + (uint64_t)ffSubtitleFrame.end_display_time * (uint64_t)500;
sub->nb_colors = r->nb_colors;
sub->xpos = r->x;
sub->ypos = r->y;
sub->width = r->w;
sub->height = r->h;
// allocate space for CLUT and image all in one chunk
sub->data = mmAlloc(r->nb_colors * 4 + r->w * r->h); //new char[r->nb_colors * 4 + r->w * r->h];
if (sub->data)
{
// copy the CLUT data
memcpy(sub->data, p->data[1], r->nb_colors * 4);
// copy the bitmap onto the end
memcpy(sub->data + r->nb_colors * 4, p->data[0], r->w * r->h);
// check for duplicate subtitles and remove them as this
// one replaces it with a new bitmap data
int pos = ffSubtitles.size();
while (pos--)
{
ffSubtitle *s = ffSubtitles[pos];
if (s->xpos == sub->xpos &&
s->ypos == sub->ypos &&
s->width == sub->width &&
s->height == sub->height)
{
//delete s;
ffSubtitles.erase(ffSubtitles.begin() + pos);
//LOGI("NATIVE FFMPEG SUBTITLE - Removed old duplicate subtitle, size %d", ffSubtitles.size());
}
}
// append to subtitles list
ffSubtitles.push_back(sub);
char *dat; // data pointer used for the CLUT table
//LOGI("NATIVE FFMPEG SUBTITLE - Added %d,%d - %d,%d, Queue %d, Length = %d",
// r->x, r->y, r->w, r->h, ffSubtitles.size(), ffSubtitleFrame.end_display_time);
// convert the CLUT (RGB) to YUV values
dat = sub->data;
for (int c = 0; c < r->nb_colors; c++)
{
int r = dat[0];
int g = dat[1];
int b = dat[2];
int y = (( 65 * r + 128 * g + 24 * b + 128) >> 8) + 16;
int u = ((-37 * r - 74 * g + 112 * b + 128) >> 8) + 128;
int v = ((112 * r - 93 * g - 18 * b + 128) >> 8) + 128;
*dat++ = (char)y;
*dat++ = (char)u;
*dat++ = (char)v;
dat++; // skip the alpha channel
}
}
else
{
//delete sub;
sub = 0;
LOGI("NATIVE FFMPEG SUBTITLE - Memory allocation error CLUT and BITMAP");
}
}
else
{
LOGI("NATIVE FFMPEG SUBTITLE - Memory allocation error ffSubtitle struct");
mmGarbageCollect();
ffSubtitles.clear();
}
}
}
}
void ffSubtitleRenderCheck(int bpos)
{
if (ffSubtitleID == -1 || !usingSubtitles)
{
// empty the list in case of memory leaks
ffSubtitles.clear();
mmGarbageCollect();
return;
}
uint64_t audioPTS = ffAudioGetPTS();
int pos = 0;
// draw the subtitle list to the YUV frames
char *yframe = ffVideoBuffers[bpos].yFrame;
char *uframe = ffVideoBuffers[bpos].uFrame;
char *vframe = ffVideoBuffers[bpos].vFrame;
int ywidth = fv.frameActualWidth; // actual width with padding
int uvwidth = fv.frameAWidthHalf; // and for uv frames
while (pos < ffSubtitles.size())
{
ffSubtitle *sub = ffSubtitles[pos];
if (sub->startPTS >= audioPTS) // okay to draw this one?
{
//LOGI("NATIVE FFMPEG SUBTITLE - Rendering subtitle bitmap %d", pos);
char *clut = sub->data; // colour table
char *dat = clut + sub->nb_colors * 4; // start of bitmap data
int w = sub->width;
int h = sub->height;
int x = sub->xpos;
int y = sub->ypos;
for (int xpos = 0; xpos < w; xpos++)
{
for (int ypos = 0; ypos < h; ypos++)
{
// get colour for pixel
char bcol = dat[ypos * w + xpos];
if (bcol != 0) // ignore 0 pixels
{
char cluty = clut[bcol * 4 + 0]; // get colours from CLUT
char clutu = clut[bcol * 4 + 1];
char clutv = clut[bcol * 4 + 2];
// draw to Y frame
int newx = x + xpos;
int newy = y + ypos;
yframe[newy * ywidth + newx] = cluty;
// draw to uv frames if we have a quarter pixel only
if ((newy & 1) && (newx & 1))
{
uframe[(newy >> 1) * uvwidth + (newx >> 1)] = clutu;
vframe[(newy >> 1) * uvwidth + (newx >> 1)] = clutv;
}
}
}
}
}
pos++;
}
// Last thing is to erase timed out subtitles
pos = ffSubtitles.size();
while (pos--)
{
ffSubtitle *sub = ffSubtitles[pos];
if (sub->endPTS < audioPTS)
{
//delete sub;
ffSubtitles.erase(ffSubtitles.begin() + pos);
//LOGI("NATIVE FFMPEG SUBTITLE - Removed timed out subtitle");
}
}
if (ffSubtitles.size() == 0)
{
// garbage collect the custom memory pool
mmGarbageCollect();
}
//LOGI("NATIVE FFMPEG SUBTITLE - Size of subtitle list = %d", ffSubtitles.size());
}
모든 정보를 주시면 감사하겠습니다 아니면는 FFmpeg의 최신 버전으로 업그레이드해야?