diff options
-rw-r--r-- | src/file.cc | 4 | ||||
-rw-r--r-- | src/file.h | 3 | ||||
-rw-r--r-- | src/mov_encoder_writer.cc | 6 | ||||
-rw-r--r-- | src/mov_encoder_writer.h | 2 | ||||
-rw-r--r-- | src/multicast.cc | 51 | ||||
-rw-r--r-- | src/multicast.h | 5 | ||||
-rw-r--r-- | src/multiplexer.cc | 135 | ||||
-rw-r--r-- | src/multiplexer.h | 15 | ||||
-rw-r--r-- | src/threadsafe_queue_fifo.h | 2 |
9 files changed, 187 insertions, 36 deletions
diff --git a/src/file.cc b/src/file.cc index 9188e6e..c3fad30 100644 --- a/src/file.cc +++ b/src/file.cc @@ -126,7 +126,7 @@ int File::Write(void* data, int size) return w; } - +/* int File::Write(char* data, int size) { return Write((void*)data, size); @@ -219,7 +219,7 @@ int File::Write(unsigned short int val) return Write((char*)&val, sizeof(val)); } - +*/ int File::createPath(char* path) { // struct stat stats; @@ -40,6 +40,7 @@ public: ~File(); int Write(void* data, int size); + /* int Write(char* data, int size); int Write(unsigned long long int val); @@ -50,7 +51,7 @@ public: int Write(unsigned int val); int Write(short int val); int Write(unsigned short int val); - + */ private: Info* info; diff --git a/src/mov_encoder_writer.cc b/src/mov_encoder_writer.cc index 732f9ba..572a81e 100644 --- a/src/mov_encoder_writer.cc +++ b/src/mov_encoder_writer.cc @@ -81,6 +81,8 @@ MovEncoderWriter::MovEncoderWriter(const char* cpr, file = new File(fname, "mpg", info); + multicast = new Multicast(info); + video_queue = video_q; audio_queue = audio_q; @@ -91,6 +93,7 @@ MovEncoderWriter::~MovEncoderWriter() { info->info("~MovEncoderWriter"); delete file; + delete multicast; } @@ -98,7 +101,8 @@ void MovEncoderWriter::thread_main() { info->info("MovEncoderWriter::run"); - Multiplexer multiplexer(file, info, &running, + Multiplexer multiplexer(file, multicast, + info, &running, video_queue, audio_queue); multiplexer.multiplex(); diff --git a/src/mov_encoder_writer.h b/src/mov_encoder_writer.h index 3146bf8..00d5262 100644 --- a/src/mov_encoder_writer.h +++ b/src/mov_encoder_writer.h @@ -31,6 +31,7 @@ #include "frame.h" #include "thread.h" #include "file.h" +#include "multicast.h" #include "info.h" #include "threadsafe_queue_priority.h" @@ -57,6 +58,7 @@ private: Info *info; File *file; + Multicast *multicast; ThreadSafeQueuePriority *video_queue; ThreadSafeQueuePriority *audio_queue; diff --git a/src/multicast.cc b/src/multicast.cc index 0cf1b87..b64bfde 100644 --- a/src/multicast.cc +++ b/src/multicast.cc @@ -35,8 +35,18 @@ Multicast::Multicast(Info *i) { - char addr[] = "192.168.0.10"; - int port = 666; + /* + Multicast adresses: + 224.0.0.1 All systems on this subnet + 224.0.0.2 All routers on this subnet + 224.0.0.5 OSPF routers + 224.0.0.6 OSPF designated routers + 224.0.0.12 DHCP server/relay agent + */ + + // Multicast to all systems on this subnet + char addr[] = "224.0.0.1"; + int port = 1234; info = i; if(!UDPOpen(addr, port)) info->error("Error creating socket %s:%d", addr, port); @@ -46,16 +56,33 @@ Multicast::~Multicast() { } -void Multicast::Write(char* buf, int size) +void Multicast::Write(void* buf, int size) { - if(write(sock, buf, size) != size) info->error("Error Writing to socket."); + // char addr[] = "192.168.0.10"; + // int port = 1234; + + if(write(sock, buf, size) != size) { + info->error("Error Writing to socket."); + // if(!UDPOpen(addr, port)) info->error("Error creating socket %s:%d", addr, port); + } } +#define USE_MULTICAST + +bool Multicast::is_address_multicast(unsigned long address) +{ + if((address & 255) >= 224 && (address & 255) <= 239) { + info->info("Address is multicast."); + return true; + } + info->info("Address is NOT multicast."); + return false; +} /* * open UDP socket */ -bool Multicast::UDPOpen(char * address, int port) +bool Multicast::UDPOpen(char *address, int port) { int enable = 1L; struct sockaddr_in stAddr; @@ -68,25 +95,27 @@ bool Multicast::UDPOpen(char * address, int port) if((host = gethostbyname(address)) == NULL) return false; stAddr.sin_addr = *((struct in_addr *) host->h_addr_list[0]); - /* Create a UDP socket */ + // Create a UDP socket if((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) return false; - /* Allow multiple instance of the client to share the same address and port */ if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &enable, sizeof(unsigned long int)) < 0) return false; + // Allow multiple instance of the client to share the same address and port + if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &enable, sizeof(unsigned long int)) < 0) + return false; #ifdef USE_MULTICAST - /* If the address is multicast, register to the multicast group */ + // If the address is multicast, register to the multicast group if(is_address_multicast(stAddr.sin_addr.s_addr)) { struct ip_mreq stMreq; - /* Bind the socket to port */ + // Bind the socket to port stLclAddr.sin_family = AF_INET; stLclAddr.sin_addr.s_addr = htonl(INADDR_ANY); stLclAddr.sin_port = stAddr.sin_port; if(bind(sock, (struct sockaddr*) & stLclAddr, sizeof(stLclAddr)) < 0) return false; - /* Register to a multicast address */ + // Register to a multicast address stMreq.imr_multiaddr.s_addr = stAddr.sin_addr.s_addr; stMreq.imr_interface.s_addr = INADDR_ANY; if(setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) & stMreq, sizeof(stMreq)) < 0) @@ -95,7 +124,7 @@ bool Multicast::UDPOpen(char * address, int port) else #endif { - /* Bind the socket to port */ + // Bind the socket to port stLclAddr.sin_family = AF_INET; stLclAddr.sin_addr.s_addr = htonl(INADDR_ANY); stLclAddr.sin_port = htons(0); diff --git a/src/multicast.h b/src/multicast.h index f0a4979..50727a5 100644 --- a/src/multicast.h +++ b/src/multicast.h @@ -35,12 +35,13 @@ public: Multicast(Info *info); ~Multicast(); - void Write(char* buf, int size); + void Write(void* buf, int size); private: Info *info; - bool UDPOpen(char * address, int port); + bool is_address_multicast(unsigned long address); + bool UDPOpen(char *address, int port); int sock; }; diff --git a/src/multiplexer.cc b/src/multiplexer.cc index 0b54bf8..096ff86 100644 --- a/src/multiplexer.cc +++ b/src/multiplexer.cc @@ -68,12 +68,13 @@ static double picture_rate_index[16] = { RESERVED, RESERVED, RESERVED, RESERVED, RESERVED, RESERVED, RESERVED }; */ -Multiplexer::Multiplexer(File *f, Info *i, volatile bool *r, +Multiplexer::Multiplexer(File *f, Multicast *m, Info *i, volatile bool *r, ThreadSafeQueuePriority *video_q, ThreadSafeQueuePriority *audio_q) { running = r; file = f; + multicast = m; info = i; frame[TYPE_VIDEO] = NULL; @@ -98,10 +99,112 @@ Multiplexer::~Multiplexer() { } +int Multiplexer::Write(void* data, int size) +{ + int ret; + + multicast->Write(data, size); + ret = file->Write(data, size); + + return ret; +} + +int Multiplexer::Write(char* data, int size) +{ + return Write((void*)data, size); +} + +int Multiplexer::Write(unsigned long long int val) +{ + int res; + int written = 0; + unsigned long int *h_u = (unsigned long int *)&val; + unsigned long int *h_l = (unsigned long int *)(((char*)&val) + sizeof(unsigned long int)); + + *h_u = htonl(*h_u); + *h_l = htonl(*h_l); + + if((res = Write((void*)h_l, sizeof(*h_l))) < 0) { + return res; + } + written += res; + + if((res = Write((void*)h_u, sizeof(*h_u))) < 0) { + return res; + } + written += res; + + return written; +} + +int Multiplexer::Write(long long int val) +{ + int res; + int written = 0; + unsigned long int *h_u = (unsigned long int *)&val; + unsigned long int *h_l = (unsigned long int *)(((char*)&val) + sizeof(unsigned long int)); + + *h_u = htonl(*h_u); + *h_l = htonl(*h_l); + + if((res = Write((void*)h_l, sizeof(*h_l))) < 0) { + return res; + } + written += res; + + if((res = Write((void*)h_u, sizeof(*h_u))) < 0) { + return res; + } + written += res; + + return written; +} + +int Multiplexer::Write(long int val) +{ + val = htonl(val); + + return Write((char*)&val, sizeof(val)); +} + +int Multiplexer::Write(unsigned long int val) +{ + val = htonl(val); + + return Write((char*)&val, sizeof(val)); +} + +int Multiplexer::Write(int val) +{ + val = htonl(val); + + return Write((char*)&val, sizeof(val)); +} + +int Multiplexer::Write(unsigned int val) +{ + val = htonl(val); + + return Write((char*)&val, sizeof(val)); +} + +int Multiplexer::Write(short int val) +{ + val = htons(val); + + return Write((char*)&val, sizeof(val)); +} + +int Multiplexer::Write(unsigned short int val) +{ + val = htons(val); + + return Write((char*)&val, sizeof(val)); +} Frame *Multiplexer::getFrame(StreamType type) { - info->info("Get %s Frame", type==TYPE_AUDIO?"Audio\0":"Video\0"); + // info->info("Get %s Frame", type==TYPE_AUDIO?"Audio\0":"Video\0"); read[type] = 0; @@ -155,13 +258,13 @@ bool Multiplexer::packet(StreamType type) 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)); + Write((void*)ISO11172_1::packet_start_code_prefix, SIZEOF(ISO11172_1::packet_start_code_prefix)); switch(type) { case TYPE_VIDEO: - file->Write((void*)ISO11172_1::stream_id_video1, SIZEOF(ISO11172_1::stream_id_video1)); + Write((void*)ISO11172_1::stream_id_video1, SIZEOF(ISO11172_1::stream_id_video1)); break; case TYPE_AUDIO: - file->Write((void*)ISO11172_1::stream_id_audio1, SIZEOF(ISO11172_1::stream_id_audio1)); + Write((void*)ISO11172_1::stream_id_audio1, SIZEOF(ISO11172_1::stream_id_audio1)); break; } @@ -173,9 +276,9 @@ bool Multiplexer::packet(StreamType type) header.system_clock_reference1 = TIMECODE32_30(SCR); header.system_clock_reference2 = TIMECODE29_15(SCR); header.system_clock_reference3 = TIMECODE14_0(SCR); - file->Write(*((unsigned long long int*)&header)); + Write(*((unsigned long long int*)&header)); - file->Write(buf, framesize); + Write(buf, framesize); if(framesize != PACKET_SIZE) return false; @@ -229,7 +332,7 @@ void Multiplexer::system_header() // info->info("\t\t[System Header]"); // system_header_start_code (32 bits) - file->Write((void*)ISO11172_1::system_header_start_code, SIZEOF(ISO11172_1::system_header_start_code)); + Write((void*)ISO11172_1::system_header_start_code, SIZEOF(ISO11172_1::system_header_start_code)); ISO11172_1::system_header header; @@ -246,21 +349,21 @@ void Multiplexer::system_header() header.system_video_clock_flag = 1; // FIXME: What excactly is this?? header.video_bound = 1; // Only 1 video stream header.reserved_byte = 0xFF; // Must be 0xFF - file->Write(*((unsigned long long int*)&header)); + Write(*((unsigned long long int*)&header)); ISO11172_1::stream_description audio_stream_description; audio_stream_description.stream_id = 0xC0; audio_stream_description.market_bits = 0x3; audio_stream_description.STD_buffer_bound_scale = 0; // Must be 0 for audio streams audio_stream_description.STD_buffer_size_bound = 32; // Buffer must be 32 * 128 bytes - file->Write(*((unsigned long int*)&audio_stream_description)); + Write(*((unsigned long int*)&audio_stream_description)); ISO11172_1::stream_description video_stream_description; video_stream_description.stream_id = 0xE3; video_stream_description.market_bits = 0x3; video_stream_description.STD_buffer_bound_scale = 1; // Must be 1 for video streams video_stream_description.STD_buffer_size_bound = 46; // Buffer must be 32 * 1024 bytes - file->Write(*((unsigned long int*)&video_stream_description)); + Write(*((unsigned long int*)&video_stream_description)); } /** @@ -270,7 +373,7 @@ bool Multiplexer::pack() { // info->info("\t[Pack"); - file->Write((void*)ISO11172_1::pack_start_code, SIZEOF(ISO11172_1::pack_start_code)); + Write((void*)ISO11172_1::pack_start_code, SIZEOF(ISO11172_1::pack_start_code)); ISO11172_1::pack_header header; // Set marker bits to 1 @@ -320,7 +423,7 @@ bool Multiplexer::pack() (unsigned long long int)header.system_clock_reference3 ); */ - file->Write(*((unsigned long long int*)&header)); + Write(*((unsigned long long int*)&header)); 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, ... @@ -345,7 +448,7 @@ void Multiplexer::iso11172_stream() // info->info("]"); // info->info("[iso11172_end_code]"); - file->Write((void*)ISO11172_1::end_code, SIZEOF(ISO11172_1::end_code)); + Write((void*)ISO11172_1::end_code, SIZEOF(ISO11172_1::end_code)); /* info->info("false && false = %d", false && false); @@ -354,7 +457,7 @@ void Multiplexer::iso11172_stream() */ } -//#define BYPASS TYPE_VIDEO +#define BYPASS TYPE_VIDEO //#define BYPASS TYPE_AUDIO void Multiplexer::multiplex() { @@ -365,7 +468,7 @@ void Multiplexer::multiplex() do { frmsz = read_stream(buf, sizeof(buf), BYPASS); info->info("Wrote %d bytes", frmsz); - file->Write(buf, frmsz); + Write(buf, frmsz); } while(frmsz == sizeof(buf)); return; diff --git a/src/multiplexer.h b/src/multiplexer.h index 2604ddc..9959009 100644 --- a/src/multiplexer.h +++ b/src/multiplexer.h @@ -33,6 +33,7 @@ #include "iso11172-3.h" #include "file.h" +#include "multicast.h" #include "info.h" #include "frame.h" @@ -68,7 +69,7 @@ typedef enum { class Multiplexer { public: - Multiplexer(File *file, Info *info, volatile bool *running, + Multiplexer(File *file, Multicast *m, Info *info, volatile bool *running, ThreadSafeQueuePriority *video_queue, ThreadSafeQueuePriority *audio_queue); ~Multiplexer(); @@ -76,6 +77,17 @@ public: void multiplex(); private: + int Write(void* data, int size); + int Write(char* data, int size); + int Write(unsigned long long int val); + int Write(long long int val); + int Write(long int val); + int Write(unsigned long int val); + int Write(int val); + int Write(unsigned int val); + int Write(short int val); + int Write(unsigned short int val); + unsigned long long int SCR; double written[NUM_TYPES]; @@ -109,6 +121,7 @@ private: unsigned int read[NUM_TYPES]; File *file; + Multicast *multicast; Info *info; volatile bool *running; diff --git a/src/threadsafe_queue_fifo.h b/src/threadsafe_queue_fifo.h index 84b2fbb..30f6645 100644 --- a/src/threadsafe_queue_fifo.h +++ b/src/threadsafe_queue_fifo.h @@ -77,6 +77,4 @@ private: std::queue<T> queue; }; - - #endif/*__MIAV_THREADSAFE_QUEUE_FIFO_H__*/ |