2012-04-06 82 views
1

SDPファイルを読み込み、ビデオストリームをh.264にエンコードし、オーディオストリームをaacにエンコードします。次に、それらのストリームをaviストリームに多重化し、次にファイルに多重化したいと考えています。私はSDPファイルの内容を事前に知らないので、playbin2を使うのが一番簡単です。Gstreamer:ビンを2つのシンクで再生ビンにリンクする

だから、私はこのような何かを考えていた:

       RawToAviMux Bin 
         ______________________________________ 
       ----- |ghostpad----x264enc 
      /  |     \ 
playbin2------  |     avimux--filesink 
       \  |     /
       -------| ghostpad----ffenc_aac 
         |_______________________________________ 

setting playbin2's videosink to an instance of RawToAviMux 
     and playbin2's audiosink to the same instance of RawToAviMux 

しかし、私は再生状態にパイプラインを取得することはできません。 RawToAviMuxerで

  recorder = new Gst.BasePlugins.PlayBin2(); 
      recorder.PlayFlags &= ~((Gst.BasePlugins.PlayBin2.PlayFlagsType)(1 << 2)); 
      recorder.Bus.AddSignalWatch(); 
      recorder.Bus.EnableSyncMessageEmission(); 

      RawToAviMuxer aviMuxer = new RawToAviMuxer(fileName);    

      recorder.VideoSink = aviMuxer; 
      recorder.AudioSink = aviMuxer; 

      recorder.SetState(Gst.State.Ready); 
      recorder.Uri = @"file:///" + filePath.Replace('\\', '/'); 
      recorder.SetState(Gst.State.Paused); 
      recorder.SetState(Gst.State.Playing); 

      Gst.State currentState; 
      Gst.State playingState = Gst.State.Playing; 
      Gst.StateChangeReturn stateReturn = recorder.GetState(out currentState, out playingState, Gst.Clock.Second); 

      if (stateReturn != Gst.StateChangeReturn.Failure) 
       return true; 

      return false; 

私は、デバッガの貫通強化していると、すべてのリンクが成功した

public class RawToAviMuxer : Gst.Bin 
{ 
    bool test = false; 

    public RawToAviMuxer(string outputFileName) 
     : base("rawToAviMux") 
    { 
     Gst.Element x264Enc = Gst.ElementFactory.Make("x264enc"); 
     Gst.Element ffenc_aac = Gst.ElementFactory.Make("ffenc_aac"); 

     x264Enc["bframes"] = (uint)0; 
     x264Enc["b-adapt"] = false; 
     x264Enc["bitrate"] = (uint)1024; 
     x264Enc["tune"] = 0x4; 
     x264Enc["speed-preset"] = 3; 
     x264Enc["sliced-threads"] = false; 
     x264Enc["profile"] = 0; 
     x264Enc["key-int-max"] = (uint)30; 

     Gst.GhostPad videoToX264Pad = new Gst.GhostPad("video_sink", x264Enc.GetStaticPad("sink")); 
     Gst.GhostPad audioToAACPad = new Gst.GhostPad("audio_sink", ffenc_aac.GetStaticPad("sink")); 

     test = this.AddPad(videoToX264Pad); 
     test = this.AddPad(audioToAACPad); 

     Gst.Element aviMux = Gst.ElementFactory.Make("avimux"); 
     Gst.Element fileSink = Gst.ElementFactory.Make("filesink"); 

     test = this.Add(new Gst.Element[]{x264Enc, ffenc_aac, aviMux, fileSink}); 
     test = x264Enc.Link(aviMux); 
     test = ffenc_aac.Link(aviMux); 
     test = aviMux.Link(fileSink); 

     fileSink["location"] = outputFileName; 
    } 
} 

として:ここで

はコードです。

uridecodebin uri=file:///C:/Users/Jonathan/AppData/Local/Temp/192.168.0.215_5000.sdp ! 
x264enc byte-stream=true bframes=0 b-adapt=0 tune=0x4 speed-preset=3 sliced-threads=false 
profile=0 ! mux. ffenc_aac ! mux. avimux name=mux ! filesink location=C:\Users\Jonathan\Desktop\test.avi 

、私はまだそれが一時停止してから抜け出すことはできません。

