P_INVOKE gboolean
bp_can_seek (BansheePlayer *player)
{
    GstQuery *query;
    gboolean can_seek = TRUE;
    
    g_return_val_if_fail (IS_BANSHEE_PLAYER (player), FALSE);
    
    if (player->playbin == NULL) {
        return FALSE;
    }
    
    query = gst_query_new_seeking (GST_FORMAT_TIME);
    if (!gst_element_query (player->playbin, query)) {
        // This will probably fail, 100% of the time, because it's apparently 
        // very unimplemented in GStreamer... when it's fixed
        // we will return FALSE here, and show the warning
        // g_warning ("Could not query pipeline for seek ability");
        return bp_get_duration (player) > 0;
    }
    
    gst_query_parse_seeking (query, NULL, &can_seek, NULL, NULL);
    gst_query_unref (query);
    
    return can_seek && bp_get_duration (player) > 0;
}
示例#2
0
static gboolean
play_do_seek (GstElement * pipeline, gint64 pos, gdouble rate,
    GstPlayTrickMode mode)
{
  GstSeekFlags seek_flags;
  GstQuery *query;
  GstEvent *seek;
  gboolean seekable = FALSE;

  query = gst_query_new_seeking (GST_FORMAT_TIME);
  if (!gst_element_query (pipeline, query)) {
    gst_query_unref (query);
    return FALSE;
  }

  gst_query_parse_seeking (query, NULL, &seekable, NULL, NULL);
  gst_query_unref (query);

  if (!seekable)
    return FALSE;

  seek_flags = GST_SEEK_FLAG_FLUSH;

  switch (mode) {
    case GST_PLAY_TRICK_MODE_DEFAULT:
      seek_flags |= GST_SEEK_FLAG_TRICKMODE;
      break;
    case GST_PLAY_TRICK_MODE_DEFAULT_NO_AUDIO:
      seek_flags |= GST_SEEK_FLAG_TRICKMODE | GST_SEEK_FLAG_TRICKMODE_NO_AUDIO;
      break;
    case GST_PLAY_TRICK_MODE_KEY_UNITS:
      seek_flags |= GST_SEEK_FLAG_TRICKMODE_KEY_UNITS;
      break;
    case GST_PLAY_TRICK_MODE_KEY_UNITS_NO_AUDIO:
      seek_flags |=
          GST_SEEK_FLAG_TRICKMODE_KEY_UNITS | GST_SEEK_FLAG_TRICKMODE_NO_AUDIO;
      break;
    case GST_PLAY_TRICK_MODE_NONE:
    default:
      break;
  }

  if (rate >= 0)
    seek = gst_event_new_seek (rate, GST_FORMAT_TIME,
        seek_flags | GST_SEEK_FLAG_ACCURATE,
        /* start */ GST_SEEK_TYPE_SET, pos,
        /* stop */ GST_SEEK_TYPE_SET, GST_CLOCK_TIME_NONE);
  else
    seek = gst_event_new_seek (rate, GST_FORMAT_TIME,
        seek_flags | GST_SEEK_FLAG_ACCURATE,
        /* start */ GST_SEEK_TYPE_SET, 0,
        /* stop */ GST_SEEK_TYPE_SET, pos);

  if (!gst_element_send_event (pipeline, seek))
    return FALSE;

  cur_rate = rate;
  trick_mode = mode;
  return TRUE;
}
static void handle_message (CustomData *data, GstMessage *msg) {
  GError *err;
  gchar *debug_info;
  
  switch (GST_MESSAGE_TYPE (msg)) {
    case GST_MESSAGE_ERROR:
      gst_message_parse_error (msg, &err, &debug_info);
      g_printerr ("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message);
      g_printerr ("Debugging information: %s\n", debug_info ? debug_info : "none");
      g_clear_error (&err);
      g_free (debug_info);
      data->terminate = TRUE;
      break;
    case GST_MESSAGE_EOS:
      g_print ("End-Of-Stream reached.\n");
      data->terminate = TRUE;
      break;
    case GST_MESSAGE_DURATION:
      /* The duration has changed, mark the current one as invalid */
      data->duration = GST_CLOCK_TIME_NONE;
      break;
    case GST_MESSAGE_STATE_CHANGED: {
      GstState old_state, new_state, pending_state;
      gst_message_parse_state_changed (msg, &old_state, &new_state, &pending_state);
      if (GST_MESSAGE_SRC (msg) == GST_OBJECT (data->playbin2)) {
        g_print ("Pipeline state changed from %s to %s:\n",
            gst_element_state_get_name (old_state), gst_element_state_get_name (new_state));
        
        /* Remember whether we are in the PLAYING state or not */
        data->playing = (new_state == GST_STATE_PLAYING);
        
        if (data->playing) {
          /* We just moved to PLAYING. Check if seeking is possible */
          GstQuery *query;
          gint64 start, end;
          query = gst_query_new_seeking (GST_FORMAT_TIME);
          if (gst_element_query (data->playbin2, query)) {
            gst_query_parse_seeking (query, NULL, &data->seek_enabled, &start, &end);
            if (data->seek_enabled) {
              g_print ("Seeking is ENABLED from %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT "\n",
                  GST_TIME_ARGS (start), GST_TIME_ARGS (end));
            } else {
              g_print ("Seeking is DISABLED for this stream.\n");
            }
          }
          else {
            g_printerr ("Seeking query failed.");
          }
          gst_query_unref (query);
        }
      }
    } break;
    default:
      /* We should not reach here */
      g_printerr ("Unexpected message received.\n");
      break;
  }
  gst_message_unref (msg);
}
示例#4
0
/* generate queries to adaptive demux */
static gboolean
testQueryCheckDataReceived (GstAdaptiveDemuxTestEngine * engine,
    GstAdaptiveDemuxTestOutputStream * stream,
    GstBuffer * buffer, gpointer user_data)
{
  GList *pads;
  GstPad *pad;
  GstQuery *query;
  gboolean ret;
  gint64 duration;
  gboolean seekable;
  gint64 segment_start;
  gint64 segment_end;
  gchar *uri;
  gchar *redirect_uri;
  gboolean redirect_permanent;

  pads = GST_ELEMENT_PADS (stream->appsink);

  /* AppSink should have only 1 pad */
  fail_unless (pads != NULL);
  fail_unless (g_list_length (pads) == 1);
  pad = GST_PAD (pads->data);

  query = gst_query_new_duration (GST_FORMAT_TIME);
  ret = gst_pad_peer_query (pad, query);
  fail_unless (ret == TRUE);
  gst_query_parse_duration (query, NULL, &duration);
  fail_unless (duration == 135743 * GST_MSECOND);
  gst_query_unref (query);

  query = gst_query_new_seeking (GST_FORMAT_TIME);
  ret = gst_pad_peer_query (pad, query);
  fail_unless (ret == TRUE);
  gst_query_parse_seeking (query, NULL, &seekable, &segment_start,
      &segment_end);
  fail_unless (seekable == TRUE);
  fail_unless (segment_start == 0);
  fail_unless (segment_end == duration);
  gst_query_unref (query);

  query = gst_query_new_uri ();
  ret = gst_pad_peer_query (pad, query);
  fail_unless (ret == TRUE);
  gst_query_parse_uri (query, &uri);
  gst_query_parse_uri_redirection (query, &redirect_uri);
  gst_query_parse_uri_redirection_permanent (query, &redirect_permanent);
  fail_unless (strcmp (uri, "http://unit.test/test.mpd") == 0);
  /* adaptive demux does not reply with redirect information */
  fail_unless (redirect_uri == NULL);
  fail_unless (redirect_permanent == FALSE);
  g_free (uri);
  g_free (redirect_uri);
  gst_query_unref (query);

  return gst_adaptive_demux_test_check_received_data (engine,
      stream, buffer, user_data);
}
示例#5
0
static VALUE
seeking_initialize(VALUE self, VALUE format)
{
    GstQuery *query;

    query = gst_query_new_seeking(RVAL2GST_FORMAT(format));

    G_INITIALIZE(self, query);
    return Qnil;
}
static void
gst_discoverer_init (GstDiscoverer * dc)
{
  GstElement *tmp;
  GstFormat format = GST_FORMAT_TIME;

  dc->priv = G_TYPE_INSTANCE_GET_PRIVATE (dc, GST_TYPE_DISCOVERER,
      GstDiscovererPrivate);

  dc->priv->timeout = DEFAULT_PROP_TIMEOUT;
  dc->priv->async = FALSE;

  dc->priv->lock = g_mutex_new ();

  GST_LOG ("Creating pipeline");
  dc->priv->pipeline = (GstBin *) gst_pipeline_new ("Discoverer");
  GST_LOG_OBJECT (dc, "Creating uridecodebin");
  dc->priv->uridecodebin =
      gst_element_factory_make ("uridecodebin", "discoverer-uri");
  if (G_UNLIKELY (dc->priv->uridecodebin == NULL)) {
    GST_ERROR ("Can't create uridecodebin");
    return;
  }
  GST_LOG_OBJECT (dc, "Adding uridecodebin to pipeline");
  gst_bin_add (dc->priv->pipeline, dc->priv->uridecodebin);

  dc->priv->pad_added_id =
      g_signal_connect_object (dc->priv->uridecodebin, "pad-added",
      G_CALLBACK (uridecodebin_pad_added_cb), dc, 0);
  dc->priv->pad_remove_id =
      g_signal_connect_object (dc->priv->uridecodebin, "pad-removed",
      G_CALLBACK (uridecodebin_pad_removed_cb), dc, 0);

  GST_LOG_OBJECT (dc, "Getting pipeline bus");
  dc->priv->bus = gst_pipeline_get_bus ((GstPipeline *) dc->priv->pipeline);

  dc->priv->bus_cb_id =
      g_signal_connect_object (dc->priv->bus, "message",
      G_CALLBACK (discoverer_bus_cb), dc, 0);

  GST_DEBUG_OBJECT (dc, "Done initializing Discoverer");

  /* This is ugly. We get the GType of decodebin2 so we can quickly detect
   * when a decodebin2 is added to uridecodebin so we can set the
   * post-stream-topology setting to TRUE */
  dc->priv->element_added_id =
      g_signal_connect_object (dc->priv->uridecodebin, "element-added",
      G_CALLBACK (uridecodebin_element_added_cb), dc, 0);
  tmp = gst_element_factory_make ("decodebin2", NULL);
  dc->priv->decodebin2_type = G_OBJECT_TYPE (tmp);
  gst_object_unref (tmp);

  /* create queries */
  dc->priv->seeking_query = gst_query_new_seeking (format);
}
示例#7
0
void test_nonseeking()
{
  GstElement *src;
  GstQuery *seeking_query;
  gint pipe_fd[2];
  gchar data[4096];
  gboolean seekable;

  xmlfile = "fdsrc_test_nonseeking";
  std_log(LOG_FILENAME_LINE, "Test Started test_nonseeking");


  fail_if (pipe (pipe_fd) < 0);

  src = setup_fdsrc ();
  g_object_set (G_OBJECT (src), "num-buffers", 3, NULL);
  g_object_set (G_OBJECT (src), "fd", pipe_fd[0], NULL);
  fail_unless (gst_element_set_state (src,
          GST_STATE_PAUSED) == GST_STATE_CHANGE_SUCCESS,
      "could not set to paused");
        


  memset (data, 0, 4096);
  
  fail_if (write (pipe_fd[1], data, 256) < 0);

  /* Test that fdsrc is non-seekable with a pipe */
  fail_unless ((seeking_query = gst_query_new_seeking (GST_FORMAT_BYTES))
      != NULL);
        

  fail_unless (gst_element_query (src, seeking_query) == TRUE);
  

  gst_query_parse_seeking (seeking_query, NULL, &seekable, NULL, NULL);
  fail_unless (seekable == FALSE);
  

  gst_query_unref (seeking_query);

  fail_unless (gst_element_set_state (src,
          GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
  

  /* cleanup */
  cleanup_fdsrc (src);
  close (pipe_fd[0]);
  close (pipe_fd[1]);
  std_log(LOG_FILENAME_LINE, "Test Successful");
  create_xml(0);


}
示例#8
0
void test_seeking()
{
  GstElement *src;
  gint in_fd;
  GstQuery *seeking_query;
  gboolean seekable;

  xmlfile = "fdsrc_test_seeking";
  std_log(LOG_FILENAME_LINE, "Test Started test_seeking");


#ifndef TESTFILE
#error TESTFILE not defined
#endif

in_fd = errno ;
  fail_if ((in_fd = open ("c:\\data\\gstreamer\\warning.wav", O_RDONLY)) < 0);
    

  src = setup_fdsrc ();

  g_object_set (G_OBJECT (src), "fd", in_fd, NULL);
  fail_unless (gst_element_set_state (src,
          GST_STATE_PAUSED) == GST_STATE_CHANGE_SUCCESS,
      "could not set to paused");
  

  /* Test that fdsrc is seekable with a file fd */
  fail_unless ((seeking_query = gst_query_new_seeking (GST_FORMAT_BYTES))
      != NULL);
  

  fail_unless (gst_element_query (src, seeking_query) == TRUE);
  

  gst_query_parse_seeking (seeking_query, NULL, &seekable, NULL, NULL);
  fail_unless (seekable == TRUE);
  

  gst_query_unref (seeking_query);

  fail_unless (gst_element_set_state (src,
          GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
  

  /* cleanup */
  cleanup_fdsrc (src);
  close (in_fd);
  std_log(LOG_FILENAME_LINE, "Test Successful");
  create_xml(0);

  
}
示例#9
0
static void
pragha_backend_evaluate_if_can_seek(PraghaBackend *backend)
{
	GstQuery *query;

	PraghaBackendPrivate *priv = backend->priv;

	query = gst_query_new_seeking (GST_FORMAT_TIME);
	if (gst_element_query (priv->pipeline, query))
		gst_query_parse_seeking (query, NULL, &priv->can_seek, NULL, NULL);
	gst_query_unref (query);
}
示例#10
0
	bool SourceObject::IsSeekable () const
	{
		std::shared_ptr<GstQuery> query (gst_query_new_seeking (GST_FORMAT_TIME), gst_query_unref);

		if (!gst_element_query (GST_ELEMENT (Dec_), query.get ()))
			return false;

		gboolean seekable = false;
		GstFormat format;
		gint64 start = 0, stop = 0;
		gst_query_parse_seeking (query.get (), &format, &seekable, &start, &stop);
		return seekable;
	}
示例#11
0
static gboolean
event_forward_func (GstPad * pad, EventData * evdata)
{
  gboolean ret = TRUE;
  GstPad *peer = gst_pad_get_peer (pad);
  GstAggregatorPadPrivate *padpriv = GST_AGGREGATOR_PAD (pad)->priv;

  if (peer) {
    ret = gst_pad_send_event (peer, gst_event_ref (evdata->event));
    GST_DEBUG_OBJECT (pad, "return of event push is %d", ret);
    gst_object_unref (peer);
  }

  if (ret == FALSE) {
    if (GST_EVENT_TYPE (evdata->event) == GST_EVENT_SEEK)
      GST_ERROR_OBJECT (pad, "Event %" GST_PTR_FORMAT " failed", evdata->event);

    if (GST_EVENT_TYPE (evdata->event) == GST_EVENT_SEEK) {
      GstQuery *seeking = gst_query_new_seeking (GST_FORMAT_TIME);

      if (gst_pad_query (peer, seeking)) {
        gboolean seekable;

        gst_query_parse_seeking (seeking, NULL, &seekable, NULL, NULL);

        if (seekable == FALSE) {
          GST_INFO_OBJECT (pad,
              "Source not seekable, We failed but it does not matter!");

          ret = TRUE;
        }
      } else {
        GST_ERROR_OBJECT (pad, "Query seeking FAILED");
      }
    }

    if (evdata->flush) {
      padpriv->pending_flush_start = FALSE;
      padpriv->pending_flush_stop = FALSE;
    }
  } else {
    evdata->one_actually_seeked = TRUE;
  }

  evdata->result &= ret;

  /* Always send to all pads */
  return FALSE;
}
static void
relative_seek (GstPlay * play, gdouble percent)
{
  GstQuery *query;
  gboolean seekable = FALSE;
  gint64 dur = -1, pos = -1, step;

  g_return_if_fail (percent >= -1.0 && percent <= 1.0);

  if (!gst_element_query_position (play->playbin, GST_FORMAT_TIME, &pos))
    goto seek_failed;

  query = gst_query_new_seeking (GST_FORMAT_TIME);
  if (!gst_element_query (play->playbin, query)) {
    gst_query_unref (query);
    goto seek_failed;
  }

  gst_query_parse_seeking (query, NULL, &seekable, NULL, &dur);
  gst_query_unref (query);

  if (!seekable || dur <= 0)
    goto seek_failed;

  step = dur * percent;
  if (ABS (step) < GST_SECOND)
    step = (percent < 0) ? -GST_SECOND : GST_SECOND;

  pos = pos + step;
  if (pos > dur) {
    if (!play_next (play)) {
      g_print ("\n%s\n", _("Reached end of play list."));
      g_main_loop_quit (play->loop);
    }
  } else {
    if (pos < 0)
      pos = 0;

    play_do_seek (play, pos, play->rate, play->trick_mode);
  }

  return;

seek_failed:
  {
    g_print ("\nCould not seek.\n");
  }
}
示例#13
0
static void
relative_seek (GstPlay * play, gdouble percent)
{
  GstQuery *query;
  gboolean seekable = FALSE;
  gint64 dur = -1, pos = -1;

  g_return_if_fail (percent >= -1.0 && percent <= 1.0);

  if (!gst_element_query_position (play->playbin, GST_FORMAT_TIME, &pos))
    goto seek_failed;

  query = gst_query_new_seeking (GST_FORMAT_TIME);
  if (!gst_element_query (play->playbin, query)) {
    gst_query_unref (query);
    goto seek_failed;
  }

  gst_query_parse_seeking (query, NULL, &seekable, NULL, &dur);
  gst_query_unref (query);

  if (!seekable || dur <= 0)
    goto seek_failed;

  pos = pos + dur * percent;
  if (pos > dur) {
    if (!play_next (play)) {
      g_print ("\nReached end of play list.\n");
      g_main_loop_quit (play->loop);
    }
  } else {
    if (pos < 0)
      pos = 0;
    if (!gst_element_seek_simple (play->playbin, GST_FORMAT_TIME,
            GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT, pos))
      goto seek_failed;
  }

  return;

seek_failed:
  {
    g_print ("\nCould not seek.\n");
  }
}
示例#14
0
bool GstVideoPlayerBackend::isSeekable() const
{
    if (!m_pipeline)
        return false;

    GstQuery *query = gst_query_new_seeking(GST_FORMAT_TIME);
    gboolean re = gst_element_query(m_pipeline, query);
    if (re)
    {
        gboolean seekable;
        gst_query_parse_seeking(query, 0, &seekable, 0, 0);
        re = seekable;
    }
    else
        qDebug() << "gstreamer: Failed to query seeking properties of the stream";

    gst_query_unref(query);
    return re;
}
示例#15
0
static gboolean
impl_seekable (RBPlayer *player)
{
	RBPlayerGst *mp = RB_PLAYER_GST (player);
	gboolean can_seek = TRUE;
	GstQuery *query;

	if (mp->priv->playbin == NULL)
		return FALSE;

	query = gst_query_new_seeking (GST_FORMAT_TIME);
	if (gst_element_query (mp->priv->playbin, query)) {
		gst_query_parse_seeking (query, NULL, &can_seek, NULL, NULL);
	} else {
		gst_query_unref (query);

		query = gst_query_new_duration (GST_FORMAT_TIME);
		can_seek = gst_element_query (mp->priv->playbin, query);
	}
	gst_query_unref (query);

	return can_seek;
}
示例#16
0
// A C-style callback used to receive messages from GStreamer:
static gboolean linGstBusCallback(
  GstBus *bus,
  GstMessage *msg,
  gpointer linGstObjectPtr)
{
  Q_UNUSED(bus);

  switch (GST_MESSAGE_TYPE(msg))
  {
  case GST_MESSAGE_TAG:
    {
      GstTagList *tags = NULL;

      gst_message_parse_tag(msg, &tags);

      gst_tag_list_foreach(tags, linHandleTag, linGstObjectPtr);

      if (tags) gst_tag_list_free(tags);
    }
    break;

  case GST_MESSAGE_STATE_CHANGED:
    // The stream has entered a new state; perform any necessary cleanup:
    {
      LinVideoDisplayForm *myForm =
        static_cast<LinVideoDisplayForm *>(linGstObjectPtr);

      // Check to see if the stream allows seeking:
      if ( myForm->seekingUnknown()
        && myForm->gstObjectMatches(GST_MESSAGE_SRC(msg)))
      {
        GstState oldState, newState, pendingState;

        gst_message_parse_state_changed(
          msg, &oldState, &newState, &pendingState);

        if (newState == GST_STATE_PLAYING)
        {
          // First, initialize the data dialog:
          myForm->setupDataDialog();

          // Now, check for seeking:
          gboolean seekEnabled;
          gint64 start, end;
          GstQuery *query;
          query = gst_query_new_seeking(GST_FORMAT_TIME);
          if (myForm->gstElementQuery(query))
          {
            gst_query_parse_seeking(query, NULL, &seekEnabled, &start, &end);

/*
            if (seekEnabled)
            {
              qDebug() << "Seek from " << start << " to " << end;
            }
*/

            myForm->setSeeking(seekEnabled == true);
          }

          gst_query_unref(query);
        }
      }
    }
    break;

  case GST_MESSAGE_BUFFERING:
    {
      LinVideoDisplayForm *myForm =
        static_cast<LinVideoDisplayForm *>(linGstObjectPtr);

      gint percent = 0;
      gst_message_parse_buffering (msg, &percent);
//qDebug() << "Buffering percentage at " << percent;
      if (percent < 100)
      {
        myForm->waitForBuffer();
      }
      else
      {
        myForm->finishedBuffer();
      }
    }
    break;

  case GST_MESSAGE_EOS:
    {
      LinVideoDisplayForm *myForm =
        static_cast<LinVideoDisplayForm *>(linGstObjectPtr);

      myForm->stopPlaying();
    }
    break;

  case GST_MESSAGE_ERROR:
    {
      gchar *debug;
      GError *err;

      gst_message_parse_error(msg, &err, &debug);
      QString errString = "[";
      errString += GST_OBJECT_NAME(msg->src);
      errString += "]: ";
      errString += err->message;
      errString += " ";
      errString += debug;
      // Display the error message!
qDebug() << errString;

      LinVideoDisplayForm *myForm =
        static_cast<LinVideoDisplayForm *>(linGstObjectPtr);

      myForm->stopPlaying();
      
      g_free (debug);
      g_error_free (err);
    }
    break;

  default:
    break;
  }

  return true;
}
示例#17
0
static void handle_message(CustomData *data, GstMessage *msg) {
  GError *err;
  gchar *debug_info;

  switch (GST_MESSAGE_TYPE(msg)) {
  case GST_MESSAGE_ERROR:
    gst_message_parse_error(msg, &err, &debug_info);
    g_printerr("Error received from element %s: %s\n",
	       GST_OBJECT_NAME(msg->src), err->message);
    g_printerr("Debugging information: %s\n", debug_info ? debug_info : "none");
    g_clear_error(&err);
    g_free(debug_info);
    data->terminate = TRUE;
    break;
  case GST_MESSAGE_EOS:
    g_print("\nEnd-Of-Stream reached.\n");
    data->terminate = TRUE;
    break;
  case GST_MESSAGE_DURATION_CHANGED:
    fprintf(stderr, "LaDurée a changé !! Ça m'énerve !!\n");
    data->duration = GST_CLOCK_TIME_NONE;
    break;
  case GST_MESSAGE_STATE_CHANGED: {
    GstState old_state, new_state, pending_state;

    if (GST_MESSAGE_SRC(msg) == GST_OBJECT(data->playbin)) {
      gst_message_parse_state_changed(msg,
				      &old_state, &new_state, &pending_state);
      g_print("Pipeline state changed from %s to %s:\n",
	      gst_element_state_get_name(old_state),
	      gst_element_state_get_name(new_state));

      data->playing = (new_state == GST_STATE_PLAYING);

      if (data->playing) {
	GstQuery *query;
	gint64 start, end;
	query = gst_query_new_seeking(GST_FORMAT_TIME);
	if (gst_element_query(data->playbin, query)) {
	  gst_query_parse_seeking(query, NULL,
				  &data->seek_enabled, &start, &end);
	  if (data->seek_enabled) {
	    g_print("Seeking is ENABLED from %" GST_TIME_FORMAT " to %"
		    GST_TIME_FORMAT "\n",
		    GST_TIME_ARGS(start), GST_TIME_ARGS(end));
	  } else {
	    g_print("Seeking is DISABLED for this stream.\n");
	  }
	}
	else {
	  g_printerr("Seeking query failed.");
	}
	gst_query_unref(query);
      }
    }
  } break;
  default:
    g_printerr("Unexpected message received.\n");
    break;
  }
  gst_message_unref(msg);
}
示例#18
0
void MediaImpl::_checkMessages()
{
    if (_bus != NULL)
    {
        // Get message.
        GstMessage *msg = gst_bus_timed_pop_filtered(
                              _bus, 0,
                              (GstMessageType) (GST_MESSAGE_STATE_CHANGED | GST_MESSAGE_ERROR | GST_MESSAGE_EOS | GST_MESSAGE_ASYNC_DONE));

        if (msg != NULL)
        {
            GError *err;
            gchar *debug_info;

            switch (GST_MESSAGE_TYPE (msg))
            {
            // Error ////////////////////////////////////////////////
            case GST_MESSAGE_ERROR:
                gst_message_parse_error(msg, &err, &debug_info);
                g_printerr("Error received from element %s: %s\n",
                           GST_OBJECT_NAME (msg->src), err->message);
                g_printerr("Debugging information: %s\n",
                           debug_info ? debug_info : "none");
                g_clear_error(&err);
                g_free(debug_info);

                if (!_isSharedMemorySource)
                {
                    _terminate = true;
                }
                else
                {
                    _attached = false;
                    gst_element_set_state (_pipeline, GST_STATE_PAUSED);
                    gst_element_set_state (_pipeline, GST_STATE_NULL);
                    gst_element_set_state (_pipeline, GST_STATE_READY);
                }
//        _finish();
                break;

            // End-of-stream ////////////////////////////////////////
            case GST_MESSAGE_EOS:
                // Automatically loop back.
                g_print("End-Of-Stream reached.\n");
                resetMovie();
//        _terminate = true;
//        _finish();
                break;

            // Pipeline has prerolled/ready to play ///////////////
            case GST_MESSAGE_ASYNC_DONE:
                if (!_isMovieReady())
                {
                    // Check if seeking is allowed.
                    gint64 start, end;
                    GstQuery *query = gst_query_new_seeking (GST_FORMAT_TIME);
                    if (gst_element_query (_pipeline, query))
                    {
                        gst_query_parse_seeking (query, NULL, (gboolean*)&_seekEnabled, &start, &end);
                        if (_seekEnabled)
                        {
                            g_print ("Seeking is ENABLED from %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT "\n",
                                     GST_TIME_ARGS (start), GST_TIME_ARGS (end));

                        }
                        else
                        {
                            g_print ("Seeking is DISABLED for this stream.\n");
                        }
                    }
                    else
                    {
                        g_printerr ("Seeking query failed.");
                    }

                    gst_query_unref (query);

                    // Movie is ready!
                    _setMovieReady(true);
                }

                break;

            case GST_MESSAGE_STATE_CHANGED:
                // We are only interested in state-changed messages from the pipeline.
                if (GST_MESSAGE_SRC (msg) == GST_OBJECT (_pipeline))
                {
                    GstState oldState, newState, pendingState;
                    gst_message_parse_state_changed(msg, &oldState, &newState,
                                                    &pendingState);
                    g_print("Pipeline state for movie %s changed from %s to %s:\n",
                            _uri.toUtf8().constData(),
                            gst_element_state_get_name(oldState),
                            gst_element_state_get_name(newState));
                }
                break;

            default:
                // We should not reach here.
                g_printerr("Unexpected message received.\n");
                break;
            }
            gst_message_unref(msg);
        }
    }
}
示例#19
0
SeekingQueryPtr SeekingQuery::create(Format format)
{
    return SeekingQueryPtr::wrap(gst_query_new_seeking(static_cast<GstFormat>(format)), false);
}
示例#20
0
void MediaImpl::_postRun()
{
  // Parse message.
  if (_bus != NULL)
  {
    GstMessage *msg = gst_bus_timed_pop_filtered(
                        _bus, 0,
                        (GstMessageType) (GST_MESSAGE_STATE_CHANGED | GST_MESSAGE_ERROR | GST_MESSAGE_EOS));

    if (msg != NULL) {
      GError *err;
      gchar *debug_info;

      switch (GST_MESSAGE_TYPE (msg)) {

      case GST_MESSAGE_ERROR:
        gst_message_parse_error(msg, &err, &debug_info);
        g_printerr("Error received from element %s: %s\n",
            GST_OBJECT_NAME (msg->src), err->message);
        g_printerr("Debugging information: %s\n",
            debug_info ? debug_info : "none");
        g_clear_error(&err);
        g_free(debug_info);

        _terminate = true;
//        _finish();
        break;

      case GST_MESSAGE_EOS:
        g_print("End-Of-Stream reached.\n");
//        _terminate = true;
//        _finish();
        break;

      case GST_MESSAGE_STATE_CHANGED:
        // We are only interested in state-changed messages from the pipeline.
        if (GST_MESSAGE_SRC (msg) == GST_OBJECT (_pipeline))
        {
          GstState oldState, newState, pendingState;
          gst_message_parse_state_changed(msg, &oldState, &newState,
              &pendingState);
          g_print("Pipeline state for movie %s changed from %s to %s:\n",
              _currentMovie.toUtf8().constData(),
              gst_element_state_get_name(oldState),
              gst_element_state_get_name(newState));

//          if (oldState == GST_STATE_PAUSED && newState == GST_STATE_READY)
//            gst_adapter_clear(_audioBufferAdapter);

          if (newState == GST_STATE_PLAYING)
          {
            // Check if seeking is allowed.
            gint64 start, end;
            GstQuery *query = gst_query_new_seeking (GST_FORMAT_TIME);
            if (gst_element_query (_pipeline, query))
            {
              gst_query_parse_seeking (query, NULL, (gboolean*)&_seekEnabled, &start, &end);
              if (_seekEnabled)
              {
                g_print ("Seeking is ENABLED from %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT "\n",
                         GST_TIME_ARGS (start), GST_TIME_ARGS (end));
              }
              else
              {
                g_print ("Seeking is DISABLED for this stream.\n");
              }
            }
            else
            {
              g_printerr ("Seeking query failed.");
            }

            gst_query_unref (query);
          }
        }
        break;

      default:
        // We should not reach here.
        g_printerr("Unexpected message received.\n");
        break;
      }
      gst_message_unref(msg);
    }
  }
}
示例#21
0
void VideoImpl::_checkMessages()
{
  if (_bus != NULL)
  {
    // Get message.
    GstMessage *msg = gst_bus_timed_pop_filtered(
                        _bus, 0,
                        (GstMessageType) (GST_MESSAGE_STATE_CHANGED | GST_MESSAGE_ERROR | GST_MESSAGE_EOS | GST_MESSAGE_ASYNC_DONE));

    if (msg != NULL)
    {
      GError *err;
      gchar *debug_info;

      switch (GST_MESSAGE_TYPE (msg))
      {
      // Error ////////////////////////////////////////////////
      case GST_MESSAGE_ERROR:
        gst_message_parse_error(msg, &err, &debug_info);
        qWarning() << "Error received from element " << GST_OBJECT_NAME (msg->src) << ": " << err->message << endl;
        qDebug() << "Debugging information: " << (debug_info ? debug_info : "none") << "." << endl;
        g_clear_error(&err);
        g_free(debug_info);

        if (!isLive())
        {
          _terminate = true;
        }
        else
        {
          gst_element_set_state (_pipeline, GST_STATE_PAUSED);
          gst_element_set_state (_pipeline, GST_STATE_NULL);
          gst_element_set_state (_pipeline, GST_STATE_READY);
        }
//        _finish();
        break;

      // End-of-stream ////////////////////////////////////////
      case GST_MESSAGE_EOS:
        // Automatically loop back.
        resetMovie();
//        _terminate = true;
//        _finish();
        break;

      // Pipeline has prerolled/ready to play ///////////////
      case GST_MESSAGE_ASYNC_DONE:
        if (!_isMovieReady())
        {
          // Check if seeking is allowed.
          gint64 start, end;
          GstQuery *query = gst_query_new_seeking (GST_FORMAT_TIME);
          if (gst_element_query (_pipeline, query))
          {
            gst_query_parse_seeking (query, NULL, (gboolean*)&_seekEnabled, &start, &end);
            if (_seekEnabled)
            {
#ifdef VIDEO_IMPL_VERBOSE
              qDebug() << "Seeking is ENABLED from " << start << " to " << end << "." << endl;
#endif
            }
            else
            {
              qDebug() << "Seeking is DISABLED for this stream." << endl;
            }
          }
          else
          {
            qWarning() << "Seeking query failed." << endl;
          }

          gst_query_unref (query);

          // Movie is ready!
#ifdef VIDEO_IMPL_VERBOSE
          qDebug() << "Preroll done: movie is ready." << endl;
#endif // ifdef
          _setMovieReady(true);
        }

        break;

      case GST_MESSAGE_STATE_CHANGED:
        // We are only interested in state-changed messages from the pipeline.
        if (GST_MESSAGE_SRC (msg) == GST_OBJECT (_pipeline))
        {
          GstState oldState, newState, pendingState;
          gst_message_parse_state_changed(msg, &oldState, &newState, &pendingState);
#ifdef VIDEO_IMPL_VERBOSE
          qDebug() << "Pipeline state for movie " << _uri
                   << " changed from " << gst_element_state_get_name(oldState)
                   << " to " << gst_element_state_get_name(newState) << endl;
#endif
        }
        break;

      default:
        // We should not reach here.
        qWarning() << "Unexpected message received." << endl;
        break;
      }
      gst_message_unref(msg);
    }
  }
}
static gboolean
gst_raw_parse_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
  GstRawParse *rp = GST_RAW_PARSE (parent);
  gboolean ret = FALSE;

  GST_DEBUG ("src_query %s", gst_query_type_get_name (GST_QUERY_TYPE (query)));

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_POSITION:
    {
      GstFormat format;
      gint64 time, value;

      GST_LOG ("query position");

      gst_query_parse_position (query, &format, NULL);

      time = rp->segment.position;
      ret = gst_raw_parse_convert (rp, GST_FORMAT_TIME, time, format, &value);

      gst_query_set_position (query, format, value);

      break;
    }
    case GST_QUERY_DURATION:{
      gint64 duration;
      GstFormat format;
      GstQuery *bquery;

      GST_LOG ("query duration");
      ret = gst_pad_peer_query (rp->sinkpad, query);
      if (ret)
        goto done;

      gst_query_parse_duration (query, &format, NULL);
      /* We only handle TIME and DEFAULT format */
      if (format != GST_FORMAT_TIME && format != GST_FORMAT_DEFAULT)
        goto error;

      bquery = gst_query_new_duration (GST_FORMAT_BYTES);
      ret = gst_pad_peer_query (rp->sinkpad, bquery);
      if (!ret) {
        gst_query_unref (bquery);
        goto error;
      }

      gst_query_parse_duration (bquery, NULL, &duration);
      gst_query_unref (bquery);

      ret =
          gst_raw_parse_convert (rp, GST_FORMAT_BYTES, duration, format,
          &duration);
      if (ret)
        gst_query_set_duration (query, format, duration);

      break;
    }
    case GST_QUERY_CONVERT:
    {
      GstFormat src_fmt, dest_fmt;
      gint64 src_val, dest_val;

      GST_LOG ("query convert");

      gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
      ret = gst_raw_parse_convert (rp, src_fmt, src_val, dest_fmt, &dest_val);
      if (!ret)
        goto error;
      gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
      break;
    }
    case GST_QUERY_SEEKING:{
      GstFormat fmt;

      ret = TRUE;
      gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
      if (fmt != GST_FORMAT_TIME && fmt != GST_FORMAT_DEFAULT
          && fmt != GST_FORMAT_BYTES) {
        gst_query_set_seeking (query, fmt, FALSE, -1, -1);
      } else if (rp->mode == GST_PAD_MODE_PUSH) {
        GstQuery *peerquery = gst_query_new_seeking (GST_FORMAT_BYTES);
        gboolean seekable;

        seekable = gst_pad_peer_query (rp->sinkpad, peerquery);
        if (seekable)
          gst_query_parse_seeking (peerquery, NULL, &seekable, NULL, NULL);

        gst_query_unref (peerquery);
        gst_query_set_seeking (query, fmt, seekable, seekable ? 0 : -1, -1);
      } else {
        gst_query_set_seeking (query, fmt, TRUE, 0, -1);
      }
      break;
    }
    default:
      /* else forward upstream */
      ret = gst_pad_query_default (rp->sinkpad, parent, query);
      break;
  }

done:
  return ret;

  /* ERRORS */
error:
  {
    GST_DEBUG_OBJECT (rp, "query failed");
    goto done;
  }
}
static gboolean
hls_test_bus_message (InsanityGstPipelineTest * ptest, GstMessage * msg)
{
  switch (GST_MESSAGE_TYPE (msg)) {
    case GST_MESSAGE_BUFFERING:
    {
      gint per;

      gst_message_parse_buffering (msg, &per);

      /* First buffering happend properly, this is requiered to be able to
       * start seeking */
      if (G_UNLIKELY (glob_buffered == FALSE)) {
        if (per == 100) {
          insanity_test_validate_checklist_item (INSANITY_TEST (ptest),
              "done-buffering", TRUE, NULL);
          glob_buffered = TRUE;

          if (glob_buffering_timeout != 0) {
            g_source_remove (glob_buffering_timeout);
            glob_buffering_timeout = 0;
          }
        } else {
          glob_buffering_timeout = g_timeout_add (250,
              (GSourceFunc) buffering_timeout, INSANITY_TEST (ptest));
        }
      }

      break;
    }
    case GST_MESSAGE_STATE_CHANGED:
      if (GST_MESSAGE_SRC (msg) == GST_OBJECT (glob_pipeline)) {
        const char *validate_checklist_item = glob_validate_on_playing;
        GstState oldstate, newstate, pending;

        gst_message_parse_state_changed (msg, &oldstate, &newstate, &pending);
        if (newstate == GST_STATE_PAUSED && oldstate == GST_STATE_READY) {
          GstIterator *it;
          GValue v = { 0, };
          gboolean queried;
          InsanityTest *test = INSANITY_TEST (ptest);
          GstQuery *query = gst_query_new_latency ();
          const gchar *step_message = "Could not query seeking\n";

          if ((queried = gst_element_query (glob_pipeline, query))) {
            gst_query_parse_latency (query, &glob_is_live, NULL, NULL);
            step_message = NULL;
          } else
            insanity_test_printf (test, "Could not query\n");

          insanity_gst_pipeline_test_set_live (ptest, glob_is_live);
          insanity_test_validate_checklist_item (test, "queried-live", queried,
              step_message);
          gst_query_unref (query);

          step_message = "Could not query seekable\n";
          query = gst_query_new_seeking (GST_FORMAT_TIME);
          if ((queried = gst_element_query (glob_pipeline, query))) {
            gst_query_parse_seeking (query, NULL, &glob_is_seekable, NULL,
                NULL);
            step_message = NULL;
          } else
            insanity_test_printf (test, "Could not query\n");

          insanity_test_validate_checklist_item (test, "queried-seekable",
              queried, step_message);
          gst_query_unref (query);

          /* Iterate over the bins to find a hlsdemux */
          it = gst_bin_iterate_recurse (GST_BIN (glob_pipeline));
          if (gst_iterator_find_custom (it, (GCompareFunc) find_hlsdemux, &v,
                  NULL)) {
            glob_hlsdemux = g_value_dup_object (&v);
          }
          g_value_unset (&v);
          gst_iterator_free (it);

          if (glob_hlsdemux != NULL) {
            insanity_test_validate_checklist_item (test, "protocol-is-hls",
                TRUE, "HLS protocol in use");

            gst_object_unref (glob_hlsdemux);
          } else {
            insanity_test_validate_checklist_item (test, "protocol-is-hls",
                FALSE, "HLS protocol in use");
            insanity_test_done (test);
          }

          /* Watch pipeline only if seekable */
          if (glob_is_seekable)
            watch_pipeline (ptest);

        } else if (newstate == GST_STATE_PLAYING
            && pending == GST_STATE_VOID_PENDING && validate_checklist_item) {
          glob_validate_on_playing = NULL;
          insanity_test_validate_checklist_item (INSANITY_TEST (ptest),
              validate_checklist_item, TRUE, NULL);
          /* let it run a couple seconds */
          glob_wait_time = hls_test_get_wait_time (INSANITY_TEST (ptest));
          glob_timer_id =
              g_timeout_add (250, (GSourceFunc) & wait_and_end_step,
              INSANITY_TEST (ptest));
        }
      }
      break;
    case GST_MESSAGE_EOS:
      return FALSE;
    default:
      break;
  }

  return TRUE;

}
static void
test_queries (InsanityTest * test)
{
  GstQuery *query = gst_query_new_seeking (GST_FORMAT_TIME);

  if (gst_element_query (glob_pipeline, query)) {
    GstFormat fmt;
    gboolean seekable, known_seekable;

    gst_query_parse_seeking (query, &fmt, &seekable, NULL, NULL);
    if (glob_media_desc_parser == NULL) {
      insanity_test_validate_checklist_item (test, "seekable-detection",
          TRUE, "No media-descriptor file, result not verified against it");

      glob_seekable = seekable;
    } else {
      known_seekable =
          media_descriptor_parser_get_seekable (glob_media_desc_parser);

      insanity_test_validate_checklist_item (test, "seekable-detection",
          known_seekable == seekable, NULL);
      glob_seekable = known_seekable;
    }
  } else {
    if (glob_media_desc_parser != NULL)
      glob_seekable =
          media_descriptor_parser_get_seekable (glob_media_desc_parser);

    LOG (test,
        "%s Does not handle seeking queries (seekable-detection \"SKIP\")",
        gst_element_factory_get_metadata (gst_element_get_factory
            (glob_demuxer), GST_ELEMENT_METADATA_LONGNAME));
  }

  gst_query_unref (query);
  query = gst_query_new_duration (GST_FORMAT_TIME);
  if (gst_element_query (glob_pipeline, query)) {
    GstFormat fmt;
    gchar *validate_msg = NULL;
    gint64 duration;

    if (glob_media_desc_parser == NULL) {
      gst_query_parse_duration (query, &fmt, &duration);
      validate_msg =
          g_strdup_printf ("Found duration %" GST_TIME_FORMAT
          " No media-descriptor file, result not verified against it",
          GST_TIME_ARGS (duration));
      insanity_test_validate_checklist_item (test, "duration-detection",
          TRUE, validate_msg);

      g_free (validate_msg);

      glob_duration = duration;
    } else {
      glob_duration =
          media_descriptor_parser_get_duration (glob_media_desc_parser);
      gst_query_parse_duration (query, &fmt, &duration);

      if (glob_duration != duration) {
        validate_msg =
            g_strdup_printf ("Found time %" GST_TIME_FORMAT "-> %"
            GST_TIME_FORMAT, GST_TIME_ARGS (duration),
            GST_TIME_ARGS (glob_duration));

        insanity_test_validate_checklist_item (test, "duration-detection",
            glob_duration == duration, validate_msg);

        g_free (validate_msg);
      } else {
        insanity_test_validate_checklist_item (test, "duration-detection",
            TRUE, NULL);
      }
    }

  } else {
    if (glob_media_desc_parser != NULL)
      glob_duration =
          media_descriptor_parser_get_seekable (glob_media_desc_parser);

    LOG (test, "%s Does not handle duration queries "
        "(duration-detection \"SKIP\")",
        gst_element_factory_get_metadata (gst_element_get_factory
            (glob_demuxer), GST_ELEMENT_METADATA_LONGNAME));
  }

  if (GST_CLOCK_TIME_IS_VALID (glob_duration) &&
      glob_playback_duration > glob_duration) {
    LOG (test, "playback_duration > media duration, setting it"
        "to media_duration != 2");

    glob_playback_duration = glob_duration / 2;
  }
  gst_query_unref (query);


  next_test (test);
}