<commit_before>#pragma once

#include "../std/algorithm.hpp"
#include "../std/vector.hpp"
#include "../base/assert.hpp"
#include "../base/swap.hpp"

template <class T, size_t N> class buffer_vector
{
private:
  enum { USE_DYNAMIC = N + 1 };
  T m_static[N];
  size_t m_size;
  vector<T> m_dynamic;

public:
  typedef T value_type;
  typedef T const & const_reference;
  typedef T & reference;

  buffer_vector() : m_size(0) {}
  explicit buffer_vector(size_t n, T c = T()) : m_size(0)
  {
    resize(n, c);
  }

  void reserve(size_t n)
  {
    if (m_size == USE_DYNAMIC || n > N)
      m_dynamic.reserve(n);
  }

  void resize(size_t n, T c = T())
  {
    if (m_size == USE_DYNAMIC)
      m_dynamic.resize(n);
    else
    {
      if (n <= N)
      {
        for (size_t i = m_size; i < n; ++i)
          m_static[i] = c;
        m_size = n;
      }
      else
      {
        m_dynamic.reserve(n);
        size_t const oldSize = m_size;
        SwitchToDynamic();
        m_dynamic.insert(m_dynamic.end(), n - oldSize, c);
        ASSERT_EQUAL(m_dynamic.size(), n, ());
      }
    }
  }

  void clear()
  {
    if (m_size == USE_DYNAMIC)
      m_dynamic.clear();
    else
      m_size = 0;
  }

  T const * data() const { return m_size == USE_DYNAMIC ? &m_dynamic[0] : &m_static[0]; }
  T       * data()       { return m_size == USE_DYNAMIC ? &m_dynamic[0] : &m_static[0]; }

  T const * begin() const { return data(); }
  T       * begin()       { return data(); }
  T const * end() const { return data() + size(); }
  T       * end()       { return data() + size(); }

  bool empty() const { return m_size == USE_DYNAMIC ? m_dynamic.empty() : m_size == 0; }
  size_t size() const { return m_size == USE_DYNAMIC ? m_dynamic.size() : m_size; }

  T const & front() const
  {
    ASSERT(!empty(), ());
    return *begin();
  }
  T & front()
  {
    ASSERT(!empty(), ());
    return *begin();
  }
  T const & back() const
  {
    ASSERT(!empty(), ());
    return *(end() - 1);
  }
  T & back()
  {
    ASSERT(!empty(), ());
    return *(end() - 1);
  }

  T const & operator[](size_t i) const
  {
    ASSERT_LESS(i, size(), ());
    return *(begin() + i);
  }
  T & operator[](size_t i)
  {
    ASSERT_LESS(i, size(), ());
    return *(begin() + i);
  }

  void swap(buffer_vector<T, N> & rhs)
  {
    m_dynamic.swap(rhs.m_dynamic);
    Swap(m_size, rhs.m_size);
    for (size_t i = 0; i < N; ++i)
      Swap(m_static[i], rhs.m_static[i]);
  }

  void push_back(T const & t)
  {
    if (m_size == USE_DYNAMIC)
      m_dynamic.push_back(t);
    else
    {
      if (m_size < N)
        m_static[m_size++] = t;
      else
      {
        ASSERT_EQUAL(m_size, N, ());
        m_dynamic.reserve(N + 1);
        SwitchToDynamic();
        m_dynamic.push_back(t);
        ASSERT_EQUAL(m_dynamic.size(), N + 1, ());
      }
    }
  }

  void pop_back()
  {
    if (m_size == USE_DYNAMIC)
      m_dynamic.pop_back();
    else
    {
      ASSERT_GREATER(m_size, 0, ());
      --m_size;
    }
  }

  template <typename IterT> void insert(T const * where, IterT beg, IterT end)
  {
    ptrdiff_t const pos = where - data();
    ASSERT_GREATER_OR_EQUAL(pos, 0, ());
    ASSERT_LESS_OR_EQUAL(pos, size(), ());
    if (m_size == USE_DYNAMIC)
      m_dynamic.insert(m_dynamic.begin() + pos, beg, end);
    else
    {
      size_t const n = end - beg;
      if (m_size + n <= N)
      {
        if (pos != m_size)
          for (ptrdiff_t i = m_size - 1; i >= pos; --i)
            Swap(m_static[i], m_static[i + n]);

        m_size += n;
        T * writableWhere = &m_static[0] + pos;
        ASSERT_EQUAL(where, writableWhere, ());
        while (beg != end)
          *(writableWhere++) = *(beg++);
      }
      else
      {
        m_dynamic.reserve(m_size + n);
        SwitchToDynamic();
        m_dynamic.insert(m_dynamic.begin() + pos, beg, end);
        ASSERT_EQUAL(m_dynamic.size(), m_dynamic.capacity(), ());
      }
    }
  }

private:
  void SwitchToDynamic()
  {
    ASSERT_NOT_EQUAL(m_size, USE_DYNAMIC, ());
    ASSERT_EQUAL(m_dynamic.size(), 0, ());
    m_dynamic.insert(m_dynamic.end(), m_size, T());
    for (size_t i = 0; i < m_size; ++i)
      Swap(m_static[i], m_dynamic[i]);
    m_size = USE_DYNAMIC;
  }
};

template <class T, size_t N>
void swap(buffer_vector<T, N> & r1, buffer_vector<T, N> & r2) { r1.swap(r2); }

template <typename T, size_t N>
inline string debug_print(buffer_vector<T, N> const & v)
{
  return ::my::impl::DebugPrintSequence(v.data(), v.data() + v.size());
}
<commit_msg>Almost no-op, fix compilation issue.<commit_after>#pragma once

#include "../std/algorithm.hpp"
#include "../std/vector.hpp"
#include "../base/assert.hpp"
#include "../base/swap.hpp"

template <class T, size_t N> class buffer_vector
{
private:
  enum { USE_DYNAMIC = N + 1 };
  T m_static[N];
  size_t m_size;
  vector<T> m_dynamic;

public:
  typedef T value_type;
  typedef T const & const_reference;
  typedef T & reference;

  buffer_vector() : m_size(0) {}
  explicit buffer_vector(size_t n, T c = T()) : m_size(0)
  {
    resize(n, c);
  }

  void reserve(size_t n)
  {
    if (m_size == USE_DYNAMIC || n > N)
      m_dynamic.reserve(n);
  }

  void resize(size_t n, T c = T())
  {
    if (m_size == USE_DYNAMIC)
      m_dynamic.resize(n);
    else
    {
      if (n <= N)
      {
        for (size_t i = m_size; i < n; ++i)
          m_static[i] = c;
        m_size = n;
      }
      else
      {
        m_dynamic.reserve(n);
        size_t const oldSize = m_size;
        SwitchToDynamic();
        m_dynamic.insert(m_dynamic.end(), n - oldSize, c);
        ASSERT_EQUAL(m_dynamic.size(), n, ());
      }
    }
  }

  void clear()
  {
    if (m_size == USE_DYNAMIC)
      m_dynamic.clear();
    else
      m_size = 0;
  }

  T const * data() const { return m_size == USE_DYNAMIC ? &m_dynamic[0] : &m_static[0]; }
  T       * data()       { return m_size == USE_DYNAMIC ? &m_dynamic[0] : &m_static[0]; }

  T const * begin() const { return data(); }
  T       * begin()       { return data(); }
  T const * end() const { return data() + size(); }
  T       * end()       { return data() + size(); }

  bool empty() const { return m_size == USE_DYNAMIC ? m_dynamic.empty() : m_size == 0; }
  size_t size() const { return m_size == USE_DYNAMIC ? m_dynamic.size() : m_size; }

  T const & front() const
  {
    ASSERT(!empty(), ());
    return *begin();
  }
  T & front()
  {
    ASSERT(!empty(), ());
    return *begin();
  }
  T const & back() const
  {
    ASSERT(!empty(), ());
    return *(end() - 1);
  }
  T & back()
  {
    ASSERT(!empty(), ());
    return *(end() - 1);
  }

  T const & operator[](size_t i) const
  {
    ASSERT_LESS(i, size(), ());
    return *(begin() + i);
  }
  T & operator[](size_t i)
  {
    ASSERT_LESS(i, size(), ());
    return *(begin() + i);
  }

  void swap(buffer_vector<T, N> & rhs)
  {
    m_dynamic.swap(rhs.m_dynamic);
    Swap(m_size, rhs.m_size);
    for (size_t i = 0; i < N; ++i)
      Swap(m_static[i], rhs.m_static[i]);
  }

  void push_back(T const & t)
  {
    if (m_size == USE_DYNAMIC)
      m_dynamic.push_back(t);
    else
    {
      if (m_size < N)
        m_static[m_size++] = t;
      else
      {
        ASSERT_EQUAL(m_size, N, ());
        m_dynamic.reserve(N + 1);
        SwitchToDynamic();
        m_dynamic.push_back(t);
        ASSERT_EQUAL(m_dynamic.size(), N + 1, ());
      }
    }
  }

  void pop_back()
  {
    if (m_size == USE_DYNAMIC)
      m_dynamic.pop_back();
    else
    {
      ASSERT_GREATER(m_size, 0, ());
      --m_size;
    }
  }

  template <typename IterT> void insert(T const * where, IterT beg, IterT end)
  {
    ptrdiff_t const pos = where - data();
    ASSERT_GREATER_OR_EQUAL(pos, 0, ());
    ASSERT_LESS_OR_EQUAL(pos, size(), ());
    if (m_size == USE_DYNAMIC)
      m_dynamic.insert(m_dynamic.begin() + pos, beg, end);
    else
    {
      size_t const n = end - beg;
      if (m_size + n <= N)
      {
        if (pos != m_size)
          for (ptrdiff_t i = m_size - 1; i >= pos; --i)
            Swap(m_static[i], m_static[i + n]);

        m_size += n;
        T * writableWhere = &m_static[0] + pos;
        ASSERT_EQUAL(where, writableWhere, ());
        while (beg != end)
          *(writableWhere++) = *(beg++);
      }
      else
      {
        m_dynamic.reserve(m_size + n);
        SwitchToDynamic();
        m_dynamic.insert(m_dynamic.begin() + pos, beg, end);
        ASSERT_EQUAL(m_dynamic.size(), m_dynamic.capacity(), ());
      }
    }
  }

private:
  void SwitchToDynamic()
  {
    ASSERT_NOT_EQUAL(m_size, static_cast<size_t>(USE_DYNAMIC), ());
    ASSERT_EQUAL(m_dynamic.size(), 0, ());
    m_dynamic.insert(m_dynamic.end(), m_size, T());
    for (size_t i = 0; i < m_size; ++i)
      Swap(m_static[i], m_dynamic[i]);
    m_size = USE_DYNAMIC;
  }
};

template <class T, size_t N>
void swap(buffer_vector<T, N> & r1, buffer_vector<T, N> & r2) { r1.swap(r2); }

