Beispiel #1
0
/**
 * 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;
}
Beispiel #4
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;
  }
}
Beispiel #5
0
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;
}
Beispiel #6
0
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);
}
Beispiel #7
0
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);
}
Beispiel #10
0
/* 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;
}
Beispiel #11
0
/* 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);
    }
}
Beispiel #12
0
/**
 * 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;
}
Beispiel #13
0
void scheduler_ref(Scheduler* scheduler) {
    MAGIC_ASSERT(scheduler);
    g_mutex_lock(&(scheduler->globalLock));
    scheduler->referenceCount++;
    g_mutex_unlock(&(scheduler->globalLock));
}
Beispiel #14
0
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;
}
Beispiel #15
0
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);
  }
}
Beispiel #16
0
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);
}
Beispiel #17
0
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));
	}
    }
}
Beispiel #18
0
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;
}
Beispiel #20
0
static void
ent_lock (GIOPMessageQueueEntry *ent)
{
	if (ent->src_thread)
		g_mutex_lock (ent->src_thread->lock);
}
Beispiel #21
0
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;
}
Beispiel #23
0
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;
}
Beispiel #26
0
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);
}
Beispiel #28
0
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;
}
Beispiel #29
0
/*!
  \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;
}
Beispiel #30
0
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;
  }
}