В основном это мой подход:
Код: Выделить всё
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;
}
Процесс работает, но мое приложение занимает до 20 ГБ ОЗУ (сообщает команда top). Я новичок в этой области обработки видео и не понимаю, почему используется так много памяти.
Я пытался изучить дампы динамической памяти, и byte[], похоже, является вещь, которая занимает больше всего памяти. Кроме того, я рассмотрел эволюцию памяти с помощью VisualVM, и вот как память развивается во времени:
[img]https: //i.sstatic.net/tCMecM0y.png[/img]
Как видите, каждый раз он поднимается все выше и выше, пока в какой-то момент не произойдет сбой или не зависнет мой компьютер. .
Я не привык к такого рода проблемам, поэтому, если у кого-то есть идеи, в чем может быть проблема, или если есть лучший способ реализовать то, что мне нужно, я открыт для предложений.
В моем случае действительно ли мне нужно использовать FrameRecorder? Есть ли лучший способ реализовать эту функциональность в Java?
Подробнее здесь: https://stackoverflow.com/questions/791 ... acv-ffmpeg