Пример #1
0
SADisplay::~SADisplay ()
{
    visual_object_unref (VISUAL_OBJECT (m_impl->screen));
}
Пример #2
0
static int fixate_with_partial_data_request (VisRingBuffer *ringbuffer, VisBuffer *data, int offset, int nbytes,
		int *buffercorr)
{
	VisListEntry *le = NULL;
	VisRingBufferEntry *entry;
	int curposition = 0;
	int curoffset = 0;
	int startat = 0;

	*buffercorr = 0;

	while ((entry = visual_list_next (ringbuffer->entries, &le)) != NULL) {
		int bsize = 0;

		startat++;

		if (entry->type == VISUAL_RINGBUFFER_ENTRY_TYPE_BUFFER) {

			if ((bsize = visual_buffer_get_size (entry->buffer)) > 0)
				curoffset += bsize;

			/* This buffer partially falls within the offset */
			if (curoffset > offset) {
				visual_buffer_put_data (data,
						(visual_buffer_get_data (entry->buffer) +
						 visual_buffer_get_size (entry->buffer)) -
						(curoffset - offset), curoffset - offset, 0);

				*buffercorr = curoffset - offset;

				break;
			}
		} else if (entry->type == VISUAL_RINGBUFFER_ENTRY_TYPE_FUNCTION) {

			if (entry->sizefunc != NULL) {
				curoffset += entry->sizefunc (ringbuffer, entry);

				/* This buffer partially falls within the offset */
				if (curoffset > offset) {

					VisBuffer *tempbuf = entry->datafunc (ringbuffer, entry);

					visual_buffer_put_data (data,
							(visual_buffer_get_data (tempbuf) +
							visual_buffer_get_size (tempbuf)) -
							(curoffset - offset), curoffset - offset, 0);

					visual_object_unref (VISUAL_OBJECT (tempbuf));

					*buffercorr = curoffset - offset;

					break;
				}
			} else {
				VisBuffer *tempbuf = entry->datafunc (ringbuffer, entry);

				if ((bsize = visual_buffer_get_size (tempbuf)) > 0)
					curoffset += bsize;

				/* This buffer partially falls within the offset */
				if (curoffset > offset) {
					visual_buffer_put_data (data,
							(visual_buffer_get_data (tempbuf) +
							visual_buffer_get_size (tempbuf)) -
							(curoffset - offset), curoffset - offset, 0);

					*buffercorr = curoffset - offset;

					break;
				}

				visual_object_unref (VISUAL_OBJECT (tempbuf));
			}
		}
	}

	return startat;
}
Пример #3
0
static void
render_frame (GstVisualGL * visual)
{
  const guint16 *data;
  VisBuffer *lbuf, *rbuf;
  guint16 ldata[VISUAL_SAMPLES], rdata[VISUAL_SAMPLES];
  guint i;
  gcahr *name;

  /* Read VISUAL_SAMPLES samples per channel */
  data =
      (const guint16 *) gst_adapter_peek (visual->adapter,
      VISUAL_SAMPLES * visual->bps);

  lbuf = visual_buffer_new_with_buffer (ldata, sizeof (ldata), NULL);
  rbuf = visual_buffer_new_with_buffer (rdata, sizeof (rdata), NULL);

  if (visual->channels == 2) {
    for (i = 0; i < VISUAL_SAMPLES; i++) {
      ldata[i] = *data++;
      rdata[i] = *data++;
    }
  } else {
    for (i = 0; i < VISUAL_SAMPLES; i++) {
      ldata[i] = *data;
      rdata[i] = *data++;
    }
  }

  visual_audio_samplepool_input_channel (visual->audio->samplepool,
      lbuf, visual->libvisual_rate, VISUAL_AUDIO_SAMPLE_FORMAT_S16,
      VISUAL_AUDIO_CHANNEL_LEFT);
  visual_audio_samplepool_input_channel (visual->audio->samplepool,
      rbuf, visual->libvisual_rate, VISUAL_AUDIO_SAMPLE_FORMAT_S16,
      VISUAL_AUDIO_CHANNEL_RIGHT);

  visual_object_unref (VISUAL_OBJECT (lbuf));
  visual_object_unref (VISUAL_OBJECT (rbuf));

  visual_audio_analyze (visual->audio);

  /* apply the matrices that the actor set up */
  glPushAttrib (GL_ALL_ATTRIB_BITS);

  glMatrixMode (GL_PROJECTION);
  glPushMatrix ();
  glLoadMatrixd (visual->actor_projection_matrix);

  glMatrixMode (GL_MODELVIEW);
  glPushMatrix ();
  glLoadMatrixd (visual->actor_modelview_matrix);

  /* This line try to hacks compatiblity with libprojectM
   * If libprojectM version <= 2.0.0 then we have to unbind our current
   * fbo to see something. But it's incorrect and we cannot use fbo chainning (append other glfilters
   * after libvisual_gl_projectM will not work)
   * To have full compatibility, libprojectM needs to take care of our fbo.
   * Indeed libprojectM has to unbind it before the first rendering pass
   * and then rebind it before the final pass. It's done from 2.0.1
   */
  name = gst_element_get_name (GST_ELEMENT (visual));
  if (g_ascii_strncasecmp (name, "visualglprojectm", 16) == 0
      && !HAVE_PROJECTM_TAKING_CARE_OF_EXTERNAL_FBO)
    glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0);
  g_free (name);

  actor_negotiate (visual->display, visual);

  if (visual->is_enabled_gl_depth_test) {
    glEnable (GL_DEPTH_TEST);
    glDepthFunc (visual->gl_depth_func);
  }

  if (visual->is_enabled_gl_blend) {
    glEnable (GL_BLEND);
    glBlendFunc (visual->gl_blend_src_alpha, GL_ZERO);
  }

  visual_actor_run (visual->actor, visual->audio);

  check_gl_matrix ();

  glMatrixMode (GL_PROJECTION);
  glPopMatrix ();

  glMatrixMode (GL_MODELVIEW);
  glPopMatrix ();

  glPopAttrib ();

  glDisable (GL_DEPTH_TEST);
  glDisable (GL_BLEND);

  /*glDisable (GL_LIGHT0);
     glDisable (GL_LIGHTING);
     glDisable (GL_POLYGON_OFFSET_FILL);
     glDisable (GL_COLOR_MATERIAL);
     glDisable (GL_CULL_FACE); */

  GST_DEBUG_OBJECT (visual, "rendered one frame");
}
Пример #4
0
int visual_ringbuffer_get_data_offset (VisRingBuffer *ringbuffer, VisBuffer *data, int offset, int nbytes)
{
	VisListEntry *le = NULL;
	VisRingBufferEntry *entry;
	int curposition = 0;
	int curoffset = 0;
	int positioncorr = 0;
	int startat = 0;
	int buffercorr = 0;

	visual_log_return_val_if_fail (ringbuffer != NULL, -VISUAL_ERROR_RINGBUFFER_NULL);
	visual_log_return_val_if_fail (data != NULL, -VISUAL_ERROR_BUFFER_NULL);

	/* Fixate possible partial buffer */
	if (offset > 0)
		startat = fixate_with_partial_data_request (ringbuffer, data, offset, nbytes, &buffercorr);

	curposition = buffercorr;

	/* Buffer fixated with partial segment, request the other segments */
	while (curposition < nbytes) {
		int lindex = 0;
		le = NULL;

		/* return immediately if there are no elements in the list */
		if(visual_list_count(ringbuffer->entries) == 0)
			return VISUAL_OK;
			
		while ((entry = visual_list_next (ringbuffer->entries, &le)) != NULL) {
			VisBuffer *tempbuf;

			lindex++;

			/* Skip to the right offset buffer fragment */
			if (lindex <= startat)
				continue;

			if (entry->type == VISUAL_RINGBUFFER_ENTRY_TYPE_BUFFER) {

				tempbuf = entry->buffer;

			} else if (entry->type == VISUAL_RINGBUFFER_ENTRY_TYPE_FUNCTION) {

				/* Will bail out through visual_error_raise(), this is fatal, let's not try to
				 * recover, it's a very obvious bug in the software */
				if (entry->datafunc == NULL) {
					visual_log (VISUAL_LOG_ERROR,
							_("No VisRingBufferDataFunc data provider function set on "
								"type VISUAL_RINGBUFFER_ENTRY_TYPE_FUNCTION"));

					return -VISUAL_ERROR_IMPOSSIBLE;
				}

				tempbuf = entry->datafunc (ringbuffer, entry);
			}

			if (curposition + visual_buffer_get_size (tempbuf) > nbytes) {
				VisBuffer buf;

				visual_buffer_init (&buf, visual_buffer_get_data (tempbuf),
						nbytes - curposition, NULL);

				visual_buffer_put (data, &buf, curposition);

				if (entry->type == VISUAL_RINGBUFFER_ENTRY_TYPE_FUNCTION)
					visual_object_unref (VISUAL_OBJECT (tempbuf));

				return VISUAL_OK;
			}

			visual_buffer_put (data, tempbuf, curposition);

			curposition += visual_buffer_get_size (tempbuf);

			if (entry->type == VISUAL_RINGBUFFER_ENTRY_TYPE_FUNCTION)
				visual_object_unref (VISUAL_OBJECT (tempbuf));

			/* Filled without room for partial buffer addition */
			if (curposition == nbytes)
				return VISUAL_OK;
		}

		startat = 0;
	}

	return VISUAL_OK;
}
Пример #5
0
int inp_alsa_init (VisPluginData *plugin)
{
	snd_pcm_hw_params_t *hwparams = NULL;
	alsaPrivate *priv;
	unsigned int rate = inp_alsa_var_samplerate;
	unsigned int exact_rate;
	unsigned int tmp;
	int dir;
	int err;

#if ENABLE_NLS
	bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
#endif

	visual_return_val_if_fail(plugin != NULL, -1);

	priv = visual_mem_new0 (alsaPrivate, 1);
	visual_return_val_if_fail(priv != NULL, -1);

	visual_object_set_private (VISUAL_OBJECT (plugin), priv);

	if ((err = snd_pcm_open(&priv->chandle, visual_strdup(inp_alsa_var_cdevice),
			SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK)) < 0) {
		visual_log(VISUAL_LOG_ERROR,
			    _("Record open error: %s"), snd_strerror(err));
		return -1;
	}

	snd_pcm_hw_params_malloc(&hwparams);
	visual_return_val_if_fail(hwparams != NULL, -1);

	if (snd_pcm_hw_params_any(priv->chandle, hwparams) < 0) {
		visual_log(VISUAL_LOG_ERROR,
			   _("Cannot configure this PCM device"));
		snd_pcm_hw_params_free(hwparams);
		return(-1);
	}

	if (snd_pcm_hw_params_set_access(priv->chandle, hwparams,
					 SND_PCM_ACCESS_RW_INTERLEAVED) < 0) {
		visual_log(VISUAL_LOG_ERROR, _("Error setting access"));
		snd_pcm_hw_params_free(hwparams);
		return(-1);
	}

#if VISUAL_LITTLE_ENDIAN == 1
	if (snd_pcm_hw_params_set_format(priv->chandle, hwparams,
					 SND_PCM_FORMAT_S16_LE) < 0) {
#else
	if (snd_pcm_hw_params_set_format(priv->chandle, hwparams,
					 SND_PCM_FORMAT_S16_BE) < 0) {
#endif
		visual_log(VISUAL_LOG_ERROR, _("Error setting format"));
		snd_pcm_hw_params_free(hwparams);
		return(-1);
	}

	exact_rate = rate;

	if (snd_pcm_hw_params_set_rate_near(priv->chandle, hwparams,
					    &exact_rate, &dir) < 0) {
		visual_log(VISUAL_LOG_ERROR, _("Error setting rate"));
		snd_pcm_hw_params_free(hwparams);
		return(-1);
	}
	if (exact_rate != rate) {
		visual_log(VISUAL_LOG_INFO,
			   _("The rate %d Hz is not supported by your " \
			   "hardware.\n" \
			   "==> Using %d Hz instead"), rate, exact_rate);
	}
	rate = exact_rate;

	if (snd_pcm_hw_params_set_channels(priv->chandle, hwparams,
					   inp_alsa_var_channels) < 0) {
	        visual_log(VISUAL_LOG_ERROR, _("Error setting channels"));
		snd_pcm_hw_params_free(hwparams);
		return(-1);
	}

       /* Setup a large buffer */

	tmp = 1000000;
	if (snd_pcm_hw_params_set_period_time_near(priv->chandle, hwparams, &tmp, &dir) < 0){
		visual_log(VISUAL_LOG_ERROR, _("Error setting period time"));
		snd_pcm_hw_params_free(hwparams);
		return(-1);
	}

	tmp = 1000000*4;
	if (snd_pcm_hw_params_set_buffer_time_near(priv->chandle, hwparams, &tmp, &dir) < 0){
		visual_log(VISUAL_LOG_ERROR, _("Error setting buffer time"));
		snd_pcm_hw_params_free(hwparams);
		return(-1);
	}


	if (snd_pcm_hw_params(priv->chandle, hwparams) < 0) {
		visual_log(VISUAL_LOG_ERROR, _("Error setting HW params"));
		snd_pcm_hw_params_free(hwparams);
		return(-1);
	}

	if (snd_pcm_prepare(priv->chandle) < 0) {
		visual_log(VISUAL_LOG_ERROR, _("Failed to prepare interface"));
		snd_pcm_hw_params_free(hwparams);
		return(-1);
	}

	snd_pcm_hw_params_free(hwparams);

	priv->loaded = 1;

	return 0;
}

int inp_alsa_cleanup (VisPluginData *plugin)
{
	alsaPrivate *priv = NULL;

	visual_return_val_if_fail(plugin != NULL, -1);
	priv = visual_object_get_private (VISUAL_OBJECT (plugin));
	visual_return_val_if_fail(priv != NULL, -1);

	if (priv->loaded == 1)
		snd_pcm_close(priv->chandle);

	visual_mem_free (priv);

	return 0;
}
Пример #6
0
static GstFlowReturn
gst_visual_chain (GstPad * pad, GstBuffer * buffer)
{
  GstBuffer *outbuf = NULL;
  guint i;
  GstVisual *visual = GST_VISUAL (gst_pad_get_parent (pad));
  GstFlowReturn ret = GST_FLOW_OK;
  guint avail;

  GST_DEBUG_OBJECT (visual, "chain function called");

  /* If we don't have an output format yet, preallocate a buffer to try and
   * set one */
  if (GST_PAD_CAPS (visual->srcpad) == NULL) {
    ret = get_buffer (visual, &outbuf);
    if (ret != GST_FLOW_OK) {
      gst_buffer_unref (buffer);
      goto beach;
    }
  }

  /* resync on DISCONT */
  if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT)) {
    gst_adapter_clear (visual->adapter);
  }

  GST_DEBUG_OBJECT (visual,
      "Input buffer has %d samples, time=%" G_GUINT64_FORMAT,
      GST_BUFFER_SIZE (buffer) / visual->bps, GST_BUFFER_TIMESTAMP (buffer));

  gst_adapter_push (visual->adapter, buffer);

  while (TRUE) {
    gboolean need_skip;
    const guint16 *data;
    guint64 dist, timestamp;

    GST_DEBUG_OBJECT (visual, "processing buffer");

    avail = gst_adapter_available (visual->adapter);
    GST_DEBUG_OBJECT (visual, "avail now %u", avail);

    /* we need at least VISUAL_SAMPLES samples */
    if (avail < VISUAL_SAMPLES * visual->bps)
      break;

    /* we need at least enough samples to make one frame */
    if (avail < visual->spf * visual->bps)
      break;

    /* get timestamp of the current adapter byte */
    timestamp = gst_adapter_prev_timestamp (visual->adapter, &dist);
    if (GST_CLOCK_TIME_IS_VALID (timestamp)) {
      /* convert bytes to time */
      dist /= visual->bps;
      timestamp += gst_util_uint64_scale_int (dist, GST_SECOND, visual->rate);
    }

    if (timestamp != -1) {
      gint64 qostime;

      /* QoS is done on running time */
      qostime = gst_segment_to_running_time (&visual->segment, GST_FORMAT_TIME,
          timestamp);
      qostime += visual->duration;

      GST_OBJECT_LOCK (visual);
      /* check for QoS, don't compute buffers that are known to be late */
      need_skip = visual->earliest_time != -1 &&
          qostime <= visual->earliest_time;
      GST_OBJECT_UNLOCK (visual);

      if (need_skip) {
        GST_WARNING_OBJECT (visual,
            "QoS: skip ts: %" GST_TIME_FORMAT ", earliest: %" GST_TIME_FORMAT,
            GST_TIME_ARGS (qostime), GST_TIME_ARGS (visual->earliest_time));
        goto skip;
      }
    }

    /* Read VISUAL_SAMPLES samples per channel */
    data =
        (const guint16 *) gst_adapter_peek (visual->adapter,
        VISUAL_SAMPLES * visual->bps);

#if defined(VISUAL_API_VERSION) && VISUAL_API_VERSION >= 4000 && VISUAL_API_VERSION < 5000
    {
      VisBuffer *lbuf, *rbuf;
      guint16 ldata[VISUAL_SAMPLES], rdata[VISUAL_SAMPLES];
      VisAudioSampleRateType rate;

      lbuf = visual_buffer_new_with_buffer (ldata, sizeof (ldata), NULL);
      rbuf = visual_buffer_new_with_buffer (rdata, sizeof (rdata), NULL);

      if (visual->channels == 2) {
        for (i = 0; i < VISUAL_SAMPLES; i++) {
          ldata[i] = *data++;
          rdata[i] = *data++;
        }
      } else {
        for (i = 0; i < VISUAL_SAMPLES; i++) {
          ldata[i] = *data;
          rdata[i] = *data++;
        }
      }

      switch (visual->rate) {
        case 8000:
          rate = VISUAL_AUDIO_SAMPLE_RATE_8000;
          break;
        case 11250:
          rate = VISUAL_AUDIO_SAMPLE_RATE_11250;
          break;
        case 22500:
          rate = VISUAL_AUDIO_SAMPLE_RATE_22500;
          break;
        case 32000:
          rate = VISUAL_AUDIO_SAMPLE_RATE_32000;
          break;
        case 44100:
          rate = VISUAL_AUDIO_SAMPLE_RATE_44100;
          break;
        case 48000:
          rate = VISUAL_AUDIO_SAMPLE_RATE_48000;
          break;
        case 96000:
          rate = VISUAL_AUDIO_SAMPLE_RATE_96000;
          break;
        default:
          visual_object_unref (VISUAL_OBJECT (lbuf));
          visual_object_unref (VISUAL_OBJECT (rbuf));
          GST_ERROR_OBJECT (visual, "unsupported rate %d", visual->rate);
          ret = GST_FLOW_ERROR;
          goto beach;
          break;
      }

      visual_audio_samplepool_input_channel (visual->audio->samplepool,
          lbuf,
          rate, VISUAL_AUDIO_SAMPLE_FORMAT_S16,
          (char *) VISUAL_AUDIO_CHANNEL_LEFT);
      visual_audio_samplepool_input_channel (visual->audio->samplepool, rbuf,
          rate, VISUAL_AUDIO_SAMPLE_FORMAT_S16,
          (char *) VISUAL_AUDIO_CHANNEL_RIGHT);

      visual_object_unref (VISUAL_OBJECT (lbuf));
      visual_object_unref (VISUAL_OBJECT (rbuf));

    }
#else
    if (visual->channels == 2) {
      for (i = 0; i < VISUAL_SAMPLES; i++) {
        visual->audio->plugpcm[0][i] = *data++;
        visual->audio->plugpcm[1][i] = *data++;
      }
    } else {
      for (i = 0; i < VISUAL_SAMPLES; i++) {
        visual->audio->plugpcm[0][i] = *data;
        visual->audio->plugpcm[1][i] = *data++;
      }
    }
#endif

    /* alloc a buffer if we don't have one yet, this happens
     * when we pushed a buffer in this while loop before */
    if (outbuf == NULL) {
      ret = get_buffer (visual, &outbuf);
      if (ret != GST_FLOW_OK) {
        goto beach;
      }
    }
    visual_video_set_buffer (visual->video, GST_BUFFER_DATA (outbuf));
    visual_audio_analyze (visual->audio);
    visual_actor_run (visual->actor, visual->audio);
    visual_video_set_buffer (visual->video, NULL);
    GST_DEBUG_OBJECT (visual, "rendered one frame");

    GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
    GST_BUFFER_DURATION (outbuf) = visual->duration;

    ret = gst_pad_push (visual->srcpad, outbuf);
    outbuf = NULL;

  skip:
    GST_DEBUG_OBJECT (visual, "finished frame, flushing %u samples from input",
        visual->spf);

    /* Flush out the number of samples per frame */
    gst_adapter_flush (visual->adapter, visual->spf * visual->bps);

    /* quit the loop if something was wrong */
    if (ret != GST_FLOW_OK)
      break;
  }

