<commit_before>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
    (Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2008 Renato Araujo Oliveira Filho <renatox@gmail.com>
Copyright (c) 2000-2014 Torus Knot Software Ltd

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/

#include "OgreException.h"
#include "OgreLogManager.h"
#include "OgreStringConverter.h"
#include "OgreRoot.h"

#include "OgreRenderSystem.h"

#include "OgreEGLSupport.h"
#include "OgreEGLWindow.h"
#if OGRE_PLATFORM != OGRE_PLATFORM_EMSCRIPTEN
#include "OgreEGLRenderTexture.h"
#endif

#ifndef EGL_VERSION_1_5
#define EGL_CONTEXT_MAJOR_VERSION EGL_CONTEXT_CLIENT_VERSION
#define EGL_CONTEXT_MINOR_VERSION EGL_NONE
#endif

#include <EGL/eglext.h>

namespace Ogre {

    EGLSupport::EGLSupport(int profile)
        : GLNativeSupport(profile), mGLDisplay(0),
          mNativeDisplay(EGL_DEFAULT_DISPLAY), hasEGL15(false)
    {
    }

    EGLDisplay EGLSupport::getGLDisplay(void)
    {
#ifdef EGL_VERSION_1_5
        static auto eglQueryDevicesEXT = (PFNEGLQUERYDEVICESEXTPROC)eglGetProcAddress("eglQueryDevicesEXT");
        static auto eglQueryDeviceStringEXT =
            (PFNEGLQUERYDEVICESTRINGEXTPROC)eglGetProcAddress("eglQueryDeviceStringEXT");

        if(eglQueryDevicesEXT && mNativeDisplay == EGL_DEFAULT_DISPLAY)
        {
            int numDevices;
            eglQueryDevicesEXT(0, NULL, &numDevices);
            EGL_CHECK_ERROR
            std::vector<EGLDeviceEXT> devices(numDevices);
            eglQueryDevicesEXT(numDevices, devices.data(), &numDevices);

            EGLAttrib attribs[] = {EGL_NONE};
            for(auto dev : devices)
            {
                EGLDisplay display = eglGetPlatformDisplay(EGL_PLATFORM_DEVICE_EXT, dev, attribs);
                EGL_CHECK_ERROR

                if(display != EGL_NO_DISPLAY && !mGLDisplay)
                {
                    mGLDisplay = display;
                    const char* exts = eglQueryDeviceStringEXT(dev, EGL_EXTENSIONS);
                    LogManager::getSingleton().stream() << "EGL: using default display. Device extensions: " << exts;
                    break;
                }
            }
        }
        else
#endif
        {
            mGLDisplay = eglGetDisplay(mNativeDisplay);
            EGL_CHECK_ERROR
        }

        if(mGLDisplay == EGL_NO_DISPLAY)
        {
            OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
                        "Couldn`t open EGLDisplay " + getDisplayName(),
                        "EGLSupport::getGLDisplay");
        }

        if (eglInitialize(mGLDisplay, &mEGLMajor, &mEGLMinor) == EGL_FALSE)
        {
            OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
                        "Couldn`t initialize EGLDisplay ",
                        "EGLSupport::getGLDisplay");
        }
        EGL_CHECK_ERROR

        return mGLDisplay;
    }

    String EGLSupport::getDisplayName(void)
    {
        return "todo";
    }

    EGLConfig* EGLSupport::chooseGLConfig(const EGLint *attribList, EGLint *nElements)
    {
        EGLConfig *configs;

        if (eglChooseConfig(mGLDisplay, attribList, NULL, 0, nElements) == EGL_FALSE)
        {
            OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to choose config");

            *nElements = 0;
            return 0;
        }
        EGL_CHECK_ERROR
        configs = (EGLConfig*) malloc(*nElements * sizeof(EGLConfig));
        if (eglChooseConfig(mGLDisplay, attribList, configs, *nElements, nElements) == EGL_FALSE)
        {
            OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to choose config");

            *nElements = 0;
            free(configs);
            return 0;
        }
        EGL_CHECK_ERROR
        return configs;
    }

    EGLConfig* EGLSupport::getConfigs(EGLint *nElements)
    {
        EGLConfig *configs;

        if (eglGetConfigs(mGLDisplay, NULL, 0, nElements) == EGL_FALSE)
        {
            OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to choose config");

            *nElements = 0;
            return 0;
        }
        EGL_CHECK_ERROR
        configs = (EGLConfig*) malloc(*nElements * sizeof(EGLConfig));
        if (eglGetConfigs(mGLDisplay, configs, *nElements, nElements) == EGL_FALSE)
        {
            OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to choose config");

            *nElements = 0;
            free(configs);
            return 0;
        }
        EGL_CHECK_ERROR
        return configs;
    }

    EGLBoolean EGLSupport::getGLConfigAttrib(EGLConfig glConfig, EGLint attribute, EGLint *value)
    {
        EGLBoolean status;

        status = eglGetConfigAttrib(mGLDisplay, glConfig, attribute, value);
        EGL_CHECK_ERROR
        return status;
    }

    void* EGLSupport::getProcAddress(const char* name) const
    {
        return (void*)eglGetProcAddress(name);
    }

    ::EGLConfig EGLSupport::getGLConfigFromContext(::EGLContext context)
    {
        ::EGLConfig glConfig;
        EGLint id = 0;
        ::EGLConfig *configs;
        EGLint numConfigs;

        if (eglQueryContext(mGLDisplay, context, EGL_CONFIG_ID, &id) == EGL_FALSE)
        {
            OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Fail to get config from context");
            return 0;
        }
        EGL_CHECK_ERROR
        configs = getConfigs(&numConfigs);
        glConfig = configs[id];
        free(configs);
        return glConfig;
    }

    ::EGLConfig EGLSupport::getGLConfigFromDrawable(::EGLSurface drawable,
                                                    unsigned int *w, unsigned int *h)
    {
        ::EGLConfig glConfig;
        EGLint id = 0;
        ::EGLConfig *configs;
        EGLint numConfigs;

        if (eglQuerySurface(mGLDisplay, drawable, EGL_CONFIG_ID, &id) == EGL_FALSE)
        {
            OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Fail to get config from drawable");
            return 0;
        }
        EGL_CHECK_ERROR
        eglQuerySurface(mGLDisplay, drawable, EGL_WIDTH, (EGLint *) w);
        EGL_CHECK_ERROR
        eglQuerySurface(mGLDisplay, drawable, EGL_HEIGHT, (EGLint *) h);
        EGL_CHECK_ERROR
        configs = getConfigs(&numConfigs);
        glConfig = configs[id];
        free(configs);
        return glConfig;
    }

    //------------------------------------------------------------------------
    // A helper class for the implementation of selectFBConfig
    //------------------------------------------------------------------------
    class GLConfigAttribs
    {
        public:
            GLConfigAttribs(const int* attribs)
            {
                fields[EGL_CONFIG_CAVEAT] = EGL_NONE;

                for (int i = 0; attribs[2*i] != EGL_NONE; i++)
                {
                    fields[attribs[2*i]] = attribs[2*i+1];
                }
            }

            void load(EGLSupport* const glSupport, EGLConfig glConfig)
            {
                std::map<int,int>::iterator it;

                for (it = fields.begin(); it != fields.end(); it++)
                {
                    it->second = EGL_NONE;

                    glSupport->getGLConfigAttrib(glConfig, it->first, &it->second);
                }
            }

            bool operator>(GLConfigAttribs& alternative)
            {
                // Caveats are best avoided, but might be needed for anti-aliasing
                if (fields[EGL_CONFIG_CAVEAT] != alternative.fields[EGL_CONFIG_CAVEAT])
                {
                    if (fields[EGL_CONFIG_CAVEAT] == EGL_SLOW_CONFIG)
                    {
                        return false;
                    }

                    if (fields.find(EGL_SAMPLES) != fields.end() &&
                        fields[EGL_SAMPLES] < alternative.fields[EGL_SAMPLES])
                    {
                        return false;
                    }
                }

                std::map<int,int>::iterator it;

                for (it = fields.begin(); it != fields.end(); it++)
                {
                    if (it->first != EGL_CONFIG_CAVEAT &&
                        fields[it->first] > alternative.fields[it->first])
                    {
                        return true;
                    }
                }

                return false;
            }

            std::map<int,int> fields;
    };

    ::EGLConfig EGLSupport::selectGLConfig(const int* minAttribs, const int *maxAttribs)
    {
        EGLConfig *glConfigs;
        EGLConfig glConfig = 0;
        int config, nConfigs = 0;

        glConfigs = chooseGLConfig(minAttribs, &nConfigs);

        if (!nConfigs)
        {
            glConfigs = getConfigs(&nConfigs);
        }

        if (!nConfigs)
        {
            return 0;
        }

        glConfig = glConfigs[0];

        if (maxAttribs)
        {
            GLConfigAttribs maximum(maxAttribs);
            GLConfigAttribs best(maxAttribs);
            GLConfigAttribs candidate(maxAttribs);

            best.load(this, glConfig);

            for (config = 1; config < nConfigs; config++)
            {
                candidate.load(this, glConfigs[config]);

                if (candidate > maximum)
                {
                    continue;
                }

                if (candidate > best)
                {
                    glConfig = glConfigs[config];

                    best.load(this, glConfig);
                }
            }
        }

        free(glConfigs);
        return glConfig;
    }

    void EGLSupport::switchMode(void)
    {
        return switchMode(mOriginalMode.width,
                          mOriginalMode.height, mOriginalMode.refreshRate);
    }

    ::EGLContext EGLSupport::createNewContext(EGLDisplay eglDisplay,
                          ::EGLConfig glconfig,
                                              ::EGLContext shareList) const
    {
        EGLint contextAttrs[] = {
            EGL_CONTEXT_MAJOR_VERSION, 3,
            EGL_CONTEXT_MINOR_VERSION, 2,
            EGL_NONE, EGL_NONE,
            EGL_NONE
        };

        if(mContextProfile != CONTEXT_ES) {
            if (!eglBindAPI(EGL_OPENGL_API))
            {
                OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Could not bind GL API");
            }
            EGL_CHECK_ERROR
            contextAttrs[1] = 4;
            contextAttrs[3] = 6;

#ifdef EGL_VERSION_1_5
            contextAttrs[4] = EGL_CONTEXT_OPENGL_PROFILE_MASK;
            contextAttrs[5] = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT;
            if(mContextProfile == CONTEXT_COMPATIBILITY)
            {
                contextAttrs[1] = 3; // MESA 20.2.6 always gives us core if we request 4.x
                contextAttrs[3] = 0;
                contextAttrs[5] = EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT;
            }
#endif
        }

        if(!hasEGL15)
        {
            contextAttrs[2] = EGL_NONE; // skips following attributes
            contextAttrs[3] = 0;
        }

        ::EGLContext context = (::EGLContext)0;

        // find maximal supported context version
        while(!context && (contextAttrs[1] >= 1))
        {
            context = eglCreateContext(eglDisplay, glconfig, shareList, contextAttrs);
            EGL_CHECK_ERROR
            contextAttrs[1] -= contextAttrs[3] == 0; // only decrement if minor == 0

            if(hasEGL15)
                contextAttrs[3] = (contextAttrs[3] - 1 + 7) % 7; // decrement: -1 -> 6
        }

        if (!context)
        {
            OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to create EGL context");
            return 0;
        }

        return context;
    }

    void EGLSupport::start()
    {
        LogManager::getSingleton().logMessage(
            "******************************\n"
            "*** Starting EGL Subsystem ***\n"
            "******************************");
        initialiseExtensions();
    }

    void EGLSupport::stop()
    {
        eglTerminate(mGLDisplay);
        EGL_CHECK_ERROR
    }

    void EGLSupport::initialiseExtensions() {
        assert (mGLDisplay);

        const char* propStr = eglQueryString(mGLDisplay, EGL_VENDOR);
        LogManager::getSingleton().stream() << "EGL_VENDOR = " << propStr;

        propStr = eglQueryString(mGLDisplay, EGL_VERSION);
        LogManager::getSingleton().stream() << "EGL_VERSION = " << propStr;

        hasEGL15 = String(propStr).find("1.5") != String::npos;

        StringStream ext;

        // client extensions
        propStr = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
        if(propStr) // NULL = failure case
            ext << propStr << " ";

        // display extension
        propStr = eglQueryString(mGLDisplay, EGL_EXTENSIONS);
        ext << propStr;

        LogManager::getSingleton().stream() << "EGL_EXTENSIONS = " << ext.str();

        String instr;
        while(ext >> instr)
        {
            extensionList.insert(instr);
        }
    }

    void EGLSupport::setGLDisplay( EGLDisplay val )
    {
        mGLDisplay = val;
    }

    GLPBuffer* EGLSupport::createPBuffer( PixelComponentType format, size_t width, size_t height )
    {
#if OGRE_PLATFORM == OGRE_PLATFORM_EMSCRIPTEN
        return nullptr;
#else
        return new EGLPBuffer(this, format, width, height);
#endif
    }
}
<commit_msg>GLSupport: fix compilation with Android NDK 20+<commit_after>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
    (Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2008 Renato Araujo Oliveira Filho <renatox@gmail.com>
Copyright (c) 2000-2014 Torus Knot Software Ltd

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/

#include "OgreException.h"
#include "OgreLogManager.h"
#include "OgreStringConverter.h"
#include "OgreRoot.h"

#include "OgreRenderSystem.h"

#include "OgreEGLSupport.h"
#include "OgreEGLWindow.h"
#if OGRE_PLATFORM != OGRE_PLATFORM_EMSCRIPTEN
#include "OgreEGLRenderTexture.h"
#endif

#ifndef EGL_VERSION_1_5
#define EGL_CONTEXT_MAJOR_VERSION EGL_CONTEXT_CLIENT_VERSION
#define EGL_CONTEXT_MINOR_VERSION EGL_NONE
#endif

#include <EGL/eglext.h>

namespace Ogre {

    EGLSupport::EGLSupport(int profile)
        : GLNativeSupport(profile), mGLDisplay(0),
          mNativeDisplay(EGL_DEFAULT_DISPLAY), hasEGL15(false)
    {
    }

    EGLDisplay EGLSupport::getGLDisplay(void)
    {
#if defined(EGL_VERSION_1_5) && OGRE_PLATFORM != OGRE_PLATFORM_ANDROID
        static auto eglQueryDevicesEXT = (PFNEGLQUERYDEVICESEXTPROC)eglGetProcAddress("eglQueryDevicesEXT");
        static auto eglQueryDeviceStringEXT =
            (PFNEGLQUERYDEVICESTRINGEXTPROC)eglGetProcAddress("eglQueryDeviceStringEXT");

        if(eglQueryDevicesEXT && mNativeDisplay == EGL_DEFAULT_DISPLAY)
        {
            int numDevices;
            eglQueryDevicesEXT(0, NULL, &numDevices);
            EGL_CHECK_ERROR
            std::vector<EGLDeviceEXT> devices(numDevices);
            eglQueryDevicesEXT(numDevices, devices.data(), &numDevices);

            EGLAttrib attribs[] = {EGL_NONE};
            for(auto dev : devices)
            {
                EGLDisplay display = eglGetPlatformDisplay(EGL_PLATFORM_DEVICE_EXT, dev, attribs);
                EGL_CHECK_ERROR

                if(display != EGL_NO_DISPLAY && !mGLDisplay)
                {
                    mGLDisplay = display;
                    const char* exts = eglQueryDeviceStringEXT(dev, EGL_EXTENSIONS);
                    LogManager::getSingleton().stream() << "EGL: using default display. Device extensions: " << exts;
                    break;
                }
            }
        }
        else
#endif
        {
            mGLDisplay = eglGetDisplay(mNativeDisplay);
            EGL_CHECK_ERROR
        }

        if(mGLDisplay == EGL_NO_DISPLAY)
        {
            OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
                        "Couldn`t open EGLDisplay " + getDisplayName(),
                        "EGLSupport::getGLDisplay");
        }

        if (eglInitialize(mGLDisplay, &mEGLMajor, &mEGLMinor) == EGL_FALSE)
        {
            OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
                        "Couldn`t initialize EGLDisplay ",
                        "EGLSupport::getGLDisplay");
        }
        EGL_CHECK_ERROR

        return mGLDisplay;
    }

    String EGLSupport::getDisplayName(void)
    {
        return "todo";
    }

    EGLConfig* EGLSupport::chooseGLConfig(const EGLint *attribList, EGLint *nElements)
    {
        EGLConfig *configs;

        if (eglChooseConfig(mGLDisplay, attribList, NULL, 0, nElements) == EGL_FALSE)
        {
            OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to choose config");

            *nElements = 0;
            return 0;
        }
        EGL_CHECK_ERROR
        configs = (EGLConfig*) malloc(*nElements * sizeof(EGLConfig));
        if (eglChooseConfig(mGLDisplay, attribList, configs, *nElements, nElements) == EGL_FALSE)
        {
            OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to choose config");

            *nElements = 0;
            free(configs);
            return 0;
        }
        EGL_CHECK_ERROR
        return configs;
    }

    EGLConfig* EGLSupport::getConfigs(EGLint *nElements)
    {
        EGLConfig *configs;

        if (eglGetConfigs(mGLDisplay, NULL, 0, nElements) == EGL_FALSE)
        {
            OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to choose config");

            *nElements = 0;
            return 0;
        }
        EGL_CHECK_ERROR
        configs = (EGLConfig*) malloc(*nElements * sizeof(EGLConfig));
        if (eglGetConfigs(mGLDisplay, configs, *nElements, nElements) == EGL_FALSE)
        {
            OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to choose config");

            *nElements = 0;
            free(configs);
            return 0;
        }
        EGL_CHECK_ERROR
        return configs;
    }

    EGLBoolean EGLSupport::getGLConfigAttrib(EGLConfig glConfig, EGLint attribute, EGLint *value)
    {
        EGLBoolean status;

        status = eglGetConfigAttrib(mGLDisplay, glConfig, attribute, value);
        EGL_CHECK_ERROR
        return status;
    }

    void* EGLSupport::getProcAddress(const char* name) const
    {
        return (void*)eglGetProcAddress(name);
    }

    ::EGLConfig EGLSupport::getGLConfigFromContext(::EGLContext context)
    {
        ::EGLConfig glConfig;
        EGLint id = 0;
        ::EGLConfig *configs;
        EGLint numConfigs;

        if (eglQueryContext(mGLDisplay, context, EGL_CONFIG_ID, &id) == EGL_FALSE)
        {
            OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Fail to get config from context");
            return 0;
        }
        EGL_CHECK_ERROR
        configs = getConfigs(&numConfigs);
        glConfig = configs[id];
        free(configs);
        return glConfig;
    }

    ::EGLConfig EGLSupport::getGLConfigFromDrawable(::EGLSurface drawable,
                                                    unsigned int *w, unsigned int *h)
    {
        ::EGLConfig glConfig;
        EGLint id = 0;
        ::EGLConfig *configs;
        EGLint numConfigs;

        if (eglQuerySurface(mGLDisplay, drawable, EGL_CONFIG_ID, &id) == EGL_FALSE)
        {
            OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Fail to get config from drawable");
            return 0;
        }
        EGL_CHECK_ERROR
        eglQuerySurface(mGLDisplay, drawable, EGL_WIDTH, (EGLint *) w);
        EGL_CHECK_ERROR
        eglQuerySurface(mGLDisplay, drawable, EGL_HEIGHT, (EGLint *) h);
        EGL_CHECK_ERROR
        configs = getConfigs(&numConfigs);
        glConfig = configs[id];
        free(configs);
        return glConfig;
    }

    //------------------------------------------------------------------------
    // A helper class for the implementation of selectFBConfig
    //------------------------------------------------------------------------
    class GLConfigAttribs
    {
        public:
            GLConfigAttribs(const int* attribs)
            {
                fields[EGL_CONFIG_CAVEAT] = EGL_NONE;

                for (int i = 0; attribs[2*i] != EGL_NONE; i++)
                {
                    fields[attribs[2*i]] = attribs[2*i+1];
                }
            }

            void load(EGLSupport* const glSupport, EGLConfig glConfig)
            {
                std::map<int,int>::iterator it;

                for (it = fields.begin(); it != fields.end(); it++)
                {
                    it->second = EGL_NONE;

                    glSupport->getGLConfigAttrib(glConfig, it->first, &it->second);
                }
            }

            bool operator>(GLConfigAttribs& alternative)
            {
                // Caveats are best avoided, but might be needed for anti-aliasing
                if (fields[EGL_CONFIG_CAVEAT] != alternative.fields[EGL_CONFIG_CAVEAT])
                {
                    if (fields[EGL_CONFIG_CAVEAT] == EGL_SLOW_CONFIG)
                    {
                        return false;
                    }

                    if (fields.find(EGL_SAMPLES) != fields.end() &&
                        fields[EGL_SAMPLES] < alternative.fields[EGL_SAMPLES])
                    {
                        return false;
                    }
                }

                std::map<int,int>::iterator it;

                for (it = fields.begin(); it != fields.end(); it++)
                {
                    if (it->first != EGL_CONFIG_CAVEAT &&
                        fields[it->first] > alternative.fields[it->first])
                    {
                        return true;
                    }
                }

                return false;
            }

            std::map<int,int> fields;
    };

    ::EGLConfig EGLSupport::selectGLConfig(const int* minAttribs, const int *maxAttribs)
    {
        EGLConfig *glConfigs;
        EGLConfig glConfig = 0;
        int config, nConfigs = 0;

        glConfigs = chooseGLConfig(minAttribs, &nConfigs);

        if (!nConfigs)
        {
            glConfigs = getConfigs(&nConfigs);
        }

        if (!nConfigs)
        {
            return 0;
        }

        glConfig = glConfigs[0];

        if (maxAttribs)
        {
            GLConfigAttribs maximum(maxAttribs);
            GLConfigAttribs best(maxAttribs);
            GLConfigAttribs candidate(maxAttribs);

            best.load(this, glConfig);

            for (config = 1; config < nConfigs; config++)
            {
                candidate.load(this, glConfigs[config]);

                if (candidate > maximum)
                {
                    continue;
                }

                if (candidate > best)
                {
                    glConfig = glConfigs[config];

                    best.load(this, glConfig);
                }
            }
        }

        free(glConfigs);
        return glConfig;
    }

    void EGLSupport::switchMode(void)
    {
        return switchMode(mOriginalMode.width,
                          mOriginalMode.height, mOriginalMode.refreshRate);
    }

    ::EGLContext EGLSupport::createNewContext(EGLDisplay eglDisplay,
                          ::EGLConfig glconfig,
                                              ::EGLContext shareList) const
    {
        EGLint contextAttrs[] = {
            EGL_CONTEXT_MAJOR_VERSION, 3,
            EGL_CONTEXT_MINOR_VERSION, 2,
            EGL_NONE, EGL_NONE,
            EGL_NONE
        };

        if(mContextProfile != CONTEXT_ES) {
            if (!eglBindAPI(EGL_OPENGL_API))
            {
                OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Could not bind GL API");
            }
            EGL_CHECK_ERROR
            contextAttrs[1] = 4;
            contextAttrs[3] = 6;

#ifdef EGL_VERSION_1_5
            contextAttrs[4] = EGL_CONTEXT_OPENGL_PROFILE_MASK;
            contextAttrs[5] = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT;
            if(mContextProfile == CONTEXT_COMPATIBILITY)
            {
                contextAttrs[1] = 3; // MESA 20.2.6 always gives us core if we request 4.x
                contextAttrs[3] = 0;
                contextAttrs[5] = EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT;
            }
#endif
        }

        if(!hasEGL15)
        {
            contextAttrs[2] = EGL_NONE; // skips following attributes
            contextAttrs[3] = 0;
        }

        ::EGLContext context = (::EGLContext)0;

        // find maximal supported context version
        while(!context && (contextAttrs[1] >= 1))
        {
            context = eglCreateContext(eglDisplay, glconfig, shareList, contextAttrs);
            EGL_CHECK_ERROR
            contextAttrs[1] -= contextAttrs[3] == 0; // only decrement if minor == 0

            if(hasEGL15)
                contextAttrs[3] = (contextAttrs[3] - 1 + 7) % 7; // decrement: -1 -> 6
        }

        if (!context)
        {
            OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to create EGL context");
            return 0;
        }

        return context;
    }

    void EGLSupport::start()
    {
        LogManager::getSingleton().logMessage(
            "******************************\n"
            "*** Starting EGL Subsystem ***\n"
            "******************************");
        initialiseExtensions();
    }

    void EGLSupport::stop()
    {
        eglTerminate(mGLDisplay);
        EGL_CHECK_ERROR
    }

    void EGLSupport::initialiseExtensions() {
        assert (mGLDisplay);

        const char* propStr = eglQueryString(mGLDisplay, EGL_VENDOR);
        LogManager::getSingleton().stream() << "EGL_VENDOR = " << propStr;

        propStr = eglQueryString(mGLDisplay, EGL_VERSION);
        LogManager::getSingleton().stream() << "EGL_VERSION = " << propStr;

        hasEGL15 = String(propStr).find("1.5") != String::npos;

        StringStream ext;

        // client extensions
        propStr = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
        if(propStr) // NULL = failure case
            ext << propStr << " ";

        // display extension
        propStr = eglQueryString(mGLDisplay, EGL_EXTENSIONS);
        ext << propStr;

        LogManager::getSingleton().stream() << "EGL_EXTENSIONS = " << ext.str();

        String instr;
        while(ext >> instr)
        {
            extensionList.insert(instr);
        }
    }

    void EGLSupport::setGLDisplay( EGLDisplay val )
    {
        mGLDisplay = val;
    }

    GLPBuffer* EGLSupport::createPBuffer( PixelComponentType format, size_t width, size_t height )
    {
#if OGRE_PLATFORM == OGRE_PLATFORM_EMSCRIPTEN
        return nullptr;
#else
        return new EGLPBuffer(this, format, width, height);
#endif
    }
}
<|endoftext|>


<commit_before>/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2011. All Rights Reserved.							  */
/* Open Source Software - may be modified and shared by FRC teams. The code   */
/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib.  */
/*----------------------------------------------------------------------------*/

#include "Commands/PIDCommand.h"

#include "PIDController.h"
#include "float.h"

PIDCommand::PIDCommand(const char *name, double p, double i, double d, double f, double period) :
		Command(name)
{
	m_controller = new PIDController(p, i, d, this, this, period);
}

PIDCommand::PIDCommand(double p, double i, double d, double f, double period)
{
	m_controller = new PIDController(p, i, d, f, this, this, period);
}

PIDCommand::PIDCommand(const char *name, double p, double i, double d) :
	Command(name)
{
	m_controller = new PIDController(p, i, d, this, this);
}

PIDCommand::PIDCommand(const char *name, double p, double i, double d, double period) :
	Command(name)
{
	m_controller = new PIDController(p, i, d, this, this, period);
}

PIDCommand::PIDCommand(double p, double i, double d)
{
	m_controller = new PIDController(p, i, d, this, this);
}

PIDCommand::PIDCommand(double p, double i, double d, double period)
{
	m_controller = new PIDController(p, i, d, this, this, period);
}

PIDCommand::~PIDCommand()
{
	delete m_controller;
}

