summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--etc/miav.conf9
-rw-r--r--src/frame.cc4
-rw-r--r--src/frame.h3
-rw-r--r--src/mov_encoder.cc16
-rw-r--r--src/mov_encoder_thread.cc9
-rw-r--r--src/multiplexer.cc62
-rw-r--r--src/multiplexer.h1
-rw-r--r--src/player.cc4
-rw-r--r--src/server.cc15
-rw-r--r--src/util.cc14
-rw-r--r--src/util.h2
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 <memory.h>
#include <stdlib.h>
-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 <functional>
@@ -69,6 +71,5 @@ typedef std::priority_queue< Frame*,
std::vector<Frame*>,
frame_priority<Frame*> > 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 <netinet/in.h>
#include <math.h>
+#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 <string.h>
#include <assert.h>
+// For nanosleep
+#include <time.h>
+
#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