summaryrefslogtreecommitdiff
path: root/src/multiplexer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/multiplexer.cc')
-rw-r--r--src/multiplexer.cc148
1 files changed, 123 insertions, 25 deletions
diff --git a/src/multiplexer.cc b/src/multiplexer.cc
index 3d764dd..d479627 100644
--- a/src/multiplexer.cc
+++ b/src/multiplexer.cc
@@ -91,6 +91,9 @@ Multiplexer::Multiplexer(File *f, Info *i, volatile bool *r,
written[TYPE_VIDEO] = 0.0;
written[TYPE_AUDIO] = 0.0;
+
+ SCR = 3904;//0x40010003LL;//0x1E80;
+
}
Multiplexer::~Multiplexer()
@@ -103,7 +106,7 @@ int Multiplexer::read_stream(char *buf, unsigned int size, StreamType type)
Frame *tmpframe;
unsigned int copied = 0;
- while(copied < size && (*running) ) {
+ while( copied < size ) {
// If we read the entire frame, prepare to get a new one
if(frame[type] && read[type] == frame[type]->size) {
@@ -112,8 +115,12 @@ 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 && (*running) ) {
- sem_wait(sem[type]);
+ 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] );
@@ -124,6 +131,11 @@ int Multiplexer::read_stream(char *buf, unsigned int size, StreamType type)
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
}
@@ -145,9 +157,14 @@ int Multiplexer::read_stream(char *buf, unsigned int size, StreamType type)
return copied;
}
-void Multiplexer::packet(StreamType type)
+bool Multiplexer::packet(StreamType type)
{
- char buf[1000000];
+ char buf[PACKET_SIZE];
+
+ // Write data
+ info->info("\t\t[%sPacket]", type==TYPE_AUDIO?"Audio\0":"Video\0");
+
+ unsigned short int framesize = read_stream(buf, PACKET_SIZE, type);
file->Write((void*)ISO11172_1::packet_start_code_prefix, SIZEOF(ISO11172_1::packet_start_code_prefix));
switch(type) {
@@ -159,38 +176,50 @@ void Multiplexer::packet(StreamType type)
break;
}
- // Write data
- info->info("\t\t[%sPacket]", type==TYPE_AUDIO?"Audio\0":"Video\0");
-
- unsigned short int hton_framesize = PACKET_SIZE + 1;
+ unsigned short int hton_framesize = framesize + 1; // Need space for dims too!
hton_framesize = htons(hton_framesize);
file->Write((char*)&hton_framesize, sizeof(hton_framesize));
char dims[] = "\x0F";
file->Write(dims, 1);
- file->Write(buf, read_stream(buf, PACKET_SIZE, type));
+ file->Write(buf, framesize);
+
+ if(framesize != PACKET_SIZE) return false;
written[type] += (double)PACKET_SIZE / (double)frame[type]->bitrate;
+
+ return true;
}
/**
* Create and write a packet
*/
-void Multiplexer::packet()
+bool Multiplexer::packet()
{
- info->info("\t\tWritten[A]: %f, Written[V]: %f", written[TYPE_AUDIO], written[TYPE_VIDEO]);
+ //info->info("\t\tWritten[A]: %f, Written[V]: %f", written[TYPE_AUDIO], written[TYPE_VIDEO]);
+
+ StreamType type;
// New switching mechanism
if(written[TYPE_AUDIO] < written[TYPE_VIDEO]) {
- packet(TYPE_AUDIO);
+ type = TYPE_AUDIO;
} else {
- packet(TYPE_VIDEO);
+ type = TYPE_VIDEO;
}
-
- // Count this up here, we want audio packets in packet 4, 9, ... NOT 0, 3, ...
+ if(!packet(type)) {
+ // Flush the other stream too...
+ if(type == TYPE_AUDIO) type = TYPE_VIDEO;
+ else type = TYPE_AUDIO;
+ while(packet(type));
+ return false;
+ }
+ return true;
+
/*
+ // Count this up here, we want audio packets in packet 4, 9, ... NOT 0, 3, ...
+
write_audio_packet++;
if(write_audio_packet % AUDIO_PACKET_FREQUENCY == 0) {
packet(TYPE_AUDIO);
@@ -230,7 +259,7 @@ void Multiplexer::system_header()
// system_video_lock_flag (1 bit) \.
// marker_bit (1 bit) ) (8 bits)
// video_bound (5 bits) _/
- char video_bound[] = "\xE1"; // Audio and Video are locked and there are only one video stream
+ char video_bound[] = "\x21"; // Audio and Video are not locked and there are only one video stream
file->Write(video_bound, SIZEOF(video_bound));
// reserved_byte (8 bit)
@@ -262,25 +291,88 @@ void Multiplexer::system_header()
}
}
+#define MASK3 0x7
+#define MASK15 0x7FFF
+#define TIMECODE32_30(x) ((x >> 30) & MASK3 )
+#define TIMECODE29_15(x) ((x >> 15) & MASK15)
+#define TIMECODE14_0(x) ((x >> 0) & MASK15)
+
/**
* Create and write a pack
*/
-void Multiplexer::pack()
+bool Multiplexer::pack()
{
info->info("\t[Pack");
file->Write((void*)ISO11172_1::pack_start_code, SIZEOF(ISO11172_1::pack_start_code));
- // Stuff! FIXME: Change this
- char stuff[] = "\x21\x00\x01\x1E\x81\x80\x1B\x83";
- file->Write(stuff, SIZEOF(stuff));
+ ISO11172_1::pack_header header;
+ // Set marker bits to 1
+ header.marker_bit1 =
+ header.marker_bit2 =
+ header.marker_bit3 =
+ header.marker_bit4 =
+ header.marker_bit5 = 1;
+
+ header.padding = 0x2;
+
+ unsigned int video_data_rate;
+ unsigned int audio_data_rate;
+
+ if(frame[TYPE_AUDIO]) audio_data_rate = frame[TYPE_AUDIO]->bitrate;
+ else audio_data_rate = 112000;
+
+ if(frame[TYPE_VIDEO]) video_data_rate = frame[TYPE_VIDEO]->bitrate;
+ else video_data_rate = 1100000;
+
+ unsigned int Rmux = ISO11172_1::Rmux(video_data_rate,
+ audio_data_rate,
+ 20, // packet_header_size,
+ 12, // pack_header_size,
+ PACKETS_PER_PACK, // packets_per_pack,
+ PACKET_SIZE);// packet_data_size)
+
+ header.mux_rate = Rmux;
+ //0x1B82;
+
+ SCR = ISO11172_1::SCR(SCR,
+ 12, //pack_header_size,
+ PACKETS_PER_PACK, //packets_per_pack,
+ PACKET_SIZE, //packet_data_size,
+ Rmux);
+
+ // SCR = 0x40010003LL;
+
+ header.system_clock_reference1 = TIMECODE32_30(SCR);
+ header.system_clock_reference2 = TIMECODE29_15(SCR);
+ header.system_clock_reference3 = TIMECODE14_0(SCR);
+ /*
+ info->info("timecode All: %lld, 1: %lld, 2: %lld, 3: %lld",
+ SCR,
+ (unsigned long long int)header.system_clock_reference1,
+ (unsigned long long int)header.system_clock_reference2,
+ (unsigned long long int)header.system_clock_reference3
+ );
+ */
+ unsigned int *hton_header_u = (unsigned int *)&header;
+ unsigned int *hton_header_l = (unsigned int *)((char*)&header + sizeof(unsigned int));
+
+ *hton_header_u = htonl(*hton_header_u);
+ *hton_header_l = htonl(*hton_header_l);
+
+ file->Write((char*)hton_header_u, sizeof(*hton_header_u));
+ file->Write((char*)hton_header_l, sizeof(*hton_header_l));
if(write_system_header % SYSTEM_HEADER_FREQUENCY == 0) system_header();
// Count this up here, we want a system header in pack 0, 5, ... NOT 4, 9, ...
write_system_header++;
- for(int cnt = 0; cnt < NUMBER_OF_PACKETS_IN_A_PACK; cnt++) packet();
+ for(int cnt = 0; cnt < PACKETS_PER_PACK; cnt++)
+ if(!packet()) return false;
+
info->info("\t]");
+
+ return true;
}
/**
@@ -289,12 +381,18 @@ void Multiplexer::pack()
void Multiplexer::iso11172_stream()
{
info->info("[iso11172_stream");
- while(*running) {
- pack();
- }
+
+ while(pack());
+
info->info("]");
info->info("[iso11172_end_code]");
file->Write((void*)ISO11172_1::end_code, SIZEOF(ISO11172_1::end_code));
+
+ /*
+ info->info("false && false = %d", false && false);
+ info->info("true && false = %d", true && false);
+ info->info("true && true = %d", true && true);
+ */
}
//#define BYPASS TYPE_VIDEO