<html>
  <head>

    <meta http-equiv="content-type" content="text/html; charset=utf-8">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    I've got two pipelines:<br>
    <br>
    data->video_pipeline = gst_parse_launch("udpsrc port=5000
    caps=application/x-rtp buffer-size=100000 ! rtph264depay !
    ffdec_h264 ! clockoverlay time-format=\"%D\n%H:%M:%S\" !
    autovideosink sync=false", &error);<br>
    <br>
    and another<br>
    <br>
    "udpsrc port=5000 caps=application/x-rtp buffer-size=100000 !
    rtph264depay  !  tee name=splitter ! ffdec_h264  ! clockoverlay
    time-format=\"%D\n%H:%M:%S\" ! autovideosink sync=false splitter. !
    queue ! mpegpsmux name=mux ! filesink location=" ( the string
    appends by file location and parses by gst_parse_launch also)<br>
    <br>
    And now i want to combine this two pipelines in one application. <br>
    What would i do with GStreamerSurfaceView when desire to switch to
    another pipeline?<br>
    <br>
    How sould i reinitialize Surface to prepare it to work with another
    pipe after setting the first one to Null- or Pause-state.<br>
    <br>
    <u>The native part of work with Surface:</u><br>
    <br>
    <font color="#3366ff"><i>static void gst_native_surface_init (JNIEnv
        *env, jobject thiz, jobject surface) {</i><i><br>
      </i><i>  CustomData *data = GET_CUSTOM_DATA (env, thiz,
        custom_data_field_id);</i><i><br>
      </i><i>  Surface = surface;</i><i><br>
      </i><i>  if (!data) return;</i><i><br>
      </i><i>  ANativeWindow *new_native_window =
        ANativeWindow_fromSurface(env, surface);</i><i><br>
      </i><i>  GST_DEBUG ("Received surface %p (native window %p)",
        surface, new_native_window);</i><i><br>
      </i><i><br>
      </i><i>  if (data->native_window) {</i><i><br>
      </i><i>    ANativeWindow_release (data->native_window);</i><i><br>
      </i><i>   </i><i><br>
      </i><i>     if (data->native_window == new_native_window) {</i><i><br>
      </i><i>        GST_DEBUG ("New native window is the same as the
        previous one", data->native_window);</i><i><br>
      </i><i>      if (data->video_sink) {</i><i><br>
      </i><i>        gst_x_overlay_expose(GST_X_OVERLAY
        (data->video_sink));</i><i><br>
      </i><i>        gst_x_overlay_expose(GST_X_OVERLAY
        (data->video_sink));</i><i><br>
      </i><i>      }</i><i><br>
      </i><i>      return;</i><i><br>
      </i><i>    } else {</i><i><br>
      </i><i>      GST_DEBUG ("Released previous native window %p",
        data->native_window);</i><i><br>
      </i><i>      data->initialized = FALSE;</i><i><br>
      </i><i>    }</i><i><br>
      </i><i>    </i><i><br>
      </i><i>  }</i><i><br>
      </i><i>  else data->native_window = new_native_window;</i><i><br>
      </i><i><br>
      </i><i>  check_initialization_complete (data);</i><i><br>
      </i><i>}</i><i><br>
      </i><i><br>
      </i><i>static void gst_native_surface_finalize (JNIEnv *env,
        jobject thiz) {</i><i><br>
      </i><i>  CustomData *data = GET_CUSTOM_DATA (env, thiz,
        custom_data_field_id);</i><i><br>
      </i><i>  if (!data) return;</i><i><br>
      </i><i>  GST_DEBUG ("Releasing Native Window %p",
        data->native_window);</i><i><br>
      </i><i><br>
      </i><i>  if (data->video_sink) {</i><i><br>
      </i><i>    gst_x_overlay_set_window_handle (GST_X_OVERLAY
        (data->video_sink), (guintptr)NULL);</i><i><br>
      </i><i>    gst_element_set_state (data->video_pipeline,
        GST_STATE_READY);</i><i><br>
      </i><i>  }</i><i><br>
      </i><i><br>
      </i><i>  ANativeWindow_release (data->native_window);</i><i><br>
      </i><i>  data->native_window = NULL;</i><i><br>
      </i><i>  data->initialized = FALSE;</i><i><br>
      </i><i>}</i></font><i><br>
    </i><br>
    <u>The GstreamerSurfaceView class:</u><u><br>
    </u><br>
    <font color="#3366ff"><i>import android.content.Context;</i><i><br>
      </i><i>import android.util.AttributeSet;</i><i><br>
      </i><i>import android.util.Log;</i><i><br>
      </i><i>import android.view.SurfaceView;</i><i><br>
      </i><i>import android.view.View;</i><i><br>
      </i><i><br>
      </i><i>// A simple SurfaceView whose width and height can be set
        from the outside</i><i><br>
      </i><i>public class GStreamerSurfaceView extends SurfaceView {</i><i><br>
      </i><i>    public int media_width = 320;</i><i><br>
      </i><i>    public int media_height = 240;</i><i><br>
      </i><i><br>
      </i><i>    // Mandatory constructors, they do not do much</i><i><br>
      </i><i>    public GStreamerSurfaceView(Context context,
        AttributeSet attrs,</i><i><br>
      </i><i>            int defStyle) {</i><i><br>
      </i><i>        super(context, attrs, defStyle);</i><i><br>
      </i><i>    }</i><i><br>
      </i><i><br>
      </i><i>    public GStreamerSurfaceView(Context context,
        AttributeSet attrs) {</i><i><br>
      </i><i>        super(context, attrs);</i><i><br>
      </i><i>    }</i><i><br>
      </i><i><br>
      </i><i>    public GStreamerSurfaceView (Context context) {</i><i><br>
      </i><i>        super(context);</i><i><br>
      </i><i>    }</i><i><br>
      </i><i><br>
      </i><i>    // Called by the layout manager to find out our size
        and give us some rules.</i><i><br>
      </i><i>    // We will try to maximize our size, and preserve the
        media's aspect ratio if</i><i><br>
      </i><i>    // we are given the freedom to do so.</i><i><br>
      </i><i>    @Override</i><i><br>
      </i><i>    protected void onMeasure(int widthMeasureSpec, int
        heightMeasureSpec) {</i><i><br>
      </i><i>        int width = 0, height = 0;</i><i><br>
      </i><i>        int wmode =
        View.MeasureSpec.getMode(widthMeasureSpec);</i><i><br>
      </i><i>        int hmode =
        View.MeasureSpec.getMode(heightMeasureSpec);</i><i><br>
      </i><i>        int wsize =
        View.MeasureSpec.getSize(widthMeasureSpec);</i><i><br>
      </i><i>        int hsize =
        View.MeasureSpec.getSize(heightMeasureSpec);</i><i><br>
      </i><i><br>
      </i><i>        Log.i ("GStreamer", "onMeasure called with " +
        media_width + "x" + media_height);</i><i><br>
      </i><i>        // Obey width rules</i><i><br>
      </i><i>        switch (wmode) {</i><i><br>
      </i><i>        case View.MeasureSpec.AT_MOST:</i><i><br>
      </i><i>            if (hmode == View.MeasureSpec.EXACTLY) {</i><i><br>
      </i><i>                width = Math.min(hsize * media_width /
        media_height, wsize);</i><i><br>
      </i><i>                break;</i><i><br>
      </i><i>            }</i><i><br>
      </i><i>        case View.MeasureSpec.EXACTLY:</i><i><br>
      </i><i>            width = wsize;</i><i><br>
      </i><i>            break;</i><i><br>
      </i><i>        case View.MeasureSpec.UNSPECIFIED:</i><i><br>
      </i><i>            width = media_width;</i><i><br>
      </i><i>        }</i><i><br>
      </i><i><br>
      </i><i>        // Obey height rules</i><i><br>
      </i><i>        switch (hmode) {</i><i><br>
      </i><i>        case View.MeasureSpec.AT_MOST:</i><i><br>
      </i><i>            if (wmode == View.MeasureSpec.EXACTLY) {</i><i><br>
      </i><i>                height = Math.min(wsize * media_height /
        media_width, hsize);</i><i><br>
      </i><i>                break;</i><i><br>
      </i><i>            }</i><i><br>
      </i><i>        case View.MeasureSpec.EXACTLY:</i><i><br>
      </i><i>            height = hsize;</i><i><br>
      </i><i>            break;</i><i><br>
      </i><i>        case View.MeasureSpec.UNSPECIFIED:</i><i><br>
      </i><i>            height = media_height;</i><i><br>
      </i><i>        }</i><i><br>
      </i><i><br>
      </i><i>        // Finally, calculate best size when both axis are
        free</i><i><br>
      </i><i>        if (hmode == View.MeasureSpec.AT_MOST &&
        wmode == View.MeasureSpec.AT_MOST) {</i><i><br>
      </i><i>            int correct_height = width * media_height /
        media_width;</i><i><br>
      </i><i>            int correct_width = height * media_width /
        media_height;</i><i><br>
      </i><i><br>
      </i><i>            if (correct_height < height)</i><i><br>
      </i><i>                height = correct_height;</i><i><br>
      </i><i>            else</i><i><br>
      </i><i>                width = correct_width;</i><i><br>
      </i><i>        }</i><i><br>
      </i><i><br>
      </i><i>        // Obey minimum size</i><i><br>
      </i><i>        width = Math.max (getSuggestedMinimumWidth(),
        width);</i><i><br>
      </i><i>        height = Math.max (getSuggestedMinimumHeight(),
        height);</i><i><br>
      </i><i>        setMeasuredDimension(width, height);</i><i><br>
      </i><i>    }</i><i><br>
      </i><i><br>
      </i><i>}</i></font><br>
    <br>
    The MainActivity implements SurfaceHolder.Callback:<br>
    <br>
    <font color="#3333ff"><i> public void surfaceChanged(SurfaceHolder
        holder, int format, int width,</i><i><br>
      </i><i>                int height) {</i><i><br>
      </i><i>            Log.d("GStreamer", "Surface changed to format "
        + format + " width "</i><i><br>
      </i><i>                    + width + " height " + height);</i><i><br>
      </i><i>          /</i><i></i><i><br>
      </i><i>                </i><i><br>
      </i><i>            nativeSurfaceInit (holder.getSurface());</i><i><br>
      </i><i>           nativePlay(); </i><i><br>
      </i><i>         </i><i>            </i><i><br>
      </i><i>        }</i><i><br>
      </i><i><br>
      </i><i>        public void surfaceCreated(SurfaceHolder holder) {</i><i><br>
      </i><i>            Log.d("GStreamer", "Surface created: " +
        holder.getSurface());</i><i><br>
      </i><i>        }</i><i><br>
      </i><i><br>
      </i><i>        public void surfaceDestroyed(SurfaceHolder holder)
        {</i><i><br>
      </i><i>            Log.d("GStreamer", "Surface destroyed");</i><i><br>
      </i><i>           // nativePause();</i><i><br>
      </i><i>            nativeSurfaceFinalize ();</i><i><br>
      </i><i>        }</i><i><br>
      </i><i><br>
      </i></font><br>
  </body>
</html>