<commit_before>/*********************************************************************
* Software License Agreement (BSD License)
*
*  Copyright (c) 2008, Willow Garage, Inc.
*  All rights reserved.
*
*  Redistribution and use in source and binary forms, with or without
*  modification, are permitted provided that the following conditions
*  are met:
*
*   * Redistributions of source code must retain the above copyright
*     notice, this list of conditions and the following disclaimer.
*   * Redistributions in binary form must reproduce the above
*     copyright notice, this list of conditions and the following
*     disclaimer in the documentation and/or other materials provided
*     with the distribution.
*   * Neither the name of the Willow Garage nor the names of its
*     contributors may be used to endorse or promote products derived
*     from this software without specific prior written permission.
*
*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
*  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
*  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
*  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
*  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
*  POSSIBILITY OF SUCH DAMAGE.
*********************************************************************/

/* Author: Wim Meeussen */

#include <boost/algorithm/string.hpp>
#include <vector>
#include "urdf_parser.h"

const bool debug = true;

namespace urdf{

bool parseMaterial(Material &material, TiXmlElement *config);
bool parseLink(Link &link, TiXmlElement *config);
bool parseJoint(Joint &joint, TiXmlElement *config);

// Added by achq on 2012/10/13 *******************//

  /**
    * @function isObjectURDF
    */
  bool isObjectURDF( const std::string &_xml_string ) {
  	TiXmlDocument xml_doc;
 	 	xml_doc.Parse( _xml_string.c_str() );

  	TiXmlElement *test_xml = xml_doc.FirstChildElement("object");
  	if ( !test_xml ) { return false; }
  	else { return true; }
	}

  /**
    * @function isRobotURDF
    */
  bool isRobotURDF( const std::string &_xml_string ) {
  	TiXmlDocument xml_doc;
 	 	xml_doc.Parse( _xml_string.c_str() );

  	TiXmlElement *test_xml = xml_doc.FirstChildElement("robot");
  	if ( !test_xml ) { return false; }
  	else { return true; }
  }

// *************************************************//

boost::shared_ptr<ModelInterface>  parseURDF(const std::string &xml_string)
{

  boost::shared_ptr<ModelInterface> model(new ModelInterface);
  model->clear();

  TiXmlDocument xml_doc;
  xml_doc.LoadFile(xml_string.c_str());
  //xml_doc.Parse(xml_string.c_str());

  TiXmlElement *robot_xml = xml_doc.FirstChildElement("robot");
  if (!robot_xml)
  {
    // Added the object if by achq for DART - GRIP (2012/10/13
    // all the rest is the same as original
    robot_xml = xml_doc.FirstChildElement("object");
    if( !robot_xml ) {
      if(debug) printf ( "Could find neither a robot nor an object element in the xml file \n" );
      model.reset();
      return model;
    }
    else {
      if(debug) printf ("Found an object file in the xml file!  \n");
    }
  }
  else {
    if(debug) printf (" Found a robot object in urdf file! \n");
  }

  // Get robot name
  const char *name = robot_xml->Attribute("name");
  if (!name)
  {
    if(debug) printf ("No name given for the robot. \n");
    model.reset();
    return model;
  }
  model->name_ = std::string(name);

  // Get all Material elements
  for (TiXmlElement* material_xml = robot_xml->FirstChildElement("material"); material_xml; material_xml = material_xml->NextSiblingElement("material"))
  {
    boost::shared_ptr<Material> material;
    material.reset(new Material);

    try {
      parseMaterial(*material, material_xml);
      if (model->getMaterial(material->name))
      {
        if(debug) printf ("material '%s' is not unique. \n", material->name.c_str());
        material.reset();
        model.reset();
        return model;
      }
      else
      {
        model->materials_.insert(make_pair(material->name,material));
        if(debug) printf ("successfully added a new material '%s' \n", material->name.c_str());
      }
    }
    catch (ParseError &e) {
      if(debug) printf ("material xml is not initialized correctly \n");
      material.reset();
      model.reset();
      return model;
    }
  }

  // Get all Link elements
  for (TiXmlElement* link_xml = robot_xml->FirstChildElement("link"); link_xml; link_xml = link_xml->NextSiblingElement("link"))
  {
    boost::shared_ptr<Link> link;
    link.reset(new Link);

    try {
      parseLink(*link, link_xml);
      if (model->getLink(link->name))
      {
        if(debug) printf ("link '%s' is not unique. \n", link->name.c_str());
        model.reset();
        return model;
      }
      else
      {
        // set link visual material
        if(debug) printf ("setting link '%s' material \n", link->name.c_str());
        if (link->visual)
        {
          if (!link->visual->material_name.empty())
          {
            if (model->getMaterial(link->visual->material_name))
            {
              if(debug) printf ("setting link '%s' material to '%s' \n", link->name.c_str(),link->visual->material_name.c_str());
              link->visual->material = model->getMaterial( link->visual->material_name.c_str() );
            }
            else
            {
              if (link->visual->material)
              {
                if(debug) printf ("link '%s' material '%s' defined in Visual. \n", link->name.c_str(),link->visual->material_name.c_str());
                model->materials_.insert(make_pair(link->visual->material->name,link->visual->material));
              }
              else
              {
                if(debug) printf ("link '%s' material '%s' undefined. \n", link->name.c_str(),link->visual->material_name.c_str());
                model.reset();
                return model;
              }
            }
          }
        }

        model->links_.insert(make_pair(link->name,link));
        if(debug) printf ("successfully added a new link '%s' \n", link->name.c_str());
      }
    }
    catch (ParseError &e) {
      if(debug) printf ("link xml is not initialized correctly \n");
      model.reset();
      return model;
    }
  }
  if (model->links_.empty()){
    if(debug) printf ("No link elements found in urdf file \n");
    model.reset();
    return model;
  }

  // Get all Joint elements
  for (TiXmlElement* joint_xml = robot_xml->FirstChildElement("joint"); joint_xml; joint_xml = joint_xml->NextSiblingElement("joint"))
  {
    boost::shared_ptr<Joint> joint;
    joint.reset(new Joint);

    if (parseJoint(*joint, joint_xml))
    {
      if (model->getJoint(joint->name))
      {
        if(debug) printf ("joint '%s' is not unique. \n", joint->name.c_str());
        model.reset();
        return model;
      }
      else
      {
        model->joints_.insert(make_pair(joint->name,joint));
        if(debug) printf ("successfully added a new joint '%s' \n", joint->name.c_str());
      }
    }
    else
    {
      if(debug) printf ("joint xml is not initialized correctly \n");
      model.reset();
      return model;
    }
  }

  // every link has children links and joints, but no parents, so we create a
  // local convenience data structure for keeping child->parent relations
  std::map<std::string, std::string> parent_link_tree;
  parent_link_tree.clear();

  // building tree: name mapping
  try
  {
    model->initTree(parent_link_tree);
  }
  catch(ParseError &e)
  {
    if(debug) printf ("Failed to build tree: %s \n", e.what());
    model.reset();
    return model;
  }

  // find the root link
  try
  {
    model->initRoot(parent_link_tree);
  }
  catch(ParseError &e)
  {
    if(debug) printf ("Failed to find root link: %s \n", e.what());
    model.reset();
    return model;
  }

  return model;
}

bool exportMaterial(Material &material, TiXmlElement *config);
bool exportLink(Link &link, TiXmlElement *config);
bool exportJoint(Joint &joint, TiXmlElement *config);
TiXmlDocument*  exportURDF(boost::shared_ptr<ModelInterface> &model)
{
  TiXmlDocument *doc = new TiXmlDocument();

  TiXmlElement *robot = new TiXmlElement("robot");
  robot->SetAttribute("name", model->name_);
  doc->LinkEndChild(robot);

  for (std::map<std::string, boost::shared_ptr<Link> >::const_iterator l=model->links_.begin(); l!=model->links_.end(); l++)
    exportLink(*(l->second), robot);

  for (std::map<std::string, boost::shared_ptr<Joint> >::const_iterator j=model->joints_.begin(); j!=model->joints_.end(); j++)
  {
    if(debug) printf ("exporting joint [%s]\n",j->second->name.c_str());
    exportJoint(*(j->second), robot);
  }

  return doc;
}

}

<commit_msg>Turned off debugging for URDF loading<commit_after>/*********************************************************************
* Software License Agreement (BSD License)
*
*  Copyright (c) 2008, Willow Garage, Inc.
*  All rights reserved.
*
*  Redistribution and use in source and binary forms, with or without
*  modification, are permitted provided that the following conditions
*  are met:
*
*   * Redistributions of source code must retain the above copyright
*     notice, this list of conditions and the following disclaimer.
*   * Redistributions in binary form must reproduce the above
*     copyright notice, this list of conditions and the following
*     disclaimer in the documentation and/or other materials provided
*     with the distribution.
*   * Neither the name of the Willow Garage nor the names of its
*     contributors may be used to endorse or promote products derived
*     from this software without specific prior written permission.
*
*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
*  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
*  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
*  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
*  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
*  POSSIBILITY OF SUCH DAMAGE.
*********************************************************************/

/* Author: Wim Meeussen */

#include <boost/algorithm/string.hpp>
#include <vector>
#include "urdf_parser.h"

//const bool debug = true;
const bool debug = false;

namespace urdf{

bool parseMaterial(Material &material, TiXmlElement *config);
bool parseLink(Link &link, TiXmlElement *config);
bool parseJoint(Joint &joint, TiXmlElement *config);

// Added by achq on 2012/10/13 *******************//

  /**
    * @function isObjectURDF
    */
  bool isObjectURDF( const std::string &_xml_string ) {
  	TiXmlDocument xml_doc;
 	 	xml_doc.Parse( _xml_string.c_str() );

  	TiXmlElement *test_xml = xml_doc.FirstChildElement("object");
  	if ( !test_xml ) { return false; }
  	else { return true; }
	}

