예제 #1
0
static void owr_inter_src_dispose(GObject *object)
{
    OwrInterSrc *self = OWR_INTER_SRC(object);

    gst_object_unparent(GST_OBJECT(self->dummy_sinkpad));
    self->dummy_sinkpad = NULL;

    gst_object_unparent(GST_OBJECT(self->internal_srcpad));
    self->internal_srcpad = NULL;

    G_OBJECT_CLASS(owr_inter_src_parent_class)->dispose(object);
}
예제 #2
0
static void
gss_program_finalize (GObject * object)
{
  GssProgram *program = GSS_PROGRAM (object);
  GList *g;

  for (g = program->streams; g; g = g_list_next (g)) {
    GssStream *stream = g->data;

    gst_object_unparent (GST_OBJECT (stream));
  }
  g_list_free (program->streams);

  if (program->hls.variant_buffer) {
    soup_buffer_free (program->hls.variant_buffer);
  }

  if (program->pngappsink)
    g_object_unref (program->pngappsink);
  if (program->jpegsink)
    g_object_unref (program->jpegsink);
  gss_metrics_free (program->metrics);
  g_free (program->follow_uri);
  g_free (program->follow_host);
  g_free (program->description);

  parent_class->finalize (object);
}
static GstStateChangeReturn
gst_audio_ringbuffer_change_state (GstElement * element,
    GstStateChange transition)
{
  GstAudioRingbuffer *ringbuffer;
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;

  ringbuffer = GST_AUDIO_RINGBUFFER (element);

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      if (ringbuffer->buffer == NULL) {
        ringbuffer->buffer = gst_int_ring_buffer_new ();
        gst_object_set_parent (GST_OBJECT (ringbuffer->buffer),
            GST_OBJECT (ringbuffer));
        gst_ring_buffer_open_device (ringbuffer->buffer);
      }
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      ringbuffer->next_sample = -1;
      ringbuffer->last_align = -1;
      gst_ring_buffer_set_flushing (ringbuffer->buffer, FALSE);
      gst_ring_buffer_may_start (ringbuffer->buffer, TRUE);
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      GST_OBJECT_LOCK (ringbuffer);
      ringbuffer->flushing = TRUE;
      ringbuffer->waiting = FALSE;
      g_cond_broadcast (ringbuffer->cond);
      GST_OBJECT_UNLOCK (ringbuffer);

      gst_ring_buffer_set_flushing (ringbuffer->buffer, TRUE);
      gst_ring_buffer_may_start (ringbuffer->buffer, FALSE);
      break;
    default:
      break;
  }

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

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      gst_ring_buffer_activate (ringbuffer->buffer, FALSE);
      gst_ring_buffer_release (ringbuffer->buffer);
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      if (ringbuffer->buffer != NULL) {
        gst_ring_buffer_close_device (ringbuffer->buffer);
        gst_object_unparent (GST_OBJECT (ringbuffer->buffer));
        ringbuffer->buffer = NULL;
      }
      break;
    default:
      break;
  }

  return ret;
}
예제 #4
0
static void
gst_deinterlace2_set_method (GstDeinterlace2 * self,
    GstDeinterlace2Methods method)
{

  if (self->method) {
    gst_child_proxy_child_removed (GST_OBJECT (self),
        GST_OBJECT (self->method));
    gst_object_unparent (GST_OBJECT (self->method));
    self->method = NULL;
  }

  switch (method) {
    case GST_DEINTERLACE2_TOMSMOCOMP:
      self->method = g_object_new (GST_TYPE_DEINTERLACE_TOMSMOCOMP, NULL);
      break;
    case GST_DEINTERLACE2_GREEDY_H:
      self->method = g_object_new (GST_TYPE_DEINTERLACE_GREEDY_H, NULL);
      break;
    case GST_DEINTERLACE2_GREEDY_L:
      self->method = g_object_new (GST_TYPE_DEINTERLACE_GREEDY_L, NULL);
      break;
    case GST_DEINTERLACE2_VFIR:
      self->method = g_object_new (GST_TYPE_DEINTERLACE_VFIR, NULL);
      break;
    case GST_DEINTERLACE2_LINEAR:
      self->method = g_object_new (GST_TYPE_DEINTERLACE_LINEAR, NULL);
      break;
    case GST_DEINTERLACE2_LINEAR_BLEND:
      self->method = g_object_new (GST_TYPE_DEINTERLACE_LINEAR_BLEND, NULL);
      break;
    case GST_DEINTERLACE2_SCALER_BOB:
      self->method = g_object_new (GST_TYPE_DEINTERLACE_SCALER_BOB, NULL);
      break;
    case GST_DEINTERLACE2_WEAVE:
      self->method = g_object_new (GST_TYPE_DEINTERLACE_WEAVE, NULL);
      break;
    case GST_DEINTERLACE2_WEAVE_TFF:
      self->method = g_object_new (GST_TYPE_DEINTERLACE_WEAVE_TFF, NULL);
      break;
    case GST_DEINTERLACE2_WEAVE_BFF:
      self->method = g_object_new (GST_TYPE_DEINTERLACE_WEAVE_BFF, NULL);
      break;
    default:
      GST_WARNING ("Invalid Deinterlacer Method");
      return;
  }

  self->method_id = method;

  gst_object_set_name (GST_OBJECT (self->method), "method");
  gst_object_set_parent (GST_OBJECT (self->method), GST_OBJECT (self));
  gst_child_proxy_child_added (GST_OBJECT (self), GST_OBJECT (self->method));
}
예제 #5
0
void
gss_program_remove_stream (GssProgram * program, GssStream * stream)
{
  g_return_if_fail (GSS_IS_PROGRAM (program));
  g_return_if_fail (GSS_IS_STREAM (stream));

  program->streams = g_list_remove (program->streams, stream);

  gss_stream_remove_resources (stream);
  gst_object_unparent (GST_OBJECT (stream));
  stream->program = NULL;
}
예제 #6
0
static void
gst_deinterlace2_finalize (GObject * object)
{
  GstDeinterlace2 *self = GST_DEINTERLACE2 (object);

  gst_deinterlace2_reset (self);

  if (self->method) {
    gst_object_unparent (GST_OBJECT (self->method));
    self->method = NULL;
  }

  G_OBJECT_CLASS (parent_class)->finalize (object);
}
예제 #7
0
static void
gst_iir_equalizer_finalize (GObject * object)
{
  GstIirEqualizer *equ = GST_IIR_EQUALIZER (object);

  gint i;

  for (i = 0; i < equ->freq_band_count; i++) {
    if (equ->bands[i])
      gst_object_unparent (GST_OBJECT (equ->bands[i]));
    equ->bands[i] = NULL;
  }
  equ->freq_band_count = 0;

  g_free (equ->bands);
  g_free (equ->history);

  G_OBJECT_CLASS (parent_class)->finalize (object);
}
예제 #8
0
static void
gst_ghost_pad_dispose (GObject * object)
{
  GstPad *pad;
  GstPad *internal;
  GstPad *peer;

  pad = GST_PAD (object);

  GST_DEBUG_OBJECT (pad, "dispose");

  gst_ghost_pad_set_target (GST_GHOST_PAD (pad), NULL);

  /* Unlink here so that gst_pad_dispose doesn't. That would lead to a call to
   * gst_ghost_pad_do_unlink when the ghost pad is in an inconsistent state */
  peer = gst_pad_get_peer (pad);
  if (peer) {
    if (GST_PAD_IS_SRC (pad))
      gst_pad_unlink (pad, peer);
    else
      gst_pad_unlink (peer, pad);

    gst_object_unref (peer);
  }

  GST_PROXY_LOCK (pad);
  internal = GST_PROXY_PAD_INTERNAL (pad);

  gst_pad_set_activatepull_function (internal, NULL);
  gst_pad_set_activatepush_function (internal, NULL);

  g_signal_handler_disconnect (internal,
      GST_GHOST_PAD_PRIVATE (pad)->notify_id);

  /* disposes of the internal pad, since the ghostpad is the only possible object
   * that has a refcount on the internal pad. */
  gst_object_unparent (GST_OBJECT_CAST (internal));
  GST_PROXY_PAD_INTERNAL (pad) = NULL;

  GST_PROXY_UNLOCK (pad);

  G_OBJECT_CLASS (gst_ghost_pad_parent_class)->dispose (object);
}
예제 #9
0
static void
gst_base_audio_src_dispose (GObject * object)
{
  GstBaseAudioSrc *src;

  src = GST_BASE_AUDIO_SRC (object);

  GST_OBJECT_LOCK (src);
  if (src->clock)
    gst_object_unref (src->clock);
  src->clock = NULL;

  if (src->ringbuffer) {
    gst_object_unparent (GST_OBJECT_CAST (src->ringbuffer));
    src->ringbuffer = NULL;
  }
  GST_OBJECT_UNLOCK (src);

  G_OBJECT_CLASS (parent_class)->dispose (object);
}
예제 #10
0
/* dispose is called when the object has to release all links
 * to other objects */
static void
gst_object_dispose (GObject * object)
{
  GstObject *self = (GstObject *) object;
  GstObject *parent;

  GST_CAT_TRACE_OBJECT (GST_CAT_REFCOUNTING, object, "dispose");

  GST_OBJECT_LOCK (object);
  if ((parent = GST_OBJECT_PARENT (object)))
    goto have_parent;
  GST_OBJECT_PARENT (object) = NULL;
  GST_OBJECT_UNLOCK (object);

  if (self->control_bindings) {
    GList *node;

    for (node = self->control_bindings; node; node = g_list_next (node)) {
      gst_object_unparent (node->data);
    }
    g_list_free (self->control_bindings);
    self->control_bindings = NULL;
  }

  ((GObjectClass *) gst_object_parent_class)->dispose (object);

  return;

  /* ERRORS */
have_parent:
  {
    g_critical ("\nTrying to dispose object \"%s\", but it still has a "
        "parent \"%s\".\nYou need to let the parent manage the "
        "object instead of unreffing the object directly.\n",
        GST_OBJECT_NAME (object), GST_OBJECT_NAME (parent));
    GST_OBJECT_UNLOCK (object);
    /* ref the object again to revive it in this error case */
    gst_object_ref (object);
    return;
  }
}
예제 #11
0
static void
gst_ghost_pad_dispose (GObject * object)
{
  GstPad *pad;
  GstPad *internal;
  GstPad *intpeer;

  pad = GST_PAD (object);

  GST_DEBUG_OBJECT (pad, "dispose");

  GST_PROXY_LOCK (pad);
  internal = GST_PROXY_PAD_INTERNAL (pad);

  gst_pad_set_activatepull_function (internal, NULL);
  gst_pad_set_activatepush_function (internal, NULL);

  g_signal_handler_disconnect (internal, GST_GHOST_PAD_CAST (pad)->notify_id);

  intpeer = gst_pad_get_peer (internal);
  if (intpeer) {
    if (GST_PAD_IS_SRC (internal))
      gst_pad_unlink (internal, intpeer);
    else
      gst_pad_unlink (intpeer, internal);

    gst_object_unref (intpeer);
  }

  GST_PROXY_PAD_INTERNAL (internal) = NULL;

  /* disposes of the internal pad, since the ghostpad is the only possible object
   * that has a refcount on the internal pad. */
  gst_object_unparent (GST_OBJECT_CAST (internal));

  GST_PROXY_UNLOCK (pad);

  G_OBJECT_CLASS (gst_ghost_pad_parent_class)->dispose (object);
}
예제 #12
0
void
gst_iir_equalizer_compute_frequencies (GstIirEqualizer * equ, guint new_count)
{
  guint old_count, i;
  gdouble freq0, freq1, step;
  gchar name[20];

  if (equ->freq_band_count == new_count)
    return;

  BANDS_LOCK (equ);

  if (G_UNLIKELY (equ->freq_band_count == new_count)) {
    BANDS_UNLOCK (equ);
    return;
  }

  old_count = equ->freq_band_count;
  equ->freq_band_count = new_count;
  GST_DEBUG ("bands %u -> %u", old_count, new_count);

  if (old_count < new_count) {
    /* add new bands */
    equ->bands = g_realloc (equ->bands, sizeof (GstObject *) * new_count);
    for (i = old_count; i < new_count; i++) {
      /* otherwise they get names like 'iirequalizerband5' */
      sprintf (name, "band%u", i);
      equ->bands[i] = g_object_new (GST_TYPE_IIR_EQUALIZER_BAND,
          "name", name, NULL);
      GST_DEBUG ("adding band[%d]=%p", i, equ->bands[i]);

      gst_object_set_parent (GST_OBJECT (equ->bands[i]), GST_OBJECT (equ));
      gst_child_proxy_child_added (GST_OBJECT (equ),
          GST_OBJECT (equ->bands[i]));
    }
  } else {
    /* free unused bands */
    for (i = new_count; i < old_count; i++) {
      GST_DEBUG ("removing band[%d]=%p", i, equ->bands[i]);
      gst_child_proxy_child_removed (GST_OBJECT (equ),
          GST_OBJECT (equ->bands[i]));
      gst_object_unparent (GST_OBJECT (equ->bands[i]));
      equ->bands[i] = NULL;
    }
  }

  alloc_history (equ);

  /* set center frequencies and name band objects
   * FIXME: arg! we can't change the name of parented objects :(
   *   application should read band->freq to get the name
   */

  step = pow (HIGHEST_FREQ / LOWEST_FREQ, 1.0 / new_count);
  freq0 = LOWEST_FREQ;
  for (i = 0; i < new_count; i++) {
    freq1 = freq0 * step;

    if (i == 0)
      equ->bands[i]->type = BAND_TYPE_LOW_SHELF;
    else if (i == new_count - 1)
      equ->bands[i]->type = BAND_TYPE_HIGH_SHELF;
    else
      equ->bands[i]->type = BAND_TYPE_PEAK;

    equ->bands[i]->freq = freq0 + ((freq1 - freq0) / 2.0);
    equ->bands[i]->width = freq1 - freq0;
    GST_DEBUG ("band[%2d] = '%lf'", i, equ->bands[i]->freq);

    g_object_notify (G_OBJECT (equ->bands[i]), "bandwidth");
    g_object_notify (G_OBJECT (equ->bands[i]), "freq");
    g_object_notify (G_OBJECT (equ->bands[i]), "type");

    /*
       if(equ->bands[i]->freq<10000.0)
       sprintf (name,"%dHz",(gint)equ->bands[i]->freq);
       else
       sprintf (name,"%dkHz",(gint)(equ->bands[i]->freq/1000.0));
       gst_object_set_name( GST_OBJECT (equ->bands[i]), name);
       GST_DEBUG ("band[%2d] = '%s'",i,name);
     */
    freq0 = freq1;
  }

  equ->need_new_coefficients = TRUE;
  BANDS_UNLOCK (equ);
}
예제 #13
0
int main(int argc, char** argv) {
	char *config = getenv("GSCAM_CONFIG");
	if (config == NULL) {
		std::cout << "Problem getting GSCAM_CONFIG variable." << std::endl;
		exit(-1);
	}

	gst_init(0,0);
	std::cout << "Gstreamer Version: " << gst_version_string() << std::endl;

	GError *error = 0; //assignment to zero is a gst requirement
	GstElement *pipeline = gst_parse_launch(config,&error);
	if (pipeline == NULL) {
		std::cout << error->message << std::endl;
		exit(-1);
	}
	GstElement * sink = gst_element_factory_make("appsink",NULL);
	GstCaps * caps = gst_caps_new_simple("video/x-raw-rgb", NULL);
	gst_app_sink_set_caps(GST_APP_SINK(sink), caps);
	gst_caps_unref(caps);

	gst_base_sink_set_sync(GST_BASE_SINK(sink), TRUE);

	if(GST_IS_PIPELINE(pipeline)) {
	    GstPad *outpad = gst_bin_find_unlinked_pad(GST_BIN(pipeline), GST_PAD_SRC);
	    g_assert(outpad);
	    GstElement *outelement = gst_pad_get_parent_element(outpad);
	    g_assert(outelement);
	    gst_object_unref(outpad);


	    if(!gst_bin_add(GST_BIN(pipeline), sink)) {
		fprintf(stderr, "gst_bin_add() failed\n"); // TODO: do some unref
		gst_object_unref(outelement);
		gst_object_unref(pipeline);
		return -1;
	    }

	    if(!gst_element_link(outelement, sink)) {
		fprintf(stderr, "GStreamer: cannot link outelement(\"%s\") -> sink\n", gst_element_get_name(outelement));
		gst_object_unref(outelement);
		gst_object_unref(pipeline);
		return -1;
	    }

	    gst_object_unref(outelement);
	} else {
	    GstElement* launchpipe = pipeline;
	    pipeline = gst_pipeline_new(NULL);
	    g_assert(pipeline);

	    gst_object_unparent(GST_OBJECT(launchpipe));

	    gst_bin_add_many(GST_BIN(pipeline), launchpipe, sink, NULL);

	    if(!gst_element_link(launchpipe, sink)) {
		fprintf(stderr, "GStreamer: cannot link launchpipe -> sink\n");
		gst_object_unref(pipeline);
		return -1;
	    }
	}

	gst_element_set_state(pipeline, GST_STATE_PAUSED);

	if (gst_element_get_state(pipeline, NULL, NULL, -1) == GST_STATE_CHANGE_FAILURE) {
		std::cout << "Failed to PAUSE." << std::endl;
		exit(-1);
	} else {
		std::cout << "stream is PAUSED." << std::endl;
	}

	// We could probably do something with the camera name, check
	// errors or something, but at the moment, we don't care.
	std::string camera_name;
	if (camera_calibration_parsers::readCalibrationIni("../camera_parameters.txt", camera_name, camera_info)) {
	  ROS_INFO("Successfully read camera calibration.  Rerun camera calibrator if it is incorrect.");
	}
	else {
	  ROS_ERROR("No camera_parameters.txt file found.  Use default file if no other is available.");
	}

	ros::init(argc, argv, "gscam_publisher");
	ros::NodeHandle nh;

	int preroll;
	nh.param("brown/gscam/preroll", preroll, 0);
	if (preroll) {
		//The PAUSE, PLAY, PAUSE, PLAY cycle is to ensure proper pre-roll
		//I am told this is needed and am erring on the side of caution.
		gst_element_set_state(pipeline, GST_STATE_PLAYING);

		if (gst_element_get_state(pipeline, NULL, NULL, -1) == GST_STATE_CHANGE_FAILURE) {
			std::cout << "Failed to PLAY." << std::endl;
			exit(-1);
		} else {
			std::cout << "stream is PLAYING." << std::endl;
		}

		gst_element_set_state(pipeline, GST_STATE_PAUSED);

		if (gst_element_get_state(pipeline, NULL, NULL, -1) == GST_STATE_CHANGE_FAILURE) {
			std::cout << "Failed to PAUSE." << std::endl;
			exit(-1);
		} else {
			std::cout << "stream is PAUSED." << std::endl;
		}
	}

	image_transport::ImageTransport it(nh);
//	image_transport::CameraPublisher pub = it.advertiseCamera("gscam/image_raw", 1);

//------------------------------------
// Added by jschoi, 2012-08-13
	char topic_name[32];
	if(argc==1)
		sprintf(topic_name, "gscam/image_raw");
	else
		sprintf(topic_name,"%s",argv[1]);	// To get the name of topic from the first arguement
//------------------------------------
	image_transport::CameraPublisher pub = it.advertiseCamera(topic_name, 1);

	ros::ServiceServer set_camera_info = nh.advertiseService("gscam/set_camera_info", setCameraInfo);

	std::cout << "Processing..." << std::endl;

	//processVideo
	rosPad = false;
	gstreamerPad = true;
	gst_element_set_state(pipeline, GST_STATE_PLAYING);
	while(nh.ok()) {
                // This should block until a new frame is awake, this way, we'll run at the 
                // actual capture framerate of the device.
		GstBuffer* buf = gst_app_sink_pull_buffer(GST_APP_SINK(sink));
		if (!buf) break;

		GstPad* pad = gst_element_get_static_pad(sink, "sink");
		const GstCaps *caps = gst_pad_get_negotiated_caps(pad);
		GstStructure *structure = gst_caps_get_structure(caps,0);
		gst_structure_get_int(structure,"width",&width);
		gst_structure_get_int(structure,"height",&height);

		sensor_msgs::Image msg;
		msg.width = width; 
		msg.height = height;
		msg.encoding = "rgb8";
		msg.is_bigendian = false;
		msg.step = width*3;
		msg.data.resize(width*height*3);
		std::copy(buf->data, buf->data+(width*height*3), msg.data.begin());

		pub.publish(msg, camera_info);

                gst_buffer_unref(buf);

		ros::spinOnce();

	}

	//close out
	std::cout << "\nquitting..." << std::endl;
	gst_element_set_state(pipeline, GST_STATE_NULL);
	gst_object_unref(pipeline);

	return 0;
}
예제 #14
0
파일: gscam.cpp 프로젝트: SirVer/gscam
  bool GSCam::init_stream()
  {
    if(!gst_is_initialized()) {
      // Initialize gstreamer pipeline
      ROS_DEBUG_STREAM( "Initializing gstreamer..." );
      gst_init(0,0);
    }

    ROS_DEBUG_STREAM( "Gstreamer Version: " << gst_version_string() );

    GError *error = 0; // Assignment to zero is a gst requirement

    pipeline_ = gst_parse_launch(gsconfig_.c_str(), &error);
    if (pipeline_ == NULL) {
      ROS_FATAL_STREAM( error->message );
      return false;
    }

    // Create RGB sink
    sink_ = gst_element_factory_make("appsink",NULL);
    GstCaps * caps = image_encoding_ == sensor_msgs::image_encodings::RGB8 ?
        gst_caps_new_simple("video/x-raw-rgb", NULL) :
        gst_caps_new_simple("video/x-raw-gray", NULL);
    gst_app_sink_set_caps(GST_APP_SINK(sink_), caps);
    gst_caps_unref(caps);

    // Set whether the sink should sync
    // Sometimes setting this to true can cause a large number of frames to be
    // dropped
    gst_base_sink_set_sync(
        GST_BASE_SINK(sink_),
        (sync_sink_) ? TRUE : FALSE);

    if(GST_IS_PIPELINE(pipeline_)) {
      GstPad *outpad = gst_bin_find_unlinked_pad(GST_BIN(pipeline_), GST_PAD_SRC);
      g_assert(outpad);

      GstElement *outelement = gst_pad_get_parent_element(outpad);
      g_assert(outelement);
      gst_object_unref(outpad);

      if(!gst_bin_add(GST_BIN(pipeline_), sink_)) {
        ROS_FATAL("gst_bin_add() failed");
        gst_object_unref(outelement);
        gst_object_unref(pipeline_);
        return false;
      }

      if(!gst_element_link(outelement, sink_)) {
        ROS_FATAL("GStreamer: cannot link outelement(\"%s\") -> sink\n", gst_element_get_name(outelement));
        gst_object_unref(outelement);
        gst_object_unref(pipeline_);
        return false;
      }

      gst_object_unref(outelement);
    } else {
      GstElement* launchpipe = pipeline_;
      pipeline_ = gst_pipeline_new(NULL);
      g_assert(pipeline_);

      gst_object_unparent(GST_OBJECT(launchpipe));

      gst_bin_add_many(GST_BIN(pipeline_), launchpipe, sink_, NULL);

      if(!gst_element_link(launchpipe, sink_)) {
        ROS_FATAL("GStreamer: cannot link launchpipe -> sink");
        gst_object_unref(pipeline_);
        return false;
      }
    }

    gst_element_set_state(pipeline_, GST_STATE_PAUSED);

    if (gst_element_get_state(pipeline_, NULL, NULL, -1) == GST_STATE_CHANGE_FAILURE) {
      ROS_FATAL("Failed to PAUSE stream, check your gstreamer configuration.");
      return false;
    } else {
      ROS_DEBUG_STREAM("Stream is PAUSED.");
    }

    // Create ROS camera interface
    camera_pub_ = image_transport_.advertiseCamera("camera/image_raw", 1);

    return true;
  }
