From 2b64c339a9b9c0f683018ee203a862062a4efa71 Mon Sep 17 00:00:00 2001 From: fastZhe Date: Wed, 27 Nov 2024 22:30:35 +0800 Subject: [PATCH] * Add `FrameFilter.videoFilterArgs/audioFilterArgs` properties to support multiple different inputs (pull #2304) --- CHANGELOG.md | 1 + .../org/bytedeco/javacv/FFmpegFrameFilter.java | 16 ++++++++++++---- .../java/org/bytedeco/javacv/FrameFilter.java | 18 ++++++++++++++++++ 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 439d96e8..b794b8c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ + * Add `FrameFilter.videoFilterArgs/audioFilterArgs` properties to support multiple different inputs ([pull #2304](https://github.com/bytedeco/javacv/pull/2304)) * Ensure `FFmpegFrameGrabber.start()` skips over streams with no codecs ([issue #2299](https://github.com/bytedeco/javacv/issues/2299)) * Add `FFmpegLogCallback.logRejectedOptions()` for debugging purposes ([pull #2301](https://github.com/bytedeco/javacv/pull/2301)) diff --git a/src/main/java/org/bytedeco/javacv/FFmpegFrameFilter.java b/src/main/java/org/bytedeco/javacv/FFmpegFrameFilter.java index f42226ef..d0e64c5e 100644 --- a/src/main/java/org/bytedeco/javacv/FFmpegFrameFilter.java +++ b/src/main/java/org/bytedeco/javacv/FFmpegFrameFilter.java @@ -308,6 +308,12 @@ public synchronized void startUnsafe() throws Exception { frame = new Frame(); default_layout = new AVChannelLayout().retainReference(); + if (videoFilterArgs != null && videoInputs != videoFilterArgs.length) { + throw new Exception("The length of videoFilterArgs is different from videoInputs"); + } + if (audioFilterArgs != null && audioInputs != audioFilterArgs.length) { + throw new Exception("The length of audioFilterArgs is different from audioInputs"); + } if (image_frame == null || samples_frame == null || filt_frame == null) { throw new Exception("Could not allocate frames"); } @@ -342,14 +348,15 @@ private void startVideoUnsafe() throws Exception { /* buffer video source: the decoded frames from the decoder will be inserted here. */ AVRational r = av_d2q(aspectRatio > 0 ? aspectRatio : 1, 255); - String args = String.format(Locale.ROOT, "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d:frame_rate=%d/%d", - imageWidth, imageHeight, pixelFormat, time_base.num(), time_base.den(), r.num(), r.den(), frame_rate.num(), frame_rate.den()); buffersrc_ctx = new AVFilterContext[videoInputs]; setpts_ctx = new AVFilterContext[videoInputs]; for (int i = 0; i < videoInputs; i++) { String name = videoInputs > 1 ? i + ":v" : "in"; outputs[i] = avfilter_inout_alloc(); + String args = videoFilterArgs != null && videoFilterArgs[i] != null ? videoFilterArgs[i] + : String.format(Locale.ROOT, "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d:frame_rate=%d/%d", + imageWidth, imageHeight, pixelFormat, time_base.num(), time_base.den(), r.num(), r.den(), frame_rate.num(), frame_rate.den()); ret = avfilter_graph_create_filter(buffersrc_ctx[i] = new AVFilterContext().retainReference(), buffersrc, name, args, null, filter_graph); if (ret < 0) { @@ -447,8 +454,9 @@ private void startAudioUnsafe() throws Exception { /* buffer audio source: the decoded frames from the decoder will be inserted here. */ av_channel_layout_default(default_layout, audioChannels); - String aargs = String.format(Locale.ROOT, "channels=%d:sample_fmt=%d:sample_rate=%d:channel_layout=%d", - audioChannels, sampleFormat, sampleRate, default_layout.u_mask()); + String aargs = audioFilterArgs != null && audioFilterArgs[i] != null ? audioFilterArgs[i] + : String.format(Locale.ROOT, "channels=%d:sample_fmt=%d:sample_rate=%d:channel_layout=%d", + audioChannels, sampleFormat, sampleRate, default_layout.u_mask()); ret = avfilter_graph_create_filter(abuffersrc_ctx[i] = new AVFilterContext().retainReference(), abuffersrc, name, aargs, null, afilter_graph); if (ret < 0) { diff --git a/src/main/java/org/bytedeco/javacv/FrameFilter.java b/src/main/java/org/bytedeco/javacv/FrameFilter.java index b655a249..b224902c 100644 --- a/src/main/java/org/bytedeco/javacv/FrameFilter.java +++ b/src/main/java/org/bytedeco/javacv/FrameFilter.java @@ -43,12 +43,14 @@ public static FrameFilter createDefault(String filtersDescr, int imageWidth, int protected double frameRate; protected double aspectRatio; protected int videoInputs; + protected String[] videoFilterArgs; protected String afilters; protected int audioChannels; protected int sampleFormat; protected int sampleRate; protected int audioInputs; + protected String[] audioFilterArgs; public String getFilters() { return filters; @@ -99,6 +101,14 @@ public void setVideoInputs(int videoInputs) { this.videoInputs = videoInputs; } + public String[] getVideoFilterArgs() { + return videoFilterArgs; + } + + public void setVideoFilterArgs(String[] videoFilterArgs) { + this.videoFilterArgs = videoFilterArgs; + } + public int getAudioChannels() { return audioChannels; } @@ -127,6 +137,14 @@ public void setAudioInputs(int audioInputs) { this.audioInputs = audioInputs; } + public String[] getAudioFilterArgs() { + return audioFilterArgs; + } + + public void setAudioFilterArgs(String[] audioFilterArgs) { + this.audioFilterArgs = audioFilterArgs; + } + public static class Exception extends IOException { public Exception(String message) { super(message); } public Exception(String message, Throwable cause) { super(message, cause); }