template <typename T, size_t N>
inline string debug_print(buffer_vector<T, N> const & v)
{
  return ::my::impl::DebugPrintSequence(v.data(), v.data() + v.size());
}
<|endoftext|>


<commit_before>#pragma once

#include "base/get_line.hpp"

#include <string>

namespace principia {
namespace base {

namespace {

int constexpr kBufferSize = 100;

std::string GetLineWithSize(std::size_t const size,
                            not_null<std::ifstream*> const stream) {
  char* buffer = new char[size];
  if (!stream->getline(buffer, size).eof() && stream->fail()) {
    stream->clear();
    std::string string_buffer(buffer);
    string_buffer += GetLineWithSize(2 * size, stream);
    return std::move(string_buffer);
  }
  return buffer;
}

}  // namespace

std::string GetLine(not_null<std::ifstream*> const stream) {
  return GetLineWithSize(kBufferSize, stream);
}

}  // namespace base
}  // namespace principia
<commit_msg>Unique ptr.<commit_after>#pragma once

#include "base/get_line.hpp"

#include <string>

namespace principia {
namespace base {

namespace {

int constexpr kBufferSize = 200;

std::string GetLineWithSize(std::size_t const size,
                            not_null<std::ifstream*> const stream) {
  std::unique_ptr<char[]> buffer(new char[size]);
  if (!stream->getline(&buffer[0], size).eof() && stream->fail()) {
    stream->clear();
    std::string string_buffer(buffer.get());
    string_buffer += GetLineWithSize(2 * size, stream);
    return std::move(string_buffer);
  } else {
    std::string string_buffer(buffer.get());
    return std::move(string_buffer);
  }
}

}  // namespace

std::string GetLine(not_null<std::ifstream*> const stream) {
  return GetLineWithSize(kBufferSize, stream);
}

}  // namespace base
}  // namespace principia
<|endoftext|>


<commit_before>#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstdint>
#include <cstring>

#include <iostream>
#include <string>

#include "sixtracklib/testlib.h"
#include "sixtracklib/sixtracklib.hpp"

int main( int argc, char* argv[] )
{
    namespace st = sixtrack;

    using size_t      = st::Buffer::size_type;
    using track_job_t = st::TrackJobCpu;

    st::Buffer input_pb;
    st::Buffer pb;
    st::Buffer eb;

    st::Particles* particles = nullptr;

    int NUM_PARTICLES                  = 0;
    int NUM_TURNS                      = 10;
    int NUM_TURNS_ELEM_BY_ELEM         = 3;
    int OUTPUT_SKIP                    = 1;
    int track_status                   = 0;

    /* -------------------------------------------------------------------- */
    /* Read command line parameters */

    if( argc < 3 )
    {
        std::cout << "Usage: " << argv[ 0 ]
                  << " PATH_TO_PARTICLES PATH_TO_BEAM_ELEMENTS" << std::endl;
        return 0;
    }

    if( ( argc >= 3 ) &&
        ( argv[ 1 ] != nullptr ) && ( std::strlen( argv[ 1 ] ) > 0u ) &&
        ( argv[ 2 ] != nullptr ) && ( std::strlen( argv[ 2 ] ) > 0u ) )
    {
        input_pb.readFromFile( argv[ 1 ] );
        eb.readFromFile( argv[ 2 ] );

        NUM_PARTICLES = st::Particles::FromBuffer(
            input_pb, 0u )->getNumParticles();
    }

    /* --------------------------------------------------------------------- */
    /* Prepare input and tracking data from run-time parameters: */

    std::printf("%-30s = %10d\n","NUM_PARTICLES",NUM_PARTICLES);
    std::printf("%-30s = %10d\n","NUM_TURNS",NUM_TURNS);
    std::printf("%-30s = %10d\n","NUM_TURNS_ELEM_BY_ELEM",NUM_TURNS_ELEM_BY_ELEM);
    std::printf("%-30s = %10d\n","OUTPUT_SKIP", OUTPUT_SKIP);

    if( NUM_PARTICLES >= 0 )
    {
        particles = pb.createNew< st::Particles >(
            st::Particles::FromBuffer( input_pb, 0u )->getNumParticles() );
    }

    if( ( eb.getNumObjects() > size_t{ 0 } ) &&
        ( NUM_TURNS > NUM_TURNS_ELEM_BY_ELEM ) )
    {
        st::BeamMonitor* beam_monitor = eb.createNew< st::BeamMonitor >();
        beam_monitor->setNumStores( NUM_TURNS - NUM_TURNS_ELEM_BY_ELEM );
        beam_monitor->setStart( NUM_TURNS_ELEM_BY_ELEM );
        beam_monitor->setSkip( OUTPUT_SKIP );
        beam_monitor->setIsRolling( true );
    }

    /* ********************************************************************* */
    /* ****               PERFORM TRACKING OPERATIONS                ******* */
    /* ********************************************************************* */

    if( ( particles != nullptr ) && ( NUM_PARTICLES > 0 ) && ( NUM_TURNS > 0 ) )
    {
        /* Create the track_job */
        track_job_t job( pb, eb, nullptr, NUM_TURNS_ELEM_BY_ELEM );

        if( NUM_TURNS_ELEM_BY_ELEM > 0 )
        {
            track_status |= st::trackElemByElem( job, NUM_TURNS_ELEM_BY_ELEM );
        }

        if( NUM_TURNS > NUM_TURNS_ELEM_BY_ELEM )
        {
            track_status |= st::track( job, NUM_TURNS );
        }

        /* ****************************************************************** */
        /* ****               PERFORM OUTPUT OPERATIONS                ****** */
        /* ****************************************************************** */

        /* NOTE: for the CPU Track Job, collect (currently) performs no
         * operations. Since this *might* change in the future, it's
         * mandated to always call NS(TrackJobCpu_collect)() before
         * accessing the particles, the beam elements or the
         * output buffer */

        st::collect( job );

        if( track_status == 0 )
        {
            st::Buffer* out_buffer = nullptr;

            if( job.hasOutputBuffer() )
            {
                out_buffer = job.ptrOutputBuffer();
            }

            if( job.hasElemByElemOutput() )
            {
                ::st_ElemByElemConfig const* elem_by_elem_config =
                    job.ptrElemByElemConfig();

                size_t const out_offset = job.elemByElemOutputBufferOffset();

                st_Particles* elem_by_elem_output = st::Particles::FromBuffer(
                    *out_buffer, out_offset );

                /* ::st_Particles_print_out(
                       elem_by_elem_output->getCApiPtr() ); */

                ( void )elem_by_elem_config;
                ( void )elem_by_elem_output;
            }

            if( job.hasBeamMonitorOutput() )
            {
                st_size_t const bemon_start_index =
                    job.beamMonitorsOutputBufferOffset();

                st_size_t const bemon_stop_index =
                    bemon_start_index + job.numBeamMonitors();

                st_size_t ii = bemon_start_index;

                for(  ; ii < bemon_stop_index ; ++ii )
                {
                    st::Particles* out_particles = st::Particles::FromBuffer(
                        *out_buffer, ii );

                    /* ::st_Particles_print_out(
                           out_particles->getCApiPtr() ); */

                    ( void )out_particles;
                }
            }
        }
    }

    return 0;
}

/* end: examples/cxx/track_job_cpu.cpp */
<commit_msg>examples/cxx: use updated public trackJob API for example<commit_after>#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstdint>
#include <cstring>

#include <iostream>
#include <string>

#include "sixtracklib/testlib.h"
#include "sixtracklib/sixtracklib.hpp"

int main( int argc, char* argv[] )
{
    namespace st = sixtrack;

    using size_t      = st::Buffer::size_type;
    using track_job_t = st::TrackJobCpu;

    st::Buffer input_pb;
    st::Buffer pb;
    st::Buffer eb;

    st::Particles* particles = nullptr;

    int NUM_PARTICLES                  = 0;
    int NUM_TURNS                      = 10;
    int NUM_TURNS_ELEM_BY_ELEM         = 3;
    int OUTPUT_SKIP                    = 1;
    int track_status                   = 0;

    /* -------------------------------------------------------------------- */
    /* Read command line parameters */

    if( argc < 3 )
    {
        std::cout << "Usage: " << argv[ 0 ]
                  << " PATH_TO_PARTICLES PATH_TO_BEAM_ELEMENTS" << std::endl;
        return 0;
    }

    if( ( argc >= 3 ) &&
        ( argv[ 1 ] != nullptr ) && ( std::strlen( argv[ 1 ] ) > 0u ) &&
        ( argv[ 2 ] != nullptr ) && ( std::strlen( argv[ 2 ] ) > 0u ) )
    {
        input_pb.readFromFile( argv[ 1 ] );
        eb.readFromFile( argv[ 2 ] );

        NUM_PARTICLES = st::Particles::FromBuffer(
            input_pb, 0u )->getNumParticles();
    }

    /* --------------------------------------------------------------------- */
    /* Prepare input and tracking data from run-time parameters: */

    std::printf("%-30s = %10d\n","NUM_PARTICLES",NUM_PARTICLES);
    std::printf("%-30s = %10d\n","NUM_TURNS",NUM_TURNS);
    std::printf("%-30s = %10d\n","NUM_TURNS_ELEM_BY_ELEM",NUM_TURNS_ELEM_BY_ELEM);
    std::printf("%-30s = %10d\n","OUTPUT_SKIP", OUTPUT_SKIP);

    if( NUM_PARTICLES >= 0 )
    {
        particles = pb.createNew< st::Particles >(
            st::Particles::FromBuffer( input_pb, 0u )->getNumParticles() );
    }

    if( ( eb.getNumObjects() > size_t{ 0 } ) &&
        ( NUM_TURNS > NUM_TURNS_ELEM_BY_ELEM ) )
    {
        st::BeamMonitor* beam_monitor = eb.createNew< st::BeamMonitor >();
        beam_monitor->setNumStores( NUM_TURNS - NUM_TURNS_ELEM_BY_ELEM );
        beam_monitor->setStart( NUM_TURNS_ELEM_BY_ELEM );
        beam_monitor->setSkip( OUTPUT_SKIP );
        beam_monitor->setIsRolling( true );
    }

    /* ********************************************************************* */
    /* ****               PERFORM TRACKING OPERATIONS                ******* */
    /* ********************************************************************* */

    if( ( particles != nullptr ) && ( NUM_PARTICLES > 0 ) && ( NUM_TURNS > 0 ) )
    {
        /* Create the track_job */
        track_job_t job( pb, eb, nullptr, NUM_TURNS_ELEM_BY_ELEM );

        if( NUM_TURNS_ELEM_BY_ELEM > 0 )
        {
            track_status |= st::trackElemByElem( job, NUM_TURNS_ELEM_BY_ELEM );
        }

        if( NUM_TURNS > NUM_TURNS_ELEM_BY_ELEM )
        {
            track_status |= st::trackUntil( job, NUM_TURNS );
        }

        /* ****************************************************************** */
        /* ****               PERFORM OUTPUT OPERATIONS                ****** */
        /* ****************************************************************** */

        /* NOTE: for the CPU Track Job, collect (currently) performs no
         * operations. Since this *might* change in the future, it's
         * mandated to always call NS(TrackJobCpu_collect)() before
         * accessing the particles, the beam elements or the
         * output buffer */

        st::collect( job );

        if( track_status == 0 )
        {
            st::Buffer* out_buffer = nullptr;

            if( job.hasOutputBuffer() )
            {
                out_buffer = job.ptrOutputBuffer();
            }

            if( job.hasElemByElemOutput() )
            {
                ::st_ElemByElemConfig const* elem_by_elem_config =
                    job.ptrElemByElemConfig();

                size_t const out_offset = job.elemByElemOutputBufferOffset();

                st_Particles* elem_by_elem_output = st::Particles::FromBuffer(
                    *out_buffer, out_offset );

                /* ::st_Particles_print_out(
                       elem_by_elem_output->getCApiPtr() ); */

                ( void )elem_by_elem_config;
                ( void )elem_by_elem_output;
            }

            if( job.hasBeamMonitorOutput() )
            {
                st_size_t const bemon_start_index =
                    job.beamMonitorsOutputBufferOffset();

                st_size_t const bemon_stop_index =
                    bemon_start_index + job.numBeamMonitors();

                st_size_t ii = bemon_start_index;

                for(  ; ii < bemon_stop_index ; ++ii )
                {
                    st::Particles* out_particles = st::Particles::FromBuffer(
                        *out_buffer, ii );

                    /* ::st_Particles_print_out(
                           out_particles->getCApiPtr() ); */

                    ( void )out_particles;
                }
            }
        }
    }

    return 0;
}

/* end: examples/cxx/track_job_cpu.cpp */
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: animationcommandnode.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: obo $ $Date: 2007-07-17 14:47:16 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_slideshow.hxx"

// must be first
#include <canvas/debug.hxx>
#include <canvas/verbosetrace.hxx>
#include <com/sun/star/presentation/EffectCommands.hpp>

#include "animationcommandnode.hxx"
#include "delayevent.hxx"
#include "tools.hxx"
#include "nodetools.hxx"

#include <boost/bind.hpp>

namespace slideshow {
namespace internal {

void AnimationCommandNode::dispose()
{
    mxCommandNode.clear();
    BaseNode::dispose();
}

void AnimationCommandNode::activate_()
{
    namespace EffectCommands = com::sun::star::presentation::EffectCommands;

    switch( mxCommandNode->getCommand() ) {
        // the command is user defined
    case EffectCommands::CUSTOM: break;
        // the command is an ole verb.
    case EffectCommands::VERB: break;
        // the command starts playing on a media object
    case EffectCommands::PLAY: break;
        // the command toggles the pause status on a media object
    case EffectCommands::TOGGLEPAUSE: break;
        // the command stops the animation on a media object
    case EffectCommands::STOP: break;
        // the command stops all currently running sound effects
    case EffectCommands::STOPAUDIO:
        getContext().mrEventMultiplexer.notifyCommandStopAudio( getSelf() );
        break;
    }

    // deactivate ASAP:
    scheduleDeactivationEvent(
        makeEvent( boost::bind( &AnimationNode::deactivate, getSelf() ) ) );
}

bool AnimationCommandNode::hasPendingAnimation() const
{
    return false;
}

} // namespace internal
} // namespace slideshow
<commit_msg>INTEGRATION: CWS changefileheader (1.8.46); FILE MERGED 2008/03/31 14:00:17 rt 1.8.46.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: animationcommandnode.cxx,v $
 * $Revision: 1.9 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_slideshow.hxx"

// must be first
#include <canvas/debug.hxx>
#include <canvas/verbosetrace.hxx>
#include <com/sun/star/presentation/EffectCommands.hpp>

#include "animationcommandnode.hxx"
#include "delayevent.hxx"
#include "tools.hxx"
#include "nodetools.hxx"

#include <boost/bind.hpp>

namespace slideshow {
namespace internal {

void AnimationCommandNode::dispose()
{
    mxCommandNode.clear();
    BaseNode::dispose();
}

void AnimationCommandNode::activate_()
{
    namespace EffectCommands = com::sun::star::presentation::EffectCommands;

    switch( mxCommandNode->getCommand() ) {
        // the command is user defined
    case EffectCommands::CUSTOM: break;
        // the command is an ole verb.
    case EffectCommands::VERB: break;
        // the command starts playing on a media object
    case EffectCommands::PLAY: break;
        // the command toggles the pause status on a media object
    case EffectCommands::TOGGLEPAUSE: break;
        // the command stops the animation on a media object
    case EffectCommands::STOP: break;
        // the command stops all currently running sound effects
    case EffectCommands::STOPAUDIO:
        getContext().mrEventMultiplexer.notifyCommandStopAudio( getSelf() );
        break;
    }

    // deactivate ASAP:
    scheduleDeactivationEvent(
        makeEvent( boost::bind( &AnimationNode::deactivate, getSelf() ) ) );
}

bool AnimationCommandNode::hasPendingAnimation() const
{
    return false;
}

} // namespace internal
} // namespace slideshow
<|endoftext|>


<commit_before>#include <FAST/Config.hpp>
#include <FAST/Utility.hpp>
#ifndef WIN32
#include <dlfcn.h>
#endif
#include "InferenceEngineManager.hpp"

namespace fast {

bool InferenceEngineManager::m_loaded = false;
std::unordered_map<std::string, std::function<InferenceEngine*()>> InferenceEngineManager::m_engines;

#ifdef WIN32
//Returns the last Win32 error, in string format. Returns an empty string if there is no error.
std::string GetLastErrorAsString()
{
    //Get the error message, if any.
    DWORD errorMessageID = ::GetLastError();
    if(errorMessageID == 0)
        return std::string(); //No error message has been recorded

    LPSTR messageBuffer = nullptr;
    size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
                                 NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);

    std::string message(messageBuffer, size);

    //Free the buffer.
    LocalFree(messageBuffer);

    return message;
}
#endif

std::vector<std::string> InferenceEngineManager::getEngineList() {
    loadAll();
    std::vector<std::string> list;
    for(auto&& engine : m_engines)
        list.push_back(engine.first);
    return list;
}

void InferenceEngineManager::loadAll() {
    if(m_loaded) {
        return;
    }
    std::string prefix = "InferenceEngine";
#ifndef WIN32
    prefix = "lib" + prefix;
#endif
    Reporter::info() << "Loading inference engines in folder " << Config::getLibraryPath() << Reporter::end();
    for(auto&& item : getDirectoryList(Config::getLibraryPath(), true, false)) {
        if(item.substr(0, prefix.size()) == prefix) {
            std::string name = item.substr(prefix.size(), item.rfind('.') - prefix.size());
            Reporter::info() << "Loading inference engine " << name << " from shared library " << item << Reporter::end();
#ifdef WIN32
            SetErrorMode(SEM_FAILCRITICALERRORS); // TODO To avoid diaglog box, when not able to load a DLL
            auto handle = LoadLibrary(item.c_str());
            if(!handle) {
                Reporter::warning() << "Failed to load plugin because " << GetLastErrorAsString() << Reporter::end();
                continue;
            }
            auto load = (InferenceEngine* (*)())GetProcAddress(handle, "load");
            if(!load) {
                FreeLibrary(handle);
                Reporter::warning() << "Failed to get adress to load function because " << GetLastErrorAsString() << Reporter::end();
                continue;
            }
#else
            auto handle = dlopen(item.c_str(), RTLD_LAZY);
            if(!handle) {
                Reporter::warning() << "Failed to load plugin because " << dlerror() << Reporter::end();
                continue;
            }
            auto load = (InferenceEngine* (*)())dlsym(handle, "load");
            if(!load) {
                dlclose(handle);
                Reporter::warning() << "Failed to get address of load function because " << Reporter::end();// dlerror() << Reporter::end();
                continue;
            }
#endif
            m_engines[name] = load;
        }
    }
    m_loaded = true;
}

std::shared_ptr<InferenceEngine> InferenceEngineManager::loadBestAvailableEngine() {
    loadAll();
    if(m_engines.empty())
        throw Exception("No inference engines available on the system");

    if(isEngineAvailable("TensorFlow")) {
        // Default is tensorflow if GPU support is enabled
        auto engine = loadEngine("TensorFlow");
        auto devices = engine->getDeviceList();
        for (auto &&device : devices) {
            if (device.type == InferenceDeviceType::GPU)
                return engine;
        }
    }

    if(isEngineAvailable("TensorRT"))
        return loadEngine("TensorRT");

    return loadEngine(getEngineList().front());
}

std::shared_ptr<InferenceEngine> InferenceEngineManager::loadBestAvailableEngine(ModelFormat modelFormat) {
    loadAll();
    if(m_engines.empty())
        throw Exception("No inference engines available on the system");

    if(isEngineAvailable("TensorFlow") && loadEngine("TensorFlow")->isModelFormatSupported(modelFormat)) {
        // Default is tensorflow if GPU support is enabled
        auto engine = loadEngine("TensorFlow");
        auto devices = engine->getDeviceList();
        for (auto &&device : devices) {
            if (device.type == InferenceDeviceType::GPU)
                return engine;
        }
    }

    if(isEngineAvailable("TensorRT") && loadEngine("TensorRT")->isModelFormatSupported(modelFormat))
        return loadEngine("TensorRT");

    for(auto name : getEngineList()) {
        auto engine = loadEngine(name);
        if(engine->isModelFormatSupported(modelFormat))
            return engine;
    }
    throw Exception("No engine for model format found");
}

bool InferenceEngineManager::isEngineAvailable(std::string name) {
    loadAll();
    return m_engines.count(name) > 0;
}

std::shared_ptr<InferenceEngine> InferenceEngineManager::loadEngine(std::string name) {
    loadAll();
    if(m_engines.count(name) == 0)
        throw Exception("Inference engine with name " + name + " is not available");
    // Call the load function which the map stores a handle to
    return std::shared_ptr<InferenceEngine>(m_engines.at(name)());
}

}<commit_msg>Check for AVX2 support before loading TensorFlow<commit_after>#include <FAST/Config.hpp>
#include <FAST/Utility.hpp>
#ifdef WIN32
// For TensorFlow AVX2 check - Taken from https://docs.microsoft.com/en-us/cpp/intrinsics/cpuid-cpuidex?view=msvc-160
#include <vector>
#include <bitset>
#include <array>
#include <string>
#include <intrin.h>
namespace fast {
class InstructionSet
{
    // forward declarations
    class InstructionSet_Internal;

public:
    // getters
    static std::string Vendor(void) { return CPU_Rep.vendor_; }
    static std::string Brand(void) { return CPU_Rep.brand_; }

