<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<p>I'm trying to use GStreamer Java Binding on Raspberry Pi to play
some dynamic audio data which is Opus encoded. I'm almost done. My
final issue is I cannot have GStreamer clean up nicely when the
data reaching the end. My testing code is as below.<br>
<br>
<br>
<font face="Courier New, Courier, monospace" size="-1"> package
org.freedesktop.gstreamer.examples;<br>
<br>
import java.awt.Dimension;<br>
import java.awt.EventQueue;<br>
import java.io.File;<br>
import java.io.FileInputStream;<br>
import java.io.FileNotFoundException;<br>
import java.io.IOException;<br>
import java.nio.ByteBuffer;<br>
<br>
import javax.swing.JFrame;<br>
import org.freedesktop.gstreamer.Bin;<br>
import org.freedesktop.gstreamer.Buffer;<br>
import org.freedesktop.gstreamer.Bus;<br>
import org.freedesktop.gstreamer.Element;<br>
import org.freedesktop.gstreamer.ElementFactory;<br>
import org.freedesktop.gstreamer.FlowReturn;<br>
import org.freedesktop.gstreamer.Gst;<br>
import org.freedesktop.gstreamer.GstObject;<br>
import org.freedesktop.gstreamer.Message;<br>
import org.freedesktop.gstreamer.Pad;<br>
import org.freedesktop.gstreamer.PadLinkReturn;<br>
import org.freedesktop.gstreamer.Pipeline;<br>
import org.freedesktop.gstreamer.State;<br>
import org.freedesktop.gstreamer.elements.AppSrc;<br>
import org.freedesktop.gstreamer.lowlevel.MainLoop;<br>
<br>
/**<br>
*<br>
* @author Superrei<br>
*/<br>
public class AudioTest {<br>
<br>
//private static final int BUFFER_SIZE = 4096;<br>
private static byte[] soundBytes = null;<br>
private static int pointer = 0;<br>
private static String filename = null;<br>
<br>
/**<br>
* @param args the command line arguments<br>
*/<br>
public static void main(String[] args) {<br>
<br>
Gst.init("AudioTest", args);<br>
filename = args[0];<br>
EventQueue.invokeLater(new Runnable() {<br>
<br>
@Override<br>
public void run() {<br>
File soundFile = new File(filename);<br>
FileInputStream inStream = null;<br>
<br>
if (soundFile.exists()){<br>
try {<br>
System.out.println("Read media
file.");<br>
long fileSize = soundFile.length();<br>
soundBytes = new
byte[(int)fileSize];<br>
inStream = new
FileInputStream(soundFile);<br>
int byteCount =
inStream.read(soundBytes);<br>
System.out.println("Number of byte
read: " + byteCount);<br>
} catch (IOException e) {<br>
e.printStackTrace();<br>
return;<br>
}<br>
}<br>
final MainLoop loop = new MainLoop(); <br>
AppSrc source =
(AppSrc)ElementFactory.make("appsrc", "app-source");<br>
Element demuxer =
ElementFactory.make("oggdemux", "ogg-demuxer");<br>
final Element decoder =
ElementFactory.make("opusdec", "opus-decoder");<br>
Element conv =
ElementFactory.make("audioconvert", "converter");<br>
Element sink =
ElementFactory.make("autoaudiosink", "audio-output");<br>
<br>
//source.set("location",
"/home/pi/gstJavaTest/transcript.ogg");<br>
<br>
Pipeline pipe = new Pipeline();<br>
Bus bus = pipe.getBus();<br>
bus.connect(new Bus.EOS() {<br>
<br>
@Override<br>
public void endOfStream(GstObject
source) {<br>
loop.quit();<br>
}<br>
<br>
});<br>
bus.connect(new Bus.ERROR() {<br>
<br>
@Override<br>
public void errorMessage(GstObject
source, int code, String message) {<br>
System.out.println("Error
detected");<br>
System.out.println("Error source: "
+ source.getName());<br>
System.out.println("Error code: " +
code);<br>
System.out.println("Message: " +
message);<br>
loop.quit();<br>
}<br>
});<br>
<br>
pipe.addMany(source, demuxer, decoder, conv,
sink);<br>
source.link(demuxer);<br>
source.set("emit-signals", true);<br>
source.connect(new AppSrc.NEED_DATA() {<br>
<br>
private ByteBuffer bb =
ByteBuffer.wrap(soundBytes);<br>
<br>
@Override<br>
public void needData(AppSrc elem, int
size) {<br>
if (bb.hasRemaining()) {<br>
// TODO Auto-generated method
stub<br>
System.out.println("needData:
size = " + size);<br>
byte[] tempBuffer;<br>
Buffer buf;<br>
if (bb.remaining() > size) {<br>
tempBuffer = new byte[size];<br>
buf = new Buffer(size);<br>
} else {<br>
tempBuffer = new
byte[bb.remaining()];<br>
buf = new
Buffer(bb.remaining());<br>
}<br>
//System.out.println("Buffer
size: " + buf.map(true).remaining());<br>
//System.arraycopy(soundBytes,
pointer, tempBuffer, 0, size);<br>
bb.get(tempBuffer);<br>
System.out.println("Temp Buffer
remaining bytes: " + bb.remaining());<br>
buf.map(true).put(ByteBuffer.wrap(tempBuffer));<br>
elem.pushBuffer(buf);<br>
} else {<br>
elem.emit("end-of-stream",
elem);<br>
}<br>
//pointer += size;<br>
}<br>
});<br>
<br>
source.connect(new AppSrc.ENOUGH_DATA() {<br>
<br>
@Override<br>
public void enoughData(AppSrc elem) {<br>
System.out.println("enoughData: " +
elem.toString());<br>
<br>
}<br>
});<br>
source.connect(new AppSrc.END_OF_STREAM() {<br>
<br>
@Override<br>
public FlowReturn endOfStream(AppSrc
elem) {<br>
// TODO Auto-generated method stub<br>
return FlowReturn.OK;<br>
}<br>
});<br>
Element.linkMany(decoder, conv, sink);<br>
demuxer.connect(new Element.PAD_ADDED() {<br>
<br>
@Override<br>
public void padAdded(Element element,
Pad pad) {<br>
System.out.println("Dynamic pad
created, linking demuxer/decoder");<br>
System.out.println("Pad name: " +
pad.getName());<br>
System.out.println("Pad type: " +
pad.getTypeName());<br>
Pad sinkPad =
decoder.getStaticPad("sink");<br>
//boolean linked =
element.link(decoder);<br>
PadLinkReturn ret =
pad.link(sinkPad);<br>
if (ret.equals(PadLinkReturn.OK)){<br>
System.out.println("Pad
linked.");<br>
} else {<br>
System.out.println("Pad link
failed");<br>
}<br>
//System.out.println("Pad Link
Return: " + ret.toString());<br>
}<br>
<br>
});<br>
<br>
System.out.println("Now Playing...");<br>
pipe.play();<br>
System.out.println("Running...");<br>
loop.run();<br>
System.out.println("Returned, stopping
playback");<br>
pipe.stop();<br>
}<br>
});<br>
}<br>
<br>
}</font><br>
<br>
I don't use playbin since the audio data will come from byte
stream finally. <br>
<br>
The test runs well until the end. When I reach the end of file. I
get error messages and follow by JVM crush. The error message is
like this:<br>
<br>
<br>
<font size="-1"><tt> (AudioTest:4643): GLib-GObject-CRITICAL
**: g_object_unref: assertion 'G_IS_OBJECT (object)' failed</tt><tt><br>
</tt><tt> </tt><tt><br>
</tt><tt> (AudioTest:4643): GLib-GObject-CRITICAL **:
g_object_unref: assertion 'G_IS_OBJECT (object)' failed </tt><tt><br>
</tt></font></p>
<p><font size="-1"><tt> Returned, stopping playback</tt><tt><br>
</tt><tt> </tt><tt><br>
</tt><tt> (AudioTest:4643): GLib-GObject-CRITICAL **:
g_object_ref: assertion 'G_IS_OBJECT (object)' failed</tt><tt><br>
</tt><tt> </tt><tt><br>
</tt><tt> (AudioTest:4643): GLib-GObject-CRITICAL **:
g_object_unref: assertion 'G_IS_OBJECT (object)' failed</tt><tt><br>
</tt><tt> </tt><tt><br>
</tt><tt> (AudioTest:4643): GLib-GObject-CRITICAL **:
g_object_ref: assertion 'G_IS_OBJECT (object)' failed</tt><tt><br>
</tt><tt> </tt><tt><br>
</tt><tt> (AudioTest:4643): GLib-GObject-CRITICAL **:
g_object_unref: assertion 'G_IS_OBJECT (object)' failed</tt><tt><br>
</tt><tt> </tt><tt><br>
</tt><tt> (AudioTest:4643): GLib-GObject-CRITICAL **:
g_value_set_object: assertion 'G_IS_OBJECT (v_object)' failed</tt><tt><br>
</tt><tt> #</tt><tt><br>
</tt><tt> # A fatal error has been detected by the Java
Runtime Environment:</tt><tt><br>
</tt><tt> #</tt><tt><br>
</tt><tt> # SIGSEGV (0xb) at pc=0x63d8b8ec, pid=4643,
tid=1658819680</tt><tt><br>
</tt><tt> #</tt><tt><br>
</tt><tt> # JRE version: Java(TM) SE Runtime Environment
(8.0_65-b17) (build</tt><tt><br>
</tt><tt> 1.8.0_65-b17)</tt><tt><br>
</tt><tt> # Java VM: Java HotSpot(TM) Client VM (25.65-b01
mixed mode linux-arm )</tt><tt><br>
</tt><tt> # Problematic frame:</tt><tt><br>
</tt><tt> # C [libglib-2.0.so.0+0x928ec]
g_rec_mutex_lock+0x8</tt><tt><br>
</tt><tt> #</tt><tt><br>
</tt><tt> # Failed to write core dump. Core dumps have been
disabled. To enable core dumping, try "ulimit -c unlimited"
before starting Java again</tt><tt><br>
</tt><tt> #</tt><tt><br>
</tt><tt> # An error report file with more information is
saved as:</tt><tt><br>
</tt><tt> # /home/pi/gstJavaTest/hs_err_pid4643.log</tt><tt><br>
</tt><tt> #</tt><tt><br>
</tt><tt> # If you would like to submit a bug report, please
visit:</tt><tt><br>
</tt><tt> # <a class="moz-txt-link-freetext" href="http://bugreport.java.com/bugreport/crash.jsp">http://bugreport.java.com/bugreport/crash.jsp</a></tt><tt><br>
</tt><tt> # The crash happened outside the Java Virtual
Machine in native code.</tt><tt><br>
</tt><tt> # See problematic frame for where to report the
bug.</tt><tt><br>
</tt><tt> # Aborted</tt><tt><br>
</tt></font><br>
I cannot find any example on using AppSrc to play something with
an end. Any help will be appreciated. Thank you.<br>
<br>
<br>
</p>
</body>
</html>