panoStitcherBase.hpp 5.54 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
// Copyright (c) 2012-2017 VideoStitch SAS
// Copyright (c) 2018 stitchEm

#pragma once

#include "gpu/buffer.hpp"
#include "gpu/hostBuffer.hpp"
#include "gpu/stream.hpp"
#include "input/inputFrame.hpp"

#include "libvideostitch/audio.hpp"
#include "libvideostitch/input.hpp"
#include "libvideostitch/matrix.hpp"
#include "libvideostitch/output.hpp"
#include "libvideostitch/quaternion.hpp"

#include <map>

namespace VideoStitch {

namespace Input {
class Reader;
}
namespace Core {

class AlgorithmOutput;
class ImageMergerFactory;
class ImageWarperFactory;
class ImageFlowFactory;
class PanoDefinition;
class DevicePhotoTransform;
class PanoSurface;
class PostProcessor;
class PreProcessor;
class StereoRigDefinition;

class Buffer;

/**
 * An enum that describes the compatibility of changes between to PanoDefinitions.
 */
enum ChangeCompatibility {
  IncompatibleChanges,       // Changes are completely incompatible (e.g. changing an input).
  SetupIncompatibleChanges,  // Changes are compatible, but setup needs to be redon (e.g. resizing an input).
  // TransformIncompatibleChanges,  // Changes are compatible, but transform needs to be re-initialized (e.g. changing
  // the photo response).
  SetupCompatibleChanges  // CHanges are fully compatible.
};

/**
 * @brief Implementation of PanoStitcher.
 */
template <typename Output>
class PanoStitcherImplBase {
 public:
  PanoStitcherImplBase(const std::string& name, const PanoDefinition&, Eye);
  virtual ~PanoStitcherImplBase();

  /**
   * Stitches a full panorama image.
   * @param output Where to write the output.
   * @param readFrame If false, the stitcher will not read the next frame but will restitch the last frame.
   * @return True on success.
   */
  Status stitch(mtime_t date, frameid_t frame, PostProcessor* postprocessor,
                std::map<readerid_t, Input::PotentialFrame> inputBuffers,
                std::map<readerid_t, Input::VideoReader*> readers, std::map<readerid_t, PreProcessor*> preprocessors,
                Output* output);

  /**
   * Returns the photo transform for a given input.
   * @param inputId Input id whose transform to retrieve.
   */
  const DevicePhotoTransform& getPhotoTransform(readerid_t inputId) const;

  /**
   * Computes the level of compatibility between two PanoDefinitions.
   * @param pano reference pano
   * @param newPano new pano
   */
  virtual ChangeCompatibility getCompatibility(const PanoDefinition& pano, const PanoDefinition& newPano) const = 0;

  /**
   * Returns the worst compatibility.
   * @param a compared
   * @param b compared to
   */
  static ChangeCompatibility worstCompatibility(ChangeCompatibility a, ChangeCompatibility b);

  /**
   * The Panostitcher is invalid until it has been setup().
   * pano must live until the PanoStitcher is destroyed.
   */
  PanoStitcherImplBase();

  /**
   * Setup the panoStitcher.
   * @param mergerFactory Used to create mergers. Can be released after the call.
   * Returns true on success.
   */
  Status setup(const ImageMergerFactory& mergerFactory, const ImageWarperFactory& warperFactory,
               const ImageFlowFactory& flowFactory, const std::map<readerid_t, Input::VideoReader*>&,
               const StereoRigDefinition* rig = NULL);

  /**
   * Re-setup the panoStitcher. This is less expensive that destroying and setting up, but is not compatible with all
   * changes (see controller::resetPano()); Returns true on success.
   */
  Status redoSetup(const PanoDefinition&, const ImageMergerFactory& mergerFactory,
                   const ImageWarperFactory& warperFactory, const ImageFlowFactory& flowFactory,
                   const std::map<readerid_t, Input::VideoReader*>, const StereoRigDefinition* = NULL);

  // Getters for implementors.

  const PanoDefinition& getPano() const { return *pano; }
  void setPano(const PanoDefinition& p) { pano = &p; }

  Eye getEye() const { return eye; }

  GPU::Stream getStreamForInput(readerid_t inputId) { return streams[inputId]; }

  virtual void applyRotation(double yaw, double pitch, double roll);
  virtual void resetRotation();
  virtual Quaternion<double> getRotation() const;

  const Matrix33<double>& getInteractivePersp() const { return interactivePersp; }

 private:
  /**
   * Actual stitching work.
   */
  virtual Status merge(frameid_t frame, const std::map<readerid_t, Input::PotentialFrame>& inputBuffers,
                       const std::map<readerid_t, Input::VideoReader*>& readers,
                       const std::map<readerid_t, PreProcessor*>& preprocessors, PanoSurface& pano) = 0;

  virtual Status setupImpl(const ImageMergerFactory& mergerFactory, const ImageWarperFactory& warperFactory,
                           const ImageFlowFactory& flowFactory, const std::map<readerid_t, Input::VideoReader*>&,
                           const StereoRigDefinition*) = 0;

  virtual Status redoSetupImpl(const ImageMergerFactory& mergerFactory, const ImageWarperFactory& warperFactory,
                               const ImageFlowFactory& flowFactory, const std::map<readerid_t, Input::VideoReader*>&,
                               const StereoRigDefinition*) = 0;

  /**
   * Creates the transforms.
   * @return false on error.
   */
  Status createTransforms(const std::map<readerid_t, Input::VideoReader*>&);

 private:
  const std::string name;
  const PanoDefinition* pano;
  std::map<readerid_t, GPU::Stream> streams;
  std::map<readerid_t, DevicePhotoTransform*> photoTransforms;
  Matrix33<double> interactivePersp;  // interactive yaw/pitch/roll
  Eye eye;
  PanoStitcherImplBase& operator=(const PanoStitcherImplBase&);
};
}  // namespace Core
}  // namespace VideoStitch