static gboolean gst_ss_demux_download_bus_cb(GstBus *bus, GstMessage *msg, gpointer data) { GstSSDemuxStream *stream = (GstSSDemuxStream *)data; GstSSDemux *demux = stream->parent; switch (GST_MESSAGE_TYPE(msg)) { case GST_MESSAGE_EOS: { guint64 download_rate = -1; GST_INFO_OBJECT (stream->pad, "received EOS on download pipe.."); // increase the fragment count on EOS stream->frag_cnt++; if (g_strrstr (gst_element_get_name(stream->urisrc), "http")) { g_object_get (stream->urisrc, "download-rate", &download_rate, NULL); g_print("*********** '%s' download rate = %d bps **************\n", stream->name, download_rate); } // TODO: need to remove download_rate> 0 check.. make it generic if ((stream->type == SS_STREAM_VIDEO) && (demux->ss_mode != SS_MODE_AONLY) && (download_rate >= 0)) { if (stream->frag_cnt >= demux->fragments_cache) { /* for switching, we are considering video download rate only */ demux->ss_mode = gst_ssm_parse_switch_qualitylevel (demux->parser, download_rate); } } else if (stream->type == SS_STREAM_AUDIO && (demux->ss_mode == SS_MODE_AONLY)) { /* when video is not present using audio download rate to calculate switching */ demux->ss_mode = gst_ssm_parse_switch_qualitylevel (demux->parser, download_rate); if (demux->ss_mode != SS_MODE_AONLY) { g_print ("\n\nMoving to AV mode by audio considering audio download rate\n\n\n\n"); } } g_cond_signal (stream->cond); #ifdef SIMULATE_AUDIO_ONLY /* when fragment count is multiple of 4, switch to audio only case */ if ((stream->frag_cnt % 4 == 0) && (stream->type == SS_STREAM_VIDEO) && GST_SSM_PARSE_IS_LIVE_PRESENTATION(demux->parser)) { g_print ("\n\t ######## Forcibly switching to audio only for testing ##########\n"); demux->ss_mode = SS_MODE_AONLY; } #endif GST_DEBUG_OBJECT (stream->pad, "Signalling eos condition..."); GST_DEBUG_OBJECT (demux, "number of fragments downloaded = %d", stream->frag_cnt); break; } case GST_MESSAGE_ERROR: { GError *error = NULL; gchar* debug = NULL; g_print ("Error from %s\n", gst_element_get_name (GST_MESSAGE_SRC(msg))); gst_message_parse_error( msg, &error, &debug ); if (error) GST_ERROR_OBJECT (demux, "GST_MESSAGE_ERROR: error= %s\n", error->message); GST_ERROR_OBJECT (demux, "GST_MESSAGE_ERROR: debug = %s\n", debug); /* handling error, when client requests url, which is yet to be prepared by server */ if ((!strncmp(error->message, "Precondition Failed", strlen("Precondition Failed"))) && (5 == error->code)) { GstStateChangeReturn ret; /* wait for 1sec & request the url again */ // TODO: need to make wait time as generic or Adding loop count to request again & again GST_INFO_OBJECT (demux, "ERROR : code = %d, msg = %s, NEED to request again", error->code, error->message); usleep (1000000); // 1 sec /* put the current pipeline to NULL state */ gst_element_set_state (stream->pipe, GST_STATE_NULL); gst_element_get_state (stream->pipe, NULL, NULL, GST_CLOCK_TIME_NONE); stream->pipe = stream->urisrc = stream->parser = stream->sink = NULL; g_print ("Going to download fragment AGAIN : %s\n", stream->uri); if (!gst_ss_demux_create_download_pipe (demux, stream, stream->uri, stream->start_ts)) { GST_ERROR_OBJECT (demux, "failed to create download pipeline"); if (!gst_element_post_message (GST_ELEMENT(demux), msg)) { GST_ERROR_OBJECT (demux, "failed to post error"); return FALSE; } } ret = gst_element_set_state (stream->pipe, GST_STATE_PLAYING); if (ret == GST_STATE_CHANGE_FAILURE) { if (!gst_element_post_message (GST_ELEMENT(demux), msg)) { GST_ERROR_OBJECT (demux, "failed to post error"); return FALSE; } } } else { if (error) g_print ("GST_MESSAGE_ERROR: error= %s\n", error->message); g_print ("GST_MESSAGE_ERROR: debug = %s\n", debug); if (!gst_element_post_message (GST_ELEMENT(demux), msg)) { GST_ERROR_OBJECT (demux, "failed to post error"); gst_ss_demux_stop (demux, stream); g_free( debug); debug = NULL; g_error_free( error); return FALSE; } gst_ss_demux_stop (demux, stream); } g_free( debug); debug = NULL; g_error_free( error); break; } case GST_MESSAGE_WARNING: { char* debug = NULL; GError* error = NULL; gst_message_parse_warning(msg, &error, &debug); GST_WARNING_OBJECT(demux, "warning : %s\n", error->message); GST_WARNING_OBJECT(demux, "debug : %s\n", debug); g_error_free( error ); g_free( debug); break; } default : { GST_LOG_OBJECT(demux, "unhandled message : %s\n", gst_message_type_get_name (GST_MESSAGE_TYPE (msg))); break; } } return TRUE; }
enum decoder_command decoder_data(struct decoder *decoder, struct input_stream *is, const void *_data, size_t length, uint16_t kbit_rate) { struct decoder_control *dc = decoder->dc; const char *data = _data; GError *error = NULL; enum decoder_command cmd; assert(dc->state == DECODE_STATE_DECODE); assert(dc->pipe != NULL); assert(length % audio_format_frame_size(&dc->in_audio_format) == 0); decoder_lock(dc); cmd = dc->command; decoder_unlock(dc); if (cmd == DECODE_COMMAND_STOP || cmd == DECODE_COMMAND_SEEK || length == 0) return cmd; /* send stream tags */ if (update_stream_tag(decoder, is)) { if (decoder->decoder_tag != NULL) { /* merge with tag from decoder plugin */ struct tag *tag; tag = tag_merge(decoder->decoder_tag, decoder->stream_tag); cmd = do_send_tag(decoder, is, tag); tag_free(tag); } else /* send only the stream tag */ cmd = do_send_tag(decoder, is, decoder->stream_tag); if (cmd != DECODE_COMMAND_NONE) return cmd; } if (!audio_format_equals(&dc->in_audio_format, &dc->out_audio_format)) { data = pcm_convert(&decoder->conv_state, &dc->in_audio_format, data, length, &dc->out_audio_format, &length, &error); if (data == NULL) { /* the PCM conversion has failed - stop playback, since we have no better way to bail out */ g_warning("%s", error->message); return DECODE_COMMAND_STOP; } } while (length > 0) { struct music_chunk *chunk; char *dest; size_t nbytes; bool full; chunk = decoder_get_chunk(decoder, is); if (chunk == NULL) { assert(dc->command != DECODE_COMMAND_NONE); return dc->command; } dest = music_chunk_write(chunk, &dc->out_audio_format, decoder->timestamp - dc->song->start_ms / 1000.0, kbit_rate, &nbytes); if (dest == NULL) { /* the chunk is full, flush it */ decoder_flush_chunk(decoder); g_cond_signal(dc->client_cond); continue; } assert(nbytes > 0); if (nbytes > length) nbytes = length; /* copy the buffer */ memcpy(dest, data, nbytes); /* expand the music pipe chunk */ full = music_chunk_expand(chunk, &dc->out_audio_format, nbytes); if (full) { /* the chunk is full, flush it */ decoder_flush_chunk(decoder); g_cond_signal(dc->client_cond); } data += nbytes; length -= nbytes; decoder->timestamp += (double)nbytes / audio_format_time_to_size(&dc->out_audio_format); if (dc->song->end_ms > 0 && decoder->timestamp >= dc->song->end_ms / 1000.0) /* the end of this range has been reached: stop decoding */ return DECODE_COMMAND_STOP; } return DECODE_COMMAND_NONE; }
//gboolean //gst_gl_context_create (GstGLContext * context, GstGLContext * other_context, GError ** error) static gpointer gst_gl_context_create_thread (GstGLContext * context) { GstGLContextClass *context_class; GstGLWindowClass *window_class; GstGLFuncs *gl; GstGLAPI compiled_api, user_api, gl_api, display_api; gchar *api_string; gchar *compiled_api_s; gchar *user_api_s; gchar *display_api_s; const gchar *user_choice; GError **error; GstGLContext *other_context; g_mutex_lock (&context->priv->render_lock); GST_DEBUG_OBJECT (context, "Creating thread"); error = context->priv->error; other_context = g_weak_ref_get (&context->priv->other_context_ref); context_class = GST_GL_CONTEXT_GET_CLASS (context); window_class = GST_GL_WINDOW_GET_CLASS (context->window); display_api = gst_gl_display_get_gl_api_unlocked (context->priv->display); if (display_api == GST_GL_API_NONE) { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_API, "Cannot create context with satisfying requested apis " "(display has no GL api!)"); goto failure; } if (window_class->open) { if (!window_class->open (context->window, error)) { GST_WARNING_OBJECT (context, "Failed to open window"); g_assert (error == NULL || *error != NULL); goto failure; } } gl = context->gl_vtable; compiled_api = _compiled_api (); compiled_api_s = gst_gl_api_to_string (compiled_api); user_choice = g_getenv ("GST_GL_API"); user_api = gst_gl_api_from_string (user_choice); user_api_s = gst_gl_api_to_string (user_api); display_api_s = gst_gl_api_to_string (display_api); if ((user_api & compiled_api & display_api) == GST_GL_API_NONE) { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_API, "Cannot create context with the user requested api (%s). " "We have support for (%s), display api (%s)", user_api_s, compiled_api_s, display_api_s); g_free (user_api_s); g_free (compiled_api_s); g_free (display_api_s); goto failure; } if (context_class->choose_format && !context_class->choose_format (context, error)) { GST_WARNING ("Failed to choose format"); g_assert (error == NULL || *error != NULL); g_free (compiled_api_s); g_free (user_api_s); g_free (display_api_s); goto failure; } GST_INFO_OBJECT (context, "Attempting to create opengl context. user chosen api(s) (%s), " "compiled api support (%s) display api (%s)", user_api_s, compiled_api_s, display_api_s); if (!context_class->create_context (context, compiled_api & user_api & display_api, other_context, error)) { GST_WARNING_OBJECT (context, "Failed to create context"); g_assert (error == NULL || *error != NULL); g_free (compiled_api_s); g_free (user_api_s); g_free (display_api_s); goto failure; } GST_INFO_OBJECT (context, "created context"); if (!gst_gl_context_activate (context, TRUE)) { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_RESOURCE_UNAVAILABLE, "Failed to activate the GL Context"); g_free (compiled_api_s); g_free (user_api_s); g_free (display_api_s); goto failure; } gl_api = gst_gl_context_get_gl_api (context); g_assert (gl_api != GST_GL_API_NONE && gl_api != GST_GL_API_ANY); api_string = gst_gl_api_to_string (gl_api); GST_INFO_OBJECT (context, "available GL APIs: %s", api_string); if (((compiled_api & gl_api & display_api) & user_api) == GST_GL_API_NONE) { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_API, "failed to create context, context " "could not provide correct api. user (%s), compiled (%s), context (%s)", user_api_s, compiled_api_s, api_string); g_free (api_string); g_free (compiled_api_s); g_free (user_api_s); g_free (display_api_s); goto failure; } g_free (api_string); g_free (compiled_api_s); g_free (user_api_s); g_free (display_api_s); GST_DEBUG_OBJECT (context, "Filling info"); if (!gst_gl_context_fill_info (context, error)) { g_assert (error == NULL || *error != NULL); goto failure; } context->priv->alive = TRUE; if (gl->DebugMessageCallback) { #if !defined(GST_DISABLE_GST_DEBUG) GST_INFO_OBJECT (context, "Enabling GL context debugging"); /* enable them all */ gl->DebugMessageControl (GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, 0, GL_TRUE); gl->DebugMessageCallback (_gst_gl_debug_callback, context); #endif } if (other_context) { GST_DEBUG_OBJECT (context, "Unreffing other_context %" GST_PTR_FORMAT, other_context); gst_object_unref (other_context); } g_cond_signal (&context->priv->create_cond); // g_mutex_unlock (&context->priv->render_lock); gst_gl_window_send_message_async (context->window, (GstGLWindowCB) _unlock_create_thread, context, NULL); gst_gl_window_run (context->window); GST_INFO_OBJECT (context, "loop exited"); g_mutex_lock (&context->priv->render_lock); context->priv->alive = FALSE; gst_gl_context_activate (context, FALSE); context_class->destroy_context (context); /* User supplied callback */ if (context->window->close) context->window->close (context->window->close_data); /* window specific shutdown */ if (window_class->close) { window_class->close (context->window); } g_cond_signal (&context->priv->destroy_cond); g_mutex_unlock (&context->priv->render_lock); return NULL; failure: { if (other_context) gst_object_unref (other_context); g_cond_signal (&context->priv->create_cond); g_mutex_unlock (&context->priv->render_lock); return NULL; } }
static void gst_droidcamsrc_dev_video_frame_callback (void *user, DroidMediaCameraRecordingData * video_data) { GstDroidCamSrcDev *dev = (GstDroidCamSrcDev *) user; GstDroidCamSrc *src = GST_DROIDCAMSRC (GST_PAD_PARENT (dev->imgsrc->pad)); void *data = droid_media_camera_recording_frame_get_data (video_data); GstBuffer *buffer; GstMemory *mem; GstDroidCamSrcDevVideoData *mem_data; gboolean drop_buffer; GST_DEBUG_OBJECT (src, "dev video frame callback"); g_mutex_lock (&dev->vid->lock); /* TODO: not sure what to do with timestamp */ /* unlikely but just in case */ if (G_UNLIKELY (!data)) { GST_ERROR ("invalid memory from camera HAL"); droid_media_camera_release_recording_frame (dev->cam, video_data); goto unlock_and_out; } /* TODO: this is bad */ mem_data = g_slice_new0 (GstDroidCamSrcDevVideoData); mem_data->dev = dev; mem_data->data = video_data; buffer = gst_buffer_new (); mem = gst_wrapped_memory_allocator_wrap (dev->wrap_allocator, data, droid_media_camera_recording_frame_get_size (video_data), (GFunc) gst_droidcamsrc_dev_release_recording_frame, mem_data); gst_buffer_insert_memory (buffer, 0, mem); GST_BUFFER_OFFSET (buffer) = dev->vid->video_frames; GST_BUFFER_OFFSET_END (buffer) = ++dev->vid->video_frames; gst_droidcamsrc_timestamp (src, buffer); g_rec_mutex_lock (dev->lock); ++dev->vid->queued_frames; g_rec_mutex_unlock (dev->lock); drop_buffer = !dev->vid->running; if (drop_buffer) { GST_INFO_OBJECT (src, "dropping buffer because video recording is not running"); gst_buffer_unref (buffer); } else { g_mutex_lock (&dev->vidsrc->lock); g_queue_push_tail (dev->vidsrc->queue, buffer); g_cond_signal (&dev->vidsrc->cond); g_mutex_unlock (&dev->vidsrc->lock); } unlock_and_out: /* in case stop_video_recording() is waiting for us */ g_cond_signal (&dev->vid->cond); g_mutex_unlock (&dev->vid->lock); }
static gboolean gst_dshowvideosrc_push_buffer (guint8 * buffer, guint size, gpointer src_object, GstClockTime duration) { GstDshowVideoSrc *src = GST_DSHOWVIDEOSRC (src_object); GstBuffer *buf = NULL; IPin *pPin = NULL; HRESULT hres = S_FALSE; AM_MEDIA_TYPE *pMediaType = NULL; GstMapInfo info; if (!buffer || size == 0 || !src) { return FALSE; } /* create a new buffer assign to it the clock time as timestamp */ buf = gst_buffer_new_and_alloc (size); gst_buffer_set_size(buf, size); GstClock *clock = gst_element_get_clock (GST_ELEMENT (src)); GST_BUFFER_TIMESTAMP (buf) = GST_CLOCK_DIFF (gst_element_get_base_time (GST_ELEMENT (src)), gst_clock_get_time (clock)); gst_object_unref (clock); GST_BUFFER_DURATION (buf) = duration; if (!gst_buffer_map(buf, &info, GST_MAP_WRITE)) { gst_buffer_unref(buf); GST_ERROR("Failed to map buffer"); return FALSE; } if (src->is_rgb) { /* FOR RGB directshow decoder will return bottom-up BITMAP * There is probably a way to get top-bottom video frames from * the decoder... */ gint line = 0; gint stride = size / src->height; for (; line < src->height; line++) { memcpy (info.data + (line * stride), buffer + (size - ((line + 1) * (stride))), stride); } } else { memcpy (info.data, buffer, size); } gst_buffer_unmap(buf, &info); GST_DEBUG ("push_buffer => pts %" GST_TIME_FORMAT "duration %" GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), GST_TIME_ARGS (duration)); g_mutex_lock (&src->buffer_mutex); if (src->buffer != NULL) gst_buffer_unref (src->buffer); src->buffer = buf; g_cond_signal (&src->buffer_cond); g_mutex_unlock (&src->buffer_mutex); return TRUE; }
static PyObject *Decoder_wait(PyObject *self, PyObject *args) { int ret; unsigned int i; gboolean found_match; struct srd_decoder_inst *di; PyObject *py_pinvalues, *py_matched; if (!self || !args) return NULL; if (!(di = srd_inst_find_by_obj(NULL, self))) { PyErr_SetString(PyExc_Exception, "decoder instance not found"); Py_RETURN_NONE; } ret = set_new_condition_list(self, args); if (ret < 0) { srd_dbg("%s: %s: Aborting wait().", di->inst_id, __func__); return NULL; } if (ret == 9999) { /* Empty condition list, automatic match. */ PyObject_SetAttrString(di->py_inst, "matched", Py_None); /* Leave self.samplenum unchanged (== di->abs_cur_samplenum). */ return get_current_pinvalues(di); } while (1) { /* Wait for new samples to process, or termination request. */ g_mutex_lock(&di->data_mutex); while (!di->got_new_samples && !di->want_wait_terminate) g_cond_wait(&di->got_new_samples_cond, &di->data_mutex); /* * Check whether any of the current condition(s) match. * Arrange for termination requests to take a code path which * won't find new samples to process, pretends to have processed * previously stored samples, and returns to the main thread, * while the termination request still gets signalled. */ found_match = FALSE; ret = process_samples_until_condition_match(di, &found_match); /* If there's a match, set self.samplenum etc. and return. */ if (found_match) { /* Set self.samplenum to the (absolute) sample number that matched. */ PyObject_SetAttrString(di->py_inst, "samplenum", PyLong_FromLong(di->abs_cur_samplenum)); if (di->match_array && di->match_array->len > 0) { py_matched = PyTuple_New(di->match_array->len); for (i = 0; i < di->match_array->len; i++) PyTuple_SetItem(py_matched, i, PyBool_FromLong(di->match_array->data[i])); PyObject_SetAttrString(di->py_inst, "matched", py_matched); match_array_free(di); } else { PyObject_SetAttrString(di->py_inst, "matched", Py_None); } py_pinvalues = get_current_pinvalues(di); g_mutex_unlock(&di->data_mutex); return py_pinvalues; } /* No match, reset state for the next chunk. */ di->got_new_samples = FALSE; di->handled_all_samples = TRUE; di->abs_start_samplenum = 0; di->abs_end_samplenum = 0; di->inbuf = NULL; di->inbuflen = 0; /* Signal the main thread that we handled all samples. */ g_cond_signal(&di->handled_all_samples_cond); /* * When termination of wait() and decode() was requested, * then exit the loop after releasing the mutex. */ if (di->want_wait_terminate) { srd_dbg("%s: %s: Will return from wait().", di->inst_id, __func__); g_mutex_unlock(&di->data_mutex); return NULL; } g_mutex_unlock(&di->data_mutex); } Py_RETURN_NONE; }
void push_message(GString *msg) { MessageID msgid = get_message_id(msg); if (((unsigned char)msg->str[0] == 0xF0) && ((unsigned char)msg->str[msg->len-1] == 0xF7)) { debug_msg(DEBUG_VERBOSE, "Pushing correct message!"); } else { g_warning("Pushing incorrect message!"); } int x; if (debug_flag_is_set(DEBUG_HEX)) { for (x = 0; x<msg->len; x++) { if (x && (x % HEX_WIDTH) == 0) { printf("\n"); } printf("%02x ", (unsigned char)msg->str[x]); } if (x % HEX_WIDTH) { printf("\n"); } } debug_msg(DEBUG_VERBOSE, "Received %s", get_message_name(msgid)); SettingParam *param; switch (msgid) { case ACK: g_string_free(msg, TRUE); return; case NACK: g_warning("Received NACK!"); g_string_free(msg, TRUE); return; case RECEIVE_PARAMETER_VALUE: { unpack_message(msg); param = setting_param_new_from_data(&msg->str[8], NULL); if (debug_flag_is_set(DEBUG_MSG2HOST)) { GString *ipv = format_ipv(param->id, param->position, param->value); debug_msg(DEBUG_MSG2HOST, "Receive RECEIVE_PARAMETER_VALUE: %s", ipv->str); g_string_free(ipv, TRUE); } GDK_THREADS_ENTER(); apply_setting_param_to_gui(param); GDK_THREADS_LEAVE(); setting_param_free(param); g_string_free(msg, TRUE); return; } case RECEIVE_DEVICE_NOTIFICATION: { unsigned char *str = (unsigned char*)msg->str; unpack_message(msg); switch (str[8]) { case NOTIFY_PRESET_MOVED: if (str[11] == PRESETS_EDIT_BUFFER && str[12] == 0) { GDK_THREADS_ENTER(); g_timeout_add(0, apply_current_preset_to_gui, NULL); GDK_THREADS_LEAVE(); debug_msg(DEBUG_MSG2HOST, "Receive RECEIVE_DEVICE_NOTIFICATION: Loaded preset " "%d from bank %d", str[10], str[9]); } else { debug_msg(DEBUG_MSG2HOST, "Receive RECEIVE_DEVICE_NOTIFICATION: %d %d moved to " "%d %d", str[9], str[10], str[11], str[12]); } break; case NOTIFY_MODIFIER_GROUP_CHANGED: { int i; if (debug_flag_is_set(DEBUG_HEX)) { printf("\n"); for (i = 0; i < msg->len; i++) { printf(" %02x", (unsigned char) str[i]); } printf("\n"); } debug_msg(DEBUG_MSG2HOST, "Receive NOTIFY_MODIFIER_GROUP_CHANGED: Modifier group " "id %d changed", (str[9] << 8) | (str[10])); break; } default: g_warning("Received unhandled device notification 0x%x", str[11]); break; } g_string_free(msg, TRUE); return; } case RECEIVE_GLOBAL_PARAMETERS: { gint tot, n, x; unpack_message(msg); tot = (unsigned char)msg->str[9]; if (debug_flag_is_set(DEBUG_HEX)) { for (n = 0; n < msg->len; n++) { printf("%02x ",(unsigned char) msg->str[n]); } printf("\n"); } n = 0; x = 10; do { param = setting_param_new_from_data(&msg->str[x], &x); debug_msg(DEBUG_MSG2HOST, "Receive RECEIVE_GLOBAL_PARAMETERS ID: %5d " "Position: %2.1d Value: %6.1d: %s", param->id, param->position, param->value, "XXX"); setting_param_free(param); } while ( (x < msg->len) && n < tot); g_string_free(msg, TRUE); return; } case RECEIVE_MODIFIER_LINKABLE_LIST: { gint tot, n; unpack_message(msg); tot = (unsigned char)msg->str[9]; if (debug_flag_is_set(DEBUG_HEX)) { for (n = 0; n < msg->len; n++) { printf("%02x ",(unsigned char) msg->str[n]); } printf("\n"); } modifier_linkable_list(msg); g_string_free(msg, TRUE); return; } default: g_mutex_lock(message_queue_mutex); g_queue_push_tail(message_queue, msg); g_cond_signal(message_queue_cond); g_mutex_unlock(message_queue_mutex); break; } }
static gpointer gegl_tile_backend_swap_writer_thread (gpointer ignored) { while (TRUE) { ThreadParams *params; g_mutex_lock (&mutex); while (g_queue_is_empty (queue) && !exit_thread) g_cond_wait (&queue_cond, &mutex); if (exit_thread) { g_mutex_unlock (&mutex); GEGL_NOTE (GEGL_DEBUG_TILE_BACKEND, "exiting writer thread"); return NULL; } params = (ThreadParams *)g_queue_pop_head (queue); if (params->operation == OP_WRITE) { in_progress = params; params->entry->link = NULL; } g_mutex_unlock (&mutex); switch (params->operation) { case OP_WRITE: gegl_tile_backend_swap_write (params); break; case OP_TRUNCATE: if (ftruncate (out_fd, total) != 0) g_warning ("failed to resize swap file: %s", g_strerror (errno)); break; } g_mutex_lock (&mutex); in_progress = NULL; if (params->operation == OP_WRITE) { queue_size -= params->length + sizeof (GList) + sizeof (ThreadParams); g_free (params->source); /* unblock the main thread if the queue had gotten too big */ if (queue_size < gegl_config ()->queue_size) g_cond_signal (&max_cond); } g_slice_free (ThreadParams, params); g_mutex_unlock (&mutex); } return NULL; }
static OMX_ERRORTYPE EventHandler (OMX_HANDLETYPE omx_handle, OMX_PTR app_data, OMX_EVENTTYPE event, OMX_U32 data_1, OMX_U32 data_2, OMX_PTR event_data) { GOmxCore *core; core = (GOmxCore *) app_data; switch (event) { case OMX_EventCmdComplete: { OMX_COMMANDTYPE cmd; cmd = (OMX_COMMANDTYPE) data_1; GST_DEBUG_OBJECT (core->object, "OMX_EventCmdComplete: %d", cmd); switch (cmd) { case OMX_CommandStateSet: complete_change_state (core, data_2); break; case OMX_CommandFlush: g_sem_up (core->flush_sem); break; case OMX_CommandPortDisable: case OMX_CommandPortEnable: g_sem_up (core->port_sem); default: break; } break; } case OMX_EventBufferFlag: { GST_DEBUG_OBJECT (core->object, "OMX_EventBufferFlag"); if (data_2 & OMX_BUFFERFLAG_EOS) { g_omx_core_set_done (core); } break; } case OMX_EventPortSettingsChanged: { GST_DEBUG_OBJECT (core->object, "OMX_EventPortSettingsChanged"); /** @todo only on the relevant port. */ if (core->settings_changed_cb) { core->settings_changed_cb (core); } break; } case OMX_EventIndexSettingChanged: { GST_DEBUG_OBJECT (core->object, "OMX_EventIndexSettingsChanged"); if (core->index_settings_changed_cb) { core->index_settings_changed_cb (core, data_1, data_2); } break; } case OMX_EventError: { core->omx_error = data_1; GST_ERROR_OBJECT (core->object, "unrecoverable error: %s (0x%lx)", g_omx_error_to_str (data_1), data_1); /* component might leave us waiting for buffers, unblock */ g_omx_core_flush_start (core); /* unlock wait_for_state */ g_mutex_lock (core->omx_state_mutex); g_cond_signal (core->omx_state_condition); g_mutex_unlock (core->omx_state_mutex); break; } #ifdef USE_OMXTICORE case OMX_TI_EventBufferRefCount: { OMX_BUFFERHEADERTYPE *omx_buffer = (OMX_BUFFERHEADERTYPE *)data_1; GOmxPort *port = get_port (core, omx_buffer->nOutputPortIndex); GST_DEBUG_OBJECT (core->object, "unref: omx_buffer=%p, pAppPrivate=%p, pBuffer=%p", omx_buffer, omx_buffer->pAppPrivate, omx_buffer->pBuffer); g_mutex_lock (core->omx_state_mutex); omx_buffer->nFlags |= GST_BUFFERFLAG_UNREF_CHECK; g_mutex_unlock (core->omx_state_mutex); g_omx_port_push_buffer (port, omx_buffer); break; } #endif default: GST_WARNING_OBJECT (core->object, "unhandled event: %d", event); break; } return OMX_ErrorNone; }
static void chr_read(void *opaque, const uint8_t *buf, int size) { TestServer *s = opaque; CharDriverState *chr = s->chr; VhostUserMsg msg; uint8_t *p = (uint8_t *) &msg; int fd; if (s->test_fail) { qemu_chr_disconnect(chr); /* now switch to non-failure */ s->test_fail = false; } if (size != VHOST_USER_HDR_SIZE) { g_test_message("Wrong message size received %d\n", size); return; } g_mutex_lock(&s->data_mutex); memcpy(p, buf, VHOST_USER_HDR_SIZE); if (msg.size) { p += VHOST_USER_HDR_SIZE; size = qemu_chr_fe_read_all(chr, p, msg.size); if (size != msg.size) { g_test_message("Wrong message size received %d != %d\n", size, msg.size); return; } } switch (msg.request) { case VHOST_USER_GET_FEATURES: /* send back features to qemu */ msg.flags |= VHOST_USER_REPLY_MASK; msg.size = sizeof(m.payload.u64); msg.payload.u64 = 0x1ULL << VHOST_F_LOG_ALL | 0x1ULL << VHOST_USER_F_PROTOCOL_FEATURES; if (s->queues > 1) { msg.payload.u64 |= 0x1ULL << VIRTIO_NET_F_MQ; } if (s->test_flags >= TEST_FLAGS_BAD) { msg.payload.u64 = 0; s->test_flags = TEST_FLAGS_END; } p = (uint8_t *) &msg; qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE + msg.size); break; case VHOST_USER_SET_FEATURES: g_assert_cmpint(msg.payload.u64 & (0x1ULL << VHOST_USER_F_PROTOCOL_FEATURES), !=, 0ULL); if (s->test_flags == TEST_FLAGS_DISCONNECT) { qemu_chr_disconnect(chr); s->test_flags = TEST_FLAGS_BAD; } break; case VHOST_USER_GET_PROTOCOL_FEATURES: /* send back features to qemu */ msg.flags |= VHOST_USER_REPLY_MASK; msg.size = sizeof(m.payload.u64); msg.payload.u64 = 1 << VHOST_USER_PROTOCOL_F_LOG_SHMFD; if (s->queues > 1) { msg.payload.u64 |= 1 << VHOST_USER_PROTOCOL_F_MQ; } p = (uint8_t *) &msg; qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE + msg.size); break; case VHOST_USER_GET_VRING_BASE: /* send back vring base to qemu */ msg.flags |= VHOST_USER_REPLY_MASK; msg.size = sizeof(m.payload.state); msg.payload.state.num = 0; p = (uint8_t *) &msg; qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE + msg.size); assert(msg.payload.state.index < s->queues * 2); s->rings &= ~(0x1ULL << msg.payload.state.index); break; case VHOST_USER_SET_MEM_TABLE: /* received the mem table */ memcpy(&s->memory, &msg.payload.memory, sizeof(msg.payload.memory)); s->fds_num = qemu_chr_fe_get_msgfds(chr, s->fds, G_N_ELEMENTS(s->fds)); /* signal the test that it can continue */ g_cond_signal(&s->data_cond); break; case VHOST_USER_SET_VRING_KICK: case VHOST_USER_SET_VRING_CALL: /* consume the fd */ qemu_chr_fe_get_msgfds(chr, &fd, 1); /* * This is a non-blocking eventfd. * The receive function forces it to be blocking, * so revert it back to non-blocking. */ qemu_set_nonblock(fd); break; case VHOST_USER_SET_LOG_BASE: if (s->log_fd != -1) { close(s->log_fd); s->log_fd = -1; } qemu_chr_fe_get_msgfds(chr, &s->log_fd, 1); msg.flags |= VHOST_USER_REPLY_MASK; msg.size = 0; p = (uint8_t *) &msg; qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE); g_cond_signal(&s->data_cond); break; case VHOST_USER_SET_VRING_BASE: assert(msg.payload.state.index < s->queues * 2); s->rings |= 0x1ULL << msg.payload.state.index; break; case VHOST_USER_GET_QUEUE_NUM: msg.flags |= VHOST_USER_REPLY_MASK; msg.size = sizeof(m.payload.u64); msg.payload.u64 = s->queues; p = (uint8_t *) &msg; qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE + msg.size); break; default: break; } g_mutex_unlock(&s->data_mutex); }
/** * hls_progress_buffer_sink_event() * * Receives event from the sink pad (currently, data from javasource). When an event comes in, * we get the data from the pad by getting at the ProgressBuffer* object associated with the pad. */ static gboolean hls_progress_buffer_sink_event(GstPad *pad, GstEvent *event) { HLSProgressBuffer *element = HLS_PROGRESS_BUFFER(GST_PAD_PARENT(pad)); gboolean ret = FALSE; switch (GST_EVENT_TYPE (event)) { case GST_EVENT_NEWSEGMENT: { gboolean update; GstFormat format; gdouble rate, arate; gint64 start, stop, time; g_mutex_lock(element->lock); if (element->srcresult != GST_FLOW_OK) { // INLINE - gst_event_unref() gst_event_unref(event); g_mutex_unlock(element->lock); return TRUE; } g_mutex_unlock(element->lock); if (element->is_eos) { element->is_eos = FALSE; element->srcresult = GST_FLOW_OK; if (gst_pad_is_linked(element->srcpad)) gst_pad_start_task(element->srcpad, hls_progress_buffer_loop, element); } // In HLS mode javasource will set time to correct position in time unit, even if segment in byte units. // Maybe not perfect, but works. gst_event_parse_new_segment_full(event, &update, &rate, &arate, &format, &start, &stop, &time); // INLINE - gst_event_unref() gst_event_unref(event); ret = TRUE; if (stop - start <= 0) { gst_element_message_full(GST_ELEMENT(element), GST_MESSAGE_ERROR, GST_STREAM_ERROR, GST_STREAM_ERROR_WRONG_TYPE, g_strdup("Only limited content is supported by hlsprogressbuffer."), NULL, ("hlsprogressbuffer.c"), ("hls_progress_buffer_src_event"), 0); return TRUE; } if (element->send_new_segment) { event = gst_event_new_new_segment(update, rate, GST_FORMAT_TIME, 0, -1, time); element->send_new_segment = FALSE; ret = gst_pad_push_event(element->srcpad, event); } // Get and prepare next write segment g_mutex_lock(element->lock); element->cache_write_index = (element->cache_write_index + 1) % NUM_OF_CACHED_SEGMENTS; while (element->srcresult == GST_FLOW_OK && !element->cache_write_ready[element->cache_write_index]) { g_mutex_unlock(element->lock); send_hls_full_message(element); g_mutex_lock(element->lock); g_cond_wait(element->del_cond, element->lock); if (element->srcresult != GST_FLOW_OK) { g_mutex_unlock(element->lock); return TRUE; } } element->cache_size[element->cache_write_index] = stop; element->cache_write_ready[element->cache_write_index] = FALSE; cache_set_write_position(element->cache[element->cache_write_index], 0); cache_set_read_position(element->cache[element->cache_write_index], 0); g_mutex_unlock(element->lock); send_hls_resume_message(element); // Send resume message for each segment } break; case GST_EVENT_FLUSH_START: g_mutex_lock(element->lock); element->is_flushing = TRUE; g_mutex_unlock(element->lock); ret = gst_pad_push_event(element->srcpad, event); hls_progress_buffer_flush_data(element); if (gst_pad_is_linked(element->srcpad)) gst_pad_pause_task(element->srcpad); break; case GST_EVENT_FLUSH_STOP: ret = gst_pad_push_event(element->srcpad, event); g_mutex_lock(element->lock); element->send_new_segment = TRUE; element->is_flushing = FALSE; element->srcresult = GST_FLOW_OK; if (!element->is_eos && gst_pad_is_linked(element->srcpad)) gst_pad_start_task(element->srcpad, hls_progress_buffer_loop, element); g_mutex_unlock(element->lock); break; case GST_EVENT_EOS: send_hls_eos_message(element); // Just in case we stall g_mutex_lock(element->lock); element->is_eos = TRUE; g_cond_signal(element->add_cond); g_mutex_unlock(element->lock); // INLINE - gst_event_unref() gst_event_unref(event); ret = TRUE; break; default: ret = gst_pad_push_event(element->srcpad, event); break; } return ret; }
//gboolean //gst_gl_context_create (GstGLContext * context, GstGLContext * other_context, GError ** error) static gpointer gst_gl_context_create_thread (GstGLContext * context) { GstGLContextClass *context_class; GstGLWindowClass *window_class; GstGLDisplay *display; GstGLFuncs *gl; gint gl_major = 0, gl_minor = 0; gboolean ret = FALSE; GstGLAPI compiled_api, user_api; gchar *api_string; gchar *compiled_api_s; gchar *user_api_string; const gchar *user_choice, *extensions; GError **error; GstGLContext *other_context; g_mutex_lock (&context->priv->render_lock); error = context->priv->error; other_context = context->priv->other_context; context_class = GST_GL_CONTEXT_GET_CLASS (context); window_class = GST_GL_WINDOW_GET_CLASS (context->window); if (window_class->open) { if (!window_class->open (context->window, error)) goto failure; } display = context->priv->display; gl = context->gl_vtable; compiled_api = _compiled_api (); user_choice = g_getenv ("GST_GL_API"); user_api = gst_gl_api_from_string (user_choice); user_api_string = gst_gl_api_to_string (user_api); compiled_api_s = gst_gl_api_to_string (compiled_api); if ((user_api & compiled_api) == GST_GL_API_NONE) { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_API, "Cannot create context with the user requested api (%s). " "We have support for (%s)", user_api_string, compiled_api_s); g_free (user_api_string); g_free (compiled_api_s); goto failure; } if (context_class->choose_format && !context_class->choose_format (context, error)) { g_assert (error == NULL || *error != NULL); g_free (compiled_api_s); g_free (user_api_string); goto failure; } GST_INFO ("Attempting to create opengl context. user chosen api(s) (%s), " "compiled api support (%s)", user_api_string, compiled_api_s); if (!context_class->create_context (context, compiled_api & user_api, other_context, error)) { g_assert (error == NULL || *error != NULL); g_free (compiled_api_s); g_free (user_api_string); goto failure; } GST_INFO ("created context"); if (!context_class->activate (context, TRUE)) { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_RESOURCE_UNAVAILABLE, "Failed to activate the GL Context"); g_free (compiled_api_s); g_free (user_api_string); goto failure; } display->gl_api = gst_gl_context_get_gl_api (context); g_assert (display->gl_api != GST_GL_API_NONE && display->gl_api != GST_GL_API_ANY); api_string = gst_gl_api_to_string (display->gl_api); GST_INFO ("available GL APIs: %s", api_string); if (((compiled_api & display->gl_api) & user_api) == GST_GL_API_NONE) { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_API, "failed to create context, context " "could not provide correct api. user (%s), compiled (%s), context (%s)", user_api_string, compiled_api_s, api_string); g_free (api_string); g_free (compiled_api_s); g_free (user_api_string); goto failure; } g_free (api_string); g_free (compiled_api_s); g_free (user_api_string); gl->GetError = gst_gl_context_get_proc_address (context, "glGetError"); gl->GetString = gst_gl_context_get_proc_address (context, "glGetString"); gl->GetStringi = gst_gl_context_get_proc_address (context, "glGetStringi"); gl->GetIntegerv = gst_gl_context_get_proc_address (context, "glGetIntegerv"); if (!gl->GetError || !gl->GetString) { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_FAILED, "could not GetProcAddress core opengl functions"); goto failure; } /* gl api specific code */ if (!ret && USING_OPENGL (display)) ret = _create_context_opengl (context, &gl_major, &gl_minor, error); if (!ret && USING_GLES2 (display)) ret = _create_context_gles2 (context, &gl_major, &gl_minor, error); if (!ret) goto failure; /* GL core contexts and GLES3 */ if (gl->GetIntegerv && gl->GetStringi) { extensions = _build_extension_string (context); } else { extensions = (const gchar *) gl->GetString (GL_EXTENSIONS); } _gst_gl_feature_check_ext_functions (context, gl_major, gl_minor, extensions); context->priv->alive = TRUE; g_cond_signal (&context->priv->create_cond); // g_mutex_unlock (&context->priv->render_lock); gst_gl_window_send_message_async (context->window, (GstGLWindowCB) _unlock_create_thread, context, NULL); gst_gl_window_run (context->window); GST_INFO ("loop exited\n"); g_mutex_lock (&context->priv->render_lock); context->priv->alive = FALSE; context_class->activate (context, FALSE); context_class->destroy_context (context); /* User supplied callback */ if (context->window->close) context->window->close (context->window->close_data); /* window specific shutdown */ if (window_class->close) { window_class->close (context->window); } g_cond_signal (&context->priv->destroy_cond); g_mutex_unlock (&context->priv->render_lock); return NULL; failure: { g_cond_signal (&context->priv->create_cond); g_mutex_unlock (&context->priv->render_lock); return NULL; } }
/* Called in the gl thread */ void gst_gl_window_run_loop (GstGLWindow * window) { GstGLWindowPrivate *priv = window->priv; g_debug ("begin loop\n"); g_mutex_lock (priv->x_lock); while (priv->running) { XEvent event; XEvent pending_event; g_mutex_unlock (priv->x_lock); /* XSendEvent (which are called in other threads) are done from another display structure */ XNextEvent (priv->device, &event); g_mutex_lock (priv->x_lock); // use in generic/cube and other related uses priv->allow_extra_expose_events = XPending (priv->device) <= 2; switch (event.type) { case ClientMessage: { Atom wm_delete = XInternAtom (priv->device, "WM_DELETE_WINDOW", True); Atom wm_gl = XInternAtom (priv->device, "WM_GL_WINDOW", True); Atom wm_quit_loop = XInternAtom (priv->device, "WM_QUIT_LOOP", True); if (wm_delete == None) g_debug ("Cannot create WM_DELETE_WINDOW\n"); if (wm_gl == None) g_debug ("Cannot create WM_GL_WINDOW\n"); if (wm_quit_loop == None) g_debug ("Cannot create WM_QUIT_LOOP\n"); /* Message sent with gst_gl_window_send_message */ if (wm_gl != None && event.xclient.message_type == wm_gl) { if (priv->running) { #if SIZEOF_VOID_P == 8 GstGLWindowCB custom_cb = (GstGLWindowCB) (((event.xclient.data. l[0] & 0xffffffff) << 32) | (event.xclient.data. l[1] & 0xffffffff)); gpointer custom_data = (gpointer) (((event.xclient.data. l[2] & 0xffffffff) << 32) | (event.xclient.data. l[3] & 0xffffffff)); #else GstGLWindowCB custom_cb = (GstGLWindowCB) event.xclient.data.l[0]; gpointer custom_data = (gpointer) event.xclient.data.l[1]; #endif if (!custom_cb || !custom_data) g_debug ("custom cb not initialized\n"); custom_cb (custom_data); } g_cond_signal (priv->cond_send_message); } /* User clicked on the cross */ else if (wm_delete != None && (Atom) event.xclient.data.l[0] == wm_delete) { g_debug ("Close %lud\n", (gulong) priv->internal_win_id); if (priv->close_cb) priv->close_cb (priv->close_data); priv->draw_cb = NULL; priv->draw_data = NULL; priv->resize_cb = NULL; priv->resize_data = NULL; priv->close_cb = NULL; priv->close_data = NULL; } /* message sent with gst_gl_window_quit_loop */ else if (wm_quit_loop != None && event.xclient.message_type == wm_quit_loop) { #if SIZEOF_VOID_P == 8 GstGLWindowCB destroy_cb = (GstGLWindowCB) (((event.xclient.data. l[0] & 0xffffffff) << 32) | (event.xclient.data. l[1] & 0xffffffff)); gpointer destroy_data = (gpointer) (((event.xclient.data. l[2] & 0xffffffff) << 32) | (event.xclient.data. l[3] & 0xffffffff)); #else GstGLWindowCB destroy_cb = (GstGLWindowCB) event.xclient.data.l[0]; gpointer destroy_data = (gpointer) event.xclient.data.l[1]; #endif g_debug ("Quit loop message %lud\n", (gulong) priv->internal_win_id); /* exit loop */ priv->running = FALSE; /* make sure last pendings send message calls are executed */ XFlush (priv->device); while (XCheckTypedEvent (priv->device, ClientMessage, &pending_event)) { #if SIZEOF_VOID_P == 8 GstGLWindowCB custom_cb = (GstGLWindowCB) (((event.xclient.data. l[0] & 0xffffffff) << 32) | (event.xclient.data. l[1] & 0xffffffff)); gpointer custom_data = (gpointer) (((event.xclient.data. l[2] & 0xffffffff) << 32) | (event.xclient.data. l[3] & 0xffffffff)); #else GstGLWindowCB custom_cb = (GstGLWindowCB) event.xclient.data.l[0]; gpointer custom_data = (gpointer) event.xclient.data.l[1]; #endif g_debug ("execute last pending custom x events\n"); if (!custom_cb || !custom_data) g_debug ("custom cb not initialized\n"); custom_cb (custom_data); g_cond_signal (priv->cond_send_message); } /* Finally we can destroy opengl ressources (texture/shaders/fbo) */ if (!destroy_cb || !destroy_data) g_debug ("destroy cb not correclty set\n"); destroy_cb (destroy_data); } else g_debug ("client message not reconized \n"); break; } case CreateNotify: case ConfigureNotify: { if (priv->resize_cb) priv->resize_cb (priv->resize_data, event.xconfigure.width, event.xconfigure.height); break; } case DestroyNotify: g_debug ("DestroyNotify\n"); break; case Expose: if (priv->draw_cb) { priv->draw_cb (priv->draw_data); glFlush (); eglSwapBuffers (priv->gl_display, priv->gl_surface); } break; case VisibilityNotify: { switch (event.xvisibility.state) { case VisibilityUnobscured: if (priv->draw_cb) priv->draw_cb (priv->draw_data); break; case VisibilityPartiallyObscured: if (priv->draw_cb) priv->draw_cb (priv->draw_data); break; case VisibilityFullyObscured: break; default: g_debug ("unknown xvisibility event: %d\n", event.xvisibility.state); break; } break; } default: g_debug ("unknown XEvent type: %ud\n", event.type); break; } // switch } // while running g_mutex_unlock (priv->x_lock); g_debug ("end loop\n"); }
static gboolean wv_play (InputPlayback * playback, const gchar * filename, VFSFile * file, gint start_time, gint stop_time, gboolean pause) { if (file == NULL) return FALSE; gint32 *input = NULL; void *output = NULL; gint sample_rate, num_channels, bits_per_sample; guint num_samples; WavpackContext *ctx = NULL; VFSFile *wvc_input = NULL; gboolean error = FALSE; if (! wv_attach (filename, file, & wvc_input, & ctx, NULL, OPEN_TAGS | OPEN_WVC)) { g_warning("Error opening Wavpack file '%s'.", filename); error = TRUE; goto error_exit; } sample_rate = WavpackGetSampleRate(ctx); num_channels = WavpackGetNumChannels(ctx); bits_per_sample = WavpackGetBitsPerSample(ctx); num_samples = WavpackGetNumSamples(ctx); if (!playback->output->open_audio(SAMPLE_FMT(bits_per_sample), sample_rate, num_channels)) { g_warning("Error opening audio output."); error = TRUE; goto error_exit; } if (pause) playback->output->pause(TRUE); input = g_malloc(BUFFER_SIZE * num_channels * sizeof(guint32)); output = g_malloc(BUFFER_SIZE * num_channels * SAMPLE_SIZE(bits_per_sample)); if (input == NULL || output == NULL) goto error_exit; playback->set_gain_from_playlist(playback); g_mutex_lock(ctrl_mutex); playback->set_params(playback, (gint) WavpackGetAverageBitrate(ctx, num_channels), sample_rate, num_channels); seek_value = (start_time > 0) ? start_time : -1; stop_flag = FALSE; playback->set_pb_ready(playback); g_mutex_unlock(ctrl_mutex); while (!stop_flag && (stop_time < 0 || playback->output->written_time () < stop_time)) { gint ret; guint samples_left; /* Handle seek and pause requests */ g_mutex_lock(ctrl_mutex); if (seek_value >= 0) { playback->output->flush (seek_value); WavpackSeekSample (ctx, (gint64) seek_value * sample_rate / 1000); seek_value = -1; g_cond_signal(ctrl_cond); } g_mutex_unlock(ctrl_mutex); /* Decode audio data */ samples_left = num_samples - WavpackGetSampleIndex(ctx); ret = WavpackUnpackSamples(ctx, input, BUFFER_SIZE); if (samples_left == 0) stop_flag = TRUE; else if (ret < 0) { g_warning("Error decoding file.\n"); break; } else { /* Perform audio data conversion and output */ guint i; gint32 *rp = input; gint8 *wp = output; gint16 *wp2 = output; gint32 *wp4 = output; if (bits_per_sample == 8) { for (i = 0; i < ret * num_channels; i++, wp++, rp++) *wp = *rp & 0xff; } else if (bits_per_sample == 16) { for (i = 0; i < ret * num_channels; i++, wp2++, rp++) *wp2 = *rp & 0xffff; } else if (bits_per_sample == 24 || bits_per_sample == 32) { for (i = 0; i < ret * num_channels; i++, wp4++, rp++) *wp4 = *rp; } playback->output->write_audio(output, ret * num_channels * SAMPLE_SIZE(bits_per_sample)); } } /* Flush buffer */ g_mutex_lock(ctrl_mutex); while (!stop_flag && playback->output->buffer_playing()) g_usleep(20000); g_cond_signal(ctrl_cond); g_mutex_unlock(ctrl_mutex); error_exit: g_free(input); g_free(output); wv_deattach (wvc_input, ctx); stop_flag = TRUE; playback->output->close_audio(); return ! error; }
void *_page_thr(void *arg) { page_thr_t *page = (page_thr_t *)arg; int num = page->page_num; GtkTable *table = page->table; display_data_t *display_data = &main_display_data[num]; static int thread_count = 0; bool reset_highlight = true; xfree(page); if (!grid_init) { /* we need to signal any threads that are waiting */ g_mutex_lock(grid_mutex); g_cond_signal(grid_cond); g_mutex_unlock(grid_mutex); /* wait for the grid to be inited */ g_mutex_lock(grid_mutex); g_cond_wait(grid_cond, grid_mutex); g_mutex_unlock(grid_mutex); /* if the grid isn't there just return */ if (!grid_init) return NULL; } g_mutex_lock(sview_mutex); thread_count++; g_mutex_unlock(sview_mutex); while (page_running == num) { #if _DEBUG DEF_TIMERS; START_TIMER; #endif // g_mutex_lock(sview_mutex); gdk_threads_enter(); sview_init_grid(reset_highlight); reset_highlight=false; (display_data->get_info)(table, display_data); //gdk_flush(); gdk_threads_leave(); // g_mutex_unlock(sview_mutex); #if _DEBUG END_TIMER; g_print("got for iteration: %s\n", TIME_STR); #endif sleep(working_sview_config.refresh_delay); g_mutex_lock(sview_mutex); if (thread_count > 1) { g_mutex_unlock(sview_mutex); break; } g_mutex_unlock(sview_mutex); } g_mutex_lock(sview_mutex); //g_print("now here\n"); thread_count--; //g_print("done decrementing\n"); g_mutex_unlock(sview_mutex); //g_print("done\n"); return NULL; }
GError * sqlx_cache_open_and_lock_base(sqlx_cache_t *cache, const hashstr_t *hname, gint *result) { gint bd; GError *err = NULL; sqlx_base_t *base = NULL; GTimeVal *deadline = g_alloca(sizeof(GTimeVal)); GRID_TRACE2("%s(%p,%s,%p)", __FUNCTION__, (void*)cache, hname ? hashstr_str(hname) : "NULL", (void*)result); EXTRA_ASSERT(cache != NULL); EXTRA_ASSERT(hname != NULL); EXTRA_ASSERT(result != NULL); if (cache->open_timeout >= 0) { g_get_current_time(deadline); g_time_val_add(deadline, cache->open_timeout * 1000); } else { // wait forever deadline = NULL; } g_mutex_lock(cache->lock); cache->used = TRUE; retry: bd = sqlx_lookup_id(cache, hname); if (bd < 0) { if (!(err = sqlx_base_reserve(cache, hname, &base))) { bd = base->index; *result = base->index; sqlx_base_debug("OPEN", base); } else { GRID_DEBUG("No base available for [%s] (%d %s)", hashstr_str(hname), err->code, err->message); if (sqlx_expire_first_idle_base(cache, NULL) >= 0) { g_clear_error(&err); goto retry; } } } else { base = GET(cache, bd); switch (base->status) { case SQLX_BASE_FREE: EXTRA_ASSERT(base->count_open == 0); EXTRA_ASSERT(base->owner == NULL); GRID_ERROR("free base referenced"); g_assert_not_reached(); break; case SQLX_BASE_IDLE: case SQLX_BASE_IDLE_HOT: EXTRA_ASSERT(base->count_open == 0); EXTRA_ASSERT(base->owner == NULL); sqlx_base_move_to_list(cache, base, SQLX_BASE_USED); base->count_open ++; base->owner = g_thread_self(); *result = base->index; break; case SQLX_BASE_USED: EXTRA_ASSERT(base->count_open > 0); EXTRA_ASSERT(base->owner != NULL); if (base->owner != g_thread_self()) { // The lock is held by another thread/request GRID_DEBUG("Base [%s] in use by another thread (%X), waiting...", hashstr_str(hname), compute_thread_id(base->owner)); /* This is to avoid server thread starvation, * due to all threads waiting on the same base. */ if (cache->max_waiting > 0 && base->count_waiting >= cache->max_waiting) { err = NEWERROR(CODE_UNAVAILABLE, "database currently in use by another request, " "and %d others threads already waiting", base->count_waiting); break; } base->count_waiting++; if (g_cond_timed_wait(base->cond, cache->lock, deadline)) { // Thread was woken up before deadline GRID_DEBUG("Retrying to open [%s]", hashstr_str(hname)); base->count_waiting--; goto retry; } else { // Deadline has been reached base->count_waiting--; if (cache->open_timeout > 0) { err = NEWERROR(CODE_UNAVAILABLE, "database currently in use by another request" " (we waited %ldms)", cache->open_timeout); } else { err = NEWERROR(CODE_UNAVAILABLE, "database currently in use by another request"); } GRID_DEBUG("failed to open base: " "in use by another request (thread %X)", compute_thread_id(base->owner)); break; } } base->owner = g_thread_self(); base->count_open ++; *result = base->index; break; case SQLX_BASE_CLOSING: EXTRA_ASSERT(base->owner != NULL); // Just wait for a notification then retry if (g_cond_timed_wait(base->cond, cache->lock, deadline)) goto retry; else { err = NEWERROR(CODE_UNAVAILABLE, "Database stuck in closing state"); break; } } } if (base) { if (!err) { sqlx_base_debug(__FUNCTION__, base); EXTRA_ASSERT(base->owner == g_thread_self()); EXTRA_ASSERT(base->count_open > 0); } g_cond_signal(base->cond); } g_mutex_unlock(cache->lock); return err; }
void find_stop( find_context_t* fc ) { fc->running = 0; g_cond_signal( &fc->find_cond ); }
GError * sqlx_cache_unlock_and_close_base(sqlx_cache_t *cache, gint bd, gboolean force) { GError *err = NULL; sqlx_base_t *base; GRID_TRACE2("%s(%p,%d,%d)", __FUNCTION__, (void*)cache, bd, force); EXTRA_ASSERT(cache != NULL); if (base_id_out(cache, bd)) return NEWERROR(500, "invalid base id=%d", bd); g_mutex_lock(cache->lock); cache->used = TRUE; base = GET(cache,bd); switch (base->status) { case SQLX_BASE_FREE: EXTRA_ASSERT(base->count_open == 0); EXTRA_ASSERT(base->owner == NULL); GRID_ERROR("Trying to close a free base"); g_assert_not_reached(); break; case SQLX_BASE_IDLE: case SQLX_BASE_IDLE_HOT: EXTRA_ASSERT(base->count_open == 0); EXTRA_ASSERT(base->owner == NULL); GRID_ERROR("Trying to close a closed base"); g_assert_not_reached(); break; case SQLX_BASE_USED: EXTRA_ASSERT(base->count_open > 0); // held by the current thread if (!(-- base->count_open)) { // to be closed if (force) { _expire_base(cache, base); } else { sqlx_base_debug("CLOSING", base); base->owner = NULL; if (base->heat >= cache->heat_threshold) sqlx_base_move_to_list(cache, base, SQLX_BASE_IDLE_HOT); else sqlx_base_move_to_list(cache, base, SQLX_BASE_IDLE); } } break; case SQLX_BASE_CLOSING: EXTRA_ASSERT(base->owner != NULL); EXTRA_ASSERT(base->owner != g_thread_self()); GRID_ERROR("Trying to close a base being closed"); g_assert_not_reached(); break; } if (base && !err) sqlx_base_debug(__FUNCTION__, base); g_cond_signal(base->cond); g_mutex_unlock(cache->lock); return err; }
static gpointer book_view_thread (gpointer data) { EBookBackendScalix *bs; gboolean stopped; const char *query; EDataBookView *book_view; EBookBackendScalixPrivate *priv; ScalixBackendSearchClosure *closure; GList *iter; ScanContext context; gboolean res; book_view = data; closure = closure_get (book_view); bs = closure->bs; priv = E_BOOK_BACKEND_SCALIX_GET_PRIVATE (bs); stopped = FALSE; bonobo_object_ref (book_view); if (priv->container == NULL) { e_data_book_view_notify_complete (book_view, GNOME_Evolution_Addressbook_AuthenticationRequired); bonobo_object_unref (book_view); return NULL; } query = e_data_book_view_get_card_query (book_view); context.sexp = e_book_backend_sexp_new (query); context.backend = E_BOOK_BACKEND (bs); context.obj_list = NULL; context.return_objects = TRUE; if (!(context.search_needed = query_is_search (query))) { e_data_book_view_notify_status_message (book_view, _("Loading...")); } else { e_data_book_view_notify_status_message (book_view, _("Searching...")); } g_mutex_lock (closure->mutex); g_cond_signal (closure->cond); g_mutex_unlock (closure->mutex); res = scalix_container_foreach (priv->container, scan_objects, &context); if (res == FALSE) { e_data_book_view_notify_complete (book_view, GNOME_Evolution_Addressbook_OtherError); bonobo_object_unref (book_view); return NULL; } for (iter = context.obj_list; iter; iter = iter->next) { g_mutex_lock (closure->mutex); stopped = closure->stopped; g_mutex_unlock (closure->mutex); if (stopped) { break; } e_data_book_view_notify_update (book_view, iter->data); g_object_unref (iter->data); } /*FIXME: we leek objects if stopped */ g_list_free (context.obj_list); if (!stopped) { e_data_book_view_notify_complete (book_view, GNOME_Evolution_Addressbook_Success); } bonobo_object_unref (book_view); return NULL; }
/*! \brief gui_dispatcher() is a GTK+ timeout that runs 30 tiems per second checking for message on the dispatch queue which handles gui operations after a thread function runs, This will attempt to handle multiple messages at a time if the queue has multiple message queued up. \param data (gpointer) unused \returns TRUE */ gboolean gui_dispatcher(gpointer data) { gint len=0; gint i=0; UpdateFunction val = 0; gint count = 0; GtkWidget *widget = NULL; Io_Message *message = NULL; Text_Message *t_message = NULL; Widget_Update *w_update = NULL; QFunction *qfunc = NULL; extern volatile gboolean leaving; /*extern gint mem_view_style[];*/ if (!gui_dispatch_queue) /*queue not built yet... */ { g_cond_signal(gui_dispatch_cond); return TRUE; } /* Endless Loop, wait for message, processs and repeat... */ trypop: /*printf("gui_dispatch queue length is %i\n",g_async_queue_length(gui_dispatch_queue));*/ if (leaving) { g_cond_signal(gui_dispatch_cond); return TRUE; } message = g_async_queue_try_pop(gui_dispatch_queue); if (!message) { /* printf("no messages waiting, returning\n");*/ g_cond_signal(gui_dispatch_cond); return TRUE; } if (message->functions != NULL) { len = message->functions->len; for (i=0;i<len;i++) { if (leaving) { dealloc_message(message); g_cond_signal(gui_dispatch_cond); return TRUE; } val = g_array_index(message->functions,UpdateFunction, i); /*printf("gui_dispatcher\n");*/ switch ((UpdateFunction)val) { case UPD_LOGBAR: /*printf("logbar update\n");*/ t_message = (Text_Message *)message->payload; gdk_threads_enter(); update_logbar(t_message->view_name,t_message->tagname,t_message->msg,t_message->count,t_message->clear); gdk_threads_leave(); dealloc_textmessage(t_message); message->payload = NULL; break; case UPD_RUN_FUNCTION: /*printf("run function\n");*/ qfunc = (QFunction *)message->payload; gdk_threads_enter(); run_post_functions(qfunc->func_name); gdk_threads_leave(); dealloc_qfunction(qfunc); message->payload = NULL; break; case UPD_WIDGET: /*printf("widget update\n");*/ widget = NULL; w_update = (Widget_Update *)message->payload; switch (w_update->type) { case MTX_ENTRY: /*printf("entry\n");*/ if (NULL == (widget = lookup_widget(w_update->widget_name))) break; gdk_threads_enter(); gtk_entry_set_text(GTK_ENTRY(widget),w_update->msg); gdk_threads_leave(); break; case MTX_LABEL: /*printf("label\n");*/ if (NULL == (widget = lookup_widget(w_update->widget_name))) break; gdk_threads_enter(); gtk_label_set_text(GTK_LABEL(widget),w_update->msg); gdk_threads_leave(); break; case MTX_TITLE: /*printf("title\n");*/ gdk_threads_enter(); set_title(g_strdup(w_update->msg)); gdk_threads_leave(); break; case MTX_SENSITIVE: /*printf("sensitivity change\n");*/ if (NULL == (widget = lookup_widget(w_update->widget_name))) break; gdk_threads_enter(); gtk_widget_set_sensitive(GTK_WIDGET(widget),w_update->state); gdk_threads_leave(); break; default: break; } dealloc_w_update(w_update); message->payload = NULL; break; gdk_threads_enter(); reset_temps(OBJ_GET(global_data,"temp_units")); gdk_threads_leave(); /* case UPD_RAW_MEMORY: update_raw_memory_view(mem_view_style[message->offset],message->offset); break; */ } gdk_threads_enter(); while (gtk_events_pending()) { if (leaving) goto dealloc; gtk_main_iteration(); } gdk_threads_leave(); } } dealloc: dealloc_message(message); /*printf ("deallocation of dispatch message complete\n");*/ count++; /* try to handle up to 4 messages at a time. If this is * set too high, we can cause the timeout to hog the gui if it's * too low, things can fall behind. (GL redraw ;( ) * */ if ((count < 3) && (!leaving)) { /*printf("trying to handle another message\n");*/ goto trypop; } /*printf("returning\n");*/ g_cond_signal(gui_dispatch_cond); return TRUE; }
static void gst_droidcamsrc_dev_compressed_image_callback (void *user, DroidMediaData * mem) { GstDroidCamSrcDev *dev = (GstDroidCamSrcDev *) user; GstDroidCamSrc *src = GST_DROIDCAMSRC (GST_PAD_PARENT (dev->imgsrc->pad)); size_t size = mem->size; void *data = mem->data; GstBuffer *buffer; GstTagList *tags; GstEvent *event = NULL; void *d; GST_DEBUG_OBJECT (src, "dev compressed image callback"); if (!data) { GST_ERROR_OBJECT (src, "invalid memory from camera hal"); return; } /* TODO: research a way to get rid of the memcpy */ d = g_malloc (size); memcpy (d, data, size); buffer = gst_buffer_new_wrapped (d, size); if (!dev->img->image_preview_sent) { gst_droidcamsrc_post_message (src, gst_structure_new_empty (GST_DROIDCAMSRC_CAPTURE_END)); /* TODO: generate and send preview if we don't get it from HAL */ dev->img->image_preview_sent = TRUE; } gst_droidcamsrc_timestamp (src, buffer); tags = gst_droidcamsrc_exif_tags_from_jpeg_data (d, size); if (tags) { GST_INFO_OBJECT (src, "pushing tags %" GST_PTR_FORMAT, tags); event = gst_event_new_tag (tags); } g_mutex_lock (&dev->imgsrc->lock); // TODO: get the correct lock if (event) { src->imgsrc->pending_events = g_list_append (src->imgsrc->pending_events, event); } g_queue_push_tail (dev->imgsrc->queue, buffer); g_cond_signal (&dev->imgsrc->cond); g_mutex_unlock (&dev->imgsrc->lock); /* we need to start restart the preview * android demands this but GStreamer does not know about it. */ g_rec_mutex_lock (dev->lock); dev->running = FALSE; g_rec_mutex_unlock (dev->lock); gst_droidcamsrc_dev_start (dev, TRUE); g_mutex_lock (&src->capture_lock); --src->captures; g_mutex_unlock (&src->capture_lock); g_object_notify (G_OBJECT (src), "ready-for-capture"); }
/*! \brief pf_dispatcher() is a GTK+ timeout that runs 10 times per second checking for message on the dispatch queue which handles gui operations after a thread function runs, This will attempt to handle multiple messages at a time if the queue has multiple message queued up. \param data (gpointer) unused \returns TRUE */ gboolean pf_dispatcher(gpointer data) { gint len=0; gint i=0; PostFunction *pf=NULL; gint count = 0; Io_Message *message = NULL; extern volatile gboolean leaving; if (!pf_dispatch_queue) /*queue not built yet... */ { g_cond_signal(pf_dispatch_cond); return TRUE; } trypop: /*printf("pf_dispatch queue length is %i\n",g_async_queue_length(pf_dispatch_queue));*/ if (leaving) { g_cond_signal(pf_dispatch_cond); return TRUE; } /* if (g_async_queue_length(pf_dispatch_queue) >40) printf("WARNING: Postfunction dispatch queue is over 40\n"); */ message = g_async_queue_try_pop(pf_dispatch_queue); if (!message) { /* printf("no messages waiting, returning\n");*/ g_cond_signal(pf_dispatch_cond); return TRUE; } if (!message->status) { /* Message failed at some point, do NOT run post functions * in this case. */ dealloc_message(message); g_cond_signal(pf_dispatch_cond); return TRUE; } if (message->command->post_functions != NULL) { len = message->command->post_functions->len; for (i=0;i<len;i++) { if (leaving) { dealloc_message(message); g_cond_signal(pf_dispatch_cond); return TRUE; } pf = g_array_index(message->command->post_functions,PostFunction *, i); /*printf("dispatching post function %s\n",pf->name);*/ if (!pf) { printf(_("ERROR postfunction was NULL, continuing\n")); continue; } if (pf->w_arg) { if (!pf->function_w_arg) printf(_("ERROR, couldn't find function with arg \"%s\"\n"),pf->name); else pf->function_w_arg(message); } else { if (!pf->function) printf(_("ERROR, couldn't find function \"%s\"\n"),pf->name); else pf->function(); } gdk_threads_enter(); while (gtk_events_pending()) { if (leaving) { gdk_threads_leave(); goto dealloc; } gtk_main_iteration(); } gdk_threads_leave(); } }
static void gst_droidcamsrc_dev_frame_available (void *user) { GstDroidCamSrcDev *dev = (GstDroidCamSrcDev *) user; GstDroidCamSrc *src = GST_DROIDCAMSRC (GST_PAD_PARENT (dev->imgsrc->pad)); GstDroidCamSrcPad *pad = dev->vfsrc; DroidMediaBuffer *buffer; GstMemory *mem; DroidMediaRect rect; guint width, height; GstBuffer *buff; DroidMediaBufferCallbacks cb; GstFlowReturn flow_ret; DroidMediaBufferInfo info; GST_DEBUG_OBJECT (src, "frame available"); if (!pad->running) { GST_DEBUG_OBJECT (src, "vfsrc pad task is not running"); goto acquire_and_release; } /* We are accessing this without a lock because: * 1) We should not be called while preview is stopped and this is when we manipulate this flag * 2) We can get called when we start the preview and we will deadlock because the lock is already held */ if (dev->use_raw_data) { goto acquire_and_release; } flow_ret = gst_buffer_pool_acquire_buffer (dev->pool, &buff, NULL); if (flow_ret != GST_FLOW_OK) { GST_WARNING_OBJECT (src, "failed to acquire buffer from pool: %s", gst_flow_get_name (flow_ret)); goto acquire_and_release; } cb.ref = (DroidMediaCallback) gst_buffer_ref; cb.unref = (DroidMediaCallback) gst_buffer_unref; cb.data = buff; mem = gst_droid_media_buffer_allocator_alloc (dev->media_allocator, dev->queue, &cb); if (!mem) { GST_ERROR_OBJECT (src, "failed to acquire buffer from droidmedia"); gst_buffer_unref (buff); return; } buffer = gst_droid_media_buffer_memory_get_buffer (mem); gst_buffer_insert_memory (buff, 0, mem); gst_droidcamsrc_timestamp (src, buff); rect = droid_media_buffer_get_crop_rect (buffer); width = droid_media_buffer_get_width (buffer); height = droid_media_buffer_get_height (buffer); gst_droidcamsrc_dev_prepare_buffer (dev, buff, rect, width, height, GST_VIDEO_FORMAT_YV12); g_mutex_lock (&pad->lock); g_queue_push_tail (pad->queue, buff); g_cond_signal (&pad->cond); g_mutex_unlock (&pad->lock); GST_OBJECT_LOCK (src); src->crop_rect = rect; GST_OBJECT_UNLOCK (src); return; acquire_and_release: if (droid_media_buffer_queue_acquire_and_release (dev->queue, &info)) { GST_OBJECT_LOCK (src); src->crop_rect = info.crop_rect; GST_OBJECT_UNLOCK (src); } }
static gboolean gst_app_sink_event (GstBaseSink * sink, GstEvent * event) { GstAppSink *appsink = GST_APP_SINK_CAST (sink); GstAppSinkPrivate *priv = appsink->priv; switch (event->type) { case GST_EVENT_SEGMENT: g_mutex_lock (&priv->mutex); GST_DEBUG_OBJECT (appsink, "receiving SEGMENT"); g_queue_push_tail (priv->queue, gst_event_ref (event)); if (!priv->preroll) gst_event_copy_segment (event, &priv->preroll_segment); g_mutex_unlock (&priv->mutex); break; case GST_EVENT_EOS:{ gboolean emit = TRUE; g_mutex_lock (&priv->mutex); GST_DEBUG_OBJECT (appsink, "receiving EOS"); priv->is_eos = TRUE; g_cond_signal (&priv->cond); g_mutex_unlock (&priv->mutex); g_mutex_lock (&priv->mutex); /* wait until all buffers are consumed or we're flushing. * Otherwise we might signal EOS before all buffers are * consumed, which is a bit confusing for the application */ while (priv->num_buffers > 0 && !priv->flushing && priv->wait_on_eos) g_cond_wait (&priv->cond, &priv->mutex); if (priv->flushing) emit = FALSE; g_mutex_unlock (&priv->mutex); if (emit) { /* emit EOS now */ if (priv->callbacks.eos) priv->callbacks.eos (appsink, priv->user_data); else g_signal_emit (appsink, gst_app_sink_signals[SIGNAL_EOS], 0); } break; } case GST_EVENT_FLUSH_START: /* we don't have to do anything here, the base class will call unlock * which will make sure we exit the _render method */ GST_DEBUG_OBJECT (appsink, "received FLUSH_START"); break; case GST_EVENT_FLUSH_STOP: g_mutex_lock (&priv->mutex); GST_DEBUG_OBJECT (appsink, "received FLUSH_STOP"); gst_app_sink_flush_unlocked (appsink); g_mutex_unlock (&priv->mutex); break; default: break; } return GST_BASE_SINK_CLASS (parent_class)->event (sink, event); }
int flush_work(gpointer data){ int ret = 0; CACHE_CTRL *cctrl = (CACHE_CTRL*)data; GTimeVal expired; char *tmp_buf = (char *)g_malloc0(cctrl->block_size \ *cctrl->flush_once_size); g_assert(tmp_buf); while (!cctrl->flush_worker_should_exit) { HLOG_DEBUG("-- flush worker doing --"); g_get_current_time(&expired); g_time_val_add(&expired, cctrl->flush_interval * 1000 * 1000); g_mutex_lock(cctrl->cache_mutex); gboolean res = g_cond_timed_wait(cctrl->flush_waken_cond, \ cctrl->cache_mutex, &expired); g_mutex_unlock(cctrl->cache_mutex); HLOG_DEBUG(" time wait res for cond is :%d !",res); if (cctrl->flush_worker_should_exit) { HLOG_INFO("-- flush worker should exit --"); break; } do { GSList *continue_blocks = NULL; ret = get_continues_blocks(cctrl, &continue_blocks); g_assert(ret==0); uint32_t blocks_count = g_slist_length(continue_blocks); uint32_t buff_len = blocks_count *cctrl->block_size; HLOG_DEBUG("--blocks_count:%d, buff_len:%d--", \ blocks_count, buff_len); if (res == TRUE && buff_len == 0) { HLOG_ERROR("Never reach here"); g_assert(0); } if (buff_len == 0) { HLOG_DEBUG("do not need flush now"); break; } if (NULL == cctrl->write_callback_func) { HLOG_WARN("--not given flush callback func--"); break; } //char* tmp_buf = g_malloc0(buff_len); //g_assert(tmp_buf!=NULL); uint32_t start_no; uint32_t end_no; int i = 0; for (i = 0; i < blocks_count; i++) { block_t *block = g_slist_nth_data(continue_blocks, i); if (i == 0) { start_no = block->block_no; } if (i == blocks_count-1) { end_no = block->block_no; } memcpy(tmp_buf + i * cctrl->block_size, \ block->block, cctrl->block_size); } //HLOG_DEBUG("--tmp_buf:%p",tmp_buf); ret = cctrl->write_callback_func(cctrl->write_callback_user_param, \ tmp_buf, start_no,end_no); g_assert(ret >= 0); //g_free(tmp_buf); if (ret >= 0 ) { HLOG_DEBUG("--signal write thread--"); g_mutex_lock(cctrl->cache_mutex); __free_from_cache(cctrl, continue_blocks); //g_cond_broadcast(cctrl->writer_waken_cond); g_cond_signal(cctrl->writer_waken_cond); g_mutex_unlock(cctrl->cache_mutex); g_slist_free(continue_blocks); //HLOG_DEBUG("--return blocks to cache over--"); } } while (get_cache_free_size(cctrl) < cctrl->flush_trigger_level \ *cctrl->cache_size / 100 || (res == 0 && get_cache_free_size(cctrl) != 0)); } g_free(tmp_buf); HLOG_INFO("--flush worker exit--"); return 0; }
static GstFlowReturn gst_app_sink_render (GstBaseSink * psink, GstBuffer * buffer) { GstFlowReturn ret; GstAppSink *appsink = GST_APP_SINK_CAST (psink); GstAppSinkPrivate *priv = appsink->priv; gboolean emit; restart: g_mutex_lock (&priv->mutex); if (priv->flushing) goto flushing; /* queue holding caps event might have been FLUSHed, * but caps state still present in pad caps */ if (G_UNLIKELY (!priv->last_caps && gst_pad_has_current_caps (GST_BASE_SINK_PAD (psink)))) { priv->last_caps = gst_pad_get_current_caps (GST_BASE_SINK_PAD (psink)); GST_DEBUG_OBJECT (appsink, "activating pad caps %" GST_PTR_FORMAT, priv->last_caps); } GST_DEBUG_OBJECT (appsink, "pushing render buffer %p on queue (%d)", buffer, priv->num_buffers); while (priv->max_buffers > 0 && priv->num_buffers >= priv->max_buffers) { if (priv->drop) { GstBuffer *old; /* we need to drop the oldest buffer and try again */ if ((old = dequeue_buffer (appsink))) { GST_DEBUG_OBJECT (appsink, "dropping old buffer %p", old); gst_buffer_unref (old); } } else { GST_DEBUG_OBJECT (appsink, "waiting for free space, length %d >= %d", priv->num_buffers, priv->max_buffers); if (priv->unlock) { /* we are asked to unlock, call the wait_preroll method */ g_mutex_unlock (&priv->mutex); if ((ret = gst_base_sink_wait_preroll (psink)) != GST_FLOW_OK) goto stopping; /* we are allowed to continue now */ goto restart; } /* wait for a buffer to be removed or flush */ g_cond_wait (&priv->cond, &priv->mutex); if (priv->flushing) goto flushing; } } /* we need to ref the buffer when pushing it in the queue */ g_queue_push_tail (priv->queue, gst_buffer_ref (buffer)); priv->num_buffers++; g_cond_signal (&priv->cond); emit = priv->emit_signals; g_mutex_unlock (&priv->mutex); if (priv->callbacks.new_sample) { ret = priv->callbacks.new_sample (appsink, priv->user_data); } else { ret = GST_FLOW_OK; if (emit) g_signal_emit (appsink, gst_app_sink_signals[SIGNAL_NEW_SAMPLE], 0, &ret); } return ret; flushing: { GST_DEBUG_OBJECT (appsink, "we are flushing"); g_mutex_unlock (&priv->mutex); return GST_FLOW_FLUSHING; } stopping: { GST_DEBUG_OBJECT (appsink, "we are stopping"); return ret; } }
void push_message(GString *msg) { if (((unsigned char)msg->str[0] == 0xF0) && ((unsigned char)msg->str[msg->len-1] == 0xF7)) g_message("Pushing correct message!"); else g_warning("Pushing incorrect message!"); int x; for (x = 0; x<msg->len; x++) printf("%02x ", (unsigned char)msg->str[x]); printf("\n"); switch (get_message_id(msg)) { case ACK: g_message("Received ACK"); g_string_free(msg, TRUE); return; case NACK: g_message("Received NACK"); g_string_free(msg, TRUE); return; case RECEIVE_PARAMETER_VALUE: unpack_message(msg); SettingParam *param = setting_param_new_from_data(&msg->str[8], NULL); g_message("Received parameter change ID: %d Position: %d Value: %d", param->id, param->position, param->value); GDK_THREADS_ENTER(); apply_setting_param_to_gui(param); GDK_THREADS_LEAVE(); setting_param_free(param); g_string_free(msg, TRUE); return; case RECEIVE_DEVICE_NOTIFICATION: unpack_message(msg); unsigned char *str = (unsigned char*)msg->str; switch (str[8]) { case NOTIFY_PRESET_MOVED: if (str[11] == PRESETS_EDIT_BUFFER && str[12] == 0) { g_message("Loaded preset %d from bank %d", str[10], str[9]); GDK_THREADS_ENTER(); g_timeout_add(0, apply_current_preset_to_gui, NULL); GDK_THREADS_LEAVE(); } else g_message("%d %d moved to %d %d", str[9], str[10], str[11], str[12]); default: g_message("Received unhandled device notification"); } g_string_free(msg, TRUE); return; default: g_mutex_lock(message_queue_mutex); g_queue_push_tail(message_queue, msg); g_cond_signal(message_queue_cond); g_mutex_unlock(message_queue_mutex); } }
static gboolean do_manage_comp_idle (struct _manage_comp *mc) { GError *error = NULL; ECalClientSourceType source_type = E_CAL_CLIENT_SOURCE_TYPE_LAST; ECalComponent *edit_comp = NULL; g_return_val_if_fail (mc, FALSE); source_type = e_cal_client_get_source_type (mc->client); if (source_type == E_CAL_CLIENT_SOURCE_TYPE_LAST) { free_manage_comp_struct (mc); g_warning ("mail-to-task: Incorrect call of %s, no data given", G_STRFUNC); return FALSE; } if (mc->stored_comp) { const gchar *ask = get_question_edit_old (source_type); if (ask) { gchar *msg = g_strdup_printf (ask, icalcomponent_get_summary (mc->stored_comp) ? icalcomponent_get_summary (mc->stored_comp) : _("[No Summary]")); gint chosen; chosen = do_ask (msg, TRUE); if (chosen == GTK_RESPONSE_YES) { edit_comp = e_cal_component_new (); if (!e_cal_component_set_icalcomponent (edit_comp, icalcomponent_new_clone (mc->stored_comp))) { g_object_unref (edit_comp); edit_comp = NULL; error = g_error_new ( E_CAL_CLIENT_ERROR, E_CAL_CLIENT_ERROR_INVALID_OBJECT, "%s", _("Invalid object returned from a server")); } } else if (chosen == GTK_RESPONSE_NO) { /* user wants to create a new event, thus generate a new UID */ gchar *new_uid = e_cal_component_gen_uid (); edit_comp = mc->comp; e_cal_component_set_uid (edit_comp, new_uid); e_cal_component_set_recurid (edit_comp, NULL); g_free (new_uid); } g_free (msg); } } else { edit_comp = mc->comp; } if (edit_comp) { EShell *shell; ECompEditor *comp_editor; /* FIXME Pass in the EShell instance. */ shell = e_shell_get_default (); comp_editor = get_component_editor ( shell, mc->client, edit_comp, edit_comp == mc->comp, &error); if (comp_editor && !error) { comp_editor_title_changed (GTK_WIDGET (comp_editor), NULL, mc); e_signal_connect_notify ( comp_editor, "notify::title", G_CALLBACK (comp_editor_title_changed), mc); g_signal_connect ( comp_editor, "editor-closed", G_CALLBACK (comp_editor_closed), mc); gtk_window_present (GTK_WINDOW (comp_editor)); if (edit_comp != mc->comp) g_object_unref (edit_comp); } else { g_warning ("Failed to create event editor: %s", error ? error->message : "Unknown error"); g_cond_signal (&mc->cond); } } else { /* User canceled editing already existing event, so * treat it as if he just closed the editor window. */ comp_editor_closed (NULL, FALSE, mc); } if (error != NULL) { e_notice ( NULL, GTK_MESSAGE_ERROR, _("An error occurred during processing: %s"), error->message); g_clear_error (&error); } return FALSE; }
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 gboolean gst_ss_demux_handle_src_event (GstPad * pad, GstEvent * event) { GstSSDemux *demux = GST_SS_DEMUX (gst_pad_get_parent (pad)); switch (event->type) { case GST_EVENT_SEEK: { gdouble rate; GstFormat format; GstSeekFlags flags; GstSeekType start_type, stop_type; gint64 start, stop; gint i = 0; GstSSDemuxStream *stream = NULL; GST_INFO_OBJECT (demux, "Received GST_EVENT_SEEK"); // TODO: should be able to seek in DVR window if (GST_SSM_PARSE_IS_LIVE_PRESENTATION (demux->parser)) { GST_WARNING_OBJECT (demux, "Received seek event for live stream"); return FALSE; } gst_event_parse_seek (event, &rate, &format, &flags, &start_type, &start, &stop_type, &stop); if (format != GST_FORMAT_TIME) { GST_WARNING_OBJECT (demux, "Only time format is supported in seek"); return FALSE; } GST_DEBUG_OBJECT (demux, "seek event, rate: %f start: %" GST_TIME_FORMAT " stop: %" GST_TIME_FORMAT, rate, GST_TIME_ARGS (start), GST_TIME_ARGS (stop)); for( i = 0; i < SS_STREAM_NUM; i++) { if (stream = demux->streams[i]) { g_cond_signal (stream->cond); gst_task_stop (stream->stream_task); } } if (flags & GST_SEEK_FLAG_FLUSH) { GST_INFO_OBJECT (demux, "sending flush start"); for( i = 0; i < SS_STREAM_NUM; i++) { if (stream = demux->streams[i]) { gst_pad_push_event (stream->pad, gst_event_new_flush_start ()); } } } gst_ssm_parse_seek_manifest (demux->parser, start); if (flags & GST_SEEK_FLAG_FLUSH) { GST_INFO_OBJECT (demux, "sending flush stop"); for( i = 0; i < SS_STREAM_NUM; i++) { if (stream = demux->streams[i]) { gst_pad_push_event (stream->pad, gst_event_new_flush_stop ()); GST_LOG_OBJECT (stream->pad, "Starting pad TASK again...\n"); stream->sent_ns = FALSE; stream->frag_cnt = 0; /*resetting to start buffering on SEEK */ gst_task_start (stream->stream_task); } } } return TRUE; } default: break; } return gst_pad_event_default (pad, event); }