diff --git a/CHANGELOG.md b/CHANGELOG.md index c98d36e8..5e5815f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ + * Add `FrameGrabber.videoSideData/audioSideData` properties and `FFmpegFrameGrabber.getDisplayRotation()` for convenience ([issue #1361](https://github.com/bytedeco/javacv/issues/1361)) * Add to `FFmpegFrameGrabber` and `FFmpegFrameRecorder` constructors taking a `URL` for convenience and clarity * Fix incorrect call to `opencv_calib3d.stereoRectify()` in `ProjectiveDevice` ([issue #1802](https://github.com/bytedeco/javacv/issues/1802)) * Retry after 10 ms when `av_read_frame()` returns `EAGAIN` in `FFmpegFrameGrabber.grabFrame()` ([issue #1784](https://github.com/bytedeco/javacv/issues/1784)) @@ -6,7 +7,7 @@ * Update `FFmpegStreamingTimeout` sample to use `timeout` instead of `stimeout` for RTSP ([pull #1758](https://github.com/bytedeco/javacv/pull/1758)) * Restore static calls to `FFmpegFrameGrabber.tryLoad()` and `FFmpegFrameRecorder.tryLoad()` ([issue #1756](https://github.com/bytedeco/javacv/issues/1756)) * Enable by default on `RealSense2FrameGrabber.start()` all color, depth, and IR streams as `videoStream` ([pull #1750](https://github.com/bytedeco/javacv/pull/1750)) - * Upgrade dependencies for OpenBLAS 0.3.20, OpenCV 4.6.0, FFmpeg 5.0.1, Leptonica 1.82.0 ([pull #1791](https://github.com/bytedeco/javacv/pull/1791)), Tesseract 5.1.0 + * Upgrade dependencies for OpenBLAS 0.3.20, OpenCV 4.6.0, FFmpeg 5.0.1, Leptonica 1.82.0 ([pull #1791](https://github.com/bytedeco/javacv/pull/1791)), Tesseract 5.2.0 ### February 11, 2022 version 1.5.7 * Fix accuracy and latency issues with `FFmpegFrameGrabber.setVideoFrameNumber()` ([pull #1734](https://github.com/bytedeco/javacv/pull/1734)) diff --git a/platform/pom.xml b/platform/pom.xml index c9a48cf5..1055ded9 100644 --- a/platform/pom.xml +++ b/platform/pom.xml @@ -93,7 +93,7 @@ org.bytedeco tesseract-platform - 5.1.0-${javacpp.version} + 5.2.0-${javacpp.version} diff --git a/pom.xml b/pom.xml index f9c53c6d..d1aa2aba 100644 --- a/pom.xml +++ b/pom.xml @@ -135,7 +135,7 @@ org.bytedeco tesseract - 5.1.0-${javacpp.version} + 5.2.0-${javacpp.version} diff --git a/src/main/java/org/bytedeco/javacv/FFmpegFrameGrabber.java b/src/main/java/org/bytedeco/javacv/FFmpegFrameGrabber.java index c67b851a..e154cb41 100644 --- a/src/main/java/org/bytedeco/javacv/FFmpegFrameGrabber.java +++ b/src/main/java/org/bytedeco/javacv/FFmpegFrameGrabber.java @@ -607,6 +607,48 @@ public double getVideoFrameRate() { return entry == null || entry.value() == null ? null : entry.value().getString(charset); } + @Override public Map getVideoSideData() { + if (video_st == null) { + return super.getVideoSideData(); + } + videoSideData = new HashMap(); + for (int i = 0; i < video_st.nb_side_data(); i++) { + AVPacketSideData sd = video_st.side_data().position(i); + String key = av_packet_side_data_name(sd.type()).getString(); + Buffer value = sd.data().capacity(sd.size()).asBuffer(); + videoSideData.put(key, value); + } + return videoSideData; + } + + @Override public Buffer getVideoSideData(String key) { + return getVideoSideData().get(key); + } + + /** Returns the rotation in degrees from the side data of the video stream, or 0 if unknown. */ + public double getDisplayRotation() { + ByteBuffer b = (ByteBuffer)getVideoSideData("Display Matrix"); + return b != null ? av_display_rotation_get(new IntPointer(new BytePointer(b))) : 0; + } + + @Override public Map getAudioSideData() { + if (audio_st == null) { + return super.getAudioSideData(); + } + audioSideData = new HashMap(); + for (int i = 0; i < audio_st.nb_side_data(); i++) { + AVPacketSideData sd = audio_st.side_data().position(i); + String key = av_packet_side_data_name(sd.type()).getString(); + Buffer value = sd.data().capacity(sd.size()).asBuffer(); + audioSideData.put(key, value); + } + return audioSideData; + } + + @Override public Buffer getAudioSideData(String key) { + return getAudioSideData().get(key); + } + /** default override of super.setFrameNumber implies setting * of a frame close to a video frame having that number */ @Override public void setFrameNumber(int frameNumber) throws Exception { diff --git a/src/main/java/org/bytedeco/javacv/FrameGrabber.java b/src/main/java/org/bytedeco/javacv/FrameGrabber.java index 6a58cd0e..f531536f 100644 --- a/src/main/java/org/bytedeco/javacv/FrameGrabber.java +++ b/src/main/java/org/bytedeco/javacv/FrameGrabber.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2019 Samuel Audet + * Copyright (C) 2009-2022 Samuel Audet * * Licensed either under the Apache License, Version 2.0, or (at your option) * under the terms of the GNU General Public License as published by @@ -27,6 +27,7 @@ import java.io.File; import java.io.IOException; import java.lang.reflect.InvocationTargetException; +import java.nio.Buffer; import java.nio.charset.Charset; import java.util.Arrays; import java.util.HashMap; @@ -200,6 +201,8 @@ public static enum SampleMode { protected Map metadata = new HashMap(); protected Map videoMetadata = new HashMap(); protected Map audioMetadata = new HashMap(); + protected Map videoSideData = new HashMap(); + protected Map audioSideData = new HashMap(); protected int frameNumber = 0; protected long timestamp = 0; protected int maxDelay = -1; @@ -485,6 +488,34 @@ public void setAudioMetadata(String key, String value) { audioMetadata.put(key, value); } + public Map getVideoSideData() { + return videoSideData; + } + public void setVideoSideData(Map videoSideData) { + this.videoSideData = videoSideData; + } + + public Buffer getVideoSideData(String key) { + return videoSideData.get(key); + } + public void setVideoSideData(String key, Buffer value) { + videoSideData.put(key, value); + } + + public Map getAudioSideData() { + return audioSideData; + } + public void setAudioSideData(Map audioSideData) { + this.audioSideData = audioSideData; + } + + public Buffer getAudioSideData(String key) { + return audioSideData.get(key); + } + public void setAudioSideData(String key, Buffer value) { + audioSideData.put(key, value); + } + public int getFrameNumber() { return frameNumber; }