  /**
    * @function isRobotURDF
    */
  bool isRobotURDF( const std::string &_xml_string ) {
  	TiXmlDocument xml_doc;
 	 	xml_doc.Parse( _xml_string.c_str() );

  	TiXmlElement *test_xml = xml_doc.FirstChildElement("robot");
  	if ( !test_xml ) { return false; }
  	else { return true; }
  }

// *************************************************//

boost::shared_ptr<ModelInterface>  parseURDF(const std::string &xml_string)
{

  boost::shared_ptr<ModelInterface> model(new ModelInterface);
  model->clear();

  TiXmlDocument xml_doc;
  xml_doc.LoadFile(xml_string.c_str());
  //xml_doc.Parse(xml_string.c_str());

  TiXmlElement *robot_xml = xml_doc.FirstChildElement("robot");
  if (!robot_xml)
  {
    // Added the object if by achq for DART - GRIP (2012/10/13
    // all the rest is the same as original
    robot_xml = xml_doc.FirstChildElement("object");
    if( !robot_xml ) {
      if(debug) printf ( "Could find neither a robot nor an object element in the xml file \n" );
      model.reset();
      return model;
    }
    else {
      if(debug) printf ("Found an object file in the xml file!  \n");
    }
  }
  else {
    if(debug) printf (" Found a robot object in urdf file! \n");
  }

  // Get robot name
  const char *name = robot_xml->Attribute("name");
  if (!name)
  {
    if(debug) printf ("No name given for the robot. \n");
    model.reset();
    return model;
  }
  model->name_ = std::string(name);

  // Get all Material elements
  for (TiXmlElement* material_xml = robot_xml->FirstChildElement("material"); material_xml; material_xml = material_xml->NextSiblingElement("material"))
  {
    boost::shared_ptr<Material> material;
    material.reset(new Material);

    try {
      parseMaterial(*material, material_xml);
      if (model->getMaterial(material->name))
      {
        if(debug) printf ("material '%s' is not unique. \n", material->name.c_str());
        material.reset();
        model.reset();
        return model;
      }
      else
      {
        model->materials_.insert(make_pair(material->name,material));
        if(debug) printf ("successfully added a new material '%s' \n", material->name.c_str());
      }
    }
    catch (ParseError &e) {
      if(debug) printf ("material xml is not initialized correctly \n");
      material.reset();
      model.reset();
      return model;
    }
  }

  // Get all Link elements
  for (TiXmlElement* link_xml = robot_xml->FirstChildElement("link"); link_xml; link_xml = link_xml->NextSiblingElement("link"))
  {
    boost::shared_ptr<Link> link;
    link.reset(new Link);

    try {
      parseLink(*link, link_xml);
      if (model->getLink(link->name))
      {
        if(debug) printf ("link '%s' is not unique. \n", link->name.c_str());
        model.reset();
        return model;
      }
      else
      {
        // set link visual material
        if(debug) printf ("setting link '%s' material \n", link->name.c_str());
        if (link->visual)
        {
          if (!link->visual->material_name.empty())
          {
            if (model->getMaterial(link->visual->material_name))
            {
              if(debug) printf ("setting link '%s' material to '%s' \n", link->name.c_str(),link->visual->material_name.c_str());
              link->visual->material = model->getMaterial( link->visual->material_name.c_str() );
            }
            else
            {
              if (link->visual->material)
              {
                if(debug) printf ("link '%s' material '%s' defined in Visual. \n", link->name.c_str(),link->visual->material_name.c_str());
                model->materials_.insert(make_pair(link->visual->material->name,link->visual->material));
              }
              else
              {
                if(debug) printf ("link '%s' material '%s' undefined. \n", link->name.c_str(),link->visual->material_name.c_str());
                model.reset();
                return model;
              }
            }
          }
        }

        model->links_.insert(make_pair(link->name,link));
        if(debug) printf ("successfully added a new link '%s' \n", link->name.c_str());
      }
    }
    catch (ParseError &e) {
      if(debug) printf ("link xml is not initialized correctly \n");
      model.reset();
      return model;
    }
  }
  if (model->links_.empty()){
    if(debug) printf ("No link elements found in urdf file \n");
    model.reset();
    return model;
  }

  // Get all Joint elements
  for (TiXmlElement* joint_xml = robot_xml->FirstChildElement("joint"); joint_xml; joint_xml = joint_xml->NextSiblingElement("joint"))
  {
    boost::shared_ptr<Joint> joint;
    joint.reset(new Joint);

    if (parseJoint(*joint, joint_xml))
    {
      if (model->getJoint(joint->name))
      {
        if(debug) printf ("joint '%s' is not unique. \n", joint->name.c_str());
        model.reset();
        return model;
      }
      else
      {
        model->joints_.insert(make_pair(joint->name,joint));
        if(debug) printf ("successfully added a new joint '%s' \n", joint->name.c_str());
      }
    }
    else
    {
      if(debug) printf ("joint xml is not initialized correctly \n");
      model.reset();
      return model;
    }
  }

  // every link has children links and joints, but no parents, so we create a
  // local convenience data structure for keeping child->parent relations
  std::map<std::string, std::string> parent_link_tree;
  parent_link_tree.clear();

  // building tree: name mapping
  try
  {
    model->initTree(parent_link_tree);
  }
  catch(ParseError &e)
  {
    if(debug) printf ("Failed to build tree: %s \n", e.what());
    model.reset();
    return model;
  }

  // find the root link
  try
  {
    model->initRoot(parent_link_tree);
  }
  catch(ParseError &e)
  {
    if(debug) printf ("Failed to find root link: %s \n", e.what());
    model.reset();
    return model;
  }

  return model;
}

bool exportMaterial(Material &material, TiXmlElement *config);
bool exportLink(Link &link, TiXmlElement *config);
bool exportJoint(Joint &joint, TiXmlElement *config);
TiXmlDocument*  exportURDF(boost::shared_ptr<ModelInterface> &model)
{
  TiXmlDocument *doc = new TiXmlDocument();

  TiXmlElement *robot = new TiXmlElement("robot");
  robot->SetAttribute("name", model->name_);
  doc->LinkEndChild(robot);

  for (std::map<std::string, boost::shared_ptr<Link> >::const_iterator l=model->links_.begin(); l!=model->links_.end(); l++)
    exportLink(*(l->second), robot);

  for (std::map<std::string, boost::shared_ptr<Joint> >::const_iterator j=model->joints_.begin(); j!=model->joints_.end(); j++)
  {
    if(debug) printf ("exporting joint [%s]\n",j->second->name.c_str());
    exportJoint(*(j->second), robot);
  }

  return doc;
}

}

<|endoftext|>


<commit_before>#include <stingray/toolkit/ITaskExecutor.h>

#if defined(PLATFORM_OSPLUS)
#	include <stingray/platform/osplus/threads/OS21TaskExecutor.h>
#else
#	include <stingray/toolkit/ThreadTaskExecutor.h>
#endif
#include <stingray/log/Logger.h>

namespace stingray
{

	ITaskExecutorPtr ITaskExecutor::Create(const std::string& name, const function<void(const std::exception&)>& exceptionHandler)
#if defined(PLATFORM_OSPLUS)
	{ return make_shared<osplus::TaskExecutor>(name, exceptionHandler); }
#else
	{ return make_shared<ThreadTaskExecutor>(name, exceptionHandler); }
#endif

	void ITaskExecutor::DefaultExceptionHandler(const std::exception& ex)
	{ Logger::Error() << "Uncaught exception in ITaskExecutor: " << diagnostic_information(ex); }

}
<commit_msg>Removed no longer necessary diagnostic_information from most files<commit_after>#include <stingray/toolkit/ITaskExecutor.h>

#if defined(PLATFORM_OSPLUS)
#	include <stingray/platform/osplus/threads/OS21TaskExecutor.h>
#else
#	include <stingray/toolkit/ThreadTaskExecutor.h>
#endif
#include <stingray/log/Logger.h>

namespace stingray
{

	ITaskExecutorPtr ITaskExecutor::Create(const std::string& name, const function<void(const std::exception&)>& exceptionHandler)
#if defined(PLATFORM_OSPLUS)
	{ return make_shared<osplus::TaskExecutor>(name, exceptionHandler); }
#else
	{ return make_shared<ThreadTaskExecutor>(name, exceptionHandler); }
#endif

	void ITaskExecutor::DefaultExceptionHandler(const std::exception& ex)
	{ Logger::Error() << "Uncaught exception in ITaskExecutor: " << ex; }

}
<|endoftext|>


<commit_before>#pragma once

#include <cassert>
#include <type_traits>
#include <utility>

#include "PImpl.hpp"

template <typename T>
PImpl<T>::PImpl(decltype(nullptr)) noexcept
{
}

template<typename T>
template<typename... Ts>
inline PImpl<T>::PImpl(Ts&&... values)
{
	create(std::forward<Ts>(values)...);
}

template<typename T>
PImpl<T>::~PImpl()
{
	static_assert(sizeof(T) > 0, "T is an incomplete type! Define it before using PImpl.");

	if (ptr)
		delete ptr;
}

template<typename T>
inline PImpl<T>::PImpl(PImpl&& other) noexcept
{
	*this = std::move(other);
}

template<typename T>
inline PImpl<T>& PImpl<T>::operator=(PImpl&& rhs) noexcept
{
	ptr = std::exchange(rhs.ptr, nullptr);

	return *this;
}

template<typename T>
template<typename... Ts>
inline void PImpl<T>::create(Ts&&... values)
{
	static_assert(std::is_constructible_v<T, Ts...>, "Cannot construct T from the given values!");

	if (ptr != nullptr)
		delete ptr;

	ptr = new T{ std::forward<Ts>(values)... };
}

/// This class is used to hide the constructors and destructors of the implementation.
/// This forces users of PImpl to only call constructors and destructors of this class.
template <typename T>
struct HideImplementation
	: public T
{
private:
	HideImplementation() = default;
	~HideImplementation() = default;
};

template<typename T>
inline auto* PImpl<T>::operator->() noexcept
{
	assert(ptr);
	return reinterpret_cast<HideImplementation<T>*>(ptr);
}

template<typename T>
inline const auto* PImpl<T>::operator->() const noexcept
{
	assert(ptr);
	return reinterpret_cast<HideImplementation<const T>*>(ptr);
}

template<typename T>
inline auto& PImpl<T>::operator*() noexcept
{
	assert(ptr);
	return *reinterpret_cast<HideImplementation<T>*>(ptr);
}

template<typename T>
inline const auto& PImpl<T>::operator*() const noexcept
{
	assert(ptr);
	return *reinterpret_cast<HideImplementation<const T>*>(ptr);
}
<commit_msg>Remove HideImplementation trick<commit_after>#pragma once

#include <cassert>
#include <type_traits>
#include <utility>

#include "PImpl.hpp"

template <typename T>
PImpl<T>::PImpl(decltype(nullptr)) noexcept
{
}

template<typename T>
template<typename... Ts>
inline PImpl<T>::PImpl(Ts&&... values)
{
	create(std::forward<Ts>(values)...);
}

template<typename T>
PImpl<T>::~PImpl()
{
	static_assert(sizeof(T) > 0, "T is an incomplete type! Define it before using PImpl.");

	if (ptr)
		delete ptr;
}

template<typename T>
inline PImpl<T>::PImpl(PImpl&& other) noexcept
{
	*this = std::move(other);
}

template<typename T>
inline PImpl<T>& PImpl<T>::operator=(PImpl&& rhs) noexcept
{
	ptr = std::exchange(rhs.ptr, nullptr);

	return *this;
}

template<typename T>
template<typename... Ts>
inline void PImpl<T>::create(Ts&&... values)
{
	static_assert(std::is_constructible_v<T, Ts...>, "Cannot construct T from the given values!");

	if (ptr != nullptr)
		delete ptr;

	ptr = new T{ std::forward<Ts>(values)... };
}

template<typename T>
inline auto* PImpl<T>::operator->() noexcept
{
	assert(ptr);
	return ptr;
}

template<typename T>
inline const auto* PImpl<T>::operator->() const noexcept
{
	assert(ptr);
	return ptr;
}

template<typename T>
inline auto& PImpl<T>::operator*() noexcept
{
	assert(ptr);
	return ptr;
}

template<typename T>
inline const auto& PImpl<T>::operator*() const noexcept
{
	assert(ptr);
	return ptr;
}
<|endoftext|>


<commit_before>/*
 * Copyright © 2010 Intel Corporation
 *
 * 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 (including the next
 * paragraph) 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.
 */

/**
 * \file brw_wm_channel_expressions.cpp
 *
 * Breaks vector operations down into operations on each component.
 *
 * The 965 fragment shader receives 8 or 16 pixels at a time, so each
 * channel of a vector is laid out as 1 or 2 8-float registers.  Each
 * ALU operation operates on one of those channel registers.  As a
 * result, there is no value to the 965 fragment shader in tracking
 * "vector" expressions in the sense of GLSL fragment shaders, when
 * doing a channel at a time may help in constant folding, algebraic
 * simplification, and reducing the liveness of channel registers.
 *
 * The exception to the desire to break everything down to floats is
 * texturing.  The texture sampler returns a writemasked masked
 * 4/8-register sequence containing the texture values.  We don't want
 * to dispatch to the sampler separately for each channel we need, so
 * we do retain the vector types in that case.
 */

extern "C" {
#include "main/core.h"
#include "brw_wm.h"
}
#include "../glsl/ir.h"
#include "../glsl/ir_expression_flattening.h"
#include "../glsl/glsl_types.h"

class ir_channel_expressions_visitor : public ir_hierarchical_visitor {
public:
   ir_channel_expressions_visitor()
   {
      this->progress = false;
      this->mem_ctx = NULL;
   }

   ir_visitor_status visit_leave(ir_assignment *);

   ir_rvalue *get_element(ir_variable *var, unsigned int element);
   void assign(ir_assignment *ir, int elem, ir_rvalue *val);

   bool progress;
   void *mem_ctx;
};

static bool
channel_expressions_predicate(ir_instruction *ir)
{
   ir_expression *expr = ir->as_expression();
   unsigned int i;

   if (!expr)
      return false;

   for (i = 0; i < expr->get_num_operands(); i++) {
      if (expr->operands[i]->type->is_vector())
	 return true;
   }

   return false;
}

GLboolean
brw_do_channel_expressions(exec_list *instructions)
{
   ir_channel_expressions_visitor v;

   /* Pull out any matrix expression to a separate assignment to a
    * temp.  This will make our handling of the breakdown to
    * operations on the matrix's vector components much easier.
    */
   do_expression_flattening(instructions, channel_expressions_predicate);

   visit_list_elements(&v, instructions);

   return v.progress;
}

ir_rvalue *
ir_channel_expressions_visitor::get_element(ir_variable *var, unsigned int elem)
{
   ir_dereference *deref;

   if (var->type->is_scalar())
      return new(mem_ctx) ir_dereference_variable(var);

   assert(elem < var->type->components());
   deref = new(mem_ctx) ir_dereference_variable(var);
   return new(mem_ctx) ir_swizzle(deref, elem, 0, 0, 0, 1);
}

void
ir_channel_expressions_visitor::assign(ir_assignment *ir, int elem, ir_rvalue *val)
{
   ir_dereference *lhs = ir->lhs->clone(mem_ctx, NULL);
   ir_assignment *assign;

   /* This assign-of-expression should have been generated by the
    * expression flattening visitor (since we never short circit to
    * not flatten, even for plain assignments of variables), so the
    * writemask is always full.
    */
   assert(ir->write_mask == (1 << ir->lhs->type->components()) - 1);

   assign = new(mem_ctx) ir_assignment(lhs, val, NULL, (1 << elem));
   ir->insert_before(assign);
}

ir_visitor_status
ir_channel_expressions_visitor::visit_leave(ir_assignment *ir)
{
   ir_expression *expr = ir->rhs->as_expression();
   bool found_vector = false;
   unsigned int i, vector_elements = 1;
   ir_variable *op_var[2];

   if (!expr)
      return visit_continue;

   if (!this->mem_ctx)
      this->mem_ctx = talloc_parent(ir);

   for (i = 0; i < expr->get_num_operands(); i++) {
      if (expr->operands[i]->type->is_vector()) {
	 found_vector = true;
	 vector_elements = expr->operands[i]->type->vector_elements;
	 break;
      }
   }
   if (!found_vector)
      return visit_continue;

   /* Store the expression operands in temps so we can use them
    * multiple times.
    */
   for (i = 0; i < expr->get_num_operands(); i++) {
      ir_assignment *assign;
      ir_dereference *deref;

      assert(!expr->operands[i]->type->is_matrix());

      op_var[i] = new(mem_ctx) ir_variable(expr->operands[i]->type,
					   "channel_expressions",
					   ir_var_temporary);
      ir->insert_before(op_var[i]);

      deref = new(mem_ctx) ir_dereference_variable(op_var[i]);
      assign = new(mem_ctx) ir_assignment(deref,
					  expr->operands[i],
					  NULL);
      ir->insert_before(assign);
   }

   const glsl_type *element_type = glsl_type::get_instance(ir->lhs->type->base_type,
							   1, 1);

   /* OK, time to break down this vector operation. */
   switch (expr->operation) {
   case ir_unop_bit_not:
   case ir_unop_logic_not:
   case ir_unop_neg:
   case ir_unop_abs:
   case ir_unop_sign:
   case ir_unop_rcp:
   case ir_unop_rsq:
   case ir_unop_sqrt:
   case ir_unop_exp:
   case ir_unop_log:
   case ir_unop_exp2:
   case ir_unop_log2:
   case ir_unop_f2i:
   case ir_unop_i2f:
   case ir_unop_f2b:
   case ir_unop_b2f:
   case ir_unop_i2b:
   case ir_unop_b2i:
   case ir_unop_u2f:
   case ir_unop_trunc:
   case ir_unop_ceil:
   case ir_unop_floor:
   case ir_unop_fract:
   case ir_unop_round_even:
   case ir_unop_sin:
   case ir_unop_cos:
   case ir_unop_dFdx:
   case ir_unop_dFdy:
      for (i = 0; i < vector_elements; i++) {
	 ir_rvalue *op0 = get_element(op_var[0], i);

	 assign(ir, i, new(mem_ctx) ir_expression(expr->operation,
						  element_type,
						  op0,
						  NULL));
      }
      break;

   case ir_binop_add:
   case ir_binop_sub:
   case ir_binop_mul:
   case ir_binop_div:
   case ir_binop_mod:
   case ir_binop_min:
   case ir_binop_max:
   case ir_binop_pow:
   case ir_binop_lshift:
   case ir_binop_rshift:
   case ir_binop_bit_and:
   case ir_binop_bit_xor:
   case ir_binop_bit_or:
   case ir_binop_less:
   case ir_binop_greater:
   case ir_binop_lequal:
   case ir_binop_gequal:
   case ir_binop_equal:
   case ir_binop_nequal:
      for (i = 0; i < vector_elements; i++) {
	 ir_rvalue *op0 = get_element(op_var[0], i);
	 ir_rvalue *op1 = get_element(op_var[1], i);

	 assign(ir, i, new(mem_ctx) ir_expression(expr->operation,
						  element_type,
						  op0,
						  op1));
      }
      break;

   case ir_unop_any: {
      ir_expression *temp;
      temp = new(mem_ctx) ir_expression(ir_binop_logic_or,
					element_type,
					get_element(op_var[0], 0),
					get_element(op_var[0], 1));

      for (i = 2; i < vector_elements; i++) {
	 temp = new(mem_ctx) ir_expression(ir_binop_logic_or,
					   element_type,
					   get_element(op_var[0], i),
					   temp);
      }
      assign(ir, 0, temp);
      break;
   }

   case ir_binop_dot: {
      ir_expression *last = NULL;
      for (i = 0; i < vector_elements; i++) {
	 ir_rvalue *op0 = get_element(op_var[0], i);
	 ir_rvalue *op1 = get_element(op_var[1], i);
	 ir_expression *temp;

	 temp = new(mem_ctx) ir_expression(ir_binop_mul,
					   element_type,
					   op0,
					   op1);
	 if (last) {
	    last = new(mem_ctx) ir_expression(ir_binop_add,
					      element_type,
					      temp,
					      last);
	 } else {
	    last = temp;
	 }
      }
      assign(ir, 0, last);
      break;
   }

   case ir_binop_logic_and:
   case ir_binop_logic_xor:
   case ir_binop_logic_or:
      ir->print();
      printf("\n");
      assert(!"not reached: expression operates on scalars only");
      break;
   case ir_binop_all_equal:
   case ir_binop_any_nequal: {
      ir_expression *last = NULL;
      for (i = 0; i < vector_elements; i++) {
	 ir_rvalue *op0 = get_element(op_var[0], i);
	 ir_rvalue *op1 = get_element(op_var[1], i);
	 ir_expression *temp;
	 ir_expression_operation join;

	 if (expr->operation == ir_binop_all_equal)
	    join = ir_binop_logic_and;
	 else
	    join = ir_binop_logic_or;

	 temp = new(mem_ctx) ir_expression(expr->operation,
					   element_type,
					   op0,
					   op1);
	 if (last) {
	    last = new(mem_ctx) ir_expression(join,
					      element_type,
					      temp,
					      last);
	 } else {
	    last = temp;
	 }
      }
      assign(ir, 0, last);
      break;
   }
   case ir_unop_noise:
      assert(!"noise should have been broken down to function call");
      break;
   }

   ir->remove();
   this->progress = true;

   return visit_continue;
}
<commit_msg>i965: Fix compile warning about missing opcodes.<commit_after>/*
 * Copyright © 2010 Intel Corporation
 *
 * 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 (including the next
 * paragraph) 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.
 */

/**
 * \file brw_wm_channel_expressions.cpp
 *
 * Breaks vector operations down into operations on each component.
 *
 * The 965 fragment shader receives 8 or 16 pixels at a time, so each
 * channel of a vector is laid out as 1 or 2 8-float registers.  Each
 * ALU operation operates on one of those channel registers.  As a
 * result, there is no value to the 965 fragment shader in tracking
 * "vector" expressions in the sense of GLSL fragment shaders, when
 * doing a channel at a time may help in constant folding, algebraic
 * simplification, and reducing the liveness of channel registers.
 *
 * The exception to the desire to break everything down to floats is
 * texturing.  The texture sampler returns a writemasked masked
 * 4/8-register sequence containing the texture values.  We don't want
 * to dispatch to the sampler separately for each channel we need, so
 * we do retain the vector types in that case.
 */

extern "C" {
#include "main/core.h"
#include "brw_wm.h"
}
#include "../glsl/ir.h"
#include "../glsl/ir_expression_flattening.h"
#include "../glsl/glsl_types.h"

class ir_channel_expressions_visitor : public ir_hierarchical_visitor {
public:
   ir_channel_expressions_visitor()
   {
      this->progress = false;
      this->mem_ctx = NULL;
   }

   ir_visitor_status visit_leave(ir_assignment *);

   ir_rvalue *get_element(ir_variable *var, unsigned int element);
   void assign(ir_assignment *ir, int elem, ir_rvalue *val);

   bool progress;
   void *mem_ctx;
};

static bool
channel_expressions_predicate(ir_instruction *ir)
{
   ir_expression *expr = ir->as_expression();
   unsigned int i;

   if (!expr)
      return false;

   for (i = 0; i < expr->get_num_operands(); i++) {
      if (expr->operands[i]->type->is_vector())
	 return true;
   }

   return false;
}

GLboolean
brw_do_channel_expressions(exec_list *instructions)
{
   ir_channel_expressions_visitor v;

   /* Pull out any matrix expression to a separate assignment to a
    * temp.  This will make our handling of the breakdown to
    * operations on the matrix's vector components much easier.
    */
   do_expression_flattening(instructions, channel_expressions_predicate);

   visit_list_elements(&v, instructions);

   return v.progress;
}

ir_rvalue *
ir_channel_expressions_visitor::get_element(ir_variable *var, unsigned int elem)
{
   ir_dereference *deref;

   if (var->type->is_scalar())
      return new(mem_ctx) ir_dereference_variable(var);

   assert(elem < var->type->components());
   deref = new(mem_ctx) ir_dereference_variable(var);
   return new(mem_ctx) ir_swizzle(deref, elem, 0, 0, 0, 1);
}

void
ir_channel_expressions_visitor::assign(ir_assignment *ir, int elem, ir_rvalue *val)
{
   ir_dereference *lhs = ir->lhs->clone(mem_ctx, NULL);
   ir_assignment *assign;

   /* This assign-of-expression should have been generated by the
    * expression flattening visitor (since we never short circit to
    * not flatten, even for plain assignments of variables), so the
    * writemask is always full.
    */
   assert(ir->write_mask == (1 << ir->lhs->type->components()) - 1);

   assign = new(mem_ctx) ir_assignment(lhs, val, NULL, (1 << elem));
   ir->insert_before(assign);
}

ir_visitor_status
ir_channel_expressions_visitor::visit_leave(ir_assignment *ir)
{
   ir_expression *expr = ir->rhs->as_expression();
   bool found_vector = false;
   unsigned int i, vector_elements = 1;
   ir_variable *op_var[2];

   if (!expr)
      return visit_continue;

   if (!this->mem_ctx)
      this->mem_ctx = talloc_parent(ir);

   for (i = 0; i < expr->get_num_operands(); i++) {
      if (expr->operands[i]->type->is_vector()) {
	 found_vector = true;
	 vector_elements = expr->operands[i]->type->vector_elements;
	 break;
      }
   }
   if (!found_vector)
      return visit_continue;

   /* Store the expression operands in temps so we can use them
    * multiple times.
    */
   for (i = 0; i < expr->get_num_operands(); i++) {
      ir_assignment *assign;
      ir_dereference *deref;

      assert(!expr->operands[i]->type->is_matrix());

      op_var[i] = new(mem_ctx) ir_variable(expr->operands[i]->type,
					   "channel_expressions",
					   ir_var_temporary);
      ir->insert_before(op_var[i]);

      deref = new(mem_ctx) ir_dereference_variable(op_var[i]);
      assign = new(mem_ctx) ir_assignment(deref,
					  expr->operands[i],
					  NULL);
      ir->insert_before(assign);
   }

   const glsl_type *element_type = glsl_type::get_instance(ir->lhs->type->base_type,
							   1, 1);

   /* OK, time to break down this vector operation. */
   switch (expr->operation) {
   case ir_unop_bit_not:
   case ir_unop_logic_not:
   case ir_unop_neg:
   case ir_unop_abs:
   case ir_unop_sign:
   case ir_unop_rcp:
   case ir_unop_rsq:
   case ir_unop_sqrt:
   case ir_unop_exp:
   case ir_unop_log:
   case ir_unop_exp2:
   case ir_unop_log2:
   case ir_unop_f2i:
   case ir_unop_i2f:
   case ir_unop_f2b:
   case ir_unop_b2f:
   case ir_unop_i2b:
   case ir_unop_b2i:
   case ir_unop_u2f:
   case ir_unop_trunc:
   case ir_unop_ceil:
   case ir_unop_floor:
   case ir_unop_fract:
   case ir_unop_round_even:
   case ir_unop_sin:
   case ir_unop_cos:
   case ir_unop_sin_reduced:
   case ir_unop_cos_reduced:
   case ir_unop_dFdx:
   case ir_unop_dFdy:
      for (i = 0; i < vector_elements; i++) {
	 ir_rvalue *op0 = get_element(op_var[0], i);

	 assign(ir, i, new(mem_ctx) ir_expression(expr->operation,
						  element_type,
						  op0,
						  NULL));
      }
      break;

   case ir_binop_add:
   case ir_binop_sub:
   case ir_binop_mul:
   case ir_binop_div:
   case ir_binop_mod:
   case ir_binop_min:
   case ir_binop_max:
   case ir_binop_pow:
   case ir_binop_lshift:
   case ir_binop_rshift:
   case ir_binop_bit_and:
   case ir_binop_bit_xor:
   case ir_binop_bit_or:
   case ir_binop_less:
   case ir_binop_greater:
   case ir_binop_lequal:
   case ir_binop_gequal:
   case ir_binop_equal:
   case ir_binop_nequal:
      for (i = 0; i < vector_elements; i++) {
	 ir_rvalue *op0 = get_element(op_var[0], i);
	 ir_rvalue *op1 = get_element(op_var[1], i);

	 assign(ir, i, new(mem_ctx) ir_expression(expr->operation,
						  element_type,
						  op0,
						  op1));
      }
      break;

   case ir_unop_any: {
      ir_expression *temp;
      temp = new(mem_ctx) ir_expression(ir_binop_logic_or,
					element_type,
					get_element(op_var[0], 0),
					get_element(op_var[0], 1));

      for (i = 2; i < vector_elements; i++) {
	 temp = new(mem_ctx) ir_expression(ir_binop_logic_or,
					   element_type,
					   get_element(op_var[0], i),
					   temp);
      }
      assign(ir, 0, temp);
      break;
   }

   case ir_binop_dot: {
      ir_expression *last = NULL;
      for (i = 0; i < vector_elements; i++) {
	 ir_rvalue *op0 = get_element(op_var[0], i);
	 ir_rvalue *op1 = get_element(op_var[1], i);
	 ir_expression *temp;

	 temp = new(mem_ctx) ir_expression(ir_binop_mul,
					   element_type,
					   op0,
					   op1);
	 if (last) {
	    last = new(mem_ctx) ir_expression(ir_binop_add,
					      element_type,
					      temp,
					      last);
	 } else {
	    last = temp;
	 }
      }
      assign(ir, 0, last);
      break;
   }

   case ir_binop_logic_and:
   case ir_binop_logic_xor:
   case ir_binop_logic_or:
      ir->print();
      printf("\n");
      assert(!"not reached: expression operates on scalars only");
      break;
   case ir_binop_all_equal:
   case ir_binop_any_nequal: {
      ir_expression *last = NULL;
      for (i = 0; i < vector_elements; i++) {
	 ir_rvalue *op0 = get_element(op_var[0], i);
	 ir_rvalue *op1 = get_element(op_var[1], i);
	 ir_expression *temp;
	 ir_expression_operation join;

	 if (expr->operation == ir_binop_all_equal)
	    join = ir_binop_logic_and;
	 else
	    join = ir_binop_logic_or;

	 temp = new(mem_ctx) ir_expression(expr->operation,
					   element_type,
					   op0,
					   op1);
	 if (last) {
	    last = new(mem_ctx) ir_expression(join,
					      element_type,
					      temp,
					      last);
	 } else {
	    last = temp;
	 }
      }
      assign(ir, 0, last);
      break;
   }
   case ir_unop_noise:
      assert(!"noise should have been broken down to function call");
      break;
   case ir_quadop_vector:
      assert(!"should have been lowered");
      break;
   }

   ir->remove();
   this->progress = true;

   return visit_continue;
}
<|endoftext|>


<commit_before>/*
 * Copyright © 2014 Intel Corporation
 *
 * 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 (including the next
 * paragraph) 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 "brw_fs.h"
#include "brw_fs_live_variables.h"
#include "brw_cfg.h"

/** @file brw_fs_dead_code_eliminate.cpp
 *
 * Dataflow-aware dead code elimination.
 *
 * Walks the instruction list from the bottom, removing instructions that
 * have results that both aren't used in later blocks and haven't been read
 * yet in the tail end of this block.
 */

bool
fs_visitor::dead_code_eliminate()
{
   bool progress = false;

   calculate_live_intervals();

   int num_vars = live_intervals->num_vars;
   BITSET_WORD *live = rzalloc_array(NULL, BITSET_WORD, BITSET_WORDS(num_vars));
   BITSET_WORD *flag_live = rzalloc_array(NULL, BITSET_WORD, 1);

   foreach_block_reverse_safe(block, cfg) {
      memcpy(live, live_intervals->block_data[block->num].liveout,
             sizeof(BITSET_WORD) * BITSET_WORDS(num_vars));
      memcpy(flag_live, live_intervals->block_data[block->num].flag_liveout,
             sizeof(BITSET_WORD));

      foreach_inst_in_block_reverse_safe(fs_inst, inst, block) {
         if (inst->dst.file == VGRF && !inst->has_side_effects()) {
            const unsigned var = live_intervals->var_from_reg(inst->dst);
            bool result_live = false;

            for (unsigned i = 0; i < regs_written(inst); i++)
               result_live |= BITSET_TEST(live, var + i);

            if (!result_live) {
               progress = true;

               if (inst->writes_accumulator || inst->flags_written()) {
                  inst->dst = fs_reg(retype(brw_null_reg(), inst->dst.type));
               } else {
                  inst->opcode = BRW_OPCODE_NOP;
               }
            }
         }

         if (inst->dst.is_null() && inst->flags_written()) {
            if (!(flag_live[0] & inst->flags_written())) {
               inst->opcode = BRW_OPCODE_NOP;
               progress = true;
            }
         }

         if ((inst->opcode != BRW_OPCODE_IF &&
              inst->opcode != BRW_OPCODE_WHILE) &&
             inst->dst.is_null() &&
             !inst->has_side_effects() &&
             !inst->flags_written() &&
             !inst->writes_accumulator) {
            inst->opcode = BRW_OPCODE_NOP;
            progress = true;
         }

         if (inst->dst.file == VGRF) {
            if (!inst->is_partial_write()) {
               int var = live_intervals->var_from_reg(inst->dst);
               for (unsigned i = 0; i < regs_written(inst); i++) {
                  BITSET_CLEAR(live, var + i);
               }
            }
         }

         if (!inst->predicate && inst->exec_size >= 8)
            flag_live[0] &= ~inst->flags_written();

         if (inst->opcode == BRW_OPCODE_NOP) {
            inst->remove(block);
            continue;
         }

         for (int i = 0; i < inst->sources; i++) {
            if (inst->src[i].file == VGRF) {
               int var = live_intervals->var_from_reg(inst->src[i]);

               for (unsigned j = 0; j < regs_read(inst, i); j++) {
                  BITSET_SET(live, var + j);
               }
            }
         }

         flag_live[0] |= inst->flags_read(devinfo);
      }
   }

   ralloc_free(live);
   ralloc_free(flag_live);

   if (progress)
      invalidate_live_intervals();

   return progress;
}
<commit_msg>i965: Make DCE explicitly not eliminate any control flow instructions.<commit_after>/*
 * Copyright © 2014 Intel Corporation
 *
 * 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 (including the next
 * paragraph) 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 "brw_fs.h"
#include "brw_fs_live_variables.h"
#include "brw_cfg.h"

/** @file brw_fs_dead_code_eliminate.cpp
 *
 * Dataflow-aware dead code elimination.
 *
 * Walks the instruction list from the bottom, removing instructions that
 * have results that both aren't used in later blocks and haven't been read
 * yet in the tail end of this block.
 */