예제 #15
0
파일: object.cpp 프로젝트: dejunk/gstreamer
void Object::unparent()
{
    gst_object_unparent(object<GstObject>());
}
예제 #16
0
static GstStateChangeReturn
gst_base_audio_src_change_state (GstElement * element,
    GstStateChange transition)
{
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
  GstBaseAudioSrc *src = GST_BASE_AUDIO_SRC (element);

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      GST_DEBUG_OBJECT (src, "NULL->READY");
      GST_OBJECT_LOCK (src);
      if (src->ringbuffer == NULL) {
        gst_audio_clock_reset (GST_AUDIO_CLOCK (src->clock), 0);
        src->ringbuffer = gst_base_audio_src_create_ringbuffer (src);
      }
      GST_OBJECT_UNLOCK (src);
      if (!gst_ring_buffer_open_device (src->ringbuffer))
        goto open_failed;
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      GST_DEBUG_OBJECT (src, "READY->PAUSED");
      src->next_sample = -1;
      gst_ring_buffer_set_flushing (src->ringbuffer, FALSE);
      gst_ring_buffer_may_start (src->ringbuffer, FALSE);
      break;
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
      GST_DEBUG_OBJECT (src, "PAUSED->PLAYING");
      gst_ring_buffer_may_start (src->ringbuffer, TRUE);
      break;
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
      GST_DEBUG_OBJECT (src, "PLAYING->PAUSED");
      gst_ring_buffer_may_start (src->ringbuffer, FALSE);
      gst_ring_buffer_pause (src->ringbuffer);
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      GST_DEBUG_OBJECT (src, "PAUSED->READY");
      gst_ring_buffer_set_flushing (src->ringbuffer, TRUE);
      break;
    default:
      break;
  }

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

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      GST_DEBUG_OBJECT (src, "PAUSED->READY");
      gst_ring_buffer_release (src->ringbuffer);
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      GST_DEBUG_OBJECT (src, "READY->NULL");
      gst_ring_buffer_close_device (src->ringbuffer);
      GST_OBJECT_LOCK (src);
      gst_object_unparent (GST_OBJECT_CAST (src->ringbuffer));
      src->ringbuffer = NULL;
      GST_OBJECT_UNLOCK (src);
      break;
    default:
      break;
  }

  return ret;

  /* ERRORS */
