aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/com/jogamp/opengl
diff options
context:
space:
mode:
Diffstat (limited to 'src/jogl/classes/com/jogamp/opengl')
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java41
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/av/SubBitmapEvent.java9
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/av/SubEmptyEvent.java9
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/av/SubTextEvent.java243
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/av/SubTextEventLine.java142
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/av/SubtitleEvent.java31
6 files changed, 299 insertions, 176 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();
diff --git a/src/jogl/classes/com/jogamp/opengl/util/av/SubBitmapEvent.java b/src/jogl/classes/com/jogamp/opengl/util/av/SubBitmapEvent.java
index 68f25d046..0032aeffc 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/av/SubBitmapEvent.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/av/SubBitmapEvent.java
@@ -61,20 +61,13 @@ public class SubBitmapEvent extends SubtitleEvent {
* @param owner {@link Texture} owner code-stub to release the texture
*/
public SubBitmapEvent(final CodecID codec, final Vec2i pos, final Vec2i dim, final Texture tex, final int pts_start, final int pts_end, final TextureOwner owner) {
- super(codec, pts_start, pts_end);
+ super(SubtitleEvent.Type.Bitmap, codec, pts_start, pts_end);
position = pos;
dimension = dim;
texture = tex;
this.owner = owner;
}
- @Override
- public final boolean isTextASS() { return false; }
- @Override
- public final boolean isBitmap() { return true; }
- @Override
- public final boolean isEmpty() { return false; }
-
/**
* {@inheritDoc}
* <p>
diff --git a/src/jogl/classes/com/jogamp/opengl/util/av/SubEmptyEvent.java b/src/jogl/classes/com/jogamp/opengl/util/av/SubEmptyEvent.java
index c49558c57..d6796dc4d 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/av/SubEmptyEvent.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/av/SubEmptyEvent.java
@@ -34,17 +34,10 @@ public class SubEmptyEvent extends SubtitleEvent {
* Empty event ctor
*/
public SubEmptyEvent(final int pts_start, final int pts_end) {
- super(CodecID.NONE, pts_start, pts_end);
+ super(SubtitleEvent.Type.Empty, CodecID.NONE, pts_start, pts_end);
}
@Override
- public final boolean isTextASS() { return false; }
- @Override
- public final boolean isBitmap() { return false; }
- @Override
- public final boolean isEmpty() { return true; }
-
- @Override
public void release() {} // nothing to be released back to the owner
@Override
diff --git a/src/jogl/classes/com/jogamp/opengl/util/av/SubTextEvent.java b/src/jogl/classes/com/jogamp/opengl/util/av/SubTextEvent.java
new file mode 100644
index 000000000..d699d9300
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/av/SubTextEvent.java
@@ -0,0 +1,243 @@
+/**
+ * Copyright 2024 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package com.jogamp.opengl.util.av;
+
+import java.time.format.DateTimeParseException;
+
+import com.jogamp.common.av.PTS;
+
+/**
+ * Text Event Line including ASS/SAA of {@link SubtitleEvent}
+ * <p>
+ * See http://www.tcax.org/docs/ass-specs.htm
+ * </p>
+ */
+public class SubTextEvent extends SubtitleEvent {
+ /** Text formatting */
+ public enum TextFormat {
+ /** Multiple ASS formats may be passed, see {@link ASSType}. */
+ ASS,
+ /** Just plain text */
+ TEXT,
+ };
+ /** ASS Formatting Type */
+ public enum ASSType {
+ /**
+ * ASS dialogue-line output w/ start and end (Given by FFmpeg 4.*)
+ * <pre>
+ 0 1 2 3 4 5 6 7 8 9
+ Marked, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
+
+ 'Dialogue: 0,0:02:02.15,0:02:02.16,Default,,0,0,0,,trying to force him to travel to that'
+ * </pre>
+ */
+ DIALOGUE,
+ /**
+ * FFMpeg ASS event-line output w/o start, end (Given by FFmpeg 5.*, 6.*, ..)
+ * <pre>
+ 0 1 2 3 4 5 6 7 8
+ Seq, Layer, Style, Name, MarginL, MarginR, MarginV, Effect, TEXT
+ * </pre>
+ */
+ EVENT,
+ /** Just plain text */
+ TEXT
+ }
+ /** {@link TextFormat} of this text subtitle event. */
+ public final TextFormat textFormat;
+ /** {@link ASSType} sub-type */
+ public final ASSType assType;
+ /** Start time in milliseconds, or -1. */
+ public final int start;
+ /** End time in milliseconds, or -1. */
+ public final int end;
+ public final String style;
+
+ public final int seqnr;
+ public final int layer;
+
+ public final String name;
+ public final String effect;
+ /** Actual subtitle text */
+ public final String text;
+ /** Number of lines of {@link #text}, i.e. occurrence of {@code \n} + 1. */
+ public final int lines;
+
+ private static boolean DEBUG = false;
+
+ /**
+ * ASS/SAA Event Line ctor
+ * @param codec the {@link CodecID}
+ * @param fmt input format of {@code ass}, currently only {@link SubTextEvent.TextFormat#ASS} and {@link SubTextEvent.TextFormat#TEXT} is supported
+ * @param ass ASS/SAA compatible event line according to {@link ASSType}
+ * @param pts_start pts start in ms, provided for {@link SubTextEvent.TextFormat#ASS} and {@link SubTextEvent.TextFormat#TEXT}
+ * @param pts_end pts end in ms, provided for {@link SubTextEvent.TextFormat#ASS} and {@link SubTextEvent.TextFormat#TEXT}
+ */
+ public SubTextEvent(final CodecID codec, final TextFormat fmt, final String ass, final int pts_start, final int pts_end) {
+ super(SubtitleEvent.Type.Text, codec, pts_start, pts_end);
+ this.textFormat = fmt;
+ ASSType assType = ASSType.TEXT;
+ int start = -1;
+ int end = -1;
+ int seqnr = 0;
+ int layer = 0;
+ String style = "Default";
+ String name = "";
+ String effect = "";
+ String text = "";
+ boolean done = false;
+ if( TextFormat.ASS == fmt ) {
+ final int len = null != ass ? ass.length() : 0;
+ {
+ // ASSType.DIALOGUE
+ int part = 0;
+ for(int i=0; 10 > part && len > i; ) {
+ if( 9 == part ) {
+ text = ass.substring(i);
+ done = true;
+ assType = ASSType.DIALOGUE;
+ } else {
+ final int j = ass.indexOf(',', i);
+ if( 0 > j ) {
+ break;
+ }
+ final String v = ass.substring(i, j);
+ try {
+ switch(part) {
+ case 1:
+ start = PTS.toMillis(v, true);
+ break;
+ case 2:
+ end = PTS.toMillis(v, true);
+ break;
+ case 3:
+ style = v;
+ break;
+ case 4:
+ name = v;
+ break;
+ case 8:
+ effect = v;
+ break;
+ }
+ } catch(final DateTimeParseException pe) {
+ if( DEBUG ) {
+ System.err.println("ASS.DIALG parsing error of part "+part+" '"+v+"' of '"+ass+"'");
+ }
+ break;
+ }
+ i = j + 1;
+ }
+ ++part;
+ }
+ }
+ if( !done ) {
+ // ASSType.EVENT
+ int part = 0;
+ for(int i=0; 9 > part && len > i; ) {
+ if( 8 == part ) {
+ text = ass.substring(i);
+ done = true;
+ assType = ASSType.EVENT;
+ } else {
+ final int j = ass.indexOf(',', i);
+ if( 0 > j ) {
+ break;
+ }
+ final String v = ass.substring(i, j);
+ try {
+ switch(part) {
+ case 0:
+ seqnr = Integer.valueOf(v);
+ break;
+ case 1:
+ layer = Integer.valueOf(v);
+ break;
+ case 2:
+ style = v;
+ break;
+ case 3:
+ name = v;
+ break;
+ case 7:
+ effect = v;
+ break;
+ }
+ } catch(final NumberFormatException nfe) {
+ if( DEBUG ) {
+ System.err.println("ASS.EVENT parsing error of part "+part+" '"+v+"' of '"+ass+"'");
+ }
+ break;
+ }
+ i = j + 1;
+ }
+ ++part;
+ }
+ }
+ }
+ if( !done && TextFormat.TEXT == fmt ) {
+ text = ass;
+ done = true;
+ assType = ASSType.TEXT;
+ }
+ this.assType = assType;
+ this.start = start;
+ this.end = end;
+ this.seqnr = seqnr;
+ this.layer = layer;
+ this.style = style;
+ this.name = name;
+ this.effect = effect;
+ this.text = text.replace("\\N", "\n");
+ {
+ final int len = this.text.length();
+ int lc = 1;
+ for(int i=0; len > i; ) {
+ final int j = this.text.indexOf("\n", i);
+ if( 0 > j ) {
+ break;
+ }
+ ++lc;
+ i = j + 1;
+ }
+ this.lines = lc;
+ }
+ }
+
+ @Override
+ public void release() {} // nothing to be released back to the owner
+
+ @Override
+ public String toString() {
+ final String start_s = 0 <= start ? PTS.toTimeStr(start, true) : "undef";
+ final String end_s = 0 <= end ? PTS.toTimeStr(end, true) : "undef";
+ final String fms_s = TextFormat.ASS == textFormat ? "ASS("+assType+")" : textFormat.toString();
+ return getStartString()+", "+fms_s+", #"+seqnr+", l_"+layer+
+ ", ["+start_s+".."+end_s+"], style "+style+", name '"+name+"', effect '"+effect+"': '"+text+"' ("+lines+")]";
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/av/SubTextEventLine.java b/src/jogl/classes/com/jogamp/opengl/util/av/SubTextEventLine.java
deleted file mode 100644
index c867dea9c..000000000
--- a/src/jogl/classes/com/jogamp/opengl/util/av/SubTextEventLine.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/**
- * Copyright 2024 JogAmp Community. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are
- * permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice, this list
- * of conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and documentation are those of the
- * authors and should not be interpreted as representing official policies, either expressed
- * or implied, of JogAmp Community.
- */
-package com.jogamp.opengl.util.av;
-
-/**
- * Text Event Line including ASS/SAA of {@link SubtitleEvent}
- * <p>
- * See http://www.tcax.org/docs/ass-specs.htm
- * </p>
- */
-public class SubTextEventLine extends SubtitleEvent {
- public enum Format {
- /** Denoting {@link SubASSEventLine} using FFMpeg output w/o start, end:
- * <pre>
- 0 1 2 3 4 5 6 7 8
- Seq, Layer, Style, Name, MarginL, MarginR, MarginV, Effect, TEXT
- * </pre>
- */
- ASS_FFMPEG,
- /** Denoting {@link SubASSEventLine}, just the plain text part */
- TEXT,
- };
- /** {@link Format} of this text subtitle event. */
- public final Format format;
- public final int seqnr;
- public final int layer;
- public final String style;
- public final String name;
- /** Actual subtitle text */
- public final String text;
- /** Number of lines of {@link #text}, i.e. occurrence of {@code \n} + 1. */
- public final int lines;
-
- /**
- * ASS/SAA Event Line ctor
- * @param codec the {@link CodecID}
- * @param fmt input format of {@code ass}, currently only {@link SubTextEventLine.Format#ASS_FFMPEG} and {@link SubTextEventLine.Format#TEXT} is supported
- * @param ass ASS/SAA compatible event line according to {@code fmt}
- * @param pts_start pts start in ms, provided for {@link SubTextEventLine.Format#ASS_FFMPEG} and {@link SubTextEventLine.Format#TEXT}
- * @param pts_end pts end in ms, provided for {@link SubTextEventLine.Format#ASS_FFMPEG} and {@link SubTextEventLine.Format#TEXT}
- */
- public SubTextEventLine(final CodecID codec, final Format fmt, final String ass, final int pts_start, final int pts_end) {
- super(codec, pts_start, pts_end);
- this.format = fmt;
- int seqnr = 0;
- int layer = 0;
- String style = "Default";
- String name = "";
- String text = "";
- if( Format.ASS_FFMPEG == fmt ) {
- final int len = null != ass ? ass.length() : 0;
- int part = 0;
- for(int i=0; 9 > part && len > i; ) {
- if( 8 == part ) {
- text = ass.substring(i);
- } else {
- final int j = ass.indexOf(',', i);
- if( 0 > j ) {
- break;
- }
- final String v = ass.substring(i, j);
- switch(part) {
- case 0:
- seqnr = Integer.valueOf(v);
- break;
- case 1:
- layer = Integer.valueOf(v);
- break;
- case 2:
- style = v;
- break;
- case 3:
- name = v;
- break;
- }
- i = j + 1;
- }
- ++part;
- }
- } else if( Format.TEXT == fmt ) {
- text = ass;
- }
- this.seqnr = seqnr;
- this.layer = layer;
- this.style = style;
- this.name = name;
- this.text = text.replace("\\N", "\n");
- {
- final int len = this.text.length();
- int lc = 1;
- for(int i=0; len > i; ) {
- final int j = this.text.indexOf("\n", i);
- if( 0 > j ) {
- break;
- }
- ++lc;
- i = j + 1;
- }
- this.lines = lc;
- }
- }
-
- @Override
- public final boolean isTextASS() { return true; }
- @Override
- public final boolean isBitmap() { return false; }
- @Override
- public final boolean isEmpty() { return false; }
-
- @Override
- public void release() {} // nothing to be released back to the owner
-
- @Override
- public String toString() {
- return getStartString()+", "+format+", #"+seqnr+", l_"+layer+", style "+style+", name '"+name+"': '"+text+"' ("+lines+")]";
- }
-}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/av/SubtitleEvent.java b/src/jogl/classes/com/jogamp/opengl/util/av/SubtitleEvent.java
index f24246a70..e75fff3f8 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/av/SubtitleEvent.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/av/SubtitleEvent.java
@@ -1,5 +1,7 @@
package com.jogamp.opengl.util.av;
+import com.jogamp.common.av.PTS;
+
/**
* Generic subtitle event
* <p>
@@ -8,12 +10,23 @@ package com.jogamp.opengl.util.av;
* </p>
*/
public abstract class SubtitleEvent {
+ /** {@link SubtitleEvent} Implementation Type */
+ public enum Type {
+ /** {@link SubTextEvent} */
+ Text,
+ /** {@link SubBitmapEvent} */
+ Bitmap,
+ /** {@link SubEmptyEvent} */
+ Empty
+ };
+ /** Implementation {@link Type} of this instance. */
+ public final Type type;
/** {@link CodecID} of this subtitle event. */
public final CodecID codec;
- /** PTS start time to start showing this subtitle event. */
+ /** PTS start time in milliseconds to start showing this subtitle event. */
public final int pts_start;
/**
- * PTS start time to end showing this subtitle event.
+ * PTS end time in milliseconds to end showing this subtitle event.
* <p>
* {@link SubBitmapEvent} often (e.g. {@link CodecID#HDMV_PGS}) have an infinite end-time, i.e. ({@link Integer#MAX_VALUE},
* and shall be overwritten by the next one or {@link SubEmptyEvent}.
@@ -22,7 +35,8 @@ public abstract class SubtitleEvent {
*/
public final int pts_end;
- public SubtitleEvent(final CodecID codec, final int pts_start, final int pts_end) {
+ public SubtitleEvent(final Type type, final CodecID codec, final int pts_start, final int pts_end) {
+ this.type = type;
this.codec = codec;
this.pts_start = pts_start;
this.pts_end = pts_end;
@@ -36,16 +50,11 @@ public abstract class SubtitleEvent {
/** See {@link #pts_end}. */
public final boolean isEndDefined() { return pts_end < Integer.MAX_VALUE; }
- /** Returns {@code true} if Text/ASS/SAA subtitle type, o.e. {@link SubTextEvent}. */
- public abstract boolean isTextASS();
- /** Returns {@code true} if bitmap subtitle type, o.e. {@link SubBitmapEvent}. */
- public abstract boolean isBitmap();
- /** Returns {@code true} if empty subtitle type, o.e. {@link SubEmptyEvent}. */
- public abstract boolean isEmpty();
-
public final String getStartString() {
final boolean ied = isEndDefined();
- return "Sub["+codec+", ["+pts_start+".."+(ied?pts_end:"undef")+"] "+(ied?getDuration():"undef")+" ms";
+ final String pts_start_s = 0 <= pts_start ? PTS.toTimeStr(pts_start, true) : "undef";
+ final String pts_end_s = 0 <= pts_end && ied ? PTS.toTimeStr(pts_end, true) : "undef";
+ return "Sub[codec "+codec+", type "+type+", ["+pts_start_s+".."+pts_end_s+"] "+(ied?getDuration():"undef")+" ms";
}