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; }
void rawlog_close(RAWLOG_REC *rawlog) { if (rawlog->logging) { write_buffer_flush(); close(rawlog->handle); rawlog->logging = 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; }
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); }
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; }
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; }
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; }
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; }
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; }
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; }