Package org.gstreamer.elements

Source Code of org.gstreamer.elements.CustomSink$CustomSinkInfo

/*
* Copyright (c) 2009 Levente Farkas
* Copyright (c) 2007 Wayne Meissner
*
* 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.elements;

import static org.gstreamer.lowlevel.GObjectAPI.GOBJECT_API;

import java.io.IOException;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Logger;

import org.gstreamer.Buffer;
import org.gstreamer.Caps;
import org.gstreamer.FlowReturn;
import org.gstreamer.PadDirection;
import org.gstreamer.PadTemplate;
import org.gstreamer.lowlevel.BaseSinkAPI;
import org.gstreamer.lowlevel.GType;
import org.gstreamer.lowlevel.GstPadTemplateAPI;
import org.gstreamer.lowlevel.GObjectAPI.GBaseInitFunc;
import org.gstreamer.lowlevel.GObjectAPI.GClassInitFunc;
import org.gstreamer.lowlevel.GObjectAPI.GTypeInfo;

import com.sun.jna.Pointer;

/**
*
* @author wayne
*/
abstract public class CustomSink extends BaseSink {
    private final static Logger logger = Logger.getLogger(CustomSink.class.getName());
    @SuppressWarnings("unused")
    private static class CustomSinkInfo {
        GType type;
        PadTemplate template;
        Caps caps;
       
        // Per-class callbacks used by gstreamer to initialize the subclass
        GClassInitFunc classInit;
        GBaseInitFunc baseInit;
       
        // Per-instance callback functions
        BaseSinkAPI.Render render;
        BaseSinkAPI.Render preroll;
        BaseSinkAPI.BooleanFunc1 start;
        BaseSinkAPI.BooleanFunc1 stop;
        BaseSinkAPI.GetCaps getCaps;
        BaseSinkAPI.SetCaps setCaps;
    }
    private static final Map<Class<? extends CustomSink>, CustomSinkInfo>  customSubclasses = new ConcurrentHashMap<Class<? extends CustomSink>, CustomSinkInfo>();
    protected CustomSink(Class<? extends CustomSink> subClass, String name) {
        super(initializer(GOBJECT_API.g_object_new(getSubclassType(subClass), "name", name)));
    }
    private static CustomSinkInfo getSubclassInfo(Class<? extends CustomSink> subClass) {
       synchronized (subClass) {
            CustomSinkInfo info = customSubclasses.get(subClass);
            if (info == null) {
                init(subClass);
                info = customSubclasses.get(subClass);
            }
            return info;
        }
    }
    private static GType getSubclassType(Class<? extends CustomSink> subClass) {
        return getSubclassInfo(subClass).type;
    }
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    private @interface SinkCallback {
    }
    @SinkCallback
    protected FlowReturn sinkRender(Buffer buffer) throws IOException {
        logger.info(getClass().getSimpleName() + ".sinkRender");
        return FlowReturn.WRONG_STATE;
    }
    @SinkCallback
    protected FlowReturn sinkPreRoll(Buffer buffer) throws IOException {
        logger.info(getClass().getSimpleName() + ".sinkPreRoll");
        return FlowReturn.WRONG_STATE;
    }
    @SinkCallback
    protected boolean sinkStart() {
        logger.info(getClass().getSimpleName() + ".sinkStart");
        return false;
    }
   
    @SinkCallback
    protected boolean sinkStop() {
        logger.info(getClass().getSimpleName() + ".sinkStop");
        return false;
    }
    @SinkCallback
    protected Caps sinkGetCaps() {
        logger.info(getClass().getSimpleName() + ".sinkGetCaps");
        return null;
    }
   