bool
fs_visitor::dead_code_eliminate()
{
   bool progress = false;

   calculate_live_intervals();

   int num_vars = live_intervals->num_vars;
   BITSET_WORD *live = rzalloc_array(NULL, BITSET_WORD, BITSET_WORDS(num_vars));
   BITSET_WORD *flag_live = rzalloc_array(NULL, BITSET_WORD, 1);

   foreach_block_reverse_safe(block, cfg) {
      memcpy(live, live_intervals->block_data[block->num].liveout,
             sizeof(BITSET_WORD) * BITSET_WORDS(num_vars));
      memcpy(flag_live, live_intervals->block_data[block->num].flag_liveout,
             sizeof(BITSET_WORD));

      foreach_inst_in_block_reverse_safe(fs_inst, inst, block) {
         if (inst->dst.file == VGRF && !inst->has_side_effects()) {
            const unsigned var = live_intervals->var_from_reg(inst->dst);
            bool result_live = false;

            for (unsigned i = 0; i < regs_written(inst); i++)
               result_live |= BITSET_TEST(live, var + i);

            if (!result_live) {
               progress = true;

               if (inst->writes_accumulator || inst->flags_written()) {
                  inst->dst = fs_reg(retype(brw_null_reg(), inst->dst.type));
               } else {
                  inst->opcode = BRW_OPCODE_NOP;
               }
            }
         }

         if (inst->dst.is_null() && inst->flags_written()) {
            if (!(flag_live[0] & inst->flags_written())) {
               inst->opcode = BRW_OPCODE_NOP;
               progress = true;
            }
         }

         if (inst->dst.is_null() &&
             !inst->is_control_flow() &&
             !inst->has_side_effects() &&
             !inst->flags_written() &&
             !inst->writes_accumulator) {
            inst->opcode = BRW_OPCODE_NOP;
            progress = true;
         }

         if (inst->dst.file == VGRF) {
            if (!inst->is_partial_write()) {
               int var = live_intervals->var_from_reg(inst->dst);
               for (unsigned i = 0; i < regs_written(inst); i++) {
                  BITSET_CLEAR(live, var + i);
               }
            }
         }

         if (!inst->predicate && inst->exec_size >= 8)
            flag_live[0] &= ~inst->flags_written();

         if (inst->opcode == BRW_OPCODE_NOP) {
            inst->remove(block);
            continue;
         }

         for (int i = 0; i < inst->sources; i++) {
            if (inst->src[i].file == VGRF) {
               int var = live_intervals->var_from_reg(inst->src[i]);

               for (unsigned j = 0; j < regs_read(inst, i); j++) {
                  BITSET_SET(live, var + j);
               }
            }
         }

         flag_live[0] |= inst->flags_read(devinfo);
      }
   }

   ralloc_free(live);
   ralloc_free(flag_live);

   if (progress)
      invalidate_live_intervals();

   return progress;
}
<|endoftext|>


<commit_before>#include <gst/gst.h>
#include "MediaPipeline.hpp"
#include <WebRtcEndpointImplFactory.hpp>
#include "WebRtcEndpointImpl.hpp"
#include <jsonrpc/JsonSerializer.hpp>
#include <KurentoException.hpp>
#include <gst/gst.h>
#include <boost/filesystem.hpp>
#include <IceCandidate.hpp>
#include <webrtcendpoint/kmsicecandidate.h>
#include <IceComponentState.hpp>
#include <SignalHandler.hpp>

#define GST_CAT_DEFAULT kurento_web_rtc_endpoint_impl
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
#define GST_DEFAULT_NAME "KurentoWebRtcEndpointImpl"

#define FACTORY_NAME "webrtcendpoint"

namespace kurento
{

static const std::string CERTTOOL_TEMPLATE = "autoCerttool.tmpl";
static const std::string CERT_KEY_PEM_FILE = "autoCertkey.pem";

static const uint DEFAULT_STUN_PORT = 3478;

static std::shared_ptr<std::string> pemCertificate;
std::mutex WebRtcEndpointImpl::certificateMutex;

class TemporalDirectory
{

public:
  ~TemporalDirectory()
  {
    if (!dir.string ().empty() ) {
      boost::filesystem::remove_all (dir);
    }
  }

  void setDir (boost::filesystem::path &dir)
  {
    this->dir = dir;
  }
private:
  boost::filesystem::path dir;
};

static TemporalDirectory tmpDir;

static void
create_pem_certificate ()
{
  int ret;
  boost::filesystem::path temporalDirectory = boost::filesystem::unique_path (
        boost::filesystem::temp_directory_path() / "WebRtcEndpoint_%%%%%%%%" );
  boost::filesystem::create_directories (temporalDirectory);
  tmpDir.setDir (temporalDirectory);

  boost::filesystem::path pemFile = temporalDirectory / CERT_KEY_PEM_FILE;
  std::string pemGenerationCommand =
    "/bin/sh -c \"certtool --generate-privkey --outfile " + pemFile .string()  +
    "\"";

  ret = system (pemGenerationCommand.c_str() );

  if (ret == -1) {
    return;
  }

  boost::filesystem::path templateFile = temporalDirectory / CERTTOOL_TEMPLATE;
  std::string certtoolCommand = "/bin/sh -c \"echo 'organization = kurento' > " +
                                templateFile.string() + " && certtool --generate-self-signed --load-privkey " +
                                pemFile.string() + " --template " + templateFile.string() +  " >> " +
                                pemFile.string() + " 2>/dev/null\"";

  ret = system (certtoolCommand.c_str() );

  if (ret == -1) {
    return;
  }

  pemCertificate = std::shared_ptr <std::string> (new std::string (
                     pemFile.string() ) );
}

std::shared_ptr<std::string>
WebRtcEndpointImpl::getPemCertificate ()
{
  std::unique_lock<std::mutex> lock (certificateMutex);

  if (pemCertificate) {
    return pemCertificate;
  }

  try {
    boost::filesystem::path pem_certificate_file_name (
      getConfigValue<std::string, WebRtcEndpoint> ("pemCertificate") );

    if (pem_certificate_file_name.is_relative() ) {
      pem_certificate_file_name = boost::filesystem::path (
                                    config.get<std::string> ("configPath") ) / pem_certificate_file_name;
    }

    pemCertificate = std::shared_ptr <std::string> (new std::string (
                       pem_certificate_file_name.string() ) );

    return pemCertificate;
  } catch (boost::property_tree::ptree_error &e) {

  }

  create_pem_certificate();

  return pemCertificate;
}

static const std::string supported_codecs[] = {"VP8", "OPUS", "PCMU"};
static const int n_codecs = sizeof (supported_codecs) / sizeof (std::string);

static void
remove_not_supported_codecs_from_pattern (GstElement *element)
{

  GstSDPMessage *old_pattern = NULL, *pattern;
  guint medias_len, i;

  g_object_get (element, "pattern-sdp", &old_pattern, NULL);

  if (old_pattern == NULL) {
    return;
  }

  if (gst_sdp_message_copy (old_pattern, &pattern) != GST_SDP_OK) {
    goto end;
  }

  medias_len = gst_sdp_message_medias_len (pattern);

  for (i = 0; i < medias_len; i ++) {
    const GstSDPMedia *media = gst_sdp_message_get_media (pattern, i);
    guint attributes_len, j, formats_len;

    attributes_len = gst_sdp_media_attributes_len (media);
    std::list <std::string> to_remove_formats;

    for (j = 0; j < attributes_len; j++) {
      const GstSDPAttribute *attribute = gst_sdp_media_get_attribute (media, j);

      if (g_ascii_strcasecmp ("rtpmap", attribute->key) == 0) {
        gchar *rtpmap = g_strstr_len (attribute->value, -1, " ");
        bool supported = false;

        if (rtpmap != NULL) {
          rtpmap = rtpmap + 1;

          for (int k = 0; k < n_codecs; k++) {
            if (g_strstr_len (rtpmap, -1, supported_codecs[k].c_str() ) == rtpmap) {
              supported = true;
              break;
            }
          }
        }

        if (!supported) {
          GST_INFO ("Removing not supported codec from pattern: '%s'", attribute->value);

          * (rtpmap - 1) = '\0';
          to_remove_formats.push_back (std::string (attribute->value) );

          gst_sdp_media_remove_attribute ( (GstSDPMedia *) media, j);
          attributes_len --;
          j--;
        }
      }
    }

    formats_len = gst_sdp_media_formats_len (media);

    for (j = 0; j < formats_len; j++) {
      bool to_remove = false;

      for (std::string format : to_remove_formats) {
        if (format == std::string (gst_sdp_media_get_format (media, j) ) ) {
          to_remove = true;
          break;
        }
      }

      if (to_remove) {
        gst_sdp_media_remove_format ( (GstSDPMedia *) media, j);
        formats_len --;
        j--;
      }
    }
  }

  g_object_set (element, "pattern-sdp", pattern, NULL);

  gst_sdp_message_free (pattern);

end:
  gst_sdp_message_free (old_pattern);
}

void WebRtcEndpointImpl::onIceCandidate (KmsIceCandidate *candidate)
{
  try {
    std::string cand_str (kms_ice_candidate_get_candidate (candidate) );
    std::string mid_str (kms_ice_candidate_get_sdp_mid (candidate) );
    int sdp_m_line_index = kms_ice_candidate_get_sdp_m_line_index (candidate);
    std::shared_ptr <IceCandidate> cand ( new  IceCandidate
                                          (cand_str, mid_str, sdp_m_line_index) );
    OnIceCandidate event (shared_from_this(), OnIceCandidate::getName(), cand);

    signalOnIceCandidate (event);
  } catch (std::bad_weak_ptr &e) {
  }
}

void WebRtcEndpointImpl::onIceGatheringDone ()
{
  try {
    OnIceGatheringDone event (shared_from_this(), OnIceGatheringDone::getName() );

    signalOnIceGatheringDone (event);
  } catch (std::bad_weak_ptr &e) {
  }
}

void WebRtcEndpointImpl::onIceComponentStateChanged (guint streamId,
    guint componentId, guint state)
{
  try {
    IceComponentState::type type;

    switch (state) {
    case NICE_COMPONENT_STATE_DISCONNECTED:
      type = IceComponentState::DISCONNECTED;
      break;

    case NICE_COMPONENT_STATE_GATHERING:
      type = IceComponentState::GATHERING;
      break;

    case NICE_COMPONENT_STATE_CONNECTING:
      type = IceComponentState::CONNECTING;
      break;

    case NICE_COMPONENT_STATE_CONNECTED:
      type = IceComponentState::CONNECTED;
      break;

    case NICE_COMPONENT_STATE_READY:
      type = IceComponentState::READY;
      break;

    case NICE_COMPONENT_STATE_FAILED:
      type = IceComponentState::FAILED;
      break;

    default:
      type = IceComponentState::FAILED;
      break;
    }

    IceComponentState *componentState = new IceComponentState (type);
    OnIceComponentStateChanged event (shared_from_this(),
                                      OnIceComponentStateChanged::getName(),
                                      streamId, componentId,  std::shared_ptr<IceComponentState> (componentState) );

    signalOnIceComponentStateChanged (event);
  } catch (std::bad_weak_ptr &e) {
  }
}

void WebRtcEndpointImpl::postConstructor ()
{
  BaseRtpEndpointImpl::postConstructor ();

  handlerOnIceCandidate = register_signal_handler (G_OBJECT (element),
                          "on-ice-candidate",
                          std::function <void (GstElement *, KmsIceCandidate *) >
                          (std::bind (&WebRtcEndpointImpl::onIceCandidate, this,
                                      std::placeholders::_2) ),
                          std::dynamic_pointer_cast<WebRtcEndpointImpl>
                          (shared_from_this() ) );

  handlerOnIceGatheringDone = register_signal_handler (G_OBJECT (element),
                              "on-ice-gathering-done",
                              std::function <void (GstElement *) >
                              (std::bind (&WebRtcEndpointImpl::onIceGatheringDone, this) ),
                              std::dynamic_pointer_cast<WebRtcEndpointImpl>
                              (shared_from_this() ) );

  handlerOnIceComponentStateChanged = register_signal_handler (G_OBJECT (element),
                                      "on-ice-component-state-changed",
                                      std::function <void (GstElement *, guint, guint, guint) >
                                      (std::bind (&WebRtcEndpointImpl::onIceComponentStateChanged, this,
                                          std::placeholders::_2, std::placeholders::_3, std::placeholders::_4) ),
                                      std::dynamic_pointer_cast<WebRtcEndpointImpl>
                                      (shared_from_this() ) );
}

WebRtcEndpointImpl::WebRtcEndpointImpl (const boost::property_tree::ptree &conf,
                                        std::shared_ptr<MediaPipeline>
                                        mediaPipeline) : BaseRtpEndpointImpl (conf,
                                              std::dynamic_pointer_cast<MediaObjectImpl>
                                              (mediaPipeline), FACTORY_NAME)
{
  uint stunPort;
  std::string stunAddress;
  std::string turnURL;

  remove_not_supported_codecs_from_pattern (element);

  //set properties
  try {
    stunPort = getConfigValue <uint, WebRtcEndpoint> ("stunServerPort");
  } catch (boost::property_tree::ptree_error &e) {
    GST_INFO ("Setting default port %d to stun server",
              DEFAULT_STUN_PORT);
    stunPort = DEFAULT_STUN_PORT;
  }

  if (stunPort != 0) {
    try {
      stunAddress = getConfigValue
                    <std::string, WebRtcEndpoint> ("stunServerAddress");
    } catch (boost::property_tree::ptree_error &e) {
      GST_INFO ("Stun address not found in config, cannot operate behind a NAT" );
    }

    if (!stunAddress.empty() ) {
      GST_INFO ("stun port %d\n", stunPort );
      g_object_set ( G_OBJECT (element), "stun-server-port",
                     stunPort, NULL);

      GST_INFO ("stun address %s\n", stunAddress.c_str() );
      g_object_set ( G_OBJECT (element), "stun-server",
                     stunAddress.c_str(),
                     NULL);
    }
  }

  try {
    turnURL = getConfigValue <std::string, WebRtcEndpoint> ("turnURL");
    GST_INFO ("turn info: %s\n", turnURL.c_str() );
    g_object_set ( G_OBJECT (element), "turn-url", turnURL.c_str(),
                   NULL);
  } catch (boost::property_tree::ptree_error &e) {

  }

  g_object_set ( G_OBJECT (element), "certificate-pem-file",
                 getPemCertificate ()->c_str(), NULL);
}

WebRtcEndpointImpl::~WebRtcEndpointImpl()
{
  if (handlerOnIceCandidate > 0) {
    unregister_signal_handler (element, handlerOnIceCandidate);
  }

  if (handlerOnIceGatheringDone > 0) {
    unregister_signal_handler (element, handlerOnIceGatheringDone);
  }

  if (handlerOnIceComponentStateChanged > 0) {
    unregister_signal_handler (element, handlerOnIceComponentStateChanged);
  }
}

std::string
WebRtcEndpointImpl::getStunServerAddress ()
{
  gchar *ret;

  g_object_get ( G_OBJECT (element), "stun-server", &ret, NULL);

  std::string stunServerAddress (ret);
  g_free (ret);

  return stunServerAddress;
}

void
WebRtcEndpointImpl::setStunServerAddress (const std::string &stunServerAddress)
{
  g_object_set ( G_OBJECT (element), "stun-server",
                 stunServerAddress.c_str(),
                 NULL);
}

int
WebRtcEndpointImpl::getStunServerPort ()
{
  int ret;

  g_object_get ( G_OBJECT (element), "stun-server-port", &ret, NULL);

  return ret;
}

void
WebRtcEndpointImpl::setStunServerPort (int stunServerPort)
{
  g_object_set ( G_OBJECT (element), "stun-server-port",
                 stunServerPort, NULL);
}

std::string
WebRtcEndpointImpl::getTurnUrl ()
{
  gchar *ret;

  g_object_get ( G_OBJECT (element), "turn-url", &ret, NULL);

  std::string turnUrl (ret);
  g_free (ret);

  return turnUrl;
}

void
WebRtcEndpointImpl::setTurnUrl (const std::string &turnUrl)
{
  g_object_set ( G_OBJECT (element), "turn-url",
                 turnUrl.c_str(),
                 NULL);
}

void
WebRtcEndpointImpl::gatherCandidates ()
{
  gboolean ret;

  g_signal_emit_by_name (element, "gather-candidates", &ret);

  if (!ret) {
    throw KurentoException (ICE_GATHER_CANDIDATES_ERROR,
                            "Error gathering candidates");
  }
}

void
WebRtcEndpointImpl::addIceCandidate (std::shared_ptr<IceCandidate> candidate)
{
  gboolean ret;
  const char *cand_str = candidate->getCandidate().c_str ();
  const char *mid_str = candidate->getSdpMid().c_str ();
  guint8 sdp_m_line_index = candidate->getSdpMLineIndex ();
  KmsIceCandidate *cand = kms_ice_candidate_new (cand_str, mid_str,
                          sdp_m_line_index);

  g_signal_emit_by_name (element, "add-ice-candidate", cand, &ret);

  if (!ret) {
    throw KurentoException (ICE_ADD_CANDIDATE_ERROR, "Error adding candidate");
  }
}

MediaObjectImpl *
WebRtcEndpointImplFactory::createObject (const boost::property_tree::ptree
    &conf, std::shared_ptr<MediaPipeline>
    mediaPipeline) const
{
  return new WebRtcEndpointImpl (conf, mediaPipeline);
}

WebRtcEndpointImpl::StaticConstructor WebRtcEndpointImpl::staticConstructor;

WebRtcEndpointImpl::StaticConstructor::StaticConstructor()
{
  GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, GST_DEFAULT_NAME, 0,
                           GST_DEFAULT_NAME);
}

} /* kurento */
<commit_msg>WebRtcEndpoint: Fix memory leak while adding ice candidates<commit_after>#include <gst/gst.h>
#include "MediaPipeline.hpp"
#include <WebRtcEndpointImplFactory.hpp>
#include "WebRtcEndpointImpl.hpp"
#include <jsonrpc/JsonSerializer.hpp>
#include <KurentoException.hpp>
#include <gst/gst.h>
#include <boost/filesystem.hpp>
#include <IceCandidate.hpp>
#include <webrtcendpoint/kmsicecandidate.h>
#include <IceComponentState.hpp>
#include <SignalHandler.hpp>

