diff options
author | Sven Göthel <[email protected]> | 2024-02-02 08:27:49 +0100 |
---|---|---|
committer | Sven Göthel <[email protected]> | 2024-02-02 08:27:49 +0100 |
commit | 23cf5279472d3ae1b2d8d1904e6b1f1e7fd8f012 (patch) | |
tree | 7f943da4a1a6c8fd917eff160b45b700a125f258 /src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java | |
parent | 9ff736464e0d2762c424bab66bc6d03ccc6e6d11 (diff) |
Bug 1494 - GLMediaPlayer/GraphUI: Support Displaying Bitmap'ed Subtitles (PGS ..) via FFMPEGFMediaPlayer/FFmpeg
FFMPEGFMediaPlayer related changes:
- Add libswscale (6th FFmpeg lib used) for sws_getCachedContext(), sws_scale() and sws_freeContext(),
used natively to convert the palette'ed bitmap into RGBA colorspace -> GL texture
- Handling AVSubtitleRect.type SUBTITLE_BITMAP
-- only handled if libswscale is available
-- config/adjust texture object
-- sws_scale palette'ed bitmap to texture
-- intermediate memory is cached, may be resized and free'ed at destroy
-- texture objects are managed and passed from GLMediaPlayerImpl,
as they are also forwarded to player client via SubBitmapEvent
- Passing the AVCodecID to GLMediaPlayerImpl, converted to our CodecID enum.
- Unifying creation and opening of AVCodecContext with 'createOpenedAVCodecContext(..)'
+++
SubtitleEvent*
- SubTextEvent now also handles ASS.Dialogue (FFmpeg 4)
besides ASS.Event (FFmpeg 5, 6, ..).
+++
GLMediaPlayerImpl
- Added ringbuffer subTexFree, managing Texture for bitmap'ed subtitles
-- Uses 1 bitmap-subtitle Texture per used textureCount in cache,
as one bitmap-subtile can be displayed per frame.
Could be potentially reduced to just 2 .. but resources used are
relatively low here.
- Validating subTexFree + videoFramesFree usage,
use blocking get/put ringbuffer due to utilization from different threads.
- Receives subtitle content from native getNextPacket0() via callback,
creates SubtitleEvent instance and passes it to a SubtitleEventListener - if exists.
(See MediaButton example)
-- SubBitmapEvent also gets its special SubBitmapEvent.TextureOwner to handle client releasing
the event and allowing us to put back the Texture resource to 'subTexFree'.
This passing through of the Texture object is probably a weakness of this lifecycle
and requires the client to ensure SubtitleEvent.release() gets called.
See MediaButton example!
- Exposing CodecID, allowing clients like MediaButton to handle SubtitleEvent content according to codec
Diffstat (limited to 'src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java')
-rw-r--r-- | src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java | 41 |
1 files changed, 34 insertions, 7 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java b/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java index 2767ea7ef..4011bddcb 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java +++ b/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java @@ -40,6 +40,7 @@ import com.jogamp.common.av.AudioSink; import com.jogamp.common.av.PTS; import com.jogamp.common.av.TimeFrameI; import com.jogamp.common.net.Uri; +import com.jogamp.math.Vec4f; import com.jogamp.opengl.util.texture.Texture; import com.jogamp.opengl.util.texture.TextureSequence; @@ -286,7 +287,7 @@ public interface GLMediaPlayer extends TextureSequence { } @Override public String toString() { - return String.format("%02d: [%s .. %s] %s", id, PTS.millisToTimeStr(start), PTS.millisToTimeStr(end), title); + return String.format("%02d: [%s .. %s] %s", id, PTS.toTimeStr(start), PTS.toTimeStr(end), title); } } @@ -326,17 +327,19 @@ public interface GLMediaPlayer extends TextureSequence { /** Attribute change bits */ public static enum Bit { /** State changed to {@link State#Initialized}. See <a href="#lifecycle">Lifecycle</a>.*/ - Init ( 1<<0 ), + Init ( 1<<0 ), /** State changed to {@link State#Uninitialized}. See <a href="#lifecycle">Lifecycle</a>.*/ Uninit ( 1<<1 ), /** State changed to {@link State#Playing}. See <a href="#lifecycle">Lifecycle</a>.*/ - Play ( 1<<2 ), + Play ( 1<<2 ), /** State changed to {@link State#Paused}. See <a href="#lifecycle">Lifecycle</a>.*/ Pause ( 1<<3 ), + /** Time position has changed, e.g. via {@link GLMediaPlayer#seek(int)}.*/ + Seek ( 1<<4 ), /** End of stream reached. See <a href("#lifecycle">Lifecycle</a>.*/ - EOS ( 1<<4 ), + EOS ( 1<<5 ), /** An error occurred, e.g. during off-thread initialization. See {@link StreamException} and <a href("#lifecycle">Lifecycle</a>. */ - Error ( 1<<5 ), + Error ( 1<<6 ), /** Stream video id change. */ VID ( 1<<16 ), @@ -352,8 +355,14 @@ public interface GLMediaPlayer extends TextureSequence { BPS ( 1<<21 ), /** Stream length change. */ Length ( 1<<22 ), - /** Stream codec change. */ - Codec ( 1<<23 ); + /** Audio, video or subtitle stream codec change. */ + Codec ( 1<<23 ), + /** Audio stream codec change. */ + ACodec ( 1<<24 ), + /** Video stream codec change. */ + VCodec ( 1<<25 ), + /** Subtitle stream codec change. */ + SCodec ( 1<<26 ); Bit(final int v) { value = v; } public final int value; @@ -833,18 +842,36 @@ public interface GLMediaPlayer extends TextureSequence { /** * <i>Warning:</i> Optional information, may not be supported by implementation. + * @return the {@link CodecID} of the video stream, if available + */ + public CodecID getVideoCodecID(); + + /** + * <i>Warning:</i> Optional information, may not be supported by implementation. * @return the codec of the video stream, if available */ public String getVideoCodec(); /** * <i>Warning:</i> Optional information, may not be supported by implementation. + * @return the {@link CodecID} of the audio stream, if available + */ + public CodecID getAudioCodecID(); + + /** + * <i>Warning:</i> Optional information, may not be supported by implementation. * @return the codec of the audio stream, if available */ public String getAudioCodec(); /** * <i>Warning:</i> Optional information, may not be supported by implementation. + * @return the {@link CodecID} of the subtitle stream, if available + */ + public CodecID getSubtitleCodecID(); + + /** + * <i>Warning:</i> Optional information, may not be supported by implementation. * @return the codec of the subtitle stream, if available */ public String getSubtitleCodec(); |