diff --git a/CHANGELOG.md b/CHANGELOG.md index 07af6976..8ed85469 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,6 @@ + * Add `FFmpegLogCallback.logRejectedOptions()` for debugging purposes ([pull #2301](https://github.com/bytedeco/javacv/pull/2301)) + ### November 16, 2024 version 1.5.11 * Fix memory leak in `FFmpegFrameGrabber` when decoding from `InputStream` ([pull #2214](https://github.com/bytedeco/javacv/pull/2214)) * Upgrade dependencies for OpenBLAS 0.3.28, OpenCV 4.10.0, FFmpeg 7.1, Leptonica 1.85.0, Tesseract 5.5.0 diff --git a/src/main/java/org/bytedeco/javacv/FFmpegFrameGrabber.java b/src/main/java/org/bytedeco/javacv/FFmpegFrameGrabber.java index 034f247a..a0e4954c 100644 --- a/src/main/java/org/bytedeco/javacv/FFmpegFrameGrabber.java +++ b/src/main/java/org/bytedeco/javacv/FFmpegFrameGrabber.java @@ -989,6 +989,7 @@ public synchronized void startUnsafe(boolean findStreamInfo) throws Exception { throw new Exception("avformat_open_input() error " + ret + ": Could not open input \"" + filename + "\". (Has setFormat() been called?)"); } } + FFmpegLogCallback.logRejectedOptions(options, "avformat_open_input"); av_dict_free(options); oc.max_delay(maxDelay); @@ -1072,6 +1073,7 @@ public synchronized void startUnsafe(boolean findStreamInfo) throws Exception { if ((ret = avcodec_open2(video_c, codec, options)) < 0) { throw new Exception("avcodec_open2() error " + ret + ": Could not open video codec."); } + FFmpegLogCallback.logRejectedOptions(options, "avcodec_open2"); av_dict_free(options); // Hack to correct wrong frame rates that seem to be generated by some codecs @@ -1123,6 +1125,7 @@ public synchronized void startUnsafe(boolean findStreamInfo) throws Exception { if ((ret = avcodec_open2(audio_c, codec, options)) < 0) { throw new Exception("avcodec_open2() error " + ret + ": Could not open audio codec."); } + FFmpegLogCallback.logRejectedOptions(options, "avcodec_open2"); av_dict_free(options); // Allocate audio samples frame diff --git a/src/main/java/org/bytedeco/javacv/FFmpegFrameRecorder.java b/src/main/java/org/bytedeco/javacv/FFmpegFrameRecorder.java index f6567fbe..47f0fa31 100644 --- a/src/main/java/org/bytedeco/javacv/FFmpegFrameRecorder.java +++ b/src/main/java/org/bytedeco/javacv/FFmpegFrameRecorder.java @@ -798,6 +798,7 @@ public synchronized void startUnsafe() throws Exception { av_dict_free(options); throw new Exception("avcodec_open2() error " + ret + ": Could not open video codec."); } + FFmpegLogCallback.logRejectedOptions(options, "avcodec_open2"); av_dict_free(options); video_outbuf = null; @@ -879,6 +880,7 @@ public synchronized void startUnsafe() throws Exception { av_dict_free(options); throw new Exception("avcodec_open2() error " + ret + ": Could not open audio codec."); } + FFmpegLogCallback.logRejectedOptions(options, "avcodec_open2"); av_dict_free(options); audio_outbuf_size = 256 * 1024; @@ -962,6 +964,7 @@ public synchronized void startUnsafe() throws Exception { av_dict_free(options); throw new Exception(errorMsg); } + FFmpegLogCallback.logRejectedOptions(options, "avio_open2"); oc.pb(pb); } @@ -976,6 +979,7 @@ public synchronized void startUnsafe() throws Exception { av_dict_free(options); throw new Exception(errorMsg); } + FFmpegLogCallback.logRejectedOptions(options, "avformat_write_header"); av_dict_free(options); if (av_log_get_level() >= AV_LOG_INFO) { diff --git a/src/main/java/org/bytedeco/javacv/FFmpegLogCallback.java b/src/main/java/org/bytedeco/javacv/FFmpegLogCallback.java index 593869ee..d9780625 100644 --- a/src/main/java/org/bytedeco/javacv/FFmpegLogCallback.java +++ b/src/main/java/org/bytedeco/javacv/FFmpegLogCallback.java @@ -61,6 +61,18 @@ public static void setLevel(int level) { av_log_set_level(level); } + /** Logs the given rejected options regarding the given command */ + public static void logRejectedOptions(final AVDictionary options, final String command) { + if (getLevel() >= AV_LOG_INFO && av_dict_count(options) > 0) { + final StringBuilder sb = new StringBuilder(command + " rejected some options:"); + AVDictionaryEntry e = null; + while ((e = av_dict_iterate(options, e)) != null) { + sb.append("\tOption: ").append(e.key().getString()).append(", value: ").append(e.value().getString()); + } + logger.info(sb.toString()); + } + } + @Override public void call(int level, BytePointer msg) { switch (level) { case AV_LOG_PANIC: