Skip to content

Commit a6e7f9d

Browse files
mutantbobneilcsmith-net
authored andcommitted
Buffer api (#97)
* add methods to Buffer for setPresentationTimestamp() setDuration(), setOffset(), and setFlags() * new MainLoop constructor that takes a GMainContext as an argument (needed for things like gst-rtsp-server framework) * add more setters/getters for the GstBuffer representation; plus a unit test * rewrite BufferFlag.java to match the GstBufferFlags enum from gstreamer 1.12.3 * rewrite MiniObjectFlags.java to match the GstMiniObjectFlags enum from gstreamer 1.12.3
1 parent 0427667 commit a6e7f9d

File tree

8 files changed

+270
-25
lines changed

8 files changed

+270
-25
lines changed

src/org/freedesktop/gstreamer/Buffer.java

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,15 @@ public ClockTime getDecodeTimestamp() {
168168
return (ClockTime)this.struct.readField("dts");
169169
}
170170

171+
/**
172+
* Set the decode timestamp of the Buffer
173+
* @param val a ClockTime representing the timestamp or {@link ClockTime#NONE} when the timestamp is not known or relevant.
174+
*/
175+
public void setDecodeTimestamp(ClockTime val)
176+
{
177+
this.struct.writeField("dts", val);
178+
}
179+
171180
/**
172181
* Gets the timestamps of this buffer.
173182
* The buffer PTS refers to the timestamp when the buffer content should be presented to the user and is not always monotonically increasing.
@@ -178,4 +187,98 @@ public ClockTime getPresentationTimestamp() {
178187
return (ClockTime)this.struct.readField("pts");
179188
}
180189

190+
/**
191+
* Set the presentation timestamp of the Buffer
192+
* @param val a ClockTime representing the timestamp or {@link ClockTime#NONE} when the timestamp is not known or relevant.
193+
*/
194+
public void setPresentationTimestamp(ClockTime val)
195+
{
196+
this.struct.writeField("pts", val);
197+
}
198+
199+
/**
200+
* Gets the duration of this buffer.
201+
*
202+
* @return a ClockTime representing the timestamp or {@link ClockTime#NONE} when the timestamp is not known or relevant.
203+
*/
204+
public ClockTime getDuration() {
205+
return (ClockTime)this.struct.readField("duration");
206+
}
207+
208+
/**
209+
* Set the duration of this buffer.
210+
* @param val a ClockTime representing the duration or {@link ClockTime#NONE} when the timestamp is not known or relevant.
211+
*/
212+
public void setDuration(ClockTime val)
213+
{
214+
this.struct.writeField("duration", val);
215+
}
216+
217+
/**
218+
* Get the offset (media-specific) of this buffer
219+
* @return a media specific offset for the buffer data. For video frames, this is the frame number of this buffer. For audio samples, this is the offset of the first sample in this buffer. For file data or compressed data this is the byte offset of the first byte in this buffer.
220+
*/
221+
public long getOffset()
222+
{
223+
return (Long)this.struct.readField("offset");
224+
}
225+
226+
/**
227+
* Set the offset (media-specific) of this buffer
228+
* @param val a media specific offset for the buffer data. For video frames, this is the frame number of this buffer. For audio samples, this is the offset of the first sample in this buffer. For file data or compressed data this is the byte offset of the first byte in this buffer.
229+
*/
230+
public void setOffset(long val)
231+
{
232+
this.struct.writeField("offset", val);
233+
}
234+
235+
/**
236+
* Get the offset (media-specific) of this buffer
237+
* @return a media specific offset for the buffer data. For video frames, this is the frame number of this buffer. For audio samples, this is the offset of the first sample in this buffer. For file data or compressed data this is the byte offset of the first byte in this buffer.
238+
*/
239+
public long getOffsetEnd()
240+
{
241+
return (Long)this.struct.readField("offset_end");
242+
}
243+
244+
/**
245+
* Set the offset (media-specific) of this buffer
246+
* @param val a media specific offset for the buffer data. For video frames, this is the frame number of this buffer. For audio samples, this is the offset of the first sample in this buffer. For file data or compressed data this is the byte offset of the first byte in this buffer.
247+
*/
248+
public void setOffsetEnd(long val)
249+
{
250+
this.struct.writeField("offset_end", val);
251+
}
252+
253+
/**
254+
* get the GstBufferFlags describing this buffer
255+
* @return a bit mask whose values can be interpreted by comparing them with {@link BufferFlag}
256+
*/
257+
public int getFlags()
258+
{
259+
return GstBufferAPI.GSTBUFFER_API.gst_buffer_get_flags(this);
260+
}
261+
262+
/**
263+
* set some of the GstBufferFlags describing this buffer. This is a union operation and does not clear flags that are not mentioned in val
264+
* @param val a bit mask of flags to be set on the buffer. bits which are zero in val do not get cleared in this buffer.
265+
* @return true if flags were successfully set on this buffer
266+
* @see BufferFlag
267+
*/
268+
public boolean setFlags(int val)
269+
{
270+
return GstBufferAPI.GSTBUFFER_API.gst_buffer_set_flags(this, val);
271+
}
272+
273+
/**
274+
* unset the GstBufferFlags describing this buffer. This is a difference operation and does not clear flags that are not mentioned in val
275+
* @param val a bit mask of flags to be cleared on the buffer. bits which are zero in val do not get cleared in this buffer.
276+
* @return true if flags were successfully cleared on this buffer
277+
* @see BufferFlag
278+
* */
279+
public boolean unsetFlags(int val)
280+
{
281+
return GstBufferAPI.GSTBUFFER_API.gst_buffer_unset_flags(this, val);
282+
}
283+
181284
}

