diff options
Diffstat (limited to 'server/mov_encoder_thread.cc')
-rw-r--r-- | server/mov_encoder_thread.cc | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/server/mov_encoder_thread.cc b/server/mov_encoder_thread.cc new file mode 100644 index 0000000..2ff013d --- /dev/null +++ b/server/mov_encoder_thread.cc @@ -0,0 +1,158 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + * mov_encoder_thread.cc + * + * Tue May 17 16:00:01 CEST 2005 + * Copyright 2005 Bent Bisballe + * deva@aasimon.org + ****************************************************************************/ + +/* + * This file is part of MIaV. + * + * MIaV is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * MIaV is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MIaV; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#include <config.h> +#include "mov_encoder_thread.h" +#include <errno.h> +#include "miav_config.h" + +MovEncoderThread::MovEncoderThread(const char *clientip, const char *cpr, Info *i) +{ + info = i; + info->info("MovEncoderThread"); + + // Queue + inputqueue = new ThreadSafeQueueFIFO(); + + // Initialize read semaphore + sem_init(&read_sem, 0, 0); + + video_output_queue = new ThreadSafeQueuePriority(info); + audio_input_queue = new ThreadSafeQueuePriority(info); + audio_output_queue = new ThreadSafeQueuePriority(info); + + info->info("video_output_queue: 0x%x", video_output_queue); + info->info("audio_input_queue: 0x%x", audio_input_queue); + info->info("audio_output_queue: 0x%x", audio_output_queue); + + block = new FrameVector(); + + num_frames_in_block = config->readString("frame_sequence")->length(); + + info->info("Frame sequence length %d", num_frames_in_block); + + threads = config->readInt("encoding_threads"); + + movencodersrunning = true; + + for(int cnt = 0; cnt < threads; cnt++) sem_post(&read_sem); + + // Create the video encoders + for(int cnt = 0; cnt < threads; cnt++) { + MovEncoder *movenc = new MovEncoder(&movencodersrunning, &read_sem, + inputqueue, + video_output_queue, + audio_input_queue, + info); + movenc->run(); + encs.push_back(movenc); + } + + // Create the audio encoder + audioenc = new AudioEncoder(audio_input_queue, + audio_output_queue, + info); + audioenc->run(); + + // Create the multiplexer + writer = new MovEncoderWriter(clientip, cpr, + video_output_queue, + audio_output_queue, + info); + writer->run(); + + frame_number = 0; +} + +//#include <unistd.h> +MovEncoderThread::~MovEncoderThread() +{ + info->info("~MovEncoderThread"); + + // First we destroy the movie encoders + for(int cnt = 0; cnt < threads; cnt++) { + encs[cnt]->wait_stop(); // Wait for it to stop + delete encs[cnt]; // Delete it + } + info->info("Deleted the movie encoders"); + + + // Then we destroy the audio encoder + audioenc->wait_stop(); // Wait for it to stop. + delete audioenc; // delete the audio encoder + info->info("Deleted the audio encoder"); + + + // Finally we destroy the writer. + writer->wait_stop(); // Wait for it to stop. + delete writer; // delete the writer (end thereby close the file) + info->info("Deleted the writer"); + + + // Destroy the semaphore. + sem_destroy(&read_sem); + + info->info("~MovEncoderThread::done"); +} + +static int output = 0; +void MovEncoderThread::encode(Frame* frame) +{ + if(output % 250 == 0) // 25 * 24 + info->info("inputqueue: %d\tvideo_outputqueue: %d\taudio_inputqueue: %d\taudio_outputqueue: %d.", + inputqueue->size(), + video_output_queue->size(), + audio_input_queue->size(), + audio_output_queue->size()); + output++; + + if(frame == NULL) { + info->info("MovEncoderThread::encode - NULL frame detected."); + // Terminate + return; + } + + frame->number = frame_number; + block->push_back(frame); + + // Switch frame + if(block->size() == num_frames_in_block || frame->endOfFrameStream == true) { + // Wait until a free encoder. + sem_wait(&read_sem); + + inputqueue->push(block); + + // Start new block + block = new FrameVector; + } + + frame_number ++; +} + +void MovEncoderThread::setSaveState(n_savestate savestate) +{ + writer->setSaveState(savestate); +} |