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; }
vod_status_t full_frame_processor_process(full_frame_processor_t* state) { u_char* read_buffer; uint32_t read_size; uint32_t cur_copy_size; uint64_t offset; bool_t processed_data = FALSE; vod_status_t rc; for (;;) { // check if we're done if (state->cur_frame >= state->last_frame) { rc = state->frame_callback(state->frame_context, NULL, NULL); if (rc != VOD_OK) { return rc; } return VOD_OK; } // 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->cur_frame->size - state->cur_frame_pos, 0, state->frames_file_index, offset, &read_buffer, &read_size)) { if (!processed_data && !state->first_time) { vod_log_error(VOD_LOG_ERR, state->request_context->log, 0, "full_frame_processor_process: no data was handled, probably a truncated file"); return VOD_BAD_DATA; } state->first_time = FALSE; return VOD_AGAIN; } processed_data = TRUE; if (state->cur_frame_pos == 0 && read_size >= state->cur_frame->size) { // have the whole frame in one piece rc = state->frame_callback(state->frame_context, state->cur_frame, read_buffer); if (rc != VOD_OK) { return rc; } // move to the next frame state->cur_frame++; state->cur_frame_offset++; continue; } // copy as much as possible from the frame cur_copy_size = MIN(state->cur_frame->size - state->cur_frame_pos, read_size); vod_memcpy(state->frame_buffer + state->cur_frame_pos, read_buffer, cur_copy_size); state->cur_frame_pos += cur_copy_size; // move to the next frame if done if (state->cur_frame_pos >= state->cur_frame->size) { rc = state->frame_callback(state->frame_context, state->cur_frame, state->frame_buffer); if (rc != VOD_OK) { return rc; } state->cur_frame++; state->cur_frame_offset++; state->cur_frame_pos = 0; } } }
vod_status_t audio_filter_process(void* context) { audio_filter_state_t* state = context; audio_filter_source_t* source; u_char* read_buffer; uint32_t read_size; uint64_t offset; bool_t processed_data = FALSE; vod_status_t rc; for (;;) { // choose a source if needed if (state->cur_source == NULL) { rc = audio_filter_choose_source(state, &source); if (rc != VOD_OK) { return rc; } if (source == NULL) { // done return audio_filter_flush_encoder(state); } state->cur_source = source; } else { source = state->cur_source; } // read some data from the frame offset = *source->cur_frame_offset + state->cur_frame_pos; if (!read_cache_get_from_cache( state->read_cache_state, source->cur_frame->size - state->cur_frame_pos, source->cache_slot_id, source->frames_source, offset, &read_buffer, &read_size)) { if (!processed_data && !state->first_time) { vod_log_error(VOD_LOG_ERR, state->request_context->log, 0, "audio_filter_process: no data was handled, probably a truncated file"); return VOD_BAD_DATA; } state->first_time = FALSE; return VOD_AGAIN; } processed_data = TRUE; if (state->cur_frame_pos == 0 && read_size >= source->cur_frame->size) { // have the whole frame in one piece rc = audio_filter_process_frame(state, read_buffer); if (rc != VOD_OK) { return rc; } // move to the next frame source->cur_frame++; source->cur_frame_offset++; state->cur_source = NULL; continue; } if (read_size < source->cur_frame->size - state->cur_frame_pos) { // didn't finish the frame, append to the frame buffer vod_memcpy(state->frame_buffer + state->cur_frame_pos, read_buffer, read_size); state->cur_frame_pos += read_size; continue; } // finished the frame vod_memcpy(state->frame_buffer + state->cur_frame_pos, read_buffer, source->cur_frame->size - state->cur_frame_pos); rc = audio_filter_process_frame(state, state->frame_buffer); if (rc != VOD_OK) { return rc; } source->cur_frame++; source->cur_frame_offset++; state->cur_frame_pos = 0; state->cur_source = NULL; } }