From 0ef298aa78a315f64a6a686407f8f10694f0ea5d Mon Sep 17 00:00:00 2001 From: deva Date: Thu, 15 Sep 2005 19:31:16 +0000 Subject: *** empty log message *** --- src/multiplexer.cc | 148 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 123 insertions(+), 25 deletions(-) (limited to 'src/multiplexer.cc') 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 -- cgit v1.2.3