/* convert the PacketLost event form a jitterbuffer to a segment update. * subclasses can override this. */ static gboolean gst_base_rtp_depayload_packet_lost (GstBaseRTPDepayload * filter, GstEvent * event) { GstBaseRTPDepayloadPrivate *priv; GstClockTime timestamp, duration, position; GstEvent *sevent; const GstStructure *s; priv = filter->priv; s = gst_event_get_structure (event); /* first start by parsing the timestamp and duration */ timestamp = -1; duration = -1; gst_structure_get_clock_time (s, "timestamp", ×tamp); gst_structure_get_clock_time (s, "duration", &duration); position = timestamp; if (duration != -1) position += duration; /* update the current segment with the elapsed time */ sevent = create_segment_event (filter, TRUE, position); return gst_pad_push_event (filter->srcpad, sevent); }
/* convert the PacketLost event from a jitterbuffer to a GAP event. * subclasses can override this. */ static gboolean gst_rtp_base_depayload_packet_lost (GstRTPBaseDepayload * filter, GstEvent * event) { GstClockTime timestamp, duration; GstEvent *sevent; const GstStructure *s; s = gst_event_get_structure (event); /* first start by parsing the timestamp and duration */ timestamp = -1; duration = -1; if (!gst_structure_get_clock_time (s, "timestamp", ×tamp) || !gst_structure_get_clock_time (s, "duration", &duration)) { GST_ERROR_OBJECT (filter, "Packet loss event without timestamp or duration"); return FALSE; } sevent = gst_pad_get_sticky_event (filter->srcpad, GST_EVENT_SEGMENT, 0); if (G_UNLIKELY (!sevent)) { /* Typically happens if lost event arrives before first buffer */ GST_DEBUG_OBJECT (filter, "Ignore packet loss because segment event missing"); return FALSE; } gst_event_unref (sevent); /* send GAP event */ sevent = gst_event_new_gap (timestamp, duration); return gst_pad_push_event (filter->srcpad, sevent); }
static gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer data) { GMainLoop *loop = (GMainLoop *) data; switch (GST_MESSAGE_TYPE (msg)) { case GST_MESSAGE_APPLICATION: { const GstStructure * msg_struct = gst_message_get_structure(msg); guint64 duration = 0; guint64 timestamp = 0; int stream_thread_id = 0; g_debug("APPLICATION CUSTOM MESSAGE !!!"); g_debug("MESSAGE THREAD ID[%p]", g_thread_self()); gst_structure_get_clock_time (msg_struct, "duration" , &duration); gst_structure_get_clock_time (msg_struct, "timestamp" , ×tamp); gst_structure_get_int (msg_struct, "stream_thread_id" , &stream_thread_id); g_debug("STREAM THREAD ID[0x%x]", stream_thread_id); g_debug("DURATION[%llu], TIMESTAMP[%llu]", duration, timestamp); g_debug("Testing string message, [%s]\n", gst_structure_get_string(msg_struct, "msg")); break; } case GST_MESSAGE_EOS: { g_print ("End of stream\n"); g_main_loop_quit (loop); break; } case GST_MESSAGE_ERROR: { gchar *debug; GError *error; gst_message_parse_error (msg, &error, &debug); g_free (debug); g_printerr ("Error: %s\n", error->message); g_error_free (error); g_main_loop_quit (loop); break; } default: g_print("Msg type [%d], Msg name [%s]\n", GST_MESSAGE_TYPE (msg), GST_MESSAGE_TYPE_NAME(msg)); break; } return TRUE; }
/** * gst_video_event_parse_downstream_force_key_unit: * @event: A #GstEvent to parse * @timestamp: (out): A pointer to the timestamp in the event * @stream_time: (out): A pointer to the stream-time in the event * @running_time: (out): A pointer to the running-time in the event * @all_headers: (out): A pointer to the all_headers flag in the event * @count: (out): A pointer to the count field of the event * * Get timestamp, stream-time, running-time, all-headers and count in the force * key unit event. See gst_video_event_new_downstream_force_key_unit() for a * full description of the downstream force key unit event. * * @running_time will be adjusted for any pad offsets of pads it was passing through. * * Returns: %TRUE if the event is a valid downstream force key unit event. */ gboolean gst_video_event_parse_downstream_force_key_unit (GstEvent * event, GstClockTime * timestamp, GstClockTime * stream_time, GstClockTime * running_time, gboolean * all_headers, guint * count) { const GstStructure *s; GstClockTime ev_timestamp, ev_stream_time, ev_running_time; gboolean ev_all_headers; guint ev_count; g_return_val_if_fail (event != NULL, FALSE); if (GST_EVENT_TYPE (event) != GST_EVENT_CUSTOM_DOWNSTREAM) return FALSE; /* Not a force key unit event */ s = gst_event_get_structure (event); if (s == NULL || !gst_structure_has_name (s, GST_VIDEO_EVENT_FORCE_KEY_UNIT_NAME)) return FALSE; if (!gst_structure_get_clock_time (s, "timestamp", &ev_timestamp)) ev_timestamp = GST_CLOCK_TIME_NONE; if (!gst_structure_get_clock_time (s, "stream-time", &ev_stream_time)) ev_stream_time = GST_CLOCK_TIME_NONE; if (!gst_structure_get_clock_time (s, "running-time", &ev_running_time)) ev_running_time = GST_CLOCK_TIME_NONE; if (!gst_structure_get_boolean (s, "all-headers", &ev_all_headers)) ev_all_headers = FALSE; if (!gst_structure_get_uint (s, "count", &ev_count)) ev_count = 0; if (timestamp) *timestamp = ev_timestamp; if (stream_time) *stream_time = ev_stream_time; if (running_time) { gint64 offset = gst_event_get_running_time_offset (event); *running_time = ev_running_time; /* Catch underflows */ if (*running_time > -offset) *running_time += offset; else *running_time = 0; } if (all_headers) *all_headers = ev_all_headers; if (count) *count = ev_count; return TRUE; }
static gboolean gst_rtp_dtmf_src_handle_dtmf_event (GstRTPDTMFSrc * dtmfsrc, const GstStructure * event_structure) { gint event_type; gboolean start; gint method; GstClockTime last_stop; gint event_number; gint event_volume; gboolean correct_order; if (!gst_structure_get_int (event_structure, "type", &event_type) || !gst_structure_get_boolean (event_structure, "start", &start) || event_type != GST_RTP_DTMF_TYPE_EVENT) goto failure; if (gst_structure_get_int (event_structure, "method", &method)) { if (method != 1) { goto failure; } } if (start) if (!gst_structure_get_int (event_structure, "number", &event_number) || !gst_structure_get_int (event_structure, "volume", &event_volume)) goto failure; GST_OBJECT_LOCK (dtmfsrc); if (gst_structure_get_clock_time (event_structure, "last-stop", &last_stop)) dtmfsrc->last_stop = last_stop; else dtmfsrc->last_stop = GST_CLOCK_TIME_NONE; correct_order = (start != dtmfsrc->last_event_was_start); dtmfsrc->last_event_was_start = start; GST_OBJECT_UNLOCK (dtmfsrc); if (!correct_order) goto failure; if (start) { if (!gst_structure_get_int (event_structure, "number", &event_number) || !gst_structure_get_int (event_structure, "volume", &event_volume)) goto failure; GST_DEBUG_OBJECT (dtmfsrc, "Received start event %d with volume %d", event_number, event_volume); gst_rtp_dtmf_src_add_start_event (dtmfsrc, event_number, event_volume); } else { GST_DEBUG_OBJECT (dtmfsrc, "Received stop event"); gst_rtp_dtmf_src_add_stop_event (dtmfsrc); } return TRUE; failure: return FALSE; }
/* receive spectral data from element message */ static gboolean message_handler (GstBus * bus, GstMessage * message, gpointer data) { if (message->type == GST_MESSAGE_ELEMENT) { const GstStructure *s = gst_message_get_structure (message); const gchar *name = gst_structure_get_name (s); if (strcmp (name, "spectrum") == 0) { GstElement *spectrum = GST_ELEMENT (GST_MESSAGE_SRC (message)); GstClockTime timestamp, duration; GstClockTime waittime = GST_CLOCK_TIME_NONE; if (gst_structure_get_clock_time (s, "running-time", ×tamp) && gst_structure_get_clock_time (s, "duration", &duration)) { /* wait for middle of buffer */ waittime = timestamp + duration / 2; } else if (gst_structure_get_clock_time (s, "endtime", ×tamp)) { waittime = timestamp; } if (GST_CLOCK_TIME_IS_VALID (waittime)) { GstClockID clock_id; GstClockTime basetime = gst_element_get_base_time (spectrum); gfloat *spect = g_new (gfloat, spect_bands); const GValue *list; const GValue *value; guint i; list = gst_structure_get_value (s, "magnitude"); for (i = 0; i < spect_bands; ++i) { value = gst_value_list_get_value (list, i); spect[i] = height_scale * g_value_get_float (value); } clock_id = gst_clock_new_single_shot_id (sync_clock, waittime + basetime); gst_clock_id_wait_async (clock_id, delayed_spectrum_update, (gpointer) spect); gst_clock_id_unref (clock_id); } } } return TRUE; }
gboolean message_handler (GstBus * bus, GstMessage * message, gpointer data) { if (message->type == GST_MESSAGE_ELEMENT) { const GstStructure *s = gst_message_get_structure (message); const gchar *name = gst_structure_get_name (s); if (strcmp (name, "level") == 0) { gint channels; GstClockTime endtime; gdouble rms_dB, peak_dB, decay_dB; gdouble rms; const GValue *list; const GValue *value; gint i; if (!gst_structure_get_clock_time (s, "endtime", &endtime)) g_warning ("Could not parse endtime"); /* we can get the number of channels as the length of any of the value * lists */ list = gst_structure_get_value (s, "rms"); channels = gst_value_list_get_size (list); g_print ("endtime: %" GST_TIME_FORMAT ", channels: %d\n", GST_TIME_ARGS (endtime), channels); for (i = 0; i < channels; ++i) { g_print ("channel %d\n", i); list = gst_structure_get_value (s, "rms"); value = gst_value_list_get_value (list, i); rms_dB = g_value_get_double (value); list = gst_structure_get_value (s, "peak"); value = gst_value_list_get_value (list, i); peak_dB = g_value_get_double (value); list = gst_structure_get_value (s, "decay"); value = gst_value_list_get_value (list, i); decay_dB = g_value_get_double (value); g_print (" RMS: %f dB, peak: %f dB, decay: %f dB\n", rms_dB, peak_dB, decay_dB); /* converting from dB to normal gives us a value between 0.0 and 1.0 */ rms = pow (10, rms_dB / 20); g_print (" normalized rms value: %f\n", rms); } } } /* we handled the message we want, and ignored the ones we didn't want. * so the core can unref the message for us */ return TRUE; }
static GstBusSyncReply on_message (GstBus * bus, GstMessage * message, gpointer user_data) { const GstStructure *s = gst_message_get_structure (message); const gchar *name = gst_structure_get_name (s); GValueArray *rms_arr; const GValue *array_val; const GValue *value; gdouble rms; gint channels2; guint i; GstClockTime *rtime; if (message->type != GST_MESSAGE_ELEMENT || strcmp (name, "videoframe-audiolevel") != 0) goto done; num_msgs++; rtime = g_new (GstClockTime, 1); if (!gst_structure_get_clock_time (s, "running-time", rtime)) { g_warning ("Could not parse running time"); g_free (rtime); } else { g_queue_push_tail (&msg_timestamp_q, rtime); } /* the values are packed into GValueArrays with the value per channel */ array_val = gst_structure_get_value (s, "rms"); rms_arr = (GValueArray *) g_value_get_boxed (array_val); channels2 = rms_arr->n_values; fail_unless_equals_int (channels2, channels); for (i = 0; i < channels; ++i) { value = g_value_array_get_nth (rms_arr, i); rms = g_value_get_double (value); if (per_channel) { fail_unless_equals_float (rms, expected_rms_per_channel[i]); } else if (early_video && *rtime <= 50 * GST_MSECOND) { fail_unless_equals_float (rms, 0); } else { fail_unless_equals_float (rms, expected_rms); } } done: return GST_BUS_PASS; }
/* receive spectral data from element message */ static gboolean message_handler (GstBus * bus, GstMessage * message, gpointer data) { if (message->type == GST_MESSAGE_ELEMENT) { const GstStructure *s = gst_message_get_structure (message); const gchar *name = gst_structure_get_name (s); GstClockTime endtime; if (strcmp (name, "spectrum") == 0) { const GValue *magnitudes; const GValue *phases; const GValue *mag, *phase; gdouble freq; guint i; if (!gst_structure_get_clock_time (s, "endtime", &endtime)) endtime = GST_CLOCK_TIME_NONE; // g_print ("New spectrum message, endtime %" GST_TIME_FORMAT "\n", // GST_TIME_ARGS (endtime)); magnitudes = gst_structure_get_value (s, "magnitude"); phases = gst_structure_get_value (s, "phase"); for (i = 0; i < spect_bands; ++i) { freq = (gdouble) ((AUDIOFREQ / 2) * i + AUDIOFREQ / 4) / spect_bands; mag = gst_value_list_get_value (magnitudes, i); phase = gst_value_list_get_value (phases, i); if (mag != NULL && phase != NULL) { g_print ("%g %f\n", freq, g_value_get_float (mag)); } } //system(" perl rtgnuplotter.pl"); } } return TRUE; }
/* receive spectral data from element message */ gboolean AudioGrabber::message_handler (GstBus * bus, GstMessage * message, gpointer data) { if (message->type == GST_MESSAGE_ELEMENT) { const GstStructure *s = gst_message_get_structure (message); const gchar *name = gst_structure_get_name (s); GstClockTime endtime; if (strcmp (name, "spectrum") == 0) { const GValue *magnitudes; const GValue *phases; const GValue *mag, *phase; gdouble freq; int i; if (!gst_structure_get_clock_time (s, "endtime", &endtime)) endtime = GST_CLOCK_TIME_NONE; //g_print ("New spectrum message, endtime %" GST_TIME_FORMAT "\n", // GST_TIME_ARGS (endtime)); magnitudes = gst_structure_get_value (s, "magnitude"); phases = gst_structure_get_value (s, "phase"); for (i = 0; i < 20; ++i) { // TODO 20 = _num_bands freq = (gdouble) ((8000 / 2) * i + 8000 / 4) / 20; // TODO 8000=_freq 8000=_freq 20=_num_bands mag = gst_value_list_get_value (magnitudes, i); phase = gst_value_list_get_value (phases, i); if (mag != NULL && phase != NULL && g_value_get_float (mag) >-50 && freq>16) { g_print ("band %d (freq %g): magnitude %f dB phase %f\n", i, freq, g_value_get_float (mag), g_value_get_float (phase)); g_print ("\n"); } } } } return TRUE; }
static void gst_hls_sink2_handle_message (GstBin * bin, GstMessage * message) { GstHlsSink2 *sink = GST_HLS_SINK2_CAST (bin); switch (message->type) { case GST_MESSAGE_ELEMENT: { const GstStructure *s = gst_message_get_structure (message); if (message->src == GST_OBJECT_CAST (sink->splitmuxsink)) { if (gst_structure_has_name (s, "splitmuxsink-fragment-opened")) { g_free (sink->current_location); sink->current_location = g_strdup (gst_structure_get_string (s, "location")); gst_structure_get_clock_time (s, "running-time", &sink->current_running_time_start); } else if (gst_structure_has_name (s, "splitmuxsink-fragment-closed")) { GstClockTime running_time; gchar *entry_location; g_assert (strcmp (sink->current_location, gst_structure_get_string (s, "location")) == 0); gst_structure_get_clock_time (s, "running-time", &running_time); GST_INFO_OBJECT (sink, "COUNT %d", sink->index); if (sink->playlist_root == NULL) { entry_location = g_path_get_basename (sink->current_location); } else { gchar *name = g_path_get_basename (sink->current_location); entry_location = g_build_filename (sink->playlist_root, name, NULL); g_free (name); } gst_m3u8_playlist_add_entry (sink->playlist, entry_location, NULL, running_time - sink->current_running_time_start, sink->index++, FALSE); g_free (entry_location); gst_hls_sink2_write_playlist (sink); g_queue_push_tail (&sink->old_locations, g_strdup (sink->current_location)); while (g_queue_get_length (&sink->old_locations) > g_queue_get_length (sink->playlist->entries)) { gchar *old_location = g_queue_pop_head (&sink->old_locations); g_remove (old_location); g_free (old_location); } } } break; } case GST_MESSAGE_EOS:{ sink->playlist->end_list = TRUE; gst_hls_sink2_write_playlist (sink); break; } default: break; } GST_BIN_CLASS (parent_class)->handle_message (bin, message); }
static gboolean gst_dtmf_src_handle_dtmf_event (GstDTMFSrc * dtmfsrc, GstEvent * event) { const GstStructure *event_structure; GstStateChangeReturn sret; GstState state; gint event_type; gboolean start; gint method; GstClockTime last_stop; gint event_number; gint event_volume; gboolean correct_order; sret = gst_element_get_state (GST_ELEMENT (dtmfsrc), &state, NULL, 0); if (sret != GST_STATE_CHANGE_SUCCESS || state != GST_STATE_PLAYING) { GST_DEBUG_OBJECT (dtmfsrc, "dtmf-event, but not in PLAYING state"); goto failure; } event_structure = gst_event_get_structure (event); if (!gst_structure_get_int (event_structure, "type", &event_type) || !gst_structure_get_boolean (event_structure, "start", &start) || (start == TRUE && event_type != GST_TONE_DTMF_TYPE_EVENT)) goto failure; if (gst_structure_get_int (event_structure, "method", &method)) { if (method != 2) { goto failure; } } if (start) if (!gst_structure_get_int (event_structure, "number", &event_number) || !gst_structure_get_int (event_structure, "volume", &event_volume)) goto failure; GST_OBJECT_LOCK (dtmfsrc); if (gst_structure_get_clock_time (event_structure, "last-stop", &last_stop)) dtmfsrc->last_stop = last_stop; else dtmfsrc->last_stop = GST_CLOCK_TIME_NONE; correct_order = (start != dtmfsrc->last_event_was_start); dtmfsrc->last_event_was_start = start; GST_OBJECT_UNLOCK (dtmfsrc); if (!correct_order) goto failure; if (start) { GST_DEBUG_OBJECT (dtmfsrc, "Received start event %d with volume %d", event_number, event_volume); gst_dtmf_src_add_start_event (dtmfsrc, event_number, event_volume); } else { GST_DEBUG_OBJECT (dtmfsrc, "Received stop event"); gst_dtmf_src_add_stop_event (dtmfsrc); } return TRUE; failure: return FALSE; }
void TrackAnalyser::messageReceived(GstMessage *message) { switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_ERROR: { GError *err; gchar *debug; gst_message_parse_error (message, &err, &debug); QString str; str = "Error #"+QString::number(err->code)+" in module "+QString::number(err->domain)+"\n"+QString::fromUtf8(err->message); if(err->code == 6 && err->domain == 851) { str += "\nMay be you should to install gstreamer0.10-plugins-ugly or gstreamer0.10-plugins-bad"; } qDebug()<< "Gstreamer error:"<< str; g_error_free (err); g_free (debug); need_finish(); break; } case GST_MESSAGE_EOS:{ qDebug() << __PRETTY_FUNCTION__ <<":"<<parentWidget()->objectName()<<" End of track reached"; need_finish(); break; } case GST_MESSAGE_ELEMENT:{ GstClockTime timestamp; const GstStructure *s = gst_message_get_structure (message); const gchar *name = gst_structure_get_name (s); if (strcmp (name, "cutter") == 0) { gst_structure_get_clock_time (s, "timestamp", ×tamp); const GValue *value; value=gst_structure_get_value (s, "above"); bool isSilent=!g_value_get_boolean(value); //if we detect a falling edge, set EndPostion to this if (isSilent) m_EndPosition=QTime(0,0).addMSecs( static_cast<uint>( ( timestamp / GST_MSECOND ) )); // nanosec -> msec else { //if this is the first rising edge, set StartPosition if (m_StartPosition==QTime(0,0) && m_EndPosition==m_MaxPosition) m_StartPosition=QTime(0,0).addMSecs( static_cast<uint>( ( timestamp / GST_MSECOND ) )); // nanosec -> msec //if we detect a rising edge, set EndPostion to track end m_EndPosition=m_MaxPosition; } //qDebug() << __PRETTY_FUNCTION__ <<QTime(0,0).addMSecs( static_cast<uint>( ( timestamp / GST_MSECOND ) ))<< " silent:" << isSilent; } break; } case GST_MESSAGE_TAG:{ const GstStructure *s = gst_message_get_structure (message); const GValue *value; value=gst_structure_get_value (s, "replaygain-track-gain"); if (value){ m_GainDB = g_value_get_double (value); //qDebug() << "Gain-db:" << gain_db; //qDebug() << "Gain-norm:" << pow (10, m_GainDB / 20); } } default: break; } }
static void gst_hls_sink_handle_message (GstBin * bin, GstMessage * message) { GstHlsSink *sink = GST_HLS_SINK_CAST (bin); switch (message->type) { case GST_MESSAGE_ELEMENT: { const char *filename; GstClockTime running_time, duration; gboolean discont = FALSE; gchar *entry_location; const GstStructure *structure; structure = gst_message_get_structure (message); if (strcmp (gst_structure_get_name (structure), "GstMultiFileSink")) break; filename = gst_structure_get_string (structure, "filename"); gst_structure_get_clock_time (structure, "running-time", &running_time); duration = running_time - sink->last_running_time; sink->last_running_time = running_time; GST_INFO_OBJECT (sink, "COUNT %d", sink->index); if (sink->playlist_root == NULL) entry_location = g_path_get_basename (filename); else { gchar *name = g_path_get_basename (filename); entry_location = g_build_filename (sink->playlist_root, name, NULL); g_free (name); } gst_m3u8_playlist_add_entry (sink->playlist, entry_location, NULL, duration, sink->index, discont); g_free (entry_location); gst_hls_sink_write_playlist (sink); /* multifilesink is starting a new file. It means that upstream sent a key * unit and we can schedule the next key unit now. */ sink->waiting_fku = FALSE; schedule_next_key_unit (sink); /* multifilesink is an internal implementation detail. If applications * need a notification, we should probably do our own message */ GST_DEBUG_OBJECT (bin, "dropping message %" GST_PTR_FORMAT, message); gst_message_unref (message); message = NULL; break; } case GST_MESSAGE_EOS:{ sink->playlist->end_list = TRUE; gst_hls_sink_write_playlist (sink); break; } default: break; } if (message) GST_BIN_CLASS (parent_class)->handle_message (bin, message); }
// get spectrum messages and delay them static gboolean on_message(GstBus *bus, GstMessage *message, gpointer data) { base *base_object = data; GstElement *spectrum = GST_ELEMENT(base_object->spectrum_element->obj); gst_object_ref(spectrum); GstElement *message_element = GST_ELEMENT(GST_MESSAGE_SRC(message)); gst_object_ref(message_element); if (message_element == spectrum) { GstClockTime waittime = GST_CLOCK_TIME_NONE; const GstStructure *message_structure = gst_message_get_structure(message); // determine waittime GstClockTime timestamp, duration; if ( gst_structure_get_clock_time(message_structure, "running-time", ×tamp) && gst_structure_get_clock_time(message_structure, "duration", &duration) ) { /* wait for middle of buffer */ waittime = timestamp + duration/2; } else if (gst_structure_get_clock_time(message_structure, "endtime", ×tamp)) { waittime = timestamp; } // delay message if (GST_CLOCK_TIME_IS_VALID(waittime)) { GstClockTime basetime = gst_element_get_base_time(spectrum); GstClockID clock_id = gst_clock_new_single_shot_id(base_object->sync_clock, basetime+waittime); spectrum_message *mess = g_malloc(sizeof(spectrum_message)); // set bands and threshold g_object_get(message_element, "bands", &(mess->bands), "threshold", &(mess->threshold), NULL); // set start and duration GstClockTime streamtime, duration; gst_structure_get_clock_time(message_structure, "stream-time", &streamtime); gst_structure_get_clock_time(message_structure, "duration", &duration); mess->start = (gfloat)streamtime / GST_SECOND; mess->duration = (gfloat)duration / GST_SECOND; // set rate GstPad *sink = gst_element_get_static_pad(GST_ELEMENT(base_object->spectrum_element->obj), "sink"); GstCaps *caps = gst_pad_get_negotiated_caps(sink); gst_object_unref(sink); GstStructure *caps_structure = gst_caps_get_structure(caps, 0); gst_structure_get_int(caps_structure, "rate", &(mess->rate)); gst_caps_unref(caps); // set magnitudes const GValue *list = gst_structure_get_value(message_structure, "magnitude"); PyGILState_STATE gstate = PyGILState_Ensure(); int i; mess->magnitudes = PyList_New(mess->bands); for (i=0; i < (mess->bands); i++) { const GValue *value = gst_value_list_get_value(list, i); gfloat f = g_value_get_float(value); PyList_SetItem(mess->magnitudes, i, Py_BuildValue("f", f)); } PyGILState_Release(gstate); // set gobj GObject *gobj = (base_object->gobj).obj; g_assert(gobj != NULL); g_object_ref(gobj); mess->gobj = gobj; // delay message gst_clock_id_wait_async(clock_id, delayed_spectrum_update, mess); gst_clock_id_unref(clock_id); } } gst_object_unref(spectrum); gst_object_unref(message_element); return TRUE; }