open_failed:
  {
    /* subclass must post a meaningfull error message */
    GST_DEBUG_OBJECT (src, "open failed");
    return GST_STATE_CHANGE_FAILURE;
  }

}
예제 #17
0
static GstStateChangeReturn
gst_base_audio_src_change_state (GstElement * element,
    GstStateChange transition)
{
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
  GstBaseAudioSrc *src = GST_BASE_AUDIO_SRC (element);

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      GST_DEBUG_OBJECT (src, "NULL->READY");
      GST_OBJECT_LOCK (src);
      if (src->ringbuffer == NULL) {
        gst_audio_clock_reset (GST_AUDIO_CLOCK (src->clock), 0);
        src->ringbuffer = gst_base_audio_src_create_ringbuffer (src);
      }
      GST_OBJECT_UNLOCK (src);
      if (!gst_ring_buffer_open_device (src->ringbuffer))
        goto open_failed;
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      GST_DEBUG_OBJECT (src, "READY->PAUSED");
      src->next_sample = -1;
      gst_ring_buffer_set_flushing (src->ringbuffer, FALSE);
      gst_ring_buffer_may_start (src->ringbuffer, FALSE);
      /* Only post clock-provide messages if this is the clock that
       * we've created. If the subclass has overriden it the subclass
       * should post this messages whenever necessary */
      if (src->clock && GST_IS_AUDIO_CLOCK (src->clock) &&
          GST_AUDIO_CLOCK_CAST (src->clock)->func ==
          (GstAudioClockGetTimeFunc) gst_base_audio_src_get_time)
        gst_element_post_message (element,
            gst_message_new_clock_provide (GST_OBJECT_CAST (element),
                src->clock, TRUE));
      break;
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
      GST_DEBUG_OBJECT (src, "PAUSED->PLAYING");
      gst_ring_buffer_may_start (src->ringbuffer, TRUE);
      break;
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
      GST_DEBUG_OBJECT (src, "PLAYING->PAUSED");
      gst_ring_buffer_may_start (src->ringbuffer, FALSE);
      gst_ring_buffer_pause (src->ringbuffer);
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      GST_DEBUG_OBJECT (src, "PAUSED->READY");
      /* Only post clock-lost messages if this is the clock that
       * we've created. If the subclass has overriden it the subclass
       * should post this messages whenever necessary */
      if (src->clock && GST_IS_AUDIO_CLOCK (src->clock) &&
          GST_AUDIO_CLOCK_CAST (src->clock)->func ==
          (GstAudioClockGetTimeFunc) gst_base_audio_src_get_time)
        gst_element_post_message (element,
            gst_message_new_clock_lost (GST_OBJECT_CAST (element), src->clock));
      gst_ring_buffer_set_flushing (src->ringbuffer, TRUE);
      break;
    default:
      break;
  }

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

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      GST_DEBUG_OBJECT (src, "PAUSED->READY");
      gst_ring_buffer_release (src->ringbuffer);
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      GST_DEBUG_OBJECT (src, "READY->NULL");
      gst_ring_buffer_close_device (src->ringbuffer);
      GST_OBJECT_LOCK (src);
      gst_object_unparent (GST_OBJECT_CAST (src->ringbuffer));
      src->ringbuffer = NULL;
      GST_OBJECT_UNLOCK (src);
      break;
    default:
      break;
  }

  return ret;

  /* ERRORS */
open_failed:
  {
    /* subclass must post a meaningfull error message */
    GST_DEBUG_OBJECT (src, "open failed");
    return GST_STATE_CHANGE_FAILURE;
  }

}