示例#1
0
static void
gst_wildmidi_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstWildmidi *wildmidi;

  g_return_if_fail (GST_IS_WILDMIDI (object));

  wildmidi = GST_WILDMIDI (object);

  switch (prop_id) {
    case PROP_LINEAR_VOLUME:
      GST_OBJECT_LOCK (object);
      g_value_set_boolean (value, wildmidi->linear_volume);
      GST_OBJECT_UNLOCK (object);
      break;
    case PROP_HIGH_QUALITY:
      GST_OBJECT_LOCK (object);
      g_value_set_boolean (value, wildmidi->high_quality);
      GST_OBJECT_UNLOCK (object);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}
示例#2
0
static void
gst_wildmidi_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstWildmidi *wildmidi;

  g_return_if_fail (GST_IS_WILDMIDI (object));

  wildmidi = GST_WILDMIDI (object);

  switch (prop_id) {
    case ARG_LINEAR_VOLUME:
      GST_OBJECT_LOCK (object);
      wildmidi->linear_volume = g_value_get_boolean (value);
      if (wildmidi->song)
        WildMidi_SetOption (wildmidi->song, WM_MO_LINEAR_VOLUME,
            wildmidi->linear_volume);
      GST_OBJECT_UNLOCK (object);
      break;
    case ARG_HIGH_QUALITY:
      GST_OBJECT_LOCK (object);
      wildmidi->high_quality = g_value_get_boolean (value);
      if (wildmidi->song)
        WildMidi_SetOption (wildmidi->song, WM_MO_EXPENSIVE_INTERPOLATION,
            wildmidi->high_quality);
      GST_OBJECT_UNLOCK (object);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}
