static void * arv_fake_stream_thread (void *data) { ArvFakeStreamThreadData *thread_data = data; ArvBuffer *buffer; arv_log_stream_thread ("[FakeStream::thread] Start"); if (thread_data->callback != NULL) thread_data->callback (thread_data->user_data, ARV_STREAM_CALLBACK_TYPE_INIT, NULL); while (!thread_data->cancel) { arv_fake_camera_wait_for_next_frame (thread_data->camera); buffer = arv_stream_pop_input_buffer (thread_data->stream); if (buffer != NULL) { arv_fake_camera_fill_buffer (thread_data->camera, buffer, NULL); if (buffer->status == ARV_BUFFER_STATUS_SUCCESS) thread_data->n_completed_buffers++; else thread_data->n_failures++; if (thread_data->callback != NULL) thread_data->callback (thread_data->user_data, ARV_STREAM_CALLBACK_TYPE_BUFFER_DONE, buffer); arv_stream_push_output_buffer (thread_data->stream, buffer); } else thread_data->n_underruns++; } if (thread_data->callback != NULL) thread_data->callback (thread_data->user_data, ARV_STREAM_CALLBACK_TYPE_EXIT, NULL); arv_log_stream_thread ("[FakeStream::thread] Stop"); return NULL; }
static void * arv_uv_stream_thread (void *data) { ArvUvStreamThreadData *thread_data = data; ArvUvspPacket *packet; ArvBuffer *buffer = NULL; void *incoming_buffer; guint64 offset; size_t transferred; arv_log_stream_thread ("Start USB3Vision stream thread"); incoming_buffer = g_malloc (MAXIMUM_TRANSFER_SIZE); if (thread_data->callback != NULL) thread_data->callback (thread_data->user_data, ARV_STREAM_CALLBACK_TYPE_INIT, NULL); offset = 0; while (!thread_data->cancel) { size_t size; transferred = 0; if (buffer == NULL) size = thread_data->leader_size; else { if (offset < buffer->priv->size) size = MIN (thread_data->payload_size, buffer->priv->size - offset); else size = thread_data->trailer_size; } /* Avoid unnecessary memory copy by transferring data directly to the image buffer */ if (buffer != NULL && buffer->priv->status == ARV_BUFFER_STATUS_FILLING && offset + size <= buffer->priv->size) packet = buffer->priv->data + offset; else packet = incoming_buffer; arv_uv_device_bulk_transfer (thread_data->uv_device, 0x81 | LIBUSB_ENDPOINT_IN, packet, size, &transferred, 0, NULL); if (transferred > 0) { ArvUvspPacketType packet_type; arv_log_sp ("Received %d bytes", transferred); arv_uvsp_packet_debug (packet, ARV_DEBUG_LEVEL_LOG); packet_type = arv_uvsp_packet_get_packet_type (packet); switch (packet_type) { case ARV_UVSP_PACKET_TYPE_LEADER: if (buffer != NULL) { arv_debug_stream_thread ("New leader received while a buffer is still open"); buffer->priv->status = ARV_BUFFER_STATUS_MISSING_PACKETS; arv_stream_push_output_buffer (thread_data->stream, buffer); thread_data->n_failures++; buffer = NULL; } buffer = arv_stream_pop_input_buffer (thread_data->stream); if (buffer != NULL) { buffer->priv->status = ARV_BUFFER_STATUS_FILLING; buffer->priv->gvsp_payload_type = ARV_GVSP_PAYLOAD_TYPE_IMAGE; arv_uvsp_packet_get_region (packet, &buffer->priv->width, &buffer->priv->height, &buffer->priv->x_offset, &buffer->priv->y_offset); buffer->priv->frame_id = arv_uvsp_packet_get_frame_id (packet); buffer->priv->timestamp_ns = arv_uvsp_packet_get_timestamp (packet); offset = 0; } else thread_data->n_underruns++; break; case ARV_UVSP_PACKET_TYPE_TRAILER: if (buffer != NULL) { arv_log_stream_thread ("Received %" G_GUINT64_FORMAT " bytes - expected %" G_GUINT64_FORMAT, offset, buffer->priv->size); buffer->priv->status = ARV_BUFFER_STATUS_SUCCESS; arv_stream_push_output_buffer (thread_data->stream, buffer); thread_data->n_completed_buffers++; buffer = NULL; } break; case ARV_UVSP_PACKET_TYPE_DATA: if (buffer != NULL && buffer->priv->status == ARV_BUFFER_STATUS_FILLING) { if (offset + transferred <= buffer->priv->size) { if (packet == incoming_buffer) memcpy (((char *) buffer->priv->data) + offset, packet, transferred); offset += transferred; } else buffer->priv->status = ARV_BUFFER_STATUS_SIZE_MISMATCH; } break; default: arv_debug_stream_thread ("Unkown packet type"); break; } } } if (thread_data->callback != NULL) thread_data->callback (thread_data->user_data, ARV_STREAM_CALLBACK_TYPE_EXIT, NULL); g_free (incoming_buffer); arv_log_stream_thread ("Stop USB3Vision stream thread"); return NULL; }
static ArvGvStreamFrameData * _find_frame_data (ArvGvStreamThreadData *thread_data, guint32 frame_id, ArvGvspPacket *packet, guint32 packet_id, size_t read_count, guint64 time_us) { ArvGvStreamFrameData *frame = NULL; ArvBuffer *buffer; GSList *iter; guint n_packets = 0; gint16 frame_id_inc; for (iter = thread_data->frames; iter != NULL; iter = iter->next) { frame = iter->data; if (frame->frame_id == frame_id) { frame->last_packet_time_us = time_us; return frame; } } frame_id_inc = (gint16) frame_id - (gint16) thread_data->last_frame_id; if (frame_id_inc < 1 && frame_id_inc > -ARV_GV_STREAM_DISCARD_LATE_FRAME_THRESHOLD) { arv_debug_stream_thread ("[GvStream::_find_frame_data] Discard late frame %u (last: %u)", frame_id, thread_data->last_frame_id); return NULL; } buffer = arv_stream_pop_input_buffer (thread_data->stream); if (buffer == NULL) { thread_data->n_underruns++; return NULL; } frame = g_new0 (ArvGvStreamFrameData, 1); frame->error_packet_received = FALSE; frame->frame_id = frame_id; frame->last_valid_packet = -1; frame->buffer = buffer; _update_socket (thread_data, frame->buffer); frame->buffer->status = ARV_BUFFER_STATUS_FILLING; n_packets = (frame->buffer->size + thread_data->data_size - 1) / thread_data->data_size + 2; frame->first_packet_time_us = time_us; frame->last_packet_time_us = time_us; frame->packet_data = g_new0 (ArvGvStreamPacketData, n_packets); frame->n_packets = n_packets; if (thread_data->callback != NULL && frame->buffer != NULL) thread_data->callback (thread_data->user_data, ARV_STREAM_CALLBACK_TYPE_START_BUFFER, NULL); thread_data->last_frame_id = frame_id; if (frame_id_inc > 1) { thread_data->n_missing_frames++; arv_log_stream_thread ("[GvStream::_find_frame_data] Missed %d frame(s) before %u", frame_id_inc - 1, frame_id); } thread_data->frames = g_slist_append (thread_data->frames, frame); arv_log_stream_thread ("[GvStream::_find_frame_data] Start frame %u", frame_id); return frame; }