src/org/freedesktop/gstreamer/BufferFlag.java

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,39 +27,74 @@
2727
* A set of buffer flags used to describe properties of a {@link Buffer}.
2828
*/
2929
public enum BufferFlag implements IntegerEnum {
30-
/**
31-
* The {@link Buffer} is read-only.
32-
* This means the data of the buffer should not be modified. The metadata
33-
* might still be modified.
34-
*/
35-
READONLY(MiniObjectFlags.READONLY.intValue()),
36-
30+
3731
/**
38-
* The {@link Buffer} is part of a preroll and should not be displayed.
32+
* the {@link Buffer} is live data and should be discarded in the PAUSED state.
33+
*/
34+
LIVE(MiniObjectFlags.LAST.intValue() << 0),
35+
36+
/**
37+
* the {@link Buffer} contains data that should be dropped
38+
* because it will be clipped against the segment
39+
* boundaries or because it does not contain data
40+
* that should be shown to the user.
3941
*/
40-
PREROLL(MiniObjectFlags.LAST.intValue() << 0),
42+
DECODE_ONLY(MiniObjectFlags.LAST.intValue() << 1),
43+
4144
/**
4245
* The {@link Buffer} marks a discontinuity in the stream.
4346
* This typically occurs after a seek or a dropped buffer from a live or
4447
* network source.
4548
*/
46-
DISCONT(MiniObjectFlags.LAST.intValue() << 1),
47-
48-
/** The {@link Buffer} has been added as a field in a {@link Caps}. */
49-
IN_CAPS(MiniObjectFlags.LAST.intValue() << 2),
50-
49+
DISCONT(MiniObjectFlags.LAST.intValue() << 2),
50+
51+
/**
52+
* The {@link Buffer} timestamps might have a discontinuity and this buffer is a good point to resynchronize.
53+
*/
54+
RESYNC(MiniObjectFlags.LAST.intValue() << 3),
55+
56+
/**
57+
* the {@link Buffer} data is corrupted.
58+
*/
59+
CORRUPTED(MiniObjectFlags.LAST.intValue() << 4),
60+
61+
/**
62+
* the buffer contains a media specific marker. for video this is typically the end of a frame boundary, for audio this is usually the start of a talkspurt.
63+
*/
64+
MARKER(MiniObjectFlags.LAST.intValue() << 5),
65+
66+
/**
67+
* he buffer contains header information that is needed to decode the following data.
68+
*/
69+
HEADER(MiniObjectFlags.LAST.intValue() << 6),
70+
5171
/**
5272
* The {@link Buffer} has been created to fill a gap in the
5373
* stream and contains media neutral data (elements can switch to optimized code
5474
* path that ignores the buffer content).
5575
*/
56-
GAP(MiniObjectFlags.LAST.intValue() << 3),
76+
GAP(MiniObjectFlags.LAST.intValue() << 7),
77+
78+
/**
79+
* the {@link Buffer} can be dropped without breaking the stream, for example to reduce bandwidth.
80+
*/
81+
DROPPABLE(MiniObjectFlags.LAST.intValue() << 8),
5782

5883
/** This unit cannot be decoded independently. */
59-
DELTA_UNIT(MiniObjectFlags.LAST.intValue() << 4),
84+
DELTA_UNIT(MiniObjectFlags.LAST.intValue() << 9),
85+
86+
/**
87+
* this flag is set when memory of the {@link Buffer} is added/removed
88+
*/
89+
TAG_MEMORY(MiniObjectFlags.LAST.intValue() << 10),
90+
91+
/**
92+
* Elements which write to disk or permanent storage should ensure the data is synced after writing the contents of this {@link Buffer}. (Since 1.6)
93+
*/
94+
SYNC_AFTER(MiniObjectFlags.LAST.intValue() << 11),
6095

6196
/* padding */
62-
LAST(MiniObjectFlags.LAST.intValue() << 8),
97+
LAST(MiniObjectFlags.LAST.intValue() << 16),
6398

6499
/** The value used for unknown native values */
65100
@DefaultEnumValue

src/org/freedesktop/gstreamer/MiniObject.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,11 @@ public static GType getType(Pointer ptr) {
5555
}
5656

5757
/**
58-
* Checks if a mini-object is writable. A mini-object is writable
59-
* if the reference count is one and the {@link MiniObjectFlags#READONLY}
60-
* flag is not set. Modification of a mini-object should only be
61-
* done after verifying that it is writable.
58+
* If mini_object has the LOCKABLE flag set, check if the current EXCLUSIVE lock on object is the only one, this means that changes to the object will not be visible to any other object.
59+
*
60+
* <p></p>If the LOCKABLE flag is not set, check if the refcount of mini_object is exactly 1, meaning that no other reference exists to the object and that the object is therefore writable.
61+
*
62+
* <p></p>Modification of a mini-object should only be done after verifying that it is writable.
6263
*
6364
* @return true if the object is writable.
6465
*/

src/org/freedesktop/gstreamer/MiniObjectFlags.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,20 @@
2424
*
2525
*/
2626
public enum MiniObjectFlags implements IntegerEnum {
27-
/** The {@link MiniObject} is read-only */
28-
READONLY(1 << 0),
27+
/**
28+
* the object can be locked and unlocked with gst_mini_object_lock() and gst_mini_object_unlock()
29+
* */
30+
LOCKABLE(1 << 0),
31+
32+
/**
33+
* the object is permanently locked in READONLY mode. Only read locks can be performed on the object.
34+
*/
35+
LOCK_READONLY(1<<1),
36+
37+
/**
38+
* the object is expected to stay alive even after gst_deinit() has been called and so should be ignored by leak detection tools. (Since 1.10)
39+
*/
40+
MAY_BE_LEAKED(1<<2),
2941

3042
/** The last valid MiniObject flag */
3143
LAST(1 << 4);

src/org/freedesktop/gstreamer/lowlevel/GstBufferAPI.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ protected List<String> getFieldOrder() {
7575
void gst_buffer_unmap(Buffer buffer, MapInfoStruct info);
7676
int gst_buffer_n_memory(Buffer buffer);
7777
boolean gst_buffer_map_range(Buffer buffer, int idx, int length, MapInfoStruct info, int flags);
78+
int gst_buffer_get_flags(Buffer buffer);
79+
boolean gst_buffer_set_flags(Buffer buffer, int flags);
80+
boolean gst_buffer_unset_flags(Buffer buffer, int flags);
7881
// boolean gst_buffer_is_metadata_writable(Buffer buf);
7982
// Buffer gst_buffer_make_metadata_writable(@Invalidate Buffer buf);
8083
// /* creating a subbuffer */

src/org/freedesktop/gstreamer/lowlevel/MainLoop.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,10 @@ public class MainLoop extends RefCountedObject {
4545
public MainLoop() {
4646
super(initializer(GLIB_API.g_main_loop_new(Gst.getMainContext(), false)));
4747
}
48-
48+
49+
public MainLoop(GMainContext ctx) {
50+
super(initializer(GLIB_API.g_main_loop_new(ctx, false)));
51+
}
4952
/**
5053
* Creates a new instance of {@code MainLoop}
5154
*
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package org.freedesktop.gstreamer;
2+
3+
import org.junit.*;
4+
import static org.junit.Assert.*;
5+
6+
/**
7+
* <p>Copyright (C) 2018 Robert Forsman, Ericsson SATV
8+
* $Author thoth $
9+
* $Date 3/8/18 $
10+
*/
11+
public class BufferFieldsTest
12+
{
13+
@BeforeClass
14+
public static void setUpClass() throws Exception {
15+
Gst.init("BufferFieldsTest", new String[] {});
16+
}
17+
18+
@AfterClass
19+
public static void tearDownClass() throws Exception {
20+
Gst.deinit();
21+
}
22+
23+
private Buffer buf;
24+
25+
@Before
26+
public void setUp()
27+
{
28+
buf = new Buffer(12);
29+
}
30+
31+
@Test
32+
public void setPTS()
33+
{
34+
buf.setPresentationTimestamp(ClockTime.fromMicros(5004003));
35+
ClockTime val = buf.getPresentationTimestamp();
36+
assertEquals(5004003, val.toMicros());
37+
}
38+
39+
@Test
40+
public void setDTS()
41+
{
42+
buf.setDecodeTimestamp(ClockTime.fromMicros(9001004));
43+
ClockTime val = buf.getDecodeTimestamp();
44+
assertEquals(9001004, val.toMicros());
45+
}
46+
47+
@Test
48+
public void setDuration()
49+
{
50+
buf.setDuration(ClockTime.fromMicros(4006008));
51+
ClockTime val = buf.getDuration();
52+
assertEquals(4006008, val.toMicros());
53+
}
54+
55+
@Test
56+
public void setOffset()
57+
{
58+
buf.setOffset(2009006);
59+
long val = buf.getOffset();
60+
assertEquals(2009006, val);
61+
}
62+
63+
@Test
64+
public void setOffsetEnd()
65+
{
66+
buf.setOffsetEnd(7005003);
67+
long val = buf.getOffsetEnd();
68+
assertEquals(7005003, val);
69+
}
70+
71+
@Test
72+
public void setFlags()
73+
{
74+
assertTrue(buf.setFlags(7));
75+
int val = buf.getFlags();
76+
assertEquals(7, val);
77+
78+
assertTrue(buf.setFlags(10));
79+
val = buf.getFlags();
80+
assertEquals(15, val);
81+
82+
assertTrue(buf.unsetFlags(20));
83+
val = buf.getFlags();
84+
assertEquals(11, val);
85+
}
86+
}

test/org/freedesktop/gstreamer/PluginTest.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,9 @@ public void testGetSource() {
7676

7777
@Test
7878
public void testGetPackage() {
79-
assertTrue(playbackPlugin.getPackage().contains("GStreamer Base"));
79+
String pkg = playbackPlugin.getPackage();
80+
assertTrue(pkg.contains("GStreamer Base")
81+
|| pkg.contains("Gentoo GStreamer"));
8082
}
8183

8284
@Test

0 commit comments

Comments
 (0)