beach:

  if (outbuf != NULL)
    gst_buffer_unref (outbuf);

  gst_object_unref (visual);

  return ret;
}
Пример #7
0
static void set_parameter_lv(void * data, const char * name,
                             const bg_parameter_value_t * val)
  {
  int supported;
  lv_priv_t * priv;
  int index;
  int i_tmp;
  uint8_t r, g, b;
  char * tmp_string;
  VisParamEntry * param;
  VisListEntry * list_entry;

  VisColor * color;
  const bg_parameter_info_t * info;
  
  if(!name)
    return;
  priv = (lv_priv_t*)data;

  info = bg_parameter_find(priv->parameters, name);
  if(!info)
    return;

  /* This would crash if multi_parameters were supported */
  index = info - priv->parameters;

  tmp_string = gavl_strdup(name);
  param = visual_param_entry_new(tmp_string);
  free(tmp_string);
  /* Menus have to be treated specially */
  if(info->type == BG_PARAMETER_STRINGLIST)
    {
    if(!priv->widgets[index])
      return;
    /* Get the selected index */
    supported = 0;
    list_entry = NULL;
    while(visual_list_next(&VISUAL_UI_CHOICE(priv->widgets[index])->choices.choices,
                           &list_entry))
      {
      if(!strcmp(((VisUIChoiceEntry*)(list_entry->data))->name, val->val_str))
        {
        visual_param_entry_set_from_param(param,
                                          ((VisUIChoiceEntry*)(list_entry->data))->value);
        supported = 1;
        break;
        }
      }
    }
  else
    {
    supported = 1;
    switch(priv->params[index]->type)
      {
      case VISUAL_PARAM_ENTRY_TYPE_NULL:     /**< No parameter. */
        supported = 0;
        break;
      case VISUAL_PARAM_ENTRY_TYPE_STRING:   /**< String parameter. */
        if(val->val_str)
          visual_param_entry_set_string(param, val->val_str);
        else
          supported = 0;
        break;
      case VISUAL_PARAM_ENTRY_TYPE_INTEGER:  /**< Integer parameter. */
        visual_param_entry_set_integer(param, val->val_i);
        break;
      case VISUAL_PARAM_ENTRY_TYPE_FLOAT:    /**< Floating point parameter. */
        visual_param_entry_set_float(param, val->val_f);
        break;
      case VISUAL_PARAM_ENTRY_TYPE_DOUBLE:   /**< Double floating point parameter. */
        visual_param_entry_set_double(param, val->val_f);
        break;
      case VISUAL_PARAM_ENTRY_TYPE_COLOR:    /**< VisColor parameter. */
        i_tmp = (int)(val->val_color[0] * 255.0 + 0.5);
        if(i_tmp < 0) i_tmp = 0;
        if(i_tmp > 255) i_tmp = 255;
        r = i_tmp;
        
        i_tmp = (int)(val->val_color[1] * 255.0 + 0.5);
        if(i_tmp < 0) i_tmp = 0;
        if(i_tmp > 255) i_tmp = 255;
        g = i_tmp;

        i_tmp = (int)(val->val_color[2] * 255.0 + 0.5);
        if(i_tmp < 0) i_tmp = 0;
        if(i_tmp > 255) i_tmp = 255;
        b = i_tmp;

        color = visual_color_new();
        visual_color_set(color, r, g, b);
        visual_param_entry_set_color_by_color(param, color);
        visual_object_unref(VISUAL_OBJECT(color));
        break;
      case VISUAL_PARAM_ENTRY_TYPE_PALETTE:  /**< VisPalette parameter. */
      case VISUAL_PARAM_ENTRY_TYPE_OBJECT:   /**< VisObject parameter. */
      case VISUAL_PARAM_ENTRY_TYPE_END:      /**< List end, and used as terminator for VisParamEntry lists. */
        supported = 0;
        break;
      }
    }
  if(supported)
    {
    visual_event_queue_add_param(visual_plugin_get_eventqueue(visual_actor_get_plugin(priv->actor)),
                              param);
    }
  else
    visual_object_unref(VISUAL_OBJECT(param));
  }
