Эффективный способ обработки видеопотока с помощью JavaCV FFMPEGJAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Эффективный способ обработки видеопотока с помощью JavaCV FFMPEG

Сообщение Anonymous »

Я пытаюсь создать Java-приложение, которое обрабатывает прямой поток с камеры, а затем передает обработанный контент куда-то еще. На данный момент я реализовал кое-что, что работает, но считаю, что это очень неэффективно с точки зрения памяти.
В основном это мой подход:

Код: Выделить всё

  private void processCamera() {
try (FFmpegFrameGrabber frameGrabber = buildGrabber();
ByteArrayOutputStream output = new ByteArrayOutputStream(1024 * 1024);
FFmpegFrameRecorder frameRecorder = buildRecorder(frameGrabber, output)) {

frameGrabber.start();
frameRecorder.start();

Frame frame;

while (frame = frameGrabber.grab() != null) {
Frame analyzedFrame = analyzeFrame(frame);
frameRecorder.setTimestamp(frameGrabber.getTimestamp());
frameRecorder.record(analyzedFrame);

if (output.size() > 0) {
outputHelper.sendData(output.toByteArray());
outputHelper.reset();
}

frame.close();
}
} catch (Exception e) {}
}

Код: Выделить всё

  private FFmpegFrameGrabber buildGrabber() throws FFmpegFrameGrabber.Exception {
FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(URL);
frameGrabber.setFormat("rtsp");
frameGrabber.setOption("hwaccel", "cuda");
frameGrabber.setOption("rtsp_transport", "tcp");
frameGrabber.setVideoCodec(avcodec.AV_CODEC_ID_H264);

return frameGrabber;
}

private FFmpegFrameRecorder buildRecorder(
FFmpegFrameGrabber frameGrabber, ByteArrayOutputStream outputStream) {
FFmpegFrameRecorder frameRecorder = new FFmpegFrameRecorder(outputStream, WIDTH, HEIGHT);
frameRecorder.setFormat("webm");
frameRecorder.setFrameRate(frameGrabber.getFrameRate());
frameRecorder.setOption("hwaccel", "cuda");
frameRecorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);
frameRecorder.setVideoCodec(avcodec.AV_CODEC_ID_VP8);
frameRecorder.setVideoOption("deadline", "realtime");
frameRecorder.setVideoOption("cpu-used", "8");
frameRecorder.setVideoBitrate(2200000);
frameRecorder.setOption("bufsize", "1M");
frameRecorder.setOption("output_queue_size", "1024");
frameRecorder.setOption("cluster_time_limit", "3000");
frameRecorder.setOption("cluster_size_limit", "1M");
frameRecorder.setOption("input_queue_size", "1024");
return frameRecorder;
}

Итак, основная идея заключается в том, что я непрерывно захватываю кадры, анализирую их и записываю с помощью FFmpegFrameRecorder, когда на выходе собирается достаточно данных, тогда мы отправьте его вперед.
Процесс работает, но мое приложение занимает до 20 ГБ ОЗУ (сообщает команда top). Я новичок в этой области обработки видео и не понимаю, почему используется так много памяти.
Я пытался изучить дампы динамической памяти, и byte[], похоже, является вещь, которая занимает больше всего памяти. Кроме того, я рассмотрел эволюцию памяти с помощью VisualVM, и вот как память развивается во времени:
[img]https: //i.sstatic.net/tCMecM0y.png[/img]

Как видите, каждый раз он поднимается все выше и выше, пока в какой-то момент не произойдет сбой или не зависнет мой компьютер. .
Я не привык к такого рода проблемам, поэтому, если у кого-то есть идеи, в чем может быть проблема, или если есть лучший способ реализовать то, что мне нужно, я открыт для предложений.
В моем случае действительно ли мне нужно использовать FrameRecorder? Есть ли лучший способ реализовать эту функциональность в Java?

Подробнее здесь: https://stackoverflow.com/questions/791 ... acv-ffmpeg
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «JAVA»