    @SinkCallback
    protected boolean sinkSetCaps(Caps caps) {
        logger.info(getClass().getSimpleName() + ".sinkSetCaps");
        return false;
    }
    private static class BooleanFunc1 implements BaseSinkAPI.BooleanFunc1 {
        private Method method;
        public BooleanFunc1(String methodName) {
            try {
                method = CustomSink.class.getDeclaredMethod(methodName, new Class[0]);
            } catch (Exception ex) {
                throw new RuntimeException(ex);
            }
        }
        public boolean callback(BaseSink element) {
            try {
                return ((Boolean) method.invoke(element)).booleanValue();
            } catch (Throwable ex) {
                return false;
            }
        }
       
    }
    private static final BooleanFunc1 startCallback = new BooleanFunc1("sinkStart");
    private static final BooleanFunc1 stopCallback = new BooleanFunc1("sinkStop");
    private static final BaseSinkAPI.Render renderCallback = new BaseSinkAPI.Render() {
       
        public FlowReturn callback(BaseSink sink, Buffer buffer) {
            try {
                return ((CustomSink) sink).sinkRender(buffer);
            } catch (Throwable ex) {
                ex.printStackTrace();
                return FlowReturn.ERROR;
            }
        }
    };
    private static final BaseSinkAPI.Render prerollCallback = new BaseSinkAPI.Render() {
       
        public FlowReturn callback(BaseSink sink, Buffer buffer) {
            try {
                return ((CustomSink) sink).sinkPreRoll(buffer);
            } catch (Throwable ex) {
                return FlowReturn.ERROR;
            }
        }
    };
    private static final BaseSinkAPI.GetCaps getCapsCallback = new BaseSinkAPI.GetCaps() {

        public Caps callback(BaseSink element) {
            try {
                return ((CustomSink) element).sinkGetCaps();
            } catch (Throwable ex) {
                return null;
            }
        }
    };
    private static final BaseSinkAPI.SetCaps setCapsCallback = new BaseSinkAPI.SetCaps() {

        public boolean callback(BaseSink element, Caps caps) {
            try {
                return ((CustomSink) element).sinkSetCaps(caps);
            } catch (Throwable ex) {
                return false;
            }
        }
    };
    private static void init(Class<? extends CustomSink> sinkClass) {
        final CustomSinkInfo info = new CustomSinkInfo();
        customSubclasses.put(sinkClass, info);
       
        //
        // Trawl through all the methods in the subclass, looking for ones that
        // over-ride the ones in CustomSink
        //
        for (Method m : CustomSink.class.getDeclaredMethods()) {
            SinkCallback cb = m.getAnnotation(SinkCallback.class);
            if (cb == null) {
                continue;
            }
            try {
                Method sinkMethod = sinkClass.getDeclaredMethod(m.getName(), m.getParameterTypes());
                if (sinkMethod.equals(m)) {
                    // Skip it if it is the same as the method in CustomSink
                    continue;
                }
                String name = m.getName().toLowerCase().substring("sink".length());
                if (name.equals("render")) {
                    info.render = renderCallback;
                } else if (name.equals("preroll")) {
                    info.preroll = prerollCallback;
                } else if (name.equals("start")) {
                    info.start = startCallback;
                } else if (name.equals("stop")) {
                    info.stop = stopCallback;
                } else if (name.equals("getcaps")) {
                    info.getCaps = getCapsCallback;
                } else if (name.equals("setcaps")) {
                    info.setCaps = setCapsCallback;
                }
            } catch (NoSuchMethodException ex) {
//            } catch (NoSuchFieldException ex) {
//            } catch (IllegalAccessException ex) {               
            }
           
           
        }
        info.classInit = new GClassInitFunc() {
            public void callback(Pointer g_class, Pointer class_data) {
                BaseSinkAPI.GstBaseSinkClass base = new BaseSinkAPI.GstBaseSinkClass(g_class);
                base.render = info.render;
                base.preroll = info.preroll;
                base.start = info.start;
                base.stop = info.stop;
                base.write();           
            }
        };
        info.baseInit = new GBaseInitFunc() {

            public void callback(Pointer g_class) {
                info.caps = Caps.anyCaps();
                info.template = new PadTemplate("sink", PadDirection.SINK, info.caps);
                GstPadTemplateAPI.GSTPADTEMPLATE_API.gst_element_class_add_pad_template(g_class, info.template);
            }
        };
       
        //
        // gstreamer boilerplate to hook the plugin in
        //
        GTypeInfo ginfo = new GTypeInfo();
        ginfo.class_init = info.classInit;
        ginfo.base_init = info.baseInit;
        ginfo.instance_init = null;
        ginfo.class_size = (short)new BaseSinkAPI.GstBaseSinkClass().size();
        ginfo.instance_size = (short)new BaseSinkAPI.GstBaseSinkStruct().size();
       
        info.type = GOBJECT_API.g_type_register_static(BaseSinkAPI.BASESINK_API.gst_base_sink_get_type(),
                sinkClass.getSimpleName(), ginfo, 0);
    }
}
TOP

Related Classes of org.gstreamer.elements.CustomSink$CustomSinkInfo

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.