    static bool SSE3(void) { return CPU_Rep.f_1_ECX_[0]; }
    static bool PCLMULQDQ(void) { return CPU_Rep.f_1_ECX_[1]; }
    static bool MONITOR(void) { return CPU_Rep.f_1_ECX_[3]; }
    static bool SSSE3(void) { return CPU_Rep.f_1_ECX_[9]; }
    static bool FMA(void) { return CPU_Rep.f_1_ECX_[12]; }
    static bool CMPXCHG16B(void) { return CPU_Rep.f_1_ECX_[13]; }
    static bool SSE41(void) { return CPU_Rep.f_1_ECX_[19]; }
    static bool SSE42(void) { return CPU_Rep.f_1_ECX_[20]; }
    static bool MOVBE(void) { return CPU_Rep.f_1_ECX_[22]; }
    static bool POPCNT(void) { return CPU_Rep.f_1_ECX_[23]; }
    static bool AES(void) { return CPU_Rep.f_1_ECX_[25]; }
    static bool XSAVE(void) { return CPU_Rep.f_1_ECX_[26]; }
    static bool OSXSAVE(void) { return CPU_Rep.f_1_ECX_[27]; }
    static bool AVX(void) { return CPU_Rep.f_1_ECX_[28]; }
    static bool F16C(void) { return CPU_Rep.f_1_ECX_[29]; }
    static bool RDRAND(void) { return CPU_Rep.f_1_ECX_[30]; }

    static bool MSR(void) { return CPU_Rep.f_1_EDX_[5]; }
    static bool CX8(void) { return CPU_Rep.f_1_EDX_[8]; }
    static bool SEP(void) { return CPU_Rep.f_1_EDX_[11]; }
    static bool CMOV(void) { return CPU_Rep.f_1_EDX_[15]; }
    static bool CLFSH(void) { return CPU_Rep.f_1_EDX_[19]; }
    static bool MMX(void) { return CPU_Rep.f_1_EDX_[23]; }
    static bool FXSR(void) { return CPU_Rep.f_1_EDX_[24]; }
    static bool SSE(void) { return CPU_Rep.f_1_EDX_[25]; }
    static bool SSE2(void) { return CPU_Rep.f_1_EDX_[26]; }

    static bool FSGSBASE(void) { return CPU_Rep.f_7_EBX_[0]; }
    static bool BMI1(void) { return CPU_Rep.f_7_EBX_[3]; }
    static bool HLE(void) { return CPU_Rep.isIntel_ && CPU_Rep.f_7_EBX_[4]; }
    static bool AVX2(void) { return CPU_Rep.f_7_EBX_[5]; }
    static bool BMI2(void) { return CPU_Rep.f_7_EBX_[8]; }
    static bool ERMS(void) { return CPU_Rep.f_7_EBX_[9]; }
    static bool INVPCID(void) { return CPU_Rep.f_7_EBX_[10]; }
    static bool RTM(void) { return CPU_Rep.isIntel_ && CPU_Rep.f_7_EBX_[11]; }
    static bool AVX512F(void) { return CPU_Rep.f_7_EBX_[16]; }
    static bool RDSEED(void) { return CPU_Rep.f_7_EBX_[18]; }
    static bool ADX(void) { return CPU_Rep.f_7_EBX_[19]; }
    static bool AVX512PF(void) { return CPU_Rep.f_7_EBX_[26]; }
    static bool AVX512ER(void) { return CPU_Rep.f_7_EBX_[27]; }
    static bool AVX512CD(void) { return CPU_Rep.f_7_EBX_[28]; }
    static bool SHA(void) { return CPU_Rep.f_7_EBX_[29]; }

    static bool PREFETCHWT1(void) { return CPU_Rep.f_7_ECX_[0]; }

    static bool LAHF(void) { return CPU_Rep.f_81_ECX_[0]; }
    static bool LZCNT(void) { return CPU_Rep.isIntel_ && CPU_Rep.f_81_ECX_[5]; }
    static bool ABM(void) { return CPU_Rep.isAMD_ && CPU_Rep.f_81_ECX_[5]; }
    static bool SSE4a(void) { return CPU_Rep.isAMD_ && CPU_Rep.f_81_ECX_[6]; }
    static bool XOP(void) { return CPU_Rep.isAMD_ && CPU_Rep.f_81_ECX_[11]; }
    static bool TBM(void) { return CPU_Rep.isAMD_ && CPU_Rep.f_81_ECX_[21]; }

    static bool SYSCALL(void) { return CPU_Rep.isIntel_ && CPU_Rep.f_81_EDX_[11]; }
    static bool MMXEXT(void) { return CPU_Rep.isAMD_ && CPU_Rep.f_81_EDX_[22]; }
    static bool RDTSCP(void) { return CPU_Rep.isIntel_ && CPU_Rep.f_81_EDX_[27]; }
    static bool _3DNOWEXT(void) { return CPU_Rep.isAMD_ && CPU_Rep.f_81_EDX_[30]; }
    static bool _3DNOW(void) { return CPU_Rep.isAMD_ && CPU_Rep.f_81_EDX_[31]; }

private:
    static const InstructionSet_Internal CPU_Rep;

    class InstructionSet_Internal
    {
    public:
        InstructionSet_Internal()
            : nIds_{ 0 },
            nExIds_{ 0 },
            isIntel_{ false },
            isAMD_{ false },
            f_1_ECX_{ 0 },
            f_1_EDX_{ 0 },
            f_7_EBX_{ 0 },
            f_7_ECX_{ 0 },
            f_81_ECX_{ 0 },
            f_81_EDX_{ 0 },
            data_{},
            extdata_{}
        {
            //int cpuInfo[4] = {-1};
            std::array<int, 4> cpui;

            // Calling __cpuid with 0x0 as the function_id argument
            // gets the number of the highest valid function ID.
            __cpuid(cpui.data(), 0);
            nIds_ = cpui[0];

            for (int i = 0; i <= nIds_; ++i)
            {
                __cpuidex(cpui.data(), i, 0);
                data_.push_back(cpui);
            }

            // Capture vendor string
            char vendor[0x20];
            memset(vendor, 0, sizeof(vendor));
            *reinterpret_cast<int*>(vendor) = data_[0][1];
            *reinterpret_cast<int*>(vendor + 4) = data_[0][3];
            *reinterpret_cast<int*>(vendor + 8) = data_[0][2];
            vendor_ = vendor;
            if (vendor_ == "GenuineIntel")
            {
                isIntel_ = true;
            }
            else if (vendor_ == "AuthenticAMD")
            {
                isAMD_ = true;
            }

            // load bitset with flags for function 0x00000001
            if (nIds_ >= 1)
            {
                f_1_ECX_ = data_[1][2];
                f_1_EDX_ = data_[1][3];
            }

            // load bitset with flags for function 0x00000007
            if (nIds_ >= 7)
            {
                f_7_EBX_ = data_[7][1];
                f_7_ECX_ = data_[7][2];
            }

            // Calling __cpuid with 0x80000000 as the function_id argument
            // gets the number of the highest valid extended ID.
            __cpuid(cpui.data(), 0x80000000);
            nExIds_ = cpui[0];

            char brand[0x40];
            memset(brand, 0, sizeof(brand));

            for (int i = 0x80000000; i <= nExIds_; ++i)
            {
                __cpuidex(cpui.data(), i, 0);
                extdata_.push_back(cpui);
            }

            // load bitset with flags for function 0x80000001
            if (nExIds_ >= 0x80000001)
            {
                f_81_ECX_ = extdata_[1][2];
                f_81_EDX_ = extdata_[1][3];
            }

            // Interpret CPU brand string if reported
            if (nExIds_ >= 0x80000004)
            {
                memcpy(brand, extdata_[2].data(), sizeof(cpui));
                memcpy(brand + 16, extdata_[3].data(), sizeof(cpui));
                memcpy(brand + 32, extdata_[4].data(), sizeof(cpui));
                brand_ = brand;
            }
        };

        int nIds_;
        int nExIds_;
        std::string vendor_;
        std::string brand_;
        bool isIntel_;
        bool isAMD_;
        std::bitset<32> f_1_ECX_;
        std::bitset<32> f_1_EDX_;
        std::bitset<32> f_7_EBX_;
        std::bitset<32> f_7_ECX_;
        std::bitset<32> f_81_ECX_;
        std::bitset<32> f_81_EDX_;
        std::vector<std::array<int, 4>> data_;
        std::vector<std::array<int, 4>> extdata_;
    };
};
}
#else
#include <dlfcn.h>
#endif
#include "InferenceEngineManager.hpp"

namespace fast {

bool InferenceEngineManager::m_loaded = false;
std::unordered_map<std::string, std::function<InferenceEngine*()>> InferenceEngineManager::m_engines;

#ifdef WIN32
//Returns the last Win32 error, in string format. Returns an empty string if there is no error.
std::string GetLastErrorAsString()
{
    //Get the error message, if any.
    DWORD errorMessageID = ::GetLastError();
    if(errorMessageID == 0)
        return std::string(); //No error message has been recorded

    LPSTR messageBuffer = nullptr;
    size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
                                 NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);

    std::string message(messageBuffer, size);

    //Free the buffer.
    LocalFree(messageBuffer);

    return message;
}
#endif

std::vector<std::string> InferenceEngineManager::getEngineList() {
    loadAll();
    std::vector<std::string> list;
    for(auto&& engine : m_engines)
        list.push_back(engine.first);
    return list;
}

void InferenceEngineManager::loadAll() {
    if(m_loaded) {
        return;
    }
    std::string prefix = "InferenceEngine";
#ifndef WIN32
    prefix = "lib" + prefix;
#endif
    Reporter::info() << "Loading inference engines in folder " << Config::getLibraryPath() << Reporter::end();
    for(auto&& item : getDirectoryList(Config::getLibraryPath(), true, false)) {
        if(item.substr(0, prefix.size()) == prefix) {
            std::string name = item.substr(prefix.size(), item.rfind('.') - prefix.size());
            Reporter::info() << "Loading inference engine " << name << " from shared library " << item << Reporter::end();
#ifdef WIN32
            if(name == "TensorFlow") {
                if(!InstructionSet::AVX2()) {
                    Reporter::warning() << "You CPU does not support AVX2, unable to load TensorFlow inference engine." << Reporter::end();
                    continue;
                }
            }
            SetErrorMode(SEM_FAILCRITICALERRORS); // TODO To avoid diaglog box, when not able to load a DLL
            auto handle = LoadLibrary(item.c_str());
            if(!handle) {
                Reporter::warning() << "Failed to load plugin because " << GetLastErrorAsString() << Reporter::end();
                continue;
            }
            auto load = (InferenceEngine* (*)())GetProcAddress(handle, "load");
            if(!load) {
                FreeLibrary(handle);
                Reporter::warning() << "Failed to get adress to load function because " << GetLastErrorAsString() << Reporter::end();
                continue;
            }
#else
            if(name == "TensorFlow") {
                if(!__builtin_cpu_supports("avx2")) {
                    Reporter::warning() << "You CPU does not support AVX2, unable to load TensorFlow inference engine." << Reporter::end();
                    continue;
                }
            }
            auto handle = dlopen(item.c_str(), RTLD_LAZY);
            if(!handle) {
                Reporter::warning() << "Failed to load plugin because " << dlerror() << Reporter::end();
                continue;
            }
            auto load = (InferenceEngine* (*)())dlsym(handle, "load");
            if(!load) {
                dlclose(handle);
                Reporter::warning() << "Failed to get address of load function because " << Reporter::end();// dlerror() << Reporter::end();
                continue;
            }
#endif
            m_engines[name] = load;
        }
    }
    m_loaded = true;
}

std::shared_ptr<InferenceEngine> InferenceEngineManager::loadBestAvailableEngine() {
    loadAll();
    if(m_engines.empty())
        throw Exception("No inference engines available on the system");

    if(isEngineAvailable("TensorFlow")) {
        // Default is tensorflow if GPU support is enabled
        auto engine = loadEngine("TensorFlow");
        auto devices = engine->getDeviceList();
        for (auto &&device : devices) {
            if (device.type == InferenceDeviceType::GPU)
                return engine;
        }
    }

    if(isEngineAvailable("TensorRT"))
        return loadEngine("TensorRT");

    return loadEngine(getEngineList().front());
}

std::shared_ptr<InferenceEngine> InferenceEngineManager::loadBestAvailableEngine(ModelFormat modelFormat) {
    loadAll();
    if(m_engines.empty())
        throw Exception("No inference engines available on the system");

    if(isEngineAvailable("TensorFlow") && loadEngine("TensorFlow")->isModelFormatSupported(modelFormat)) {
        // Default is tensorflow if GPU support is enabled
        auto engine = loadEngine("TensorFlow");
        auto devices = engine->getDeviceList();
        for (auto &&device : devices) {
            if (device.type == InferenceDeviceType::GPU)
                return engine;
        }
    }

    if(isEngineAvailable("TensorRT") && loadEngine("TensorRT")->isModelFormatSupported(modelFormat))
        return loadEngine("TensorRT");

    for(auto name : getEngineList()) {
        auto engine = loadEngine(name);
        if(engine->isModelFormatSupported(modelFormat))
            return engine;
    }
    throw Exception("No engine for model format found");
}

bool InferenceEngineManager::isEngineAvailable(std::string name) {
    loadAll();
    return m_engines.count(name) > 0;
}

std::shared_ptr<InferenceEngine> InferenceEngineManager::loadEngine(std::string name) {
    loadAll();
    if(m_engines.count(name) == 0)
        throw Exception("Inference engine with name " + name + " is not available");
    // Call the load function which the map stores a handle to
    return std::shared_ptr<InferenceEngine>(m_engines.at(name)());
}

}<|endoftext|>


<commit_before>#include "QtVmbViewer.h"
#include <iostream>
#include <QPixmap>
#include <QVBoxLayout>

// Constructor
QtVmbViewer::QtVmbViewer( QWidget *parent ) : QWidget( parent ), label( new QLabel ) {
    // Scale the image label
    label->setScaledContents( true );
    // Widget layout
    QVBoxLayout* layout = new QVBoxLayout( this );
    layout->addWidget( label );
    layout->setSizeConstraint( QLayout::SetFixedSize );
    // Create the camera
    camera = new VmbCamera( "50-0503323406" );
    // Connect the camera signal to get the received frame
    connect( camera, &VmbCamera::FrameReceived, this, &QtVmbViewer::GetFrame );
    // Open the camera
    camera->Open();
    // Create the image
    image = new QImage( camera->width, camera->height, QImage::Format_Indexed8 );
    // Create a indexed color table
    image->setColorCount( 256 );
    for( int i = 0; i < 256; i++ ) {
        image->setColor( i, qRgb(i, i, i) );
    }
    // Start acquisition
    camera->StartCapture();
}

// Destructor
QtVmbViewer::~QtVmbViewer() {
    // Stop acquisition
    camera->StopCapture();
    // Close the camera
    camera->Close();
    // Delete the camera
    delete camera;
    // Delete the image
    delete image;
}

// Image callback
void QtVmbViewer::GetFrame( const VmbFrame_t* frame_pointer ) {
    // Copy the camera frame to the widget image
    VmbUchar_t* pCursor = image->bits();
    VmbUchar_t* pInBuffer = (VmbUchar_t*)frame_pointer->buffer;
    for( int y=0; y<camera->height; ++y ) {
        pCursor = image->scanLine( y );
        for( int x=0; x<camera->width; ++x ) {
            *pCursor = *pInBuffer;
            ++pCursor;
            ++pInBuffer;
        }
    }
    // Set the image to the label
    label->setPixmap( QPixmap::fromImage( *image ) );
    // Update the widget
    label->update();
}

<commit_msg>Copy the camera frame buffer to the Qt image using memcpy.<commit_after>#include "QtVmbViewer.h"
#include <iostream>
#include <QPixmap>
#include <QVBoxLayout>

// Constructor
QtVmbViewer::QtVmbViewer( QWidget *parent ) : QWidget( parent ), label( new QLabel ) {
    // Scale the image label
    label->setScaledContents( true );
    // Widget layout
    QVBoxLayout* layout = new QVBoxLayout( this );
    layout->addWidget( label );
    layout->setSizeConstraint( QLayout::SetFixedSize );
    // Create the camera
    camera = new VmbCamera( "50-0503323406" );
    // Connect the camera signal to get the received frame
    connect( camera, &VmbCamera::FrameReceived, this, &QtVmbViewer::GetFrame );
    // Open the camera
    camera->Open();
    // Create the image
    image = new QImage( camera->width, camera->height, QImage::Format_Indexed8 );
    // Create a indexed color table
    image->setColorCount( 256 );
    for( int i = 0; i < 256; i++ ) {
        image->setColor( i, qRgb(i, i, i) );
    }
    // Start acquisition
    camera->StartCapture();
}

// Destructor
QtVmbViewer::~QtVmbViewer() {
    // Stop acquisition
    camera->StopCapture();
    // Close the camera
    camera->Close();
    // Delete the camera
    delete camera;
    // Delete the image
    delete image;
}

// Image callback
void QtVmbViewer::GetFrame( const VmbFrame_t* frame_pointer ) {
    // Copy the camera frame buffer to the Qt image
    memcpy( image->bits(), frame_pointer->buffer, camera->height*camera->width );
    // Set the image to the label
    label->setPixmap( QPixmap::fromImage( *image ) );
    // Update the widget
    label->update();
}

<|endoftext|>


<commit_before>// Copyright (c) 2003 Daniel Wallin and Arvid Norberg

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

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

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

#ifndef LUABIND_OUT_VALUE_POLICY_HPP_INCLUDED
#define LUABIND_OUT_VALUE_POLICY_HPP_INCLUDED

#include <luabind/config.hpp>
#include <luabind/detail/policy.hpp>    // for find_conversion_policy, etc
#include <luabind/detail/decorate_type.hpp>  // for decorated_type
#include <luabind/detail/primitives.hpp>  // for by_pointer, by_reference, etc
#include <luabind/detail/typetraits.hpp>  // for is_nonconst_pointer, is_nonconst_reference, etc
#include <new>                          // for operator new

namespace luabind { namespace detail
{
	template<int N>
	struct char_array
	{
		char storage[N];
	};

	template<class U>
	char_array<sizeof(typename identity<U>::type)> indirect_sizeof_test(by_reference<U>);

	template<class U>
	char_array<sizeof(typename identity<U>::type)> indirect_sizeof_test(by_const_reference<U>);

	template<class U>
	char_array<sizeof(typename identity<U>::type)> indirect_sizeof_test(by_pointer<U>);

	template<class U>
	char_array<sizeof(typename identity<U>::type)> indirect_sizeof_test(by_const_pointer<U>);

	template<class U>
	char_array<sizeof(typename identity<U>::type)> indirect_sizeof_test(by_value<U>);

	template<class T>
	struct indirect_sizeof
	{
		static const int value = sizeof(indirect_sizeof_test(decorated_type<T>()));
	};

	namespace out_value_detail {

		template< int Size >
		struct temporary_storage_size {

			template< typename T, typename... Args >
			void construct(Args&&... args)
			{
				new (&m_storage) T(std::forward<Args>(args)...);
			}

			template<typename T>
			T& get() {
				return *reinterpret_cast<T*>(&m_storage);
			}

			template<typename T>
			const T& get() const {
				return *reinterpret_cast<T*>(&m_storage);
			}

			template<typename T>
			void destroy()
			{
				get<T>().~T();
			}

			typename std::aligned_storage<Size>::type m_storage;

		};

		template< typename T >
		struct temporary_storage_type {

			template< typename... Args >
			void construct(Args&&... args)
			{
				new (&m_storage) T(std::forward<Args>(args)...);
			}

			T& get() {
				return *reinterpret_cast<T*>(&m_storage);
			}

			const T& get() const {
				return *reinterpret_cast<T*>(&m_storage);
			}

			void destroy()
			{
				get().~T();
			}

			typename std::aligned_storage<sizeof(T),alignof(T)>::type m_storage;

		};

	}

	// See note in out_value_policy about why we're not templating
	// for the parameter type.
	template<typename T, class Policies = no_policies>
	struct out_value_converter
	{
		enum { consumed_args = 1 };

        template<class T>
		T& to_cpp(lua_State* L, by_reference<T>, int index)
		{
			//specialized_converter_policy_n<1, Policies, T, lua_to_cpp> converter;
			storage_.construct(converter_.to_cpp(L, decorated_type<T>(), index));
			return storage_.get();
		}

		static int match(lua_State* L, by_reference<T>, int index)
		{
			return converter_.match(L, decorated_type<T&>(), index);
		}

		void converter_postcall(lua_State* L, by_reference<T>, int)
		{
			//specialized_converter_policy_n<2,Policies,T,cpp_to_lua> converter;
			converter_.to_lua(L, storage_.get());
			storage_.destroy();
		}

		T* to_cpp(lua_State* L, by_pointer<T>, int index)
		{
			storage_.construct(converter_.to_cpp(L, decorated_type<T>(), index));
			return &storage_.get();
		}

		int match(lua_State* L, by_pointer<T>, int index)
		{
			return converter_.match(L, decorated_type<T>(), index);
		}

		template<class T>
		void converter_postcall(lua_State* L, by_pointer<T>, int)
		{
			//specialized_converter_policy_n<2, Policies, T, cpp_to_lua> converter;
			converter_.to_lua(L, storage_.get());
			storage_.destroy();
		}

	private:
		specialized_converter_policy_n<1, Policies, T, lua_to_cpp > converter_;
		out_value_detail::temporary_storage_type<T> storage_;
	};

	template<class Policies = no_policies>
	struct out_value_policy
	{
		struct only_accepts_nonconst_references_or_pointers {};
		struct can_only_convert_from_lua_to_cpp {};

		template<class T, class Direction>
		struct specialize
		{
			static_assert(std::is_same< Direction, lua_to_cpp >::value, "Out value policy can only convert from lua to cpp");
			static_assert(meta::or_< is_nonconst_reference<T>, is_nonconst_pointer<T> >::value, "Out value policy only accepts non const references or pointers");

			// Note to myself:
			// Using the size and template members instead of a policy templated for the type seems
			// to be done to tame template bloat. Need to check if this is worth is.
			using base_type = typename std::remove_pointer< typename std::remove_reference< T >::type >::type;
			typedef out_value_converter<base_type, Policies> type;
		};
	};

	template<int Size, class Policies = no_policies>
	struct pure_out_value_converter
	{
		enum { consumed_args = 0 };

        template<class T>
		T& to_cpp(lua_State*, by_reference<T>, int)
		{
			storage_.construct<T>();
			return storage_.get<T>();
		}

		template<class T>
		static int match(lua_State*, by_reference<T>, int)
		{
			return 0;
		}

		template<class T>
		void converter_postcall(lua_State* L, by_reference<T>, int)
		{
			specialized_converter_policy_n<1, Policies, T, cpp_to_lua> converter;
			converter.to_lua(L, storage_.get<T>());
			storage_.destroy<T>();
		}

		template<class T>
		T* to_cpp(lua_State*, by_pointer<T>, int)
		{
			storage_.construct<T>();
			return &storage_.get<T>();
		}

		template<class T>
		static int match(lua_State*, by_pointer<T>, int)
		{
			return 0;
		}

		template<class T>
		void converter_postcall(lua_State* L, by_pointer<T>, int)
		{
			specialized_converter_policy_n<1, Policies, T, cpp_to_lua> converter;
			converter.to_lua(L, storage_.get<T>());
			storage_.destroy<T>();
		}

	private:
		out_value_detail::temporary_storage_size<Size> storage_;
	};

	template<class Policies = no_policies>
	struct pure_out_value_policy
	{
		struct only_accepts_nonconst_references_or_pointers {};
		struct can_only_convert_from_lua_to_cpp {};

		template<class T, class Direction>
		struct specialize
		{
			static_assert(std::is_same< Direction, lua_to_cpp >::value, "Pure out value policy can only convert from lua to cpp");
			static_assert(meta::or_< is_nonconst_reference<T>, is_nonconst_pointer<T> >::value, "Pure out value policy only accepts non const references or pointers");

			typedef pure_out_value_converter<indirect_sizeof<T>::value, Policies> type;
		};
	};

}}

namespace luabind
{
	template<unsigned int N, class Policies = no_policies >
	using out_value = meta::type_list<converter_policy_injector<N,detail::out_value_policy<Policies>>>;

	template<unsigned int N, class Policies = no_policies >
	using pure_out_value = meta::type_list<converter_policy_injector<N,detail::pure_out_value_policy<Policies>>>;
}

#endif // LUABIND_OUT_VALUE_POLICY_HPP_INCLUDED

<commit_msg>Fix out_value_converter compilation.<commit_after>// Copyright (c) 2003 Daniel Wallin and Arvid Norberg

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

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

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

#ifndef LUABIND_OUT_VALUE_POLICY_HPP_INCLUDED
#define LUABIND_OUT_VALUE_POLICY_HPP_INCLUDED

#include <luabind/config.hpp>
#include <luabind/detail/policy.hpp>    // for find_conversion_policy, etc
#include <luabind/detail/decorate_type.hpp>  // for decorated_type
#include <luabind/detail/primitives.hpp>  // for by_pointer, by_reference, etc
#include <luabind/detail/typetraits.hpp>  // for is_nonconst_pointer, is_nonconst_reference, etc
#include <new>                          // for operator new

namespace luabind { namespace detail
{
	template<int N>
	struct char_array
	{
		char storage[N];
	};

	template<class U>
	char_array<sizeof(typename identity<U>::type)> indirect_sizeof_test(by_reference<U>);

	template<class U>
	char_array<sizeof(typename identity<U>::type)> indirect_sizeof_test(by_const_reference<U>);

	template<class U>
	char_array<sizeof(typename identity<U>::type)> indirect_sizeof_test(by_pointer<U>);

	template<class U>
	char_array<sizeof(typename identity<U>::type)> indirect_sizeof_test(by_const_pointer<U>);

	template<class U>
	char_array<sizeof(typename identity<U>::type)> indirect_sizeof_test(by_value<U>);

	template<class T>
	struct indirect_sizeof
	{
		static const int value = sizeof(indirect_sizeof_test(decorated_type<T>()));
	};

	namespace out_value_detail {

		template< int Size >
		struct temporary_storage_size {

			template< typename T, typename... Args >
			void construct(Args&&... args)
			{
				new (&m_storage) T(std::forward<Args>(args)...);
			}

			template<typename T>
			T& get() {
				return *reinterpret_cast<T*>(&m_storage);
			}

			template<typename T>
			const T& get() const {
				return *reinterpret_cast<T*>(&m_storage);
			}

			template<typename T>
			void destroy()
			{
				get<T>().~T();
			}

			typename std::aligned_storage<Size>::type m_storage;

		};

		template< typename T >
		struct temporary_storage_type {

			template< typename... Args >
			void construct(Args&&... args)
			{
				new (&m_storage) T(std::forward<Args>(args)...);
			}

			T& get() {
				return *reinterpret_cast<T*>(&m_storage);
			}

			const T& get() const {
				return *reinterpret_cast<T*>(&m_storage);
			}

			void destroy()
			{
				get().~T();
			}

			typename std::aligned_storage<sizeof(T),alignof(T)>::type m_storage;

		};

	}

	// See note in out_value_policy about why we're not templating
	// for the parameter type.
	template<typename T, class Policies = no_policies>
	struct out_value_converter
	{
		enum { consumed_args = 1 };

        template<class T>
		T& to_cpp(lua_State* L, by_reference<T>, int index)
		{
			//specialized_converter_policy_n<1, Policies, T, lua_to_cpp> converter;
			storage_.construct(converter_.to_cpp(L, decorated_type<T>(), index));
			return storage_.get();
		}

		int match(lua_State* L, by_reference<T>, int index)
		{
			return converter_.match(L, decorated_type<T>(), index);
		}

		void converter_postcall(lua_State* L, by_reference<T>, int)
		{
			//specialized_converter_policy_n<2,Policies,T,cpp_to_lua> converter;
			converter_.to_lua(L, storage_.get());
			storage_.destroy();
		}

		T* to_cpp(lua_State* L, by_pointer<T>, int index)
		{
			storage_.construct(converter_.to_cpp(L, decorated_type<T>(), index));
			return &storage_.get();
		}

		int match(lua_State* L, by_pointer<T>, int index)
		{
			return converter_.match(L, decorated_type<T>(), index);
		}

		template<class T>
		void converter_postcall(lua_State* L, by_pointer<T>, int)
		{
			//specialized_converter_policy_n<2, Policies, T, cpp_to_lua> converter;
			converter_.to_lua(L, storage_.get());
			storage_.destroy();
		}

	private:
		specialized_converter_policy_n<1, Policies, T, lua_to_cpp > converter_;
		out_value_detail::temporary_storage_type<T> storage_;
	};

	template<class Policies = no_policies>
	struct out_value_policy
	{
		struct only_accepts_nonconst_references_or_pointers {};
		struct can_only_convert_from_lua_to_cpp {};

		template<class T, class Direction>
		struct specialize
		{
			static_assert(std::is_same< Direction, lua_to_cpp >::value, "Out value policy can only convert from lua to cpp");
			static_assert(meta::or_< is_nonconst_reference<T>, is_nonconst_pointer<T> >::value, "Out value policy only accepts non const references or pointers");

			// Note to myself:
			// Using the size and template members instead of a policy templated for the type seems
			// to be done to tame template bloat. Need to check if this is worth is.
			using base_type = typename std::remove_pointer< typename std::remove_reference< T >::type >::type;
			typedef out_value_converter<base_type, Policies> type;
		};
	};

	template<int Size, class Policies = no_policies>
	struct pure_out_value_converter
	{
		enum { consumed_args = 0 };

        template<class T>
		T& to_cpp(lua_State*, by_reference<T>, int)
		{
			storage_.construct<T>();
			return storage_.get<T>();
		}

		template<class T>
		static int match(lua_State*, by_reference<T>, int)
		{
			return 0;
		}

		template<class T>
		void converter_postcall(lua_State* L, by_reference<T>, int)
		{
			specialized_converter_policy_n<1, Policies, T, cpp_to_lua> converter;
			converter.to_lua(L, storage_.get<T>());
			storage_.destroy<T>();
		}

		template<class T>
		T* to_cpp(lua_State*, by_pointer<T>, int)
		{
			storage_.construct<T>();
			return &storage_.get<T>();
		}

		template<class T>
		static int match(lua_State*, by_pointer<T>, int)
		{
			return 0;
		}

		template<class T>
		void converter_postcall(lua_State* L, by_pointer<T>, int)
		{
			specialized_converter_policy_n<1, Policies, T, cpp_to_lua> converter;
			converter.to_lua(L, storage_.get<T>());
			storage_.destroy<T>();
		}

	private:
		out_value_detail::temporary_storage_size<Size> storage_;
	};

	template<class Policies = no_policies>
	struct pure_out_value_policy
	{
		struct only_accepts_nonconst_references_or_pointers {};
		struct can_only_convert_from_lua_to_cpp {};

		template<class T, class Direction>
		struct specialize
		{
			static_assert(std::is_same< Direction, lua_to_cpp >::value, "Pure out value policy can only convert from lua to cpp");
			static_assert(meta::or_< is_nonconst_reference<T>, is_nonconst_pointer<T> >::value, "Pure out value policy only accepts non const references or pointers");

			typedef pure_out_value_converter<indirect_sizeof<T>::value, Policies> type;
		};
	};

}}

namespace luabind
{
	template<unsigned int N, class Policies = no_policies >
	using out_value = meta::type_list<converter_policy_injector<N,detail::out_value_policy<Policies>>>;

	template<unsigned int N, class Policies = no_policies >
	using pure_out_value = meta::type_list<converter_policy_injector<N,detail::pure_out_value_policy<Policies>>>;
}

#endif // LUABIND_OUT_VALUE_POLICY_HPP_INCLUDED

<|endoftext|>


<commit_before>/*
 * Copyright (c) 2014, Ford Motor Company
 * 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 Ford Motor Company 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 HOLDER 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.
 */

#include "media_manager/audio/from_mic_to_file_recorder_thread.h"
#include <unistd.h>
#include <cstring>
#include <sstream>
#include "interfaces/MOBILE_API.h"
#include "utils/logger.h"