示例#3
0
static gboolean
gst_wildmidi_src_query (GstPad * pad, GstQuery * query)
{
  gboolean res = TRUE;
  GstWildmidi *wildmidi = GST_WILDMIDI (gst_pad_get_parent (pad));
  GstFormat src_format, dst_format;
  gint64 src_value, dst_value;

  if (!wildmidi->song) {
    gst_object_unref (wildmidi);
    return FALSE;
  }

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_DURATION:
      gst_query_set_duration (query, GST_FORMAT_TIME,
          gst_util_uint64_scale_int (wildmidi->o_len, GST_SECOND,
              WILDMIDI_RATE));
      break;
    case GST_QUERY_POSITION:
      gst_query_set_position (query, GST_FORMAT_TIME,
          gst_util_uint64_scale_int (wildmidi->o_segment->last_stop, GST_SECOND,
              WILDMIDI_RATE));
      break;
    case GST_QUERY_CONVERT:
      gst_query_parse_convert (query, &src_format, &src_value,
          &dst_format, NULL);

      res =
          gst_wildmidi_src_convert (wildmidi, src_format, src_value,
          &dst_format, &dst_value);
      if (res)
        gst_query_set_convert (query, src_format, src_value, dst_format,
            dst_value);

      break;
    case GST_QUERY_FORMATS:
      gst_query_set_formats (query, 3,
          GST_FORMAT_TIME, GST_FORMAT_BYTES, GST_FORMAT_DEFAULT);
      break;
    case GST_QUERY_SEGMENT:
      gst_query_set_segment (query, wildmidi->o_segment->rate,
          wildmidi->o_segment->format, wildmidi->o_segment->start,
          wildmidi->o_segment->stop);
      break;
    case GST_QUERY_SEEKING:
      gst_query_set_seeking (query, wildmidi->o_segment->format,
          TRUE, 0, wildmidi->o_len);
      break;
    default:
      res = FALSE;
      break;
  }

  gst_object_unref (wildmidi);
  return res;
}
示例#4
0
static void
gst_wildmidi_finalize (GObject * object)
{
  GstWildmidi *wildmidi;

  wildmidi = GST_WILDMIDI (object);

  g_object_unref (wildmidi->adapter);

  G_OBJECT_CLASS (parent_class)->finalize (object);
}
示例#5
0
static GstFlowReturn
gst_wildmidi_chain (GstPad * sinkpad, GstObject * parent, GstBuffer * buffer)
{
  GstWildmidi *wildmidi;

  wildmidi = GST_WILDMIDI (parent);

  /* push stuff in the adapter, we will start doing something in the sink event
   * handler when we get EOS */
  gst_adapter_push (wildmidi->adapter, buffer);

  return GST_FLOW_OK;
}
示例#6
0
static gboolean
gst_wildmidi_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  gboolean res = FALSE;
  GstWildmidi *wildmidi = GST_WILDMIDI (parent);

  GST_DEBUG_OBJECT (pad, "%s event received", GST_EVENT_TYPE_NAME (event));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEEK:
      res = gst_wildmidi_do_seek (wildmidi, event);
      break;
    default:
      break;
  }
  gst_event_unref (event);

  return res;
}
示例#7
0
static GstStateChangeReturn
gst_wildmidi_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
  GstWildmidi *wildmidi = GST_WILDMIDI (element);

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      wildmidi->offset = 0;
      wildmidi->state = GST_WILDMIDI_STATE_LOAD;
      wildmidi->discont = FALSE;
      break;
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
      break;
    default:
      break;
  }

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);

  switch (transition) {
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      GST_OBJECT_LOCK (wildmidi);
      if (wildmidi->song)
        WildMidi_Close (wildmidi->song);
      wildmidi->song = NULL;
      GST_OBJECT_UNLOCK (wildmidi);
      gst_adapter_clear (wildmidi->adapter);
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      break;
    default:
      break;
  }

  return ret;
}
示例#8
0
static gboolean
gst_wildmidi_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  gboolean res;
  GstWildmidi *wildmidi = GST_WILDMIDI (parent);

  GST_DEBUG_OBJECT (pad, "%s event received", GST_EVENT_TYPE_NAME (event));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_EOS:
      wildmidi->state = GST_WILDMIDI_STATE_PARSE;
      /* now start the parsing task */
      res = gst_pad_start_task (wildmidi->sinkpad,
          (GstTaskFunction) gst_wildmidi_loop, wildmidi->sinkpad, NULL);
      /* don't forward the event */
      gst_event_unref (event);
      break;
    default:
      res = gst_pad_event_default (pad, parent, event);
      break;
  }
  return res;
}
示例#9
0
static void
gst_wildmidi_loop (GstPad * sinkpad)
{
  GstWildmidi *wildmidi = GST_WILDMIDI (GST_PAD_PARENT (sinkpad));
  GstFlowReturn ret;

  switch (wildmidi->state) {
    case GST_WILDMIDI_STATE_LOAD:
    {
      GstBuffer *buffer = NULL;

      GST_DEBUG_OBJECT (wildmidi, "loading song");

      ret =
          gst_pad_pull_range (wildmidi->sinkpad, wildmidi->offset, -1, &buffer);

      if (ret == GST_FLOW_EOS) {
        GST_DEBUG_OBJECT (wildmidi, "Song loaded");
        wildmidi->state = GST_WILDMIDI_STATE_PARSE;
      } else if (ret != GST_FLOW_OK) {
        GST_ELEMENT_ERROR (wildmidi, STREAM, DECODE, (NULL),
            ("Unable to read song"));
        goto pause;
      } else {
        GST_DEBUG_OBJECT (wildmidi, "pushing buffer");
        gst_adapter_push (wildmidi->adapter, buffer);
        wildmidi->offset += gst_buffer_get_size (buffer);
      }
      break;
    }
    case GST_WILDMIDI_STATE_PARSE:
      ret = gst_wildmidi_parse_song (wildmidi);
      if (ret != GST_FLOW_OK)
        goto pause;
      wildmidi->state = GST_WILDMIDI_STATE_PLAY;
      break;
    case GST_WILDMIDI_STATE_PLAY:
      ret = gst_wildmidi_do_play (wildmidi);
      if (ret != GST_FLOW_OK)
        goto pause;
      break;
    default:
      break;
  }
  return;

pause:
  {
    const gchar *reason = gst_flow_get_name (ret);
    GstEvent *event;

    GST_DEBUG_OBJECT (wildmidi, "pausing task, reason %s", reason);
    gst_pad_pause_task (sinkpad);
    if (ret == GST_FLOW_EOS) {
      /* perform EOS logic */
      event = gst_event_new_eos ();
      gst_pad_push_event (wildmidi->srcpad, event);
    } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
      event = gst_event_new_eos ();
      /* for fatal errors we post an error message, post the error
       * first so the app knows about the error first. */
      GST_ELEMENT_ERROR (wildmidi, STREAM, FAILED,
          ("Internal data flow error."),
          ("streaming task paused, reason %s (%d)", reason, ret));
      gst_pad_push_event (wildmidi->srcpad, event);
    }
  }
}
示例#10
0
static gboolean
gst_wildmidi_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
  gboolean res = TRUE;
  GstWildmidi *wildmidi = GST_WILDMIDI (parent);
  GstFormat src_format, dst_format;
  gint64 src_value, dst_value;

  if (!wildmidi->song)
    return FALSE;

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_DURATION:
      gst_query_set_duration (query, GST_FORMAT_TIME,
          gst_util_uint64_scale_int (wildmidi->o_len, GST_SECOND,
              WILDMIDI_RATE));
      break;
    case GST_QUERY_POSITION:
      gst_query_set_position (query, GST_FORMAT_TIME,
          gst_util_uint64_scale_int (wildmidi->o_segment->position, GST_SECOND,
              WILDMIDI_RATE));
      break;
    case GST_QUERY_CONVERT:
      gst_query_parse_convert (query, &src_format, &src_value,
          &dst_format, NULL);

      res =
          gst_wildmidi_src_convert (wildmidi, src_format, src_value,
          &dst_format, &dst_value);
      if (res)
        gst_query_set_convert (query, src_format, src_value, dst_format,
            dst_value);

      break;
    case GST_QUERY_FORMATS:
      gst_query_set_formats (query, 3,
          GST_FORMAT_TIME, GST_FORMAT_BYTES, GST_FORMAT_DEFAULT);
      break;
    case GST_QUERY_SEGMENT:{
      GstFormat format;
      gint64 start, stop;

      format = wildmidi->o_segment->format;

      start =
          gst_segment_to_stream_time (wildmidi->o_segment, format,
          wildmidi->o_segment->start);
      if ((stop = wildmidi->o_segment->stop) == -1)
        stop = wildmidi->o_segment->duration;
      else
        stop = gst_segment_to_stream_time (wildmidi->o_segment, format, stop);

      gst_query_set_segment (query, wildmidi->o_segment->rate, format, start,
          stop);
      res = TRUE;
      break;
    }
    case GST_QUERY_SEEKING:
      gst_query_set_seeking (query, wildmidi->o_segment->format,
          TRUE, 0, wildmidi->o_len);
      break;
    default:
      res = gst_pad_query_default (pad, parent, query);
      break;
  }

  return res;
}