void PIDCommand::_Initialize()
{
	m_controller->Enable();
}

void PIDCommand::_End()
{
	m_controller->Disable();
}

void PIDCommand::_Interrupted()
{
	_End();
}

void PIDCommand::SetSetpointRelative(double deltaSetpoint)
{
	SetSetpoint(GetSetpoint() + deltaSetpoint);
}

void PIDCommand::PIDWrite(float output)
{
	UsePIDOutput(output);
}

double PIDCommand::PIDGet()
{
	return ReturnPIDInput();
}

PIDController *PIDCommand::GetPIDController()
{
	return m_controller;
}

void PIDCommand::SetSetpoint(double setpoint)
{
	m_controller->SetSetpoint(setpoint);
}

double PIDCommand::GetSetpoint()
{
	return m_controller->GetSetpoint();
}

double PIDCommand::GetPosition()
{
	return ReturnPIDInput();
}

std::string PIDCommand::GetSmartDashboardType(){
        return "PIDCommand";
}
void PIDCommand::InitTable(ITable* table){
	m_controller->InitTable(table);
	Command::InitTable(table);
}
<commit_msg>Forwarded the f argument in a ctor (accidentally unused - alex)<commit_after>/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2011. All Rights Reserved.							  */
/* Open Source Software - may be modified and shared by FRC teams. The code   */
/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib.  */
/*----------------------------------------------------------------------------*/

#include "Commands/PIDCommand.h"

#include "PIDController.h"
#include "float.h"

PIDCommand::PIDCommand(const char *name, double p, double i, double d, double f, double period) :
		Command(name)
{
	m_controller = new PIDController(p, i, d, f, this, this, period);
}

PIDCommand::PIDCommand(double p, double i, double d, double f, double period)
{
	m_controller = new PIDController(p, i, d, f, this, this, period);
}

PIDCommand::PIDCommand(const char *name, double p, double i, double d) :
	Command(name)
{
	m_controller = new PIDController(p, i, d, this, this);
}

PIDCommand::PIDCommand(const char *name, double p, double i, double d, double period) :
	Command(name)
{
	m_controller = new PIDController(p, i, d, this, this, period);
}

PIDCommand::PIDCommand(double p, double i, double d)
{
	m_controller = new PIDController(p, i, d, this, this);
}

PIDCommand::PIDCommand(double p, double i, double d, double period)
{
	m_controller = new PIDController(p, i, d, this, this, period);
}

PIDCommand::~PIDCommand()
{
	delete m_controller;
}

void PIDCommand::_Initialize()
{
	m_controller->Enable();
}

void PIDCommand::_End()
{
	m_controller->Disable();
}

void PIDCommand::_Interrupted()
{
	_End();
}

void PIDCommand::SetSetpointRelative(double deltaSetpoint)
{
	SetSetpoint(GetSetpoint() + deltaSetpoint);
}

void PIDCommand::PIDWrite(float output)
{
	UsePIDOutput(output);
}

double PIDCommand::PIDGet()
{
	return ReturnPIDInput();
}

PIDController *PIDCommand::GetPIDController()
{
	return m_controller;
}

void PIDCommand::SetSetpoint(double setpoint)
{
	m_controller->SetSetpoint(setpoint);
}

double PIDCommand::GetSetpoint()
{
	return m_controller->GetSetpoint();
}

double PIDCommand::GetPosition()
{
	return ReturnPIDInput();
}

std::string PIDCommand::GetSmartDashboardType(){
        return "PIDCommand";
}
void PIDCommand::InitTable(ITable* table){
	m_controller->InitTable(table);
	Command::InitTable(table);
}
<|endoftext|>


<commit_before>// This file is distributed under the MIT license.
// See the LICENSE file for details.

#include <array>

#include <visionaray/math/vector.h>
#include <visionaray/generic_material.h>
#include <visionaray/material.h>

using namespace visionaray;

int main()
{

#if defined GENMAT_PACK_FLOAT4

    std::array<generic_material<matte<float>,emissive<float>,mirror<float>>, 4> gm_array;
    simd::generic_material4<matte<float>,emissive<float>,mirror<float>> gm = simd::pack(gm_array);

#elif defined GENMAT_PACK_FLOAT8

#if VSNRAY_SIMD_ISA >= VSNRAY_SIMD_ISA_AVX
    std::array<generic_material<matte<float>,emissive<float>,mirror<float>>, 8> gm_array;
    simd::generic_material8<matte<float>,emissive<float>,mirror<float>> gm = simd::pack(gm_array);
#endif

#elif defined GENMAT_PACK_ILLEGAL_LENGTH_1

    std::array<generic_material<matte<float>,emissive<float>,mirror<float>>, 1> gm_array;
    auto gm = simd::pack(gm_array);

#elif defined GENMAT_PACK_ILLEGAL_LENGTH_3

    std::array<generic_material<matte<float>,emissive<float>,mirror<float>>, 3> gm_array;
    auto gm = simd::pack(gm_array);

#elif defined GENMAT_PACK_ILLEGAL_INTEGRAL

    std::array<generic_material<float>, 4> gm_array;
    auto gm = simd::pack(gm_array);

#elif defined GENMAT_UNPACK_FLOAT4

    simd::generic_material4<matte<float>,emissive<float>,mirror<float>> gm({});
    std::array<generic_material<matte<float>,emissive<float>,mirror<float>>, 4> gm_array = simd::unpack(gm);

#elif defined GENMAT_UNPACK_FLOAT8

#if VSNRAY_SIMD_ISA >= VSNRAY_SIMD_ISA_AVX
    simd::generic_material8<matte<float>,emissive<float>,mirror<float>> gm({});
    std::array<generic_material<matte<float>,emissive<float>,mirror<float>>, 8> gm_array = simd::unpack(gm);
#endif

#elif defined GENMAT_UNPACK_ILLEGAL_LENGTH

    simd::generic_material4<matte<float>,emissive<float>,mirror<float>> gm({});
    std::array<generic_material<matte<float>,emissive<float>,mirror<float>>, 8> gm_array = simd::unpack(gm);

#elif defined GENMAT_UNPACK_ILLEGAL_INTEGRAL

    simd::generic_material4<float> gm({});
    auto gm_array = simd::unpack(gm);

#elif defined GENMAT_UNPACK_SINGLE

    generic_material<matte<float>,emissive<float>,mirror<float>> gm({});
    auto gm_array = simd::unpack(gm);

#endif

    return 0;
}
<commit_msg>Adapt tests to recent changes<commit_after>// This file is distributed under the MIT license.
// See the LICENSE file for details.

#include <array>

#include <visionaray/math/vector.h>
#include <visionaray/generic_material.h>
#include <visionaray/material.h>

using namespace visionaray;

int main()
{

#if defined GENMAT_PACK_FLOAT4

    std::array<generic_material<matte<float>,emissive<float>,mirror<float>>, 4> gm_array;
    simd::generic_material<4, matte<float>,emissive<float>,mirror<float>> gm = simd::pack(gm_array);

#elif defined GENMAT_PACK_FLOAT8

#if VSNRAY_SIMD_ISA >= VSNRAY_SIMD_ISA_AVX
    std::array<generic_material<matte<float>,emissive<float>,mirror<float>>, 8> gm_array;
    simd::generic_material<8, matte<float>,emissive<float>,mirror<float>> gm = simd::pack(gm_array);
#endif

#elif defined GENMAT_PACK_ILLEGAL_LENGTH_1

    std::array<generic_material<matte<float>,emissive<float>,mirror<float>>, 1> gm_array;
    auto gm = simd::pack(gm_array);

#elif defined GENMAT_PACK_ILLEGAL_LENGTH_3

    std::array<generic_material<matte<float>,emissive<float>,mirror<float>>, 3> gm_array;
    auto gm = simd::pack(gm_array);

#elif defined GENMAT_PACK_ILLEGAL_INTEGRAL

    std::array<generic_material<float>, 4> gm_array;
    auto gm = simd::pack(gm_array);

#elif defined GENMAT_UNPACK_FLOAT4

    simd::generic_material<4, matte<float>,emissive<float>,mirror<float>> gm({});
    std::array<generic_material<matte<float>,emissive<float>,mirror<float>>, 4> gm_array = simd::unpack(gm);

#elif defined GENMAT_UNPACK_FLOAT8

#if VSNRAY_SIMD_ISA >= VSNRAY_SIMD_ISA_AVX
    simd::generic_material<8, matte<float>,emissive<float>,mirror<float>> gm({});
    std::array<generic_material<matte<float>,emissive<float>,mirror<float>>, 8> gm_array = simd::unpack(gm);
#endif

#elif defined GENMAT_UNPACK_ILLEGAL_LENGTH

    simd::generic_material<4, matte<float>,emissive<float>,mirror<float>> gm({});
    std::array<generic_material<matte<float>,emissive<float>,mirror<float>>, 8> gm_array = simd::unpack(gm);

#elif defined GENMAT_UNPACK_ILLEGAL_INTEGRAL

    simd::generic_material<4, float> gm({});
    auto gm_array = simd::unpack(gm);

#elif defined GENMAT_UNPACK_SINGLE

    generic_material<matte<float>,emissive<float>,mirror<float>> gm({});
    auto gm_array = simd::unpack(gm);

#endif

    return 0;
}
<|endoftext|>


<commit_before>// ComplexCi.cpp : ̨Ӧóڵ㡣
//

//#include "stdafx.h"

#include <iostream>
#include <vector>
#include <set>
#include <fstream>
#include <string>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <sstream>
#include <iterator>
#include <queue>
#include <algorithm>

using namespace std;

template<typename Out>
void split(const std::string &s, char delim, Out result) {
	std::stringstream ss;
	ss.str(s);
	std::string item;
	while (std::getline(ss, item, delim)) {
		*(result++) = item;
	}
}

std::vector<std::string> split(const std::string &s, char delim) {
	std::vector<std::string> elems;
	split(s, delim, std::back_inserter(elems));
	return elems;
}

void getNeighbourFrontierAndScope(const unordered_map<int, vector<int> > &adjListGraph, int scope, int currentNode, unordered_set<int> &currentSet, unordered_set<int>& alreadyAccess)
{
	currentSet.insert(currentNode);
	alreadyAccess.insert(currentNode);

	for (int i = 0; i < scope; i++)
	{
		unordered_set<int> nextSet;
		for (const auto& node : currentSet)
		{
			const vector<int>& neighbourNodeList = adjListGraph.at(node);

			for (const auto& eachNeighbour : neighbourNodeList)
			{
				if (alreadyAccess.find(eachNeighbour) == alreadyAccess.end())
				{
					nextSet.insert(eachNeighbour);
					alreadyAccess.insert(eachNeighbour);
				}
			}

		}

		currentSet = nextSet;
	}
}

long long basicCi(const unordered_map<int, vector<int> > &adjListGraph, int ballRadius, int currentNode)
{
	if (adjListGraph.at(currentNode).size() == 0)
	{
		return -1;
	}

	unordered_set<int> currentFrontier;
	unordered_set<int> dummyValue;

	getNeighbourFrontierAndScope(adjListGraph, ballRadius, currentNode, currentFrontier, dummyValue);

	long long ci = 0;

	for (auto node : currentFrontier)
	{
		ci += (adjListGraph.at(node).size() - 1);
	}

	ci *= (adjListGraph.at(currentNode).size() - 1);

	return ci;
}

void deleteNode(unordered_map<int, vector<int> > &adjListGraph, int node)
{
	if (adjListGraph[node].size() == 0)
	{
		return;
	}

	for (auto neighbour: adjListGraph[node])
	{
		adjListGraph[neighbour].erase(remove(adjListGraph[neighbour].begin(), adjListGraph[neighbour].end(), node), adjListGraph[neighbour].end());
	}

	adjListGraph[node].clear();

}

int main(int argc, char* argv[])
{
	unsigned int ballRadius = 1;
	unsigned int updateBatch = 1;
	unsigned int outputNumBatch = 1;

	string path = "";
	string output = "";

	if (argc > 4)
	{
		path = argv[1];
		output = path + "_out";

		ballRadius = stoi(argv[2]);
		updateBatch = stoi(argv[3]);
		outputNumBatch = stoi(argv[4]);

	}
	else
	{
		cout << "at least 3 parameters for csv path" <<endl;
		cout << "e.g. 'C:/Users/zhfkt/Documents/Visual Studio 2013/Projects/ComplexCi/Release/karate.txt' 2 500 500" <<endl;
		return 0;
	}

	string modelID = "";

	{
		vector<string> fileName = split(path, '/');
		modelID = split(fileName[fileName.size() - 1], '.')[0];
	}

	std::cout << "path: " << path << endl;
	std::cout << "output: " << output << endl;
	std::cout << "modelID: " << modelID << endl;

	std::cout << "ballRadius: " << ballRadius << endl;
	std::cout << "updateBatch: " << updateBatch << endl;
	std::cout << "outputNumBatch: " << outputNumBatch << endl;

	unordered_map<int, vector<int> > adjListGraph;
	unordered_set<int> allVex;

	ifstream is(path);
	string eachLine;
	while (is >> eachLine)
	{
		vector<string> csvEachLine = split(eachLine, ',');

		adjListGraph[stoi(csvEachLine[0])].push_back(stoi(csvEachLine[1]));
		adjListGraph[stoi(csvEachLine[1])].push_back(stoi(csvEachLine[0]));

		allVex.insert(stoi(csvEachLine[0]));
		allVex.insert(stoi(csvEachLine[1]));

	}

	is.close();

	int totalSize = adjListGraph.size();

	//--------------

	set<pair<long long, int> > allPQ; //ci/currentNode --- long is 32 bit on the win and long long is 64 bit / and long long can be multiple
	unordered_map<int, long long> revereseLoopUpAllPQ;
	cout << "modelID: " << modelID << " First Cal CI" << endl;

	for (const auto& i : adjListGraph)
	{
		int currentNode = i.first;
		// core_ci
		long long ci = basicCi(adjListGraph, ballRadius, currentNode);

		allPQ.insert(make_pair(ci, currentNode));
		revereseLoopUpAllPQ[currentNode] = ci;
	}

	vector<int> finalOutput;
	int loopCount = 0;
	while (true)
	{
		cout << "modelID: " << modelID << " loopCount: " << loopCount << " totalSize: " << totalSize << " maxCi: " << allPQ.rbegin()->first << " node: " << allPQ.rbegin()->second << endl;
		loopCount += updateBatch;

		vector<int> batchList;
		unsigned int batchLimiti = 0;
		for (auto rit = allPQ.rbegin(); (rit != allPQ.rend()) || batchLimiti < updateBatch; rit++, batchLimiti++)
		{
			batchList.push_back(rit->second);
			finalOutput.push_back(rit->second);
			allVex.erase(rit->second);  //remove key

			if (rit ->first <= 0)
			{
				// ci algorithm ends
				goto CIEND;
			}
		}

		unordered_set<int> candidateUpdateNodes;
		for (int i : batchList)
		{
			unordered_set<int> allScopeInBallRadiusPlusOne;
			unordered_set<int> dummyValue;
			getNeighbourFrontierAndScope(adjListGraph, ballRadius + 1, i, dummyValue, allScopeInBallRadiusPlusOne);
			candidateUpdateNodes.insert(allScopeInBallRadiusPlusOne.begin(), allScopeInBallRadiusPlusOne.end());
		}

		for (int i : batchList)
		{
			deleteNode(adjListGraph, i);
			//candidateUpdateNodesWithCi.insert(make_pair(i, -1));// no need to because self will be included in the candidateUpdateNodes and updated in the below
		}

		for (int i : candidateUpdateNodes)
		{
			long long updatedCi = basicCi(adjListGraph, ballRadius + 1, i);

			long long olderCi = revereseLoopUpAllPQ[i];

			allPQ.erase(make_pair(olderCi, i));
			allPQ.insert(make_pair(updatedCi, i));

			revereseLoopUpAllPQ[i] = updatedCi;
		}

	}

CIEND:

	//add left random

	cout << "leftVex:" <<endl;
	for (auto leftVex : allVex)
	{
		finalOutput.push_back(leftVex);
		cout << " " << leftVex ;
	}

	while (true)
	{
		if (finalOutput.size() % outputNumBatch == 0)
		{
			break;
		}
		else
		{
			finalOutput.push_back(-1);
		}
	}

	//--------------

	ofstream os(output);

	string output500 = "";
	for (unsigned int i = 0; i < finalOutput.size(); i++)
	{
		if (i % outputNumBatch == 0)
		{
			output500 = modelID;
		}

		if (finalOutput[i] != -1)
		{
			output500 += (',' + std::to_string(finalOutput[i]));
		}
		else
		{
			output500 += ',';
		}

		if (i % outputNumBatch == (outputNumBatch - 1) || i == (finalOutput.size() - 1))
		{
			os << output500 << endl;
			std::cout << "output500: " << output500 << endl;
			output500.clear();
		}

	}

	os.close();

	system("pause");
	return 0;
}

<commit_msg>Improve and output and fix mainly bug<commit_after>// ComplexCi.cpp : ̨Ӧóڵ㡣
//

//#include "stdafx.h"

#include <iostream>
#include <vector>
#include <set>
#include <fstream>
#include <string>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <sstream>
#include <iterator>
#include <queue>
#include <algorithm>

using namespace std;

template<typename Out>
void split(const std::string &s, char delim, Out result) {
	std::stringstream ss;
	ss.str(s);
	std::string item;
	while (std::getline(ss, item, delim)) {
		*(result++) = item;
	}
}

std::vector<std::string> split(const std::string &s, char delim) {
	std::vector<std::string> elems;
	split(s, delim, std::back_inserter(elems));
	return elems;
}

void getNeighbourFrontierAndScope(const unordered_map<int, vector<int> > &adjListGraph, int scope, int currentNode, unordered_set<int> &currentSet, unordered_set<int>& alreadyAccess)
{
	currentSet.insert(currentNode);
	alreadyAccess.insert(currentNode);

	for (int i = 0; i < scope; i++)
	{
		unordered_set<int> nextSet;
		for (const auto& node : currentSet)
		{
			const vector<int>& neighbourNodeList = adjListGraph.at(node);

			for (const auto& eachNeighbour : neighbourNodeList)
			{
				if (alreadyAccess.find(eachNeighbour) == alreadyAccess.end())
				{
					nextSet.insert(eachNeighbour);
					alreadyAccess.insert(eachNeighbour);
				}
			}

		}

		currentSet = nextSet;
	}
}

long long basicCi(const unordered_map<int, vector<int> > &adjListGraph, int ballRadius, int currentNode)
{
	if (adjListGraph.at(currentNode).size() == 0)
	{
		return -1;
	}

	unordered_set<int> currentFrontier;
	unordered_set<int> dummyValue;

	getNeighbourFrontierAndScope(adjListGraph, ballRadius, currentNode, currentFrontier, dummyValue);

	long long ci = 0;

	for (auto node : currentFrontier)
	{
		ci += (adjListGraph.at(node).size() - 1);
	}

	ci *= (adjListGraph.at(currentNode).size() - 1);

	return ci;
}

void deleteNode(unordered_map<int, vector<int> > &adjListGraph, int node)
{
	if (adjListGraph[node].size() == 0)
	{
		return;
	}

	for (auto neighbour: adjListGraph[node])
	{
		adjListGraph[neighbour].erase(remove(adjListGraph[neighbour].begin(), adjListGraph[neighbour].end(), node), adjListGraph[neighbour].end());
	}

	adjListGraph[node].clear();

}

int main(int argc, char* argv[])
{
	unsigned int ballRadius = 1;
	unsigned int updateBatch = 1;
	unsigned int outputNumBatch = 1;

	string path = "";
	string output = "";

	if (argc > 4)
	{
		path = argv[1];
		output = path + "_out";

		ballRadius = stoi(argv[2]);
		updateBatch = stoi(argv[3]);
		outputNumBatch = stoi(argv[4]);

	}
	else
	{
		cout << "at least 3 parameters for csv path" <<endl;
		cout << "e.g. 'C:/Users/zhfkt/Documents/Visual Studio 2013/Projects/ComplexCi/Release/karate.txt' 2 500 500" <<endl;
		return 0;
	}

	string modelID = "";

	{
		vector<string> fileName = split(path, '/');
		modelID = split(fileName[fileName.size() - 1], '.')[0];
	}

	std::cout << "path: " << path << endl;
	std::cout << "output: " << output << endl;
	std::cout << "modelID: " << modelID << endl;

	std::cout << "ballRadius: " << ballRadius << endl;
	std::cout << "updateBatch: " << updateBatch << endl;
	std::cout << "outputNumBatch: " << outputNumBatch << endl;

	unordered_map<int, vector<int> > adjListGraph;
	unordered_set<int> allVex;

	ifstream is(path);
	string eachLine;
	while (is >> eachLine)
	{
		vector<string> csvEachLine = split(eachLine, ',');

		adjListGraph[stoi(csvEachLine[0])].push_back(stoi(csvEachLine[1]));
		adjListGraph[stoi(csvEachLine[1])].push_back(stoi(csvEachLine[0]));

		allVex.insert(stoi(csvEachLine[0]));
		allVex.insert(stoi(csvEachLine[1]));

	}

	is.close();

	int totalSize = adjListGraph.size();

	//--------------

	set<pair<long long, int> > allPQ; //ci/currentNode --- long is 32 bit on the win and long long is 64 bit / and long long can be multiple
	unordered_map<int, long long> revereseLoopUpAllPQ;
	cout << "modelID: " << modelID << " First Cal CI" << endl;

	for (const auto& i : adjListGraph)
	{
		int currentNode = i.first;
		// core_ci
		long long ci = basicCi(adjListGraph, ballRadius, currentNode);

		allPQ.insert(make_pair(ci, currentNode));
		revereseLoopUpAllPQ[currentNode] = ci;
	}

	vector<int> finalOutput;
	int loopCount = 0;
	while (true)
	{
		cout << "modelID: " << modelID << " loopCount: " << loopCount << " totalSize: " << totalSize << " maxCi: " << allPQ.rbegin()->first << " node: " << allPQ.rbegin()->second << endl;
		loopCount += updateBatch;

		vector<int> batchList;
		unsigned int batchLimiti = 0;
		for (auto rit = allPQ.rbegin(); batchLimiti < updateBatch && (rit != allPQ.rend()); rit++, batchLimiti++)
		{
			batchList.push_back(rit->second);
			finalOutput.push_back(rit->second);
			allVex.erase(rit->second);  //remove key

			if (rit ->first <= 0)
			{
				// ci algorithm ends
				goto CIEND;
			}
		}

		//cout << "monitor 1" << endl;

		int debugCount = 0;

		unordered_set<int> candidateUpdateNodes;
		for (int i : batchList)
		{
			unordered_set<int> allScopeInBallRadiusPlusOne;
			unordered_set<int> dummyValue;
			getNeighbourFrontierAndScope(adjListGraph, ballRadius + 1, i, dummyValue, allScopeInBallRadiusPlusOne);
			candidateUpdateNodes.insert(allScopeInBallRadiusPlusOne.begin(), allScopeInBallRadiusPlusOne.end());

			//cout << "monitor 1_2: " << debugCount++ << " " << batchList.size() << " " << candidateUpdateNodes.size() << endl;

		}

		//cout << "monitor 2" << endl;

		for (int i : batchList)
		{
			deleteNode(adjListGraph, i);
			//candidateUpdateNodesWithCi.insert(make_pair(i, -1));// no need to because self will be included in the candidateUpdateNodes and updated in the below
		}

		//cout << "monitor 3" << endl;
		debugCount = 0;

		for (int i : candidateUpdateNodes)
		{
			long long updatedCi = basicCi(adjListGraph, ballRadius, i);

			long long olderCi = revereseLoopUpAllPQ[i];

			allPQ.erase(make_pair(olderCi, i));
			allPQ.insert(make_pair(updatedCi, i));

			revereseLoopUpAllPQ[i] = updatedCi;

			//cout << "monitor 3_4: " << debugCount++ << " " << candidateUpdateNodes.size() << endl;
		}
		//cout << "monitor 4" << endl;

	}

CIEND:

	//add left random

	cout << "Before Random adding the left CI==0 equals zero: " << finalOutput.size() << endl;
	for (auto leftVex : allVex)
	{
		finalOutput.push_back(leftVex);
	}
	cout << "After Random adding the left CI equals zero: " << finalOutput.size() << endl;

	while (true)
	{
		if (finalOutput.size() % outputNumBatch == 0)
		{
			break;
		}
		else
		{
			finalOutput.push_back(-1);
		}
	}

	//--------------

	std::cout << "Outputing Start.." << endl;

	ofstream os(output);

	string output500 = "";
	for (unsigned int i = 0; i < finalOutput.size(); i++)
	{
		if (i % outputNumBatch == 0)
		{
			output500 = modelID;
		}

		if (finalOutput[i] != -1)
		{
			output500 += (',' + std::to_string(finalOutput[i]));
		}
		else
		{
			output500 += ',';
		}

		if (i % outputNumBatch == (outputNumBatch - 1) || i == (finalOutput.size() - 1))
		{
			os << output500 << endl;
			//std::cout << "output500: " << output500 << endl;
			output500.clear();
		}

	}

	os.close();

	std::cout << "Outputing End.." << endl;

	system("pause");
	return 0;
}

<|endoftext|>


<commit_before>#undef DEBUG
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cmath>

//needed for select
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

//needed for poll
#include <poll.h>

//for connection to server
#include "../sockets/SocketW.h"
bool ready4data = false;//set to true when streaming starts
bool inited = false;
bool stopparsing = false;
timeval lastrec;

#include "parsechunks.cpp" //chunkstream parsing
#include "handshake.cpp" //handshaking
#include "../util/flv_sock.cpp" //FLV parsing with SocketW

int main(){
  unsigned int ts;
  unsigned int fts = 0;
  unsigned int ftst;
  SWUnixSocket ss;
  //fd_set pollset;
  //struct timeval timeout;
  //0 timeout - return immediately after select call
  //timeout.tv_sec = 1; timeout.tv_usec = 0;
  //FD_ZERO(&pollset);//clear the polling set
  //FD_SET(0, &pollset);//add stdin to polling set

  pollfd cinfd[1];
  cinfd[0].fd = fileno(stdin);
  cinfd[0].events = POLLIN;

  //first timestamp set
  firsttime = getNowMS();

  #ifdef DEBUG
  fprintf(stderr, "Doing handshake...\n");
  #endif
  if (doHandshake()){
    #ifdef DEBUG
    fprintf(stderr, "Handshake succcess!\n");
    #endif
  }else{
    #ifdef DEBUG
    fprintf(stderr, "Handshake fail!\n");
    #endif
    return 0;
  }
  #ifdef DEBUG
  fprintf(stderr, "Starting processing...\n");
  #endif
  while (std::cin.good() && std::cout.good()){
    //select(1, &pollset, 0, 0, &timeout);
    //only parse input from stdin if available or not yet init'ed
    //FD_ISSET(0, &pollset) || //NOTE: Polling does not work? WHY?!? WHY DAMN IT?!?
    //if ((!ready4data || (snd_cnt - snd_window_at >= snd_window_size)) && !stopparsing){fflush(stdout);parseChunk();fflush(stdout);}
    if ((!ready4data || (snd_cnt - snd_window_at >= snd_window_size)) && poll(cinfd, 1, 100)){parseChunk();fflush(stdout);}
    if (ready4data){
      if (!inited){
        //we are ready, connect the socket!
        if (!ss.connect(streamname.c_str())){
          #ifdef DEBUG
          fprintf(stderr, "Could not connect to server!\n");
          #endif
          return 0;
        }
        FLV_Readheader(ss);//read the header, we don't want it
        #ifdef DEBUG
        fprintf(stderr, "Header read, starting to send video data...\n");
        #endif
        inited = true;
      }
      //only send data if previous data has been ACK'ed...
      if (snd_cnt - snd_window_at < snd_window_size){
        if (FLV_GetPacket(ss)){//able to read a full packet?
          ts = FLVbuffer[7] * 256*256*256;
          ts += FLVbuffer[4] * 256*256;
          ts += FLVbuffer[5] * 256;
          ts += FLVbuffer[6];
          if (ts != 0){
            if (fts == 0){fts = ts;ftst = getNowMS();}
            ts -= fts;
            FLVbuffer[7] = ts / (256*256*256);
            FLVbuffer[4] = ts / (256*256);
            FLVbuffer[5] = ts / 256;
            FLVbuffer[6] = ts % 256;
            ts += ftst;
          }else{
            ftst = getNowMS();
            FLVbuffer[7] = ftst / (256*256*256);
            FLVbuffer[4] = ftst / (256*256);
            FLVbuffer[5] = ftst / 256;
            FLVbuffer[6] = ftst % 256;
          }
          SendMedia((unsigned char)FLVbuffer[0], (unsigned char *)FLVbuffer+11, FLV_len-15, ts);
          FLV_Dump();//dump packet and get ready for next
        }
        if ((SWBerr != SWBaseSocket::ok) && (SWBerr != SWBaseSocket::notReady)){
          #ifdef DEBUG
          fprintf(stderr, "No more data! :-(  (%s)\n", SWBerr.get_error().c_str());
          #endif
          return 0;//no more input possible! Fail immediately.
        }
      }
    }
    //send ACK if we received a whole window
    if (rec_cnt - rec_window_at > rec_window_size){
      rec_window_at = rec_cnt;
      SendCTL(3, rec_cnt);//send ack (msg 3)
    }
  }
  #ifdef DEBUG
  fprintf(stderr, "User disconnected.\n");
  #endif
  return 0;
}//main
<commit_msg>Select poging nummer 1<commit_after>#undef DEBUG
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cmath>

//needed for select
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

//needed for poll
//#include <poll.h>

//for connection to server
#include "../sockets/SocketW.h"
bool ready4data = false;//set to true when streaming starts
bool inited = false;
bool stopparsing = false;
timeval lastrec;

#include "parsechunks.cpp" //chunkstream parsing
#include "handshake.cpp" //handshaking
#include "../util/flv_sock.cpp" //FLV parsing with SocketW

int main(){
  unsigned int ts;
  unsigned int fts = 0;
  unsigned int ftst;
  SWUnixSocket ss;

  fd_set pollset;
  struct timeval timeout;
  //0 timeout - return immediately after select call
  timeout.tv_sec = 1; timeout.tv_usec = 0;

  //pollfd cinfd[1];
  //cinfd[0].fd = fileno(stdin);
  //cinfd[0].events = POLLIN;

  //first timestamp set
  firsttime = getNowMS();

  #ifdef DEBUG
  fprintf(stderr, "Doing handshake...\n");
  #endif
  if (doHandshake()){
    #ifdef DEBUG
    fprintf(stderr, "Handshake succcess!\n");
    #endif
  }else{
    #ifdef DEBUG
    fprintf(stderr, "Handshake fail!\n");
    #endif
    return 0;
  }
  #ifdef DEBUG
  fprintf(stderr, "Starting processing...\n");
  #endif
  while (std::cin.good() && std::cout.good()){
    FD_ZERO(&pollset);//clear the polling set
    FD_SET(fileno(stdin), &pollset);//add stdin to polling set
    select(1, &pollset, 0, 0, &timeout);
    //only parse input from stdin if available or not yet init'ed
    if ((!ready4data || (snd_cnt - snd_window_at >= snd_window_size)) && FD_ISSET(0, &pollset)){parseChunk();fflush(stdout);}
    if (ready4data){
      if (!inited){
        //we are ready, connect the socket!
        if (!ss.connect(streamname.c_str())){
          #ifdef DEBUG
          fprintf(stderr, "Could not connect to server!\n");
          #endif
          return 0;
        }
        FLV_Readheader(ss);//read the header, we don't want it
        #ifdef DEBUG
        fprintf(stderr, "Header read, starting to send video data...\n");
        #endif
        inited = true;
      }
      //only send data if previous data has been ACK'ed...
      if (snd_cnt - snd_window_at < snd_window_size){
        if (FLV_GetPacket(ss)){//able to read a full packet?
          ts = FLVbuffer[7] * 256*256*256;
          ts += FLVbuffer[4] * 256*256;
          ts += FLVbuffer[5] * 256;
          ts += FLVbuffer[6];
          if (ts != 0){
            if (fts == 0){fts = ts;ftst = getNowMS();}
            ts -= fts;
            FLVbuffer[7] = ts / (256*256*256);
            FLVbuffer[4] = ts / (256*256);
            FLVbuffer[5] = ts / 256;
            FLVbuffer[6] = ts % 256;
            ts += ftst;
          }else{
            ftst = getNowMS();
            FLVbuffer[7] = ftst / (256*256*256);
            FLVbuffer[4] = ftst / (256*256);
            FLVbuffer[5] = ftst / 256;
            FLVbuffer[6] = ftst % 256;
          }
          SendMedia((unsigned char)FLVbuffer[0], (unsigned char *)FLVbuffer+11, FLV_len-15, ts);
          FLV_Dump();//dump packet and get ready for next
        }
        if ((SWBerr != SWBaseSocket::ok) && (SWBerr != SWBaseSocket::notReady)){
          #ifdef DEBUG
          fprintf(stderr, "No more data! :-(  (%s)\n", SWBerr.get_error().c_str());
          #endif
          return 0;//no more input possible! Fail immediately.
        }
      }
    }
    //send ACK if we received a whole window
    if (rec_cnt - rec_window_at > rec_window_size){
      rec_window_at = rec_cnt;
      SendCTL(3, rec_cnt);//send ack (msg 3)
    }
  }
  #ifdef DEBUG
  fprintf(stderr, "User disconnected.\n");
  #endif
  return 0;
}//main
<|endoftext|>


<commit_before>/// \file Connector_RTSP/main.cpp
/// Contains the main code for the RTSP Connector

#include <queue>
#include <cmath>
#include <ctime>
#include <cstdio>
#include <string>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <getopt.h>
#include <iostream>
#include <sys/time.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/epoll.h>
#include "../util/socket.h"
#include "../util/flv_tag.h"
#include "../util/http_parser.h"
//JRTPLIB
#include "rtp.h"

std::string ReadNALU( ) {
  static char Separator[3] = { (char)0x00, (char)0x00, (char)0x01 };
  std::string Buffer;
  std::string Result;
  do {
    Buffer += std::cin.get();
  } while ( std::cin.good() && ( Buffer.find( Separator,0,3 ) == std::string::npos ) );
  if( !std::cin.good() ) { return ""; }
  Result = Buffer.substr(0, Buffer.find( Separator,0,3 ) );
  while( *(Result.end() - 1) == (char)0x00 ) { Result.erase( Result.end() - 1 ); }
  if( Result.size() == 0 ) { Result = ReadNALU( ); }
  return Result;
}

/// The main function of the connector
/// \param conn A connection with the client
int RTSP_Handler( Socket::Connection conn ) {
  bool ready4data = false;
  FLV::Tag tag;///< Temporary tag buffer for incoming video data.
  bool PlayVideo = false;
  bool PlayAudio = true;
  bool InitVideo = false;
  bool InitAudio = true;
  bool VideoMeta = false;
  int RTPClientPort;
  int RTCPClientPort;
  bool inited;
  jrtplib::RTPSession VideoSession;
  jrtplib::RTPSessionParams VideoParams;
  jrtplib::RTPUDPv4TransmissionParams VideoTransParams;
  std::string PreviousRequest = "";
  Socket::Connection ss(-1);
  HTTP::Parser HTTP_R, HTTP_S;
  bool PerRequest = false;
  while(conn.connected() && !FLV::Parse_Error) {
    if( HTTP_R.Read(conn ) ) {
      fprintf( stderr, "REQUEST:\n%s\n", HTTP_R.BuildRequest().c_str() );
      if( HTTP_R.GetHeader( "User-Agent" ).find( "RealMedia Player Version" ) != std::string::npos) {
        PerRequest = true;
      }
      HTTP_S.protocol = "RTSP/1.0";
      if( HTTP_R.method == "OPTIONS" ) {
        HTTP_S.SetHeader( "CSeq", HTTP_R.GetHeader( "CSeq" ).c_str() );
        HTTP_S.SetHeader( "Public", "DESCRIBE, SETUP, TEARDOWN, PLAY" );
        HTTP_S.SetBody( "\r\n\r\n" );
        fprintf( stderr, "RESPONSE:\n%s\n", HTTP_S.BuildResponse( "200", "OK" ).c_str() );
        conn.write( HTTP_S.BuildResponse( "200", "OK" ) );
      } else if ( HTTP_R.method == "DESCRIBE" ) {
        if( HTTP_R.GetHeader( "Accept" ).find( "application/sdp" ) == std::string::npos ) {
          fprintf( stderr, "RESPONSE:\n%s\n", HTTP_S.BuildResponse( "501", "Not Implemented" ).c_str() );
          conn.write( HTTP_S.BuildResponse( "501", "Not Implemented" ) );
        } else {
          HTTP_S.SetHeader( "CSeq", HTTP_R.GetHeader( "CSeq" ).c_str() );
          HTTP_S.SetHeader( "Content-Type", "application/sdp" );
          HTTP_S.SetBody( "v=0\r\no=- 0 0 IN IP4 ddvtech.com\r\ns=Fifa Test\r\nc=IN IP4 127.0.0.1\r\nt=0 0\r\na=recvonly\r\nm=video 0 RTP/AVP 98\r\na=rtpmap:98 H264/700000\r\n\r\n" );//a=fmtp:98 packetization-mode=1\r\n\r\n" );
          fprintf( stderr, "RESPONSE:\n%s\n", HTTP_S.BuildResponse( "200", "OK" ).c_str() );
          conn.write( HTTP_S.BuildResponse( "200", "OK" ) );
        }
      } else if ( HTTP_R.method == "SETUP" ) {
        std::string temp = HTTP_R.GetHeader("Transport");
        int ClientRTPLoc = temp.find( "client_port=" ) + 12;
        int PortSpacer = temp.find( "-", ClientRTPLoc );
        int PortEnd = ( temp.find( ";", PortSpacer ) );
        RTPClientPort = atoi( temp.substr( ClientRTPLoc, ( PortSpacer - ClientRTPLoc ) ).c_str() );
        RTCPClientPort = atoi( temp.substr( PortSpacer + 1 , ( PortEnd - ( PortSpacer + 1 ) ) ).c_str() );
        if( HTTP_S.GetHeader( "Session" ) != "" ) {
          fprintf( stderr, "RESPONSE:\n%s\n", HTTP_S.BuildResponse( "459", "Aggregate Operation Not Allowed" ).c_str() );
          conn.write( HTTP_S.BuildResponse( "459", "Aggregate Operation Not Allowed" ) );
        } else {
          HTTP_S.SetHeader( "CSeq", HTTP_R.GetHeader( "CSeq" ).c_str() );
          HTTP_S.SetHeader( "Session", time(NULL) );
          HTTP_S.SetHeader( "Transport", HTTP_R.GetHeader( "Transport" ) + ";server_port=50000-50001" );
          HTTP_S.SetBody( "\r\n\r\n" );
          fprintf( stderr, "RESPONSE:\n%s\n", HTTP_S.BuildResponse( "200", "OK" ).c_str() );
          conn.write( HTTP_S.BuildResponse( "200", "OK" ) );
        }
      } else if( HTTP_R.method == "PLAY" ) {
        if( HTTP_R.GetHeader( "Range" ).substr(0,4) != "npt=" ) {
          fprintf( stderr, "RESPONSE:\n%s\n", HTTP_S.BuildResponse( "501", "Not Implemented" ).c_str() );
          conn.write( HTTP_S.BuildResponse( "501", "Not Implemented" ) );
        } else {
          HTTP_S.SetHeader( "CSeq", HTTP_R.GetHeader( "CSeq" ).c_str() );
          HTTP_S.SetHeader( "Session", HTTP_R.GetHeader( "Session" ) );
          HTTP_S.SetHeader( "Range", HTTP_R.GetHeader( "Range" ) );
          HTTP_S.SetHeader( "RTP-Info", "url=" + HTTP_R.url + ";seq=0;rtptime=0" );
          HTTP_S.SetBody( "\r\n\r\n" );
          fprintf( stderr, "RESPONSE:\n%s\n", HTTP_S.BuildResponse( "200", "OK" ).c_str() );
          conn.write( HTTP_S.BuildResponse( "200", "OK" ) );
          PlayVideo = true;
        }
      } else if( HTTP_R.method == "TEARDOWN" ) {
          HTTP_S.SetHeader( "CSeq", HTTP_R.GetHeader( "CSeq" ).c_str() );
          HTTP_S.SetBody( "\r\n\r\n" );
          fprintf( stderr, "RESPONSE:\n%s\n", HTTP_S.BuildResponse( "200", "OK" ).c_str() );
          conn.write( HTTP_S.BuildResponse( "200", "OK" ) );
          PlayVideo = false;
      } else {
        fprintf( stderr, "RESPONSE:\n%s\n", HTTP_S.BuildResponse( "501", "Not Implemented" ).c_str() );
        conn.write( HTTP_S.BuildResponse( "501", "Not Implemented" ) );
      }
      HTTP_R.Clean();
      HTTP_S.Clean();
      if( PerRequest ) {
        conn.close();
      }
/*      if( ( PlayVideo ) && !inited ) {
        ss = Socket::Connection("/tmp/shared_socket_fifa");
        if (!ss.connected()){
          #if DEBUG >= 1
          fprintf(stderr, "Could not connect to server!\n");
          #endif
          conn.close();
          break;
        }
        #if DEBUG >= 3
        fprintf(stderr, "Everything connected, starting to send video data...\n");
        #endif
        inited = true;
      }*/
    }
    if( PlayVideo ) {
      if( !InitVideo ) {
        VideoParams.SetOwnTimestampUnit( 1.0/90000.0 );
        VideoParams.SetMaximumPacketSize( 10000 );
        VideoTransParams.SetPortbase( 50000 );
        int VideoStatus = VideoSession.Create( VideoParams, &VideoTransParams );
        if( VideoStatus < 0 ) {
          std::cerr << jrtplib::RTPGetErrorString( VideoStatus ) << std::endl;
          exit( -1 );
        } else {
          std::cerr << "Created video session\n";
        }
        uint8_t localip[]={127,0,0,1};
        jrtplib::RTPIPv4Address addr(localip,RTPClientPort);

        VideoStatus = VideoSession.AddDestination(addr);
        if (VideoStatus < 0) {
          std::cerr << jrtplib::RTPGetErrorString(VideoStatus) << std::endl;
          exit(-1);
        } else {
          std::cerr << "Destination Set\n";
        }
        VideoSession.SetDefaultPayloadType(98);
        VideoSession.SetDefaultMark(false);
        VideoSession.SetDefaultTimestampIncrement(0);
        InitVideo = true;
      }
//      std::cerr << "Retrieving NALU from stdin\n";
      std::string VideoBuf = ReadNALU( );
      if( VideoBuf == "" ) {
        jrtplib::RTPTime delay = jrtplib::RTPTime(10.0);
        VideoSession.BYEDestroy(delay,"Out of data",11);
        conn.close();
      } else {
//        std::cerr << "NALU Retrieved:\n";
//        std::cerr << "\t" << (int)VideoBuf[0] << " " << (int)VideoBuf[2]
//        << " " << (int)VideoBuf[3] << " " << (int)VideoBuf[4] << "\n";
        VideoSession.SendPacket( VideoBuf.c_str(), VideoBuf.size(), 98, false, ( 700000.0 / VideoBuf.size() ) );
      }
    }
/*
    switch (ss.ready()){
      case -1:
        conn.close();
        #if DEBUG >= 1
        fprintf(stderr, "Source socket is disconnected.\n");
        #endif
        break;
      case 0: break;//not ready yet
      default:
        if (tag.SockLoader(ss)){//able to read a full packet?
          if( tag.data[ 0 ] == 0x09 ) {
            if( ( ( tag.data[ 11 ] & 0x0F ) == 7 ) ) { //&& ( tag.data[ 12 ] == 1 ) ) {
              fprintf(stderr, "Video contains NALU\n" );
            }
          }
          if( tag.data[ 0 ] == 0x08 ) {
            if( ( tag.data[ 11 ] == 0xAF ) && ( tag.data[ 12 ] == 0x01 ) ) {
              fprintf(stderr, "Audio Contains Raw AAC\n");
            }
          }
        }
        break;
    }*/
  }
  return 0;
}

#define DEFAULT_PORT 554
#define MAINHANDLER RTSP_Handler
#define CONFIGSECT RTSP
#include "../util/server_setup.cpp"
<commit_msg>RTSP: Blokkerig beeld, hapert veel, maar iig hebben we bewegend beeld<commit_after>/// \file Connector_RTSP/main.cpp
/// Contains the main code for the RTSP Connector

#include <queue>
#include <cmath>
#include <ctime>
#include <cstdio>
#include <string>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <getopt.h>
#include <iostream>
#include <sys/time.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/epoll.h>
#include "../util/socket.h"
#include "../util/flv_tag.h"
#include "../util/http_parser.h"
//JRTPLIB
#include "rtp.h"

/// Reads a single NALU from std::cin. Expected is H.264 Bytestream format.
/// \return The Nalu data.
std::string ReadNALU( ) {
  static char Separator[3] = { (char)0x00, (char)0x00, (char)0x01 };
  std::string Buffer;
  std::string Result;
  do {
    Buffer += std::cin.get();
  } while ( std::cin.good() && ( Buffer.find( Separator,0,3 ) == std::string::npos ) );
  if( !std::cin.good() ) { return ""; }
  Result = Buffer.substr(0, Buffer.find( Separator,0,3 ) );
  while( *(Result.end() - 1) == (char)0x00 ) { Result.erase( Result.end() - 1 ); }
  if( Result.size() == 0 ) { Result = ReadNALU( ); }
  return Result;
}

/// The main function of the connector
/// \param conn A connection with the client
int RTSP_Handler( Socket::Connection conn ) {
  FLV::Tag tag;///< Temporary tag buffer for incoming video data.
  bool PlayVideo = false;
  bool PlayAudio = true;
  jrtplib::RTPSession VideoSession;
  jrtplib::RTPSessionParams VideoParams;
  jrtplib::RTPUDPv4TransmissionParams VideoTransParams;
  std::string PreviousRequest = "";
  Socket::Connection ss(-1);
  HTTP::Parser HTTP_R, HTTP_S;
  bool PerRequest = false;
  while(conn.connected() && !FLV::Parse_Error) {
    if( HTTP_R.Read(conn ) ) {
      fprintf( stderr, "REQUEST:\n%s\n", HTTP_R.BuildRequest().c_str() );
//      if( HTTP_R.GetHeader( "User-Agent" ).find( "RealMedia Player Version" ) != std::string::npos) {
//        PerRequest = true;
//      }
      HTTP_S.protocol = "RTSP/1.0";
      if( HTTP_R.method == "OPTIONS" ) {
        HTTP_S.SetHeader( "CSeq", HTTP_R.GetHeader( "CSeq" ).c_str() );
        HTTP_S.SetHeader( "Public", "OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY" );
        HTTP_S.SetBody( "\r\n\r\n" );
        fprintf( stderr, "RESPONSE:\n%s\n", HTTP_S.BuildResponse( "200", "OK" ).c_str() );
        conn.write( HTTP_S.BuildResponse( "200", "OK" ) );
      } else if ( HTTP_R.method == "DESCRIBE" ) {
        if( HTTP_R.GetHeader( "Accept" ).find( "application/sdp" ) == std::string::npos ) {
          fprintf( stderr, "RESPONSE:\n%s\n", HTTP_S.BuildResponse( "501", "Not Implemented" ).c_str() );
          conn.write( HTTP_S.BuildResponse( "501", "Not Implemented" ) );
        } else {
          HTTP_S.SetHeader( "CSeq", HTTP_R.GetHeader( "CSeq" ).c_str() );
          HTTP_S.SetHeader( "Content-Type", "application/sdp" );
          /// \todo Retrieve presence of video and audio data, and process into response
          /// \todo Retrieve Packetization mode ( is 1 for now ). Where can I retrieve this?
          HTTP_S.SetBody( "v=0\r\no=- 0 0 IN IP4 ddvtech.com\r\ns=Fifa Test\r\nc=IN IP4 127.0.0.1\r\nt=0 0\r\na=recvonly\r\nm=video 0 RTP/AVP 98\r\na=control:rtsp://localhost/fifa/video\r\na=rtpmap:98 H264/90000\r\na=fmtp:98 packetization-mode=1\r\nm=audio 0 RTP/AVP 96\r\na=control:rtsp://localhost/fifa/audio\r\na=rtpmap:96 mpeg4-generic/16000/2\r\n\r\n");
          fprintf( stderr, "RESPONSE:\n%s\n", HTTP_S.BuildResponse( "200", "OK" ).c_str() );
          conn.write( HTTP_S.BuildResponse( "200", "OK" ) );
        }
      } else if ( HTTP_R.method == "SETUP" ) {
        std::string temp = HTTP_R.GetHeader("Transport");
        int ClientRTPLoc = temp.find( "client_port=" ) + 12;
        int PortSpacer = temp.find( "-", ClientRTPLoc );
        int RTPClientPort = atoi( temp.substr( ClientRTPLoc, ( PortSpacer - ClientRTPLoc ) ).c_str() );
        if( HTTP_S.GetHeader( "Session" ) != "" ) {
          fprintf( stderr, "RESPONSE:\n%s\n", HTTP_S.BuildResponse( "459", "Aggregate Operation Not Allowed" ).c_str() );
          conn.write( HTTP_S.BuildResponse( "459", "Aggregate Operation Not Allowed" ) );
        } else {
          HTTP_S.SetHeader( "CSeq", HTTP_R.GetHeader( "CSeq" ).c_str() );
          HTTP_S.SetHeader( "Session", time(NULL) );
          /// \todo "Random" generation of server_ports
          if( HTTP_R.url.find( "audio" ) != std::string::npos ) {
            HTTP_S.SetHeader( "Transport", HTTP_R.GetHeader( "Transport" ) + ";server_port=50002-50003" );
          } else {
            HTTP_S.SetHeader( "Transport", HTTP_R.GetHeader( "Transport" ) + ";server_port=50000-50001" );
            VideoParams.SetOwnTimestampUnit( ( 1.0 / 29.917 ) * 90000.0 );
            VideoParams.SetMaximumPacketSize( 10000 );
            //pick the right port here
            VideoTransParams.SetPortbase( 50000 );
            int VideoStatus = VideoSession.Create( VideoParams, &VideoTransParams );
            if( VideoStatus < 0 ) {
              std::cerr << jrtplib::RTPGetErrorString( VideoStatus ) << std::endl;
              exit( -1 );
            } else {
              std::cerr << "Created video session\n";
            }
            /// \todo retrieve other client than localhost --> Socket::Connection has no support for this yet?
            uint8_t localip[]={127,0,0,1};
            jrtplib::RTPIPv4Address addr(localip,RTPClientPort);

            VideoStatus = VideoSession.AddDestination(addr);
            if (VideoStatus < 0) {
              std::cerr << jrtplib::RTPGetErrorString(VideoStatus) << std::endl;
              exit(-1);
            } else {
              std::cerr << "Destination Set\n";
            }
            VideoSession.SetDefaultPayloadType(98);
            VideoSession.SetDefaultMark(false);
            VideoSession.SetDefaultTimestampIncrement( ( 1.0 / 29.917 ) * 90000 );
          }
          HTTP_S.SetBody( "\r\n\r\n" );
          fprintf( stderr, "RESPONSE:\n%s\n", HTTP_S.BuildResponse( "200", "OK" ).c_str() );
          conn.write( HTTP_S.BuildResponse( "200", "OK" ) );
        }
      } else if( HTTP_R.method == "PLAY" ) {
        if( HTTP_R.GetHeader( "Range" ).substr(0,4) != "npt=" ) {
          fprintf( stderr, "RESPONSE:\n%s\n", HTTP_S.BuildResponse( "501", "Not Implemented" ).c_str() );
          conn.write( HTTP_S.BuildResponse( "501", "Not Implemented" ) );
        } else {
          HTTP_S.SetHeader( "CSeq", HTTP_R.GetHeader( "CSeq" ).c_str() );
          HTTP_S.SetHeader( "Session", HTTP_R.GetHeader( "Session" ) );
          HTTP_S.SetHeader( "Range", HTTP_R.GetHeader( "Range" ) );
          HTTP_S.SetHeader( "RTP-Info", "url=" + HTTP_R.url + ";seq=0;rtptime=0" );
          HTTP_S.SetBody( "\r\n\r\n" );
          fprintf( stderr, "RESPONSE:\n%s\n", HTTP_S.BuildResponse( "200", "OK" ).c_str() );
          conn.write( HTTP_S.BuildResponse( "200", "OK" ) );
          PlayVideo = true;
        }
      } else if( HTTP_R.method == "TEARDOWN" ) {
          HTTP_S.SetHeader( "CSeq", HTTP_R.GetHeader( "CSeq" ).c_str() );
          HTTP_S.SetBody( "\r\n\r\n" );
          fprintf( stderr, "RESPONSE:\n%s\n", HTTP_S.BuildResponse( "200", "OK" ).c_str() );
          conn.write( HTTP_S.BuildResponse( "200", "OK" ) );
          PlayVideo = false;
      } else {
        fprintf( stderr, "RESPONSE:\n%s\n", HTTP_S.BuildResponse( "501", "Not Implemented" ).c_str() );
        conn.write( HTTP_S.BuildResponse( "501", "Not Implemented" ) );
      }
      HTTP_R.Clean();
      HTTP_S.Clean();
      if( PerRequest ) {
        conn.close();
      }
    }
    if( PlayVideo ) {
      /// \todo Select correct source
      std::string VideoBuf = ReadNALU( );
      if( VideoBuf == "" ) {
        jrtplib::RTPTime delay = jrtplib::RTPTime(10.0);
        VideoSession.BYEDestroy(delay,"Out of data",11);
        conn.close();
      } else {
        VideoSession.SendPacket( VideoBuf.c_str(), VideoBuf.size() );//, 98, true, ( 1.0 / 29.917 ) );
//        jrtplib::RTPTime delay( 1.0 / 29.917 );
//        jrtplib::RTPTime::Wait( delay );
      }
    }
  }
  return 0;
}

#define DEFAULT_PORT 554
#define MAINHANDLER RTSP_Handler
#define CONFIGSECT RTSP
#include "../util/server_setup.cpp"
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
** package.
**
** If you have questions regarding the use of this file, please
** contact Nokia at http://qt.nokia.com/contact.
** $QT_END_LICENSE$
**
****************************************************************************/

#include "transformcontactdata.h"

QList<CContactItemField *> TransformContactData::transformDetail(const QContactDetail &detail)
{
	QList<CContactItemField *> fieldList;

	TRAPD(error, fieldList = transformDetailL(detail));

	return fieldList;
}

QContactDetail *TransformContactData::transformItemField(const CContactItemField& field, const QContact &contact)
{
	QContactDetail *detail(0);

	TRAPD(error, detail = transformItemFieldL(field, contact));

	return detail;
}

void TransformContactData::setContexts(const TUid &fieldType, QContactDetail &detail)
{
	if (fieldType == KUidContactFieldVCardMapHOME)
	{
		detail.setContexts(QContactDetail::ContextHome);
	}

	else if (fieldType == KUidContactFieldVCardMapWORK)
	{
		detail.setContexts(QContactDetail::ContextWork);
	}
}

void TransformContactData::setContextsL(const QContactDetail &detail, CContactItemField &field)
{
	QStringList contexts = detail.contexts();

	for (int i = 0; contexts.count(); i++)
	{
		if (contexts.at(i) == QContactDetail::ContextHome )
		{
			field.AddFieldTypeL(KUidContactFieldVCardMapHOME);
		}

		else if (contexts.at(i) == QContactDetail::ContextWork )
		{
			field.AddFieldTypeL(KUidContactFieldVCardMapWORK);
		}
	}
}
<commit_msg>fixed a contexts bug<commit_after>/****************************************************************************
**
** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
** package.
**
** If you have questions regarding the use of this file, please
** contact Nokia at http://qt.nokia.com/contact.
** $QT_END_LICENSE$
**
****************************************************************************/

#include "transformcontactdata.h"

QList<CContactItemField *> TransformContactData::transformDetail(const QContactDetail &detail)
{
	QList<CContactItemField *> fieldList;

	TRAPD(error, fieldList = transformDetailL(detail));

	return fieldList;
}

QContactDetail *TransformContactData::transformItemField(const CContactItemField& field, const QContact &contact)
{
	QContactDetail *detail(0);

	TRAPD(error, detail = transformItemFieldL(field, contact));

	return detail;
}

void TransformContactData::setContexts(const TUid &fieldType, QContactDetail &detail)
{
	if (fieldType == KUidContactFieldVCardMapHOME)
	{
		detail.setContexts(QContactDetail::ContextHome);
	}

	else if (fieldType == KUidContactFieldVCardMapWORK)
	{
		detail.setContexts(QContactDetail::ContextWork);
	}
}

void TransformContactData::setContextsL(const QContactDetail &detail, CContactItemField &field)
{
	QStringList contexts = detail.contexts();

	for (int i = 0; i < contexts.count(); i++)
	{
		if (contexts.at(i) == QContactDetail::ContextHome )
		{
			field.AddFieldTypeL(KUidContactFieldVCardMapHOME);
		}

		else if (contexts.at(i) == QContactDetail::ContextWork )
		{
			field.AddFieldTypeL(KUidContactFieldVCardMapWORK);
		}
	}
}
<|endoftext|>