template <class T> std::shared_ptr<T>
MediaSet::getMediaObject (const KmsMediaObjectRef &mediaObject)
throw (KmsMediaServerException)
{
  std::map<KmsMediaObjectId, std::shared_ptr<MediaObjectImpl> >::iterator it;
  std::shared_ptr<KmsMediaObjectRef> mo = NULL;
  std::shared_ptr<T> typedMo;

  mutex.lock();
  it = mediaObjectsMap.find (mediaObject.id);

  if (it != mediaObjectsMap.end() )
    mo = it->second;

  mutex.unlock();

  if (mo == NULL) {
    KmsMediaServerException except;

    createKmsMediaServerException (except, g_KmsMediaErrorCodes_constants.MEDIA_OBJECT_NOT_FOUND, "Media object not found");
    throw except;
  }

  typedMo = std::dynamic_pointer_cast<T> (mo);

  if (typedMo == NULL) {
    KmsMediaServerException except;

    createKmsMediaServerException (except, g_KmsMediaErrorCodes_constants.MEDIA_OBJECT_CAST_ERROR, "Media Object found is not of requested type");
    throw except;
  }

  return typedMo;
}
PlayerEndPoint::PlayerEndPoint (MediaSet &mediaSet,
                                std::shared_ptr<MediaPipeline> parent,
                                const std::map<std::string, KmsMediaParam> &params)
throw (KmsMediaServerException)
  : UriEndPoint (mediaSet, parent,
                 g_KmsMediaPlayerEndPointType_constants.TYPE_NAME, params)
{
  const KmsMediaParam *p;
  KmsMediaUriEndPointConstructorParams uriEpParams;

  p = getParam (params,
                g_KmsMediaUriEndPointType_constants.CONSTRUCTOR_PARAMS_DATA_TYPE);

  if (p == NULL) {
    KmsMediaServerException except;

    createKmsMediaServerException (except,
                                   g_KmsMediaErrorCodes_constants.MEDIA_OBJECT_ILLEGAL_PARAM_ERROR,
                                   "Param '" + g_KmsMediaUriEndPointType_constants.CONSTRUCTOR_PARAMS_DATA_TYPE +
                                   "' not found");
    throw except;
  }

  unmarshalKmsMediaUriEndPointConstructorParams (uriEpParams, p->data);

  init (parent, uriEpParams.uri);
}
/* default constructor */
GStreamerFilter::GStreamerFilter (
  MediaSet &mediaSet, std::shared_ptr<MediaPipeline> parent,
  const std::map<std::string, KmsMediaParam> &params)
  : Filter (mediaSet, parent, g_KmsMediaGStreamerFilterType_constants.TYPE_NAME,
            params)
{
  std::string commandLine, command, rest_token;
  GstElement *gstreamerFilter;

  getStringParam (commandLine, params,
                  g_KmsMediaGStreamerFilterType_constants.CONSTRUCTOR_PARAM_GSTREAMER_COMMAND);

  command = commandLine.substr (0, commandLine.find (' ') );

  GST_DEBUG ("Command %s", command.c_str() );

  element = gst_element_factory_make ("filterelement", NULL);

  g_object_set (element, "filter-factory", command.c_str(), NULL);
  g_object_ref (element);
  gst_bin_add (GST_BIN (parent->pipeline), element);
  gst_element_sync_state_with_parent (element);

  g_object_get (G_OBJECT (element), "filter", &gstreamerFilter, NULL);

  if (gstreamerFilter == NULL) {
    KmsMediaServerException except;

    createKmsMediaServerException (except,
                                   g_KmsMediaErrorCodes_constants.MEDIA_OBJECT_TYPE_NOT_FOUND,
                                   "Media Object type not found");
    throw except;
  }

  this->filter = gstreamerFilter;
  g_object_unref (gstreamerFilter);

  rest_token = commandLine.substr (command.length(), commandLine.length() - 1);

  if (rest_token.front() == ' ') {
    rest_token = rest_token.substr (rest_token.find_first_not_of (" "),
                                    rest_token.length() - 1);
  }

  if (rest_token.length() != 0) {
    setCommandProperties (rest_token);
  }

}
RecorderEndPoint::RecorderEndPoint (MediaSet &mediaSet,
                                    std::shared_ptr<MediaPipeline> parent,
                                    const std::map<std::string, KmsMediaParam> &params)
