/** * gst_app_src_push_buffer: * @appsrc: a #GstAppSrc * @buffer: a #GstBuffer to push * * Adds a buffer to the queue of buffers that the appsrc element will * push to its source pad. This function takes ownership of the buffer. * * Returns: #GST_FLOW_OK when the buffer was successfuly queued. * #GST_FLOW_WRONG_STATE when @appsrc is not PAUSED or PLAYING. * #GST_FLOW_UNEXPECTED when EOS occured. */ GstFlowReturn gst_app_src_push_buffer (GstAppSrc * appsrc, GstBuffer * buffer) { gboolean first = TRUE; g_return_val_if_fail (appsrc, GST_FLOW_ERROR); g_return_val_if_fail (GST_IS_APP_SRC (appsrc), GST_FLOW_ERROR); g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR); g_mutex_lock (appsrc->mutex); while (TRUE) { /* can't accept buffers when we are flushing or EOS */ if (appsrc->flushing) goto flushing; if (appsrc->is_eos) goto eos; if (appsrc->queued_bytes >= appsrc->max_bytes) { GST_DEBUG_OBJECT (appsrc, "queue filled (%" G_GUINT64_FORMAT " >= %" G_GUINT64_FORMAT ")", appsrc->queued_bytes, appsrc->max_bytes); if (first) { /* only signal on the first push */ g_mutex_unlock (appsrc->mutex); g_signal_emit (appsrc, gst_app_src_signals[SIGNAL_ENOUGH_DATA], 0, NULL); g_mutex_lock (appsrc->mutex); /* continue to check for flushing/eos after releasing the lock */ first = FALSE; continue; } if (appsrc->block) { GST_DEBUG_OBJECT (appsrc, "waiting for free space"); /* we are filled, wait until a buffer gets popped or when we * flush. */ g_cond_wait (appsrc->cond, appsrc->mutex); } else { /* no need to wait for free space, we just pump data into the queue */ break; } } else break; } GST_DEBUG_OBJECT (appsrc, "queueing buffer %p", buffer); g_queue_push_tail (appsrc->queue, buffer); appsrc->queued_bytes += GST_BUFFER_SIZE (buffer); g_cond_broadcast (appsrc->cond); g_mutex_unlock (appsrc->mutex); return GST_FLOW_OK; /* ERRORS */ flushing: { GST_DEBUG_OBJECT (appsrc, "refuse buffer %p, we are flushing", buffer); gst_buffer_unref (buffer); return GST_FLOW_WRONG_STATE; } eos: { GST_DEBUG_OBJECT (appsrc, "refuse buffer %p, we are EOS", buffer); gst_buffer_unref (buffer); return GST_FLOW_UNEXPECTED; } }
static void gegl_tile_backend_swap_entry_read (GeglTileBackendSwap *self, SwapEntry *entry, guchar *dest) { gint tile_size = gegl_tile_backend_get_tile_size (GEGL_TILE_BACKEND (self)); gint to_be_read = tile_size; guint64 offset = entry->offset; gegl_tile_backend_swap_ensure_exist (); if (entry->link || in_progress) { ThreadParams *queued_op = NULL; g_mutex_lock (&mutex); if (entry->link) queued_op = entry->link->data; else if (in_progress && in_progress->entry == entry) queued_op = in_progress; if (queued_op) { memcpy (dest, queued_op->source, to_be_read); g_mutex_unlock (&mutex); GEGL_NOTE(GEGL_DEBUG_TILE_BACKEND, "read entry %i, %i, %i from queue", entry->x, entry->y, entry->z); return; } g_mutex_unlock (&mutex); } if (in_offset != offset) { if (lseek (in_fd, offset, SEEK_SET) < 0) { g_warning ("unable to seek to tile in buffer: %s", g_strerror (errno)); return; } in_offset = offset; } while (to_be_read > 0) { GError *error = NULL; gint byte_read; byte_read = read (in_fd, dest + tile_size - to_be_read, to_be_read); if (byte_read <= 0) { g_message ("unable to read tile data from swap: " "%s (%d/%d bytes read) %s", g_strerror (errno), byte_read, to_be_read, error?error->message:"--"); return; } to_be_read -= byte_read; in_offset += byte_read; } GEGL_NOTE(GEGL_DEBUG_TILE_BACKEND, "read entry %i, %i, %i from %i", entry->x, entry->y, entry->z, (gint)offset); }
static int glib_thread_mutex_lock (void **lock) { g_mutex_lock (*lock); 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; } }
static gboolean _read_memory (ArvGvDeviceIOData *io_data, guint32 address, guint32 size, void *buffer, GError **error) { ArvGvcpPacket *packet; size_t packet_size; size_t answer_size; int count; unsigned int n_retries = 0; gboolean success = FALSE; answer_size = arv_gvcp_packet_get_read_memory_ack_size (size); g_return_val_if_fail (answer_size <= ARV_GV_DEVICE_BUFFER_SIZE, FALSE); #if GLIB_CHECK_VERSION(2,32,0) g_mutex_lock (&io_data->mutex); #else g_mutex_lock (io_data->mutex); #endif packet = arv_gvcp_packet_new_read_memory_cmd (address, ((size + sizeof (guint32) - 1) / sizeof (guint32)) * sizeof (guint32), 0, &packet_size); do { io_data->packet_id = arv_gvcp_next_packet_id (io_data->packet_id); arv_gvcp_packet_set_packet_id (packet, io_data->packet_id); arv_gvcp_packet_debug (packet, ARV_DEBUG_LEVEL_LOG); g_socket_send_to (io_data->socket, io_data->device_address, (const char *) packet, packet_size, NULL, NULL); if (g_poll (&io_data->poll_in_event, 1, io_data->gvcp_timeout_ms) > 0) { count = g_socket_receive (io_data->socket, io_data->buffer, ARV_GV_DEVICE_BUFFER_SIZE, NULL, NULL); if (count >= answer_size) { ArvGvcpPacket *ack_packet = io_data->buffer; ArvGvcpPacketType packet_type; ArvGvcpCommand command; guint16 packet_id; arv_gvcp_packet_debug (ack_packet, ARV_DEBUG_LEVEL_LOG); packet_type = arv_gvcp_packet_get_packet_type (ack_packet); command = arv_gvcp_packet_get_command (ack_packet); packet_id = arv_gvcp_packet_get_packet_id (ack_packet); if (packet_type == ARV_GVCP_PACKET_TYPE_ACK && command == ARV_GVCP_COMMAND_READ_MEMORY_ACK && packet_id == io_data->packet_id) { memcpy (buffer, arv_gvcp_packet_get_read_memory_ack_data (ack_packet), size); success = TRUE; } else arv_gvcp_packet_debug (ack_packet, ARV_DEBUG_LEVEL_WARNING); } } n_retries++; } while (!success && n_retries < io_data->gvcp_n_retries); arv_gvcp_packet_free (packet); #if GLIB_CHECK_VERSION(2,32,0) g_mutex_unlock (&io_data->mutex); #else g_mutex_unlock (io_data->mutex); #endif if (!success) { if (error != NULL && *error == NULL) *error = g_error_new (ARV_DEVICE_ERROR, ARV_DEVICE_STATUS_TIMEOUT, "[ArvDevice::read_memory] Timeout"); } return success; }
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); }
static DWORD WINAPI wince_reader_thread (LPVOID lParam) { struct vehicle_priv *priv = lParam; char chunk_buffer[3*82]; BOOL status; DWORD bytes_read; int waitcounter; dbg(0, "GPS Port:[%s]\n", priv->source); priv->thread_up = 1; if ( !initDevice(priv) ) { return -1; } while (priv->is_running) { dbg(1,"readfile\n"); waitcounter = 0; status = ReadFile(priv->m_hGPSDevice, chunk_buffer, sizeof(chunk_buffer), &bytes_read, NULL); if ( !status ) { dbg(0,"Error reading file/device. Try again.\n"); initDevice(priv); continue; } while ( priv->read_buffer_pos + bytes_read > buffer_size ) { /* TODO (rikky#1#): should use blocking */ if ( priv->file_type != file_type_file ) { dbg(3, "GPS data comes too fast. Have to wait here\n"); } Sleep(50); waitcounter++; if ( waitcounter % 8 == 0 ) { dbg(1, "Remind them of the data\n"); event_call_callback(priv->priv_cbl); } if(waitcounter % 200 == 0) { dbg(0,"Will main thread ever be ready for the GPS data? Already %d intervals gone.\n",waitcounter); } } if(waitcounter>2) dbg(0,"Sent GPS data to the main thread after %d intervals delay.\n",waitcounter); g_mutex_lock(&priv->lock); memcpy(priv->read_buffer + priv->read_buffer_pos , chunk_buffer, bytes_read ); priv->read_buffer_pos += bytes_read; if ( !priv->has_data ) { event_call_callback(priv->priv_cbl); priv->has_data = 1; } g_mutex_unlock(&priv->lock); } return TRUE; }
/* 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"); }
/* Must be called in the gl thread */ static void gst_gl_window_finalize (GObject * object) { GstGLWindow *window = GST_GL_WINDOW (object); GstGLWindowPrivate *priv = window->priv; XEvent event; Bool ret = TRUE; g_mutex_lock (priv->x_lock); g_debug ("about to finalize gl window\n"); priv->parent = 0; if (priv->device) XUnmapWindow (priv->device, priv->internal_win_id); if (priv->gl_context) { ret = eglMakeCurrent (priv->device, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); if (!ret) g_debug ("failed to release opengl context\n"); eglDestroyContext (priv->device, priv->gl_context); } if (priv->device) eglTerminate (priv->device); XFree (priv->visual_info); XReparentWindow (priv->device, priv->internal_win_id, priv->root, 0, 0); XDestroyWindow (priv->device, priv->internal_win_id); XSync (priv->device, FALSE); while (XPending (priv->device)) XNextEvent (priv->device, &event); XSetCloseDownMode (priv->device, DestroyAll); /*XAddToSaveSet (display, w) Display *display; Window w; */ //FIXME: it seems it causes destroy all created windows, even by other display connection: //This is case in: gst-launch-0.10 videotestsrc ! tee name=t t. ! queue ! glimagesink t. ! queue ! glimagesink //When the first window is closed and so its display is closed by the following line, then the other Window managed by the //other glimagesink, is not useable and so each opengl call causes a segmentation fault. //Maybe the solution is to use: XAddToSaveSet //The following line is commented to avoid the disagreement explained before. //XCloseDisplay (priv->device); g_debug ("display receiver closed\n"); XCloseDisplay (priv->disp_send); g_debug ("display sender closed\n"); if (priv->cond_send_message) { g_cond_free (priv->cond_send_message); priv->cond_send_message = NULL; } g_mutex_unlock (priv->x_lock); if (priv->x_lock) { g_mutex_free (priv->x_lock); priv->x_lock = NULL; } G_OBJECT_CLASS (gst_gl_window_parent_class)->finalize (object); }
/* Must be called in the gl thread */ GstGLWindow * gst_gl_window_new (gulong external_gl_context) { GstGLWindow *window = g_object_new (GST_GL_TYPE_WINDOW, NULL); GstGLWindowPrivate *priv = window->priv; EGLint config_attrib[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_DEPTH_SIZE, 16, EGL_NONE }; EGLint context_attrib[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; EGLint majorVersion; EGLint minorVersion; EGLint numConfigs; EGLConfig config; XSetWindowAttributes win_attr; XTextProperty text_property; XWMHints wm_hints; unsigned long mask; const gchar *title = "OpenGL renderer"; Atom wm_atoms[3]; static gint x = 0; static gint y = 0; setlocale (LC_NUMERIC, "C"); priv->x_lock = g_mutex_new (); priv->cond_send_message = g_cond_new (); priv->running = TRUE; priv->visible = FALSE; priv->parent = 0; priv->allow_extra_expose_events = TRUE; g_mutex_lock (priv->x_lock); priv->device = XOpenDisplay (priv->display_name); XSynchronize (priv->device, FALSE); g_debug ("gl device id: %ld\n", (gulong) priv->device); priv->disp_send = XOpenDisplay (priv->display_name); XSynchronize (priv->disp_send, FALSE); g_debug ("gl display sender: %ld\n", (gulong) priv->disp_send); priv->screen_num = DefaultScreen (priv->device); priv->root = RootWindow (priv->device, priv->screen_num); priv->depth = DefaultDepth (priv->device, priv->screen_num); g_debug ("gl root id: %lud\n", (gulong) priv->root); priv->device_width = DisplayWidth (priv->device, priv->screen_num); priv->device_height = DisplayHeight (priv->device, priv->screen_num); priv->visual_info = g_new0 (XVisualInfo, 1); XMatchVisualInfo (priv->device, priv->screen_num, priv->depth, TrueColor, priv->visual_info); win_attr.event_mask = StructureNotifyMask | ExposureMask | VisibilityChangeMask; win_attr.do_not_propagate_mask = NoEventMask; win_attr.background_pixmap = None; win_attr.background_pixel = 0; win_attr.border_pixel = 0; win_attr.colormap = XCreateColormap (priv->device, priv->root, priv->visual_info->visual, AllocNone); mask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask; x += 20; y += 20; priv->internal_win_id = XCreateWindow (priv->device, priv->root, x, y, 1, 1, 0, priv->visual_info->depth, InputOutput, priv->visual_info->visual, mask, &win_attr); if (!priv->internal_win_id) { g_debug ("XCreateWindow failed\n"); goto failure; } XSync (priv->device, FALSE); XSetWindowBackgroundPixmap (priv->device, priv->internal_win_id, None); g_debug ("gl window id: %lud\n", (gulong) priv->internal_win_id); g_debug ("gl window props: x:%d y:%d\n", x, y); wm_atoms[0] = XInternAtom (priv->device, "WM_DELETE_WINDOW", True); if (wm_atoms[0] == None) g_debug ("Cannot create WM_DELETE_WINDOW\n"); wm_atoms[1] = XInternAtom (priv->device, "WM_GL_WINDOW", False); if (wm_atoms[1] == None) g_debug ("Cannot create WM_GL_WINDOW\n"); wm_atoms[2] = XInternAtom (priv->device, "WM_QUIT_LOOP", False); if (wm_atoms[2] == None) g_debug ("Cannot create WM_QUIT_LOOP\n"); XSetWMProtocols (priv->device, priv->internal_win_id, wm_atoms, 2); wm_hints.flags = StateHint; wm_hints.initial_state = NormalState; wm_hints.input = False; XStringListToTextProperty ((char **) &title, 1, &text_property); XSetWMProperties (priv->device, priv->internal_win_id, &text_property, &text_property, 0, 0, NULL, &wm_hints, NULL); XFree (text_property.value); priv->gl_display = eglGetDisplay ((EGLNativeDisplayType) priv->device); if (eglInitialize (priv->gl_display, &majorVersion, &minorVersion)) g_debug ("egl initialized: %d.%d\n", majorVersion, minorVersion); else { g_debug ("failed to initialize egl %ld, %s\n", (gulong) priv->gl_display, EGLErrorString ()); goto failure; } if (eglChooseConfig (priv->gl_display, config_attrib, &config, 1, &numConfigs)) g_debug ("config set: %ld, %ld\n", (gulong) config, (gulong) numConfigs); else { g_debug ("failed to set config %ld, %s\n", (gulong) priv->gl_display, EGLErrorString ()); goto failure; } priv->gl_surface = eglCreateWindowSurface (priv->gl_display, config, (EGLNativeWindowType) priv->internal_win_id, NULL); if (priv->gl_surface != EGL_NO_SURFACE) g_debug ("surface created: %ld\n", (gulong) priv->gl_surface); else { g_debug ("failed to create surface %ld, %ld, %ld, %s\n", (gulong) priv->gl_display, (gulong) priv->gl_surface, (gulong) priv->gl_display, EGLErrorString ()); goto failure; } g_debug ("about to create gl context\n"); priv->gl_context = eglCreateContext (priv->gl_display, config, (EGLContext) (guint) external_gl_context, context_attrib); if (priv->gl_context != EGL_NO_CONTEXT) g_debug ("gl context created: %ld\n", (gulong) priv->gl_context); else { g_debug ("failed to create glcontext %ld, %ld, %s\n", (gulong) priv->gl_context, (gulong) priv->gl_display, EGLErrorString ()); goto failure; } if (!eglMakeCurrent (priv->gl_display, priv->gl_surface, priv->gl_surface, priv->gl_context)) { g_debug ("failed to make opengl context current %ld, %s\n", (gulong) priv->gl_display, EGLErrorString ()); goto failure; } g_mutex_unlock (priv->x_lock); return window; failure: g_mutex_unlock (priv->x_lock); g_object_unref (G_OBJECT (window)); return NULL; }
/* Not called by the gl thread */ void gst_gl_window_draw (GstGLWindow * window, gint width, gint height) { if (window) { GstGLWindowPrivate *priv = window->priv; g_mutex_lock (priv->x_lock); if (priv->running) { XEvent event; XWindowAttributes attr; XGetWindowAttributes (priv->disp_send, priv->internal_win_id, &attr); if (!priv->visible) { if (!priv->parent) { attr.width = width; attr.height = height; XResizeWindow (priv->disp_send, priv->internal_win_id, attr.width, attr.height); XSync (priv->disp_send, FALSE); } XMapWindow (priv->disp_send, priv->internal_win_id); priv->visible = TRUE; } if (priv->parent) { XWindowAttributes attr_parent; XGetWindowAttributes (priv->disp_send, priv->parent, &attr_parent); if (attr.width != attr_parent.width || attr.height != attr_parent.height) { XMoveResizeWindow (priv->disp_send, priv->internal_win_id, 0, 0, attr_parent.width, attr_parent.height); XSync (priv->disp_send, FALSE); attr.width = attr_parent.width; attr.height = attr_parent.height; g_debug ("parent resize: %d, %d\n", attr_parent.width, attr_parent.height); } } event.xexpose.type = Expose; event.xexpose.send_event = TRUE; event.xexpose.display = priv->disp_send; event.xexpose.window = priv->internal_win_id; event.xexpose.x = attr.x; event.xexpose.y = attr.y; event.xexpose.width = attr.width; event.xexpose.height = attr.height; event.xexpose.count = 0; XSendEvent (priv->disp_send, priv->internal_win_id, FALSE, ExposureMask, &event); XSync (priv->disp_send, FALSE); } g_mutex_unlock (priv->x_lock); } }
/** * gstreamill_job_start: * @job: (in): json type of job description. * * Returns: json type of job execution result. */ gchar * gstreamill_job_start (Gstreamill *gstreamill, gchar *job_desc) { gchar *p, *name; Job *job; if (!jobdesc_is_valid (job_desc)) { p = g_strdup ("Invalid job"); return p; } if (jobdesc_is_live (job_desc)) { GST_ERROR ("live job arrived"); } else { GST_ERROR ("transcode job arrived"); } /* create job object */ name = jobdesc_get_name (job_desc); if (get_job (gstreamill, name) != NULL) { GST_ERROR ("start live job failure, duplicated name %s.", name); p = g_strdup_printf ("start live job failure, duplicated name %s.", name); g_free (name); return p; } job = job_new ("job", job_desc, "name", name, NULL); g_free (name); /* job initialize */ job->log_dir = gstreamill->log_dir; g_mutex_init (&(job->access_mutex)); job->is_live = jobdesc_is_live (job_desc); job->eos = FALSE; job->current_access = 0; job->age = 0; job->last_start_time = NULL; if (job_initialize (job, gstreamill->daemon) != 0) { p = g_strdup ("initialize job failure"); g_object_unref (job); return p; } /* reset and start job */ job_reset (job); if (gstreamill->daemon) { p = create_job_process (job); GST_ERROR ("%s: %s", p, job->name); if (g_str_has_suffix (p, "success")) { g_mutex_lock (&(gstreamill->job_list_mutex)); gstreamill->job_list = g_slist_append (gstreamill->job_list, job); g_mutex_unlock (&(gstreamill->job_list_mutex)); } else { g_object_unref (job); } } else { if (job_start (job) == 0) { g_mutex_lock (&(gstreamill->job_list_mutex)); gstreamill->job_list = g_slist_append (gstreamill->job_list, job); g_mutex_unlock (&(gstreamill->job_list_mutex)); p = g_strdup ("success"); } else { p = g_strdup ("failure"); } } return p; }
void scheduler_ref(Scheduler* scheduler) { MAGIC_ASSERT(scheduler); g_mutex_lock(&(scheduler->globalLock)); scheduler->referenceCount++; g_mutex_unlock(&(scheduler->globalLock)); }
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; }
static void gst_dvbsrc_set_property (GObject * _object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstDvbSrc *object; g_return_if_fail (GST_IS_DVBSRC (_object)); object = GST_DVBSRC (_object); switch (prop_id) { case ARG_DVBSRC_ADAPTER: object->adapter_number = g_value_get_int (value); break; case ARG_DVBSRC_FRONTEND: object->frontend_number = g_value_get_int (value); break; case ARG_DVBSRC_DISEQC_SRC: if (object->diseqc_src != g_value_get_int (value)) { object->diseqc_src = g_value_get_int (value); object->send_diseqc = TRUE; } GST_INFO_OBJECT (object, "Set Property: ARG_DVBSRC_DISEQC_ID"); break; case ARG_DVBSRC_FREQUENCY: object->freq = g_value_get_uint (value); GST_INFO_OBJECT (object, "Set Property: ARG_DVBSRC_FREQUENCY (%d Hz)", object->freq); break; case ARG_DVBSRC_POLARITY: { const char *s = NULL; s = g_value_get_string (value); if (s != NULL) { object->pol = (s[0] == 'h' || s[0] == 'H') ? DVB_POL_H : DVB_POL_V; GST_INFO_OBJECT (object, "Set Property: ARG_DVBSRC_POLARITY"); GST_INFO_OBJECT (object, "\t%s", (s[0] == 'h' || s[0] == 'H') ? "DVB_POL_H" : "DVB_POL_V"); } break; } case ARG_DVBSRC_PIDS: { gchar *pid_string; pid_string = g_value_dup_string (value); GST_INFO_OBJECT (object, "Set Property: ARG_DVBSRC_PIDS %s", pid_string); if (!strcmp (pid_string, "8192")) { /* get the whole ts */ int pid_count = 1; object->pids[0] = 8192; while (pid_count < MAX_FILTERS) { object->pids[pid_count++] = G_MAXUINT16; } } else { int pid = 0; int pid_count; gchar **pids; char **tmp; tmp = pids = g_strsplit (pid_string, ":", MAX_FILTERS); if (pid_string) g_free (pid_string); /* always add the PAT and CAT pids */ object->pids[0] = 0; object->pids[1] = 1; pid_count = 2; while (*pids != NULL && pid_count < MAX_FILTERS) { pid = strtol (*pids, NULL, 0); if (pid > 1 && pid <= 8192) { GST_INFO_OBJECT (object, "\tParsed Pid: %d", pid); object->pids[pid_count] = pid; pid_count++; } pids++; } while (pid_count < MAX_FILTERS) { object->pids[pid_count++] = G_MAXUINT16; } g_strfreev (tmp); } /* if we are in playing or paused, then set filters now */ GST_INFO_OBJECT (object, "checking if playing for setting pes filters"); if (GST_ELEMENT (object)->current_state == GST_STATE_PLAYING || GST_ELEMENT (object)->current_state == GST_STATE_PAUSED) { GST_INFO_OBJECT (object, "Setting pes filters now"); gst_dvbsrc_set_pes_filters (object); } } break; case ARG_DVBSRC_SYM_RATE: object->sym_rate = g_value_get_uint (value); GST_INFO_OBJECT (object, "Set Property: ARG_DVBSRC_SYM_RATE to value %d", object->sym_rate); break; case ARG_DVBSRC_BANDWIDTH: object->bandwidth = g_value_get_enum (value); break; case ARG_DVBSRC_CODE_RATE_HP: object->code_rate_hp = g_value_get_enum (value); break; case ARG_DVBSRC_CODE_RATE_LP: object->code_rate_lp = g_value_get_enum (value); break; case ARG_DVBSRC_GUARD: object->guard_interval = g_value_get_enum (value); break; case ARG_DVBSRC_MODULATION: object->modulation = g_value_get_enum (value); break; case ARG_DVBSRC_TRANSMISSION_MODE: object->transmission_mode = g_value_get_enum (value); break; case ARG_DVBSRC_HIERARCHY_INF: object->hierarchy_information = g_value_get_enum (value); break; case ARG_DVBSRC_INVERSION: object->inversion = g_value_get_enum (value); break; case ARG_DVBSRC_TUNE:{ GST_INFO_OBJECT (object, "Set Property: ARG_DVBSRC_TUNE"); /* if we are in paused/playing state tune now, otherwise in ready to paused state change */ if (GST_STATE (object) > GST_STATE_READY) { g_mutex_lock (&object->tune_mutex); gst_dvbsrc_tune (object); g_mutex_unlock (&object->tune_mutex); } break; } case ARG_DVBSRC_STATS_REPORTING_INTERVAL: object->stats_interval = g_value_get_uint (value); object->stats_counter = 0; break; case ARG_DVBSRC_TIMEOUT: object->timeout = g_value_get_uint64 (value); break; case ARG_DVBSRC_DVB_BUFFER_SIZE: object->dvb_buffer_size = g_value_get_uint (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } }
static void close_connection (GVfsAfpConnection *conn) { GVfsAfpConnectionPrivate *priv = conn->priv; guint16 req_id; gboolean res; GError *err = NULL; GQueue *request_queue; GSList *pending_closes, *siter; GHashTable *request_hash; GHashTableIter iter; RequestData *req_data; /* Take lock */ g_mutex_lock (&priv->mutex); /* Set closed flag */ g_atomic_int_set (&priv->atomic_state, STATE_CLOSED); request_queue = priv->request_queue; priv->request_queue = NULL; request_hash = priv->request_hash; priv->request_hash = NULL; pending_closes = priv->pending_closes; priv->pending_closes = NULL; /* Release lock */ g_mutex_unlock (&priv->mutex); /* close DSI session */ req_id = get_request_id (conn); res = send_request_sync (g_io_stream_get_output_stream (priv->stream), DSI_CLOSE_SESSION, req_id, 0, 0, NULL, NULL, &err); if (!res) g_io_stream_close (priv->stream, NULL, NULL); else res = g_io_stream_close (priv->stream, NULL, &err); g_clear_object (&priv->stream); #define REQUEST_DATA_CLOSED(request_data) { \ g_simple_async_result_set_from_error (req_data->simple, \ g_error_new_literal (G_IO_ERROR, G_IO_ERROR_CLOSED, "Connection was closed")); \ \ g_simple_async_result_complete_in_idle (req_data->simple); \ free_request_data (req_data); \ } while ((req_data = g_queue_pop_head (request_queue))) { REQUEST_DATA_CLOSED (req_data); } g_hash_table_iter_init (&iter, request_hash); while (g_hash_table_iter_next (&iter, NULL, (void **)&req_data)) { REQUEST_DATA_CLOSED (req_data); } #undef REQUEST_DATA_CLOSED /* quit main_loop */ g_main_loop_quit (priv->worker_loop); g_main_loop_unref (priv->worker_loop); g_main_context_unref (priv->worker_context); for (siter = pending_closes; siter != NULL; siter = siter->next) { SyncData *close_data = siter->data; close_data->res = TRUE; sync_data_signal (close_data); } g_slist_free (pending_closes); }
void g_logv (const gchar *log_domain, GLogLevelFlags log_level, const gchar *format, va_list args1) { gboolean was_fatal = (log_level & G_LOG_FLAG_FATAL) != 0; gboolean was_recursion = (log_level & G_LOG_FLAG_RECURSION) != 0; gint i; log_level &= G_LOG_LEVEL_MASK; if (!log_level) return; for (i = g_bit_nth_msf (log_level, -1); i >= 0; i = g_bit_nth_msf (log_level, i)) { register GLogLevelFlags test_level; test_level = 1 << i; if (log_level & test_level) { guint depth = GPOINTER_TO_UINT (g_private_get (g_log_depth)); GLogDomain *domain; GLogFunc log_func; GLogLevelFlags domain_fatal_mask; gpointer data = NULL; gboolean masquerade_fatal = FALSE; if (was_fatal) test_level |= G_LOG_FLAG_FATAL; if (was_recursion) test_level |= G_LOG_FLAG_RECURSION; /* check recursion and lookup handler */ g_mutex_lock (g_messages_lock); domain = g_log_find_domain_L (log_domain ? log_domain : ""); if (depth) test_level |= G_LOG_FLAG_RECURSION; depth++; domain_fatal_mask = domain ? domain->fatal_mask : G_LOG_FATAL_MASK; if ((domain_fatal_mask | g_log_always_fatal) & test_level) test_level |= G_LOG_FLAG_FATAL; if (test_level & G_LOG_FLAG_RECURSION) log_func = _g_log_fallback_handler; else log_func = g_log_domain_get_handler_L (domain, test_level, &data); domain = NULL; g_mutex_unlock (g_messages_lock); g_private_set (g_log_depth, GUINT_TO_POINTER (depth)); /* had to defer debug initialization until we can keep track of recursion */ if (!(test_level & G_LOG_FLAG_RECURSION) && !_g_debug_initialized) { GLogLevelFlags orig_test_level = test_level; _g_debug_init (); if ((domain_fatal_mask | g_log_always_fatal) & test_level) test_level |= G_LOG_FLAG_FATAL; if (test_level != orig_test_level) { /* need a relookup, not nice, but not too bad either */ g_mutex_lock (g_messages_lock); domain = g_log_find_domain_L (log_domain ? log_domain : ""); log_func = g_log_domain_get_handler_L (domain, test_level, &data); domain = NULL; g_mutex_unlock (g_messages_lock); } } if (test_level & G_LOG_FLAG_RECURSION) { /* we use a stack buffer of fixed size, since we're likely * in an out-of-memory situation */ gchar buffer[1025]; gsize size G_GNUC_UNUSED; va_list args2; G_VA_COPY (args2, args1); size = _g_vsnprintf (buffer, 1024, format, args2); va_end (args2); log_func (log_domain, test_level, buffer, data); } else { gchar *msg; va_list args2; G_VA_COPY (args2, args1); msg = g_strdup_vprintf (format, args2); va_end (args2); log_func (log_domain, test_level, msg, data); if ((test_level & G_LOG_FLAG_FATAL) && !(test_level & G_LOG_LEVEL_ERROR)) { masquerade_fatal = fatal_log_func && !fatal_log_func (log_domain, test_level, msg, fatal_log_data); } g_free (msg); } if ((test_level & G_LOG_FLAG_FATAL) && !masquerade_fatal) { #ifdef G_OS_WIN32 gchar *locale_msg = g_locale_from_utf8 (fatal_msg_buf, -1, NULL, NULL, NULL); MessageBox (NULL, locale_msg, NULL, MB_ICONERROR|MB_SETFOREGROUND); if (IsDebuggerPresent () && !(test_level & G_LOG_FLAG_RECURSION)) G_BREAKPOINT (); else abort (); #else if (!(test_level & G_LOG_FLAG_RECURSION)) G_BREAKPOINT (); else abort (); #endif /* !G_OS_WIN32 */ } depth--; g_private_set (g_log_depth, GUINT_TO_POINTER (depth)); } } }
static void dispatch_reply (GVfsAfpConnection *afp_connection) { GVfsAfpConnectionPrivate *priv = afp_connection->priv; DSIHeader *dsi_header = &priv->read_dsi_header; switch (dsi_header->command) { case DSI_CLOSE_SESSION: { g_warning ("Server closed session\n"); break; } case DSI_TICKLE: { RequestData *req_data; /* Send back a tickle message */ req_data = g_slice_new0 (RequestData); req_data->type = REQUEST_TYPE_TICKLE; req_data->conn = afp_connection; /* take lock */ g_mutex_lock (&priv->mutex); g_queue_push_head (priv->request_queue, req_data); if (!priv->send_loop_running) { priv->send_loop_running = TRUE; send_request_unlocked (afp_connection); } /* release lock */ g_mutex_unlock (&priv->mutex); break; } case DSI_ATTENTION: { guint8 attention_code; attention_code = priv->reply_buf[0] >> 4; g_signal_emit (afp_connection, signals[ATTENTION], 0, attention_code); break; } case DSI_COMMAND: case DSI_WRITE: { RequestData *req_data; req_data = g_hash_table_lookup (priv->request_hash, GUINT_TO_POINTER ((guint)dsi_header->requestID)); if (req_data) { GVfsAfpReply *reply; reply = g_vfs_afp_reply_new (dsi_header->errorCode, priv->reply_buf, dsi_header->totalDataLength, priv->free_reply_buf); priv->free_reply_buf = FALSE; g_simple_async_result_set_op_res_gpointer (req_data->simple, reply, g_object_unref); g_simple_async_result_complete_in_idle (req_data->simple); g_hash_table_remove (priv->request_hash, GUINT_TO_POINTER ((guint)dsi_header->requestID)); } break; } default: g_assert_not_reached (); } }
/** * 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; }
static void ent_lock (GIOPMessageQueueEntry *ent) { if (ent->src_thread) g_mutex_lock (ent->src_thread->lock); }
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); }
static gboolean impl_CalFactory_get_cal (EGdbusCalFactory *object, GDBusMethodInvocation *invocation, const gchar * const *in_source_type, EDataCalFactory *factory) { EDataCal *calendar; EBackend *backend; EDataCalFactoryPrivate *priv = factory->priv; GDBusConnection *connection; ESource *source; gchar *uri; gchar *path = NULL; const gchar *sender; GList *list; GError *error = NULL; gchar *source_xml = NULL; guint type = 0; sender = g_dbus_method_invocation_get_sender (invocation); connection = g_dbus_method_invocation_get_connection (invocation); if (!e_gdbus_cal_factory_decode_get_cal (in_source_type, &source_xml, &type)) { error = g_error_new ( E_DATA_CAL_ERROR, NoSuchCal, _("Invalid call")); g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); return TRUE; } source = e_source_new_from_standalone_xml (source_xml); g_free (source_xml); if (!source) { error = g_error_new ( E_DATA_CAL_ERROR, NoSuchCal, _("Invalid source")); g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); return TRUE; } uri = e_source_get_uri (source); if (uri == NULL || *uri == '\0') { g_object_unref (source); g_free (uri); error = g_error_new ( E_DATA_CAL_ERROR, NoSuchCal, _("Empty URI")); g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); return TRUE; } backend = e_data_cal_factory_get_backend (factory, source, uri, type); if (backend == NULL) { error = g_error_new ( E_DATA_CAL_ERROR, NoSuchCal, _("Invalid source")); g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); return TRUE; } g_mutex_lock (priv->calendars_lock); e_dbus_server_hold (E_DBUS_SERVER (factory)); path = construct_cal_factory_path (); calendar = e_data_cal_new (E_CAL_BACKEND (backend)); g_hash_table_insert (priv->calendars, g_strdup (path), calendar); e_cal_backend_add_client (E_CAL_BACKEND (backend), calendar); e_data_cal_register_gdbus_object (calendar, connection, path, &error); g_object_weak_ref ( G_OBJECT (calendar), (GWeakNotify) calendar_freed_cb, factory); /* Update the hash of open connections. */ g_mutex_lock (priv->connections_lock); list = g_hash_table_lookup (priv->connections, sender); list = g_list_prepend (list, calendar); g_hash_table_insert (priv->connections, g_strdup (sender), list); g_mutex_unlock (priv->connections_lock); g_mutex_unlock (priv->calendars_lock); g_object_unref (source); g_free (uri); e_gdbus_cal_factory_complete_get_cal ( object, invocation, path, error); if (error) g_error_free (error); g_free (path); return TRUE; }
gboolean _write_register (ArvGvDeviceIOData *io_data, guint32 address, guint32 value, GError **error) { ArvGvcpPacket *packet; size_t packet_size; int count; unsigned int n_retries = 0; gboolean success = FALSE; #if GLIB_CHECK_VERSION(2,32,0) g_mutex_lock (&io_data->mutex); #else g_mutex_lock (io_data->mutex); #endif packet = arv_gvcp_packet_new_write_register_cmd (address, value, io_data->packet_id, &packet_size); do { io_data->packet_id = arv_gvcp_next_packet_id (io_data->packet_id); arv_gvcp_packet_set_packet_id (packet, io_data->packet_id); arv_gvcp_packet_debug (packet, ARV_DEBUG_LEVEL_LOG); g_socket_send_to (io_data->socket, io_data->device_address, (const char *) packet, packet_size, NULL, NULL); if (g_poll (&io_data->poll_in_event, 1, io_data->gvcp_timeout_ms) > 0) { count = g_socket_receive (io_data->socket, io_data->buffer, ARV_GV_DEVICE_BUFFER_SIZE, NULL, NULL); if (count > 0) { ArvGvcpPacket *ack_packet = io_data->buffer; ArvGvcpPacketType packet_type; ArvGvcpCommand command; guint16 packet_id; arv_gvcp_packet_debug (ack_packet, ARV_DEBUG_LEVEL_LOG); packet_type = arv_gvcp_packet_get_packet_type (ack_packet); command = arv_gvcp_packet_get_command (ack_packet); packet_id = arv_gvcp_packet_get_packet_id (ack_packet); arv_log_gvcp ("%d, %d, %d", packet_type, command, packet_id); if (packet_type == ARV_GVCP_PACKET_TYPE_ACK && command == ARV_GVCP_COMMAND_WRITE_REGISTER_ACK && packet_id == io_data->packet_id) success = TRUE; else arv_gvcp_packet_debug (ack_packet, ARV_DEBUG_LEVEL_WARNING); } } n_retries++; } while (!success && n_retries < io_data->gvcp_n_retries); arv_gvcp_packet_free (packet); #if GLIB_CHECK_VERSION(2,32,0) g_mutex_unlock (&io_data->mutex); #else g_mutex_unlock (io_data->mutex); #endif if (!success) { if (error != NULL && *error == NULL) *error = g_error_new (ARV_DEVICE_ERROR, ARV_DEVICE_STATUS_TIMEOUT, "[ArvDevice::write_register] Timeout"); } return success; }
//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; } }
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 gboolean rb_mtp_src_start (GstBaseSrc *basesrc) { RBMTPSrc *src = RB_MTP_SRC (basesrc); /* download the file, if we haven't already */ if (src->tempfile == NULL) { g_mutex_lock (src->download_mutex); src->download_done = FALSE; rb_mtp_thread_download_track (src->device_thread, src->track_id, "", (RBMtpDownloadCallback)download_cb, g_object_ref (src), g_object_unref); while (src->download_done == FALSE) { g_cond_wait (src->download_cond, src->download_mutex); } g_mutex_unlock (src->download_mutex); rb_debug ("download finished"); if (src->download_error) { int code; switch (src->download_error->code) { case RB_MTP_THREAD_ERROR_NO_SPACE: code = GST_RESOURCE_ERROR_NO_SPACE_LEFT; break; case RB_MTP_THREAD_ERROR_TEMPFILE: code = GST_RESOURCE_ERROR_OPEN_WRITE; break; default: case RB_MTP_THREAD_ERROR_GET_TRACK: code = GST_RESOURCE_ERROR_READ; break; } GST_WARNING_OBJECT (src, "error: %s", src->download_error->message); gst_element_message_full (GST_ELEMENT (src), GST_MESSAGE_ERROR, GST_RESOURCE_ERROR, code, src->download_error->message, NULL, __FILE__, GST_FUNCTION, __LINE__); return FALSE; } } /* open file - maybe do this in create after waiting for it to finish downloading */ src->fd = open (src->tempfile, O_RDONLY, 0); if (src->fd < 0) { switch (errno) { case ENOENT: GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL), ("Could not find temporary file")); break; default: GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), ("Could not open temporary file for reading")); } return FALSE; } src->read_position = 0; return TRUE; }
static void gegl_tile_backend_swap_entry_destroy (GeglTileBackendSwap *self, SwapEntry *entry) { guint64 start, end; gint tile_size = gegl_tile_backend_get_tile_size (GEGL_TILE_BACKEND (self)); GList *hlink; if (entry->link) { GList *link; g_mutex_lock (&mutex); if ((link = entry->link)) { ThreadParams *queued_op = link->data; g_queue_delete_link (queue, link); g_free (queued_op->source); g_slice_free (ThreadParams, queued_op); } g_mutex_unlock (&mutex); } start = entry->offset; end = start + tile_size; if ((hlink = gap_list)) while (hlink) { GList *llink = hlink->prev; SwapGap *lgap, *hgap; if (llink) lgap = llink->data; hgap = hlink->data; /* attempt to merge lower, upper and this gap */ if (llink != NULL && lgap->end == start && hgap->start == end) { llink->next = hlink->next; if (hlink->next) hlink->next->prev = llink; lgap->end = hgap->end; g_slice_free (SwapGap, hgap); hlink->next = NULL; hlink->prev = NULL; g_list_free (hlink); break; } /* attempt to merge with upper gap */ else if (hgap->start == end) { hgap->start = start; break; } /* attempt to merge with lower gap */ else if (llink != NULL && lgap->end == start) { lgap->end = end; break; } /* create new gap */ else if (hgap->start > end) { lgap = gegl_tile_backend_swap_gap_new (start, end); gap_list = g_list_insert_before (gap_list, hlink, lgap); break; } /* if there's no more elements in the list after this */ else if (hlink->next == NULL) { /* attempt to merge with the last gap */ if (hgap->end == start) { hgap->end = end; } /* create a new gap in the end of the list */ else { GList *new_link; hgap = gegl_tile_backend_swap_gap_new (start, end); new_link = g_list_alloc (); new_link->next = NULL; new_link->prev = hlink; new_link->data = hgap; hlink->next = new_link; } break; } hlink = hlink->next; } else gap_list = g_list_prepend (NULL, gegl_tile_backend_swap_gap_new (start, end)); g_hash_table_remove (self->index, entry); g_slice_free (SwapEntry, entry); }
static gboolean on_incoming_connection(GThreadedSocketService *service, GSocketConnection *connection, GObject *source_object, OwrImageServer *image_server) { GOutputStream *bos; GDataInputStream *dis; gchar *error_body, *error_header = NULL, *response_header = NULL; gchar *line, *tag; gsize line_length, i; guint content_length = 0; OwrImageRenderer *image_renderer; GBytes *image; gconstpointer image_data; gsize image_data_size = 0; OWR_UNUSED(service); OWR_UNUSED(source_object); g_return_val_if_fail(OWR_IS_IMAGE_SERVER(image_server), TRUE); bos = g_buffered_output_stream_new(g_io_stream_get_output_stream(G_IO_STREAM(connection))); dis = g_data_input_stream_new(g_io_stream_get_input_stream(G_IO_STREAM(connection))); g_data_input_stream_set_newline_type(dis, G_DATA_STREAM_NEWLINE_TYPE_CR_LF); error_body = "404 Not Found"; error_header = g_strdup_printf(HTTP_RESPONSE_HEADER_TEMPLATE, 404, "Not Found", "text/plain", (guint)strlen(error_body), "*"); while (TRUE) { line = g_data_input_stream_read_line(dis, &line_length, NULL, NULL); if (!line) break; if (line_length > 6) { tag = g_strdup(line + 7); for (i = 0; i < strlen(tag); i++) { if (tag[i] == '-') { tag[i] = '\0'; break; } } } else tag = NULL; g_free(line); while ((line = g_data_input_stream_read_line(dis, &line_length, NULL, NULL))) { g_free(line); if (!line_length) { /* got all request headers */ break; } } if (!line) break; g_mutex_lock(&image_server->priv->image_renderers_mutex); image_renderer = tag ? g_hash_table_lookup(image_server->priv->image_renderers, tag) : NULL; if (image_renderer) g_object_ref(image_renderer); g_mutex_unlock(&image_server->priv->image_renderers_mutex); image = image_renderer ? _owr_image_renderer_pull_bmp_image(image_renderer) : NULL; if (image_renderer) g_object_unref(image_renderer); if (!image) { g_output_stream_write(bos, error_header, strlen(error_header), NULL, NULL); g_output_stream_write(bos, error_body, strlen(error_body), NULL, NULL); break; } image_data = g_bytes_get_data(image, &image_data_size); if (content_length != image_data_size) { content_length = image_data_size; g_free(response_header); response_header = g_strdup_printf(HTTP_RESPONSE_HEADER_TEMPLATE, 200, "OK", "image/bmp", content_length, image_server->priv->allow_origin); g_buffered_output_stream_set_buffer_size(G_BUFFERED_OUTPUT_STREAM(bos), strlen(response_header) + content_length); } g_output_stream_write(bos, response_header, strlen(response_header), NULL, NULL); g_output_stream_write(bos, image_data, image_data_size, NULL, NULL); g_output_stream_flush(bos, NULL, NULL); g_bytes_unref(image); } g_free(response_header); g_free(error_header); g_object_unref(dis); g_object_unref(bos); return FALSE; }
/*! \brief setup_serial_params() is another wrapper that calls the appropriate calls to initialize the serial port to the proper speed, bits, flow, parity etc.. */ G_MODULE_EXPORT void setup_serial_params(void) { GMutex *serio_mutex = NULL; gchar * baud_str = NULL; Parity parity = NONE; gint baudrate = 0; gint bits = 0; gint stop = 0; Serial_Params *serial_params = NULL; #ifndef __WIN32__ speed_t baud; #endif serial_params = DATA_GET(global_data,"serial_params"); serio_mutex = DATA_GET(global_data,"serio_mutex"); baud_str = DATA_GET(global_data,"ecu_baud_str"); if (!parse_baud_str(baud_str,&baudrate,&bits,&parity,&stop)) MTXDBG(SERIAL_RD|SERIAL_WR|CRITICAL,_("ERROR! couldn't parse ecu_baud string %s\n"),baud_str); DATA_SET(global_data,"ecu_baud",GINT_TO_POINTER(baudrate)); if (serial_params->open == FALSE) return; if (DATA_GET(global_data,"network_mode")) { printf("network mode, exiting!\n"); return; } /*printf("setup_serial_params entered\n");*/ g_mutex_lock(serio_mutex); #ifdef __WIN32__ win32_setup_serial_params(serial_params->fd,baudrate,bits,parity,stop); #else /* Save serial port status */ tcgetattr(serial_params->fd,&serial_params->oldtio); g_mutex_unlock(serio_mutex); flush_serial(serial_params->fd, BOTH); g_mutex_lock(serio_mutex); /* Sets up serial port for the modes we want to use. * NOTE: Original serial tio params are stored and restored * in the open_serial() and close_serial() functions. */ /*clear struct for new settings*/ memset(&serial_params->newtio, 0, sizeof(serial_params->newtio)); /* * BAUDRATE: Set bps rate. You could also use cfsetispeed and * cfsetospeed * CRTSCTS : output hardware flow control (only used if the cable has * all necessary lines. See sect. 7 of Serial-HOWTO) * CS8 : 8n1 (8bit,no parity,1 stopbit) * CLOCAL : local connection, no modem contol * CREAD : enable receiving characters */ /* Set baud (posix way) */ switch (baudrate) { case 8192: baud = B38400; break; case 9600: baud = B9600; break; case 19200: baud = B19200; break; case 38400: baud = B38400; break; case 57600: baud = B57600; break; case 115200: baud = B115200; break; default: /* Assume 9600 */ baud = B9600; } cfsetispeed(&serial_params->newtio, baud); cfsetospeed(&serial_params->newtio, baud); /* Mask and set to 8N1 mode... */ /* Mask out HW flow control */ serial_params->newtio.c_cflag &= ~(CRTSCTS); /* Set additional flags, note |= syntax.. */ /* CLOCAL == Ignore modem control lines CREAD == Enable receiver */ serial_params->newtio.c_cflag |= CLOCAL | CREAD; /* Mask out Bit size */ serial_params->newtio.c_cflag &= ~(CSIZE); switch (bits) { case 8: serial_params->newtio.c_cflag |= CS8; break; case 7: serial_params->newtio.c_cflag |= CS7; break; case 6: serial_params->newtio.c_cflag |= CS6; break; case 5: serial_params->newtio.c_cflag |= CS5; break; } /* Mask out Parity Flags */ serial_params->newtio.c_cflag &= ~(PARENB | PARODD); switch (parity) { case ODD: serial_params->newtio.c_cflag |= (PARENB | PARODD); break; case EVEN: serial_params->newtio.c_cflag |= PARENB; break; case NONE: break; } /* Mask out Stip bit flags */ serial_params->newtio.c_cflag &= ~(CSTOPB); if (stop == 2) serial_params->newtio.c_cflag |= CSTOPB; /* 1 stop bit is default */ /* RAW Input */ /* Ignore signals, disable canonical, echo, etc */ /* serial_params->newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHONL | IEXTEN | ISIG); */ serial_params->newtio.c_lflag = 0; /* Disable software flow control */ serial_params->newtio.c_iflag &= ~(IXON | IXOFF | IXANY ); /* serial_params->newtio.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL ); */ serial_params->newtio.c_iflag = IGNBRK; /* Set raw output */ /* serial_params->newtio.c_oflag &= ~OPOST; */ serial_params->newtio.c_oflag = 0; /* initialize all control characters default values can be found in /usr/include/termios.h, and are given in the comments, but we don't need them here */ serial_params->newtio.c_cc[VINTR] = 0; /* Ctrl-c */ serial_params->newtio.c_cc[VQUIT] = 0; /* Ctrl-\ */ serial_params->newtio.c_cc[VERASE] = 0; /* del */ serial_params->newtio.c_cc[VKILL] = 0; /* @ */ serial_params->newtio.c_cc[VEOF] = 0; /* Ctrl-d */ serial_params->newtio.c_cc[VEOL] = 0; /* '\0' */ /* Fredcooke say vmin = 1 solves his hang on close issue with his broken FTDI driver, but that will break interrogation unless I completely transition to nonblocking IO */ serial_params->newtio.c_cc[VMIN] = 0; serial_params->newtio.c_cc[VTIME] = 1; /* 100ms timeout */ /* PIS Specific (odd baud rate) DISABLED */ /* if (ioctl(serial_params->fd, TIOCGSERIAL, &serial_params->oldctl) != 0) MTXDBG(SERIAL_RD|SERIAL_WR|CRITICAL, _("Error getting serial line information error %s\n"),strerror(errno)); else { MTXDBG(SERIAL_RD|SERIAL_WR, _("Get serial line info call OK\n")); // copy ioctl structure memcpy(&serial_params->newctl, &serial_params->oldctl, sizeof(serial_params->newctl)); // and if we are PIS 8192 make a custom divisor if (baudrate == 8192) { if (serial_params->newctl.baud_base < 115200) serial_params->newctl.baud_base = 115200; serial_params->newctl.custom_divisor = 14; serial_params->newctl.flags |= (ASYNC_SPD_MASK & ASYNC_SPD_CUST); if (ioctl(serial_params->fd, TIOCSSERIAL, &serial_params->newctl) != 0) MTXDBG(SERIAL_RD|SERIAL_WR|CRITICAL,_("Error setting ioctl\n")); else MTXDBG(SERIAL_RD|SERIAL_WR,_("Set ioctl OK\n")); } } */ tcsetattr(serial_params->fd, TCSANOW, &serial_params->newtio); #endif g_mutex_unlock(serio_mutex); flush_serial(serial_params->fd,BOTH); return; }
static GstFlowReturn gst_app_src_create (GstBaseSrc * bsrc, guint64 offset, guint size, GstBuffer ** buf) { GstAppSrc *appsrc = GST_APP_SRC (bsrc); GstFlowReturn ret; g_mutex_lock (appsrc->mutex); /* check flushing first */ if (G_UNLIKELY (appsrc->flushing)) goto flushing; if (appsrc->stream_type == GST_APP_STREAM_TYPE_RANDOM_ACCESS) { /* if we are dealing with a random-access stream, issue a seek if the offset * changed. */ if (G_UNLIKELY (appsrc->offset != offset)) { gboolean res; g_mutex_unlock (appsrc->mutex); GST_DEBUG_OBJECT (appsrc, "we are at %" G_GINT64_FORMAT ", seek to %" G_GINT64_FORMAT, appsrc->offset, offset); g_signal_emit (appsrc, gst_app_src_signals[SIGNAL_SEEK_DATA], 0, offset, &res); if (G_UNLIKELY (!res)) /* failing to seek is fatal */ goto seek_error; g_mutex_lock (appsrc->mutex); appsrc->offset = offset; } } while (TRUE) { /* return data as long as we have some */ if (!g_queue_is_empty (appsrc->queue)) { guint buf_size; *buf = g_queue_pop_head (appsrc->queue); buf_size = GST_BUFFER_SIZE (*buf); GST_DEBUG_OBJECT (appsrc, "we have buffer %p of size %u", *buf, buf_size); appsrc->queued_bytes -= buf_size; /* only update the offset when in random_access mode */ if (appsrc->stream_type == GST_APP_STREAM_TYPE_RANDOM_ACCESS) { appsrc->offset += buf_size; } gst_buffer_set_caps (*buf, appsrc->caps); /* signal that we removed an item */ g_cond_broadcast (appsrc->cond); ret = GST_FLOW_OK; break; } else { g_mutex_unlock (appsrc->mutex); /* we have no data, we need some. We fire the signal with the size hint. */ g_signal_emit (appsrc, gst_app_src_signals[SIGNAL_NEED_DATA], 0, size, NULL); g_mutex_lock (appsrc->mutex); /* we can be flushing now because we released the lock */ if (G_UNLIKELY (appsrc->flushing)) goto flushing; /* if we have a buffer now, continue the loop and try to return it. In * random-access mode (where a buffer is normally pushed in the above * signal) we can still be empty because the pushed buffer got flushed or * when the application pushes the requested buffer later, we support both * possiblities. */ if (!g_queue_is_empty (appsrc->queue)) continue; /* no buffer yet, maybe we are EOS, if not, block for more data. */ } /* check EOS */ if (G_UNLIKELY (appsrc->is_eos)) goto eos; /* nothing to return, wait a while for new data or flushing. */ g_cond_wait (appsrc->cond, appsrc->mutex); } g_mutex_unlock (appsrc->mutex); return ret; /* ERRORS */ flushing: { GST_DEBUG_OBJECT (appsrc, "we are flushing"); g_mutex_unlock (appsrc->mutex); return GST_FLOW_WRONG_STATE; } eos: { GST_DEBUG_OBJECT (appsrc, "we are EOS"); g_mutex_unlock (appsrc->mutex); return GST_FLOW_UNEXPECTED; } seek_error: { GST_ELEMENT_ERROR (appsrc, RESOURCE, READ, ("failed to seek"), GST_ERROR_SYSTEM); return GST_FLOW_ERROR; } }