Package org.gstreamer

Source Code of org.gstreamer.Bus$SEGMENT_START

/*
* Copyright (C) 2007 Wayne Meissner
* Copyright (C) 2004 Wim Taymans <wim@fluendo.com>
*
* This file is part of gstreamer-java.
*
* This code is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
* version 3 for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.
*/

package org.gstreamer;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.gstreamer.event.BusSyncHandler;
import org.gstreamer.lowlevel.GstBusAPI;
import org.gstreamer.lowlevel.GstMessageAPI;
import org.gstreamer.lowlevel.GstMiniObjectAPI;
import org.gstreamer.lowlevel.GstNative;
import org.gstreamer.lowlevel.GstAPI.GErrorStruct;
import org.gstreamer.lowlevel.GstAPI.GstCallback;
import org.gstreamer.lowlevel.GstBusAPI.BusCallback;

import com.sun.jna.Callback;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.PointerByReference;

import static org.gstreamer.lowlevel.GlibAPI.GLIB_API;

/**
* The {@link Bus} is an object responsible for delivering {@link Message}s in
* a first-in first-out way from the streaming threads to the application.
* <p>
* Since the application typically only wants to deal with delivery of these
* messages from one thread, the Bus will marshall the messages between
* different threads. This is important since the actual streaming of media
* is done in another thread than the application.
* <p>
* A message is posted on the bus with the gst_bus_post() method. With the
* gst_bus_peek() and gst_bus_pop() methods one can look at or retrieve a
* previously posted message.
* <p>
* The bus can be polled with the gst_bus_poll() method. This methods blocks
* up to the specified timeout value until one of the specified messages types
* is posted on the bus. The application can then _pop() the messages from the
* bus to handle them.
* <p>
* It is also possible to get messages from the bus without any thread
* marshalling with the {@link #setSyncHandler} method. This makes it
* possible to react to a message in the same thread that posted the
* message on the bus. This should only be used if the application is able
* to deal with messages from different threads.
* <p>
* Every {@link Pipeline} has one bus.
* <p>
* Note that a Pipeline will set its bus into flushing state when changing
* from READY to NULL state.
*/
public class Bus extends GstObject {
    static final Logger log = Logger.getLogger(Bus.class.getName());
    static final Level LOG_DEBUG = Level.FINE;
   
    // Create an API with just the subset needed.
    private static interface API extends GstBusAPI, GstMessageAPI, GstMiniObjectAPI {}
    private static final API gst = GstNative.load(API.class);

    /**
     * This constructor is used internally by gstreamer-java
     *
     * @param init internal initialization data
     */
    public Bus(Initializer init) {
        super(init);
        gst.gst_bus_set_sync_handler(this, null, null);
        gst.gst_bus_set_sync_handler(this, syncCallback, null);
    }
   
    /**
     * Instructs the bus to flush out any queued messages.
     *
     * If flushing, flush out any messages queued in the bus. Will flush future
     * messages until {@link #setFlushing} is called with false.
     *
     * @param flushing true if flushing is desired.
     */
    public void setFlushing(boolean flushing) {
        gst.gst_bus_set_flushing(this, flushing ? 1 : 0);
    }
   
    /**
     * Signal emitted when end-of-stream is reached in a pipeline.
     *
     * The application will only receive this message in the PLAYING state and
     * every time it sets a pipeline to PLAYING that is in the EOS state.
     * The application can perform a flushing seek in the pipeline, which will
     * undo the EOS state again.
     *
     * @see #connect(EOS)
     * @see #disconnect(EOS)
     */
    public static interface EOS {
        /**
         * Called when a {@link Pipeline} element posts a end-of-stream message.
         *
         * @param source the element which posted the message.
         */
        public void endOfStream(GstObject source);
    }
   
    /**
     * Signal emitted when an error occurs.
     * <p>
     * When the application receives an error message it should stop playback
     * of the pipeline and not assume that more data will be played.
     *
     * @see #connect(ERROR)
     * @see #disconnect(ERROR)
     */
    public static interface ERROR {
        /**
         * Called when a {@link Pipeline} element posts an error message.
         *
         * @param source the element which posted the message.
         * @param code a numeric code representing the error.
         * @param message a string representation of the error.
         */
        public void errorMessage(GstObject source, int code, String message);
    }
   
