gBroutin / gstreamer-java

Automatically exported from code.google.com/p/gstreamer-java
0 stars 0 forks source link

decodebin Element fails #36

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
** What steps will reproduce the problem?
Trying this code :
        pipe2 = new Pipeline("Pipeline that must work");
        String srcPath = "/home/rom1dep/Musique/01.flac";
        System.out.println(new File(srcPath).exists());
→Prints TRUE
        Element p2audiosource = ElementFactory.make("filesrc", "file in");
        p2audiosource.set("location", srcPath);
@CASE 1 : Uncomment this ↓
        //final Element p2decoder = new DecodeBin("decoder");
@CASE 2 : Uncomment this ↓
        //final Element p2decoder = ElementFactory.make("decodebin", 
"decoder");
@CASE 3 : Uncomment this ↓
        //final Element p2decoder = ElementFactory.make("flacdec", 
"decoder");
        p2equalizer = ElementFactory.make("equalizer-10bands", "10b 
equalizer");
        Element p2audiosink = ElementFactory.make("pulsesink", "PA 
output");
        pipe2.addMany(p2audiosource, p2decoder, p2equalizer, p2audiosink);
        pipe2.linkMany(p2audiosource, p2decoder, p2equalizer, p2audiosink);
        new Thread(new Runnable() {

            public void run() {
                try {
                    Thread.sleep(1000);
                    System.out.println(p2decoder.getState());
→Prints PAUSED in both cases 1 and 2, but PLAYING in case 3
                } catch (InterruptedException e) {
                }
            }
        }).start();
        pipe2.play();

**What is the expected output? What do you see instead?
Expected output is sound + pipeline state=PLAYING in each case :
[rom1dep@NetSam ~]$ gst-launch-0.10 filesrc 
location=/home/rom1dep/Musique/01.flac ! decodebin ! pulsesink
works well.
Instead, the flac file is played only when p2decoder is manually set as an 
instance of flacdec (case 3), so, the decodebin implementation within gst-
java is inefficient.

**What version of the product are you using? On what operating system?
GStreamer version +OS :
[rom1dep@NetSam ~]$ gst-inspect-0.10 --version
gst-inspect-0.10 version 0.10.25
GStreamer 0.10.25
http://www.mandriva.com/

Binding version:
[rom1dep@NetSam gstreamer]$ ls
gstreamer-java-1.3.jar      gstreamer-java-src-1.3.zip
gstreamer-java-doc-1.3.zip  jna-3.2.4.jar

**Please provide any additional information below.
Just hope for the bug report to be understandable...

Original issue reported on code.google.com by rom1dep on 25 Feb 2010 at 11:49

GoogleCodeExporter commented 8 years ago
we just wrap the native decodebin. if it's works with the native decode bit 
then it 
should have to work with gstreamer-java too. and your command line do not 
contains 
p2equalizer...
is this problem still exists?

Original comment by lfar...@gmail.com on 26 Apr 2010 at 1:13

GoogleCodeExporter commented 8 years ago
Adding the equalizer changes nothing...
Maybe am I doing a bad use of the gst-java binding... So let's start with the 
beginning !
This is the (working) pipeline I want to recreate with gst-java :
[rom1dep@NetSam ~]$ gst-launch-0.10 filesrc 
location=/home/rom1dep/Musique/01.flac !
decodebin ! pulsesink

And this is the code I use to reproduce the pipeline above :
**********************************
package gstbrunch;

import java.io.File;
import org.gstreamer.Element;
import org.gstreamer.ElementFactory;
import org.gstreamer.Gst;
import org.gstreamer.Pipeline;
import org.gstreamer.State;
import org.gstreamer.elements.PlayBin;

/**
 * @author rom1dep
 */
public class Main {

    public Main(String[] gstArgs) {
        Gst.init("GstBrunch", gstArgs);

        File file = new File("/home/rom1dep/Musique/01.flac");//test file.exists()→true

        Pipeline pipeline = new Pipeline("Processing pipeline");
        Element source = ElementFactory.make("filesrc", "file loader");
        Element decoder = ElementFactory.make("decodebin", "decoder");
        Element sink = ElementFactory.make("pulsesink", "system audio sink");

        source.set("location", "/home/rom1dep/Musique/01.flac/");

        pipeline.addMany(source, decoder, sink);
        Pipeline.linkMany(source, decoder, sink);

        pipeline.setState(State.PLAYING);
        Gst.main();
        pipeline.setState(State.NULL);

//        PlayBin playbin = new PlayBin("myplaybin");
//        playbin.setInputFile(file);
//        playbin.setAudioSink(ElementFactory.make("pulsesink", "sink"));
//        playbin.setState(State.PLAYING);
//        Gst.main();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        new Main(args);
    }
}
**************************
The track isn't even declared within pavucontrol while the commented code at 
the end
works. I don't understand, maybe am I missing some step that is automated 
within the
PlayBin class, but I can't find what...
Thanks for your precious time :)

Original comment by rom1dep on 27 Apr 2010 at 9:05

GoogleCodeExporter commented 8 years ago
Your location setting seems to me wrong. Nevertheless could you create a 
pipeline using Pipeline.launch() with 
*exactly* the same pipeline def which works for you from the command line?  

Original comment by tsha...@gmail.com on 27 Apr 2010 at 11:31

GoogleCodeExporter commented 8 years ago
        Pipeline pipe=Pipeline.launch("filesrc location=/home/rom1dep/Musique/01.flac
! decodebin ! pulsesink");
        pipe.setState(State.PLAYING);
        Gst.main();

This works... 

Original comment by rom1dep on 28 Apr 2010 at 12:25

GoogleCodeExporter commented 8 years ago
source.set("location", "/home/rom1dep/Musique/01.flac/");
                                                    ^^^
try to remove the trailing /

Original comment by lfar...@gmail.com on 28 Apr 2010 at 11:49

GoogleCodeExporter commented 8 years ago
With '/' or without, it's the same... I added it to test
@tshalif: you spoke about location, so I added this :
        final Pipeline pipe = Pipeline.launch("filesrc
location=/home/rom1dep/Musique/01.flac ! decodebin ! pulsesink");
        for (Element el : pipe.getElementsRecursive()) {
            System.out.println(el);
            if (el.toString().equalsIgnoreCase("BaseSrc: [filesrc0]")) {
                System.out.println(el.get("location"));
            }
        }
        pipe.setState(State.PLAYING);
*******
what prints
BaseSink: [pulsesink0]
Bin: [decodebin0]
BaseSink: [fakesink]
Element: [typefind]
BaseSrc: [filesrc0]
/home/rom1dep/Musique/01.flac

Original comment by rom1dep on 28 Apr 2010 at 1:54

GoogleCodeExporter commented 8 years ago
1. What does it print when you construct the pipeline manually?
2. Can you remove space characters from the element names?

Original comment by tsha...@gmail.com on 28 Apr 2010 at 11:22

GoogleCodeExporter commented 8 years ago
1. Nothing, no error is thrown, all looks OK at runtime
2. I changed the names, changed the scope of the Element+Pipeline vars, used
pipeline.play() instead of setState, same : noting outputs

Original comment by rom1dep on 29 Apr 2010 at 6:17

GoogleCodeExporter commented 8 years ago
It seems the problem is decodebin fails to link to pulsesink, because it does 
not
know yet it will later have an appropriate audio source pad. Setting the 
pipeline
state to PAUSED before adding/linking the audio sink seems to fix the problem. 
If it
is a bug, it is at least not Java specific (same behaviour with gst-python). 
Have a
look at the code below which works (replace audio file location with your own):

------------------------ FlacTest.java ----------------------------------------
package org.gstreamer.example;

import org.gstreamer.Element;
import org.gstreamer.ElementFactory;
import org.gstreamer.Gst;
import org.gstreamer.Pipeline;
import org.gstreamer.State;

/**
 * @author rom1dep
 */
public class FlacTest {

    public FlacTest(String[] gstArgs) {
        Gst.init("GstBrunch", gstArgs);

        Pipeline pipeline;

        boolean I_want_to_do_it_the_hard_way = true;

        if (I_want_to_do_it_the_hard_way) {
           pipeline = new Pipeline("Processing pipeline");

            Element source = ElementFactory.make("filesrc", "src");
            Element decoder = ElementFactory.make("decodebin", "decoder");
            Element sink = ElementFactory.make("pulsesink", "audiosink");

            source.set("location", "/tmp/heli.flac");

            pipeline.addMany(source, decoder);

            if (!source.link(decoder)) {
                throw new RuntimeException("failed to link pipeline elements");
            }

            pipeline.setState(State.PAUSED);

            sink.setState(State.PAUSED);

            pipeline.add(sink);

            if (!decoder.link(sink)) {
                throw new RuntimeException("failed to link pipeline elements");
            }
        } else {
            pipeline = Pipeline.launch("filesrc name=src ! decodebin ! pulsesink");
            pipeline.getElementByName("src").set("location", "/tmp/heli.flac");
        }

        pipeline.setState(State.PLAYING);
        Gst.main();
        pipeline.setState(State.NULL);
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        new FlacTest(args);
    }
}

Original comment by tsha...@gmail.com on 29 Apr 2010 at 11:19

GoogleCodeExporter commented 8 years ago
Wow ! Finally ! it works ! :) Very strange, thanks for having found this !
So, in practice in consequent gstreamer projects, do you think it's 
safer/recommended
to use Pipeline.launch instead of "doing it the hard way" ?
If other bindings are 'broken' the problem is gstreamer itself, shouldn't I/we 
open a
bug upstream for this ?
Thanks for all and have a nice day then :)

Original comment by rom1dep on 29 Apr 2010 at 11:48

GoogleCodeExporter commented 8 years ago
I wouldn't say it is safer or more recommended to use Pipeline.launch() rather 
than
creating your pipeline step-by-step. It is simpler, cleaner and less verbose, so
there is less chance of making mistakes and it is easier to understand.

If the decodebin problem is specific to FLAC, but not to other formats, it is a 
bug
that should be reported on the gstreamer bugzilla. It is a good idea to 
investigate
the gstreamer documentation to see either there is already an explanation on 
why a
parsed pipeline behaves differently.

Original comment by tsha...@gmail.com on 29 Apr 2010 at 5:53