#define GST_CAT_DEFAULT kurento_web_rtc_endpoint_impl
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
#define GST_DEFAULT_NAME "KurentoWebRtcEndpointImpl"

#define FACTORY_NAME "webrtcendpoint"

namespace kurento
{

static const std::string CERTTOOL_TEMPLATE = "autoCerttool.tmpl";
static const std::string CERT_KEY_PEM_FILE = "autoCertkey.pem";

static const uint DEFAULT_STUN_PORT = 3478;

static std::shared_ptr<std::string> pemCertificate;
std::mutex WebRtcEndpointImpl::certificateMutex;

class TemporalDirectory
{

public:
  ~TemporalDirectory()
  {
    if (!dir.string ().empty() ) {
      boost::filesystem::remove_all (dir);
    }
  }

  void setDir (boost::filesystem::path &dir)
  {
    this->dir = dir;
  }
private:
  boost::filesystem::path dir;
};

static TemporalDirectory tmpDir;

static void
create_pem_certificate ()
{
  int ret;
  boost::filesystem::path temporalDirectory = boost::filesystem::unique_path (
        boost::filesystem::temp_directory_path() / "WebRtcEndpoint_%%%%%%%%" );
  boost::filesystem::create_directories (temporalDirectory);
  tmpDir.setDir (temporalDirectory);

  boost::filesystem::path pemFile = temporalDirectory / CERT_KEY_PEM_FILE;
  std::string pemGenerationCommand =
    "/bin/sh -c \"certtool --generate-privkey --outfile " + pemFile .string()  +
    "\"";

  ret = system (pemGenerationCommand.c_str() );

  if (ret == -1) {
    return;
  }

  boost::filesystem::path templateFile = temporalDirectory / CERTTOOL_TEMPLATE;
  std::string certtoolCommand = "/bin/sh -c \"echo 'organization = kurento' > " +
                                templateFile.string() + " && certtool --generate-self-signed --load-privkey " +
                                pemFile.string() + " --template " + templateFile.string() +  " >> " +
                                pemFile.string() + " 2>/dev/null\"";

  ret = system (certtoolCommand.c_str() );

  if (ret == -1) {
    return;
  }

  pemCertificate = std::shared_ptr <std::string> (new std::string (
                     pemFile.string() ) );
}

std::shared_ptr<std::string>
WebRtcEndpointImpl::getPemCertificate ()
{
  std::unique_lock<std::mutex> lock (certificateMutex);

  if (pemCertificate) {
    return pemCertificate;
  }

  try {
    boost::filesystem::path pem_certificate_file_name (
      getConfigValue<std::string, WebRtcEndpoint> ("pemCertificate") );

    if (pem_certificate_file_name.is_relative() ) {
      pem_certificate_file_name = boost::filesystem::path (
                                    config.get<std::string> ("configPath") ) / pem_certificate_file_name;
    }

    pemCertificate = std::shared_ptr <std::string> (new std::string (
                       pem_certificate_file_name.string() ) );

    return pemCertificate;
  } catch (boost::property_tree::ptree_error &e) {

  }

  create_pem_certificate();

  return pemCertificate;
}

static const std::string supported_codecs[] = {"VP8", "OPUS", "PCMU"};
static const int n_codecs = sizeof (supported_codecs) / sizeof (std::string);

static void
remove_not_supported_codecs_from_pattern (GstElement *element)
{

  GstSDPMessage *old_pattern = NULL, *pattern;
  guint medias_len, i;

  g_object_get (element, "pattern-sdp", &old_pattern, NULL);

  if (old_pattern == NULL) {
    return;
  }

  if (gst_sdp_message_copy (old_pattern, &pattern) != GST_SDP_OK) {
    goto end;
  }

  medias_len = gst_sdp_message_medias_len (pattern);

  for (i = 0; i < medias_len; i ++) {
    const GstSDPMedia *media = gst_sdp_message_get_media (pattern, i);
    guint attributes_len, j, formats_len;

    attributes_len = gst_sdp_media_attributes_len (media);
    std::list <std::string> to_remove_formats;

    for (j = 0; j < attributes_len; j++) {
      const GstSDPAttribute *attribute = gst_sdp_media_get_attribute (media, j);

      if (g_ascii_strcasecmp ("rtpmap", attribute->key) == 0) {
        gchar *rtpmap = g_strstr_len (attribute->value, -1, " ");
        bool supported = false;

        if (rtpmap != NULL) {
          rtpmap = rtpmap + 1;

          for (int k = 0; k < n_codecs; k++) {
            if (g_strstr_len (rtpmap, -1, supported_codecs[k].c_str() ) == rtpmap) {
              supported = true;
              break;
            }
          }
        }

        if (!supported) {
          GST_INFO ("Removing not supported codec from pattern: '%s'", attribute->value);

          * (rtpmap - 1) = '\0';
          to_remove_formats.push_back (std::string (attribute->value) );

          gst_sdp_media_remove_attribute ( (GstSDPMedia *) media, j);
          attributes_len --;
          j--;
        }
      }
    }

    formats_len = gst_sdp_media_formats_len (media);

    for (j = 0; j < formats_len; j++) {
      bool to_remove = false;

      for (std::string format : to_remove_formats) {
        if (format == std::string (gst_sdp_media_get_format (media, j) ) ) {
          to_remove = true;
          break;
        }
      }

      if (to_remove) {
        gst_sdp_media_remove_format ( (GstSDPMedia *) media, j);
        formats_len --;
        j--;
      }
    }
  }

  g_object_set (element, "pattern-sdp", pattern, NULL);

  gst_sdp_message_free (pattern);

end:
  gst_sdp_message_free (old_pattern);
}

void WebRtcEndpointImpl::onIceCandidate (KmsIceCandidate *candidate)
{
  try {
    std::string cand_str (kms_ice_candidate_get_candidate (candidate) );
    std::string mid_str (kms_ice_candidate_get_sdp_mid (candidate) );
    int sdp_m_line_index = kms_ice_candidate_get_sdp_m_line_index (candidate);
    std::shared_ptr <IceCandidate> cand ( new  IceCandidate
                                          (cand_str, mid_str, sdp_m_line_index) );
    OnIceCandidate event (shared_from_this(), OnIceCandidate::getName(), cand);

    signalOnIceCandidate (event);
  } catch (std::bad_weak_ptr &e) {
  }
}

void WebRtcEndpointImpl::onIceGatheringDone ()
{
  try {
    OnIceGatheringDone event (shared_from_this(), OnIceGatheringDone::getName() );

    signalOnIceGatheringDone (event);
  } catch (std::bad_weak_ptr &e) {
  }
}

void WebRtcEndpointImpl::onIceComponentStateChanged (guint streamId,
    guint componentId, guint state)
{
  try {
    IceComponentState::type type;

    switch (state) {
    case NICE_COMPONENT_STATE_DISCONNECTED:
      type = IceComponentState::DISCONNECTED;
      break;

    case NICE_COMPONENT_STATE_GATHERING:
      type = IceComponentState::GATHERING;
      break;

    case NICE_COMPONENT_STATE_CONNECTING:
      type = IceComponentState::CONNECTING;
      break;

    case NICE_COMPONENT_STATE_CONNECTED:
      type = IceComponentState::CONNECTED;
      break;

    case NICE_COMPONENT_STATE_READY:
      type = IceComponentState::READY;
      break;

    case NICE_COMPONENT_STATE_FAILED:
      type = IceComponentState::FAILED;
      break;

    default:
      type = IceComponentState::FAILED;
      break;
    }

    IceComponentState *componentState = new IceComponentState (type);
    OnIceComponentStateChanged event (shared_from_this(),
                                      OnIceComponentStateChanged::getName(),
                                      streamId, componentId,  std::shared_ptr<IceComponentState> (componentState) );

    signalOnIceComponentStateChanged (event);
  } catch (std::bad_weak_ptr &e) {
  }
}

void WebRtcEndpointImpl::postConstructor ()
{
  BaseRtpEndpointImpl::postConstructor ();

  handlerOnIceCandidate = register_signal_handler (G_OBJECT (element),
                          "on-ice-candidate",
                          std::function <void (GstElement *, KmsIceCandidate *) >
                          (std::bind (&WebRtcEndpointImpl::onIceCandidate, this,
                                      std::placeholders::_2) ),
                          std::dynamic_pointer_cast<WebRtcEndpointImpl>
                          (shared_from_this() ) );

  handlerOnIceGatheringDone = register_signal_handler (G_OBJECT (element),
                              "on-ice-gathering-done",
                              std::function <void (GstElement *) >
                              (std::bind (&WebRtcEndpointImpl::onIceGatheringDone, this) ),
                              std::dynamic_pointer_cast<WebRtcEndpointImpl>
                              (shared_from_this() ) );

  handlerOnIceComponentStateChanged = register_signal_handler (G_OBJECT (element),
                                      "on-ice-component-state-changed",
                                      std::function <void (GstElement *, guint, guint, guint) >
                                      (std::bind (&WebRtcEndpointImpl::onIceComponentStateChanged, this,
                                          std::placeholders::_2, std::placeholders::_3, std::placeholders::_4) ),
                                      std::dynamic_pointer_cast<WebRtcEndpointImpl>
                                      (shared_from_this() ) );
}

WebRtcEndpointImpl::WebRtcEndpointImpl (const boost::property_tree::ptree &conf,
                                        std::shared_ptr<MediaPipeline>
                                        mediaPipeline) : BaseRtpEndpointImpl (conf,
                                              std::dynamic_pointer_cast<MediaObjectImpl>
                                              (mediaPipeline), FACTORY_NAME)
{
  uint stunPort;
  std::string stunAddress;
  std::string turnURL;

  remove_not_supported_codecs_from_pattern (element);

  //set properties
  try {
    stunPort = getConfigValue <uint, WebRtcEndpoint> ("stunServerPort");
  } catch (boost::property_tree::ptree_error &e) {
    GST_INFO ("Setting default port %d to stun server",
              DEFAULT_STUN_PORT);
    stunPort = DEFAULT_STUN_PORT;
  }

  if (stunPort != 0) {
    try {
      stunAddress = getConfigValue
                    <std::string, WebRtcEndpoint> ("stunServerAddress");
    } catch (boost::property_tree::ptree_error &e) {
      GST_INFO ("Stun address not found in config, cannot operate behind a NAT" );
    }

    if (!stunAddress.empty() ) {
      GST_INFO ("stun port %d\n", stunPort );
      g_object_set ( G_OBJECT (element), "stun-server-port",
                     stunPort, NULL);

      GST_INFO ("stun address %s\n", stunAddress.c_str() );
      g_object_set ( G_OBJECT (element), "stun-server",
                     stunAddress.c_str(),
                     NULL);
    }
  }

  try {
    turnURL = getConfigValue <std::string, WebRtcEndpoint> ("turnURL");
    GST_INFO ("turn info: %s\n", turnURL.c_str() );
    g_object_set ( G_OBJECT (element), "turn-url", turnURL.c_str(),
                   NULL);
  } catch (boost::property_tree::ptree_error &e) {

  }

  g_object_set ( G_OBJECT (element), "certificate-pem-file",
                 getPemCertificate ()->c_str(), NULL);
}

WebRtcEndpointImpl::~WebRtcEndpointImpl()
{
  if (handlerOnIceCandidate > 0) {
    unregister_signal_handler (element, handlerOnIceCandidate);
  }

  if (handlerOnIceGatheringDone > 0) {
    unregister_signal_handler (element, handlerOnIceGatheringDone);
  }

  if (handlerOnIceComponentStateChanged > 0) {
    unregister_signal_handler (element, handlerOnIceComponentStateChanged);
  }
}

std::string
WebRtcEndpointImpl::getStunServerAddress ()
{
  gchar *ret;

  g_object_get ( G_OBJECT (element), "stun-server", &ret, NULL);

  std::string stunServerAddress (ret);
  g_free (ret);

  return stunServerAddress;
}

void
WebRtcEndpointImpl::setStunServerAddress (const std::string &stunServerAddress)
{
  g_object_set ( G_OBJECT (element), "stun-server",
                 stunServerAddress.c_str(),
                 NULL);
}

int
WebRtcEndpointImpl::getStunServerPort ()
{
  int ret;

  g_object_get ( G_OBJECT (element), "stun-server-port", &ret, NULL);

  return ret;
}

void
WebRtcEndpointImpl::setStunServerPort (int stunServerPort)
{
  g_object_set ( G_OBJECT (element), "stun-server-port",
                 stunServerPort, NULL);
}

std::string
WebRtcEndpointImpl::getTurnUrl ()
{
  gchar *ret;

  g_object_get ( G_OBJECT (element), "turn-url", &ret, NULL);

  std::string turnUrl (ret);
  g_free (ret);

  return turnUrl;
}

void
WebRtcEndpointImpl::setTurnUrl (const std::string &turnUrl)
{
  g_object_set ( G_OBJECT (element), "turn-url",
                 turnUrl.c_str(),
                 NULL);
}

void
WebRtcEndpointImpl::gatherCandidates ()
{
  gboolean ret;

  g_signal_emit_by_name (element, "gather-candidates", &ret);

  if (!ret) {
    throw KurentoException (ICE_GATHER_CANDIDATES_ERROR,
                            "Error gathering candidates");
  }
}

void
WebRtcEndpointImpl::addIceCandidate (std::shared_ptr<IceCandidate> candidate)
{
  gboolean ret;
  const char *cand_str = candidate->getCandidate().c_str ();
  const char *mid_str = candidate->getSdpMid().c_str ();
  guint8 sdp_m_line_index = candidate->getSdpMLineIndex ();
  KmsIceCandidate *cand = kms_ice_candidate_new (cand_str, mid_str,
                          sdp_m_line_index);

  g_signal_emit_by_name (element, "add-ice-candidate", cand, &ret);

  g_object_unref (cand);

  if (!ret) {
    throw KurentoException (ICE_ADD_CANDIDATE_ERROR, "Error adding candidate");
  }
}

MediaObjectImpl *
WebRtcEndpointImplFactory::createObject (const boost::property_tree::ptree
    &conf, std::shared_ptr<MediaPipeline>
    mediaPipeline) const
{
  return new WebRtcEndpointImpl (conf, mediaPipeline);
}

WebRtcEndpointImpl::StaticConstructor WebRtcEndpointImpl::staticConstructor;

WebRtcEndpointImpl::StaticConstructor::StaticConstructor()
{
  GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, GST_DEFAULT_NAME, 0,
                           GST_DEFAULT_NAME);
}

} /* kurento */
<|endoftext|>