    /**
     * Signal emitted when a warning message is delivered.
     *
     * @see #connect(WARNING)
     * @see #disconnect(WARNING)
     */
    public static interface WARNING {
        /**
         * Called when a {@link Pipeline} element posts an warning message.
         *
         * @param source the element which posted the message.
         * @param code a numeric code representing the warning.
         * @param message a string representation of the warning.
         */
        public void warningMessage(GstObject source, int code, String message);
    }
   
    /**
     * Signal emitted when an informational message is delivered.
     *
     * @see #connect(INFO)
     * @see #disconnect(INFO)
     */
    public static interface INFO {
        /**
         * Called when a {@link Pipeline} element posts an informational message.
         *
         * @param source the element which posted the message.
         * @param code a numeric code representing the informational message.
         * @param message a string representation of the informational message.
         */
        public void infoMessage(GstObject source, int code, String message);
    }
   
    /**
     * Signal emitted when a new tag is identified on the stream.
     *
     * @see #connect(TAG)
     * @see #disconnect(TAG)
     */
    public static interface TAG {
        /**
         * Called when a {@link Pipeline} element finds media meta-data.
         *
         * @param source the element which posted the message.
         * @param tagList a list of media meta-data.
         */
        public void tagsFound(GstObject source, TagList tagList);
    }
   
    /**
     * Signal emitted when a state change happens.
     *
     * @see #connect(STATE_CHANGED)
     * @see #disconnect(STATE_CHANGED)
     */
    public static interface STATE_CHANGED {
        /**
         * Called when a {@link Pipeline} element executes a {@link State} change.
         *
         * @param source the element which posted the message.
         * @param old the old state that the element is changing from.
         * @param current the new (current) state the element is changing to.
         * @param pending the pending (target) state.
         */
        public void stateChanged(GstObject source, State old, State current, State pending);
    }
   
    /**
     * Signal emitted when the pipeline is buffering data.
     *
     * @see #connect(BUFFERING)
     * @see #disconnect(BUFFERING)
     */
    public static interface BUFFERING {
        /**
         * Called when a {@link Pipeline} element needs to buffer data before
         * it can continue processing.
         * <p>
         * {@code percent} is a value between 0 and 100. A value of 100 means that
         * the buffering completed.
         * <p>
         * When {@code percent} is < 100 the application should PAUSE a PLAYING pipeline.
         * When {@code percent} is 100, the application can set the pipeline (back) to PLAYING.
         * <p>
         * The application must be prepared to receive BUFFERING messages in the
         * PREROLLING state and may only set the pipeline to PLAYING after receiving a
         * message with {@code percent} set to 100, which can happen after the pipeline
         * completed prerolling.
         *
         * @param source the element which posted the message.
         * @param percent the percentage of buffering that has completed.
         */
        public void bufferingData(GstObject source, int percent);
    }
   
    /**
     * Signal sent when a new duration message is posted by an element that
     * know the duration of a stream in a specific format.
     * <p>
     * This message is received by bins and is used to calculate the total
     * duration of a pipeline.
     * <p>
     * Elements may post a duration message with a duration of
     * {@link ClockTime#NONE} to indicate that the duration has changed and the
     * cached duration should be discarded. The new duration can then be
     * retrieved via a query.
     * The application can get the new duration with a duration query.
     *
     * @see #connect(DURATION)
     * @see #disconnect(DURATION)
     */
    public static interface DURATION {
        /**
         * Called when a new duration message is posted on the Bus.
         *
         * @param source the element which posted the message.
         * @param format the format of the duration
         * @param duration the new duration.
         */
        public void durationChanged(GstObject source, Format format, long duration);
    }
   
    /**
     * This message is posted by elements that start playback of a segment as a
     * result of a segment seek.
     * <p>
     * This message is not received by the application
     * but is used for maintenance reasons in container elements.
     */
    public static interface SEGMENT_START {
        public void segmentStart(GstObject source, Format format, long position);
    }
   
    /**
     * Signal emitted when the pipeline has completed playback of a segment.
     * <p>
     * This message is posted by elements that finish playback of a segment as a
     * result of a segment seek. This message is received by the application
     * after all elements that posted a {@link SEGMENT_START} have posted segment-done.
     *
     * @see #connect(SEGMENT_DONE)
     * @see #disconnect(SEGMENT_DONE)
     */
    public static interface SEGMENT_DONE {
        /**
         * Called when a segment-done message has been posted.
         *
         * @param source the element which posted the message.
         * @param format the format of the position being done.
         * @param position the position of the segment being done.
         */
        public void segmentDone(GstObject source, Format format, long position);
    }
   
    /**
     * Signal emitted by elements when they complete an ASYNC state change.
     * <p>
     * Applications will only receive this message from the top level pipeline.
     * </p>
     *
     * @see #connect(ASYNC_DONE)
     * @see #disconnect(ASYNC_DONE)
     */
    public static interface ASYNC_DONE {
        /**
         * Called when a segment-done message has been posted.
         *
         * @param source the element which posted the message.
         */
        public void asyncDone(GstObject source);
    }

    /**
     * Catch all signals emitted on the Bus. 
     * <p>
     * The signal handler will be called asynchronously from the thread that posted
     * the message on the Bus.
     *
     * @see #connect(MESSAGE)
     * @see #disconnect(MESSAGE)
     */
    public static interface MESSAGE {
        /**
         * Called when a {@link Element} posts a {@link Message} on the Bus.
         *
         * @param bus the Bus the message was posted on.
         * @param message the message that was posted.
         */
        public void busMessage(Bus bus, Message message);
    }

    /**
     * Add a listener for end-of-stream messages.
     *
     * @param listener The listener to be called when end-of-stream is encountered.
     */
    public void connect(final EOS listener) {
        connect(EOS.class, listener, new BusCallback() {
            public boolean callback(Bus bus, Message msg, Pointer user_data) {
                listener.endOfStream(msg.getSource());
                return true;
            }
        });
    }
   
    /**
     * Disconnect the listener for end-of-stream messages.
     *
     * @param listener The listener that was registered to receive the message.
     */
    public void disconnect(EOS listener) {
        disconnect(EOS.class, listener);
    }
   
    /**
     * Add a listener for error messages.
     *
     * @param listener The listener to be called when an error in the stream is encountered.
     */
    public void connect(final ERROR listener) {
        connect(ERROR.class, listener, new BusCallback() {
            public boolean callback(Bus bus, Message msg, Pointer user_data) {
                PointerByReference err = new PointerByReference();
                gst.gst_message_parse_error(msg, err, null);
                GErrorStruct error = new GErrorStruct(err.getValue());
                listener.errorMessage(msg.getSource(), error.getCode(), error.getMessage());
                GLIB_API.g_error_free(err.getValue());
                return true;
            }
        });
    }
   
    /**
     * Disconnect the listener for error messages.
     *
     * @param listener The listener that was registered to receive the message.
     */
    public void disconnect(ERROR listener) {
        disconnect(ERROR.class, listener);
    }
   
    /**
     * Add a listener for warning messages.
     *
     * @param listener The listener to be called when an {@link Element} emits a warning.
     */
    public void connect(final WARNING listener) {
        connect(WARNING.class, listener, new BusCallback() {
            public boolean callback(Bus bus, Message msg, Pointer user_data) {
                PointerByReference err = new PointerByReference();
                gst.gst_message_parse_warning(msg, err, null);               
                GErrorStruct error = new GErrorStruct(err.getValue());
                listener.warningMessage(msg.getSource(), error.getCode(), error.getMessage());
                GLIB_API.g_error_free(err.getValue());
                return true;
            }
        });
    }
   
    /**
     * Disconnect the listener for warning messages.
     *
     * @param listener The listener that was registered to receive the message.
     */
    public void disconnect(WARNING listener) {
        disconnect(WARNING.class, listener);
    }
   
    /**
     * Add a listener for informational messages.
     *
     * @param listener The listener to be called when an {@link Element} emits a an informational message.
     */
    public void connect(final INFO listener) {
        connect(INFO.class, listener, new BusCallback() {
            public boolean callback(Bus bus, Message msg, Pointer user_data) {
                PointerByReference err = new PointerByReference();
                gst.gst_message_parse_info(msg, err, null);               
                GErrorStruct error = new GErrorStruct(err.getValue());
                listener.infoMessage(msg.getSource(), error.getCode(), error.getMessage());
                GLIB_API.g_error_free(err.getValue());
                return true;
            }
        });
    }
   
    /**
     * Disconnect the listener for informational messages.
     *
     * @param listener The listener that was registered to receive the message.
     */
    public void disconnect(INFO listener) {
        disconnect(INFO.class, listener);
    }
   
    /**
     * Add a listener for {@link State} changes in the Pipeline.
     *
     * @param listener The listener to be called when the Pipeline changes state.
     */
    public void connect(final STATE_CHANGED listener) {
        connect(STATE_CHANGED.class, listener, new BusCallback() {
            public boolean callback(Bus bus, Message msg, Pointer user_data) {
                State[] o = new State[1];
                State[] n = new State[1];
                State[] p = new State[1];
                gst.gst_message_parse_state_changed(msg, o, n, p);
                listener.stateChanged(msg.getSource(), o[0], n[0], p[0]);
                return true;
            }
        });
    }
    /**
     * Disconnect the listener for {@link State} change messages.
     *
     * @param listener The listener that was registered to receive the message.
     */
    public void disconnect(STATE_CHANGED listener) {
        disconnect(STATE_CHANGED.class, listener);
    }
    /**
     * Add a listener for new media tags.
     *
     * @param listener The listener to be called when new media tags are found.
     */
    public void connect(final TAG listener) {
        connect(TAG.class, listener, new BusCallback() {
            public boolean callback(Bus bus, Message msg, Pointer user_data) {
                PointerByReference list = new PointerByReference();
                gst.gst_message_parse_tag(msg, list);
                TagList tl = new TagList(TagList.initializer(list.getValue()));
                listener.tagsFound(msg.getSource(), tl);
                return true;
            }
        });
    }
   
    /**
     * Disconnect the listener for tag messages.
     *
     * @param listener The listener that was registered to receive the message.
     */
    public void disconnect(TAG listener) {
        disconnect(TAG.class, listener);
    }
   
    /**
     * Add a listener for {@link BUFFERING} messages in the Pipeline.
     *
     * @param listener The listener to be called when the Pipeline buffers data.
     */
    public void connect(final BUFFERING listener) {
        connect(BUFFERING.class, listener, new BusCallback() {
            public boolean callback(Bus bus, Message msg, Pointer user_data) {
                int[] percent = { 0 };
                gst.gst_message_parse_buffering(msg, percent);
                listener.bufferingData(msg.getSource(), percent[0]);
                return true;
            }
        });
    }
   
    /**
     * Disconnect the listener for buffering messages.
     *
     * @param listener The listener that was registered to receive the message.
     */
    public void disconnect(BUFFERING listener) {
        disconnect(BUFFERING.class, listener);
    }
   
    /**
     * Add a listener for duration changes.
     *
     * @param listener The listener to be called when the duration changes.
     */
    public void connect(final DURATION listener) {
        connect(DURATION.class, listener, new BusCallback() {
            public boolean callback(Bus bus, Message msg, Pointer user_data) {
                System.out.println("duration update");
                Format[] format = new Format[1];
                long[] duration = { 0 };
                gst.gst_message_parse_duration(msg, format, duration);
                listener.durationChanged(msg.getSource(), format[0], duration[0]);
                return true;
            }
        });
    }
    /**
     * Disconnect the listener for duration change messages.
     *
     * @param listener The listener that was registered to receive the message.
     */
    public void disconnect(DURATION listener) {
        disconnect(DURATION.class, listener);
    }
   
    /**
     * Add a listener for {@link SEGMENT_START} messages in the Pipeline.
     *
     * @param listener The listener to be called when the Pipeline has started a segment.
     */
    public void connect(final SEGMENT_START listener) {
        connect(SEGMENT_START.class, listener, new BusCallback() {
            public boolean callback(Bus bus, Message msg, Pointer user_data) {
                Format[] format = new Format[1];
                long[] position = { 0 };
                gst.gst_message_parse_segment_start(msg, format, position);
                listener.segmentStart(msg.getSource(), format[0], position[0]);
                return true;
            }
        });
    }
   
    /**
     * Disconnect the listener for segment-start messages.
     *
     * @param listener The listener that was registered to receive the message.
     */
    public void disconnect(SEGMENT_START listener) {
        disconnect(SEGMENT_START.class, listener);
    }
   
    /**
     * Add a listener for {@link SEGMENT_DONE} messages in the Pipeline.
     *
     * @param listener The listener to be called when the Pipeline has finished a segment.
     */
    public void connect(final SEGMENT_DONE listener) {
        connect(SEGMENT_DONE.class, listener, new BusCallback() {
            public boolean callback(Bus bus, Message msg, Pointer user_data) {
                Format[] format = new Format[1];
                long[] position = { 0 };
                gst.gst_message_parse_segment_done(msg, format, position);
                listener.segmentDone(msg.getSource(), format[0], position[0]);
                return true;
            }
        });
    }
   
    /**
     * Disconnect the listener for segment-done messages.
     *
     * @param listener The listener that was registered to receive the message.
     */
    public void disconnect(SEGMENT_DONE listener) {
        disconnect(SEGMENT_DONE.class, listener);
    }
   
    /**
     * Add a listener for {@link ASYNC_DONE} messages in the Pipeline.
     *
     * @param listener The listener to be called when the an element has finished
     * an async state change.
     */
    public void connect(final ASYNC_DONE listener) {
        connect(ASYNC_DONE.class, listener, new BusCallback() {
            public boolean callback(Bus bus, Message msg, Pointer user_data) {
                listener.asyncDone(msg.getSource());
                return true;
            }
        });
    }
   
    /**
     * Disconnect the listener for async-done messages.
     *
     * @param listener The listener that was registered to receive the message.
     */
    public void disconnect(ASYNC_DONE listener) {
        disconnect(ASYNC_DONE.class, listener);
    }

    /**
     * Add a listener for all messages posted on the Bus.
     *
     * @param listener The listener to be called when a {@link Message} is posted.
     */
    public void connect(final MESSAGE listener) {
        connect(MESSAGE.class, listener, new BusCallback() {
            public boolean callback(Bus bus, Message msg, Pointer user_data) {
                listener.busMessage(bus, msg);
                return true;
            }
        });
    }
   
    /**
     * Add a listener for messages of type {@code signal} posted on the Bus.
     *
     * @param signal the signal to connect to.
     * @param listener The listener to be called when a {@link Message} is posted.
     */
    public void connect(String signal, final MESSAGE listener) {
        //
        // Deal with being called as e.g. "message::eos"
        //
        if (signal.contains("::")) {
            signal = signal.substring(signal.lastIndexOf("::") + 2);
        }
        connect(signal, MESSAGE.class, listener, new BusCallback() {
            public boolean callback(Bus bus, Message msg, Pointer user_data) {
                listener.busMessage(bus, msg);
                return true;
            }
        });
    }
   
    /**
     * Disconnect the listener for segment-done messages.
     *
     * @param listener The listener that was registered to receive the message.
     */
    public void disconnect(MESSAGE listener) {
        disconnect(MESSAGE.class, listener);
    }
   
    /**
     * Posts a {@link Message} on this Bus.
     *
     * @param message the message to post.
     * @return <tt>true</tt> if the message could be posted, <tt>false</tt> if
     * the bus is flushing.
     */
    public boolean post(Message message) {
        return gst.gst_bus_post(this, message);
    }
   
    private BusSyncHandler syncHandler = new BusSyncHandler() {
        public BusSyncReply syncMessage(Message msg) {
            return BusSyncReply.PASS;
        }
    };
    public BusSyncHandler getSyncHandler() {
        return syncHandler;
    }
    public void setSyncHandler(BusSyncHandler handler) {
        syncHandler = handler;
    }
    private static GstCallback syncCallback = new GstCallback() {
        @SuppressWarnings("unused")
        public int callback(final Bus bus, final Message msg, Pointer data) {
            BusSyncReply reply = bus.syncHandler.syncMessage(msg);
           
            if (reply != BusSyncReply.DROP) {
                Gst.getExecutor().execute(new Runnable() {
                    public void run() {
                        bus.dispatchMessage(msg);
                    }
                });
            }
            //
            // Unref the message, since we are dropping it.
            // (the normal GC will drop other refs to it)
            //
            gst.gst_mini_object_unref(msg);
            return BusSyncReply.DROP.intValue();
        }
    };
   