throw (KmsMediaServerException)
  : UriEndPoint (mediaSet, parent,
                 g_KmsMediaRecorderEndPointType_constants.TYPE_NAME, params)
{
  const KmsMediaParam *p;
  KmsMediaUriEndPointConstructorParams uriEpParams;
  KmsMediaRecoderEndPointConstructorParams recorderParams;
  KmsMediaProfile profile;

  p = getParam (params, g_KmsMediaUriEndPointType_constants.CONSTRUCTOR_PARAMS_DATA_TYPE);

  if (p == NULL) {
    KmsMediaServerException except;

    createKmsMediaServerException (except, g_KmsMediaErrorCodes_constants.MEDIA_OBJECT_ILLEGAL_PARAM_ERROR,
                                   "Param '" + g_KmsMediaUriEndPointType_constants.CONSTRUCTOR_PARAMS_DATA_TYPE + "' not found");
    throw except;
  }

  unmarshalKmsMediaUriEndPointConstructorParams (uriEpParams, p->data);
  //unmarshal KmsMediaRecoderEndPointConstructorParams
  p = getParam (params, g_KmsMediaRecorderEndPointType_constants.CONSTRUCTOR_PARAMS_DATA_TYPE);
  profile.mediaMuxer = KmsMediaMuxer::WEBM;

  if (p != NULL) {
    unmarshalStruct (recorderParams, p->data);

    if (recorderParams.__isset.profileType) {
      profile = recorderParams.profileType;
    }
  }

  init (parent, uriEpParams.uri, profile);
}
/* default constructor */
PointerDetectorFilter::PointerDetectorFilter (
  MediaSet &mediaSet, std::shared_ptr<MediaPipeline> parent,
  const std::map<std::string, KmsMediaParam> &params)
  : Filter (mediaSet, parent, g_KmsMediaPointerDetectorFilterType_constants.TYPE_NAME, params)
{
  const KmsMediaParam *p;
  KmsMediaPointerDetectorWindowSet windowSet;

  element = gst_element_factory_make ("filterelement", NULL);

  g_object_set (element, "filter-factory", "pointerdetector", NULL);
  g_object_ref (element);
  gst_bin_add (GST_BIN (parent->pipeline), element);
  gst_element_sync_state_with_parent (element);

  GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (parent->pipeline) );
  GstElement *pointerDetector;

  g_object_get (G_OBJECT (element), "filter", &pointerDetector, NULL);

  this->pointerDetector = pointerDetector;

  if (this->pointerDetector == NULL) {
    g_object_unref (bus);
    KmsMediaServerException except;

    createKmsMediaServerException (except,
                                   g_KmsMediaErrorCodes_constants.MEDIA_OBJECT_NOT_AVAILAIBLE,
                                   "Media Object not available");
    throw except;
  }

  p = getParam (params,
                g_KmsMediaPointerDetectorFilterType_constants.CONSTRUCTOR_PARAMS_DATA_TYPE);

  if (p != NULL) {
    GstStructure *buttonsLayout;
    //there are data about windows
    unmarshalStruct (windowSet, p->data);
    /* set the window layout list */
    buttonsLayout = gst_structure_new_empty  ("windowsLayout");

    for (auto it = windowSet.windows.begin(); it != windowSet.windows.end(); ++it) {
      KmsMediaPointerDetectorWindow windowInfo = *it;
      GstStructure *buttonsLayoutAux;
      buttonsLayoutAux = gst_structure_new (
                           windowInfo.id.c_str(),
                           "upRightCornerX", G_TYPE_INT, windowInfo.topRightCornerX,
                           "upRightCornerY", G_TYPE_INT, windowInfo.topRightCornerY,
                           "width", G_TYPE_INT, windowInfo.width,
                           "height", G_TYPE_INT, windowInfo.height,
                           "id", G_TYPE_STRING, windowInfo.id.c_str(),
                           NULL);
      gst_structure_set (buttonsLayout,
                         windowInfo.id.c_str(), GST_TYPE_STRUCTURE, buttonsLayoutAux,
                         NULL);

      gst_structure_free (buttonsLayoutAux);
    }

    g_object_set (G_OBJECT (this->pointerDetector), WINDOWS_LAYOUT, buttonsLayout, NULL);
    gst_structure_free (buttonsLayout);
  }

  windowSet.windows.clear();

  bus_handler_id = g_signal_connect (bus, "message", G_CALLBACK (pointerDetector_receive_message), this);
  g_object_unref (bus);
  // There is no need to reference pointerdetector because its life cycle is the same as the filter life cycle
  g_object_unref (pointerDetector);
}