Пример #8
0
bg_plugin_info_t * bg_lv_get_info(const char * filename)
  {
  int i;
  VisVideoAttributeOptions *vidoptions;
  bg_x11_window_t * win;
  bg_plugin_info_t * ret;
  VisPluginRef * ref;
  VisList * list;
  VisActor * actor;
  VisPluginInfo * info;
  char * tmp_string;
  const char * actor_name = NULL;
  check_init();
  
  list = visual_plugin_get_registry();
  /* Find out if there is a plugin matching the filename */
  while((actor_name = visual_actor_get_next_by_name(actor_name)))
    {
    ref = visual_plugin_find(list, actor_name);
    if(ref && !strcmp(ref->file, filename))
      break;
    }
  if(!actor_name)
    return NULL;
  
  actor = visual_actor_new(actor_name);
  
  if(!actor)
    return NULL;

  ret = calloc(1, sizeof(*ret));

  info = visual_plugin_get_info(visual_actor_get_plugin(actor));
    
  
  ret->name        = bg_sprintf("vis_lv_%s", actor_name);
  ret->long_name   = gavl_strdup(info->name);
  ret->type        = BG_PLUGIN_VISUALIZATION;
  ret->api         = BG_PLUGIN_API_LV;
  ret->description = bg_sprintf(TR("libvisual plugin"));
  ret->module_filename = gavl_strdup(filename);
  /* Optional info */
  if(info->author && *info->author)
    {
    tmp_string = bg_sprintf(TR("\nAuthor: %s"),
                            info->author);
    ret->description = gavl_strcat(ret->description, tmp_string);
    free(tmp_string);
    }
  if(info->version && *info->version)
    {
    tmp_string = bg_sprintf(TR("\nVersion: %s"),
                            info->version);
    ret->description = gavl_strcat(ret->description, tmp_string);
    free(tmp_string);
    }
  if(info->about && *info->about)
    {
    tmp_string = bg_sprintf(TR("\nAbout: %s"),
                            info->about);
    ret->description = gavl_strcat(ret->description, tmp_string);
    free(tmp_string);
    }
  if(info->help && *info->help)
    {
    tmp_string = bg_sprintf(TR("\nHelp: %s"),
                            info->help);
    ret->description = gavl_strcat(ret->description, tmp_string);
    free(tmp_string);
    }
  if(info->license && *info->license)
    {
    tmp_string = bg_sprintf(TR("\nLicense: %s"),
                            info->license);
    ret->description = gavl_strcat(ret->description, tmp_string);
    free(tmp_string);
    }
  
  /* Check out if it's an OpenGL plugin */
  if(visual_actor_get_supported_depth(actor) &
     VISUAL_VIDEO_DEPTH_GL)
    {
    ret->flags |=  BG_PLUGIN_VISUALIZE_GL;
    
    win = bg_x11_window_create(NULL);
    
    /* Create an OpenGL context. For this, we need the OpenGL attributes */
    vidoptions = visual_actor_get_video_attribute_options(actor);
    for(i = 0; i < VISUAL_GL_ATTRIBUTE_LAST; i++)
      {
      if((vidoptions->gl_attributes[i].mutated) && (bg_attributes[i] >= 0))
        {
        bg_x11_window_set_gl_attribute(win, bg_attributes[i],
                                       vidoptions->gl_attributes[i].value);
        }
      }
    /* Set bogus dimensions, will be corrected by the size_callback */
    bg_x11_window_set_size(win, 640, 480);
    
    bg_x11_window_realize(win);
    if(!bg_x11_window_start_gl(win))
      {
      ret->flags |=  BG_PLUGIN_UNSUPPORTED;
      }
    else
      bg_x11_window_set_gl(win);
    }
  else
    {
    ret->flags |=  BG_PLUGIN_VISUALIZE_FRAME;
    win = NULL;
    }
  ret->priority = 1;

  /* Must realize the actor to get the parameters */

  if(!(ret->flags & BG_PLUGIN_UNSUPPORTED))
    {
    visual_actor_realize(actor);
    ret->parameters =
      create_parameters(actor, NULL, NULL);
    visual_object_unref(VISUAL_OBJECT(actor));
    }
  
  
  if(win)
    {
    bg_x11_window_unset_gl(win);
    bg_x11_window_stop_gl(win);
    bg_x11_window_destroy(win);
    }
  
  return ret;
  }