当前位置: 首页 > 工具软件 > FFMPEG-Java > 使用案例 >

java ffmpeg内存耗用_ffmpeg - 使用ffmpeg进行转码可能会占用大量内存 - 堆栈内存溢出...

谭建章
2023-12-01

原因 :fifo过滤器在被请求之前不会输出帧。 并且ffmpeg仅请求属于具有最小时间戳的流的帧(请参见choose_output()函数)。 因此,当媒体中包含一些异常内容时,例如一小段没有音频的纯图像或某些音频解码错误,ffmpeg将继续请求音频帧,并在fifo过滤器中阻塞成千上万的视频帧,从而耗尽您的内存。

解决方案 :我遇到了同样的问题,并通过在fifo过滤器中添加了样本限制来解决了该问题。 当缓冲的帧数超过限制时,它将强制下一个链接的过滤器请求帧。 码:

libavfilter/fifo.c:

+ #define NB_SAMPLE_MAX 500 // About 1GB memory

typedef struct Buf {

AVFrame *frame;

struct Buf *next;

AVFrame *out;

int allocated_samples; ///< number of samples out was allocated for

+ int buffered_samples; ///< avoid memory overflow

} FifoContext;

static av_cold int init(AVFilterContext *ctx)

{

FifoContext *fifo = ctx->priv;

fifo->last = &fifo->root;

+ fifo->buffered_samples = 0;

return 0;

}

static int add_to_queue(AVFilterLink *inlink, AVFrame *frame)

{

FifoContext *fifo = inlink->dst->priv;

+ int i;

fifo->last->next = av_mallocz(sizeof(Buf));

if (!fifo->last->next) {

av_frame_free(&frame);

return AVERROR(ENOMEM);

}

fifo->last = fifo->last->next;

fifo->last->frame = frame;

+ fifo->buffered_samples++;

+ if (fifo->buffered_samples > NB_SAMPLE_MAX) {

+ av_log(NULL, AV_LOG_DEBUG, "Too many frames buffered in fifo.\n");

+ for (i = 0; i < inlink->dst->nb_outputs; i++) {

+ inlink->dst->outputs[i]->frame_wanted_out = 1; // it will force the next filter to request frames

+ }

+ }

return 0;

}

static void queue_pop(FifoContext *s)

{

Buf *tmp = s->root.next->next;

if (s->last == s->root.next)

s->last = &s->root;

av_freep(&s->root.next);

s->root.next = tmp;

+ if (s->buffered_samples > 0)

+ s->buffered_samples--;

}

我不确定这些更改是否还会导致其他问题。 如果有人有更好的解决方案,请告诉我。

 类似资料: