<commit_before>// ======================================================================== //
// Copyright 2009-2017 Intel Corporation                                    //
//                                                                          //
// Licensed under the Apache License, Version 2.0 (the "License");          //
// you may not use this file except in compliance with the License.         //
// You may obtain a copy of the License at                                  //
//                                                                          //
//     http://www.apache.org/licenses/LICENSE-2.0                           //
//                                                                          //
// Unless required by applicable law or agreed to in writing, software      //
// distributed under the License is distributed on an "AS IS" BASIS,        //
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
// See the License for the specific language governing permissions and      //
// limitations under the License.                                           //
// ======================================================================== //

#include <limits>
// ospray
#include "mpi/volume/DataDistributedBlockedVolume.h"
#include "volume/GhostBlockBrickedVolume.h"
#include "transferFunction/TransferFunction.h"
#include "volume/GhostBlockBrickedVolume.h"
#include "mpi/common/Core.h"
#if EXP_DATA_PARALLEL
#include "mpi/common/MPICommon.h"
#endif
// ispc exports:
#include "DataDistributedBlockedVolume_ispc.h"

namespace ospray {

#if EXP_DATA_PARALLEL

  //! Allocate storage and populate the volume, called through the OSPRay API.
  void DataDistributedBlockedVolume::commit()
  {
    // IW: do NOT call parent commit here - this would try to build
    // the parent acceleration strucutre, which doesn't make sense on
    // blocks that do not exist!!!!

    updateEditableParameters();//

    StructuredVolume::commit();

    for (uint32_t i=0;i<numDDBlocks;i++) {
      DDBlock *block = ddBlock+i;
      if (!block->isMine) {
        continue;
      }
      block->cppVolume->commit();
    }
  }

  DataDistributedBlockedVolume::DataDistributedBlockedVolume() :
    numDDBlocks(0),
    ddBlock(NULL)
  {
    PING;
  }

  void DataDistributedBlockedVolume::updateEditableParameters()
  {
    StructuredVolume::updateEditableParameters();
    for (uint32_t i = 0; i < numDDBlocks; i++) {
      DDBlock *block = ddBlock+i;

      if (!block->isMine) {
        continue;
      }

      Ref<TransferFunction> transferFunction
        = (TransferFunction *)getParamObject("transferFunction", NULL);

      auto &cppVolume = block->cppVolume;
      cppVolume->findParam("transferFunction",1)->set(transferFunction.ptr);

      cppVolume->findParam("samplingRate",1)->set(getParam1f("samplingRate",
                                                             1.f));
      cppVolume->findParam("gradientShadingEnabled",
                           1)->set(getParam1i("gradientShadingEnabled", 0));

      cppVolume.ptr->updateEditableParameters();
    }
  }

  bool DataDistributedBlockedVolume::isDataDistributed() const
  {
    return true;
  }

  void DataDistributedBlockedVolume::buildAccelerator()
  {
    std::cout << "intentionally SKIP building an accelerator for data parallel "
              << "volume (this'll be done on the brick level)" << std::endl;
  }

  std::string DataDistributedBlockedVolume::toString() const
  {
    return("ospray::DataDistributedBlockedVolume<" + voxelType + ">");
  }

  //! Copy voxels into the volume at the given index (non-zero return value
  //! indicates success).
  int DataDistributedBlockedVolume::setRegion(
      /* points to the first voxel to be copies. The
         voxels at 'soruce' MUST have dimensions
         'regionSize', must be organized in 3D-array
         order, and must have the same voxel type as the
         volume.*/
      const void *source,
      /*! coordinates of the lower,
        left, front corner of the target
        region.*/
      const vec3i &regionCoords,
      /*! size of the region that we're writing to; MUST
        be the same as the dimensions of source[][][] */
      const vec3i &regionSize)
  {
    // Create the equivalent ISPC volume container and allocate memory for voxel
    // data.
    if (ispcEquivalent == NULL) createEquivalentISPC();

    // The block domains are in terms of the scaled regions so we must check
    // if the data is for the block in the scaled volume
    vec3i finalRegionCoords(vec3f(regionCoords) * scaleFactor);
    vec3i finalRegionSize(vec3f(regionSize) * scaleFactor);
    if (scaleFactor != vec3f(-1.f)) {
      finalRegionCoords = vec3i(vec3f(regionCoords) * scaleFactor);
      finalRegionSize = vec3i(vec3f(regionSize) * scaleFactor);
    } else {
      finalRegionCoords = regionCoords;
      finalRegionSize = regionSize;
    }

    for (uint32_t i = 0; i < numDDBlocks; i++) {
      // that block isn't mine, I shouldn't care ...
      if (!ddBlock[i].isMine) continue;

      // first, do some culling to make sure we only do setrgion
      // calls on blocks that actually map to this block
      if (ddBlock[i].domain.lower.x >= finalRegionCoords.x+finalRegionSize.x) continue;
      if (ddBlock[i].domain.lower.y >= finalRegionCoords.y+finalRegionSize.y) continue;
      if (ddBlock[i].domain.lower.z >= finalRegionCoords.z+finalRegionSize.z) continue;

      if (ddBlock[i].domain.upper.x+finalRegionSize.x < finalRegionCoords.x) continue;
      if (ddBlock[i].domain.upper.y+finalRegionSize.y < finalRegionCoords.y) continue;
      if (ddBlock[i].domain.upper.z+finalRegionSize.z < finalRegionCoords.z) continue;

      vec3i setRegionCoords = finalRegionCoords - ddBlock[i].domain.lower;
      if (scaleFactor != vec3f(-1.f)) {
        setRegionCoords = vec3i(vec3f(setRegionCoords) / scaleFactor);
      }

      ddBlock[i].cppVolume->setRegion(source, setRegionCoords, regionSize);

      ddBlock[i].ispcVolume = ddBlock[i].cppVolume->getIE();

#ifndef OSPRAY_VOLUME_VOXELRANGE_IN_APP
      ManagedObject::Param *param = ddBlock[i].cppVolume->findParam("voxelRange");
      if (param != NULL && param->type == OSP_FLOAT2){
        vec2f blockRange = param->u_vec2f;
        voxelRange.x = std::min(voxelRange.x, blockRange.x);
        voxelRange.y = std::max(voxelRange.y, blockRange.y);
      }
#endif
    }

#ifndef OSPRAY_VOLUME_VOXELRANGE_IN_APP
    // Do a reduction here to worker 0 since it will be queried for the voxel range by the display node
    vec2f globalVoxelRange = voxelRange;
    MPI_CALL(Reduce(&voxelRange.x, &globalVoxelRange.x, 1, MPI_FLOAT, MPI_MIN, 0, mpi::worker.comm));
    MPI_CALL(Reduce(&voxelRange.y, &globalVoxelRange.y, 1, MPI_FLOAT, MPI_MAX, 0, mpi::worker.comm));
    set("voxelRange", globalVoxelRange);
#endif
    return true;
  }

  void DataDistributedBlockedVolume::createEquivalentISPC()
  {
    if (ispcEquivalent != NULL) return;

    // Get the voxel type.
    voxelType = getParamString("voxelType", "unspecified");
    exitOnCondition(getVoxelType() == OSP_UNKNOWN,
                    "unrecognized voxel type (must be set before calling "
                    "ospSetRegion())");

    // Get the volume dimensions.
    this->dimensions = getParam3i("dimensions", vec3i(0));
    exitOnCondition(reduce_min(this->dimensions) <= 0,
                    "invalid volume dimensions (must be set before calling "
                    "ospSetRegion())");

    ddBlocks    = getParam3i("num_dp_blocks",vec3i(4,4,4));
    blockSize   = divRoundUp(dimensions,ddBlocks);
    std::cout << "#osp:dp: using data parallel volume of " << ddBlocks
              << " blocks, blockSize is " << blockSize << std::endl;

    // Set the grid origin, default to (0,0,0).
    this->gridOrigin = getParam3f("gridOrigin", vec3f(0.f));

    // Get the volume dimensions.
    this->dimensions = getParam3i("dimensions", vec3i(0));
    exitOnCondition(reduce_min(this->dimensions) <= 0,
                    "invalid volume dimensions");

    // Set the grid spacing, default to (1,1,1).
    this->gridSpacing = getParam3f("gridSpacing", vec3f(1.f));

    this->scaleFactor = getParam3f("scaleFactor", vec3f(-1.f));

    numDDBlocks = ospcommon::reduce_mul(ddBlocks);
    ddBlock     = new DDBlock[numDDBlocks];

    printf("=======================================================\n");
    printf("created %ix%ix%i data distributed volume blocks\n",
           ddBlocks.x,ddBlocks.y,ddBlocks.z);
    printf("=======================================================\n");

    if (!ospray::core::isMpiParallel()) {
      throw std::runtime_error("data parallel volume, but not in mpi parallel "
                               "mode...");
    }
    uint64_t numWorkers = ospray::core::getWorkerCount();
    // PRINT(numDDBlocks);
    // PRINT(numWorkers);

    voxelType = getParamString("voxelType", "unspecified");

    // if (numDDBlocks >= numWorkers) {
    // we have more workers than blocks - use one owner per block,
    // meaning we'll end up with multiple blocks per worker
    int blockID = 0;
    for (int iz=0;iz<ddBlocks.z;iz++)
      for (int iy=0;iy<ddBlocks.y;iy++)
        for (int ix=0;ix<ddBlocks.x;ix++, blockID++) {
          DDBlock *block = &ddBlock[blockID];
          if (numDDBlocks >= numWorkers) {
            block->firstOwner = blockID % numWorkers;
            block->numOwners = 1;
          } else {
            block->firstOwner = (blockID * numWorkers) / numDDBlocks;
            int nextBlockFirstOwner = ((blockID+1)*numWorkers) / numDDBlocks;
            block->numOwners = nextBlockFirstOwner - block->firstOwner; // + 1;
          }
          block->isMine
            = (ospray::core::getWorkerRank() >= block->firstOwner)
            && (ospray::core::getWorkerRank() <
                (block->firstOwner + block->numOwners));
          block->domain.lower = vec3i(ix,iy,iz) * blockSize;
          block->domain.upper = min(block->domain.lower+blockSize,dimensions);
          block->bounds.lower = gridOrigin +
            (gridSpacing * vec3f(block->domain.lower));
          block->bounds.upper = gridOrigin +
            (gridSpacing * vec3f(block->domain.upper));

          // iw: add one voxel overlap, so we can properly interpolate
          // even across block boundaries (we need the full *cell* on
          // the right side, not just the last *voxel*!)
          block->domain.upper = min(block->domain.upper+vec3i(1),dimensions);

          if (block->isMine) {
#ifdef EXP_NEW_BB_VOLUME_KERNELS
            Ref<Volume> volume = new GhostBlockBrickedVolume;
#else
            Ref<Volume> volume = new BlockBrickedVolume;
#endif
            vec3i blockDims = block->domain.upper - block->domain.lower;
            volume->findParam("dimensions",1)->set(blockDims);
            volume->findParam("gridOrigin",1)->set(block->bounds.lower);
            volume->findParam("gridSpacing",1)->set(gridSpacing);
            volume->findParam("voxelType",1)->set(voxelType.c_str());
            if (scaleFactor != vec3f(-1.f)) {
              volume->findParam("scaleFactor",1)->set(scaleFactor);
            }

            printf("worker rank %li owns block %i,%i,%i (ID %i), dims %i %i %i\n",
                   (size_t)core::getWorkerRank(),ix,iy,iz,
                   blockID,blockDims.x,blockDims.y,blockDims.z);
            block->cppVolume = volume;
            block->ispcVolume = NULL; //volume->getIE();
          } else {
            block->ispcVolume = NULL;
            block->cppVolume = NULL;
          }
        }

    // Create an ISPC BlockBrickedVolume object and assign type-specific
    // function pointers.
    ispcEquivalent = ispc::DDBVolume_create(this,
                                            (int)getVoxelType(),
                                            (const ispc::vec3i&)dimensions,
                                            (const ispc::vec3i&)ddBlocks,
                                            (const ispc::vec3i&)blockSize,
                                            ddBlock);
    if (!ispcEquivalent) {
      throw std::runtime_error("could not create create data distributed "
                               "volume");
    }
  }

  // A volume type with internal data-distribution. needs a renderer
  // that is capable of data-parallel rendering!
  OSP_REGISTER_VOLUME(DataDistributedBlockedVolume, data_distributed_volume);

#endif

} // ::ospray
<commit_msg>We no longer need the voxelrange setup stuff<commit_after>// ======================================================================== //
// Copyright 2009-2017 Intel Corporation                                    //
//                                                                          //
// Licensed under the Apache License, Version 2.0 (the "License");          //
// you may not use this file except in compliance with the License.         //
// You may obtain a copy of the License at                                  //
//                                                                          //
//     http://www.apache.org/licenses/LICENSE-2.0                           //
//                                                                          //
// Unless required by applicable law or agreed to in writing, software      //
// distributed under the License is distributed on an "AS IS" BASIS,        //
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
// See the License for the specific language governing permissions and      //
// limitations under the License.                                           //
// ======================================================================== //

#include <limits>
// ospray
#include "mpi/volume/DataDistributedBlockedVolume.h"
#include "volume/GhostBlockBrickedVolume.h"
#include "transferFunction/TransferFunction.h"
#include "volume/GhostBlockBrickedVolume.h"
#include "mpi/common/Core.h"
#if EXP_DATA_PARALLEL
#include "mpi/common/MPICommon.h"
#endif
// ispc exports:
#include "DataDistributedBlockedVolume_ispc.h"

namespace ospray {

#if EXP_DATA_PARALLEL

  //! Allocate storage and populate the volume, called through the OSPRay API.
  void DataDistributedBlockedVolume::commit()
  {
    // IW: do NOT call parent commit here - this would try to build
    // the parent acceleration strucutre, which doesn't make sense on
    // blocks that do not exist!!!!

    updateEditableParameters();//

    StructuredVolume::commit();

    for (uint32_t i=0;i<numDDBlocks;i++) {
      DDBlock *block = ddBlock+i;
      if (!block->isMine) {
        continue;
      }
      block->cppVolume->commit();
    }
  }

  DataDistributedBlockedVolume::DataDistributedBlockedVolume() :
    numDDBlocks(0),
    ddBlock(NULL)
  {
    PING;
  }

  void DataDistributedBlockedVolume::updateEditableParameters()
  {
    StructuredVolume::updateEditableParameters();
    for (uint32_t i = 0; i < numDDBlocks; i++) {
      DDBlock *block = ddBlock+i;

      if (!block->isMine) {
        continue;
      }

      Ref<TransferFunction> transferFunction
        = (TransferFunction *)getParamObject("transferFunction", NULL);

      auto &cppVolume = block->cppVolume;
      cppVolume->findParam("transferFunction",1)->set(transferFunction.ptr);

      cppVolume->findParam("samplingRate",1)->set(getParam1f("samplingRate",
                                                             1.f));
      cppVolume->findParam("gradientShadingEnabled",
                           1)->set(getParam1i("gradientShadingEnabled", 0));

      cppVolume.ptr->updateEditableParameters();
    }
  }

  bool DataDistributedBlockedVolume::isDataDistributed() const
  {
    return true;
  }

  void DataDistributedBlockedVolume::buildAccelerator()
  {
    std::cout << "intentionally SKIP building an accelerator for data parallel "
              << "volume (this'll be done on the brick level)" << std::endl;
  }

  std::string DataDistributedBlockedVolume::toString() const
  {
    return("ospray::DataDistributedBlockedVolume<" + voxelType + ">");
  }

  //! Copy voxels into the volume at the given index (non-zero return value
  //! indicates success).
  int DataDistributedBlockedVolume::setRegion(
      /* points to the first voxel to be copies. The
         voxels at 'soruce' MUST have dimensions
         'regionSize', must be organized in 3D-array
         order, and must have the same voxel type as the
         volume.*/
      const void *source,
      /*! coordinates of the lower,
        left, front corner of the target
        region.*/
      const vec3i &regionCoords,
      /*! size of the region that we're writing to; MUST
        be the same as the dimensions of source[][][] */
      const vec3i &regionSize)
  {
    // Create the equivalent ISPC volume container and allocate memory for voxel
    // data.
    if (ispcEquivalent == NULL) createEquivalentISPC();

    // The block domains are in terms of the scaled regions so we must check
    // if the data is for the block in the scaled volume
    vec3i finalRegionCoords(vec3f(regionCoords) * scaleFactor);
    vec3i finalRegionSize(vec3f(regionSize) * scaleFactor);
    if (scaleFactor != vec3f(-1.f)) {
      finalRegionCoords = vec3i(vec3f(regionCoords) * scaleFactor);
      finalRegionSize = vec3i(vec3f(regionSize) * scaleFactor);
    } else {
      finalRegionCoords = regionCoords;
      finalRegionSize = regionSize;
    }

    for (uint32_t i = 0; i < numDDBlocks; i++) {
      // that block isn't mine, I shouldn't care ...
      if (!ddBlock[i].isMine) continue;

      // first, do some culling to make sure we only do setrgion
      // calls on blocks that actually map to this block
      if (ddBlock[i].domain.lower.x >= finalRegionCoords.x+finalRegionSize.x) continue;
      if (ddBlock[i].domain.lower.y >= finalRegionCoords.y+finalRegionSize.y) continue;
      if (ddBlock[i].domain.lower.z >= finalRegionCoords.z+finalRegionSize.z) continue;

      if (ddBlock[i].domain.upper.x+finalRegionSize.x < finalRegionCoords.x) continue;
      if (ddBlock[i].domain.upper.y+finalRegionSize.y < finalRegionCoords.y) continue;
      if (ddBlock[i].domain.upper.z+finalRegionSize.z < finalRegionCoords.z) continue;

      vec3i setRegionCoords = finalRegionCoords - ddBlock[i].domain.lower;
      if (scaleFactor != vec3f(-1.f)) {
        setRegionCoords = vec3i(vec3f(setRegionCoords) / scaleFactor);
      }

      ddBlock[i].cppVolume->setRegion(source, setRegionCoords, regionSize);

      ddBlock[i].ispcVolume = ddBlock[i].cppVolume->getIE();

    }

    return true;
  }

  void DataDistributedBlockedVolume::createEquivalentISPC()
  {
    if (ispcEquivalent != NULL) return;

    // Get the voxel type.
    voxelType = getParamString("voxelType", "unspecified");
    exitOnCondition(getVoxelType() == OSP_UNKNOWN,
                    "unrecognized voxel type (must be set before calling "
                    "ospSetRegion())");

    // Get the volume dimensions.
    this->dimensions = getParam3i("dimensions", vec3i(0));
    exitOnCondition(reduce_min(this->dimensions) <= 0,
                    "invalid volume dimensions (must be set before calling "
                    "ospSetRegion())");

    ddBlocks    = getParam3i("num_dp_blocks",vec3i(4,4,4));
    blockSize   = divRoundUp(dimensions,ddBlocks);
    std::cout << "#osp:dp: using data parallel volume of " << ddBlocks
              << " blocks, blockSize is " << blockSize << std::endl;

    // Set the grid origin, default to (0,0,0).
    this->gridOrigin = getParam3f("gridOrigin", vec3f(0.f));

    // Get the volume dimensions.
    this->dimensions = getParam3i("dimensions", vec3i(0));
    exitOnCondition(reduce_min(this->dimensions) <= 0,
                    "invalid volume dimensions");

    // Set the grid spacing, default to (1,1,1).
    this->gridSpacing = getParam3f("gridSpacing", vec3f(1.f));

    this->scaleFactor = getParam3f("scaleFactor", vec3f(-1.f));

    numDDBlocks = ospcommon::reduce_mul(ddBlocks);
    ddBlock     = new DDBlock[numDDBlocks];

    printf("=======================================================\n");
    printf("created %ix%ix%i data distributed volume blocks\n",
           ddBlocks.x,ddBlocks.y,ddBlocks.z);
    printf("=======================================================\n");

    if (!ospray::core::isMpiParallel()) {
      throw std::runtime_error("data parallel volume, but not in mpi parallel "
                               "mode...");
    }
    uint64_t numWorkers = ospray::core::getWorkerCount();
    // PRINT(numDDBlocks);
    // PRINT(numWorkers);

    voxelType = getParamString("voxelType", "unspecified");

    // if (numDDBlocks >= numWorkers) {
    // we have more workers than blocks - use one owner per block,
    // meaning we'll end up with multiple blocks per worker
    int blockID = 0;
    for (int iz=0;iz<ddBlocks.z;iz++)
      for (int iy=0;iy<ddBlocks.y;iy++)
        for (int ix=0;ix<ddBlocks.x;ix++, blockID++) {
          DDBlock *block = &ddBlock[blockID];
          if (numDDBlocks >= numWorkers) {
            block->firstOwner = blockID % numWorkers;
            block->numOwners = 1;
          } else {
            block->firstOwner = (blockID * numWorkers) / numDDBlocks;
            int nextBlockFirstOwner = ((blockID+1)*numWorkers) / numDDBlocks;
            block->numOwners = nextBlockFirstOwner - block->firstOwner; // + 1;
          }
          block->isMine
            = (ospray::core::getWorkerRank() >= block->firstOwner)
            && (ospray::core::getWorkerRank() <
                (block->firstOwner + block->numOwners));
          block->domain.lower = vec3i(ix,iy,iz) * blockSize;
          block->domain.upper = min(block->domain.lower+blockSize,dimensions);
          block->bounds.lower = gridOrigin +
            (gridSpacing * vec3f(block->domain.lower));
          block->bounds.upper = gridOrigin +
            (gridSpacing * vec3f(block->domain.upper));

          // iw: add one voxel overlap, so we can properly interpolate
          // even across block boundaries (we need the full *cell* on
          // the right side, not just the last *voxel*!)
          block->domain.upper = min(block->domain.upper+vec3i(1),dimensions);

          if (block->isMine) {
#ifdef EXP_NEW_BB_VOLUME_KERNELS
            Ref<Volume> volume = new GhostBlockBrickedVolume;
#else
            Ref<Volume> volume = new BlockBrickedVolume;
#endif
            vec3i blockDims = block->domain.upper - block->domain.lower;
            volume->findParam("dimensions",1)->set(blockDims);
            volume->findParam("gridOrigin",1)->set(block->bounds.lower);
            volume->findParam("gridSpacing",1)->set(gridSpacing);
            volume->findParam("voxelType",1)->set(voxelType.c_str());
            if (scaleFactor != vec3f(-1.f)) {
              volume->findParam("scaleFactor",1)->set(scaleFactor);
            }

            printf("worker rank %li owns block %i,%i,%i (ID %i), dims %i %i %i\n",
                   (size_t)core::getWorkerRank(),ix,iy,iz,
                   blockID,blockDims.x,blockDims.y,blockDims.z);
            block->cppVolume = volume;
            block->ispcVolume = NULL; //volume->getIE();
          } else {
            block->ispcVolume = NULL;
            block->cppVolume = NULL;
          }
        }

    // Create an ISPC BlockBrickedVolume object and assign type-specific
    // function pointers.
    ispcEquivalent = ispc::DDBVolume_create(this,
                                            (int)getVoxelType(),
                                            (const ispc::vec3i&)dimensions,
                                            (const ispc::vec3i&)ddBlocks,
                                            (const ispc::vec3i&)blockSize,
                                            ddBlock);
    if (!ispcEquivalent) {
      throw std::runtime_error("could not create create data distributed "
                               "volume");
    }
  }

  // A volume type with internal data-distribution. needs a renderer
  // that is capable of data-parallel rendering!
  OSP_REGISTER_VOLUME(DataDistributedBlockedVolume, data_distributed_volume);

#endif

} // ::ospray
<|endoftext|>


<commit_before>#include <string.h>
#include <stdlib.h>
#include <gtk/gtk.h>
#include <iostream>

#include <bot_vis/bot_vis.h>
#include <lcm/lcm.h>
#include <bot_core/bot_core.h>
#include <path_util/path_util.h>
#include <ConciseArgs>

//renderers
#include <bot_frames/bot_frames_renderers.h>
#include <laser_utils/renderer_laser.h>
#include <bot_lcmgl_render/lcmgl_bot_renderer.h>
#include <visualization/collections_renderer.hpp>
#include <octomap_utils/renderer_octomap.h>
#include <mav_state_est/mav_state_est_renderers.h>
#include <occ_map/occ_map_renderers.h>

using namespace std;

int main(int argc, char *argv[])
{
  string config_file = "drc_robot_02_mit.cfg";

  gtk_init(&argc, &argv);
  glutInit(&argc, argv);
  g_thread_init(NULL);

//  if (argc < 2) {
//    fprintf(stderr, "usage: %s <render_plugins>\n", g_path_get_basename(argv[0]));
//    exit(1);
//  }
  lcm_t * lcm = bot_lcm_get_global(NULL);
  bot_glib_mainloop_attach_lcm(lcm);
  BotParam * bot_param;
  if(config_file.size()) {
    fprintf(stderr,"Reading config from file\n");
    std::string config_path = std::string(getConfigPath()) +'/' + std::string(config_file);
    bot_param = bot_param_new_from_file(config_path.c_str());
    if (bot_param == NULL) {
      std::cerr << "Couldn't get bot param from file %s\n" << config_path << std::endl;
      exit(-1);
    }
  }else {
    bot_param = bot_param_new_from_server(lcm, 0);
    if (bot_param == NULL) {
      fprintf(stderr, "Couldn't get bot param from server.\n");
      return 1;
    }
  }

  BotFrames* bot_frames = bot_frames_new(lcm, bot_param);

  BotViewer* viewer = bot_viewer_new("Pronto Viewer");
  //die cleanly for control-c etc :-)
  bot_gtk_quit_on_interrupt();

  // setup renderers
  bot_viewer_add_stock_renderer(viewer, BOT_VIEWER_STOCK_RENDERER_GRID, 1);
  collections_add_renderer_to_viewer(viewer, 1, lcm);
  bot_lcmgl_add_renderer_to_viewer(viewer,lcm, 1);
  laser_util_add_renderer_to_viewer(viewer, 1, lcm, bot_param, bot_frames);
  bot_frames_add_renderer_to_viewer(viewer, 1, bot_frames );

  add_octomap_renderer_to_viewer(viewer, 1, lcm);
  add_map_measurement_renderer_to_viewer(viewer, 1, lcm, bot_param, bot_frames);
  add_mav_state_est_renderer_to_viewer(viewer, 1, lcm, bot_param, bot_frames);

  //load the renderer params from the config file.
  char *fname = g_build_filename(g_get_user_config_dir(), ".bot-plugin-viewerrc", NULL);
  bot_viewer_load_preferences(viewer, fname);

  gtk_main();

  //save the renderer params to the config file.
  bot_viewer_save_preferences(viewer, fname);

  bot_viewer_unref(viewer);
}
<commit_msg>multiple pronto bot frames<commit_after>#include <string.h>
#include <stdlib.h>
#include <gtk/gtk.h>
#include <iostream>

#include <bot_vis/bot_vis.h>
#include <lcm/lcm.h>
#include <bot_core/bot_core.h>
#include <path_util/path_util.h>
#include <ConciseArgs>

//renderers
#include <bot_frames/bot_frames_renderers.h>
#include <laser_utils/renderer_laser.h>
#include <bot_lcmgl_render/lcmgl_bot_renderer.h>
#include <visualization/collections_renderer.hpp>
#include <octomap_utils/renderer_octomap.h>
#include <mav_state_est/mav_state_est_renderers.h>
#include <occ_map/occ_map_renderers.h>

using namespace std;

int main(int argc, char *argv[])
{
  string config_file = "drc_robot_02_mit.cfg";

  gtk_init(&argc, &argv);
  glutInit(&argc, argv);
  g_thread_init(NULL);

//  if (argc < 2) {
//    fprintf(stderr, "usage: %s <render_plugins>\n", g_path_get_basename(argv[0]));
//    exit(1);
//  }
  lcm_t * lcm = bot_lcm_get_global(NULL);
  bot_glib_mainloop_attach_lcm(lcm);
  BotParam * bot_param;
  if(config_file.size()) {
    fprintf(stderr,"Reading config from file\n");
    std::string config_path = std::string(getConfigPath()) +'/' + std::string(config_file);
    bot_param = bot_param_new_from_file(config_path.c_str());
    if (bot_param == NULL) {
      std::cerr << "Couldn't get bot param from file %s\n" << config_path << std::endl;
      exit(-1);
    }
  }else {
    bot_param = bot_param_new_from_server(lcm, 0);
    if (bot_param == NULL) {
      fprintf(stderr, "Couldn't get bot param from server.\n");
      return 1;
    }
  }

  BotFrames* bot_frames = bot_frames_new(lcm, bot_param);

  BotViewer* viewer = bot_viewer_new("Pronto Viewer");
  //die cleanly for control-c etc :-)
  bot_gtk_quit_on_interrupt();

  // setup renderers
  bot_viewer_add_stock_renderer(viewer, BOT_VIEWER_STOCK_RENDERER_GRID, 1);
  collections_add_renderer_to_viewer(viewer, 1, lcm);
  bot_lcmgl_add_renderer_to_viewer(viewer,lcm, 1);
  laser_util_add_renderer_to_viewer(viewer, 1, lcm, bot_param, bot_frames);
  bot_frames_add_renderer_to_viewer(viewer, 1, bot_frames );
  bot_frames_add_renderer_to_viewer(viewer, 1, bot_frames );
  bot_frames_add_renderer_to_viewer(viewer, 1, bot_frames );

  add_octomap_renderer_to_viewer(viewer, 1, lcm);
  add_map_measurement_renderer_to_viewer(viewer, 1, lcm, bot_param, bot_frames);
  add_mav_state_est_renderer_to_viewer(viewer, 1, lcm, bot_param, bot_frames);

  //load the renderer params from the config file.
  char *fname = g_build_filename(g_get_user_config_dir(), ".bot-plugin-viewerrc", NULL);
  bot_viewer_load_preferences(viewer, fname);

  gtk_main();

  //save the renderer params to the config file.
  bot_viewer_save_preferences(viewer, fname);

  bot_viewer_unref(viewer);
}
<|endoftext|>


<commit_before>/*
	This file is part of cpp-ethereum.

	cpp-ethereum is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	cpp-ethereum 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 General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file CommonEth.cpp
 * @author Gav Wood <i@gavwood.com>
 * @date 2014
 */

#include "CommonEth.h"
#include <random>
#include <secp256k1/secp256k1.h>
#include <libdevcrypto/SHA3.h>
#include "Exceptions.h"
using namespace std;
using namespace dev;
using namespace dev::eth;

