Gstreamer Tee / Queue несколько конвейеров - PullRequest
3 голосов
/ 14 февраля 2012

, поэтому я использую gstreamer для Java и пытаюсь воспроизвести видео в реальном времени и записать его одновременно.сейчас я могу сделать по одному, но я не знаю, как сделать их одновременно.Я пытался создать поток, но возник конфликт, поскольку оба потока пытались получить доступ к одному и тому же ресурсу.Затем мой та сказал мне, что мне нужно использовать тройник и очереди, в основном, чтобы все разные пути совместно использовали одни и те же ресурсы вместо того, чтобы пытаться управлять им (вот что я думаю), я не уверен, как это сделатьхотя в java и сейчас в интернете нет хорошего учебника по java о тройниках ... (просмотрел немного, все, что есть, это код, который не компилируется на моей машине) вот идея того, что я делал

public class Main { 
private static Pipeline pipe;
private static Pipeline pipeB;
public static void main(String[] args) { 
    args = Gst.init("SwingVideoTest", args); 




    pipe = new Pipeline("pipeline");
    pipeB = new Pipeline("pipeline");

    final Element tee = ElementFactory.make("queue", null);
    Element queue0 = ElementFactory.make("queue", null);
    Element queue1 = ElementFactory.make("queue", null);
    AppSink appsink = (AppSink)ElementFactory.make("appsink", null);

    tee.set("silent", "false");
    appsink.set("emit-signals", "true");

    final Element videosrc = ElementFactory.make("v4l2src", "source");
    videosrc.set("device" , "/dev/video1");

    final Element colorspace = ElementFactory.make("ffmpegcolorspace", "colorspace");
    final Element videofilter = ElementFactory.make("capsfilter", "flt"); 
    videofilter.setCaps(Caps.fromString("video/x-raw-yuv,  width=640, height=480, framerate=10/1"));

    final Element enc = ElementFactory.make("ffenc_mpeg4", "Encoder");
    final Element mux = ElementFactory.make("avimux", "muxer");

    final Element sink = ElementFactory.make("filesink", "File sink");
    sink.set("location", "./test.avi");


    final Element videosrcB = ElementFactory.make("v4l2src", "source");
    videosrcB.set("device" , "/dev/video0");
    final Element videofilterB = ElementFactory.make("capsfilter", "flt"); 
    videofilterB.setCaps(Caps.fromString("video/x-raw-yuv, width=640, height=480"));



   VideoPlayer threadA = new VideoPlayer("screen", videosrcB, null, videofilterB, null, null, null, pipe);
   VideoPlayer threadB = new VideoPlayer("recorder", videosrc, colorspace, videofilter, enc, mux, sink, pipeB);


   threadA.run();
   threadB.run();
}




public class VideoPlayer implements Runnable{

private String playerType;
private Element videosrc, colorspace, videofilter, enc, mux, sink;
private Pipeline pipe;

VideoPlayer(final String playerType, final Element videosrc, final Element colorspace, final Element videofilter, final Element enc, final Element mux, final Element sink, final Pipeline pipe){
        this.playerType = playerType;
        this.videosrc = videosrc;
        this.colorspace = colorspace;
        this.videofilter = videofilter;
        this.enc = enc;
        this.mux = mux;
        this.sink = sink;
        this.pipe = pipe;
}

public void run(){
    VideoComponent videoComponent = new VideoComponent(); 

    Element videosink = videoComponent.getElement(); 



    if(playerType.equals("screen")){

        System.out.println(playerType);

        pipe.addMany(videosrc, videofilter, videosink);

        Element.linkMany(videosrc, videofilter, videosink);

        JFrame frame = new JFrame("Swing Video Test"); 
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
        frame.add(videoComponent, BorderLayout.CENTER); 
        videoComponent.setPreferredSize(new Dimension(640, 480)); 
        frame.pack(); 
        frame.setVisible(true); 
        // Start the pipeline processing 

        pipe.setState(State.PLAYING);
    }

    else if(playerType.equals("recorder")){

        System.out.println(playerType);


        pipe.addMany(videosrc,  colorspace, videofilter, enc, mux, sink);
        Element.linkMany(videosrc,  colorspace, videofilter,  enc, mux, sink);    

        JFrame frame = new JFrame("Swing Video Test"); 
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
        frame.add(videoComponent, BorderLayout.CENTER); 
        videoComponent.setPreferredSize(new Dimension(640, 480)); 
        frame.pack(); 
        //frame.setVisible(true); 

        pipe.setState(State.PLAYING);
    }
}

довольно долго, но довольно легко увидеть, что я пытался сделать.Если бы кто-нибудь мог сказать мне, как реализовать тройник (я пробовал?), Это было бы здорово.Спасибо!

1 Ответ

4 голосов
/ 14 февраля 2012

Вы не должны создавать два видеоисточника, как вы это сделали. videosrc & videosrcB.

По сути, вы должны получить данные от videosrc и передать их GstTee, теперь у тройника должно быть две SrcPad. Это позволит двум путям функционировать отдельно.

Первый путь src должен соединиться с вашими enc и mux, что приведет к записи, а второй путь появится на дисплее. Все должно работать одновременно.

Tee может быть буферизован Queue в каждом пути. С точки зрения схемы это не существенно, но это хорошо, так что путь № 2 не ждет, пока путь № 1 не завершится при вызове блокировки.

Вот как выглядит схема.

Circuit

...