namespace media_manager {

SDL_CREATE_LOG_VARIABLE("MediaManager")

GMainLoop* FromMicToFileRecorderThread::loop = NULL;

// As per spec, AudioPassThru recording is in monaural
static const int kNumAudioChannels = 1;

FromMicToFileRecorderThread::FromMicToFileRecorderThread(
    const std::string& output_file,
    int32_t duration,
    mobile_apis::SamplingRate::eType sampling_rate,
    mobile_apis::BitsPerSample::eType bits_per_sample,
    mobile_apis::AudioType::eType audio_type)
    : threads::ThreadDelegate()
    , argc_(5)
    , argv_(NULL)
    , oKey_("-o")
    , tKey_("-t")
    , sleepThread_(NULL)
    , outputFileName_(output_file)
    , samplingRate_(sampling_rate)
    , bitsPerSample_(bits_per_sample) {
  SDL_LOG_AUTO_TRACE();
  set_record_duration(duration);
  // audio_type is not used as we always employ LPCM
}

FromMicToFileRecorderThread::~FromMicToFileRecorderThread() {
  SDL_LOG_AUTO_TRACE();
  if (sleepThread_) {
    sleepThread_->Stop(threads::Thread::kThreadSoftStop);
    delete sleepThread_->GetDelegate();
    threads::DeleteThread(sleepThread_);
  }
}

void FromMicToFileRecorderThread::set_output_file(
    const std::string& output_file) {
  SDL_LOG_AUTO_TRACE();
  outputFileName_ = output_file;
}

void FromMicToFileRecorderThread::set_record_duration(int32_t duration) {
  SDL_LOG_AUTO_TRACE();

  std::stringstream stringStream;
  stringStream << duration / 1000;
  durationString_ = stringStream.str();
}

void FromMicToFileRecorderThread::initArgs() {
  SDL_LOG_AUTO_TRACE();

  argv_ = new gchar*[argc_];

  argv_[0] = new gchar[14];
  argv_[1] = new gchar[3];
  argv_[2] = new gchar[outputFileName_.length() + 1];
  argv_[3] = new gchar[3];
  argv_[4] = new gchar[durationString_.length() + 1];

  std::strcpy(argv_[0], "AudioManager");
  std::strcpy(argv_[1], oKey_.c_str());
  std::strcpy(argv_[2], outputFileName_.c_str());
  std::strcpy(argv_[3], tKey_.c_str());
  std::strcpy(argv_[4], durationString_.c_str());
}

void FromMicToFileRecorderThread::deinitArgs() {
  SDL_LOG_AUTO_TRACE();

  if (argv_) {
    for (int32_t i = 0; i < argc_; ++i) {
      delete[] argv_[i];
    }
    delete[] argv_;
    argv_ = NULL;
  }
}

void FromMicToFileRecorderThread::threadMain() {
  SDL_LOG_AUTO_TRACE();

  {
    sync_primitives::AutoLock auto_lock(stopFlagLock_);
    shouldBeStoped_ = false;
  }

  initArgs();

  GstElement* pipeline;
  GstElement *alsasrc, *audioconvert, *capsfilter, *wavenc, *filesink;
  GstCaps* audiocaps;
  GstBus* bus;

  const gchar* device = "hw:0,0";
  gchar* outfile = NULL;
  gint duration = -1;
  GOptionContext* context = NULL;
  GError* err = NULL;
  GOptionEntry entries[] = {{"device",
                             'd',
                             0,
                             G_OPTION_ARG_FILENAME,
                             &device,
                             "device file (Default: hw:0,0)",
                             "SRC"},
                            {"output",
                             'o',
                             0,
                             G_OPTION_ARG_FILENAME,
                             &outfile,
                             "save output of the stream to DEST",
                             "DEST"},
                            {"duration",
                             't',
                             0,
                             G_OPTION_ARG_INT,
                             &duration,
                             "length of time in seconds to capture",
                             "int32_t"},
                            {NULL}};
  // g_option_context_parse() modifies params, so keep argc_ and argv_
  int32_t argc = argc_;
  gchar** argv = new gchar*[argc];
  for (int32_t i = 0; i < argc; ++i) {
    argv[i] = argv_[i];
  }

#ifndef GLIB_VERSION_2_32  // g_thread_init() does nothing since 2.32
  if (!g_thread_supported()) {
    g_thread_init(NULL);
  }
#endif
  // Parse the arguments
  context = g_option_context_new("-- M-AUDIO RAW");
  g_option_context_add_main_entries(context, entries, NULL);
  g_option_context_add_group(context, gst_init_get_option_group());
  if (!g_option_context_parse(context, &argc, &argv, &err)) {
    g_error("%s\n", err->message);
  }

  // Check for proper arguments
  if (outfile == NULL) {
    g_error("Must supply destination (-d FILE)\n");
  }

  SDL_LOG_TRACE("Reading from device: " << device);
  SDL_LOG_TRACE("Saving pipeline output to: " << outfile);
  SDL_LOG_TRACE("Duration set to: " << duration);

  // Initialize gstreamer and setup the main loop information
  gst_init(&argc, &argv);

  delete[] argv;
  argv = NULL;

  pipeline = gst_pipeline_new("vga2usb-h264");

  // Set up error handling
  bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
  gst_bus_add_watch(
      bus,
      reinterpret_cast<int32_t (*)(_GstBus*, _GstMessage*, void*)>(recvmsg),
      NULL);
  gst_object_unref(bus);

  // Create all of the elements to be added to the pipeline
  alsasrc = gst_element_factory_make("alsasrc", "alsasrc0");
  audioconvert = gst_element_factory_make("audioconvert", "audioconvert0");
  capsfilter = gst_element_factory_make("capsfilter", "filter0");
  wavenc = gst_element_factory_make("wavenc", "wavenc0");
  filesink = gst_element_factory_make("filesink", "filesink0");

  // Create a capability to specify audio format. It also downmixes the recorded
  // audio to monaural.
  std::string caps_string = create_caps_string();
  SDL_LOG_DEBUG("Using audio caps: " << caps_string);
  audiocaps = gst_caps_from_string(caps_string.c_str());

  // Assert that all the elements were created
  if (!alsasrc || !audioconvert || !capsfilter || !wavenc || !filesink ||
      !audiocaps) {
    g_error("Failed creating one or more of the pipeline elements.\n");
  }

  // Set input and output destinations
  g_object_set(G_OBJECT(alsasrc), "device", device, NULL);
  g_object_set(G_OBJECT(filesink), "location", outfile, NULL);

  // Add the elements to the pipeline
  gst_bin_add_many(GST_BIN(pipeline),
                   alsasrc,
                   audioconvert,
                   capsfilter,
                   wavenc,
                   filesink,
                   NULL);

  // Link the elements
  gst_element_link_many(
      alsasrc, audioconvert, capsfilter, wavenc, filesink, NULL);

  // set the capability
  g_object_set(G_OBJECT(capsfilter), "caps", audiocaps, NULL);
  gst_caps_unref(audiocaps);

  gst_element_set_state(pipeline, GST_STATE_PLAYING);

  SDL_LOG_TRACE("Initializing pipeline ...");
  while (GST_STATE(pipeline) != GST_STATE_PLAYING) {
    bool shouldBeStoped;
    {
      // FIXME(dchmerev@luxoft.com):
      sync_primitives::AutoLock auto_lock(stopFlagLock_);
      shouldBeStoped = shouldBeStoped_;
    }

    if (shouldBeStoped) {
      gst_element_set_state(pipeline, GST_STATE_NULL);
      gst_object_unref(GST_OBJECT(pipeline));
      g_option_context_free(context);

      deinitArgs();
      return;
    }
  }
  SDL_LOG_TRACE("Pipeline started ...\n");

  // Start up a timer for the pipeline
  if (duration > 0) {
    GstTimeout timeout;
    timeout.pipeline = pipeline;
    timeout.duration = duration;

    sleepThread_ =
        threads::CreateThread("SleepThread", new SleepThreadDelegate(timeout));
    sleepThread_->Start();
  }

  loop = g_main_loop_new(NULL, FALSE);

  g_main_loop_run(loop);

  gst_element_set_state(pipeline, GST_STATE_NULL);

  SDL_LOG_TRACE("Deleting pipeline\n");
  gst_object_unref(GST_OBJECT(pipeline));
  g_main_loop_unref(loop);
  g_option_context_free(context);

  deinitArgs();

  loop = NULL;
}

std::string FromMicToFileRecorderThread::create_caps_string() {
  SDL_LOG_AUTO_TRACE();

  std::stringstream ss;
  ss << "audio/x-raw";

  switch (bitsPerSample_) {
    case mobile_apis::BitsPerSample::BitsPerSample_8_BIT:
      // format is 8-bit unsigned
      ss << ",format=(string)U8";
      break;
    case mobile_apis::BitsPerSample::BitsPerSample_16_BIT:
      // format is 16-bit signed, in little endian
      ss << ",format=(string)S16LE";
      break;
    default:
      // do not specify the format; use system default
      break;
  }

  switch (samplingRate_) {
    case mobile_apis::SamplingRate::SamplingRate_8KHZ:
      ss << ",rate=8000";
      break;
    case mobile_apis::SamplingRate::SamplingRate_16KHZ:
      ss << ",rate=16000";
      break;
    case mobile_apis::SamplingRate::SamplingRate_22KHZ:
      ss << ",rate=22050";
      break;
    case mobile_apis::SamplingRate::SamplingRate_44KHZ:
      ss << ",rate=44100";
      break;
    default:
      // do not specify the sampling rate; use system default
      break;
  }

  ss << ",channels=" << kNumAudioChannels;

  return ss.str();
}

FromMicToFileRecorderThread::SleepThreadDelegate::SleepThreadDelegate(
    GstTimeout timeout)
    : threads::ThreadDelegate(), timeout_(timeout) {}

void FromMicToFileRecorderThread::SleepThreadDelegate::threadMain() {
  SDL_LOG_TRACE("Sleep for " << timeout_.duration << " seconds");

  sleep(timeout_.duration);

  if (NULL != loop) {
    if (g_main_loop_is_running(loop)) {
      gst_element_send_event(timeout_.pipeline, gst_event_new_eos());
    }
  }
}

void FromMicToFileRecorderThread::exitThreadMain() {
  SDL_LOG_AUTO_TRACE();

  if (NULL != loop) {
    if (g_main_loop_is_running(loop)) {
      SDL_LOG_TRACE("Quit loop\n");
      g_main_loop_quit(loop);
    }
  }

  if (sleepThread_) {
    SDL_LOG_DEBUG("Stop sleep thread\n");
    sleepThread_->stop();
  }

  SDL_LOG_TRACE("Set should be stopped flag\n");
  sync_primitives::AutoLock auto_lock(stopFlagLock_);
  shouldBeStoped_ = true;
}

}  // namespace media_manager
<commit_msg>Fix thread stop method (#3712)<commit_after>/*
 * Copyright (c) 2014, Ford Motor Company
 * 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 Ford Motor Company 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 HOLDER 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.
 */

#include "media_manager/audio/from_mic_to_file_recorder_thread.h"
#include <unistd.h>
#include <cstring>
#include <sstream>
#include "interfaces/MOBILE_API.h"
#include "utils/logger.h"

namespace media_manager {

SDL_CREATE_LOG_VARIABLE("MediaManager")

GMainLoop* FromMicToFileRecorderThread::loop = NULL;

// As per spec, AudioPassThru recording is in monaural
static const int kNumAudioChannels = 1;

FromMicToFileRecorderThread::FromMicToFileRecorderThread(
    const std::string& output_file,
    int32_t duration,
    mobile_apis::SamplingRate::eType sampling_rate,
    mobile_apis::BitsPerSample::eType bits_per_sample,
    mobile_apis::AudioType::eType audio_type)
    : threads::ThreadDelegate()
    , argc_(5)
    , argv_(NULL)
    , oKey_("-o")
    , tKey_("-t")
    , sleepThread_(NULL)
    , outputFileName_(output_file)
    , samplingRate_(sampling_rate)
    , bitsPerSample_(bits_per_sample) {
  SDL_LOG_AUTO_TRACE();
  set_record_duration(duration);
  // audio_type is not used as we always employ LPCM
}

FromMicToFileRecorderThread::~FromMicToFileRecorderThread() {
  SDL_LOG_AUTO_TRACE();
  if (sleepThread_) {
    sleepThread_->Stop(threads::Thread::kThreadSoftStop);
    delete sleepThread_->GetDelegate();
    threads::DeleteThread(sleepThread_);
  }
}

void FromMicToFileRecorderThread::set_output_file(
    const std::string& output_file) {
  SDL_LOG_AUTO_TRACE();
  outputFileName_ = output_file;
}

void FromMicToFileRecorderThread::set_record_duration(int32_t duration) {
  SDL_LOG_AUTO_TRACE();

  std::stringstream stringStream;
  stringStream << duration / 1000;
  durationString_ = stringStream.str();
}

void FromMicToFileRecorderThread::initArgs() {
  SDL_LOG_AUTO_TRACE();

  argv_ = new gchar*[argc_];

  argv_[0] = new gchar[14];
  argv_[1] = new gchar[3];
  argv_[2] = new gchar[outputFileName_.length() + 1];
  argv_[3] = new gchar[3];
  argv_[4] = new gchar[durationString_.length() + 1];

  std::strcpy(argv_[0], "AudioManager");
  std::strcpy(argv_[1], oKey_.c_str());
  std::strcpy(argv_[2], outputFileName_.c_str());
  std::strcpy(argv_[3], tKey_.c_str());
  std::strcpy(argv_[4], durationString_.c_str());
}

void FromMicToFileRecorderThread::deinitArgs() {
  SDL_LOG_AUTO_TRACE();

  if (argv_) {
    for (int32_t i = 0; i < argc_; ++i) {
      delete[] argv_[i];
    }
    delete[] argv_;
    argv_ = NULL;
  }
}

void FromMicToFileRecorderThread::threadMain() {
  SDL_LOG_AUTO_TRACE();

  {
    sync_primitives::AutoLock auto_lock(stopFlagLock_);
    shouldBeStoped_ = false;
  }

  initArgs();

  GstElement* pipeline;
  GstElement *alsasrc, *audioconvert, *capsfilter, *wavenc, *filesink;
  GstCaps* audiocaps;
  GstBus* bus;

  const gchar* device = "hw:0,0";
  gchar* outfile = NULL;
  gint duration = -1;
  GOptionContext* context = NULL;
  GError* err = NULL;
  GOptionEntry entries[] = {{"device",
                             'd',
                             0,
                             G_OPTION_ARG_FILENAME,
                             &device,
                             "device file (Default: hw:0,0)",
                             "SRC"},
                            {"output",
                             'o',
                             0,
                             G_OPTION_ARG_FILENAME,
                             &outfile,
                             "save output of the stream to DEST",
                             "DEST"},
                            {"duration",
                             't',
                             0,
                             G_OPTION_ARG_INT,
                             &duration,
                             "length of time in seconds to capture",
                             "int32_t"},
                            {NULL}};
  // g_option_context_parse() modifies params, so keep argc_ and argv_
  int32_t argc = argc_;
  gchar** argv = new gchar*[argc];
  for (int32_t i = 0; i < argc; ++i) {
    argv[i] = argv_[i];
  }

#ifndef GLIB_VERSION_2_32  // g_thread_init() does nothing since 2.32
  if (!g_thread_supported()) {
    g_thread_init(NULL);
  }
#endif
  // Parse the arguments
  context = g_option_context_new("-- M-AUDIO RAW");
  g_option_context_add_main_entries(context, entries, NULL);
  g_option_context_add_group(context, gst_init_get_option_group());
  if (!g_option_context_parse(context, &argc, &argv, &err)) {
    g_error("%s\n", err->message);
  }

  // Check for proper arguments
  if (outfile == NULL) {
    g_error("Must supply destination (-d FILE)\n");
  }

  SDL_LOG_TRACE("Reading from device: " << device);
  SDL_LOG_TRACE("Saving pipeline output to: " << outfile);
  SDL_LOG_TRACE("Duration set to: " << duration);

  // Initialize gstreamer and setup the main loop information
  gst_init(&argc, &argv);

  delete[] argv;
  argv = NULL;

  pipeline = gst_pipeline_new("vga2usb-h264");

  // Set up error handling
  bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
  gst_bus_add_watch(
      bus,
      reinterpret_cast<int32_t (*)(_GstBus*, _GstMessage*, void*)>(recvmsg),
      NULL);
  gst_object_unref(bus);

  // Create all of the elements to be added to the pipeline
  alsasrc = gst_element_factory_make("alsasrc", "alsasrc0");
  audioconvert = gst_element_factory_make("audioconvert", "audioconvert0");
  capsfilter = gst_element_factory_make("capsfilter", "filter0");
  wavenc = gst_element_factory_make("wavenc", "wavenc0");
  filesink = gst_element_factory_make("filesink", "filesink0");

  // Create a capability to specify audio format. It also downmixes the recorded
  // audio to monaural.
  std::string caps_string = create_caps_string();
  SDL_LOG_DEBUG("Using audio caps: " << caps_string);
  audiocaps = gst_caps_from_string(caps_string.c_str());

  // Assert that all the elements were created
  if (!alsasrc || !audioconvert || !capsfilter || !wavenc || !filesink ||
      !audiocaps) {
    g_error("Failed creating one or more of the pipeline elements.\n");
  }

  // Set input and output destinations
  g_object_set(G_OBJECT(alsasrc), "device", device, NULL);
  g_object_set(G_OBJECT(filesink), "location", outfile, NULL);

  // Add the elements to the pipeline
  gst_bin_add_many(GST_BIN(pipeline),
                   alsasrc,
                   audioconvert,
                   capsfilter,
                   wavenc,
                   filesink,
                   NULL);

  // Link the elements
  gst_element_link_many(
      alsasrc, audioconvert, capsfilter, wavenc, filesink, NULL);

  // set the capability
  g_object_set(G_OBJECT(capsfilter), "caps", audiocaps, NULL);
  gst_caps_unref(audiocaps);

  gst_element_set_state(pipeline, GST_STATE_PLAYING);

  SDL_LOG_TRACE("Initializing pipeline ...");
  while (GST_STATE(pipeline) != GST_STATE_PLAYING) {
    bool shouldBeStoped;
    {
      // FIXME(dchmerev@luxoft.com):
      sync_primitives::AutoLock auto_lock(stopFlagLock_);
      shouldBeStoped = shouldBeStoped_;
    }

    if (shouldBeStoped) {
      gst_element_set_state(pipeline, GST_STATE_NULL);
      gst_object_unref(GST_OBJECT(pipeline));
      g_option_context_free(context);

      deinitArgs();
      return;
    }
  }
  SDL_LOG_TRACE("Pipeline started ...\n");

  // Start up a timer for the pipeline
  if (duration > 0) {
    GstTimeout timeout;
    timeout.pipeline = pipeline;
    timeout.duration = duration;

    sleepThread_ =
        threads::CreateThread("SleepThread", new SleepThreadDelegate(timeout));
    sleepThread_->Start();
  }

  loop = g_main_loop_new(NULL, FALSE);

  g_main_loop_run(loop);

  gst_element_set_state(pipeline, GST_STATE_NULL);

  SDL_LOG_TRACE("Deleting pipeline\n");
  gst_object_unref(GST_OBJECT(pipeline));
  g_main_loop_unref(loop);
  g_option_context_free(context);

  deinitArgs();

  loop = NULL;
}

std::string FromMicToFileRecorderThread::create_caps_string() {
  SDL_LOG_AUTO_TRACE();

  std::stringstream ss;
  ss << "audio/x-raw";

  switch (bitsPerSample_) {
    case mobile_apis::BitsPerSample::BitsPerSample_8_BIT:
      // format is 8-bit unsigned
      ss << ",format=(string)U8";
      break;
    case mobile_apis::BitsPerSample::BitsPerSample_16_BIT:
      // format is 16-bit signed, in little endian
      ss << ",format=(string)S16LE";
      break;
    default:
      // do not specify the format; use system default
      break;
  }

  switch (samplingRate_) {
    case mobile_apis::SamplingRate::SamplingRate_8KHZ:
      ss << ",rate=8000";
      break;
    case mobile_apis::SamplingRate::SamplingRate_16KHZ:
      ss << ",rate=16000";
      break;
    case mobile_apis::SamplingRate::SamplingRate_22KHZ:
      ss << ",rate=22050";
      break;
    case mobile_apis::SamplingRate::SamplingRate_44KHZ:
      ss << ",rate=44100";
      break;
    default:
      // do not specify the sampling rate; use system default
      break;
  }

  ss << ",channels=" << kNumAudioChannels;

  return ss.str();
}

FromMicToFileRecorderThread::SleepThreadDelegate::SleepThreadDelegate(
    GstTimeout timeout)
    : threads::ThreadDelegate(), timeout_(timeout) {}

void FromMicToFileRecorderThread::SleepThreadDelegate::threadMain() {
  SDL_LOG_TRACE("Sleep for " << timeout_.duration << " seconds");

  sleep(timeout_.duration);

  if (NULL != loop) {
    if (g_main_loop_is_running(loop)) {
      gst_element_send_event(timeout_.pipeline, gst_event_new_eos());
    }
  }
}

void FromMicToFileRecorderThread::exitThreadMain() {
  SDL_LOG_AUTO_TRACE();

  if (NULL != loop) {
    if (g_main_loop_is_running(loop)) {
      SDL_LOG_TRACE("Quit loop\n");
      g_main_loop_quit(loop);
    }
  }

  if (sleepThread_) {
    SDL_LOG_DEBUG("Stop sleep thread\n");
    sleepThread_->Stop(threads::Thread::kThreadStopDelegate);
  }

  SDL_LOG_TRACE("Set should be stopped flag\n");
  sync_primitives::AutoLock auto_lock(stopFlagLock_);
  shouldBeStoped_ = true;
}

}  // namespace media_manager
<|endoftext|>


<commit_before><commit_msg>tpcNClsFound -> tpcNClsFoundMin<commit_after><|endoftext|>