void main(int argc, char* argv[]){ printf("creating segment...\n"); segment* seg = segment_new( sizeof(char), 5 ); if( segment_full( seg)){ printf("\033[31mError: segment should not have been full.\033[0m"); debug_segment( seg, ""); exit( -1); } printf("Filling segment...\n"); char c; for( int i = 0; i<5; i++){ c = 'a' + i; printf("\tpushing item %i: %c\n",i, c); if( segment_push( seg, &c ) == 0 ){ printf("\033[31mError adding to segment.\033[0m"); debug_segment( seg, "" ); exit( -2); } debug_segment( seg, "" ); } if( ! segment_full( seg)){ printf("\033[31mError: segment should have been full.\033[0m"); debug_segment( seg, ""); } printf("Getting each char back...\n"); char* cptr; for( int i=0; i < 5; i++){ cptr = (char*)segment_getptr(seg, i ); printf("\titem %i: %c\n", i, *cptr ); } }
int rudp_input(Rudp *rudp, uint8_t *data, uint32_t len) { if (data==NULL || len < MIN_RUDP_HEAD_SIZE) { return -1; } const uint8_t *ptr = (const uint8_t *)data; uint32_t conv_id; uint8_t ctrl_bit, head_len, seq, ack; // read rudp head ptr = read32(ptr, &conv_id); if (conv_id != rudp->conv_id) { return -2; } ptr = read8(ptr, &ctrl_bit); ptr = read8(ptr, &head_len); ptr = read8(ptr, &seq); ptr = read8(ptr, &ack); if (ctrl_bit & CTRL_SYN) { RudpSynParam syn_param; read_syn(ptr, &syn_param); rudp->rcv_irs = seq; rudp->rcv_cur = seq; rudp->rcv_max = rudp->rcv_cur + rudp->rcv_wnd; if (rudp->state == RUDP_STATE_LISTEN) { rudp->state = RUDP_STATE_SYN_RCVD; // TODO 构建syn-ack包 } } if (ctrl_bit & CTRL_ACK) { uint8_t out_of_seqs[256]; // FIXME size_t out_of_cnt = 0; if (ctrl_bit & CTRL_EAK) { out_of_cnt = head_len - MIN_RUDP_HEAD_SIZE; read_eak(ptr, seqs); } // TODO 解析未确认的包 parse_una(rudp, ack, out_of_seqs, out_of_cnt); } #if 0 if (len>head_len) { Segment *seq = segment_new(len-head_len); if (seq!=NULL) { seq->seq = seq; memcpy(seq->data, data+head_len, len-head_len); } // TODO 加入rcv_seq } #endif }
Worm worm_new(Grid grid, int size) { Worm retval = malloc(sizeof(struct _Worm)); retval->grid = grid; retval->size = size; retval->state = worm_state_new(); int i; for (i = 0; i < size; i++) { segment_new(retval); } debug("Creating new segment for worm of size %d", size); return retval; }
int rudp_send(Rudp *rudp, uint8_t *buf, uint32_t len) { if (rudp==NULL || (len>0 && buf==NULL)) { return -1; } Segment *seg = segment_new(sizeof(*seg) + len); if (seg==NULL) { return -2; } if (len>0) { memcpy(seg->data, buf, len); } SIMPLEQ_INSERT_TAIL(&rudp->snd_buf, seg); return 0; }
Segment template_new(int t_kind, int t_size, int words, int **ptr) /*;template_new*/ { Segment s; s = segment_new(SEGMENT_KIND_DATA, words); s->seg_ptr = ptr; /* save address of pointer to be updated */ /* return pointer to start of segment */ *(s->seg_ptr) = (int *) s->seg_data; segment_put_word(s, t_kind); segment_put_word(s, t_size); /* assume user will fill in rest direcly so point to end */ s->seg_pos = s->seg_maxpos = words; return s; }
GList * copy_segment_list (GList * list) { GList *res = NULL; while (list) { Segment *pdata = (Segment *) list->data; res = g_list_append (res, segment_new (pdata->rate, pdata->format, pdata->start, pdata->stop, pdata->position)); list = list->next; } return res; }
int rudp_open(Rudp *rudp) { // SYN Segment *seg = segment_new(32); if (seg==NULL) { return -1; } memset(seg, 0, sizeof(*seg)); seg->seq = rudp->snd_iss; uint16_t checksum = 0; uint8_t * ptr = seg->data; ptr = write32(ptr, rudp->conv_id); ptr = write8(ptr, (uint8_t)CTRL_SYN); ptr = write8(ptr, 32); ptr = write8(ptr, seg->seq); ptr = write8(ptr, 0); ptr = write8(ptr, 1); // ver ptr = write8(ptr, 1); // max number of out standing segs ptr = write8(ptr, 0); // opt flags ptr = write8(ptr, 0); // spare ptr = write16(ptr, rudp->param.max_seg_size); ptr = write16(ptr, rudp->param.retrans_timeout); ptr = write16(ptr, rudp->param.cum_ack_timeout); ptr = write16(ptr, rudp->param.null_seg_timout); ptr = write16(ptr, rudp->param.trans_state_timeout); ptr = write8(ptr, rudp->param.max_retrans); ptr = write8(ptr, rudp->param.max_cum_ack); ptr = write8(ptr, rudp->param.max_out_of_seq); ptr = write8(ptr, rudp->param.max_auto_reset); ptr = write32(ptr, rudp->conv_id); // connection id ptr = write16(ptr, checksum); SIMPLEQ_INSERT_TAIL(&rudp->snd_segs, seg, link); rudp->state = RUDP_STATE_SYN_SENT; return 0; }
static void test_one_after_other_full (gboolean async) { GstElement *pipeline; GstElement *comp, *sink, *source1, *source2; CollectStructure *collect; GstBus *bus; GstMessage *message; gboolean carry_on = TRUE; guint64 start, stop; gint64 duration; GstPad *sinkpad; pipeline = gst_pipeline_new ("test_pipeline"); comp = gst_element_factory_make_or_warn ("gnlcomposition", "test_composition"); fail_if (comp == NULL); /* Source 1 Start : 0s Duration : 1s Media start : 5s Media Duartion : 1s Priority : 1 */ source1 = videotest_gnl_src_full ("source1", 0, 1 * GST_SECOND, 5 * GST_SECOND, 1 * GST_SECOND, 3, 1); fail_if (source1 == NULL); check_start_stop_duration (source1, 0, 1 * GST_SECOND, 1 * GST_SECOND); /* Source 2 Start : 1s Duration : 1s Media start : 2s Media Duration : 1s Priority : 1 */ source2 = videotest_gnl_src_full ("source2", 1 * GST_SECOND, 1 * GST_SECOND, 2 * GST_SECOND, 1 * GST_SECOND, 2, 1); fail_if (source2 == NULL); check_start_stop_duration (source2, 1 * GST_SECOND, 2 * GST_SECOND, 1 * GST_SECOND); /* Add one source */ DISABLE_ASYNC_UPDATE; gst_bin_add (GST_BIN (comp), source1); ENABLE_ASYNC_UPDATE; check_start_stop_duration (comp, 0, 1 * GST_SECOND, 1 * GST_SECOND); ASSERT_OBJECT_REFCOUNT (source1, "source1", 1); /* Second source */ DISABLE_ASYNC_UPDATE; gst_bin_add (GST_BIN (comp), source2); ENABLE_ASYNC_UPDATE; check_start_stop_duration (comp, 0, 2 * GST_SECOND, 2 * GST_SECOND); ASSERT_OBJECT_REFCOUNT (source2, "source2", 1); /* Remove first source */ gst_object_ref (source1); DISABLE_ASYNC_UPDATE; gst_bin_remove (GST_BIN (comp), source1); ENABLE_ASYNC_UPDATE; check_start_stop_duration (comp, 1 * GST_SECOND, 2 * GST_SECOND, 1 * GST_SECOND); ASSERT_OBJECT_REFCOUNT (source1, "source1", 1); /* Re-add first source */ DISABLE_ASYNC_UPDATE; gst_bin_add (GST_BIN (comp), source1); ENABLE_ASYNC_UPDATE; check_start_stop_duration (comp, 0, 2 * GST_SECOND, 2 * GST_SECOND); gst_object_unref (source1); ASSERT_OBJECT_REFCOUNT (source1, "source1", 1); sink = gst_element_factory_make_or_warn ("fakesink", "sink"); fail_if (sink == NULL); gst_bin_add_many (GST_BIN (pipeline), comp, sink, NULL); /* Shared data */ collect = g_new0 (CollectStructure, 1); collect->comp = comp; collect->sink = sink; /* Expected segments */ collect->expected_segments = g_list_append (collect->expected_segments, segment_new (1.0, GST_FORMAT_TIME, 5 * GST_SECOND, 6 * GST_SECOND, 0)); collect->expected_segments = g_list_append (collect->expected_segments, segment_new (1.0, GST_FORMAT_TIME, 2 * GST_SECOND, 3 * GST_SECOND, 1 * GST_SECOND)); g_signal_connect (G_OBJECT (comp), "pad-added", G_CALLBACK (composition_pad_added_cb), collect); sinkpad = gst_element_get_pad (sink, "sink"); gst_pad_add_event_probe (sinkpad, G_CALLBACK (sinkpad_event_probe), collect); gst_pad_add_buffer_probe (sinkpad, G_CALLBACK (sinkpad_buffer_probe), collect); bus = gst_element_get_bus (GST_ELEMENT (pipeline)); GST_DEBUG ("Setting pipeline to PLAYING"); ASSERT_OBJECT_REFCOUNT (source1, "source1", 1); fail_if (gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE); GST_DEBUG ("Let's poll the bus"); while (carry_on) { message = gst_bus_poll (bus, GST_MESSAGE_ANY, GST_SECOND / 2); if (message) { switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_EOS: /* we should check if we really finished here */ GST_WARNING ("Got an EOS"); carry_on = FALSE; break; case GST_MESSAGE_SEGMENT_START: case GST_MESSAGE_SEGMENT_DONE: /* We shouldn't see any segement messages, since we didn't do a segment seek */ GST_WARNING ("Saw a Segment start/stop"); fail_if (TRUE); break; case GST_MESSAGE_ERROR: GST_WARNING ("Saw an ERROR"); fail_if (TRUE); default: break; } gst_mini_object_unref (GST_MINI_OBJECT (message)); } } GST_DEBUG ("Setting pipeline to NULL"); fail_if (gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_READY) == GST_STATE_CHANGE_FAILURE); fail_if (collect->expected_segments != NULL); GST_DEBUG ("Resetted pipeline to READY"); /* Expected segments */ collect->expected_segments = g_list_append (collect->expected_segments, segment_new (1.0, GST_FORMAT_TIME, 5 * GST_SECOND, 6 * GST_SECOND, 0)); collect->expected_segments = g_list_append (collect->expected_segments, segment_new (1.0, GST_FORMAT_TIME, 2 * GST_SECOND, 3 * GST_SECOND, 1 * GST_SECOND)); collect->gotsegment = FALSE; GST_DEBUG ("Setting pipeline to PLAYING again"); fail_if (gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE); carry_on = TRUE; GST_DEBUG ("Let's poll the bus AGAIN"); while (carry_on) { message = gst_bus_poll (bus, GST_MESSAGE_ANY, GST_SECOND / 2); if (message) { switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_EOS: /* we should check if we really finished here */ carry_on = FALSE; break; case GST_MESSAGE_SEGMENT_START: case GST_MESSAGE_SEGMENT_DONE: /* We shouldn't see any segement messages, since we didn't do a segment seek */ GST_WARNING ("Saw a Segment start/stop"); fail_if (TRUE); break; case GST_MESSAGE_ERROR: GST_ERROR ("Saw an ERROR"); fail_if (TRUE); default: break; } gst_mini_object_unref (GST_MINI_OBJECT (message)); } else { GST_DEBUG ("bus_poll responded, but there wasn't any message..."); } } fail_if (collect->expected_segments != NULL); gst_object_unref (GST_OBJECT (sinkpad)); fail_if (gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL) == GST_STATE_CHANGE_FAILURE); ASSERT_OBJECT_REFCOUNT_BETWEEN (pipeline, "main pipeline", 1, 2); gst_object_unref (pipeline); ASSERT_OBJECT_REFCOUNT_BETWEEN (bus, "main bus", 1, 2); gst_object_unref (bus); g_free (collect); }
static void test_one_under_another_full (gboolean async) { GstElement *pipeline; GstElement *comp, *sink, *source1, *source2; CollectStructure *collect; GstBus *bus; GstMessage *message; gboolean carry_on = TRUE; guint64 start, stop; gint64 duration; GstPad *sinkpad; pipeline = gst_pipeline_new ("test_pipeline"); comp = gst_element_factory_make_or_warn ("gnlcomposition", "test_composition"); fail_if (comp == NULL); /* Source 1 Start : 0s Duration : 2s Priority : 1 */ source1 = videotest_gnl_src ("source1", 0, 2 * GST_SECOND, 3, 1); fail_if (source1 == NULL); check_start_stop_duration (source1, 0, 2 * GST_SECOND, 2 * GST_SECOND); /* Source 2 Start : 1s Duration : 2s Priority : 2 */ source2 = videotest_gnl_src ("source2", 1 * GST_SECOND, 2 * GST_SECOND, 2, 2); fail_if (source2 == NULL); check_start_stop_duration (source2, 1 * GST_SECOND, 3 * GST_SECOND, 2 * GST_SECOND); /* Add two sources */ DISABLE_ASYNC_UPDATE; gst_bin_add (GST_BIN (comp), source1); gst_bin_add (GST_BIN (comp), source2); ENABLE_ASYNC_UPDATE; check_start_stop_duration (comp, 0, 3 * GST_SECOND, 3 * GST_SECOND); /* Remove second source */ gst_object_ref (source1); DISABLE_ASYNC_UPDATE; gst_bin_remove (GST_BIN (comp), source1); ENABLE_ASYNC_UPDATE; check_start_stop_duration (comp, 1 * GST_SECOND, 3 * GST_SECOND, 2 * GST_SECOND); /* Re-add second source */ DISABLE_ASYNC_UPDATE; gst_bin_add (GST_BIN (comp), source1); ENABLE_ASYNC_UPDATE; check_start_stop_duration (comp, 0, 3 * GST_SECOND, 3 * GST_SECOND); gst_object_unref (source1); sink = gst_element_factory_make_or_warn ("fakesink", "sink"); fail_if (sink == NULL); gst_bin_add_many (GST_BIN (pipeline), comp, sink, NULL); /* Shared data */ collect = g_new0 (CollectStructure, 1); collect->comp = comp; collect->sink = sink; /* Expected segments */ collect->expected_segments = g_list_append (collect->expected_segments, segment_new (1.0, GST_FORMAT_TIME, 0, GST_SECOND, 0)); collect->expected_segments = g_list_append (collect->expected_segments, segment_new (1.0, GST_FORMAT_TIME, GST_SECOND, 2 * GST_SECOND, GST_SECOND)); collect->expected_segments = g_list_append (collect->expected_segments, segment_new (1.0, GST_FORMAT_TIME, 2 * GST_SECOND, 3 * GST_SECOND, 2 * GST_SECOND)); g_signal_connect (G_OBJECT (comp), "pad-added", G_CALLBACK (composition_pad_added_cb), collect); sinkpad = gst_element_get_pad (sink, "sink"); gst_pad_add_event_probe (sinkpad, G_CALLBACK (sinkpad_event_probe), collect); gst_pad_add_buffer_probe (sinkpad, G_CALLBACK (sinkpad_buffer_probe), collect); bus = gst_element_get_bus (GST_ELEMENT (pipeline)); fail_if (gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE); while (carry_on) { message = gst_bus_poll (bus, GST_MESSAGE_ANY, GST_SECOND / 2); if (message) { switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_EOS: /* we should check if we really finished here */ carry_on = FALSE; break; case GST_MESSAGE_SEGMENT_START: case GST_MESSAGE_SEGMENT_DONE: /* check if the segment is the correct one (0s-4s) */ carry_on = FALSE; break; case GST_MESSAGE_ERROR: fail_if (TRUE); default: break; } gst_message_unref (message); } } fail_if (collect->expected_segments != NULL); fail_if (gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL) == GST_STATE_CHANGE_FAILURE); gst_bus_poll (bus, GST_MESSAGE_ANY, GST_SECOND / 2); gst_object_unref (GST_OBJECT (sinkpad)); ASSERT_OBJECT_REFCOUNT_BETWEEN (pipeline, "main pipeline", 1, 2); gst_object_unref (pipeline); ASSERT_OBJECT_REFCOUNT_BETWEEN (bus, "main bus", 1, 2); gst_object_unref (bus); g_free (collect); }