namespace dev
{
namespace eth
{

const unsigned c_protocolVersion = 47;
const unsigned c_databaseVersion = 5;

static const vector<pair<u256, string>> g_units =
{
	{((((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000, "Uether"},
	{((((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000, "Vether"},
	{((((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000, "Dether"},
	{(((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000, "Nether"},
	{(((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000, "Yether"},
	{(((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000, "Zether"},
	{((u256(1000000000) * 1000000000) * 1000000000) * 1000000000, "Eether"},
	{((u256(1000000000) * 1000000000) * 1000000000) * 1000000, "Pether"},
	{((u256(1000000000) * 1000000000) * 1000000000) * 1000, "Tether"},
	{(u256(1000000000) * 1000000000) * 1000000000, "Gether"},
	{(u256(1000000000) * 1000000000) * 1000000, "Mether"},
	{(u256(1000000000) * 1000000000) * 1000, "Kether"},
	{u256(1000000000) * 1000000000, "ether"},
	{u256(1000000000) * 1000000, "finney"},
	{u256(1000000000) * 1000, "szabo"},
	{u256(1000000000), "Gwei"},
	{u256(1000000), "Mwei"},
	{u256(1000), "Kwei"},
	{u256(1), "wei"}
};

vector<pair<u256, string>> const& units()
{
	return g_units;
}

std::string formatBalance(u256 _b)
{
	ostringstream ret;
	if (_b > g_units[0].first * 10000)
	{
		ret << (_b / g_units[0].first) << " " << g_units[0].second;
		return ret.str();
	}
	ret << setprecision(5);
	for (auto const& i: g_units)
		if (i.first != 1 && _b >= i.first * 100)
		{
			ret << (double(_b / (i.first / 1000)) / 1000.0) << " " << i.second;
			return ret.str();
		}
	ret << _b << " wei";
	return ret.str();
}

}}
<commit_msg>PV48.<commit_after>/*
	This file is part of cpp-ethereum.

	cpp-ethereum is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	cpp-ethereum 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 General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file CommonEth.cpp
 * @author Gav Wood <i@gavwood.com>
 * @date 2014
 */

#include "CommonEth.h"
#include <random>
#include <secp256k1/secp256k1.h>
#include <libdevcrypto/SHA3.h>
#include "Exceptions.h"
using namespace std;
using namespace dev;
using namespace dev::eth;

namespace dev
{
namespace eth
{

const unsigned c_protocolVersion = 48;
const unsigned c_databaseVersion = 5;

static const vector<pair<u256, string>> g_units =
{
	{((((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000, "Uether"},
	{((((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000, "Vether"},
	{((((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000, "Dether"},
	{(((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000, "Nether"},
	{(((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000, "Yether"},
	{(((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000, "Zether"},
	{((u256(1000000000) * 1000000000) * 1000000000) * 1000000000, "Eether"},
	{((u256(1000000000) * 1000000000) * 1000000000) * 1000000, "Pether"},
	{((u256(1000000000) * 1000000000) * 1000000000) * 1000, "Tether"},
	{(u256(1000000000) * 1000000000) * 1000000000, "Gether"},
	{(u256(1000000000) * 1000000000) * 1000000, "Mether"},
	{(u256(1000000000) * 1000000000) * 1000, "Kether"},
	{u256(1000000000) * 1000000000, "ether"},
	{u256(1000000000) * 1000000, "finney"},
	{u256(1000000000) * 1000, "szabo"},
	{u256(1000000000), "Gwei"},
	{u256(1000000), "Mwei"},
	{u256(1000), "Kwei"},
	{u256(1), "wei"}
};

vector<pair<u256, string>> const& units()
{
	return g_units;
}

std::string formatBalance(u256 _b)
{
	ostringstream ret;
	if (_b > g_units[0].first * 10000)
	{
		ret << (_b / g_units[0].first) << " " << g_units[0].second;
		return ret.str();
	}
	ret << setprecision(5);
	for (auto const& i: g_units)
		if (i.first != 1 && _b >= i.first * 100)
		{
			ret << (double(_b / (i.first / 1000)) / 1000.0) << " " << i.second;
			return ret.str();
		}
	ret << _b << " wei";
	return ret.str();
}

}}
<|endoftext|>


<commit_before>#include <cerrno>
#include <cstring>
#include <ctime>
#include <iostream>

#include <pqxx/connection>
#include <pqxx/transaction>
#include <pqxx/transactor>
#include <pqxx/trigger>
#include <pqxx/result>

using namespace PGSTD;
using namespace pqxx;

// Example program for libpqxx.  Send notification to self.
//
// Usage: test004 [connect-string]
//
// Where connect-string is a set of connection options in Postgresql's
// PQconnectdb() format, eg. "dbname=template1" to select from a database
// called template1, or "host=foo.bar.net user=smith" to connect to a
// backend running on host foo.bar.net, logging in as user smith.

#ifdef _WIN32
#include <windows.h>
#else
extern "C"
{
#ifdef PQXX_HAVE_SYS_SELECT_H
#include <sys/select.h>
#else
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#endif
}
#endif	// _WIN32

namespace
{

int Backend_PID = 0;

#ifndef _WIN32
// Reasonably portable way to sleep for a given number of milliseconds
/* This definition is not needed on Windows, which provides its own Sleep()
 * function with the same semantics.
 */
void Sleep(int ms)
{
  fd_set F;
  FD_ZERO(&F);
  struct timeval timeout;
  timeout.tv_sec = ms / 1000;
  timeout.tv_usec = (ms % 1000) * 1000;
  if (select(0, &F, &F, &F, &timeout) == -1)
    throw runtime_error(strerror(errno));
}
#endif	// _WIN32

// Sample implementation of trigger handler
class TestTrig : public trigger
{
  bool m_Done;

public:
  explicit TestTrig(connection_base &C) : trigger(C, "trig"), m_Done(false) {}

  virtual void operator()(int be_pid)
  {
    m_Done = true;
    if (be_pid != Backend_PID)
      throw logic_error("Expected notification from backend process " +
		        to_string(Backend_PID) +
			", but got one from " +
			to_string(be_pid));

    cout << "Received notification: " << name() << " pid=" << be_pid << endl;
  }

  bool Done() const { return m_Done; }
};

// A transactor to trigger our trigger handler
class Notify : public transactor<>
{
  string m_Trigger;

public:
  explicit Notify(string TrigName) :
    transactor<>("Notifier"), m_Trigger(TrigName) { }

  void operator()(argument_type &T)
  {
    T.exec("NOTIFY " + m_Trigger);
    Backend_PID = T.conn().backendpid();
  }

  void OnAbort(const char Reason[]) throw ()
  {
    try
    {
      cerr << "Notify failed!" << endl;
      if (Reason) cerr << "Reason: " << Reason << endl;
    }
    catch (const exception &)
    {
    }
  }
};

} // namespace

int main(int, char *argv[])
{
  try
  {
    connection C(argv[1]);
    cout << "Adding trigger..." << endl;
    TestTrig Trig(C);

    cout << "Sending notification..." << endl;
    C.perform(Notify(Trig.name()));

    int notifs = 0;
    for (int i=0; (i < 20) && !Trig.Done(); ++i)
    {
      if (notifs)
	throw logic_error("Got " + to_string(notifs) +
	    " unexpected notification(s)!");
      Sleep(500);
      notifs = C.get_notifs();
      cout << ".";
    }
    cout << endl;

    if (!Trig.Done())
    {
      cout << "No notification received!" << endl;
      return 1;
    }
    if (notifs != 1)
      throw logic_error("Expected 1 notification, got " + to_string(notifs));
  }
  catch (const sql_error &e)
  {
    // If we're interested in the text of a failed query, we can write separate
    // exception handling code for this type of exception
    cerr << "SQL error: " << e.what() << endl
         << "Query was: '" << e.query() << "'" << endl;
    return 1;
  }
  catch (const exception &e)
  {
    // All exceptions thrown by libpqxx are derived from std::exception
    cerr << "Exception: " << e.what() << endl;
    return 2;
  }
  catch (...)
  {
    // This is really unexpected (see above)
    cerr << "Unhandled exception" << endl;
    return 100;
  }

  return 0;
}

<commit_msg>Quoted trigger names<commit_after>#include <cerrno>
#include <cstring>
#include <ctime>
#include <iostream>

#include <pqxx/connection>
#include <pqxx/transaction>
#include <pqxx/transactor>
#include <pqxx/trigger>
#include <pqxx/result>

using namespace PGSTD;
using namespace pqxx;

// Example program for libpqxx.  Send notification to self.
//
// Usage: test004 [connect-string]
//
// Where connect-string is a set of connection options in Postgresql's
// PQconnectdb() format, eg. "dbname=template1" to select from a database
// called template1, or "host=foo.bar.net user=smith" to connect to a
// backend running on host foo.bar.net, logging in as user smith.

#ifdef _WIN32
#include <windows.h>
#else
extern "C"
{
#ifdef PQXX_HAVE_SYS_SELECT_H
#include <sys/select.h>
#else
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#endif
}
#endif	// _WIN32

namespace
{

int Backend_PID = 0;

#ifndef _WIN32
// Reasonably portable way to sleep for a given number of milliseconds
/* This definition is not needed on Windows, which provides its own Sleep()
 * function with the same semantics.
 */
void Sleep(int ms)
{
  fd_set F;
  FD_ZERO(&F);
  struct timeval timeout;
  timeout.tv_sec = ms / 1000;
  timeout.tv_usec = (ms % 1000) * 1000;
  if (select(0, &F, &F, &F, &timeout) == -1)
    throw runtime_error(strerror(errno));
}
#endif	// _WIN32

// Sample implementation of trigger handler
class TestTrig : public trigger
{
  bool m_Done;

public:
  explicit TestTrig(connection_base &C) : trigger(C, "trig"), m_Done(false) {}

  virtual void operator()(int be_pid)
  {
    m_Done = true;
    if (be_pid != Backend_PID)
      throw logic_error("Expected notification from backend process " +
		        to_string(Backend_PID) +
			", but got one from " +
			to_string(be_pid));

    cout << "Received notification: " << name() << " pid=" << be_pid << endl;
  }

  bool Done() const { return m_Done; }
};

// A transactor to trigger our trigger handler
class Notify : public transactor<>
{
  string m_Trigger;

public:
  explicit Notify(string TrigName) :
    transactor<>("Notifier"), m_Trigger(TrigName) { }

  void operator()(argument_type &T)
  {
    T.exec("NOTIFY \"" + m_Trigger + "\"");
    Backend_PID = T.conn().backendpid();
  }

  void OnAbort(const char Reason[]) throw ()
  {
    try
    {
      cerr << "Notify failed!" << endl;
      if (Reason) cerr << "Reason: " << Reason << endl;
    }
    catch (const exception &)
    {
    }
  }
};

} // namespace

int main(int, char *argv[])
{
  try
  {
    connection C(argv[1]);
    cout << "Adding trigger..." << endl;
    TestTrig Trig(C);

    cout << "Sending notification..." << endl;
    C.perform(Notify(Trig.name()));

    int notifs = 0;
    for (int i=0; (i < 20) && !Trig.Done(); ++i)
    {
      if (notifs)
	throw logic_error("Got " + to_string(notifs) +
	    " unexpected notification(s)!");
      Sleep(500);
      notifs = C.get_notifs();
      cout << ".";
    }
    cout << endl;

    if (!Trig.Done())
    {
      cout << "No notification received!" << endl;
      return 1;
    }
    if (notifs != 1)
      throw logic_error("Expected 1 notification, got " + to_string(notifs));
  }
  catch (const sql_error &e)
  {
    // If we're interested in the text of a failed query, we can write separate
    // exception handling code for this type of exception
    cerr << "SQL error: " << e.what() << endl
         << "Query was: '" << e.query() << "'" << endl;
    return 1;
  }
  catch (const exception &e)
  {
    // All exceptions thrown by libpqxx are derived from std::exception
    cerr << "Exception: " << e.what() << endl;
    return 2;
  }
  catch (...)
  {
    // This is really unexpected (see above)
    cerr << "Unhandled exception" << endl;
    return 100;
  }

  return 0;
}

<|endoftext|>


<commit_before>#ifndef MJOLNIR_GLOBAL_EXTERNAL_INTERACTION
#define MJOLNIR_GLOBAL_EXTERNAL_INTERACTION
#include "GlobalInteractionBase.hpp"

namespace mjolnir
{

template<typename traitsT, typename potentialT, typename partition>
class GlobalExternalInteraction : public GlobalInteractionBase<traitsT>
{
  public:

    using traits_type             = traitsT;
    using potential_type          = potentialT;
    using partition_type          = partitionT;
    using base_type               = GlobalInteractionBase<traits_type>;
    using real_type               = base_type::real_type;
    using coordinate_type         = base_type::coordinate_type;
    using system_type             = base_type::system_type;
    using particle_type           = base_type::particle_type;
    using boundary_type           = base_type::boundary_type;

  public:
    GlobalExternalInteraction()  = default;
    ~GlobalExternalInteraction() = default;

    GlobalExternalInteraction(potential_type&& pot, partition_type&& part)
	: potential_(std::move(pot)),spatial_partition_(std::move(part))
    {}

    void initialize(const system_type&, const real_type) override
    {
	return ;
    }

    void calc_force(system_type&)                          override;
    void calc_energy(const particle_container_type&) const override;

  private:

    potential_type potential_;
    spatial_partition_type spatial_partition_;
};

template<typename traitsT, typename potT, typename spaceT>
void GlobalExternalInteraction<traitsT, potT, spaceT>::calc_force(
    system_type& sys)
{
    for(std::size_t i = 0; i < sys.size(); ++i){
	const real_type force = potential_.derivative(sys[i].position.at(2));
	sys[i].force.at(2) += f;
    }
    return ;
}

template<typename traitsT, typename potT, typename spaceT>
typename GlobalExternalInteraction<traitsT, potT, spaceT>::calc_energy
(system_type& sys) const
{
    real_type e = 0.0;
    for(std::size_t i = 0; i < sys.size(); ++i){
	e += potential_.potential(sys[i].position.at(2));
    }
    return e;
}

}
#endif /* MJOLNIR_GLOBAL_EXTERNAL_INTERACTION */
<commit_msg>correct typename specification and sign of force.<commit_after>#ifndef MJOLNIR_GLOBAL_EXTERNAL_INTERACTION
#define MJOLNIR_GLOBAL_EXTERNAL_INTERACTION
#include "GlobalInteractionBase.hpp"

namespace mjolnir
{

template<typename traitsT, typename potentialT, typename partitionT>
class GlobalExternalInteraction : public GlobalInteractionBase<traitsT>
{
  public:

    using traits_type             = traitsT;
    using potential_type          = potentialT;
    using partition_type          = partitionT;
    using base_type               = GlobalInteractionBase<traits_type>;
    using real_type               = typename base_type::real_type;
    using coordinate_type         = typename base_type::coordinate_type;
    using system_type             = typename base_type::system_type;
    using particle_type           = typename base_type::particle_type;
    using boundary_type           = typename base_type::boundary_type;

  public:
    GlobalExternalInteraction()  = default;
    ~GlobalExternalInteraction() = default;

    GlobalExternalInteraction(potential_type&& pot, partition_type&& part)
	: potential_(std::move(pot)),spatial_partition_(std::move(part))
    {}

    void initialize(const system_type&, const real_type) override
    {
	return ;
    }

    void      calc_force(system_type&)              override;
    real_type calc_energy(const system_type&) const override;

  private:

    potential_type potential_;
    partition_type spatial_partition_;
};

template<typename traitsT, typename potT, typename spaceT>
void GlobalExternalInteraction<traitsT, potT, spaceT>::calc_force(
    system_type& sys)
{
    for(std::size_t i = 0; i < sys.size(); ++i){
	const real_type force = -potential_.derivative(i, sys[i].position.at(2));
	sys[i].force.at(2) += force;
    }
    return ;
}

template<typename traitsT, typename potT, typename spaceT>
typename GlobalExternalInteraction<traitsT, potT, spaceT>::real_type
GlobalExternalInteraction<traitsT, potT, spaceT>::calc_energy(
    const system_type& sys) const
{
    real_type e = 0.0;
    for(std::size_t i = 0; i < sys.size(); ++i){
	e += potential_.potential(i, sys[i].position.at(2));
    }
    return e;
}

}
#endif /* MJOLNIR_GLOBAL_EXTERNAL_INTERACTION */
<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2018.  All rights reserved
 */
#include "../StroikaPreComp.h"

#include "Sanitizer.h"

#include "AssertExternallySynchronizedLock.h"

using namespace Stroika;
using namespace Stroika::Foundation;
using namespace Stroika::Foundation::Debug;

#if qDebug
/*
 ********************************************************************************
 ****************** Debug::AssertExternallySynchronizedLock *********************
 ********************************************************************************
 */
DISABLE_COMPILER_MSC_WARNING_START (4297)
// workaround https://stroika.atlassian.net/browse/STK-665, https://stroika.atlassian.net/browse/STK-500 - ARM ONLY
Stroika_Foundation_Debug_ATTRIBUTE_NO_SANITIZE ("address")
    AssertExternallySynchronizedLock::AssertExternallySynchronizedLock () noexcept try : fSharedLockThreads_ () {
}
catch (...) {
    AssertNotReached ();
}
DISABLE_COMPILER_MSC_WARNING_END (4297)

void AssertExternallySynchronizedLock::lock_ () const noexcept
{
    try {
        if (fLocks_++ == 0) {
            // If first time in, save thread-id
            fCurLockThread_ = this_thread::get_id ();
            lock_guard<mutex> sharedLockProtect{GetSharedLockMutexThreads_ ()};
            if (not fSharedLockThreads_.empty ()) {
                // If first already shared locks - OK - so long as same thread
                Require (fSharedLockThreads_.count (fCurLockThread_) == fSharedLockThreads_.size ());
            }
        }
        else {
            // If first already locked - OK - so long as same thread
            Require (fCurLockThread_ == this_thread::get_id ());
        }
    }
    catch (...) {
        AssertNotReached ();
    }
}

void AssertExternallySynchronizedLock::unlock_ () const noexcept
{
    Require (fCurLockThread_ == this_thread::get_id ());
    Require (fLocks_ > 0); // else unbalanced
    --fLocks_;
}

// workaround https://stroika.atlassian.net/browse/STK-665
Stroika_Foundation_Debug_ATTRIBUTE_NO_SANITIZE ("address") void AssertExternallySynchronizedLock::lock_shared_ () const noexcept
{
    try {
        // OK to shared lock from various threads
        // But if already locked, NOT OK (would have blocked in real impl) - if you try to shared lock from another thread while locked
        if (fLocks_ != 0) {
            // If first already locks - OK - so long as same thread
            Require (fCurLockThread_ == this_thread::get_id ());
        }
        lock_guard<mutex> sharedLockProtect{GetSharedLockMutexThreads_ ()};
        fSharedLockThreads_.insert (this_thread::get_id ());
    }
    catch (...) {
        AssertNotReached ();
    }
}

void AssertExternallySynchronizedLock::unlock_shared_ () const noexcept
{
    try {
        lock_guard<mutex>              sharedLockProtect{GetSharedLockMutexThreads_ ()};
        multiset<thread::id>::iterator tti = fSharedLockThreads_.find (this_thread::get_id ());
        Require (tti != fSharedLockThreads_.end ()); // else unbalanced
        fSharedLockThreads_.erase (tti);
    }
    catch (...) {
        AssertNotReached ();
    }
}
#endif
<commit_msg>Cosmetic<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2018.  All rights reserved
 */
#include "../StroikaPreComp.h"

#include "Sanitizer.h"

#include "AssertExternallySynchronizedLock.h"

using namespace Stroika;
using namespace Stroika::Foundation;
using namespace Stroika::Foundation::Debug;

#if qDebug
/*
 ********************************************************************************
 ****************** Debug::AssertExternallySynchronizedLock *********************
 ********************************************************************************
 */
DISABLE_COMPILER_MSC_WARNING_START (4297)
// workaround https://stroika.atlassian.net/browse/STK-665, https://stroika.atlassian.net/browse/STK-500 - ARM ONLY
Stroika_Foundation_Debug_ATTRIBUTE_NO_SANITIZE ("address")
    AssertExternallySynchronizedLock::AssertExternallySynchronizedLock () noexcept try : fSharedLockThreads_ () {
}
catch (...) {
    AssertNotReached ();
}
DISABLE_COMPILER_MSC_WARNING_END (4297)

void AssertExternallySynchronizedLock::lock_ () const noexcept
{
    try {
        if (fLocks_++ == 0) {
            // If first time in, save thread-id
            fCurLockThread_ = this_thread::get_id ();
            lock_guard<mutex> sharedLockProtect{GetSharedLockMutexThreads_ ()};
            if (not fSharedLockThreads_.empty ()) {
                // If first already shared locks - OK - so long as same thread
                Require (fSharedLockThreads_.count (fCurLockThread_) == fSharedLockThreads_.size ());
            }
        }
        else {
            // If first already locked - OK - so long as same thread
            Require (fCurLockThread_ == this_thread::get_id ());
        }
    }
    catch (...) {
        AssertNotReached ();
    }
}

void AssertExternallySynchronizedLock::unlock_ () const noexcept
{
    Require (fCurLockThread_ == this_thread::get_id ());
    Require (fLocks_ > 0); // else unbalanced
    --fLocks_;
}

// workaround https://stroika.atlassian.net/browse/STK-665- Stroika_Foundation_Debug_ATTRIBUTE_NO_SANITIZE ("address")
Stroika_Foundation_Debug_ATTRIBUTE_NO_SANITIZE ("address") void AssertExternallySynchronizedLock::lock_shared_ () const noexcept
{
    try {
        // OK to shared lock from various threads
        // But if already locked, NOT OK (would have blocked in real impl) - if you try to shared lock from another thread while locked
        if (fLocks_ != 0) {
            // If first already locks - OK - so long as same thread
            Require (fCurLockThread_ == this_thread::get_id ());
        }
        lock_guard<mutex> sharedLockProtect{GetSharedLockMutexThreads_ ()};
        fSharedLockThreads_.insert (this_thread::get_id ());
    }
    catch (...) {
        AssertNotReached ();
    }
}

void AssertExternallySynchronizedLock::unlock_shared_ () const noexcept
{
    try {
        lock_guard<mutex>              sharedLockProtect{GetSharedLockMutexThreads_ ()};
        multiset<thread::id>::iterator tti = fSharedLockThreads_.find (this_thread::get_id ());
        Require (tti != fSharedLockThreads_.end ()); // else unbalanced
        fSharedLockThreads_.erase (tti);
    }
    catch (...) {
        AssertNotReached ();
    }
}
#endif
<|endoftext|>


<commit_before>// Copyright (c) 2019 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 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 "mfx_common.h"
#if defined(MFX_ENABLE_H265_VIDEO_ENCODE) && defined(MFX_ENABLE_HEVCE_WEIGHTED_PREDICTION)

#include "hevcehw_g9_weighted_prediction.h"
#include <numeric>

using namespace HEVCEHW;
using namespace HEVCEHW::Gen9;

void WeightPred::SetSupported(ParamSupport& blocks)
{
    blocks.m_ebCopySupported[MFX_EXTBUFF_CODING_OPTION3].emplace_back(
        [](const mfxExtBuffer* pSrc, mfxExtBuffer* pDst) -> void
    {
        auto& buf_src = *(const mfxExtCodingOption3*)pSrc;
        auto& buf_dst = *(mfxExtCodingOption3*)pDst;

        MFX_COPY_FIELD(WeightedPred);
        MFX_COPY_FIELD(WeightedBiPred);
        MFX_COPY_FIELD(FadeDetection);
    });
}

void WeightPred::Query1WithCaps(const FeatureBlocks& /*blocks*/, TPushQ1 Push)
{
    Push(BLK_CheckAndFix
        , [this](const mfxVideoParam& /*in*/, mfxVideoParam& par, StorageW& global) -> mfxStatus
    {
        mfxExtCodingOption3* pCO3 = ExtBuffer::Get(par);
        MFX_CHECK(pCO3, MFX_ERR_NONE);

        auto&  caps         = Glob::EncodeCaps::Get(global);
        auto   hw           = Glob::VideoCore::Get(global).GetHWType();
        bool   bFDSupported = !caps.NoWeightedPred && (hw < MFX_HW_ICL);
        mfxU32 changed      = 0;

        changed += CheckOrZero<mfxU16>(
            pCO3->WeightedPred
            , mfxU16(MFX_WEIGHTED_PRED_UNKNOWN)
            , mfxU16(MFX_WEIGHTED_PRED_DEFAULT)
            , mfxU16(!caps.NoWeightedPred * MFX_WEIGHTED_PRED_EXPLICIT));

        changed += CheckOrZero<mfxU16>(
            pCO3->WeightedBiPred
            , mfxU16(MFX_WEIGHTED_PRED_UNKNOWN)
            , mfxU16(MFX_WEIGHTED_PRED_DEFAULT)
            , mfxU16(!caps.NoWeightedPred * MFX_WEIGHTED_PRED_EXPLICIT));

        changed += CheckOrZero<mfxU16>(
            pCO3->FadeDetection
            , mfxU16(MFX_CODINGOPTION_UNKNOWN)
            , mfxU16(MFX_CODINGOPTION_OFF)
            , mfxU16(bFDSupported * MFX_CODINGOPTION_ON));

        MFX_CHECK(!changed, MFX_WRN_INCOMPATIBLE_VIDEO_PARAM);

        return MFX_ERR_NONE;
    });
}

void WeightPred::SetDefaults(const FeatureBlocks& /*blocks*/, TPushSD Push)
{
    Push(BLK_SetDefaults
        , [this](mfxVideoParam& par, StorageW& /*strg*/, StorageRW&)
    {
        mfxExtCodingOption3* pCO3 = ExtBuffer::Get(par);
        MFX_CHECK(pCO3, MFX_ERR_NONE);

        SetDefault(pCO3->FadeDetection, MFX_CODINGOPTION_OFF);
        SetDefault(pCO3->WeightedPred
            , IsOn(pCO3->FadeDetection) * MFX_WEIGHTED_PRED_EXPLICIT
            + IsOff(pCO3->FadeDetection) * MFX_WEIGHTED_PRED_DEFAULT);
        SetDefault(pCO3->WeightedBiPred, pCO3->WeightedPred);

        return MFX_ERR_NONE;
    });
}

void WeightPred::InitInternal(const FeatureBlocks& /*blocks*/, TPushII Push)
{
    Push(BLK_SetPPS
        , [this](StorageRW& strg, StorageRW&) -> mfxStatus
    {
        auto& par = Glob::VideoParam::Get(strg);
        const mfxExtCodingOption3& CO3 = ExtBuffer::Get(par);

        PPS& pps = Glob::PPS::Get(strg);
        pps.weighted_pred_flag   = (CO3.WeightedPred   == MFX_WEIGHTED_PRED_EXPLICIT);
        pps.weighted_bipred_flag = (CO3.WeightedBiPred == MFX_WEIGHTED_PRED_EXPLICIT) || (IsOn(CO3.GPB) && pps.weighted_pred_flag);

        MFX_CHECK(strg.Contains(Glob::RealState::Key), MFX_ERR_NONE);

        const PPS& oldPPS = Glob::PPS::Get(Glob::RealState::Get(strg));
        Glob::ResetHint::Get(strg).Flags |=
            RF_PPS_CHANGED
            * (    (pps.weighted_pred_flag != oldPPS.weighted_pred_flag)
                || (pps.weighted_bipred_flag != oldPPS.weighted_bipred_flag));

        return MFX_ERR_NONE;
    });
}

void WeightPred::PostReorderTask(const FeatureBlocks& /*blocks*/, TPushPostRT Push)
{
    Push(BLK_SetSSH
        , [](StorageW& global, StorageW& s_task) -> mfxStatus
    {
        auto& pps = Glob::PPS::Get(global);
        auto& ssh = Task::SSH::Get(s_task);

        bool bNeedPWT =
            (pps.weighted_pred_flag && ssh.type == 1)
            || (pps.weighted_bipred_flag && ssh.type == 0);

        MFX_CHECK(bNeedPWT, MFX_ERR_NONE);

        const mfxU16 Y = 0, Cb = 1, Cr = 2, W = 0, O = 1;
        auto& task             = Task::Common::Get(s_task);
        auto& caps             = Glob::EncodeCaps::Get(global);
        auto  pExtPWT          = (mfxExtPredWeightTable*)ExtBuffer::Get(task.ctrl);
        auto  SetDefaultWeight = [&](mfxI16 (&pwt)[3][2])
        {
            pwt[Y][W]  = (1 << ssh.luma_log2_weight_denom);
            pwt[Y][O]  = 0;
            pwt[Cb][W] = (1 << ssh.chroma_log2_weight_denom);
            pwt[Cb][O] = 0;
            pwt[Cr][W] = (1 << ssh.chroma_log2_weight_denom);
            pwt[Cr][O] = 0;
        };
        auto  CopyLxPWT        = [&](mfxU16 l, mfxU16 sz)
        {
            auto CopyY = [&](mfxU16 i)
            {
                ssh.pwt[l][i][Y][W] = pExtPWT->Weights[l][i][Y][W];
                ssh.pwt[l][i][Y][O] = pExtPWT->Weights[l][i][Y][O];
            };
            auto CopyC = [&](mfxU16 i)
            {
                ssh.pwt[l][i][Cb][W] = pExtPWT->Weights[l][i][Cb][W];
                ssh.pwt[l][i][Cb][O] = pExtPWT->Weights[l][i][Cb][O];
                ssh.pwt[l][i][Cr][W] = pExtPWT->Weights[l][i][Cr][W];
                ssh.pwt[l][i][Cr][O] = pExtPWT->Weights[l][i][Cr][O];
            };

            std::list<mfxI16> idxY(sz * caps.LumaWeightedPred, 0);
            std::list<mfxI16> idxC(sz * caps.ChromaWeightedPred, 0);

            std::iota(idxY.begin(), idxY.end(), mfxI16(0));
            std::iota(idxC.begin(), idxC.end(), mfxI16(0));

            idxY.remove_if([&](mfxI16 i) { return !pExtPWT->LumaWeightFlag[l][i]; });
            idxC.remove_if([&](mfxI16 i) { return !pExtPWT->ChromaWeightFlag[l][i]; });

            for_each(idxY.begin(), idxY.end(), CopyY);
            for_each(idxC.begin(), idxC.end(), CopyC);
        };

        ssh.luma_log2_weight_denom   = 6;
        ssh.chroma_log2_weight_denom = ssh.luma_log2_weight_denom;

        if (pExtPWT)
        {
            ssh.luma_log2_weight_denom   = pExtPWT->LumaLog2WeightDenom;
            ssh.chroma_log2_weight_denom = pExtPWT->ChromaLog2WeightDenom;
        }

        std::for_each(std::begin(ssh.pwt[0]), std::end(ssh.pwt[0]), SetDefaultWeight);
        std::for_each(std::begin(ssh.pwt[1]), std::end(ssh.pwt[1]), SetDefaultWeight);

        MFX_CHECK(pExtPWT, MFX_ERR_NONE);

        CopyLxPWT(0, std::min<mfxU16>(ssh.num_ref_idx_l0_active_minus1 + 1, caps.MaxNum_WeightedPredL0));
        CopyLxPWT(1, std::min<mfxU16>(ssh.num_ref_idx_l1_active_minus1 + 1, caps.MaxNum_WeightedPredL1));

        bool bForceSameWeights =
            task.isLDB
            && std::equal(
                std::begin(task.RefPicList[0])
                , std::end(task.RefPicList[0])
                , std::begin(task.RefPicList[1]));

        MFX_CHECK(bForceSameWeights, MFX_ERR_NONE);

        std::copy_n((mfxU8*)ssh.pwt[0], sizeof(ssh.pwt[0]), (mfxU8*)ssh.pwt[1]);

        return MFX_ERR_NONE;
    });
}

#endif //defined(MFX_ENABLE_H265_VIDEO_ENCODE)<commit_msg>HEVCe: fix fade-detection support condition<commit_after>// Copyright (c) 2019 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 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 "mfx_common.h"
#if defined(MFX_ENABLE_H265_VIDEO_ENCODE) && defined(MFX_ENABLE_HEVCE_WEIGHTED_PREDICTION)

#include "hevcehw_g9_weighted_prediction.h"
#include <numeric>

using namespace HEVCEHW;
using namespace HEVCEHW::Gen9;

void WeightPred::SetSupported(ParamSupport& blocks)
{
    blocks.m_ebCopySupported[MFX_EXTBUFF_CODING_OPTION3].emplace_back(
        [](const mfxExtBuffer* pSrc, mfxExtBuffer* pDst) -> void
    {
        auto& buf_src = *(const mfxExtCodingOption3*)pSrc;
        auto& buf_dst = *(mfxExtCodingOption3*)pDst;

        MFX_COPY_FIELD(WeightedPred);
        MFX_COPY_FIELD(WeightedBiPred);
        MFX_COPY_FIELD(FadeDetection);
    });
}

void WeightPred::Query1WithCaps(const FeatureBlocks& /*blocks*/, TPushQ1 Push)
{
    Push(BLK_CheckAndFix
        , [this](const mfxVideoParam& /*in*/, mfxVideoParam& par, StorageW& global) -> mfxStatus
    {
        mfxExtCodingOption3* pCO3 = ExtBuffer::Get(par);
        MFX_CHECK(pCO3, MFX_ERR_NONE);

        auto&  caps         = Glob::EncodeCaps::Get(global);
        auto   hw           = Glob::VideoCore::Get(global).GetHWType();
        bool   bFDSupported = !caps.NoWeightedPred && (hw >= MFX_HW_ICL);
        mfxU32 changed      = 0;

        changed += CheckOrZero<mfxU16>(
            pCO3->WeightedPred
            , mfxU16(MFX_WEIGHTED_PRED_UNKNOWN)
            , mfxU16(MFX_WEIGHTED_PRED_DEFAULT)
            , mfxU16(!caps.NoWeightedPred * MFX_WEIGHTED_PRED_EXPLICIT));

        changed += CheckOrZero<mfxU16>(
            pCO3->WeightedBiPred
            , mfxU16(MFX_WEIGHTED_PRED_UNKNOWN)
            , mfxU16(MFX_WEIGHTED_PRED_DEFAULT)
            , mfxU16(!caps.NoWeightedPred * MFX_WEIGHTED_PRED_EXPLICIT));

        changed += CheckOrZero<mfxU16>(
            pCO3->FadeDetection
            , mfxU16(MFX_CODINGOPTION_UNKNOWN)
            , mfxU16(MFX_CODINGOPTION_OFF)
            , mfxU16(bFDSupported * MFX_CODINGOPTION_ON));

        MFX_CHECK(!changed, MFX_WRN_INCOMPATIBLE_VIDEO_PARAM);

        return MFX_ERR_NONE;
    });
}

void WeightPred::SetDefaults(const FeatureBlocks& /*blocks*/, TPushSD Push)
{
    Push(BLK_SetDefaults
        , [this](mfxVideoParam& par, StorageW& /*strg*/, StorageRW&)
    {
        mfxExtCodingOption3* pCO3 = ExtBuffer::Get(par);
        MFX_CHECK(pCO3, MFX_ERR_NONE);

        SetDefault(pCO3->FadeDetection, MFX_CODINGOPTION_OFF);
        SetDefault(pCO3->WeightedPred
            , IsOn(pCO3->FadeDetection) * MFX_WEIGHTED_PRED_EXPLICIT
            + IsOff(pCO3->FadeDetection) * MFX_WEIGHTED_PRED_DEFAULT);
        SetDefault(pCO3->WeightedBiPred, pCO3->WeightedPred);

        return MFX_ERR_NONE;
    });
}

void WeightPred::InitInternal(const FeatureBlocks& /*blocks*/, TPushII Push)
{
    Push(BLK_SetPPS
        , [this](StorageRW& strg, StorageRW&) -> mfxStatus
    {
        auto& par = Glob::VideoParam::Get(strg);
        const mfxExtCodingOption3& CO3 = ExtBuffer::Get(par);

        PPS& pps = Glob::PPS::Get(strg);
        pps.weighted_pred_flag   = (CO3.WeightedPred   == MFX_WEIGHTED_PRED_EXPLICIT);
        pps.weighted_bipred_flag = (CO3.WeightedBiPred == MFX_WEIGHTED_PRED_EXPLICIT) || (IsOn(CO3.GPB) && pps.weighted_pred_flag);

        MFX_CHECK(strg.Contains(Glob::RealState::Key), MFX_ERR_NONE);

        const PPS& oldPPS = Glob::PPS::Get(Glob::RealState::Get(strg));
        Glob::ResetHint::Get(strg).Flags |=
            RF_PPS_CHANGED
            * (    (pps.weighted_pred_flag != oldPPS.weighted_pred_flag)
                || (pps.weighted_bipred_flag != oldPPS.weighted_bipred_flag));

        return MFX_ERR_NONE;
    });
}

void WeightPred::PostReorderTask(const FeatureBlocks& /*blocks*/, TPushPostRT Push)
{
    Push(BLK_SetSSH
        , [](StorageW& global, StorageW& s_task) -> mfxStatus
    {
        auto& pps = Glob::PPS::Get(global);
        auto& ssh = Task::SSH::Get(s_task);

        bool bNeedPWT =
            (pps.weighted_pred_flag && ssh.type == 1)
            || (pps.weighted_bipred_flag && ssh.type == 0);

        MFX_CHECK(bNeedPWT, MFX_ERR_NONE);

        const mfxU16 Y = 0, Cb = 1, Cr = 2, W = 0, O = 1;
        auto& task             = Task::Common::Get(s_task);
        auto& caps             = Glob::EncodeCaps::Get(global);
        auto  pExtPWT          = (mfxExtPredWeightTable*)ExtBuffer::Get(task.ctrl);
        auto  SetDefaultWeight = [&](mfxI16 (&pwt)[3][2])
        {
            pwt[Y][W]  = (1 << ssh.luma_log2_weight_denom);
            pwt[Y][O]  = 0;
            pwt[Cb][W] = (1 << ssh.chroma_log2_weight_denom);
            pwt[Cb][O] = 0;
            pwt[Cr][W] = (1 << ssh.chroma_log2_weight_denom);
            pwt[Cr][O] = 0;
        };
        auto  CopyLxPWT        = [&](mfxU16 l, mfxU16 sz)
        {
            auto CopyY = [&](mfxU16 i)
            {
                ssh.pwt[l][i][Y][W] = pExtPWT->Weights[l][i][Y][W];
                ssh.pwt[l][i][Y][O] = pExtPWT->Weights[l][i][Y][O];
            };
            auto CopyC = [&](mfxU16 i)
            {
                ssh.pwt[l][i][Cb][W] = pExtPWT->Weights[l][i][Cb][W];
                ssh.pwt[l][i][Cb][O] = pExtPWT->Weights[l][i][Cb][O];
                ssh.pwt[l][i][Cr][W] = pExtPWT->Weights[l][i][Cr][W];
                ssh.pwt[l][i][Cr][O] = pExtPWT->Weights[l][i][Cr][O];
            };

            std::list<mfxI16> idxY(sz * caps.LumaWeightedPred, 0);
            std::list<mfxI16> idxC(sz * caps.ChromaWeightedPred, 0);

            std::iota(idxY.begin(), idxY.end(), mfxI16(0));
            std::iota(idxC.begin(), idxC.end(), mfxI16(0));

            idxY.remove_if([&](mfxI16 i) { return !pExtPWT->LumaWeightFlag[l][i]; });
            idxC.remove_if([&](mfxI16 i) { return !pExtPWT->ChromaWeightFlag[l][i]; });

            for_each(idxY.begin(), idxY.end(), CopyY);
            for_each(idxC.begin(), idxC.end(), CopyC);
        };

        ssh.luma_log2_weight_denom   = 6;
        ssh.chroma_log2_weight_denom = ssh.luma_log2_weight_denom;

        if (pExtPWT)
        {
            ssh.luma_log2_weight_denom   = pExtPWT->LumaLog2WeightDenom;
            ssh.chroma_log2_weight_denom = pExtPWT->ChromaLog2WeightDenom;
        }

        std::for_each(std::begin(ssh.pwt[0]), std::end(ssh.pwt[0]), SetDefaultWeight);
        std::for_each(std::begin(ssh.pwt[1]), std::end(ssh.pwt[1]), SetDefaultWeight);

        MFX_CHECK(pExtPWT, MFX_ERR_NONE);

        CopyLxPWT(0, std::min<mfxU16>(ssh.num_ref_idx_l0_active_minus1 + 1, caps.MaxNum_WeightedPredL0));
        CopyLxPWT(1, std::min<mfxU16>(ssh.num_ref_idx_l1_active_minus1 + 1, caps.MaxNum_WeightedPredL1));

        bool bForceSameWeights =
            task.isLDB
            && std::equal(
                std::begin(task.RefPicList[0])
                , std::end(task.RefPicList[0])
                , std::begin(task.RefPicList[1]));

        MFX_CHECK(bForceSameWeights, MFX_ERR_NONE);

        std::copy_n((mfxU8*)ssh.pwt[0], sizeof(ssh.pwt[0]), (mfxU8*)ssh.pwt[1]);

        return MFX_ERR_NONE;
    });
}

#endif //defined(MFX_ENABLE_H265_VIDEO_ENCODE)<|endoftext|>


<commit_before>#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
#include <stdexcept>
#include "opencv2/core/core.hpp"
#include "opencv2/video/video.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/videostab/videostab.hpp"

using namespace std;
using namespace cv;
using namespace cv::videostab;

Ptr<IFrameSource> stabilizedFrames;
string saveMotionsPath;
double outputFps;
string outputPath;
bool quietMode;

void run();
void saveMotionsIfNecessary();
void printHelp();

class GlobalMotionReader : public IGlobalMotionEstimator
{
public:
    GlobalMotionReader(string path)
    {
        ifstream f(path.c_str());
        if (!f.is_open())
            throw runtime_error("can't open motions file: " + path);
        int size = 0; f >> size;
        motions_.resize(size);
        for (int i = 0; i < size; ++i)
        {
            Mat_<float> M(3, 3);
            for (int l = 0; l < 3; ++l)
                for (int s = 0; s < 3; ++s)
                    f >> M(l,s);
            motions_[i] = M;
        }
        pos_ = 0;
    }

    virtual Mat estimate(const Mat &/*frame0*/, const Mat &/*frame1*/)
    {
        if (pos_ >= motions_.size())
        {
            stringstream text;
            text << "can't load motion between frames " << pos_ << " and " << pos_+1;
            throw runtime_error(text.str());
        }
        return motions_[pos_++];
    }

private:
    vector<Mat> motions_;
    size_t pos_;
};

void run()
{
    VideoWriter writer;
    Mat stabilizedFrame;

    while (!(stabilizedFrame = stabilizedFrames->nextFrame()).empty())
    {
        if (!saveMotionsPath.empty())
            saveMotionsIfNecessary();
        if (!outputPath.empty())
        {
            if (!writer.isOpened())
                writer.open(outputPath, CV_FOURCC('X','V','I','D'), outputFps, stabilizedFrame.size());
            writer << stabilizedFrame;
        }
        if (!quietMode)
        {
            imshow("stabilizedFrame", stabilizedFrame);
            char key = static_cast<char>(waitKey(3));
            if (key == 27)
                break;
        }
    }

    cout << "\nfinished\n";
}

void saveMotionsIfNecessary()
{
    static bool areMotionsSaved = false;
    if (!areMotionsSaved)
    {
        IFrameSource *frameSource = static_cast<IFrameSource*>(stabilizedFrames);
        TwoPassStabilizer *twoPassStabilizer = dynamic_cast<TwoPassStabilizer*>(frameSource);
        if (twoPassStabilizer)
        {
            ofstream f(saveMotionsPath.c_str());
            const vector<Mat> &motions = twoPassStabilizer->motions();
            f << motions.size() << endl;
            for (size_t i = 0; i < motions.size(); ++i)
            {
                Mat_<float> M = motions[i];
                for (int l = 0, k = 0; l < 3; ++l)
                    for (int s = 0; s < 3; ++s, ++k)
                        f << M(l,s) << " ";
                f << endl;
            }
        }
        areMotionsSaved = true;
        cout << "motions are saved";
    }
}

void printHelp()
{
    cout << "OpenCV video stabilizer.\n"
            "Usage: videostab <file_path> [arguments]\n\n"
            "Arguments:\n"
            "  -m, --model=(transl|transl_and_scale|linear_sim|affine)\n"
            "      Set motion model. The default is affine.\n"
            "  --outlier-ratio=<float_number>\n"
            "      Outliers ratio in motion estimation. The default is 0.5.\n"
            "  --min-inlier-ratio=<float_number>\n"
            "      Minimum inlier ratio to decide if estimated motion is OK. The default is 0.1,\n"
            "      but you may want to increase it.\n\n"
            "  --save-motions=<file_path>\n"
            "      Save estimated motions into file.\n"
            "  --load-motions=<file_path>\n"
            "      Load motions from file.\n\n"
            "  -r, --radius=<int_number>\n"
            "      Set smoothing radius. The default is 15.\n"
            "  --stdev=<float_number>\n"
            "      Set smoothing weights standard deviation. The default is sqrt(radius).\n\n"
            "  --deblur=(yes|no)\n"
            "      Do deblurring.\n"
            "  --deblur-sens=<float_number>\n"
            "      Set deblurring sensitivity (from 0 to +inf). The default is 0.1.\n\n"
            "  -t, --trim-ratio=<float_number>\n"
            "      Set trimming ratio (from 0 to 0.5). The default is 0.0.\n"
            "  --est-trim=(yes|no)\n"
            "      Estimate trim ratio automatically. The default is yes (that leads to two passes,\n"
            "      you can turn it off if you want to use one pass only).\n"
            "  --incl-constr=(yes|no)\n"
            "      Ensure the inclusion constraint is always satisfied. The default is no.\n\n"
            "  --border-mode=(replicate|reflect|const)\n"
            "      Set border extrapolation mode. The default is replicate.\n\n"
            "  --mosaic=(yes|no)\n"
            "      Do consistent mosaicing. The default is no.\n"
            "  --mosaic-stdev=<float_number>\n"
            "      Consistent mosaicing stdev threshold. The default is 10.0.\n\n"
            "  --motion-inpaint=(yes|no)\n"
            "      Do motion inpainting (requires GPU support). The default is no.\n"
            "  --dist-thresh=<float_number>\n"
            "      Estimated flow distance threshold for motion inpainting. The default is 5.0.\n\n"
            "  --color-inpaint=(no|average|ns|telea)\n"
            "      Do color inpainting. The defailt is no.\n"
            "  --color-inpaint-radius=<float_number>\n"
            "      Set color inpainting radius (for ns and telea options only).\n\n"
            "  -o, --output=(no|<file_path>)\n"
            "      Set output file path explicitely. The default is stabilized.avi.\n"
            "  --fps=<int_number>\n"
            "      Set output video FPS explicitely. By default the source FPS is used.\n"
            "  -q, --quiet\n"
            "      Don't show output video frames.\n\n"
            "  -h, --help\n"
            "      Print help.\n"
            "\n";
}

int main(int argc, const char **argv)
{
    try
    {
        const char *keys =
                "{ 1 | | | | }"
                "{ m | model | | }"
                "{ | min-inlier-ratio | | }"
                "{ | outlier-ratio | | }"
                "{ | save-motions | | }"
                "{ | load-motions | | }"
                "{ r | radius | | }"
                "{ | stdev | | }"
                "{ | deblur | | }"
                "{ | deblur-sens | | }"
                "{ | est-trim | yes | }"
                "{ t | trim-ratio | | }"
                "{ | incl-constr | | }"
                "{ | border-mode | | }"
                "{ | mosaic | | }"
                "{ | mosaic-stdev | | }"
                "{ | motion-inpaint | | }"
                "{ | dist-thresh | | }"
                "{ | color-inpaint | no | }"
                "{ | color-inpaint-radius | | }"
                "{ o | output | stabilized.avi | }"
                "{ | fps | | }"
                "{ q | quiet | false | }"
                "{ h | help | false | }";
        CommandLineParser cmd(argc, argv, keys);

        // parse command arguments

        if (cmd.get<bool>("help"))
        {
            printHelp();
            return 0;
        }

        StabilizerBase *stabilizer;
        GaussianMotionFilter *motionFilter = 0;

        if (!cmd.get<string>("stdev").empty())
        {
            motionFilter = new GaussianMotionFilter();
            motionFilter->setStdev(cmd.get<float>("stdev"));
        }

        if (!cmd.get<string>("save-motions").empty())
            saveMotionsPath = cmd.get<string>("save-motions");

        bool isTwoPass =
                cmd.get<string>("est-trim") == "yes" ||
                !cmd.get<string>("save-motions").empty();

        if (isTwoPass)
        {
            TwoPassStabilizer *twoPassStabilizer = new TwoPassStabilizer();
            if (!cmd.get<string>("est-trim").empty())
                twoPassStabilizer->setEstimateTrimRatio(cmd.get<string>("est-trim") == "yes");
            if (motionFilter)
                twoPassStabilizer->setMotionStabilizer(motionFilter);
            stabilizer = twoPassStabilizer;
        }
        else
        {
            OnePassStabilizer *onePassStabilizer= new OnePassStabilizer();
            if (motionFilter)
                onePassStabilizer->setMotionFilter(motionFilter);
            stabilizer = onePassStabilizer;
        }

        string inputPath = cmd.get<string>("1");
        if (inputPath.empty())
            throw runtime_error("specify video file path");

        VideoFileSource *frameSource = new VideoFileSource(inputPath);
        outputFps = frameSource->fps();
        stabilizer->setFrameSource(frameSource);
        cout << "frame count: " << frameSource->frameCount() << endl;

        PyrLkRobustMotionEstimator *motionEstimator = new PyrLkRobustMotionEstimator();
        if (cmd.get<string>("model") == "transl")
            motionEstimator->setMotionModel(TRANSLATION);
        else if (cmd.get<string>("model") == "transl_and_scale")
            motionEstimator->setMotionModel(TRANSLATION_AND_SCALE);
        else if (cmd.get<string>("model") == "linear_sim")
            motionEstimator->setMotionModel(LINEAR_SIMILARITY);
        else if (cmd.get<string>("model") == "affine")
            motionEstimator->setMotionModel(AFFINE);
        else if (!cmd.get<string>("model").empty())
            throw runtime_error("unknow motion mode: " + cmd.get<string>("model"));
        if (!cmd.get<string>("outlier-ratio").empty())
        {
            RansacParams ransacParams = motionEstimator->ransacParams();
            ransacParams.eps = cmd.get<float>("outlier-ratio");
            motionEstimator->setRansacParams(ransacParams);
        }
        if (!cmd.get<string>("min-inlier-ratio").empty())
            motionEstimator->setMinInlierRatio(cmd.get<float>("min-inlier-ratio"));
        stabilizer->setMotionEstimator(motionEstimator);
        if (!cmd.get<string>("load-motions").empty())
            stabilizer->setMotionEstimator(new GlobalMotionReader(cmd.get<string>("load-motions")));

        if (!cmd.get<string>("radius").empty())
            stabilizer->setRadius(cmd.get<int>("radius"));

        if (cmd.get<string>("deblur") == "yes")
        {
            WeightingDeblurer *deblurer = new WeightingDeblurer();
            if (!cmd.get<string>("deblur-sens").empty())
                deblurer->setSensitivity(cmd.get<float>("deblur-sens"));
            stabilizer->setDeblurer(deblurer);
        }

        if (!cmd.get<string>("trim-ratio").empty())
            stabilizer->setTrimRatio(cmd.get<float>("trim-ratio"));

        if (!cmd.get<string>("incl-constr").empty())
            stabilizer->setCorrectionForInclusion(cmd.get<string>("incl-constr") == "yes");

        if (cmd.get<string>("border-mode") == "reflect")
            stabilizer->setBorderMode(BORDER_REFLECT);
        else if (cmd.get<string>("border-mode") == "replicate")
            stabilizer->setBorderMode(BORDER_REPLICATE);
        else if (cmd.get<string>("border-mode") == "const")
            stabilizer->setBorderMode(BORDER_CONSTANT);
        else if (!cmd.get<string>("border-mode").empty())
            throw runtime_error("unknown border extrapolation mode: " + cmd.get<string>("border-mode"));

        InpaintingPipeline *inpainters = new InpaintingPipeline();
        if (cmd.get<string>("mosaic") == "yes")
        {
            ConsistentMosaicInpainter *inpainter = new ConsistentMosaicInpainter();
            if (!cmd.get<string>("mosaic-stdev").empty())
                inpainter->setStdevThresh(cmd.get<float>("mosaic-stdev"));
            inpainters->pushBack(inpainter);
        }
        if (cmd.get<string>("motion-inpaint") == "yes")
        {
            MotionInpainter *inpainter = new MotionInpainter();
            if (!cmd.get<string>("dist-thresh").empty())
                inpainter->setDistThreshold(cmd.get<float>("dist-thresh"));
            inpainters->pushBack(inpainter);
        }
        if (!cmd.get<string>("color-inpaint").empty())
        {
            if (cmd.get<string>("color-inpaint") == "average")
                inpainters->pushBack(new ColorAverageInpainter());
            else if (!cmd.get<string>("color-inpaint-radius").empty())
            {
                float radius = cmd.get<float>("color-inpaint-radius");
                if (cmd.get<string>("color-inpaint") == "ns")
                    inpainters->pushBack(new ColorInpainter(INPAINT_NS, radius));
                else if (cmd.get<string>("color-inpaint") == "telea")
                    inpainters->pushBack(new ColorInpainter(INPAINT_TELEA, radius));
                else if (cmd.get<string>("color-inpaint") != "no")
                    throw runtime_error("unknown color inpainting method: " + cmd.get<string>("color-inpaint"));
            }
            else
            {
                if (cmd.get<string>("color-inpaint") == "ns")
                    inpainters->pushBack(new ColorInpainter(INPAINT_NS));
                else if (cmd.get<string>("color-inpaint") == "telea")
                    inpainters->pushBack(new ColorInpainter(INPAINT_TELEA));
                else if (cmd.get<string>("color-inpaint") != "no")
                    throw runtime_error("unknown color inpainting method: " + cmd.get<string>("color-inpaint"));
            }
        }
        if (!inpainters->empty())
            stabilizer->setInpainter(inpainters);

        stabilizer->setLog(new LogToStdout());

        outputPath = cmd.get<string>("output") != "no" ? cmd.get<string>("output") : "";

        if (!cmd.get<string>("fps").empty())
            outputFps = cmd.get<double>("fps");

        quietMode = cmd.get<bool>("quiet");

        stabilizedFrames = dynamic_cast<IFrameSource*>(stabilizer);

        run();
    }
    catch (const exception &e)
    {
        cout << "error: " << e.what() << endl;
        stabilizedFrames.release();
        return -1;
    }
    stabilizedFrames.release();
    return 0;
}
<commit_msg>Fix clang build warning<commit_after>#if defined __clang__
#  pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
#endif

#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
#include <stdexcept>
#include "opencv2/core/core.hpp"
#include "opencv2/video/video.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/videostab/videostab.hpp"

using namespace std;
using namespace cv;
using namespace cv::videostab;

Ptr<IFrameSource> stabilizedFrames;
string saveMotionsPath;
double outputFps;
string outputPath;
bool quietMode;

void run();
void saveMotionsIfNecessary();
void printHelp();

class GlobalMotionReader : public IGlobalMotionEstimator
{
public:
    GlobalMotionReader(string path)
    {
        ifstream f(path.c_str());
        if (!f.is_open())
            throw runtime_error("can't open motions file: " + path);
        int size = 0; f >> size;
        motions_.resize(size);
        for (int i = 0; i < size; ++i)
        {
            Mat_<float> M(3, 3);
            for (int l = 0; l < 3; ++l)
                for (int s = 0; s < 3; ++s)
                    f >> M(l,s);
            motions_[i] = M;
        }
        pos_ = 0;
    }

    virtual Mat estimate(const Mat &/*frame0*/, const Mat &/*frame1*/)
    {
        if (pos_ >= motions_.size())
        {
            stringstream text;
            text << "can't load motion between frames " << pos_ << " and " << pos_+1;
            throw runtime_error(text.str());
        }
        return motions_[pos_++];
    }

private:
    vector<Mat> motions_;
    size_t pos_;
};

void run()
{
    VideoWriter writer;
    Mat stabilizedFrame;

    while (!(stabilizedFrame = stabilizedFrames->nextFrame()).empty())
    {
        if (!saveMotionsPath.empty())
            saveMotionsIfNecessary();
        if (!outputPath.empty())
        {
            if (!writer.isOpened())
                writer.open(outputPath, CV_FOURCC('X','V','I','D'), outputFps, stabilizedFrame.size());
            writer << stabilizedFrame;
        }
        if (!quietMode)
        {
            imshow("stabilizedFrame", stabilizedFrame);
            char key = static_cast<char>(waitKey(3));
            if (key == 27)
                break;
        }
    }

    cout << "\nfinished\n";
}

void saveMotionsIfNecessary()
{
    static bool areMotionsSaved = false;
    if (!areMotionsSaved)
    {
        IFrameSource *frameSource = static_cast<IFrameSource*>(stabilizedFrames);
        TwoPassStabilizer *twoPassStabilizer = dynamic_cast<TwoPassStabilizer*>(frameSource);
        if (twoPassStabilizer)
        {
            ofstream f(saveMotionsPath.c_str());
            const vector<Mat> &motions = twoPassStabilizer->motions();
            f << motions.size() << endl;
            for (size_t i = 0; i < motions.size(); ++i)
            {
                Mat_<float> M = motions[i];
                for (int l = 0, k = 0; l < 3; ++l)
                    for (int s = 0; s < 3; ++s, ++k)
                        f << M(l,s) << " ";
                f << endl;
            }
        }
        areMotionsSaved = true;
        cout << "motions are saved";
    }
}

void printHelp()
{
    cout << "OpenCV video stabilizer.\n"
            "Usage: videostab <file_path> [arguments]\n\n"
            "Arguments:\n"
            "  -m, --model=(transl|transl_and_scale|linear_sim|affine)\n"
            "      Set motion model. The default is affine.\n"
            "  --outlier-ratio=<float_number>\n"
            "      Outliers ratio in motion estimation. The default is 0.5.\n"
            "  --min-inlier-ratio=<float_number>\n"
            "      Minimum inlier ratio to decide if estimated motion is OK. The default is 0.1,\n"
            "      but you may want to increase it.\n\n"
            "  --save-motions=<file_path>\n"
            "      Save estimated motions into file.\n"
            "  --load-motions=<file_path>\n"
            "      Load motions from file.\n\n"
            "  -r, --radius=<int_number>\n"
            "      Set smoothing radius. The default is 15.\n"
            "  --stdev=<float_number>\n"
            "      Set smoothing weights standard deviation. The default is sqrt(radius).\n\n"
            "  --deblur=(yes|no)\n"
            "      Do deblurring.\n"
            "  --deblur-sens=<float_number>\n"
            "      Set deblurring sensitivity (from 0 to +inf). The default is 0.1.\n\n"
            "  -t, --trim-ratio=<float_number>\n"
            "      Set trimming ratio (from 0 to 0.5). The default is 0.0.\n"
            "  --est-trim=(yes|no)\n"
            "      Estimate trim ratio automatically. The default is yes (that leads to two passes,\n"
            "      you can turn it off if you want to use one pass only).\n"
            "  --incl-constr=(yes|no)\n"
            "      Ensure the inclusion constraint is always satisfied. The default is no.\n\n"
            "  --border-mode=(replicate|reflect|const)\n"
            "      Set border extrapolation mode. The default is replicate.\n\n"
            "  --mosaic=(yes|no)\n"
            "      Do consistent mosaicing. The default is no.\n"
            "  --mosaic-stdev=<float_number>\n"
            "      Consistent mosaicing stdev threshold. The default is 10.0.\n\n"
            "  --motion-inpaint=(yes|no)\n"
            "      Do motion inpainting (requires GPU support). The default is no.\n"
            "  --dist-thresh=<float_number>\n"
            "      Estimated flow distance threshold for motion inpainting. The default is 5.0.\n\n"
            "  --color-inpaint=(no|average|ns|telea)\n"
            "      Do color inpainting. The defailt is no.\n"
            "  --color-inpaint-radius=<float_number>\n"
            "      Set color inpainting radius (for ns and telea options only).\n\n"
            "  -o, --output=(no|<file_path>)\n"
            "      Set output file path explicitely. The default is stabilized.avi.\n"
            "  --fps=<int_number>\n"
            "      Set output video FPS explicitely. By default the source FPS is used.\n"
            "  -q, --quiet\n"
            "      Don't show output video frames.\n\n"
            "  -h, --help\n"
            "      Print help.\n"
            "\n";
}

int main(int argc, const char **argv)
{
    try
    {
        const char *keys =
                "{ 1 | | | | }"
                "{ m | model | | }"
                "{ | min-inlier-ratio | | }"
                "{ | outlier-ratio | | }"
                "{ | save-motions | | }"
                "{ | load-motions | | }"
                "{ r | radius | | }"
                "{ | stdev | | }"
                "{ | deblur | | }"
                "{ | deblur-sens | | }"
                "{ | est-trim | yes | }"
                "{ t | trim-ratio | | }"
                "{ | incl-constr | | }"
                "{ | border-mode | | }"
                "{ | mosaic | | }"
                "{ | mosaic-stdev | | }"
                "{ | motion-inpaint | | }"
                "{ | dist-thresh | | }"
                "{ | color-inpaint | no | }"
                "{ | color-inpaint-radius | | }"
                "{ o | output | stabilized.avi | }"
                "{ | fps | | }"
                "{ q | quiet | false | }"
                "{ h | help | false | }";
        CommandLineParser cmd(argc, argv, keys);

        // parse command arguments

        if (cmd.get<bool>("help"))
        {
            printHelp();
            return 0;
        }

        StabilizerBase *stabilizer;
        GaussianMotionFilter *motionFilter = 0;

        if (!cmd.get<string>("stdev").empty())
        {
            motionFilter = new GaussianMotionFilter();
            motionFilter->setStdev(cmd.get<float>("stdev"));
        }

        if (!cmd.get<string>("save-motions").empty())
            saveMotionsPath = cmd.get<string>("save-motions");

        bool isTwoPass =
                cmd.get<string>("est-trim") == "yes" ||
                !cmd.get<string>("save-motions").empty();

        if (isTwoPass)
        {
            TwoPassStabilizer *twoPassStabilizer = new TwoPassStabilizer();
            if (!cmd.get<string>("est-trim").empty())
                twoPassStabilizer->setEstimateTrimRatio(cmd.get<string>("est-trim") == "yes");
            if (motionFilter)
                twoPassStabilizer->setMotionStabilizer(motionFilter);
            stabilizer = twoPassStabilizer;
        }
        else
        {
            OnePassStabilizer *onePassStabilizer= new OnePassStabilizer();
            if (motionFilter)
                onePassStabilizer->setMotionFilter(motionFilter);
            stabilizer = onePassStabilizer;
        }

        string inputPath = cmd.get<string>("1");
        if (inputPath.empty())
            throw runtime_error("specify video file path");

        VideoFileSource *frameSource = new VideoFileSource(inputPath);
        outputFps = frameSource->fps();
        stabilizer->setFrameSource(frameSource);
        cout << "frame count: " << frameSource->frameCount() << endl;

        PyrLkRobustMotionEstimator *motionEstimator = new PyrLkRobustMotionEstimator();
        if (cmd.get<string>("model") == "transl")
            motionEstimator->setMotionModel(TRANSLATION);
        else if (cmd.get<string>("model") == "transl_and_scale")
            motionEstimator->setMotionModel(TRANSLATION_AND_SCALE);
        else if (cmd.get<string>("model") == "linear_sim")
            motionEstimator->setMotionModel(LINEAR_SIMILARITY);
        else if (cmd.get<string>("model") == "affine")
            motionEstimator->setMotionModel(AFFINE);
        else if (!cmd.get<string>("model").empty())
            throw runtime_error("unknow motion mode: " + cmd.get<string>("model"));
        if (!cmd.get<string>("outlier-ratio").empty())
        {
            RansacParams ransacParams = motionEstimator->ransacParams();
            ransacParams.eps = cmd.get<float>("outlier-ratio");
            motionEstimator->setRansacParams(ransacParams);
        }
        if (!cmd.get<string>("min-inlier-ratio").empty())
            motionEstimator->setMinInlierRatio(cmd.get<float>("min-inlier-ratio"));
        stabilizer->setMotionEstimator(motionEstimator);
        if (!cmd.get<string>("load-motions").empty())
            stabilizer->setMotionEstimator(new GlobalMotionReader(cmd.get<string>("load-motions")));

        if (!cmd.get<string>("radius").empty())
            stabilizer->setRadius(cmd.get<int>("radius"));

        if (cmd.get<string>("deblur") == "yes")
        {
            WeightingDeblurer *deblurer = new WeightingDeblurer();
            if (!cmd.get<string>("deblur-sens").empty())
                deblurer->setSensitivity(cmd.get<float>("deblur-sens"));
            stabilizer->setDeblurer(deblurer);
        }

        if (!cmd.get<string>("trim-ratio").empty())
            stabilizer->setTrimRatio(cmd.get<float>("trim-ratio"));

        if (!cmd.get<string>("incl-constr").empty())
            stabilizer->setCorrectionForInclusion(cmd.get<string>("incl-constr") == "yes");

        if (cmd.get<string>("border-mode") == "reflect")
            stabilizer->setBorderMode(BORDER_REFLECT);
        else if (cmd.get<string>("border-mode") == "replicate")
            stabilizer->setBorderMode(BORDER_REPLICATE);
        else if (cmd.get<string>("border-mode") == "const")
            stabilizer->setBorderMode(BORDER_CONSTANT);
        else if (!cmd.get<string>("border-mode").empty())
            throw runtime_error("unknown border extrapolation mode: " + cmd.get<string>("border-mode"));

        InpaintingPipeline *inpainters = new InpaintingPipeline();
        if (cmd.get<string>("mosaic") == "yes")
        {
            ConsistentMosaicInpainter *inpainter = new ConsistentMosaicInpainter();
            if (!cmd.get<string>("mosaic-stdev").empty())
                inpainter->setStdevThresh(cmd.get<float>("mosaic-stdev"));
            inpainters->pushBack(inpainter);
        }
        if (cmd.get<string>("motion-inpaint") == "yes")
        {
            MotionInpainter *inpainter = new MotionInpainter();
            if (!cmd.get<string>("dist-thresh").empty())
                inpainter->setDistThreshold(cmd.get<float>("dist-thresh"));
            inpainters->pushBack(inpainter);
        }
        if (!cmd.get<string>("color-inpaint").empty())
        {
            if (cmd.get<string>("color-inpaint") == "average")
                inpainters->pushBack(new ColorAverageInpainter());
            else if (!cmd.get<string>("color-inpaint-radius").empty())
            {
                float radius = cmd.get<float>("color-inpaint-radius");
                if (cmd.get<string>("color-inpaint") == "ns")
                    inpainters->pushBack(new ColorInpainter(INPAINT_NS, radius));
                else if (cmd.get<string>("color-inpaint") == "telea")
                    inpainters->pushBack(new ColorInpainter(INPAINT_TELEA, radius));
                else if (cmd.get<string>("color-inpaint") != "no")
                    throw runtime_error("unknown color inpainting method: " + cmd.get<string>("color-inpaint"));
            }
            else
            {
                if (cmd.get<string>("color-inpaint") == "ns")
                    inpainters->pushBack(new ColorInpainter(INPAINT_NS));
                else if (cmd.get<string>("color-inpaint") == "telea")
                    inpainters->pushBack(new ColorInpainter(INPAINT_TELEA));
                else if (cmd.get<string>("color-inpaint") != "no")
                    throw runtime_error("unknown color inpainting method: " + cmd.get<string>("color-inpaint"));
            }
        }
        if (!inpainters->empty())
            stabilizer->setInpainter(inpainters);

        stabilizer->setLog(new LogToStdout());

        outputPath = cmd.get<string>("output") != "no" ? cmd.get<string>("output") : "";

        if (!cmd.get<string>("fps").empty())
            outputFps = cmd.get<double>("fps");

        quietMode = cmd.get<bool>("quiet");

        stabilizedFrames = dynamic_cast<IFrameSource*>(stabilizer);

        run();
    }
    catch (const exception &e)
    {
        cout << "error: " << e.what() << endl;
        stabilizedFrames.release();
        return -1;
    }
    stabilizedFrames.release();
    return 0;
}
<|endoftext|>