    /**
     * Connects to a signal.
     *
     * The signal name is deduced from the listenerClass name.
     *
     * @param listenerClass the class of the listener.
     * @param listener the listener to associate with the {@code callback}
     * @param callback The callback to call when the signal is emitted.
     */
    private <T> void connect(Class<T> listenerClass, T listener, BusCallback callback) {
        final String signal = listenerClass.getSimpleName().toLowerCase().replaceAll("_", "-");
        connect(signal, listenerClass, listener, callback);
    }
   
    /**
     * Connects a callback to a signal.
     * <p>
     * This differs to {@link GObject#connect} in that it hooks up Bus signals
     * to the sync callback, not the generic GObject signal mechanism.
     *
     * @param signal the name of the signal to connect to.
     * @param listenerClass the class of the {@code listener}
     * @param listener the listener to associate with the {@code callback}
     * @param callback the callback to call when the signal is emitted.
     */
    @Override
    public synchronized <T> void connect(String signal, Class<T> listenerClass, T listener,
            final Callback callback) {
        if (listenerClass.getEnclosingClass() != Bus.class) {
            super.connect(signal, listenerClass, listener, callback);
            return;
        }
        MessageType type = MessageType.forName(signal);
        if (type == MessageType.UNKNOWN && "message".equals(signal)) {
            type = MessageType.ANY;
        }
        if (type == MessageType.UNKNOWN) {
            throw new IllegalArgumentException("Illegal signal: " + signal);
        }
        final Map<Class<?>, Map<Object, MessageProxy>> signals = getListenerMap();
        Map<Object, MessageProxy> m = signals.get(type);
        if (m == null) {
            m = new HashMap<Object, MessageProxy>();
            signals.put(listenerClass, m);
        }
        MessageProxy proxy = new MessageProxy(type, (BusCallback) callback);
        m.put(listener, proxy);
        messageProxies.add(proxy);
    }
   
    @Override
    public synchronized <T> void disconnect(Class<T> listenerClass, T listener) {
        if (listenerClass.getEnclosingClass() != Bus.class) {
            super.disconnect(listenerClass, listener);
            return;
        }
        final Map<Class<?>, Map<Object, MessageProxy>> signals = getListenerMap();
        Map<Object, MessageProxy> m = signals.get(listenerClass);
        if (m != null) {
            MessageProxy proxy = m.remove(listener);
            if (proxy != null) {
                messageProxies.remove(proxy);
            }
            if (m.isEmpty()) {
                signals.remove(listenerClass);
            }
        }
    }
   
    /**
     * Dispatches a message to all interested listeners.
     *
     * <p>
     * We do this here from a sync callback, because the default gstbus dispatch
     * uses the default main context to signal that there are messages waiting on
     * the bus.  Since that is used by the GTK L&F under swing, we never get those
     * notifications, and the messages just queue up.
     * @param message
     */
    private void dispatchMessage(Message msg) {
        // Dispatch to listeners
        for (Object listener : messageProxies) {
            ((MessageProxy) listener).busMessage(this, msg);
        }
    }
    private static class MessageProxy implements MESSAGE {
        private final MessageType type;
        private final BusCallback callback;
        public MessageProxy(MessageType type, BusCallback callback) {
            this.type = type;
            this.callback = callback;
        }
        public void busMessage(Bus bus, Message msg) {
            if ((type.intValue() & msg.getType().intValue()) != 0) {
                callback.callback(bus, msg, null);
            }
        }
    }
   
    private final Map<Class<?>, Map<Object, MessageProxy>> getListenerMap() {
        if (signalListeners == null) {
            signalListeners = new ConcurrentHashMap<Class<?>, Map<Object, MessageProxy>>();
        }
        return signalListeners;
    }
   
   
    private Map<Class<?>, Map<Object, MessageProxy>> signalListeners;
    private List<MessageProxy> messageProxies = new CopyOnWriteArrayList<MessageProxy>();
}
TOP

Related Classes of org.gstreamer.Bus$SEGMENT_START

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.