2012-02-14 1 views
3

그래서 자바 용 gstreamer를 사용하고 있으며 라이브 비디오 스트림을 재생하고 동시에 기록하려고합니다. 지금 당장은 한 번에 하나씩 할 수는 있지만 동시에 두 가지를 모두 수행하는 방법을 모르겠습니다. 스레드를 시도했지만 두 스레드가 동일한 리소스에 액세스하려고했기 때문에 충돌이있었습니다. 그런 다음, 내 차는 티와 대기열을 사용해야한다고 말했습니다. 기본적으로 모든 다른 경로가 그것을 제어하려고 시도하는 대신 동일한 리소스를 공유합니다 (내가 생각하는 것). 어떻게해야할지 모르겠습니다. 자바에서, 그리고 지금은 인터넷 doesnt 자바 티셔츠에 대한 좋은 자습서가 ... (비트를 보았다, 그게 전부 내 컴퓨터에서 컴파일하지 않는 코드입니다) heres는 내가 뭘하는지 heres 생각Gstreamer Tee/Queue multiple pipelining

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); 
    } 
} 

다소 길지만 꽤 쉽게 나는 무엇을 하려는지 알기가 쉽습니다. 누구든지 티를 구현하는 법을 말해 줄 수 있다면 (시도해 보셨나요?) 그렇게 좋을 것입니다. 감사!

답변

4

두 비디오 소스를 만들지 말아야합니다. videosrc & videosrcB.

기본적으로 videosrc의 데이터를 받아야하고 GstTee으로 지정해야합니다. 이제 Tee에는 2 개의 SrcPads가 있어야합니다. 이렇게하면 두 경로가 별도로 작동 할 수 있습니다.

첫 번째 src 경로는 encmux에 연결되어야 녹음이 진행되며 두 번째 경로가 표시됩니다. 모두 동시에 작동해야합니다.

Tee은 각 경로에 Queue으로 버퍼링 할 수 있습니다. 회로의 관점에서 이것은 필수적인 것은 아니지만 경로 # 1이 차단 호출에서 경로 # 1이 끝날 때까지 대기하지 않는 것이 좋습니다.

다음은 회로의 모양입니다.

Circuit

+0

어디에서 대기열을 넣을 까? –