Пример #1
0
static int v4l2_g_ctrl(GstImxV4l2VideoSrc *v4l2src, int id, int *value)
{
	struct v4l2_control control;
	int ret;

	control.id = id;
	ret = ioctl(GST_IMX_FD_OBJECT_GET_FD(v4l2src->fd_obj_v4l), VIDIOC_G_CTRL, &control);

	if (ret < 0)
		GST_LOG_OBJECT(v4l2src, "VIDIOC_G_CTRL(%s) failed", ctrl_name(id));
	else {
		GST_LOG_OBJECT(v4l2src, "VIDIOC_G_CTRL(%s) returned %d", ctrl_name(id), control.value);
		*value = control.value;
	}

	return ret;
}
Пример #2
0
static inline int v4l2_s_ctrl(GstImxV4l2VideoSrc *v4l2src, int id, int value)
{
	struct v4l2_control control;
	int ret;

	GST_LOG_OBJECT(v4l2src, "VIDIOC_S_CTRL(%s, %d)", ctrl_name(id), value);

	control.id = id;
	control.value = value;
	ret = ioctl(GST_IMX_FD_OBJECT_GET_FD(v4l2src->fd_obj_v4l), VIDIOC_S_CTRL, &control);

	if (ret < 0)
		GST_LOG_OBJECT(v4l2src, "VIDIOC_S_CTRL(%s, %d) failed", ctrl_name(id), value);
	else
		GST_LOG_OBJECT(v4l2src, "VIDIOC_S_CTRL(%s, %d) succeed", ctrl_name(id), value);

	return ret;
}
Пример #3
0
/*
 * Handles merlin control events inside the module. Control events
 * that relate to cross-host communication only never reaches this.
 */
void handle_control(merlin_node *node, merlin_event *pkt)
{
	const char *ctrl;
	if (!pkt) {
		lerr("handle_control() called with NULL packet");
		return;
	}

	ctrl = ctrl_name(pkt->hdr.code);
	linfo("Received control packet code %d (%s) from %s",
		  pkt->hdr.code, ctrl, node ? node->name : "local Merlin daemon");

	/* protect against bogus headers */
	if (!node && (pkt->hdr.code == CTRL_INACTIVE || pkt->hdr.code == CTRL_ACTIVE)) {
		lerr("Received %s with unknown node id %d", ctrl, pkt->hdr.selection);
		return;
	}
	switch (pkt->hdr.code) {
	case CTRL_INACTIVE:
		/*
		 * must memset() node->info before the disconnect handler
		 * so we discard it in the peer id calculation dance if
		 * we get data from it before it sends us a CTRL_ACTIVE
		 * packet
		 */
		memset(&node->info, 0, sizeof(node->info));
		node_set_state(node, STATE_NONE, "Received CTRL_INACTIVE");
		break;
	case CTRL_ACTIVE:
		/*
		 * Only mark the node as connected if the CTRL_ACTIVE packet
		 * checks out properly and the info is new. If it *is* new,
		 * we must re-do the peer assignment thing.
		 */
		if (!handle_ctrl_active(node, pkt)) {
			node_set_state(node, STATE_CONNECTED, "Received CTRL_ACTIVE");
			assign_peer_ids();
		}
		break;
	case CTRL_STALL:
		ctrl_stall_start();
		break;
	case CTRL_RESUME:
		ctrl_stall_stop();
		assign_peer_ids();
		break;
	case CTRL_STOP:
		linfo("Received (and ignoring) CTRL_STOP event. What voodoo is this?");
		break;
	default:
		lwarn("Unknown control code: %d", pkt->hdr.code);
	}
}
Пример #4
0
/*
 * wraps io_send_all() and adds proper error handling when we run
 * into sending errors. It's up to the caller to poll the socket
 * for writability, or pass the proper flags and ignore errors
 */
int node_send(merlin_node *node, void *data, int len, int flags)
{
	merlin_event *pkt = (merlin_event *)data;
	int sent, sd = 0;

	if (!node || node->sock < 0)
		return 0;

	if (len >= HDR_SIZE && pkt->hdr.type == CTRL_PACKET) {
		ldebug("Sending %s to %s", ctrl_name(pkt->hdr.code), node->name);
		if (pkt->hdr.code == CTRL_ACTIVE) {
			merlin_nodeinfo *info = (merlin_nodeinfo *)&pkt->body;
			ldebug("   start time: %lu.%lu",
			       info->start.tv_sec, info->start.tv_usec);
			ldebug("  config hash: %s", tohex(info->config_hash, 20));
			ldebug(" config mtime: %lu", info->last_cfg_change);
		}
	}

	sent = io_send_all(node->sock, data, len);
	/* success. Should be the normal case */
	if (sent == len) {
		node->stats.bytes.sent += sent;
		node->last_action = node->last_sent = time(NULL);
		return sent;
	}

	/*
	 * partial writes and complete failures can only be handled
	 * by disconnecting and re-syncing the stream
	 */
	sd = node->sock;
	node_disconnect(node, "Partial or failed write() (sent=%d; len=%d): %s",
				   sent, len, strerror(errno));

	if (sent < 0) {
		/* if we would have blocked, we simply return 0 */
		if (errno == EAGAIN || errno == EWOULDBLOCK)
			return 0;

		/* otherwise we log the error and disconnect the node */
		lerr("Failed to send(%d, %p, %d, %d) to %s: %s",
			 sd, data, len, flags, node->name, strerror(errno));
		return sent;
	}

	/* partial write. ugh... */
	lerr("Partial send() to %s. %d of %d bytes sent",
		 node->name, sent, len);
	return -1;
}