Beispiel #1
0
void bgav_rtp_packet_buffer_destroy(bgav_rtp_packet_buffer_t * b)
  {
  pthread_mutex_destroy(&b->read_mutex);
  pthread_mutex_destroy(&b->write_mutex);
  pthread_mutex_destroy(&b->eof_mutex);
  if(b->stats.timer) gavl_timer_destroy(b->stats.timer);
  free_packets(b->read_packets);
  free_packets(b->write_packets);
  free_packets(b->read_packet);
  free_packets(b->write_packet);
  free(b);
  }
Beispiel #2
0
static bool init_connect(struct rtmp_stream *stream)
{
	obs_service_t *service;
	obs_data_t *settings;

	if (stopping(stream))
		pthread_join(stream->send_thread, NULL);

	free_packets(stream);

	service = obs_output_get_service(stream->output);
	if (!service)
		return false;

	os_atomic_set_bool(&stream->disconnected, false);
	stream->total_bytes_sent = 0;
	stream->dropped_frames   = 0;
	stream->min_drop_dts_usec= 0;
	stream->min_priority     = 0;

	settings = obs_output_get_settings(stream->output);
	dstr_copy(&stream->path,     obs_service_get_url(service));
	dstr_copy(&stream->key,      obs_service_get_key(service));
	dstr_copy(&stream->username, obs_service_get_username(service));
	dstr_copy(&stream->password, obs_service_get_password(service));
	stream->drop_threshold_usec =
		(int64_t)obs_data_get_int(settings, OPT_DROP_THRESHOLD) * 1000;
	stream->max_shutdown_time_sec =
		(int)obs_data_get_int(settings, OPT_MAX_SHUTDOWN_TIME_SEC);
	obs_data_release(settings);
	return true;
}
Beispiel #3
0
void obs_output_destroy(obs_output_t output)
{
	if (output) {
		obs_context_data_remove(&output->context);

		if (output->valid && output->active)
			obs_output_stop(output);
		if (output->service)
			output->service->output = NULL;

		free_packets(output);

		if (output->context.data)
			output->info.destroy(output->context.data);

		if (output->video_encoder) {
			obs_encoder_remove_output(output->video_encoder,
					output);
		}
		if (output->audio_encoder) {
			obs_encoder_remove_output(output->audio_encoder,
					output);
		}

		pthread_mutex_destroy(&output->interleaved_mutex);
		os_event_destroy(output->reconnect_stop_event);
		obs_context_data_free(&output->context);
		bfree(output);
	}
}
Beispiel #4
0
static void rtmp_stream_destroy(void *data)
{
	struct rtmp_stream *stream = data;

	if (stopping(stream) && !connecting(stream)) {
		pthread_join(stream->send_thread, NULL);

	} else if (connecting(stream) || active(stream)) {
		if (stream->connecting)
			pthread_join(stream->connect_thread, NULL);

		os_event_signal(stream->stop_event);

		if (active(stream)) {
			os_sem_post(stream->send_sem);
			obs_output_end_data_capture(stream->output);
			pthread_join(stream->send_thread, NULL);
		}
	}

	if (stream) {
		free_packets(stream);
		dstr_free(&stream->path);
		dstr_free(&stream->key);
		dstr_free(&stream->username);
		dstr_free(&stream->password);
		dstr_free(&stream->encoder_name);
		os_event_destroy(stream->stop_event);
		os_sem_destroy(stream->send_sem);
		pthread_mutex_destroy(&stream->packets_mutex);
		circlebuf_free(&stream->packets);
		bfree(stream);
	}
}
Beispiel #5
0
static void *send_thread(void *data)
{
	struct rtmp_stream *stream = data;
	bool disconnected = false;

	while (os_sem_wait(stream->send_sem) == 0) {
		struct encoder_packet packet;

		if (os_event_try(stream->stop_event) != EAGAIN)
			break;
		if (!get_next_packet(stream, &packet))
			continue;
		if (send_packet(stream, &packet, false) < 0) {
			disconnected = true;
			break;
		}
	}

	if (!disconnected && !send_remaining_packets(stream))
		disconnected = true;

	if (disconnected) {
		blog(LOG_INFO, "Disconnected from %s", stream->path.array);
		free_packets(stream);
	}

	if (os_event_try(stream->stop_event) == EAGAIN) {
		pthread_detach(stream->send_thread);
		obs_output_signal_stop(stream->output, OBS_OUTPUT_DISCONNECTED);
	}

	stream->active = false;
	return NULL;
}
Beispiel #6
0
static void hook_data_capture(struct obs_output *output, bool encoded,
		bool has_video, bool has_audio)
{
	void (*encoded_callback)(void *data, struct encoder_packet *packet);

	if (encoded) {
		output->received_video   = false;
		output->received_video   = false;
		output->highest_audio_ts = 0;
		output->highest_video_ts = 0;
		free_packets(output);

		encoded_callback = (has_video && has_audio) ?
			interleave_packets : default_encoded_callback;

		if (has_video)
			obs_encoder_start(output->video_encoder,
					encoded_callback, output);
		if (has_audio)
			obs_encoder_start(output->audio_encoder,
					encoded_callback, output);
	} else {
		if (has_video)
			video_output_connect(output->video,
					get_video_conversion(output),
					default_raw_video_callback, output);
		if (has_audio)
			audio_output_connect(output->audio,
					get_audio_conversion(output),
					output->info.raw_audio,
					output->context.data);
	}
}
Beispiel #7
0
static void *send_thread(void *data)
{
	struct rtmp_stream *stream = data;

	os_set_thread_name("rtmp-stream: send_thread");

	while (os_sem_wait(stream->send_sem) == 0) {
		struct encoder_packet packet;

		if (stopping(stream) && stream->stop_ts == 0) {
			break;
		}

		if (!get_next_packet(stream, &packet))
			continue;

		if (stopping(stream)) {
			if (can_shutdown_stream(stream, &packet)) {
				obs_free_encoder_packet(&packet);
				break;
			}
		}

		if (!stream->sent_headers) {
			if (!send_headers(stream)) {
				os_atomic_set_bool(&stream->disconnected, true);
				break;
			}
		}

		if (send_packet(stream, &packet, false, packet.track_idx) < 0) {
			os_atomic_set_bool(&stream->disconnected, true);
			break;
		}
	}

	if (disconnected(stream)) {
		info("Disconnected from %s", stream->path.array);
	} else {
		info("User stopped the stream");
	}

	RTMP_Close(&stream->rtmp);

	if (!stopping(stream)) {
		pthread_detach(stream->send_thread);
		obs_output_signal_stop(stream->output, OBS_OUTPUT_DISCONNECTED);
	} else {
		obs_output_end_data_capture(stream->output);
	}

	free_packets(stream);
	os_event_reset(stream->stop_event);
	os_atomic_set_bool(&stream->active, false);
	stream->sent_headers = false;
	return NULL;
}
Beispiel #8
0
void
gsq_source_free (GsqQuerier *querier)
{
	Private *priv = gsq_querier_get_pdata (querier);
	if (priv->packets) {
		free_packets (priv->packets);
		g_array_free (priv->packets, TRUE);
	}
	
	g_slice_free (Private, priv);
}
Beispiel #9
0
static bool init_connect(struct rtmp_stream *stream)
{
	obs_service_t *service;
	obs_data_t *settings;
	const char *bind_ip;
	int64_t drop_p;
	int64_t drop_b;

	if (stopping(stream)) {
		pthread_join(stream->send_thread, NULL);
	}

	free_packets(stream);

	service = obs_output_get_service(stream->output);
	if (!service)
		return false;

	os_atomic_set_bool(&stream->disconnected, false);
	stream->total_bytes_sent = 0;
	stream->dropped_frames   = 0;
	stream->min_priority     = 0;

	settings = obs_output_get_settings(stream->output);
	dstr_copy(&stream->path,     obs_service_get_url(service));
	dstr_copy(&stream->key,      obs_service_get_key(service));
	dstr_copy(&stream->username, obs_service_get_username(service));
	dstr_copy(&stream->password, obs_service_get_password(service));
	dstr_depad(&stream->path);
	dstr_depad(&stream->key);
	drop_b = (int64_t)obs_data_get_int(settings, OPT_DROP_THRESHOLD);
	drop_p = (int64_t)obs_data_get_int(settings, OPT_PFRAME_DROP_THRESHOLD);
	stream->max_shutdown_time_sec =
		(int)obs_data_get_int(settings, OPT_MAX_SHUTDOWN_TIME_SEC);

	if (drop_p < (drop_b + 200))
		drop_p = drop_b + 200;

	stream->drop_threshold_usec = 1000 * drop_b;
	stream->pframe_drop_threshold_usec = 1000 * drop_p;

	bind_ip = obs_data_get_string(settings, OPT_BIND_IP);
	dstr_copy(&stream->bind_ip, bind_ip);

	stream->new_socket_loop = obs_data_get_bool(settings,
			OPT_NEWSOCKETLOOP_ENABLED);
	stream->low_latency_mode = obs_data_get_bool(settings,
			OPT_LOWLATENCY_ENABLED);

	obs_data_release(settings);
	return true;
}
Beispiel #10
0
static void reset_packet_data(obs_output_t *output)
{
	output->received_audio   = false;
	output->received_video   = false;
	output->highest_audio_ts = 0;
	output->highest_video_ts = 0;
	output->video_offset     = 0;

	for (size_t i = 0; i < MAX_AUDIO_MIXES; i++)
		output->audio_offsets[0] = 0;

	free_packets(output);
}
Beispiel #11
0
static void rtmp_stream_destroy(void *data)
{
	struct rtmp_stream *stream = data;

	if (stopping(stream) && !connecting(stream)) {
		pthread_join(stream->send_thread, NULL);

	} else if (connecting(stream) || active(stream)) {
		if (stream->connecting)
			pthread_join(stream->connect_thread, NULL);

		stream->stop_ts = 0;
		os_event_signal(stream->stop_event);

		if (active(stream)) {
			os_sem_post(stream->send_sem);
			obs_output_end_data_capture(stream->output);
			pthread_join(stream->send_thread, NULL);
		}
	}

	free_packets(stream);
	dstr_free(&stream->path);
	dstr_free(&stream->key);
	dstr_free(&stream->username);
	dstr_free(&stream->password);
	dstr_free(&stream->encoder_name);
	dstr_free(&stream->bind_ip);
	os_event_destroy(stream->stop_event);
	os_sem_destroy(stream->send_sem);
	pthread_mutex_destroy(&stream->packets_mutex);
	circlebuf_free(&stream->packets);
#ifdef TEST_FRAMEDROPS
	circlebuf_free(&stream->droptest_info);
#endif

	os_event_destroy(stream->buffer_space_available_event);
	os_event_destroy(stream->buffer_has_data_event);
	os_event_destroy(stream->socket_available_event);
	os_event_destroy(stream->send_thread_signaled_exit);
	pthread_mutex_destroy(&stream->write_buf_mutex);

	if (stream->write_buf)
		bfree(stream->write_buf);
	bfree(stream);
}
Beispiel #12
0
void obs_output_destroy(obs_output_t *output)
{
	if (output) {
		obs_context_data_remove(&output->context);

		blog(LOG_INFO, "output '%s' destroyed", output->context.name);

		if (output->valid && active(output))
			obs_output_actual_stop(output, true, 0);

		os_event_wait(output->stopping_event);
		if (data_capture_ending(output))
			pthread_join(output->end_data_capture_thread, NULL);

		if (output->service)
			output->service->output = NULL;
		if (output->context.data)
			output->info.destroy(output->context.data);

		free_packets(output);

		if (output->video_encoder) {
			obs_encoder_remove_output(output->video_encoder,
					output);
		}

		for (size_t i = 0; i < MAX_AUDIO_MIXES; i++) {
			if (output->audio_encoders[i]) {
				obs_encoder_remove_output(
						output->audio_encoders[i],
						output);
			}
		}

		os_event_destroy(output->stopping_event);
		pthread_mutex_destroy(&output->interleaved_mutex);
		pthread_mutex_destroy(&output->delay_mutex);
		os_event_destroy(output->reconnect_stop_event);
		obs_context_data_free(&output->context);
		circlebuf_free(&output->delay_data);
		if (output->owns_info_id)
			bfree((void*)output->info.id);
		bfree(output);
	}
}
Beispiel #13
0
static void rtmp_stream_destroy(void *data)
{
	struct rtmp_stream *stream = data;

	if (stream->active)
		rtmp_stream_stop(data);

	if (stream) {
		free_packets(stream);
		dstr_free(&stream->path);
		dstr_free(&stream->key);
		dstr_free(&stream->username);
		dstr_free(&stream->password);
		os_event_destroy(stream->stop_event);
		os_sem_destroy(stream->send_sem);
		pthread_mutex_destroy(&stream->packets_mutex);
		circlebuf_free(&stream->packets);
		bfree(stream);
	}
}
Beispiel #14
0
size_t transmit(quicly_conn_t *src, quicly_conn_t *dst)
{
    quicly_raw_packet_t *packets[32];
    size_t num_packets, i;
    quicly_decoded_packet_t decoded[32];
    int ret;

    num_packets = sizeof(packets) / sizeof(packets[0]);
    ret = quicly_send(src, packets, &num_packets);
    ok(ret == 0);

    if (num_packets != 0) {
        decode_packets(decoded, packets, num_packets);
        for (i = 0; i != num_packets; ++i) {
            ret = quicly_receive(dst, decoded + i);
            ok(ret == 0);
        }
        free_packets(packets, num_packets);
    }

    return num_packets;
}
void whohas_flooding(struct Request* request){
  int packet_count = 0;
  struct packet* packets = make_packet(WHOHAS, NULL, NULL, -1, 0, 0, NULL, &packet_count, request);
  int i;
  for(i=0;i<packet_count;i++){
    print_packet(&packets[i]);
  }
  if(packet_count!=0){
    struct bt_peer_s* peer = config.peers;
    while(peer!=NULL) {
        if(peer->id==config.identity){
          peer = peer->next;
        }
        else{
          send_whohas_packet_to_all(packets, packet_count, sock, (struct sockaddr*)&peer->addr);
          peer = peer->next;
        }
    }
  }
  free_packets(packets, packet_count);
  return;
}
Beispiel #16
0
static void hook_data_capture(struct obs_output *output, bool encoded,
		bool has_video, bool has_audio)
{
	encoded_callback_t encoded_callback;

	if (encoded) {
		output->received_audio   = false;
		output->received_video   = false;
		output->highest_audio_ts = 0;
		output->highest_video_ts = 0;
		output->video_offset     = 0;

		for (size_t i = 0; i < MAX_AUDIO_MIXES; i++)
			output->audio_offsets[0] = 0;

		free_packets(output);

		encoded_callback = (has_video && has_audio) ?
			interleave_packets : default_encoded_callback;

		if (has_video)
			obs_encoder_start(output->video_encoder,
					encoded_callback, output);
		if (has_audio)
			start_audio_encoders(output, encoded_callback);
	} else {
		if (has_video)
			video_output_connect(output->video,
					get_video_conversion(output),
					default_raw_video_callback, output);
		if (has_audio)
			audio_output_connect(output->audio, output->mixer_idx,
					get_audio_conversion(output),
					default_raw_audio_callback, output);
	}
}
Beispiel #17
0
void obs_output_destroy(obs_output_t *output)
{
	if (output) {
		obs_context_data_remove(&output->context);

		blog(LOG_INFO, "output '%s' destroyed", output->context.name);

		if (output->valid && output->active)
			obs_output_stop(output);
		if (output->service)
			output->service->output = NULL;

		free_packets(output);

		if (output->context.data)
			output->info.destroy(output->context.data);

		if (output->video_encoder) {
			obs_encoder_remove_output(output->video_encoder,
					output);
		}

		for (size_t i = 0; i < MAX_AUDIO_MIXES; i++) {
			if (output->audio_encoders[i]) {
				obs_encoder_remove_output(
						output->audio_encoders[i],
						output);
			}
		}

		pthread_mutex_destroy(&output->interleaved_mutex);
		os_event_destroy(output->reconnect_stop_event);
		obs_context_data_free(&output->context);
		bfree(output);
	}
}
// Besides passing in type, also pass some necessary fields as parameters
// Other fields in the parameters can be arbitrary values
// To make a WHOHAS packet, pass in the request and *packet_count
// To make a IHAVE packet, pass in a WHOHAS packet as packet_in
// To make a Get packet, pass in p_chunk
// 
struct packet* make_packet(unsigned char packet_type, struct Chunk* p_chunk, char* data, int data_size, int seq_number, int ack_number, struct packet* packet_in, int* packet_count, struct Request* request){
  unsigned char i = 0;
  int j = 0;
  int unfinished_chunk_count = 0;
  struct packet* packet = NULL;
  switch(packet_type){
    case WHOHAS:
      for(i=0;i<request->chunk_number;i++){
        // TODO: here may need to change add more state to chunks
        if(request->chunks[i].state == NOT_STARTED){
          unfinished_chunk_count++;
        }
      }
      if(unfinished_chunk_count%CHUNK_PER_PACKET==0){
        *packet_count = unfinished_chunk_count/CHUNK_PER_PACKET;
      }
      else{
        *packet_count = unfinished_chunk_count/CHUNK_PER_PACKET + 1; 
      }
      struct packet* packets = (struct packet*)malloc(sizeof(struct packet)* (*packet_count));
      memset(packets, 0, sizeof(struct packet)* (*packet_count));
      if(unfinished_chunk_count==0){
        free_packets(packets, *packet_count);
        packets = NULL;
      }
      int current_chunk_index = 0;
      for(j=0;j<(*packet_count);j++){
        unsigned char chunk_count = CHUNK_PER_PACKET;
        if(*packet_count <= j+1){
          chunk_count = (unsigned char)(unfinished_chunk_count - j*CHUNK_PER_PACKET);
        }
        fill_header(&packets[j].header, WHOHAS, chunk_count*SHA1_HASH_SIZE+HEADER_LENGTH+CHUNK_NUMBER_AND_PADDING_SIZE, 0, 0);
        *(packets[j].payload) = chunk_count;
        int k=0;
        for(k=0;k<chunk_count;k++){
          for(; current_chunk_index<request->chunk_number;current_chunk_index++){
            if(request->chunks[current_chunk_index].state==NOT_STARTED){
              memcpy(packets[j].payload+CHUNK_NUMBER_AND_PADDING_SIZE+k*SHA1_HASH_SIZE,(request->chunks)[current_chunk_index].hash, SHA1_HASH_SIZE);
              current_chunk_index++;
              break;
            } 
          }
        }
      }
      return packets;
    case IHAVE:
      packet = (struct packet*)malloc(sizeof(struct packet));
      memset(packet, 0, sizeof(struct packet));
      unsigned char chunk_count = *((char*)packet_in+16);
      unsigned char count_ihave = 0;

      for(i=0;i<chunk_count;i++){
        uint8_t* hash = (uint8_t*)((char*)packet_in+16+CHUNK_NUMBER_AND_PADDING_SIZE+i*SHA1_HASH_SIZE);
        if(find_chunk(hash)>0){
          memcpy(packet->payload+CHUNK_NUMBER_AND_PADDING_SIZE+count_ihave*SHA1_HASH_SIZE, hash, SHA1_HASH_SIZE);
          count_ihave++;
        }
      }
      if(count_ihave==0){
        free_packet(packet);
        packet = NULL;
      }
      else{
        fill_header(&(packet->header), IHAVE, count_ihave*SHA1_HASH_SIZE+HEADER_LENGTH+CHUNK_NUMBER_AND_PADDING_SIZE, 0, 0);
        // *(packet->payload) = count_ihave;
        memcpy(packet->payload, &count_ihave, 1);
      }
      break;
    case GET:
      packet = (struct packet*)malloc(sizeof(struct packet));
      memset(packet, 0, sizeof(struct packet));
      fill_header(&packet->header, GET, SHA1_HASH_SIZE+HEADER_LENGTH, 0, 0);
      memcpy(packet->payload, p_chunk->hash, SHA1_HASH_SIZE);
      break;
    case DATA:
      packet = (struct packet*)malloc(sizeof(struct packet));
      memset(packet, 0, sizeof(struct packet));
      fill_header(&packet->header, DATA, data_size+HEADER_LENGTH, seq_number, 0);
      memcpy(packet->payload, data, data_size);
      break;
    case ACK:
      packet = (struct packet*)malloc(sizeof(struct packet));
      memset(packet, 0, sizeof(struct packet));
      fill_header(&packet->header, ACK, HEADER_LENGTH, 0, ack_number);
      break;
    default:
      printf("Should not happen in make_packet\n");
      break;
  }
  return packet;
}