void gst_audio_fx_base_fir_filter_set_kernel (GstAudioFXBaseFIRFilter * self, gdouble * kernel, guint kernel_length, guint64 latency, const GstAudioInfo * info) { gboolean latency_changed; GstAudioFormat format; gint channels; g_return_if_fail (kernel != NULL); g_return_if_fail (self != NULL); g_mutex_lock (&self->lock); latency_changed = (self->latency != latency || (!self->low_latency && self->kernel_length < FFT_THRESHOLD && kernel_length >= FFT_THRESHOLD) || (!self->low_latency && self->kernel_length >= FFT_THRESHOLD && kernel_length < FFT_THRESHOLD)); /* FIXME: If the latency changes, the buffer size changes too and we * have to drain in any case until this is fixed in the future */ if (self->buffer && (!self->drain_on_changes || latency_changed)) { gst_audio_fx_base_fir_filter_push_residue (self); self->start_ts = GST_CLOCK_TIME_NONE; self->start_off = GST_BUFFER_OFFSET_NONE; self->nsamples_out = 0; self->nsamples_in = 0; self->buffer_fill = 0; } g_free (self->kernel); if (!self->drain_on_changes || latency_changed) { g_free (self->buffer); self->buffer = NULL; self->buffer_fill = 0; self->buffer_length = 0; } self->kernel = kernel; self->kernel_length = kernel_length; if (info) { format = GST_AUDIO_INFO_FORMAT (info); channels = GST_AUDIO_INFO_CHANNELS (info); } else { format = GST_AUDIO_FILTER_FORMAT (self); channels = GST_AUDIO_FILTER_CHANNELS (self); } gst_audio_fx_base_fir_filter_calculate_frequency_response (self); gst_audio_fx_base_fir_filter_select_process_function (self, format, channels); if (latency_changed) { self->latency = latency; gst_element_post_message (GST_ELEMENT (self), gst_message_new_latency (GST_OBJECT (self))); } g_mutex_unlock (&self->lock); }
static GstFlowReturn gst_amc_audio_dec_drain (GstAmcAudioDec * self) { GstFlowReturn ret; gint idx; GST_DEBUG_OBJECT (self, "Draining codec"); if (!self->started) { GST_DEBUG_OBJECT (self, "Codec not started yet"); return GST_FLOW_OK; } /* Don't send EOS buffer twice, this doesn't work */ if (self->eos) { GST_DEBUG_OBJECT (self, "Codec is EOS already"); return GST_FLOW_OK; } /* Make sure to release the base class stream lock, otherwise * _loop() can't call _finish_frame() and we might block forever * because no input buffers are released */ GST_AUDIO_DECODER_STREAM_UNLOCK (self); /* Send an EOS buffer to the component and let the base * class drop the EOS event. We will send it later when * the EOS buffer arrives on the output port. * Wait at most 0.5s here. */ idx = gst_amc_codec_dequeue_input_buffer (self->codec, 500000); GST_AUDIO_DECODER_STREAM_LOCK (self); if (idx >= 0 && idx < self->n_input_buffers) { GstAmcBufferInfo buffer_info; GST_AUDIO_DECODER_STREAM_UNLOCK (self); g_mutex_lock (&self->drain_lock); self->draining = TRUE; memset (&buffer_info, 0, sizeof (buffer_info)); buffer_info.size = 0; buffer_info.presentation_time_us = gst_util_uint64_scale (self->last_upstream_ts, 1, GST_USECOND); buffer_info.flags |= BUFFER_FLAG_END_OF_STREAM; if (gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info)) { GST_DEBUG_OBJECT (self, "Waiting until codec is drained"); g_cond_wait (&self->drain_cond, &self->drain_lock); GST_DEBUG_OBJECT (self, "Drained codec"); ret = GST_FLOW_OK; } else { GST_ERROR_OBJECT (self, "Failed to queue input buffer"); ret = GST_FLOW_ERROR; } g_mutex_unlock (&self->drain_lock); GST_AUDIO_DECODER_STREAM_LOCK (self); } else if (idx >= self->n_input_buffers) { GST_ERROR_OBJECT (self, "Invalid input buffer index %d of %d", idx, self->n_input_buffers); ret = GST_FLOW_ERROR; } else { GST_ERROR_OBJECT (self, "Failed to acquire buffer for EOS: %d", idx); ret = GST_FLOW_ERROR; } return ret; }
/** * gvir_storage_pool_refresh: * @pool: the storage pool * @cancellable: (allow-none)(transfer none): cancellation object */ gboolean gvir_storage_pool_refresh(GVirStoragePool *pool, GCancellable *cancellable, GError **err) { GVirStoragePoolPrivate *priv; GHashTable *vol_hash; gchar **volumes = NULL; gint nvolumes = 0; gboolean ret = FALSE; gint i; virStoragePoolPtr vpool = NULL; GError *lerr = NULL; g_return_val_if_fail(GVIR_IS_STORAGE_POOL(pool), FALSE); g_return_val_if_fail((cancellable == NULL) || G_IS_CANCELLABLE(cancellable), FALSE); g_return_val_if_fail(err == NULL || *err == NULL, FALSE); priv = pool->priv; vpool = priv->handle; if (virStoragePoolRefresh(vpool, 0) < 0) { gvir_set_error_literal(err, GVIR_STORAGE_POOL_ERROR, 0, "Unable to refresh storage pool"); goto cleanup; } volumes = fetch_list(vpool, "Storage Volumes", virStoragePoolNumOfVolumes, virStoragePoolListVolumes, cancellable, &nvolumes, &lerr); if (lerr) { g_propagate_error(err, lerr); lerr = NULL; goto cleanup; } if (g_cancellable_set_error_if_cancelled(cancellable, err)) goto cleanup; vol_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_object_unref); for (i = 0 ; i < nvolumes ; i++) { if (g_cancellable_set_error_if_cancelled(cancellable, err)) goto cleanup; virStorageVolPtr vvolume; GVirStorageVol *volume; vvolume = virStorageVolLookupByName(vpool, volumes[i]); if (!vvolume) continue; volume = GVIR_STORAGE_VOL(g_object_new(GVIR_TYPE_STORAGE_VOL, "handle", vvolume, "pool", pool, NULL)); g_hash_table_insert(vol_hash, g_strdup(volumes[i]), volume); } g_mutex_lock(priv->lock); if (priv->volumes) g_hash_table_unref(priv->volumes); priv->volumes = vol_hash; g_mutex_unlock(priv->lock); ret = TRUE; cleanup: for (i = 0 ; i < nvolumes ; i++) g_free(volumes[i]); g_free(volumes); return ret; }
static gpointer brasero_burn_uri_thread (gpointer data) { BraseroBurnURI *self = BRASERO_BURN_URI (data); BraseroTrack *current = NULL; BraseroBurnURIPrivate *priv; BraseroTrackData *track; GSList *excluded = NULL; GSList *grafts = NULL; guint64 num = 0; GSList *src; priv = BRASERO_BURN_URI_PRIVATE (self); brasero_job_set_current_action (BRASERO_JOB (self), BRASERO_BURN_ACTION_FILE_COPY, _("Copying files locally"), TRUE); brasero_job_get_current_track (BRASERO_JOB (self), ¤t); /* This is for IMAGE tracks */ if (BRASERO_IS_TRACK_IMAGE (current)) { gchar *uri; gchar *path_toc; gchar *path_image; goffset blocks = 0; BraseroTrackImage *image; path_image = NULL; uri = brasero_track_image_get_source (BRASERO_TRACK_IMAGE (current), TRUE); if (!brasero_burn_uri_retrieve_path (self, uri, &path_image)) { g_free (uri); goto end; } g_free (uri); path_toc = NULL; uri = brasero_track_image_get_toc_source (BRASERO_TRACK_IMAGE (current), TRUE); if (uri) { /* NOTE: if it's a .bin image there is not .toc file */ if (!brasero_burn_uri_retrieve_path (self, uri, &path_toc)) { g_free (path_image); g_free (uri); goto end; } g_free (uri); } brasero_track_get_size (current, &blocks, NULL); image = brasero_track_image_new (); brasero_track_tag_copy_missing (BRASERO_TRACK (image), current); brasero_track_image_set_source (image, path_image, path_toc, brasero_track_image_get_format (BRASERO_TRACK_IMAGE (current))); brasero_track_image_set_block_num (image, blocks); priv->track = BRASERO_TRACK (image); g_free (path_toc); g_free (path_image); goto end; } /* This is for DATA tracks */ for (src = brasero_track_data_get_grafts (BRASERO_TRACK_DATA (current)); src; src = src->next) { GFile *file; GFileInfo *info; BraseroGraftPt *graft; graft = src->data; if (!graft->uri) { grafts = g_slist_prepend (grafts, brasero_graft_point_copy (graft)); continue; } if (!g_str_has_prefix (graft->uri, "burn://")) { grafts = g_slist_prepend (grafts, brasero_graft_point_copy (graft)); continue; } BRASERO_JOB_LOG (self, "Information retrieval for %s", graft->uri); file = g_file_new_for_uri (graft->uri); info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_NAME "," G_FILE_ATTRIBUTE_STANDARD_TYPE "," "burn::backing-file", G_FILE_QUERY_INFO_NONE, priv->cancel, &priv->error); if (priv->error) { g_object_unref (file); goto end; } if (g_cancellable_is_cancelled (priv->cancel)) { g_object_unref (file); goto end; } if (!info) { /* Error */ g_object_unref (file); g_object_unref (info); goto end; } /* See if we were passed the burn:/// uri itself (the root). * Then skip graft point addition */ if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) { if (g_file_info_get_name (info) && strcmp (g_file_info_get_name (info), "/")) { BraseroGraftPt *newgraft; /* we need a dummy directory */ newgraft = g_new0 (BraseroGraftPt, 1); newgraft->uri = NULL; newgraft->path = g_strdup (graft->path); grafts = g_slist_prepend (grafts, newgraft); BRASERO_JOB_LOG (self, "Adding directory %s at %s", newgraft->uri, newgraft->path); grafts = brasero_burn_uri_explore_directory (self, grafts, file, newgraft->path, priv->cancel, &priv->error); } else { BRASERO_JOB_LOG (self, "Directory is root"); grafts = brasero_burn_uri_explore_directory (self, grafts, file, "/", priv->cancel, &priv->error); } if (!grafts) { g_object_unref (info); g_object_unref (file); goto end; } } else if (g_file_info_get_file_type (info) == G_FILE_TYPE_REGULAR /* NOTE: burn:// URI allows symlink */ || g_file_info_get_file_type (info) == G_FILE_TYPE_SYMBOLIC_LINK) { const gchar *real_path; BraseroGraftPt *newgraft; real_path = g_file_info_get_attribute_byte_string (info, "burn::backing-file"); if (!real_path) { priv->error = g_error_new (BRASERO_BURN_ERROR, BRASERO_BURN_ERROR_GENERAL, _("Impossible to retrieve local file path")); g_slist_foreach (grafts, (GFunc) brasero_graft_point_free, NULL); g_slist_free (grafts); g_object_unref (info); g_object_unref (file); goto end; } newgraft = brasero_graft_point_copy (graft); g_free (newgraft->uri); newgraft->uri = g_strdup (real_path); /* FIXME: maybe one day, graft->uri will always be an URI */ /* newgraft->uri = g_filename_to_uri (real_path, NULL, NULL); */ BRASERO_JOB_LOG (self, "Added file %s at %s", newgraft->uri, newgraft->path); grafts = g_slist_prepend (grafts, newgraft); } g_object_unref (info); g_object_unref (file); } grafts = g_slist_reverse (grafts); /* remove all excluded starting by burn:// from the list */ for (src = brasero_track_data_get_excluded_list (BRASERO_TRACK_DATA (current)); src; src = src->next) { gchar *uri; uri = src->data; if (uri && g_str_has_prefix (uri, "burn://")) continue; uri = g_strdup (uri); excluded = g_slist_prepend (excluded, uri); BRASERO_JOB_LOG (self, "Added excluded file %s", uri); } excluded = g_slist_reverse (excluded); track = brasero_track_data_new (); brasero_track_tag_copy_missing (BRASERO_TRACK (track), current); brasero_track_data_add_fs (track, brasero_track_data_get_fs (BRASERO_TRACK_DATA (current))); brasero_track_data_get_file_num (BRASERO_TRACK_DATA (current), &num); brasero_track_data_set_file_num (track, num); brasero_track_data_set_source (track, grafts, excluded); priv->track = BRASERO_TRACK (track); end: if (!g_cancellable_is_cancelled (priv->cancel)) priv->thread_id = g_idle_add ((GSourceFunc) brasero_burn_uri_thread_finished, self); /* End thread */ g_mutex_lock (priv->mutex); g_atomic_pointer_set (&priv->thread, NULL); g_cond_signal (priv->cond); g_mutex_unlock (priv->mutex); g_thread_exit (NULL); return NULL; }
int network_backends_save_to_config(network_backends_t *bs, gchar* config_path) { int i, len, file_size = 0, first_append_master = 1, first_append_slave = 1, first_append_standby = 1; GKeyFile* keyfile; network_backend_t *backend; GString *master, *slave, *standby; GError *gerr = NULL; gchar* file_buf = NULL; master = g_string_new(NULL); slave = g_string_new(NULL); standby = g_string_new(NULL); keyfile = g_key_file_new(); g_key_file_set_list_separator(keyfile, ','); if (FALSE == g_key_file_load_from_file(keyfile, config_path, G_KEY_FILE_NONE, NULL)) { g_message("%s:load %s error,load config file failed", G_STRLOC, config_path); g_string_free(master, TRUE); g_string_free(slave, TRUE); g_string_free(standby, TRUE); g_key_file_free(keyfile); return -1; } g_mutex_lock(bs->backends_mutex); len = bs->backends->len; for (i = 0; i < len; i++) { backend = g_ptr_array_index(bs->backends, i); if (backend->type == BACKEND_TYPE_RW) { if (first_append_master) { g_string_append(master, backend->addr->name->str); first_append_master = 0; } else { g_string_append_c(master, ','); g_string_append(master, backend->addr->name->str); } } else if (backend->type == BACKEND_TYPE_RO) { if (first_append_slave) { g_string_append(slave, backend->addr->name->str); first_append_slave = 0; } else { g_string_append_c(slave, ','); g_string_append(slave, backend->addr->name->str); } } else if (backend->type == BACKEND_TYPE_SY) { if (first_append_standby) { g_string_append(standby, backend->addr->name->str); first_append_standby = 0; } else { g_string_append_c(standby, ','); g_string_append(standby, backend->addr->name->str); } } } g_mutex_unlock(bs->backends_mutex); if (master->len != 0) g_key_file_set_string(keyfile, "mysql-proxy", "proxy-backend-addresses", master->str); else g_key_file_set_string(keyfile, "mysql-proxy", "proxy-backend-addresses", ""); if (slave->len != 0) g_key_file_set_string(keyfile, "mysql-proxy", "proxy-read-only-backend-addresses", slave->str); else g_key_file_set_string(keyfile, "mysql-proxy", "proxy-read-only-backend-addresses", ""); if (standby->len != 0) g_key_file_set_string(keyfile, "mysql-proxy", "proxy-master-standby-address", standby->str); else g_key_file_set_string(keyfile, "mysql-proxy", "proxy-master-standby-address", ""); file_buf = g_key_file_to_data(keyfile, &file_size, &gerr); if (file_buf) { if (FALSE == g_file_set_contents(config_path, file_buf, file_size, &gerr)) { g_message("%s:g_file_set_contents, gerr is:%s", G_STRLOC, gerr->message); g_error_free(gerr); gerr = NULL; g_message("%s:save to config failure", G_STRLOC); } else { g_message("%s:save to config success", G_STRLOC); } g_free(file_buf); } else { g_message("%s:save to config failure", G_STRLOC); } g_string_free(master, TRUE); g_string_free(slave, TRUE); g_string_free(standby, TRUE); g_key_file_free(keyfile); return 0; }
/* always call with stream lock */ static GstFlowReturn gst_droidadec_finish (GstAudioDecoder * decoder) { GstDroidADec *dec = GST_DROIDADEC (decoder); gint available; GST_DEBUG_OBJECT (dec, "finish"); if (!dec->running) { GST_DEBUG_OBJECT (dec, "decoder is not running"); goto finish; } g_mutex_lock (&dec->eos_lock); dec->eos = TRUE; if (dec->codec) { droid_media_codec_drain (dec->codec); } else { goto out; } /* release the lock to allow _data_available () to do its job */ GST_AUDIO_DECODER_STREAM_UNLOCK (decoder); /* Now we wait for the codec to signal EOS */ g_cond_wait (&dec->eos_cond, &dec->eos_lock); GST_AUDIO_DECODER_STREAM_LOCK (decoder); finish: /* We drained the codec. Better to recreate it. */ if (dec->codec) { droid_media_codec_stop (dec->codec); droid_media_codec_destroy (dec->codec); dec->codec = NULL; } if (dec->spf != -1) { available = gst_adapter_available (dec->adapter); if (available > 0) { gint size = dec->spf * dec->info->bpf; gint nframes = available / size; GstBuffer *out; GstFlowReturn ret G_GNUC_UNUSED; GST_INFO_OBJECT (dec, "pushing remaining %d bytes", available); if (nframes > 0) { out = gst_adapter_take_buffer (dec->adapter, nframes * size); available -= (nframes * size); } else { out = gst_adapter_take_buffer (dec->adapter, available); nframes = 1; available = 0; } ret = gst_audio_decoder_finish_frame (decoder, out, nframes); GST_INFO_OBJECT (dec, "pushed %d frames. flow return: %s", nframes, gst_flow_get_name (ret)); if (available > 0) { GST_ERROR_OBJECT (dec, "%d bytes remaining", available); } } } dec->dirty = TRUE; out: dec->eos = FALSE; g_mutex_unlock (&dec->eos_lock); return GST_FLOW_OK; }
void rm_trie_iter(RmTrie *self, RmNode *root, bool pre_order, bool all_nodes, RmTrieIterCallback callback, void *user_data) { g_mutex_lock(&self->lock); _rm_trie_iter(self, root, pre_order, all_nodes, callback, user_data, 0); g_mutex_unlock(&self->lock); }
static GstFlowReturn gst_spectrum_transform_ip (GstBaseTransform * trans, GstBuffer * buffer) { GstSpectrum *spectrum = GST_SPECTRUM (trans); guint rate = GST_AUDIO_FILTER_RATE (spectrum); guint channels = GST_AUDIO_FILTER_CHANNELS (spectrum); guint bps = GST_AUDIO_FILTER_BPS (spectrum); guint bpf = GST_AUDIO_FILTER_BPF (spectrum); guint output_channels = spectrum->multi_channel ? channels : 1; guint c; gfloat max_value = (1UL << ((bps << 3) - 1)) - 1; guint bands = spectrum->bands; guint nfft = 2 * bands - 2; guint input_pos; gfloat *input; GstMapInfo map; const guint8 *data; gsize size; guint fft_todo, msg_todo, block_size; gboolean have_full_interval; GstSpectrumChannel *cd; GstSpectrumInputData input_data; g_mutex_lock (&spectrum->lock); gst_buffer_map (buffer, &map, GST_MAP_READ); data = map.data; size = map.size; GST_LOG_OBJECT (spectrum, "input size: %" G_GSIZE_FORMAT " bytes", size); if (GST_BUFFER_IS_DISCONT (buffer)) { GST_DEBUG_OBJECT (spectrum, "Discontinuity detected -- flushing"); gst_spectrum_flush (spectrum); } /* If we don't have a FFT context yet (or it was reset due to parameter * changes) get one and allocate memory for everything */ if (spectrum->channel_data == NULL) { GST_DEBUG_OBJECT (spectrum, "allocating for bands %u", bands); gst_spectrum_alloc_channel_data (spectrum); /* number of sample frames we process before posting a message * interval is in ns */ spectrum->frames_per_interval = gst_util_uint64_scale (spectrum->interval, rate, GST_SECOND); spectrum->frames_todo = spectrum->frames_per_interval; /* rounding error for frames_per_interval in ns, * aggregated it in accumulated_error */ spectrum->error_per_interval = (spectrum->interval * rate) % GST_SECOND; if (spectrum->frames_per_interval == 0) spectrum->frames_per_interval = 1; GST_INFO_OBJECT (spectrum, "interval %" GST_TIME_FORMAT ", fpi %" G_GUINT64_FORMAT ", error %" GST_TIME_FORMAT, GST_TIME_ARGS (spectrum->interval), spectrum->frames_per_interval, GST_TIME_ARGS (spectrum->error_per_interval)); spectrum->input_pos = 0; gst_spectrum_flush (spectrum); } if (spectrum->num_frames == 0) spectrum->message_ts = GST_BUFFER_TIMESTAMP (buffer); input_pos = spectrum->input_pos; input_data = spectrum->input_data; while (size >= bpf) { /* run input_data for a chunk of data */ fft_todo = nfft - (spectrum->num_frames % nfft); msg_todo = spectrum->frames_todo - spectrum->num_frames; GST_LOG_OBJECT (spectrum, "message frames todo: %u, fft frames todo: %u, input frames %" G_GSIZE_FORMAT, msg_todo, fft_todo, (size / bpf)); block_size = msg_todo; if (block_size > (size / bpf)) block_size = (size / bpf); if (block_size > fft_todo) block_size = fft_todo; for (c = 0; c < output_channels; c++) { cd = &spectrum->channel_data[c]; input = cd->input; /* Move the current frames into our ringbuffers */ input_data (data + c * bps, input, block_size, channels, max_value, input_pos, nfft); } data += block_size * bpf; size -= block_size * bpf; input_pos = (input_pos + block_size) % nfft; spectrum->num_frames += block_size; have_full_interval = (spectrum->num_frames == spectrum->frames_todo); GST_LOG_OBJECT (spectrum, "size: %" G_GSIZE_FORMAT ", do-fft = %d, do-message = %d", size, (spectrum->num_frames % nfft == 0), have_full_interval); /* If we have enough frames for an FFT or we have all frames required for * the interval and we haven't run a FFT, then run an FFT */ if ((spectrum->num_frames % nfft == 0) || (have_full_interval && !spectrum->num_fft)) { for (c = 0; c < output_channels; c++) { cd = &spectrum->channel_data[c]; gst_spectrum_run_fft (spectrum, cd, input_pos); } spectrum->num_fft++; } /* Do we have the FFTs for one interval? */ if (have_full_interval) { GST_DEBUG_OBJECT (spectrum, "nfft: %u frames: %" G_GUINT64_FORMAT " fpi: %" G_GUINT64_FORMAT " error: %" GST_TIME_FORMAT, nfft, spectrum->num_frames, spectrum->frames_per_interval, GST_TIME_ARGS (spectrum->accumulated_error)); spectrum->frames_todo = spectrum->frames_per_interval; if (spectrum->accumulated_error >= GST_SECOND) { spectrum->accumulated_error -= GST_SECOND; spectrum->frames_todo++; } spectrum->accumulated_error += spectrum->error_per_interval; if (spectrum->post_messages) { GstMessage *m; for (c = 0; c < output_channels; c++) { cd = &spectrum->channel_data[c]; gst_spectrum_prepare_message_data (spectrum, cd); } m = gst_spectrum_message_new (spectrum, spectrum->message_ts, spectrum->interval); gst_element_post_message (GST_ELEMENT (spectrum), m); } if (GST_CLOCK_TIME_IS_VALID (spectrum->message_ts)) spectrum->message_ts += gst_util_uint64_scale (spectrum->num_frames, GST_SECOND, rate); for (c = 0; c < output_channels; c++) { cd = &spectrum->channel_data[c]; gst_spectrum_reset_message_data (spectrum, cd); } spectrum->num_frames = 0; spectrum->num_fft = 0; } } spectrum->input_pos = input_pos; gst_buffer_unmap (buffer, &map); g_mutex_unlock (&spectrum->lock); g_assert (size == 0); return GST_FLOW_OK; }
/** * gst_bus_post: * @bus: a #GstBus to post on * @message: (transfer full): the #GstMessage to post * * Post a message on the given bus. Ownership of the message * is taken by the bus. * * Returns: %TRUE if the message could be posted, %FALSE if the bus is flushing. * * MT safe. */ gboolean gst_bus_post (GstBus * bus, GstMessage * message) { GstBusSyncReply reply = GST_BUS_PASS; GstBusSyncHandler handler; gboolean emit_sync_message; gpointer handler_data; g_return_val_if_fail (GST_IS_BUS (bus), FALSE); g_return_val_if_fail (GST_IS_MESSAGE (message), FALSE); GST_DEBUG_OBJECT (bus, "[msg %p] posting on bus %" GST_PTR_FORMAT, message, message); /* check we didn't accidentally add a public flag that maps to same value */ g_assert (!GST_MINI_OBJECT_FLAG_IS_SET (message, GST_MESSAGE_FLAG_ASYNC_DELIVERY)); GST_OBJECT_LOCK (bus); /* check if the bus is flushing */ if (GST_OBJECT_FLAG_IS_SET (bus, GST_BUS_FLUSHING)) goto is_flushing; handler = bus->priv->sync_handler; handler_data = bus->priv->sync_handler_data; emit_sync_message = bus->priv->num_sync_message_emitters > 0; GST_OBJECT_UNLOCK (bus); /* first call the sync handler if it is installed */ if (handler) reply = handler (bus, message, handler_data); /* emit sync-message if requested to do so via gst_bus_enable_sync_message_emission. terrible but effective */ if (emit_sync_message && reply != GST_BUS_DROP && handler != gst_bus_sync_signal_handler) gst_bus_sync_signal_handler (bus, message, NULL); /* If this is a bus without async message delivery * always drop the message */ if (!bus->priv->poll) reply = GST_BUS_DROP; /* now see what we should do with the message */ switch (reply) { case GST_BUS_DROP: /* drop the message */ GST_DEBUG_OBJECT (bus, "[msg %p] dropped", message); break; case GST_BUS_PASS: /* pass the message to the async queue, refcount passed in the queue */ GST_DEBUG_OBJECT (bus, "[msg %p] pushing on async queue", message); gst_atomic_queue_push (bus->priv->queue, message); gst_poll_write_control (bus->priv->poll); GST_DEBUG_OBJECT (bus, "[msg %p] pushed on async queue", message); break; case GST_BUS_ASYNC: { /* async delivery, we need a mutex and a cond to block * on */ GCond *cond = GST_MESSAGE_GET_COND (message); GMutex *lock = GST_MESSAGE_GET_LOCK (message); g_cond_init (cond); g_mutex_init (lock); GST_MINI_OBJECT_FLAG_SET (message, GST_MESSAGE_FLAG_ASYNC_DELIVERY); GST_DEBUG_OBJECT (bus, "[msg %p] waiting for async delivery", message); /* now we lock the message mutex, send the message to the async * queue. When the message is handled by the app and destroyed, * the cond will be signalled and we can continue */ g_mutex_lock (lock); gst_atomic_queue_push (bus->priv->queue, message); gst_poll_write_control (bus->priv->poll); /* now block till the message is freed */ g_cond_wait (cond, lock); /* we acquired a new ref from gst_message_dispose() so we can clean up */ g_mutex_unlock (lock); GST_DEBUG_OBJECT (bus, "[msg %p] delivered asynchronously", message); GST_MINI_OBJECT_FLAG_UNSET (message, GST_MESSAGE_FLAG_ASYNC_DELIVERY); g_mutex_clear (lock); g_cond_clear (cond); gst_message_unref (message); break; } default: g_warning ("invalid return from bus sync handler"); break; } return TRUE; /* ERRORS */ is_flushing: { GST_DEBUG_OBJECT (bus, "bus is flushing"); GST_OBJECT_UNLOCK (bus); gst_message_unref (message); return FALSE; } }
static gboolean interpolate_trigger_get_value_array (GstTimedValueControlSource * self, GstClockTime timestamp, GstClockTime interval, guint n_values, gdouble * values) { gboolean ret = FALSE; guint i; GstClockTime ts = timestamp; GstClockTime next_ts = 0; gdouble val; GSequenceIter *iter1 = NULL, *iter2 = NULL; gboolean triggered = FALSE; g_mutex_lock (&self->lock); for (i = 0; i < n_values; i++) { val = NAN; if (ts >= next_ts) { iter1 = gst_timed_value_control_source_find_control_point_iter (self, ts); if (!iter1) { if (G_LIKELY (self->values)) iter2 = g_sequence_get_begin_iter (self->values); else iter2 = NULL; } else { iter2 = g_sequence_iter_next (iter1); } if (iter2 && !g_sequence_iter_is_end (iter2)) { GstControlPoint *cp; cp = g_sequence_get (iter2); next_ts = cp->timestamp; } else { next_ts = GST_CLOCK_TIME_NONE; } if (iter1) { val = _interpolate_trigger (self, iter1, ts); if (!isnan (val)) ret = TRUE; } else { g_mutex_unlock (&self->lock); return FALSE; } triggered = TRUE; } else if (triggered) { if (iter1) { val = _interpolate_trigger (self, iter1, ts); if (!isnan (val)) ret = TRUE; } else { g_mutex_unlock (&self->lock); return FALSE; } triggered = FALSE; } *values = val; ts += interval; values++; } g_mutex_unlock (&self->lock); return ret; }
static void gst_lfo_control_source_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstLFOControlSource *self = GST_LFO_CONTROL_SOURCE (object); switch (prop_id) { case PROP_WAVEFORM: g_mutex_lock (self->lock); gst_lfo_control_source_set_waveform (self, g_value_get_enum (value)); g_mutex_unlock (self->lock); break; case PROP_FREQUENCY:{ gdouble frequency = g_value_get_double (value); g_return_if_fail (frequency > 0 || ((GstClockTime) (GST_SECOND / frequency)) != 0); g_mutex_lock (self->lock); self->priv->frequency = frequency; self->priv->period = GST_SECOND / frequency; g_mutex_unlock (self->lock); break; } case PROP_TIMESHIFT: g_mutex_lock (self->lock); self->priv->timeshift = g_value_get_uint64 (value); g_mutex_unlock (self->lock); break; case PROP_AMPLITUDE:{ GValue *val = g_value_get_boxed (value); if (self->priv->type != G_TYPE_INVALID) { g_return_if_fail (g_value_type_transformable (self->priv->type, G_VALUE_TYPE (val))); g_mutex_lock (self->lock); if (G_IS_VALUE (&self->priv->amplitude)) g_value_unset (&self->priv->amplitude); g_value_init (&self->priv->amplitude, self->priv->type); g_value_transform (val, &self->priv->amplitude); g_mutex_unlock (self->lock); } else { g_mutex_lock (self->lock); if (G_IS_VALUE (&self->priv->amplitude)) g_value_unset (&self->priv->amplitude); g_value_init (&self->priv->amplitude, G_VALUE_TYPE (val)); g_value_copy (val, &self->priv->amplitude); g_mutex_unlock (self->lock); } break; } case PROP_OFFSET:{ GValue *val = g_value_get_boxed (value); if (self->priv->type != G_TYPE_INVALID) { g_return_if_fail (g_value_type_transformable (self->priv->type, G_VALUE_TYPE (val))); g_mutex_lock (self->lock); if (G_IS_VALUE (&self->priv->offset)) g_value_unset (&self->priv->offset); g_value_init (&self->priv->offset, self->priv->type); g_value_transform (val, &self->priv->offset); g_mutex_unlock (self->lock); } else { g_mutex_lock (self->lock); if (G_IS_VALUE (&self->priv->offset)) g_value_unset (&self->priv->offset); g_value_init (&self->priv->offset, G_VALUE_TYPE (val)); g_value_copy (val, &self->priv->offset); g_mutex_unlock (self->lock); } break; } default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static void angel_connection_io_cb(liEventBase *watcher, int events) { liAngelConnection *acon = LI_CONTAINER_OF(li_event_io_from(watcher), liAngelConnection, fd_watcher); if (events | LI_EV_WRITE) { GString *out_str; int i; ssize_t written, len; gchar *data; gboolean out_queue_empty; angel_connection_send_item_t *send_item; int fd = li_event_io_fd(&acon->fd_watcher); g_mutex_lock(acon->mutex); send_item = g_queue_peek_head(acon->out); g_mutex_unlock(acon->mutex); for (i = 0; send_item && (i < 10); i++) { /* don't send more than 10 chunks */ switch (send_item->type) { case ANGEL_CONNECTION_ITEM_GSTRING: out_str = send_item->value.string.buf; written = send_item->value.string.pos; data = out_str->str + written; len = out_str->len - written; while (len > 0) { written = write(fd, data, len); if (written < 0) { switch (errno) { case EINTR: continue; case EAGAIN: #if EWOULDBLOCK != EAGAIN case EWOULDBLOCK: #endif goto write_eagain; default: /* Fatal error, connection has to be closed */ li_event_clear(&acon->out_notify_watcher); li_event_clear(&acon->fd_watcher); acon->close_cb(acon, NULL); /* TODO: set err */ return; } } else { data += written; len -= written; send_item->value.string.pos += written; } } break; case ANGEL_CONNECTION_ITEM_FDS: while (send_item->value.fds.pos < send_item->value.fds.fds->len) { switch (li_send_fd(fd, g_array_index(send_item->value.fds.fds, int, send_item->value.fds.pos))) { case 0: send_item->value.fds.pos++; continue; case -1: /* Fatal error, connection has to be closed */ li_event_clear(&acon->out_notify_watcher); li_event_clear(&acon->fd_watcher); acon->close_cb(acon, NULL); /* TODO: set err */ return; case -2: goto write_eagain; } } break; } g_mutex_lock(acon->mutex); send_queue_clean(acon->out); send_item = g_queue_peek_head(acon->out); g_mutex_unlock(acon->mutex); } write_eagain: g_mutex_lock(acon->mutex); send_queue_clean(acon->out); out_queue_empty = (0 == acon->out->length); g_mutex_unlock(acon->mutex); if (out_queue_empty) li_event_io_rem_events(&acon->fd_watcher, LI_EV_WRITE); }
static gboolean angel_dispatch(liAngelConnection *acon, GError **err) { gint32 id = acon->parse.id, type = acon->parse.type; liAngelCall *call; switch (type) { case ANGEL_CALL_SEND_SIMPLE: if (-1 != id) { g_set_error(err, LI_ANGEL_CONNECTION_ERROR, LI_ANGEL_CONNECTION_INVALID_DATA, "Invalid id: %i, should be -1 for simple call", (gint) id); close_fd_array(acon->parse.fds); return FALSE; } if (acon->parse.error->len > 0 || acon->parse.fds->len > 0) { g_set_error(err, LI_ANGEL_CONNECTION_ERROR, LI_ANGEL_CONNECTION_INVALID_DATA, "Wrong data in call"); close_fd_array(acon->parse.fds); return FALSE; } acon->recv_call(acon, GSTR_LEN(acon->parse.mod), GSTR_LEN(acon->parse.action), id, acon->parse.data); break; case ANGEL_CALL_SEND_CALL: if (-1 == id) { g_set_error(err, LI_ANGEL_CONNECTION_ERROR, LI_ANGEL_CONNECTION_INVALID_DATA, "Invalid id: -1, should be >= 0 for call"); close_fd_array(acon->parse.fds); return FALSE; } if (acon->parse.error->len > 0 || acon->parse.fds->len > 0) { g_set_error(err, LI_ANGEL_CONNECTION_ERROR, LI_ANGEL_CONNECTION_INVALID_DATA, "Wrong data in call"); close_fd_array(acon->parse.fds); return FALSE; } acon->recv_call(acon, GSTR_LEN(acon->parse.mod), GSTR_LEN(acon->parse.action), id, acon->parse.data); break; case ANGEL_CALL_SEND_RESULT: g_mutex_lock(acon->mutex); if (!li_idlist_is_used(acon->call_id_list, id)) { g_mutex_unlock(acon->mutex); g_set_error(err, LI_ANGEL_CONNECTION_ERROR, LI_ANGEL_CONNECTION_INVALID_DATA, "Invalid id: %i", (gint) id); close_fd_array(acon->parse.fds); return FALSE; } li_idlist_put(acon->call_id_list, id); call = NULL; if ((guint) id < acon->call_table->len) { call = (liAngelCall*) g_ptr_array_index(acon->call_table, id); g_ptr_array_index(acon->call_table, id) = NULL; } if (NULL != call) { call->id = -1; call->result.error = acon->parse.error; call->result.data = acon->parse.data; call->result.fds = acon->parse.fds; acon->parse.error = g_string_sized_new(0); acon->parse.data = g_string_sized_new(0); acon->parse.fds = g_array_new(FALSE, FALSE, sizeof(int)); li_event_async_send(&call->result_watcher); } else { /* timeout - call is gone */ g_string_truncate(acon->parse.error, 0); g_string_truncate(acon->parse.data, 0); close_fd_array(acon->parse.fds); } g_mutex_unlock(acon->mutex); break; default: g_set_error(err, LI_ANGEL_CONNECTION_ERROR, LI_ANGEL_CONNECTION_INVALID_DATA, "Invalid type: %i", (gint) type); close_fd_array(acon->parse.fds); return FALSE; } return TRUE; }
static GstFlowReturn gst_audio_fx_base_fir_filter_transform (GstBaseTransform * base, GstBuffer * inbuf, GstBuffer * outbuf) { GstAudioFXBaseFIRFilter *self = GST_AUDIO_FX_BASE_FIR_FILTER (base); GstClockTime timestamp, expected_timestamp; gint channels = GST_AUDIO_FILTER_CHANNELS (self); gint rate = GST_AUDIO_FILTER_RATE (self); gint bps = GST_AUDIO_FILTER_BPS (self); GstMapInfo inmap, outmap; guint input_samples; guint output_samples; guint generated_samples; guint64 output_offset; gint64 diff = 0; GstClockTime stream_time; timestamp = GST_BUFFER_TIMESTAMP (outbuf); if (!GST_CLOCK_TIME_IS_VALID (timestamp) && !GST_CLOCK_TIME_IS_VALID (self->start_ts)) { GST_ERROR_OBJECT (self, "Invalid timestamp"); return GST_FLOW_ERROR; } g_mutex_lock (&self->lock); stream_time = gst_segment_to_stream_time (&base->segment, GST_FORMAT_TIME, timestamp); GST_DEBUG_OBJECT (self, "sync to %" GST_TIME_FORMAT, GST_TIME_ARGS (timestamp)); if (GST_CLOCK_TIME_IS_VALID (stream_time)) gst_object_sync_values (GST_OBJECT (self), stream_time); g_return_val_if_fail (self->kernel != NULL, GST_FLOW_ERROR); g_return_val_if_fail (channels != 0, GST_FLOW_ERROR); if (GST_CLOCK_TIME_IS_VALID (self->start_ts)) expected_timestamp = self->start_ts + gst_util_uint64_scale_int (self->nsamples_in, GST_SECOND, rate); else expected_timestamp = GST_CLOCK_TIME_NONE; /* Reset the residue if already existing on discont buffers */ if (GST_BUFFER_IS_DISCONT (inbuf) || (GST_CLOCK_TIME_IS_VALID (expected_timestamp) && (ABS (GST_CLOCK_DIFF (timestamp, expected_timestamp) > 5 * GST_MSECOND)))) { GST_DEBUG_OBJECT (self, "Discontinuity detected - flushing"); if (GST_CLOCK_TIME_IS_VALID (expected_timestamp)) gst_audio_fx_base_fir_filter_push_residue (self); self->buffer_fill = 0; g_free (self->buffer); self->buffer = NULL; self->start_ts = timestamp; self->start_off = GST_BUFFER_OFFSET (inbuf); self->nsamples_out = 0; self->nsamples_in = 0; } else if (!GST_CLOCK_TIME_IS_VALID (self->start_ts)) { self->start_ts = timestamp; self->start_off = GST_BUFFER_OFFSET (inbuf); } gst_buffer_map (inbuf, &inmap, GST_MAP_READ); gst_buffer_map (outbuf, &outmap, GST_MAP_WRITE); input_samples = (inmap.size / bps) / channels; output_samples = (outmap.size / bps) / channels; self->nsamples_in += input_samples; generated_samples = self->process (self, inmap.data, outmap.data, input_samples); gst_buffer_unmap (inbuf, &inmap); gst_buffer_unmap (outbuf, &outmap); g_assert (generated_samples <= output_samples); self->nsamples_out += generated_samples; if (generated_samples == 0) goto no_samples; /* Calculate the number of samples we can push out now without outputting * latency zeros in the beginning */ diff = ((gint64) self->nsamples_out) - ((gint64) self->latency); if (diff < 0) goto no_samples; if (diff < generated_samples) { gint64 tmp = diff; diff = generated_samples - diff; generated_samples = tmp; } else { diff = 0; } gst_buffer_resize (outbuf, diff * bps * channels, generated_samples * bps * channels); output_offset = self->nsamples_out - self->latency - generated_samples; GST_BUFFER_TIMESTAMP (outbuf) = self->start_ts + gst_util_uint64_scale_int (output_offset, GST_SECOND, rate); GST_BUFFER_DURATION (outbuf) = gst_util_uint64_scale_int (output_samples, GST_SECOND, rate); if (self->start_off != GST_BUFFER_OFFSET_NONE) { GST_BUFFER_OFFSET (outbuf) = self->start_off + output_offset; GST_BUFFER_OFFSET_END (outbuf) = GST_BUFFER_OFFSET (outbuf) + generated_samples; } else { GST_BUFFER_OFFSET (outbuf) = GST_BUFFER_OFFSET_NONE; GST_BUFFER_OFFSET_END (outbuf) = GST_BUFFER_OFFSET_NONE; } g_mutex_unlock (&self->lock); GST_DEBUG_OBJECT (self, "Pushing buffer of size %" G_GSIZE_FORMAT " with timestamp: %" GST_TIME_FORMAT ", duration: %" GST_TIME_FORMAT ", offset: %" G_GUINT64_FORMAT ", offset_end: %" G_GUINT64_FORMAT ", nsamples_out: %d", gst_buffer_get_size (outbuf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)), GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)), GST_BUFFER_OFFSET (outbuf), GST_BUFFER_OFFSET_END (outbuf), generated_samples); return GST_FLOW_OK; no_samples: { g_mutex_unlock (&self->lock); return GST_BASE_TRANSFORM_FLOW_DROPPED; } }
static gboolean gst_soup_http_client_sink_start (GstBaseSink * sink) { GstSoupHttpClientSink *souphttpsink = GST_SOUP_HTTP_CLIENT_SINK (sink); if (souphttpsink->prop_session) { souphttpsink->session = souphttpsink->prop_session; } else { GSource *source; GError *error = NULL; souphttpsink->context = g_main_context_new (); /* set up idle source to signal when the main loop is running and * it's safe for ::stop() to call g_main_loop_quit() */ source = g_idle_source_new (); g_source_set_callback (source, thread_ready_idle_cb, sink, NULL); g_source_attach (source, souphttpsink->context); g_source_unref (source); souphttpsink->loop = g_main_loop_new (souphttpsink->context, TRUE); g_mutex_lock (&souphttpsink->mutex); souphttpsink->thread = g_thread_try_new ("souphttpclientsink-thread", thread_func, souphttpsink, &error); if (error != NULL) { GST_DEBUG_OBJECT (souphttpsink, "failed to start thread, %s", error->message); g_error_free (error); g_mutex_unlock (&souphttpsink->mutex); return FALSE; } GST_LOG_OBJECT (souphttpsink, "waiting for main loop thread to start up"); g_cond_wait (&souphttpsink->cond, &souphttpsink->mutex); g_mutex_unlock (&souphttpsink->mutex); GST_LOG_OBJECT (souphttpsink, "main loop thread running"); if (souphttpsink->proxy == NULL) { souphttpsink->session = soup_session_async_new_with_options (SOUP_SESSION_ASYNC_CONTEXT, souphttpsink->context, SOUP_SESSION_USER_AGENT, souphttpsink->user_agent, SOUP_SESSION_TIMEOUT, souphttpsink->timeout, SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_PROXY_RESOLVER_DEFAULT, NULL); } else { souphttpsink->session = soup_session_async_new_with_options (SOUP_SESSION_ASYNC_CONTEXT, souphttpsink->context, SOUP_SESSION_USER_AGENT, souphttpsink->user_agent, SOUP_SESSION_TIMEOUT, souphttpsink->timeout, SOUP_SESSION_PROXY_URI, souphttpsink->proxy, NULL); } g_signal_connect (souphttpsink->session, "authenticate", G_CALLBACK (authenticate), souphttpsink); } /* Set up logging */ gst_soup_util_log_setup (souphttpsink->session, souphttpsink->log_level, GST_ELEMENT (souphttpsink)); return TRUE; }
/** * gst_bus_timed_pop_filtered: * @bus: a #GstBus to pop from * @timeout: a timeout in nanoseconds, or GST_CLOCK_TIME_NONE to wait forever * @types: message types to take into account, GST_MESSAGE_ANY for any type * * Get a message from the bus whose type matches the message type mask @types, * waiting up to the specified timeout (and discarding any messages that do not * match the mask provided). * * If @timeout is 0, this function behaves like gst_bus_pop_filtered(). If * @timeout is #GST_CLOCK_TIME_NONE, this function will block forever until a * matching message was posted on the bus. * * Returns: (transfer full) (nullable): a #GstMessage matching the * filter in @types, or %NULL if no matching message was found on * the bus until the timeout expired. The message is taken from * the bus and needs to be unreffed with gst_message_unref() after * usage. * * MT safe. */ GstMessage * gst_bus_timed_pop_filtered (GstBus * bus, GstClockTime timeout, GstMessageType types) { GstMessage *message; GTimeVal now, then; gboolean first_round = TRUE; GstClockTime elapsed = 0; g_return_val_if_fail (GST_IS_BUS (bus), NULL); g_return_val_if_fail (types != 0, NULL); g_return_val_if_fail (timeout == 0 || bus->priv->poll != NULL, NULL); g_mutex_lock (&bus->priv->queue_lock); while (TRUE) { gint ret; GST_LOG_OBJECT (bus, "have %d messages", gst_atomic_queue_length (bus->priv->queue)); while ((message = gst_atomic_queue_pop (bus->priv->queue))) { if (bus->priv->poll) gst_poll_read_control (bus->priv->poll); GST_DEBUG_OBJECT (bus, "got message %p, %s from %s, type mask is %u", message, GST_MESSAGE_TYPE_NAME (message), GST_MESSAGE_SRC_NAME (message), (guint) types); if ((GST_MESSAGE_TYPE (message) & types) != 0) { /* Extra check to ensure extended types don't get matched unless * asked for */ if ((!GST_MESSAGE_TYPE_IS_EXTENDED (message)) || (types & GST_MESSAGE_EXTENDED)) { /* exit the loop, we have a message */ goto beach; } } GST_DEBUG_OBJECT (bus, "discarding message, does not match mask"); gst_message_unref (message); message = NULL; } /* no need to wait, exit loop */ if (timeout == 0) break; else if (timeout != GST_CLOCK_TIME_NONE) { if (first_round) { g_get_current_time (&then); first_round = FALSE; } else { g_get_current_time (&now); elapsed = GST_TIMEVAL_TO_TIME (now) - GST_TIMEVAL_TO_TIME (then); if (elapsed > timeout) break; } } /* only here in timeout case */ g_assert (bus->priv->poll); g_mutex_unlock (&bus->priv->queue_lock); ret = gst_poll_wait (bus->priv->poll, timeout - elapsed); g_mutex_lock (&bus->priv->queue_lock); if (ret == 0) { GST_INFO_OBJECT (bus, "timed out, breaking loop"); break; } else { GST_INFO_OBJECT (bus, "we got woken up, recheck for message"); } } beach: g_mutex_unlock (&bus->priv->queue_lock); return message; }
static GstFlowReturn webkitMediaPlayReadyDecryptTransformInPlace(GstBaseTransform* base, GstBuffer* buffer) { WebKitMediaPlayReadyDecrypt* self = WEBKIT_MEDIA_PLAYREADY_DECRYPT(base); GstFlowReturn result = GST_FLOW_OK; GstMapInfo map; const GValue* value; guint sampleIndex = 0; int errorCode; uint32_t trackID = 0; GstPad* pad; GstCaps* caps; GstMapInfo boxMap; GstBuffer* box = nullptr; GstProtectionMeta* protectionMeta = 0; gboolean boxMapped = FALSE; gboolean bufferMapped = FALSE; GST_TRACE_OBJECT(self, "Processing buffer"); g_mutex_lock(&self->mutex); GST_TRACE_OBJECT(self, "Mutex acquired, stream received: %s", self->streamReceived ? "yes":"no"); // The key might not have been received yet. Wait for it. if (!self->streamReceived) g_cond_wait(&self->condition, &self->mutex); if (!self->streamReceived) { GST_DEBUG_OBJECT(self, "Condition signaled from state change transition. Aborting."); result = GST_FLOW_NOT_SUPPORTED; goto beach; } GST_TRACE_OBJECT(self, "Proceeding with decryption"); protectionMeta = reinterpret_cast<GstProtectionMeta*>(gst_buffer_get_protection_meta(buffer)); if (!protectionMeta || !buffer) { if (!protectionMeta) GST_ERROR_OBJECT(self, "Failed to get GstProtection metadata from buffer %p", buffer); if (!buffer) GST_ERROR_OBJECT(self, "Failed to get writable buffer"); result = GST_FLOW_NOT_SUPPORTED; goto beach; } bufferMapped = gst_buffer_map(buffer, &map, static_cast<GstMapFlags>(GST_MAP_READWRITE)); if (!bufferMapped) { GST_ERROR_OBJECT(self, "Failed to map buffer"); result = GST_FLOW_NOT_SUPPORTED; goto beach; } pad = gst_element_get_static_pad(GST_ELEMENT(self), "src"); caps = gst_pad_get_current_caps(pad); if (g_str_has_prefix(gst_structure_get_name(gst_caps_get_structure(caps, 0)), "video/")) trackID = 1; else trackID = 2; gst_caps_unref(caps); gst_object_unref(pad); if (!gst_structure_get_uint(protectionMeta->info, "sample-index", &sampleIndex)) { GST_ERROR_OBJECT(self, "failed to get sample-index"); result = GST_FLOW_NOT_SUPPORTED; goto beach; } value = gst_structure_get_value(protectionMeta->info, "box"); if (!value) { GST_ERROR_OBJECT(self, "Failed to get encryption box for sample"); result = GST_FLOW_NOT_SUPPORTED; goto beach; } box = gst_value_get_buffer(value); boxMapped = gst_buffer_map(box, &boxMap, GST_MAP_READ); if (!boxMapped) { GST_ERROR_OBJECT(self, "Failed to map encryption box"); result = GST_FLOW_NOT_SUPPORTED; goto beach; } GST_TRACE_OBJECT(self, "decrypt sample %u", sampleIndex); if ((errorCode = self->sessionMetaData->decrypt(static_cast<void*>(map.data), static_cast<uint32_t>(map.size), static_cast<void*>(boxMap.data), static_cast<uint32_t>(boxMap.size), static_cast<uint32_t>(sampleIndex), trackID))) { GST_WARNING_OBJECT(self, "ERROR - packet decryption failed [%d]", errorCode); GST_MEMDUMP_OBJECT(self, "box", boxMap.data, boxMap.size); result = GST_FLOW_ERROR; goto beach; } beach: if (boxMapped) gst_buffer_unmap(box, &boxMap); if (bufferMapped) gst_buffer_unmap(buffer, &map); if (protectionMeta) gst_buffer_remove_meta(buffer, reinterpret_cast<GstMeta*>(protectionMeta)); GST_TRACE_OBJECT(self, "Unlocking mutex"); g_mutex_unlock(&self->mutex); return result; }
static int gst_droidcamsrc_stream_window_enqueue_buffer (struct preview_stream_ops *w, buffer_handle_t * buffer) { GstDroidCamSrcStreamWindow *win; GstDroidCamSrc *src; GstBuffer *buff; int ret; GstVideoCropMeta *meta; GST_DEBUG ("enqueue buffer %p", buffer); win = container_of (w, GstDroidCamSrcStreamWindow, window); g_mutex_lock (&win->lock); src = GST_DROIDCAMSRC (GST_PAD_PARENT (win->pad->pad)); buff = gst_droidcamsrc_stream_window_get_buffer (buffer); if (!buff) { GST_ERROR ("no buffer corresponding to handle %p", buffer); ret = -1; goto unlock_and_out; } /* if the buffer pool is not our current pool then just release it */ if (buff->pool != GST_BUFFER_POOL (win->pool)) { GST_DEBUG ("releasing old buffer %p", buffer); gst_buffer_unref (buff); ret = 0; goto unlock_and_out; } /* now update crop meta */ meta = gst_buffer_get_video_crop_meta (buff); meta->x = win->left; meta->y = win->top; meta->width = win->right - win->left; meta->height = win->bottom - win->top; GST_LOG ("window width = %d, height = %d, crop info: left = %d, top = %d, right = %d, bottom = %d", win->width, win->height, win->left, win->top, win->right, win->bottom); g_mutex_unlock (&win->lock); /* it should be safe to access that variable without locking. * pad gets activated during READY_TO_PAUSED and deactivated during * PAUSED_TO_READY while we start the preview during PAUSED_TO_PLAYING * and stop it during PLAYING_TO_PAUSED. */ if (!win->pad->running) { gst_buffer_unref (buff); GST_DEBUG ("unreffing buffer because pad task is not running"); ret = 0; goto unlock_pad_and_out; } // TODO: duration, offset, offset_end ... gst_droidcamsrc_timestamp (src, buff); g_mutex_lock (&win->pad->queue_lock); g_queue_push_tail (win->pad->queue, buff); g_cond_signal (&win->pad->cond); ret = 0; goto unlock_pad_and_out; unlock_and_out: g_mutex_unlock (&win->lock); return ret; unlock_pad_and_out: g_mutex_unlock (&win->pad->queue_lock); return ret; }
static GstFlowReturn gst_droidadec_handle_frame (GstAudioDecoder * decoder, GstBuffer * buffer) { GstDroidADec *dec = GST_DROIDADEC (decoder); GstFlowReturn ret; DroidMediaCodecData data; DroidMediaBufferCallbacks cb; GST_DEBUG_OBJECT (dec, "handle frame"); if (G_UNLIKELY (!buffer)) { return gst_droidadec_finish (decoder); } if (dec->downstream_flow_ret != GST_FLOW_OK) { GST_DEBUG_OBJECT (dec, "not handling frame in error state: %s", gst_flow_get_name (dec->downstream_flow_ret)); ret = dec->downstream_flow_ret; goto error; } g_mutex_lock (&dec->eos_lock); if (dec->eos) { GST_WARNING_OBJECT (dec, "got frame in eos state"); g_mutex_unlock (&dec->eos_lock); ret = GST_FLOW_EOS; goto error; } g_mutex_unlock (&dec->eos_lock); /* We must create the codec before we process any data. _create_codec will call * construct_decoder_codec_data which will store the nal prefix length for H264. * This is a bad situation. TODO: fix it */ if (G_UNLIKELY (dec->dirty)) { if (dec->codec) { gst_droidadec_finish (decoder); } if (!gst_droidadec_create_codec (dec, buffer)) { ret = GST_FLOW_ERROR; goto error; } dec->dirty = FALSE; } if (!gst_droid_codec_process_decoder_data (dec->codec_type, buffer, &data.data)) { /* TODO: error */ ret = GST_FLOW_ERROR; goto error; } cb.unref = g_free; cb.data = data.data.data; GST_DEBUG_OBJECT (dec, "decoding data of size %d (%d)", gst_buffer_get_size (buffer), data.data.size); /* * We are ignoring timestamping completely and relying * on the base class to do our bookkeeping ;-) */ data.ts = 0; data.sync = false; /* This can deadlock if droidmedia/stagefright input buffer queue is full thus we * cannot write the input buffer. We end up waiting for the write operation * which does not happen because stagefright needs us to provide * output buffers to be filled (which can not happen because _loop() tries * to call get_oldest_frame() which acquires the stream lock the base class * is holding before calling us */ GST_AUDIO_DECODER_STREAM_UNLOCK (decoder); droid_media_codec_queue (dec->codec, &data, &cb); GST_AUDIO_DECODER_STREAM_LOCK (decoder); /* from now on decoder owns a frame reference so we cannot use the out label otherwise * we will drop the needed reference */ if (dec->downstream_flow_ret != GST_FLOW_OK) { GST_DEBUG_OBJECT (dec, "not handling frame in error state: %s", gst_flow_get_name (dec->downstream_flow_ret)); ret = dec->downstream_flow_ret; goto out; } g_mutex_lock (&dec->eos_lock); if (dec->eos) { GST_WARNING_OBJECT (dec, "got frame in eos state"); g_mutex_unlock (&dec->eos_lock); ret = GST_FLOW_EOS; goto out; } g_mutex_unlock (&dec->eos_lock); ret = GST_FLOW_OK; out: return ret; error: /* don't leak the frame */ gst_audio_decoder_finish_frame (decoder, NULL, 1); return ret; }
static int gst_droidcamsrc_stream_window_dequeue_buffer (struct preview_stream_ops *w, buffer_handle_t ** buffer, int *stride) { GstDroidCamSrcStreamWindow *win; GstBuffer *buff; GstFlowReturn ret; int trials; GstBufferPoolAcquireParams params; GstMemory *mem; struct ANativeWindowBuffer *native; int res; GST_DEBUG ("dequeue buffer %p", buffer); win = container_of (w, GstDroidCamSrcStreamWindow, window); g_mutex_lock (&win->lock); retry: GST_DEBUG ("needs reconfigure? %d", win->needs_reconfigure); if (!win->pool || (win->pool && win->needs_reconfigure)) { /* create and re/configure the pool */ gst_droidcamsrc_stream_window_reset_buffer_pool_locked (win); } if (!win->pool) { GST_ERROR ("failed to create buffer pool"); res = -1; goto unlock_and_exit; } mem = NULL; trials = ACQUIRE_BUFFER_TRIALS; params.flags = GST_BUFFER_POOL_ACQUIRE_FLAG_DONTWAIT; while (trials > 0) { ret = gst_buffer_pool_acquire_buffer (GST_BUFFER_POOL (win->pool), &buff, ¶ms); if (ret == GST_FLOW_OK) { /* we have our buffer */ break; } else if (ret == GST_FLOW_ERROR || ret == GST_FLOW_FLUSHING) { /* no point in waiting */ break; } /* we need to unlock here to allow buffers to be returned back */ g_mutex_unlock (&win->lock); usleep (ACQUIRE_BUFFER_TIMEOUT); g_mutex_lock (&win->lock); if (win->needs_reconfigure) { /* out of here */ goto retry; } --trials; } if (buff) { /* handover */ mem = gst_buffer_peek_memory (buff, 0); } else if (ret == GST_FLOW_FLUSHING) { GST_INFO ("pool is flushing"); } else { GST_WARNING ("failed to get a buffer"); } if (!mem) { GST_ERROR ("no buffer memory found"); res = -1; goto unlock_and_exit; } native = gst_memory_get_native_buffer (mem); if (!native) { GST_ERROR ("invalid buffer"); gst_buffer_unref (buff); res = -1; goto unlock_and_exit; } *buffer = &native->handle; *stride = native->stride; GST_LOG ("dequeue buffer done %p", *buffer); res = 0; unlock_and_exit: g_mutex_unlock (&win->lock); return res; }
static void * example_thread(void *data) { NiceAgent *agent; NiceCandidate *local, *remote; GIOChannel* io_stdin; guint stream_id; gchar *line = NULL; int rval; io_stdin = g_io_channel_unix_new(fileno(stdin)); g_io_channel_set_flags (io_stdin, G_IO_FLAG_NONBLOCK, NULL); // Create the nice agent agent = nice_agent_new(g_main_loop_get_context (gloop), NICE_COMPATIBILITY_RFC5245); if (agent == NULL) g_error("Failed to create agent"); // Set the STUN settings and controlling mode if (stun_addr) { g_object_set(G_OBJECT(agent), "stun-server", stun_addr, NULL); g_object_set(G_OBJECT(agent), "stun-server-port", stun_port, NULL); } g_object_set(G_OBJECT(agent), "controlling-mode", controlling, NULL); // Connect to the signals g_signal_connect(G_OBJECT(agent), "candidate-gathering-done", G_CALLBACK(cb_candidate_gathering_done), NULL); g_signal_connect(G_OBJECT(agent), "new-selected-pair", G_CALLBACK(cb_new_selected_pair), NULL); g_signal_connect(G_OBJECT(agent), "component-state-changed", G_CALLBACK(cb_component_state_changed), NULL); // Create a new stream with one component stream_id = nice_agent_add_stream(agent, 1); if (stream_id == 0) g_error("Failed to add stream"); // Attach to the component to receive the data // Without this call, candidates cannot be gathered nice_agent_attach_recv(agent, stream_id, 1, g_main_loop_get_context (gloop), cb_nice_recv, NULL); // Start gathering local candidates if (!nice_agent_gather_candidates(agent, stream_id)) g_error("Failed to start candidate gathering"); g_debug("waiting for candidate-gathering-done signal..."); g_mutex_lock(&gather_mutex); while (!exit_thread && !candidate_gathering_done) g_cond_wait(&gather_cond, &gather_mutex); g_mutex_unlock(&gather_mutex); if (exit_thread) goto end; // Candidate gathering is done. Send our local candidates on stdout printf("Copy this line to remote client:\n"); printf("\n "); print_local_data(agent, stream_id, 1); printf("\n"); // Listen on stdin for the remote candidate list printf("Enter remote data (single line, no wrapping):\n"); printf("> "); fflush (stdout); while (!exit_thread) { GIOStatus s = g_io_channel_read_line (io_stdin, &line, NULL, NULL, NULL); if (s == G_IO_STATUS_NORMAL) { // Parse remote candidate list and set it on the agent rval = parse_remote_data(agent, stream_id, 1, line); if (rval == EXIT_SUCCESS) { g_free (line); break; } else { fprintf(stderr, "ERROR: failed to parse remote data\n"); printf("Enter remote data (single line, no wrapping):\n"); printf("> "); fflush (stdout); } g_free (line); } else if (s == G_IO_STATUS_AGAIN) { usleep (100000); } } g_debug("waiting for state READY or FAILED signal..."); g_mutex_lock(&negotiate_mutex); while (!exit_thread && !negotiation_done) g_cond_wait(&negotiate_cond, &negotiate_mutex); g_mutex_unlock(&negotiate_mutex); if (exit_thread) goto end; // Get current selected candidate pair and print IP address used if (nice_agent_get_selected_pair (agent, stream_id, 1, &local, &remote)) { gchar ipaddr[INET6_ADDRSTRLEN]; nice_address_to_string(&local->addr, ipaddr); printf("\nNegotiation complete: ([%s]:%d,", ipaddr, nice_address_get_port(&local->addr)); nice_address_to_string(&remote->addr, ipaddr); printf(" [%s]:%d)\n", ipaddr, nice_address_get_port(&remote->addr)); } // Listen to stdin and send data written to it printf("\nSend lines to remote (Ctrl-D to quit):\n"); printf("> "); fflush (stdout); while (!exit_thread) { GIOStatus s = g_io_channel_read_line (io_stdin, &line, NULL, NULL, NULL); if (s == G_IO_STATUS_NORMAL) { nice_agent_send(agent, stream_id, 1, strlen(line), line); g_free (line); printf("> "); fflush (stdout); } else if (s == G_IO_STATUS_AGAIN) { usleep (100000); } else { // Ctrl-D was pressed. nice_agent_send(agent, stream_id, 1, 1, "\0"); break; } } end: g_io_channel_unref (io_stdin); g_object_unref(agent); g_main_loop_quit (gloop); return NULL; }
GSList* action_database_lookup(ActionDatabase* database,char* name){ g_mutex_lock(&(database->mutex)); GSList* result = g_hash_table_lookup(database->hash_table,name); g_mutex_unlock(&(database->mutex)); return result; }
gboolean eas_gdbus_call (struct eas_gdbus_client *client, const gchar *object, const gchar *interface, const gchar *method, EasProgressFn progress_fn, gpointer progress_data, const gchar *in_params, const gchar *out_params, GCancellable *cancellable, GError **error, ...) { GDBusMessage *message; struct _eas_call_data call; GMainContext *ctxt; GVariant *v = NULL; va_list ap; gboolean success; guint cancel_handler_id; guint32 serial = 0; va_start (ap, error); message = g_dbus_message_new_method_call (EAS_SERVICE_NAME, object, interface, method); v = g_variant_new_va (in_params, NULL, &ap); g_dbus_message_set_body (message, v); call.cancelled = FALSE; call.result = NULL; ctxt = g_main_context_new (); call.loop = g_main_loop_new (ctxt, FALSE); g_main_context_push_thread_default (ctxt); g_dbus_connection_send_message_with_reply (client->connection, message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, 1000000, &serial, cancellable, _call_done, (gpointer) &call); g_object_unref (message); if (cancellable) cancel_handler_id = g_cancellable_connect (cancellable, G_CALLBACK (_call_cancel), (gpointer) &call, NULL); /* Ignore error; it's not the end of the world if progress info is lost, and it should never happen anyway */ if (progress_fn) eas_client_add_progress_info_to_table (client, serial, progress_fn, progress_data, NULL); g_main_loop_run (call.loop); if (cancellable) g_cancellable_disconnect (cancellable, cancel_handler_id); success = eas_gdbus_call_finish (client, call.result, call.cancelled ? serial : 0, out_params, &ap, error); if (serial && progress_fn) { EasProgressCallbackInfo *cbinfo; g_mutex_lock (client->progress_lock); cbinfo = g_hash_table_lookup (client->progress_fns_table, GUINT_TO_POINTER (serial)); if (cbinfo && cbinfo->calling) { g_debug ("Progress for call %u is running; wait for it to complete", serial); g_hash_table_steal (client->progress_fns_table, GUINT_TO_POINTER (serial)); do { g_cond_wait (client->progress_cond, client->progress_lock); } while (cbinfo->calling); g_free (cbinfo); } else if (cbinfo) { g_hash_table_remove (client->progress_fns_table, GUINT_TO_POINTER (serial)); } g_mutex_unlock (client->progress_lock); } va_end (ap); g_main_context_pop_thread_default (ctxt); g_main_context_unref (ctxt); g_main_loop_unref (call.loop); g_object_unref (call.result); return success; }
static void gst_shmdata_src_make_data_rendered(GstShmdataSrc *self){ g_mutex_lock (&self->data_rendered_mutex); self->data_rendered = TRUE; g_cond_broadcast(&self->data_rendered_cond); g_mutex_unlock (&self->data_rendered_mutex); }
static int vips_sequential_generate( VipsRegion *or, void *seq, void *a, void *b, gboolean *stop ) { VipsSequential *sequential = (VipsSequential *) b; VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( sequential ); VipsRect *r = &or->valid; VipsRegion *ir = (VipsRegion *) seq; VIPS_DEBUG_MSG( "thread %p request for %d lines, start line %d\n", g_thread_self(), r->height, r->top ); if( sequential->trace ) vips_diag( class->nickname, "request for %d lines, starting at line %d", r->height, r->top ); g_mutex_lock( sequential->lock ); VIPS_DEBUG_MSG( "thread %p has lock ...\n", g_thread_self() ); /* If we've seen an error, everything must stop. */ if( sequential->error ) { g_mutex_unlock( sequential->lock ); return( -1 ); } if( r->top > sequential->y_pos && sequential->y_pos > 0 ) { /* We have started reading (y_pos > 0) and this request is for * stuff beyond that, stall for a short while to give other * threads time to catch up. * * The stall can be cancelled by a signal on @ready. */ VIPS_DEBUG_MSG( "thread %p stalling for up to %gs ...\n", g_thread_self(), STALL_TIME ); vips_g_cond_timed_wait( sequential->ready, sequential->lock, STALL_TIME * 1000000 ); VIPS_DEBUG_MSG( "thread %p awake again ...\n", g_thread_self() ); } /* This is a request for something some way down the image, and we've * either not read anything yet or fallen through from the stall * above. * * Probably the operation is something like extract_area and we should * skip the initial part of the image. In fact, we read to cache, * since it may be useful. */ if( r->top > sequential->y_pos ) { VipsRect area; VIPS_DEBUG_MSG( "thread %p skipping to line %d ...\n", g_thread_self(), r->top ); area.left = 0; area.top = sequential->y_pos; area.width = 1; area.height = r->top - sequential->y_pos; if( vips_region_prepare( ir, &area ) ) { VIPS_DEBUG_MSG( "thread %p error, unlocking ...\n", g_thread_self() ); sequential->error = -1; g_cond_broadcast( sequential->ready ); g_mutex_unlock( sequential->lock ); return( -1 ); } sequential->y_pos = VIPS_RECT_BOTTOM( &area ); } /* This is a request for old or present pixels -- serve from cache. * This may trigger further, sequential reads. */ VIPS_DEBUG_MSG( "thread %p reading ...\n", g_thread_self() ); if( vips_region_prepare( ir, r ) || vips_region_region( or, ir, r, r->left, r->top ) ) { VIPS_DEBUG_MSG( "thread %p error, unlocking ...\n", g_thread_self() ); sequential->error = -1; g_cond_broadcast( sequential->ready ); g_mutex_unlock( sequential->lock ); return( -1 ); } if( VIPS_RECT_BOTTOM( r ) > sequential->y_pos ) { /* This request has moved the read point. Update it, and wake * up all stalled threads for a retry. */ sequential->y_pos = VIPS_RECT_BOTTOM( r ); VIPS_DEBUG_MSG( "thread %p updating y_pos to %d and " "waking stalled\n", g_thread_self(), sequential->y_pos ); g_cond_broadcast( sequential->ready ); } VIPS_DEBUG_MSG( "thread %p unlocking ...\n", g_thread_self() ); g_mutex_unlock( sequential->lock ); return( 0 ); }
static GstFlowReturn gst_shmdata_src_create (GstPushSrc *psrc, GstBuffer **outbuf) { GstShmdataSrc *self = GST_SHMDATA_SRC (psrc); if (self->unlocked) { return GST_FLOW_FLUSHING; } g_mutex_lock (&self->on_data_mutex); while (!self->on_data && !self->unlocked) g_cond_wait_until (&self->on_data_cond, &self->on_data_mutex, g_get_monotonic_time () + 10 * G_TIME_SPAN_MILLISECOND); if (self->unlocked) { self->on_data = FALSE; g_mutex_unlock (&self->on_data_mutex); gst_shmdata_src_make_data_rendered(self); return GST_FLOW_FLUSHING; } self->on_data = FALSE; g_mutex_unlock (&self->on_data_mutex); if (self->is_first_read) { gst_shmdata_src_make_data_rendered(self); self->is_first_read = FALSE; } if (self->has_new_caps && (GST_STATE_PAUSED == GST_STATE(self) || GST_STATE_PLAYING == GST_STATE(self))) { self->has_new_caps = FALSE; g_object_notify(G_OBJECT(self), "caps"); GstPad *pad = gst_element_get_static_pad (GST_ELEMENT(self),"src"); if(!gst_pad_set_caps (pad, self->caps)) { GST_ELEMENT_ERROR (GST_ELEMENT(self), CORE, NEGOTIATION, (NULL), ("caps fix caps from shmdata type description")); return GST_FLOW_ERROR; } gst_object_unref(pad); } if(!self->copy_buffers){ *outbuf = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY, self->current_data, self->current_size, 0, self->current_size, self, gst_shmdata_src_on_data_rendered); } else { GstBuffer *tmp = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY, self->current_data, self->current_size, 0, self->current_size, NULL, NULL); *outbuf = gst_buffer_copy (tmp); gst_shmdata_src_on_data_rendered(self); gst_buffer_unref(tmp); } return GST_FLOW_OK; }
static void gst_amc_audio_dec_loop (GstAmcAudioDec * self) { GstFlowReturn flow_ret = GST_FLOW_OK; gboolean is_eos; GstAmcBufferInfo buffer_info; gint idx; GST_AUDIO_DECODER_STREAM_LOCK (self); retry: /*if (self->input_caps_changed) { idx = INFO_OUTPUT_FORMAT_CHANGED; } else { */ GST_DEBUG_OBJECT (self, "Waiting for available output buffer"); GST_AUDIO_DECODER_STREAM_UNLOCK (self); /* Wait at most 100ms here, some codecs don't fail dequeueing if * the codec is flushing, causing deadlocks during shutdown */ idx = gst_amc_codec_dequeue_output_buffer (self->codec, &buffer_info, 100000); GST_AUDIO_DECODER_STREAM_LOCK (self); /*} */ if (idx < 0) { if (self->flushing) goto flushing; switch (idx) { case INFO_OUTPUT_BUFFERS_CHANGED:{ GST_DEBUG_OBJECT (self, "Output buffers have changed"); if (self->output_buffers) gst_amc_codec_free_buffers (self->output_buffers, self->n_output_buffers); self->output_buffers = gst_amc_codec_get_output_buffers (self->codec, &self->n_output_buffers); if (!self->output_buffers) goto get_output_buffers_error; break; } case INFO_OUTPUT_FORMAT_CHANGED:{ GstAmcFormat *format; gchar *format_string; GST_DEBUG_OBJECT (self, "Output format has changed"); format = gst_amc_codec_get_output_format (self->codec); if (!format) goto format_error; format_string = gst_amc_format_to_string (format); GST_DEBUG_OBJECT (self, "Got new output format: %s", format_string); g_free (format_string); if (!gst_amc_audio_dec_set_src_caps (self, format)) { gst_amc_format_free (format); goto format_error; } gst_amc_format_free (format); if (self->output_buffers) gst_amc_codec_free_buffers (self->output_buffers, self->n_output_buffers); self->output_buffers = gst_amc_codec_get_output_buffers (self->codec, &self->n_output_buffers); if (!self->output_buffers) goto get_output_buffers_error; goto retry; break; } case INFO_TRY_AGAIN_LATER: GST_DEBUG_OBJECT (self, "Dequeueing output buffer timed out"); goto retry; break; case G_MININT: GST_ERROR_OBJECT (self, "Failure dequeueing output buffer"); goto dequeue_error; break; default: g_assert_not_reached (); break; } goto retry; } GST_DEBUG_OBJECT (self, "Got output buffer at index %d: size %d time %" G_GINT64_FORMAT " flags 0x%08x", idx, buffer_info.size, buffer_info.presentation_time_us, buffer_info.flags); is_eos = ! !(buffer_info.flags & BUFFER_FLAG_END_OF_STREAM); self->n_buffers++; if (buffer_info.size > 0) { GstAmcAudioDecClass *klass = GST_AMC_AUDIO_DEC_GET_CLASS (self); GstBuffer *outbuf; GstAmcBuffer *buf; GstMapInfo minfo; /* This sometimes happens at EOS or if the input is not properly framed, * let's handle it gracefully by allocating a new buffer for the current * caps and filling it */ if (idx >= self->n_output_buffers) goto invalid_buffer_index; if (strcmp (klass->codec_info->name, "OMX.google.mp3.decoder") == 0) { /* Google's MP3 decoder outputs garbage in the first output buffer * so we just drop it here */ if (self->n_buffers == 1) { GST_DEBUG_OBJECT (self, "Skipping first buffer of Google MP3 decoder output"); goto done; } } outbuf = gst_audio_decoder_allocate_output_buffer (GST_AUDIO_DECODER (self), buffer_info.size); if (!outbuf) goto failed_allocate; gst_buffer_map (outbuf, &minfo, GST_MAP_WRITE); buf = &self->output_buffers[idx]; if (self->needs_reorder) { gint i, n_samples, c, n_channels; gint *reorder_map = self->reorder_map; gint16 *dest, *source; dest = (gint16 *) minfo.data; source = (gint16 *) (buf->data + buffer_info.offset); n_samples = buffer_info.size / self->info.bpf; n_channels = self->info.channels; for (i = 0; i < n_samples; i++) { for (c = 0; c < n_channels; c++) { dest[i * n_channels + reorder_map[c]] = source[i * n_channels + c]; } } } else { orc_memcpy (minfo.data, buf->data + buffer_info.offset, buffer_info.size); } gst_buffer_unmap (outbuf, &minfo); /* FIXME: We should get one decoded input frame here for * every buffer. If this is not the case somewhere, we will * error out at some point and will need to add workarounds */ flow_ret = gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (self), outbuf, 1); } done: if (!gst_amc_codec_release_output_buffer (self->codec, idx, TRUE)) goto failed_release; if (is_eos || flow_ret == GST_FLOW_EOS) { GST_AUDIO_DECODER_STREAM_UNLOCK (self); g_mutex_lock (&self->drain_lock); if (self->draining) { GST_DEBUG_OBJECT (self, "Drained"); self->draining = FALSE; g_cond_broadcast (&self->drain_cond); } else if (flow_ret == GST_FLOW_OK) { GST_DEBUG_OBJECT (self, "Component signalled EOS"); flow_ret = GST_FLOW_EOS; } g_mutex_unlock (&self->drain_lock); GST_AUDIO_DECODER_STREAM_LOCK (self); } else { GST_DEBUG_OBJECT (self, "Finished frame: %s", gst_flow_get_name (flow_ret)); } self->downstream_flow_ret = flow_ret; if (flow_ret != GST_FLOW_OK) goto flow_error; GST_AUDIO_DECODER_STREAM_UNLOCK (self); return; dequeue_error: { GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL), ("Failed to dequeue output buffer")); gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ()); gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self)); self->downstream_flow_ret = GST_FLOW_ERROR; GST_AUDIO_DECODER_STREAM_UNLOCK (self); return; } get_output_buffers_error: { GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL), ("Failed to get output buffers")); gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ()); gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self)); self->downstream_flow_ret = GST_FLOW_ERROR; GST_AUDIO_DECODER_STREAM_UNLOCK (self); return; } format_error: { GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL), ("Failed to handle format")); gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ()); gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self)); self->downstream_flow_ret = GST_FLOW_ERROR; GST_AUDIO_DECODER_STREAM_UNLOCK (self); return; } failed_release: { GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL), ("Failed to release output buffer index %d", idx)); gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ()); gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self)); self->downstream_flow_ret = GST_FLOW_ERROR; GST_AUDIO_DECODER_STREAM_UNLOCK (self); return; } flushing: { GST_DEBUG_OBJECT (self, "Flushing -- stopping task"); gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self)); self->downstream_flow_ret = GST_FLOW_FLUSHING; GST_AUDIO_DECODER_STREAM_UNLOCK (self); return; } flow_error: { if (flow_ret == GST_FLOW_EOS) { GST_DEBUG_OBJECT (self, "EOS"); gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ()); gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self)); } else if (flow_ret == GST_FLOW_NOT_LINKED || flow_ret < GST_FLOW_EOS) { GST_ELEMENT_ERROR (self, STREAM, FAILED, ("Internal data stream error."), ("stream stopped, reason %s", gst_flow_get_name (flow_ret))); gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ()); gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self)); } GST_AUDIO_DECODER_STREAM_UNLOCK (self); return; } invalid_buffer_index: { GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL), ("Invalid input buffer index %d of %d", idx, self->n_input_buffers)); gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ()); gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self)); self->downstream_flow_ret = GST_FLOW_ERROR; GST_AUDIO_DECODER_STREAM_UNLOCK (self); return; } failed_allocate: { GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL), ("Failed to allocate output buffer")); gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ()); gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self)); self->downstream_flow_ret = GST_FLOW_ERROR; GST_AUDIO_DECODER_STREAM_UNLOCK (self); return; } }
void gst_soup_http_client_sink_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec) { GstSoupHttpClientSink *souphttpsink = GST_SOUP_HTTP_CLIENT_SINK (object); g_mutex_lock (&souphttpsink->mutex); switch (property_id) { case PROP_SESSION: if (souphttpsink->prop_session) { g_object_unref (souphttpsink->prop_session); } souphttpsink->prop_session = g_value_dup_object (value); break; case PROP_LOCATION: g_free (souphttpsink->location); souphttpsink->location = g_value_dup_string (value); souphttpsink->offset = 0; if ((souphttpsink->location == NULL) || !gst_uri_is_valid (souphttpsink->location)) { GST_WARNING_OBJECT (souphttpsink, "The location (\"%s\") set, is not a valid uri.", souphttpsink->location); g_free (souphttpsink->location); souphttpsink->location = NULL; } break; case PROP_USER_AGENT: g_free (souphttpsink->user_agent); souphttpsink->user_agent = g_value_dup_string (value); break; case PROP_AUTOMATIC_REDIRECT: souphttpsink->automatic_redirect = g_value_get_boolean (value); break; case PROP_USER_ID: g_free (souphttpsink->user_id); souphttpsink->user_id = g_value_dup_string (value); break; case PROP_USER_PW: g_free (souphttpsink->user_pw); souphttpsink->user_pw = g_value_dup_string (value); break; case PROP_PROXY_ID: g_free (souphttpsink->proxy_id); souphttpsink->proxy_id = g_value_dup_string (value); break; case PROP_PROXY_PW: g_free (souphttpsink->proxy_pw); souphttpsink->proxy_pw = g_value_dup_string (value); break; case PROP_PROXY: { const gchar *proxy; proxy = g_value_get_string (value); if (proxy == NULL) { GST_WARNING ("proxy property cannot be NULL"); goto done; } if (!gst_soup_http_client_sink_set_proxy (souphttpsink, proxy)) { GST_WARNING ("badly formatted proxy URI"); goto done; } break; } case PROP_COOKIES: g_strfreev (souphttpsink->cookies); souphttpsink->cookies = g_strdupv (g_value_get_boxed (value)); break; case PROP_SOUP_LOG_LEVEL: souphttpsink->log_level = g_value_get_enum (value); break; case PROP_RETRY_DELAY: souphttpsink->retry_delay = g_value_get_int (value); break; case PROP_RETRIES: souphttpsink->retries = g_value_get_int (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } done: g_mutex_unlock (&souphttpsink->mutex); }
static CamelAuthenticationResult ews_transport_authenticate_sync (CamelService *service, const gchar *mechanism, GCancellable *cancellable, GError **error) { CamelAuthenticationResult result; CamelEwsTransport *ews_transport; CamelSettings *settings; CamelEwsSettings *ews_settings; EEwsConnection *connection; const gchar *password; gchar *hosturl, *new_sync_state = NULL; GSList *folders_created = NULL; GSList *folders_updated = NULL; GSList *folders_deleted = NULL; gboolean includes_last_folder = FALSE; GError *local_error = NULL; ews_transport = CAMEL_EWS_TRANSPORT (service); password = camel_service_get_password (service); settings = camel_service_ref_settings (service); ews_settings = CAMEL_EWS_SETTINGS (settings); hosturl = camel_ews_settings_dup_hosturl (ews_settings); connection = e_ews_connection_new (hosturl, ews_settings); e_ews_connection_set_password (connection, password); g_free (hosturl); g_object_unref (settings); e_binding_bind_property ( service, "proxy-resolver", connection, "proxy-resolver", G_BINDING_SYNC_CREATE); /* XXX We need to run some operation that requires authentication * but does not change any server-side state, so we can check * the error status and determine if our password is valid. * David suggested e_ews_connection_sync_folder_hierarchy(), * since we have to do that eventually anyway. */ e_ews_connection_sync_folder_hierarchy_sync (connection, EWS_PRIORITY_MEDIUM, NULL, &new_sync_state, &includes_last_folder, &folders_created, &folders_updated, &folders_deleted, cancellable, &local_error); g_slist_free_full (folders_created, g_object_unref); g_slist_free_full (folders_updated, g_object_unref); g_slist_free_full (folders_deleted, g_free); g_free (new_sync_state); if (g_error_matches (local_error, EWS_CONNECTION_ERROR, EWS_CONNECTION_ERROR_UNAVAILABLE)) { local_error->domain = CAMEL_SERVICE_ERROR; local_error->code = CAMEL_SERVICE_ERROR_UNAVAILABLE; } if (!local_error) { g_mutex_lock (&ews_transport->priv->connection_lock); g_clear_object (&ews_transport->priv->connection); ews_transport->priv->connection = g_object_ref (connection); g_mutex_unlock (&ews_transport->priv->connection_lock); } else { g_mutex_lock (&ews_transport->priv->connection_lock); g_clear_object (&ews_transport->priv->connection); g_mutex_unlock (&ews_transport->priv->connection_lock); } if (!local_error) { result = CAMEL_AUTHENTICATION_ACCEPTED; } else if (g_error_matches (local_error, EWS_CONNECTION_ERROR, EWS_CONNECTION_ERROR_AUTHENTICATION_FAILED)) { g_clear_error (&local_error); result = CAMEL_AUTHENTICATION_REJECTED; } else { g_propagate_error (error, local_error); result = CAMEL_AUTHENTICATION_ERROR; } g_object_unref (connection); return result; }
static void pragha_scanner_update_handler(PraghaScanner *scanner, const gchar *dir_name) { GDir *dir; const gchar *next_file = NULL; gchar *ab_file = NULL, *s_ab_file = NULL; GError *error = NULL; struct stat sbuf; PraghaMusicobject *mobj = NULL; if(g_cancellable_is_cancelled (scanner->cancellable)) return; dir = g_dir_open(dir_name, 0, &error); if (!dir) { g_critical("Unable to open library : %s", dir_name); return; } next_file = g_dir_read_name(dir); while (next_file) { if(g_cancellable_is_cancelled (scanner->cancellable)) return; ab_file = g_strconcat(dir_name, G_DIR_SEPARATOR_S, next_file, NULL); if (g_file_test(ab_file, G_FILE_TEST_IS_DIR)) { pragha_scanner_update_handler(scanner, ab_file); } else { mobj = g_hash_table_lookup(scanner->tracks_table, ab_file); if(!mobj) { mobj = new_musicobject_from_file(ab_file); if (G_LIKELY(mobj)) g_hash_table_insert(scanner->tracks_table, g_strdup(pragha_musicobject_get_file(mobj)), mobj); } else { if ((g_stat(ab_file, &sbuf) == 0) && (sbuf.st_mtime > scanner->last_update.tv_sec)) { mobj = new_musicobject_from_file(ab_file); if (G_LIKELY(mobj)) { g_hash_table_replace(scanner->tracks_table, g_strdup(pragha_musicobject_get_file(mobj)), mobj); } } } g_mutex_lock (&scanner->files_scanned_mutex); scanner->files_scanned++; g_mutex_unlock (&scanner->files_scanned_mutex); g_free(s_ab_file); } g_free(ab_file); next_file = g_dir_read_name(dir); } g_dir_close(dir); }