/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /*************************************************************************** * mov_encoder.cc * * Sat Feb 19 14:13:19 CET 2005 * Copyright 2005 Bent Bisballe * deva@aasimon.org ****************************************************************************/ /* * Originally from: * RTVideoRec Realtime video recoder and encoder for Linux * * Copyright (C) 2004 B. Stultiens * Copyright (C) 2004 Koen Otter and Glenn van der Meyden */ /* * 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 "mov_encoder.h" #include // For nice #include #include "configuration.h" #include "info.h" #include "libfame_wrapper.h" MovEncoder::MovEncoder(volatile bool *r, sem_t *r_sem, ThreadSafeQueueFIFO *in, ThreadSafeQueuePriority *video_out, ThreadSafeQueuePriority *audio_out) { MIaV::info->info("MovEncoder"); running = r; // Queues inputqueue = in; video_output_queue = video_out; audio_output_queue = audio_out; read_sem = r_sem; } MovEncoder::~MovEncoder() { MIaV::info->info("~MovEncoder"); } // this runs in a thread void MovEncoder::thread_main() { MIaV::info->info("MovEncoder::run"); // Run with slightly lower priority than MovEncoderWriter AND AudioEncoder nice(2); FrameVector *item; Frame *in_frame; Frame *out_v_frame; Frame *out_a_frame; LibFAMEWrapper fame; // Process until running == false and the queue is empty while(*running) { item = inputqueue->pop(); if(item) { for(unsigned int cnt = 0; cnt < item->size(); cnt++) { in_frame = item->at(cnt); // Check for end of stream if(in_frame->endOfFrameStream == true) { MIaV::info->info("endOfFrameStream in MovEncoder"); // Signal to stop running *running = false; // Kick them sleepy ones so they get the message. int threads; if(MIaV::config->get("encoding_threads", &threads)) MIaV::info->error("Could not read the symbol [encoding_threads] from the conf file!"); threads -= 1; // -1 cause we only need the others! for(int cnt = 0; cnt < threads; cnt++) { inputqueue->push(NULL); } } // Encode video out_v_frame = fame.encode(in_frame); out_v_frame->number = in_frame->number; out_v_frame->endOfFrameStream = in_frame->endOfFrameStream; // Create audio frame out_a_frame = in_frame; video_output_queue->push(out_v_frame); audio_output_queue->push(out_a_frame); } delete item; item = NULL; // Kick reader sem_post(read_sem); } } MIaV::info->info("MovEncoder::stop"); } /* // this runs in a thread void MovEncoder::thread_main() { info->info("MovEncoder::run"); // static volatile int test = 0; #ifndef NEW_QUEUE int v_outsize = 0; int a_outsize = 0; #endif int insize = 0; // Run with slightly lower priority than MovEncoderWriter AND AudioEncoder nice(3); FrameVector *item; Frame *in_frame; Frame *out_v_frame; Frame *out_a_frame; LibFAMEWrapper fame(info); // Process until running == false and the queue is empty while(*running) { sem_wait(input_sem); // Lock inout mutex pthread_mutex_lock(input_mutex); item = inputqueue->front(); inputqueue->pop(); insize = inputqueue->size(); pthread_mutex_unlock(input_mutex); // Unlock input mutex if(item) { for(unsigned int cnt = 0; cnt < item->size(); cnt++) { in_frame = item->at(cnt); // Check for end of stream if(in_frame->endOfFrameStream == true) { info->info("endOfFrameStream in MovEncoder"); // Signal to stop running *running = false; // Kick them sleepy ones so they get the message. int threads = MIaV::config->readInt("encoding_threads"); for(int cnt = 0; cnt < threads; cnt++) sem_post(input_sem); } // Encode video out_v_frame = fame.encode(in_frame); out_v_frame->number = in_frame->number; out_v_frame->endOfFrameStream = in_frame->endOfFrameStream; // Create audio frame out_a_frame = in_frame; #ifdef NEW_QUEUE video_output_queue->push(out_v_frame); audio_output_queue->push(out_a_frame); #else // Lock output mutex pthread_mutex_lock(video_output_mutex); video_outputqueue->push(out_v_frame); v_outsize = video_outputqueue->size(); pthread_mutex_unlock(video_output_mutex); // Unlock output mutex // Kick multiplexer (video) sem_post(video_output_sem); // Lock output mutex pthread_mutex_lock(audio_output_mutex); audio_outputqueue->push(out_a_frame); a_outsize = audio_outputqueue->size(); pthread_mutex_unlock(audio_output_mutex); // Unlock output mutex // Kick audio encoder sem_post(audio_output_sem); #endif } delete item; item = NULL; // Kick reader sem_post(read_sem); } } //info->info("Input pool size: %d, video output pool size: %d, audio output pool size: %d", // insize, v_outsize, a_outsize); #ifndef NEW_QUEUE // Kick audio encoder sem_post(audio_output_sem); // Kick multiplexer (video) sem_post(video_output_sem); #endif info->info("MovEncoder::stop"); } */