更新が

は[OK]をので、私はGst.Parse.Launchと、次のパイプラインを試してみました。

私はWindowsビルドを使用していますので、おそらく何か問題がありますか?

私は実際に何が起こっているのか把握できるように、メッセージハンドラをバスに付けることもできません。これは本当に迷惑になり始めます。

私はちょうど私が直接フォーマットが前もって何であるかを知ってudpsrc素子を介してストリームを、つかむ場合、これはしかし、

、それだけでrtph264depay要素では動作しません見つけました。パイプラインにh264parse要素がなければなりません。これはuridecodebinが私のために働いていない理由かもしれません?

は、私は次のことをやってしまった を解く:

  if (!gst_is_init) 
      {     
       Gst.Application.Init(); 
       gst_is_init = true; 
      } 

      if(recorder != null) 
      { 
       recorder.SetState(Gst.State.Null); 
       recorder.Dispose(); 
      } 

      string videoDepay, audioDepay, strExtension, strMuxer; 

      GetGstElements(stream.VideoCaps, out videoDepay, out strMuxer, out strExtension); 
      GetGstElements(stream.AudioCaps, out audioDepay, out strMuxer, out strExtension); 

      fileName = Path.ChangeExtension(fileName, strExtension); 

      //recorder = new Gst.Pipeline("recordingPipe"); 
      string pipeString = String.Format("udpsrc port={0} ! {1} {2} ! {3} ! queue ! mux. udpsrc port={4} ! {1} {5} ! {6} ! mux. {7} name=mux ! filesink location={8}", 
       portToUse, "application/x-rtp,", stream.VideoCaps, videoDepay, (portToUse + 2), stream.AudioCaps, audioDepay, strMuxer, fileName.Replace("\\", "\\\\")); 

      recorder = (Gst.Pipeline)Gst.Parse.Launch(pipeString);     

      recordingFileName = fileName; 

       recorder.SetState(Gst.State.Ready);     
      recorder.SetState(Gst.State.Paused);     
      recorder.SetState(Gst.State.Playing); 

      Gst.State currentState;     

      Gst.StateChangeReturn stateReturn = recorder.GetState(out currentState, Gst.Clock.Second);    

      if (stateReturn != Gst.StateChangeReturn.Failure) 
       return true; 

      return false; 

あなたが演奏に行くパイプラインのために、すべてのストリームのためのパーサを持っている必要があります。ですから、h264ストリームが入っている場合は、rtph264depayを使う必要があります! h264parse。さらに、NALUとバイトストリームはタイミングが合うように一致する必要があります。

また、ファイルを使用できるようにするには、パイプラインを廃棄する前にEOSをダウンストリームで送信する必要があります。

   recorder.SendEvent(Gst.Event.NewEos()); 
       System.Threading.Thread.Sleep(100); 
       recorder.SetState(Gst.State.Paused); 
       recorder.SetState(Gst.State.Ready); 
       recorder.SetState(Gst.State.Null); 
       recorder.Dispose();    

答えて

1

はい、これは機能しません。ここであなたがそれを行う方法があります。 Playbin2はモジュラーコンポーネントで、uridecodebinとplaysinkbinで構成されています。メディアファイルuriを設定し、パッド追加用のシグナルハンドラを追加し、新しく作成されたパッドをrawtoavimuxコンポーネントのシンクパッドに接続するだけで、uridecodebinを使用することができます。

rawtoavimuxの代わりに、encodebinを使用することもできます。 uridecodebinを使用する!1つ以上のストリームのフォーマットが既に正しいフォーマットになっている場合、エンコード・ビンは潜在的にスマート・トランスコーディングを行い、デコードおよび再エンコードを回避することができる。

+0

[OK]を、今私はそれを行うuridecodebinの方法を参照してください、ありがとう!しかし、私はgst-inspectでencodebinを見つけることができません。 –

+0

多少新品です。あなたは新しいgtreamerのバージョンを得ることができます(例えば、ubuntuのgstreamer-developers-ppa)。 – ensonic

+0

この特定のコンポーネントは、Windowsビルドを使用しています。彼らはまだそれを持っているとは思わない。とにかく、私はそれまでそれをコード変換する必要があります。ありがとう! –

関連する問題