From 8e52138ba8a6fe9b92192512ba510451a2655384 Mon Sep 17 00:00:00 2001 From: deva Date: Sun, 18 Sep 2005 14:34:10 +0000 Subject: *** empty log message *** --- etc/miav.conf | 9 ++++--- src/frame.cc | 4 +-- src/frame.h | 3 ++- src/mov_encoder.cc | 16 ++++++------ src/mov_encoder_thread.cc | 9 ++----- src/multiplexer.cc | 62 ++++++++++++++++++++++++----------------------- src/multiplexer.h | 1 + src/player.cc | 4 +-- src/server.cc | 15 +++--------- src/util.cc | 14 +++++++++++ src/util.h | 2 ++ 11 files changed, 74 insertions(+), 65 deletions(-) diff --git a/etc/miav.conf b/etc/miav.conf index bbbb9f6..50d36b7 100644 --- a/etc/miav.conf +++ b/etc/miav.conf @@ -39,10 +39,13 @@ server_image_root = "/home/miav/miav_image_files" # which is fast to create, but uses a lot of discspace. # B uses changes since last frame, is more cpu intensive, but uses a # lot less diskspace than I frames -frame_sequence = "IPPPP" +frame_sequence = "IPPPIPPIP" # quality in % - 100% is best quality -frame_quality = 85 +video_quality = 85 + +# bitrate in kbytes pr. second (0 == vbr) +video_bitrate = 0 # mp3 encoding quality settings mp3_quality = 3 @@ -56,4 +59,4 @@ encoding_threads = 1 # "mpeg1" For use with mpeg1 encoding. # "mpeg4" for use with mpeg4 encoding # default is "mpeg1" -encoding_codec = "mpeg4" +encoding_codec = "mpeg1" diff --git a/src/frame.cc b/src/frame.cc index b216164..a274d89 100644 --- a/src/frame.cc +++ b/src/frame.cc @@ -32,8 +32,6 @@ #include #include -Frame *endOfFrameStream = NULL;// = (Frame*)0xffffffff; - Frame::Frame(unsigned char *d, int sz) { if(sz) data = new unsigned char[sz]; @@ -41,6 +39,8 @@ Frame::Frame(unsigned char *d, int sz) size = sz; number = 0; memset(timecode, 0, sizeof(timecode)); + + endOfFrameStream = false; } Frame::~Frame() diff --git a/src/frame.h b/src/frame.h index 17de4fa..2b8d9f5 100644 --- a/src/frame.h +++ b/src/frame.h @@ -50,6 +50,8 @@ public: int freeze; // 1 is freeze, -1 is unfreeze bool record; char timecode[12]; + + bool endOfFrameStream; }; #include @@ -69,6 +71,5 @@ typedef std::priority_queue< Frame*, std::vector, frame_priority > FramePriorityQueue; -extern Frame *endOfFrameStream; #endif/*__FRAME_H__*/ diff --git a/src/mov_encoder.cc b/src/mov_encoder.cc index 9212e5a..09e6fa3 100644 --- a/src/mov_encoder.cc +++ b/src/mov_encoder.cc @@ -97,7 +97,7 @@ void MovEncoder::thread_main() LibFAMEWrapper fame(info); // Process until running == false and the queue is empty - while(*running || ((*running == false) && (insize > 0))) { + while(*running) { sem_wait(input_sem); // Lock inout mutex @@ -113,18 +113,16 @@ void MovEncoder::thread_main() in_frame = item->at(cnt); // Check for end of stream - if(in_frame == endOfFrameStream) { + if(in_frame->endOfFrameStream == true) { info->info("endOfFrameStream in MovEncoder"); - - out_v_frame = in_frame; - // Stop running *running = false; - } else { - // Encode video - out_v_frame = fame.encode(in_frame); - out_v_frame->number = in_frame->number; } + // 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; diff --git a/src/mov_encoder_thread.cc b/src/mov_encoder_thread.cc index 4562ec9..1e8263b 100644 --- a/src/mov_encoder_thread.cc +++ b/src/mov_encoder_thread.cc @@ -98,12 +98,6 @@ MovEncoderThread::~MovEncoderThread() { info->info("~MovEncoderThread"); - // Push end of stream frame to the queue. - num_frames_in_block = block->size() + 1; // Make the next frame fill out the block. - encode(endOfFrameStream); - - info->info("Posted endOfFrameStream"); - // First we destroy the movie encoders for(int cnt = 0; cnt < threads; cnt++) sem_post(&in_sem); // Kick them for(int cnt = 0; cnt < threads; cnt++) { @@ -121,6 +115,7 @@ MovEncoderThread::~MovEncoderThread() info->info("Deleted the audio encoder"); // Finally we destroy the writer. + writer->running = false; sem_post(&video_out_sem); // Kick it to make it stop. sem_post(&audio_out_sem); // Kick it to make it stop. writer->wait_stop(); // Wait for it to stop. @@ -201,7 +196,7 @@ void MovEncoderThread::encode(Frame* frame) block->push_back(frame); // Switch frame - if(block->size() == num_frames_in_block) { + if(block->size() == num_frames_in_block || frame->endOfFrameStream == true) { // Wait until a free encoder. sem_wait(&read_sem); diff --git a/src/multiplexer.cc b/src/multiplexer.cc index 323b33c..12e9768 100644 --- a/src/multiplexer.cc +++ b/src/multiplexer.cc @@ -31,6 +31,8 @@ #include #include +#include "util.h" + #define SIZEOF(x) (sizeof(x)-1) // Audio index lists @@ -101,9 +103,36 @@ Multiplexer::~Multiplexer() } -int Multiplexer::read_stream(char *buf, unsigned int size, StreamType type) +Frame *Multiplexer::getFrame(StreamType type) { Frame *tmpframe; + Frame *frame = NULL; + + sem_wait(sem[type]); + //if(*running) sem_wait(sem[type]); + + while( frame == NULL ) { + // Lock output mutex + pthread_mutex_lock( mutex[type] ); + tmpframe = queue[type]->top(); + + if(tmpframe && tmpframe->number == frame_number[type] ) { + queue[type]->pop(); + frame = tmpframe; + frame_number[type]++; + read[type] = 0; + } + + pthread_mutex_unlock( mutex[type] ); + // Unlock output mutex + + sleep_1_frame(); + } + return frame; +} + +int Multiplexer::read_stream(char *buf, unsigned int size, StreamType type) +{ unsigned int copied = 0; while( copied < size ) { @@ -115,37 +144,10 @@ int Multiplexer::read_stream(char *buf, unsigned int size, StreamType type) } // If no frame is in the buffer, get one from the queue - while( frame[type] == NULL ) { - - // if(!*running) info->warn("Halt detected!"); - - // If we are not running anymore, just process the last frames as fast as possible! - if(*running) sem_wait(sem[type]); - - // Lock output mutex - pthread_mutex_lock( mutex[type] ); - tmpframe = queue[type]->top(); - - if(tmpframe && tmpframe->number == frame_number[type] ) { - queue[type]->pop(); - frame[type] = tmpframe; - frame_number[type]++; - read[type] = 0; - } - /* - if(*running == false && frame[type] == NULL) { - pthread_mutex_unlock( mutex[type] ); - //info->info("Bailed out early %d!", copied); - return copied; - } - */ - - pthread_mutex_unlock( mutex[type] ); - // Unlock output mutex - } + if(frame[type] == NULL) frame[type] = getFrame(type); // check for end of stream - if( frame[type] == endOfFrameStream ) { + if( frame[type]->endOfFrameStream == true) { info->info("endOfFrameStream in Multiplexer %s-stream.", type==TYPE_VIDEO?"video\0":"audio\0"); return copied; } diff --git a/src/multiplexer.h b/src/multiplexer.h index c0ac663..8d67766 100644 --- a/src/multiplexer.h +++ b/src/multiplexer.h @@ -99,6 +99,7 @@ private: unsigned int write_system_header; unsigned int write_audio_packet; + Frame *getFrame(StreamType type); int read_stream(char *buf, unsigned int size, StreamType type); FramePriorityQueue *queue[NUM_TYPES]; diff --git a/src/player.cc b/src/player.cc index bb495e5..de4e335 100644 --- a/src/player.cc +++ b/src/player.cc @@ -139,8 +139,6 @@ void Player::player() int pitches[3]; - struct timespec ts; - if(!noErrors) return; // FIXME: Gracefully exit... bool first = true; @@ -211,6 +209,8 @@ void Player::player() } if(decoder) dv_decoder_free(decoder); + struct timespec ts; + /* Remove any late buffer */ /* We don't care, the encoder finishes them all */ ts.tv_sec = 0; diff --git a/src/server.cc b/src/server.cc index 892b2e9..6d4d26b 100644 --- a/src/server.cc +++ b/src/server.cc @@ -56,9 +56,6 @@ void newConnection(Socket *socket, Info *info) { - // We need to create the end of stream frame. - if(endOfFrameStream == NULL) endOfFrameStream = new Frame(NULL, 1); - char cpr[256]; bool hasCpr = false; ServerStatus status(info); @@ -88,14 +85,6 @@ void newConnection(Socket *socket, Info *info) hasCpr = true; } - // printf("Read: %d bytes ", ret); - // printf("typ: %d ", h.header_type); -// fprintf(stdout, "cpr: %s ", cpr); -// fprintf(stdout, "frz: %d ", h.header.h_data.freeze); -// fprintf(stdout, "sht: %d ", h.header.h_data.snapshot); -// fprintf(stdout, "save: %d ", h.header.h_data.savestate); -// fflush(stdout); - if(h.header.h_data.snapshot) { if(freeze_frame) { ImgEncoder(cpr, info).encode(freeze_frame, 100); @@ -130,6 +119,10 @@ void newConnection(Socket *socket, Info *info) info->info("Closing connection..."); + // Send end of stream frame. + frame->endOfFrameStream = true; + enc->encode(frame); + if(enc) delete enc; info->info("Connection closed"); diff --git a/src/util.cc b/src/util.cc index a3fdd1c..b9d57ad 100644 --- a/src/util.cc +++ b/src/util.cc @@ -38,6 +38,9 @@ #include #include +// For nanosleep +#include + #include "util.h" void *xmalloc(size_t s) @@ -68,3 +71,14 @@ void *xrealloc(void *b, size_t s) } return p; } + +void sleep_1_frame() +{ + // Sleep 1/25th of a second + + struct timespec ts; + + ts.tv_sec = 0; + ts.tv_nsec = 1000000000L / 25L; // 1000ms / 25 + nanosleep(&ts, NULL); +} diff --git a/src/util.h b/src/util.h index f33c5ce..39ded7f 100644 --- a/src/util.h +++ b/src/util.h @@ -45,6 +45,8 @@ void *xmalloc(size_t s); void *xrealloc(void *b, size_t s); +void sleep_1_frame(); + //#ifdef __cplusplus //} //#endif -- cgit v1.2.3