예제 #1
0
vod_status_t
write_buffer_write(
	write_buffer_state_t* state,
	const u_char* buffer,
	size_t size)
{
	vod_status_t rc;
	size_t cur_copy_size;

	for (;;)
	{
		cur_copy_size = state->end_pos - state->cur_pos;
		if (cur_copy_size > size)
		{
			cur_copy_size = size;
		}
		state->cur_pos = vod_copy(state->cur_pos, buffer, cur_copy_size);
		size -= cur_copy_size;
		if (size <= 0)
		{
			break;
		}
		buffer += cur_copy_size;

		rc = write_buffer_flush(state, TRUE);
		if (rc != VOD_OK)
		{
			return rc;
		}
	}

	return VOD_OK;
}
예제 #2
0
파일: rawlog.c 프로젝트: Liaf/irssi
void rawlog_close(RAWLOG_REC *rawlog)
{
	if (rawlog->logging) {
		write_buffer_flush();
		close(rawlog->handle);
		rawlog->logging = 0;
	}
}
예제 #3
0
static vod_status_t
mp4_encrypt_audio_write_buffer(void* context, u_char* buffer, uint32_t size)
{
	mp4_encrypt_state_t* state = (mp4_encrypt_state_t*)context;
	u_char* buffer_end = buffer + size;
	u_char* cur_pos = buffer;
	uint32_t write_size;
	bool_t ignore;
	vod_status_t rc;

	while (cur_pos < buffer_end)
	{
		if (state->frame_size_left <= 0)
		{
			rc = mp4_encrypt_start_frame(state);
			if (rc != VOD_OK)
			{
				return rc;
			}
		}

		write_size = (uint32_t)(buffer_end - cur_pos);
		write_size = vod_min(write_size, state->frame_size_left);
		
		rc = mp4_encrypt_write_encrypted(state, cur_pos, write_size);
		if (rc != VOD_OK)
		{
			return rc;
		}

		cur_pos += write_size;
		state->frame_size_left -= write_size;

		if (state->frame_size_left > 0)
		{
			break;
		}

		// finished a frame
		if (!mp4_encrypt_move_to_next_frame(state, &ignore))
		{
			// finished all frames
			rc = write_buffer_flush(&state->write_buffer, FALSE);
			if (rc != VOD_OK)
			{
				return rc;
			}
		}
	}

	return VOD_OK;
}
예제 #4
0
파일: rawlog.c 프로젝트: Liaf/irssi
void rawlog_destroy(RAWLOG_REC *rawlog)
{
	g_return_if_fail(rawlog != NULL);

	g_slist_foreach(rawlog->lines, (GFunc) g_free, NULL);
	g_slist_free(rawlog->lines);

	if (rawlog->logging) {
		write_buffer_flush();
		close(rawlog->handle);
	}
	g_free(rawlog);
}
예제 #5
0
파일: log.c 프로젝트: FabrizioFabbe/silc
void log_stop_logging(LOG_REC *log)
{
	g_return_if_fail(log != NULL);

	if (log->handle == -1)
		return;

	signal_emit("log stopped", 1, log);

	log_write_timestamp(log->handle,
			    settings_get_str("log_close_string"),
			    "\n", time(NULL));

#ifdef HAVE_FCNTL
        memset(&lock, 0, sizeof(lock));
	lock.l_type = F_UNLCK;
	fcntl(log->handle, F_SETLK, &lock);
#endif

	write_buffer_flush();
	close(log->handle);
	log->handle = -1;
}
예제 #6
0
vod_status_t
write_buffer_get_bytes(
	write_buffer_state_t* state,
	size_t min_size,
	size_t* size,
	u_char** buffer)
{
	vod_status_t rc;

	if (min_size > WRITE_BUFFER_SIZE)
	{
		vod_log_error(VOD_LOG_ERR, state->request_context->log, 0,
			"write_buffer_get_bytes: invalid size request %uz", min_size);
		return VOD_UNEXPECTED;
	}

	if (state->cur_pos + min_size > state->end_pos)
	{
		rc = write_buffer_flush(state, TRUE);
		if (rc != VOD_OK)
		{
			return rc;
		}
	}

	*buffer = state->cur_pos;
	if (size != NULL)
	{
		// Note: in this mode, the caller is responsible for incrementing cur_pos
		*size = state->end_pos - state->cur_pos;
	}
	else
	{
		state->cur_pos += min_size;
	}
	return VOD_OK;
}
예제 #7
0
vod_status_t
hds_muxer_process_frames(hds_muxer_state_t* state)
{
	u_char* read_buffer;
	uint32_t read_size;
	vod_status_t rc;
	bool_t wrote_data = FALSE;
	bool_t frame_done;

	for (;;)
	{
		// read some data from the frame
		rc = state->frames_source->read(state->frames_source_context, &read_buffer, &read_size, &frame_done);
		if (rc != VOD_OK)
		{
			if (rc != VOD_AGAIN)
			{
				return rc;
			}

			if (!wrote_data && !state->first_time)
			{
				vod_log_error(VOD_LOG_ERR, state->request_context->log, 0,
					"hds_muxer_process_frames: no data was handled, probably a truncated file");
				return VOD_BAD_DATA;
			}

			state->first_time = FALSE;

			return VOD_AGAIN;
		}

		wrote_data = TRUE;

		// write the frame
		rc = write_buffer_write(&state->write_buffer_state, read_buffer, read_size);
		if (rc != VOD_OK)
		{
			vod_log_debug1(VOD_LOG_DEBUG_LEVEL, state->request_context->log, 0,
				"hds_muxer_process_frames: write_buffer_write failed %i", rc);
			return rc;
		}

		// if not done, ask the cache for more data
		if (!frame_done)
		{
			continue;
		}

		// end the frame and start a new one
		rc = hds_muxer_end_frame(state);
		if (rc != VOD_OK)
		{
			vod_log_debug1(VOD_LOG_DEBUG_LEVEL, state->request_context->log, 0,
				"hds_muxer_process_frames: write_buffer_write failed %i", rc);
			return rc;
		}

		rc = hds_muxer_start_frame(state);
		if (rc != VOD_OK)
		{
			if (rc == VOD_NOT_FOUND)
			{
				break;		// done
			}

			vod_log_debug1(VOD_LOG_DEBUG_LEVEL, state->request_context->log, 0,
				"hds_muxer_process_frames: hds_muxer_start_frame failed %i", rc);
			return rc;
		}
	}

	// flush the buffer
	rc = write_buffer_flush(&state->write_buffer_state, FALSE);
	if (rc != VOD_OK)
	{
		vod_log_debug1(VOD_LOG_DEBUG_LEVEL, state->request_context->log, 0,
			"hds_muxer_process_frames: write_buffer_flush failed %i", rc);
		return rc;
	}
	return VOD_OK;
}
예제 #8
0
vod_status_t
hds_muxer_process_frames(hds_muxer_state_t* state, uint64_t* required_offset)
{
	u_char* read_buffer;
	uint32_t read_size;
	uint32_t write_size;
	uint64_t offset;
	vod_status_t rc;
	bool_t first_time = (state->cur_frame == NULL);
	bool_t wrote_data = FALSE;

	for (;;)
	{
		// start a new frame if we don't have a frame
		if (state->cur_frame == NULL)
		{
			rc = hds_muxer_start_frame(state);
			if (rc != VOD_OK)
			{
				vod_log_debug1(VOD_LOG_DEBUG_LEVEL, state->request_context->log, 0,
					"hds_muxer_process_frames: hds_muxer_start_frame failed %i", rc);
				return rc;
			}

			if (state->cur_frame == NULL)
			{
				break;		// done
			}
		}

		// read some data from the frame
		offset = state->cur_frame_offset + state->cur_frame_pos;
		if (!read_cache_get_from_cache(state->read_cache_state, state->cache_slot_id, offset, &read_buffer, &read_size))
		{
			if (!wrote_data && !first_time)
			{
				vod_log_error(VOD_LOG_ERR, state->request_context->log, 0,
					"hds_muxer_process_frames: no data was handled, probably a truncated file");
				return VOD_BAD_DATA;
			}
			*required_offset = offset;
			return VOD_AGAIN;
		}

		wrote_data = TRUE;

		// write the frame
		write_size = MIN(state->cur_frame->size - state->cur_frame_pos, read_size);
		rc = write_buffer_write(&state->write_buffer_state, read_buffer, write_size);
		if (rc != VOD_OK)
		{
			vod_log_debug1(VOD_LOG_DEBUG_LEVEL, state->request_context->log, 0,
				"hds_muxer_process_frames: write_buffer_write failed %i", rc);
			return rc;
		}
		state->cur_frame_pos += write_size;

		// flush the frame if we finished writing it
		if (state->cur_frame_pos >= state->cur_frame->size)
		{
			rc = hds_muxer_end_frame(state);
			if (rc != VOD_OK)
			{
				vod_log_debug1(VOD_LOG_DEBUG_LEVEL, state->request_context->log, 0,
					"hds_muxer_process_frames: write_buffer_write failed %i", rc);
				return rc;
			}

			state->cur_frame = NULL;
		}
	}

	// flush the buffer
	rc = write_buffer_flush(&state->write_buffer_state, FALSE);
	if (rc != VOD_OK)
	{
		vod_log_debug1(VOD_LOG_DEBUG_LEVEL, state->request_context->log, 0,
			"hds_muxer_process_frames: write_buffer_flush failed %i", rc);
		return rc;
	}
	return VOD_OK;
}
예제 #9
0
static vod_status_t
mp4_encrypt_video_write_buffer(void* context, u_char* buffer, uint32_t size)
{
	mp4_encrypt_video_state_t* state = (mp4_encrypt_video_state_t*)context;
	vod_str_t fragment_header;
	u_char* buffer_end = buffer + size;
	u_char* cur_pos = buffer;
	u_char* output;
	uint32_t write_size;
	int32_t cur_shift;
	size_t ignore;
	bool_t init_track;
	vod_status_t rc;

	while (cur_pos < buffer_end)
	{
		switch (state->cur_state)
		{
		case STATE_PACKET_SIZE:
			if (state->base.frame_size_left <= 0)
			{
				rc = mp4_encrypt_video_start_frame(state);
				if (rc != VOD_OK)
				{
					return rc;
				}

				if (state->base.frame_size_left <= 0)
				{
					state->cur_state = STATE_PACKET_DATA;
					break;
				}
			}

			for (; state->length_bytes_left && cur_pos < buffer_end; state->length_bytes_left--)
			{
				state->packet_size_left = (state->packet_size_left << 8) | *cur_pos++;
			}

			if (cur_pos >= buffer_end)
			{
				break;
			}

			if (state->base.frame_size_left < state->nal_packet_size_length + state->packet_size_left)
			{
				vod_log_error(VOD_LOG_ERR, state->base.request_context->log, 0,
					"mp4_encrypt_video_write_buffer: frame size %uD too small, nalu size %uD packet size %uD",
					state->base.frame_size_left, state->nal_packet_size_length, state->packet_size_left);
				return VOD_BAD_DATA;
			}

			state->base.frame_size_left -= state->nal_packet_size_length + state->packet_size_left;

			state->cur_state++;
			// fall through

		case STATE_NAL_TYPE:

			// write the packet size and nal type
			rc = write_buffer_get_bytes(&state->base.write_buffer, state->nal_packet_size_length + 1, NULL, &output);
			if (rc != VOD_OK)
			{
				return rc;
			}

			for (cur_shift = (state->nal_packet_size_length - 1) * 8; cur_shift >= 0; cur_shift -= 8)
			{
				*output++ = (state->packet_size_left >> cur_shift) & 0xff;
			}

			*output++ = *cur_pos++;		// nal type

			// update the packet size
			if (state->packet_size_left <= 0)
			{
				vod_log_error(VOD_LOG_ERR, state->base.request_context->log, 0,
					"mp4_encrypt_video_write_buffer: zero size packet");
				return VOD_BAD_DATA;
			}
			state->packet_size_left--;

			// add the subsample
			rc = mp4_encrypt_video_add_subsample(state, state->nal_packet_size_length + 1, state->packet_size_left);
			if (rc != VOD_OK)
			{
				return rc;
			}

			state->cur_state++;
			// fall through

		case STATE_PACKET_DATA:
			write_size = (uint32_t)(buffer_end - cur_pos);
			write_size = vod_min(write_size, state->packet_size_left);
			
			rc = mp4_encrypt_write_encrypted(&state->base, cur_pos, write_size);
			if (rc != VOD_OK)
			{
				return rc;
			}

			cur_pos += write_size;
			state->packet_size_left -= write_size;
			if (state->packet_size_left > 0)
			{
				break;
			}

			// finished a packet
			state->cur_state = STATE_PACKET_SIZE;
			state->length_bytes_left = state->nal_packet_size_length;
			state->packet_size_left = 0;

			if (state->base.frame_size_left > 0)
			{
				break;
			}

			// finished a frame
			rc = mp4_encrypt_video_end_frame(state);
			if (rc != VOD_OK)
			{
				return rc;
			}

			// move to the next frame
			if (mp4_encrypt_move_to_next_frame(&state->base, &init_track))
			{
				if (init_track)
				{
					rc = mp4_encrypt_video_init_track(state, state->base.cur_clip->first_track);
					if (rc != VOD_OK)
					{
						return rc;
					}
				}

				break;
			}

			// finished all frames
			rc = write_buffer_flush(&state->base.write_buffer, FALSE);
			if (rc != VOD_OK)
			{
				return rc;
			}

			mp4_encrypt_video_prepare_saiz_saio(state);

			rc = state->build_fragment_header(state, &fragment_header, &ignore);
			if (rc != VOD_OK)
			{
				return rc;
			}

			rc = state->base.segment_writer.write_head(
				state->base.segment_writer.context,
				fragment_header.data,
				fragment_header.len);
			if (rc != VOD_OK)
			{
				vod_log_debug1(VOD_LOG_DEBUG_LEVEL, state->base.request_context->log, 0,
					"mp4_encrypt_video_write_buffer: write_head failed %i", rc);
				return rc;
			}

			break;
		}
	}

	return VOD_OK;
}
예제 #10
0
static vod_status_t
mp4_encrypt_video_snpf_write_buffer(void* context, u_char* buffer, uint32_t size)
{
	mp4_encrypt_video_state_t* state = (mp4_encrypt_video_state_t*)context;
	u_char* buffer_end = buffer + size;
	u_char* cur_pos = buffer;
	u_char* cur_end_pos;
	u_char* output;
	uint32_t write_size;
	bool_t init_track;
	vod_status_t rc;

	while (cur_pos < buffer_end)
	{
		switch (state->cur_state)
		{
		case STATE_CLEAR_BYTES:
			// start a new frame if needed
			if (state->base.frame_size_left <= 0)
			{
				rc = mp4_encrypt_start_frame(&state->base);
				if (rc != VOD_OK)
				{
					return rc;
				}

				if (state->base.frame_size_left <= 0)
				{
					state->cur_state = STATE_ENCRYPTED_BYTES;
					break;
				}
			}

			// copy the clear bytes
			write_size = (uint32_t)(buffer_end - cur_pos);
			write_size = vod_min(write_size, state->length_bytes_left + 1);

			rc = write_buffer_get_bytes(&state->base.write_buffer, write_size, NULL, &output);
			if (rc != VOD_OK)
			{
				return rc;
			}

			// copy the nalu length
			if (write_size >= state->length_bytes_left)
			{
				cur_end_pos = cur_pos + state->length_bytes_left;
				state->length_bytes_left = 0;
			}
			else
			{
				cur_end_pos = cur_pos + write_size;
				state->length_bytes_left -= write_size;
			}

			while (cur_pos < cur_end_pos)
			{
				state->packet_size_left = (state->packet_size_left << 8) | *cur_pos;
				*output++ = *cur_pos++;
			}

			if (cur_pos >= buffer_end)
			{
				break;
			}

			// copy the nalu type
			*output++ = *cur_pos++;

			if (state->base.frame_size_left < state->nal_packet_size_length + 1)
			{
				vod_log_error(VOD_LOG_ERR, state->base.request_context->log, 0,
					"mp4_encrypt_video_snpf_write_buffer: frame size %uD too small, nalu size %uD",
					state->base.frame_size_left, state->nal_packet_size_length);
				return VOD_BAD_DATA;
			}

			state->base.frame_size_left -= state->nal_packet_size_length;

			if (state->packet_size_left != state->base.frame_size_left && 
				!state->single_nalu_warning_printed)
			{
				vod_log_error(VOD_LOG_WARN, state->base.request_context->log, 0,
					"mp4_encrypt_video_snpf_write_buffer: frame does not contain a single nalu, "
					"consider changing vod_min_single_nalu_per_frame_segment, "
					"packet size=%uD, frame size=%uD",
					state->packet_size_left, state->base.frame_size_left);
				state->single_nalu_warning_printed = TRUE;
			}

			state->base.frame_size_left--;

			state->cur_state++;
			// fall through

		case STATE_ENCRYPTED_BYTES:
			write_size = (uint32_t)(buffer_end - cur_pos);
			write_size = vod_min(write_size, state->base.frame_size_left);

			rc = mp4_encrypt_write_encrypted(&state->base, cur_pos, write_size);
			if (rc != VOD_OK)
			{
				return rc;
			}

			cur_pos += write_size;

			state->base.frame_size_left -= write_size;
			if (state->base.frame_size_left > 0)
			{
				break;
			}

			// finished a packet
			state->cur_state = STATE_CLEAR_BYTES;
			state->length_bytes_left = state->nal_packet_size_length;
			state->packet_size_left = 0;

			// move to the next frame
			if (mp4_encrypt_move_to_next_frame(&state->base, &init_track))
			{
				if (init_track)
				{
					rc = mp4_encrypt_video_init_track(state, state->base.cur_clip->first_track);
					if (rc != VOD_OK)
					{
						return rc;
					}
				}

				break;
			}

			// finished all frames
			rc = write_buffer_flush(&state->base.write_buffer, FALSE);
			if (rc != VOD_OK)
			{
				return rc;
			}

			break;
		}
	}

	return VOD_OK;
}