<commit_before><commit_msg>IVGCVSW-1929: Optimize function signature change<commit_after><|endoftext|>


<commit_before>#include "DataTreatment.h"

//Empty constructor
DataTreatment::DataTreatment() {
    m_myFileName = "";
    m_myProfileName = "";
    m_numberOfFriends = 0;
    m_peopleList = 0;
}//End class' empty constructor

//Class constructor
DataTreatment::DataTreatment(QString myFileName,
                             QString myProfileName,
                             int numberOfFriends)
{
    m_myFileName = myFileName;
    m_myProfileName = myProfileName;
    m_numberOfFriends = numberOfFriends;
    m_peopleList = new Person[m_numberOfFriends];
    readData();
}//End class' non-empty-constructor

DataTreatment::~DataTreatment() {
    delete m_friendsRelationListFile;
    delete [] m_peopleList;
}//End class' destructor

void DataTreatment::readData() {
    //Reading the entry file
    QFile dataEntry(m_myFileName);
    dataEntry.open(QIODevice::ReadOnly);

    //Checking if the file has been opened
    if(!dataEntry.isOpen()) {
        qDebug().quote() << dataEntry.fileName()
                         << "File Not Opened";
    }

    //Create friends relations file
    m_friendsRelationListFile = new QFile("FriendsRelations.txt");
    m_friendsRelationListFile->open(QIODevice::WriteOnly);

    QString line, personName1, personName2;

    int personAndLineCounter = 0;

    while(personAndLineCounter != m_numberOfFriends) {
        //Get file line
        line = dataEntry.readLine(1024);

        //Extract the first name in the string
        personName1 = line.section('"', 1, 1);

        //Extract the second name in the string
        personName2 = line.section('"', 3, 3);

        //Insert the friend's name in the friend
        //list
        personName1 != m_myProfileName ?
                    m_peopleList[personAndLineCounter].setPersonName(personName1):
                    m_peopleList[personAndLineCounter].setPersonName(personName2);
        m_peopleList[personAndLineCounter].setPersonalID(personAndLineCounter);

        personAndLineCounter++;

        //Copy the related friends to
        //the friends relation file
        if(personAndLineCounter == m_numberOfFriends) {
            while(!dataEntry.atEnd()) {
                QByteArray getData = dataEntry.read(8000);
                m_friendsRelationListFile->write(getData);
            }//End loop while
        }//End condition if
    }//End loop while
    m_friendsRelationListFile->close();
}//End method readData

void DataTreatment::setRelations() {
    //Open file
    m_friendsRelationListFile->open(QIODevice::ReadOnly);

    //Checking if the file was
    //Correctly opened
    if(!m_friendsRelationListFile->isOpen()) {
        qDebug().noquote() << m_friendsRelationListFile->fileName()
                           << "file has not been opened";
    }

    QString line, personName1, personName2, lastPersonChecked;
    int unknownPerson1, unknownPerson2;

    //Empty string
    lastPersonChecked = "";

    while(!m_friendsRelationListFile->atEnd()) {
        line = m_friendsRelationListFile->readLine(1024);
        personName1 = line.section('"', 1, 1);
        personName2 = line.section('"', 3, 3);

        //Condition to make sure that persons
        //with same name will not be
        //double checked
        if(lastPersonChecked != "") {
            if(lastPersonChecked != personName1) {
                for(int i = 0; i < m_numberOfFriends; i++) {
                    if(m_peopleList[i].name() == lastPersonChecked) {
                        m_peopleList[i].setVerification(true);
                    }//End condition if
                }//End loop for
            }//End condition if
        }//End condition if

        //Get current person being checked
        lastPersonChecked = personName1;

        //Get persons index
        for(int i = 0; i < m_numberOfFriends; i++) {
            //Person 1 index
            if(personName1 == m_peopleList[i].name()
                    && !m_peopleList[i].isVerified()) {
                unknownPerson1 = m_peopleList[i].personalID();
            }

            //Person2 index
            if(personName2 == m_peopleList[i].name()) {
                unknownPerson2 = m_peopleList[i].personalID();
            }//End condition if
        }//End loop for

        //Person1 is related with person2
        m_peopleList[unknownPerson1].setFriend(unknownPerson2);
        m_peopleList[unknownPerson2].setFriend(unknownPerson1);
    }//End loop while
}//End method setRelations

void DataTreatment::toMatrix() {
    QFile matrixFile("FaceBookMatrix.txt");
    matrixFile.open(QIODevice::WriteOnly);

    if(!matrixFile.isOpen()) {
        qDebug().noquote() << matrixFile.fileName()
                           << "file has not been opened";
    }//End condition if

    int currentPerson = 1;
    QByteArray matrixRepresentation;

    while(currentPerson <= m_numberOfFriends) {
        for(int relatedPerson = 1; relatedPerson <= m_numberOfFriends;
            relatedPerson++) {
            for(int column = 1; column <= 3; column++) {
                if(column == 1) {
                    matrixRepresentation
                            .append(QString::number(currentPerson));
                    matrixRepresentation.append(' ');
                }
                else if(column == 2) {
                    matrixRepresentation
                            .append(QString::number(relatedPerson));
                    matrixRepresentation.append(' ');
                }
                else if(column == 3) {
                    if(currentPerson == relatedPerson) {
                        matrixRepresentation.append('1');
                        matrixRepresentation.append("\n");
                    }
                    else if(m_peopleList[currentPerson - 1]
                            .isFriendWith(relatedPerson - 1)) {
                        matrixRepresentation.append('1');
                        matrixRepresentation.append("\n");
                    }
                    else {
                        matrixRepresentation.append('0');
                        matrixRepresentation.append("\n");
                    }
                }//End condition else
            }//End loop column
        }//End loop relatedPerson
        matrixFile.write(matrixRepresentation);
        matrixFile.write("\n");
        matrixRepresentation.clear();
        currentPerson++;
    }//End loop currentPerson
    matrixFile.close();
}//End method toMatrix

void DataTreatment::friendList() {
    QFile friendList("FriendList.txt");
    friendList.open(QIODevice::WriteOnly);
    if(!friendList.isOpen()) {
        qDebug().noquote() << friendList.fileName()
                           << "file has not been opened";

    }
    QByteArray toFile;
    for(int i = 0; i < m_numberOfFriends; i++) {
        toFile.append(QString::number(m_peopleList[i].personalID() + 1) + " - ");
        toFile.append(m_peopleList[i].name());
        toFile.append('\n');
    }
    friendList.write(toFile);
    friendList.write("\n");
}
<commit_msg>minor friendList function fix<commit_after>#include "DataTreatment.h"

//Empty constructor
DataTreatment::DataTreatment() {
    m_myFileName = "";
    m_myProfileName = "";
    m_numberOfFriends = 0;
    m_peopleList = 0;
}//End class' empty constructor

//Class constructor
DataTreatment::DataTreatment(QString myFileName,
                             QString myProfileName,
                             int numberOfFriends)
{
    m_myFileName = myFileName;
    m_myProfileName = myProfileName;
    m_numberOfFriends = numberOfFriends;
    m_peopleList = new Person[m_numberOfFriends];
    readData();
}//End class' non-empty-constructor

DataTreatment::~DataTreatment() {
    delete m_friendsRelationListFile;
    delete [] m_peopleList;
}//End class' destructor

void DataTreatment::readData() {
    //Reading the entry file
    QFile dataEntry(m_myFileName);
    dataEntry.open(QIODevice::ReadOnly);

    //Checking if the file has been opened
    if(!dataEntry.isOpen()) {
        qDebug().quote() << dataEntry.fileName()
                         << "File Not Opened";
    }

    //Create friends relations file
    m_friendsRelationListFile = new QFile("FriendsRelations.txt");
    m_friendsRelationListFile->open(QIODevice::WriteOnly);

    QString line, personName1, personName2;

    int personAndLineCounter = 0;

    while(personAndLineCounter != m_numberOfFriends) {
        //Get file line
        line = dataEntry.readLine(1024);

        //Extract the first name in the string
        personName1 = line.section('"', 1, 1);

        //Extract the second name in the string
        personName2 = line.section('"', 3, 3);

        //Insert the friend's name in the friend
        //list
        personName1 != m_myProfileName ?
                    m_peopleList[personAndLineCounter].setPersonName(personName1):
                    m_peopleList[personAndLineCounter].setPersonName(personName2);
        m_peopleList[personAndLineCounter].setPersonalID(personAndLineCounter);

        personAndLineCounter++;

        //Copy the related friends to
        //the friends relation file
        if(personAndLineCounter == m_numberOfFriends) {
            while(!dataEntry.atEnd()) {
                QByteArray getData = dataEntry.read(8000);
                m_friendsRelationListFile->write(getData);
            }//End loop while
        }//End condition if
    }//End loop while
    m_friendsRelationListFile->close();
}//End method readData

void DataTreatment::setRelations() {
    //Open file
    m_friendsRelationListFile->open(QIODevice::ReadOnly);

    //Checking if the file was
    //Correctly opened
    if(!m_friendsRelationListFile->isOpen()) {
        qDebug().noquote() << m_friendsRelationListFile->fileName()
                           << "file has not been opened";
    }

    QString line, personName1, personName2, lastPersonChecked;
    int unknownPerson1, unknownPerson2;

    //Empty string
    lastPersonChecked = "";

    while(!m_friendsRelationListFile->atEnd()) {
        line = m_friendsRelationListFile->readLine(1024);
        personName1 = line.section('"', 1, 1);
        personName2 = line.section('"', 3, 3);

        //Condition to make sure that persons
        //with same name will not be
        //double checked
        if(lastPersonChecked != "") {
            if(lastPersonChecked != personName1) {
                for(int i = 0; i < m_numberOfFriends; i++) {
                    if(m_peopleList[i].name() == lastPersonChecked) {
                        m_peopleList[i].setVerification(true);
                    }//End condition if
                }//End loop for
            }//End condition if
        }//End condition if

        //Get current person being checked
        lastPersonChecked = personName1;

        //Get persons index
        for(int i = 0; i < m_numberOfFriends; i++) {
            //Person 1 index
            if(personName1 == m_peopleList[i].name()
                    && !m_peopleList[i].isVerified()) {
                unknownPerson1 = m_peopleList[i].personalID();
            }

            //Person2 index
            if(personName2 == m_peopleList[i].name()) {
                unknownPerson2 = m_peopleList[i].personalID();
            }//End condition if
        }//End loop for

        //Person1 is related with person2
        m_peopleList[unknownPerson1].setFriend(unknownPerson2);
        m_peopleList[unknownPerson2].setFriend(unknownPerson1);
    }//End loop while
}//End method setRelations

void DataTreatment::toMatrix() {
    QFile matrixFile("FaceBookMatrix.txt");
    matrixFile.open(QIODevice::WriteOnly);

    if(!matrixFile.isOpen()) {
        qDebug().noquote() << matrixFile.fileName()
                           << "file has not been opened";
    }//End condition if

    int currentPerson = 1;
    QByteArray matrixRepresentation;

    while(currentPerson <= m_numberOfFriends) {
        for(int relatedPerson = 1; relatedPerson <= m_numberOfFriends;
            relatedPerson++) {
            for(int column = 1; column <= 3; column++) {
                if(column == 1) {
                    matrixRepresentation
                            .append(QString::number(currentPerson));
                    matrixRepresentation.append(' ');
                }
                else if(column == 2) {
                    matrixRepresentation
                            .append(QString::number(relatedPerson));
                    matrixRepresentation.append(' ');
                }
                else if(column == 3) {
                    if(currentPerson == relatedPerson) {
                        matrixRepresentation.append('1');
                        matrixRepresentation.append("\n");
                    }
                    else if(m_peopleList[currentPerson - 1]
                            .isFriendWith(relatedPerson - 1)) {
                        matrixRepresentation.append('1');
                        matrixRepresentation.append("\n");
                    }
                    else {
                        matrixRepresentation.append('0');
                        matrixRepresentation.append("\n");
                    }
                }//End condition else
            }//End loop column
        }//End loop relatedPerson
        matrixFile.write(matrixRepresentation);
        matrixFile.write("\n");
        matrixRepresentation.clear();
        currentPerson++;
    }//End loop currentPerson
    matrixFile.close();
}//End method toMatrix

void DataTreatment::friendList() {
    QFile friendList("FriendList.txt");
    friendList.open(QIODevice::WriteOnly);
    if(!friendList.isOpen()) {
        qDebug().noquote() << friendList.fileName()
                           << "file has not been opened";

    }
    QByteArray toFile;
    for(int i = 0; i < m_numberOfFriends; i++) {
        toFile.append(QString::number(m_peopleList[i].personalID() + 1) + " - ");
        toFile.append(m_peopleList[i].name());
        toFile.append('\n');
    }
    friendList.write(toFile);
    friendList.close();
}
<|endoftext|>