From 0ff825e0e6fe5fc7238e3964d24779a07cb53518 Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Wed, 14 May 2014 14:24:34 +0200 Subject: Split miav server and client apart. Port client to Qt4. Replace libraw1994 with libiec61883. Add unit tests for multiplexer and fix some bugs in it. --- src/multiplexer.cc | 149 +++++++++++++++++++++++++---------------------------- 1 file changed, 71 insertions(+), 78 deletions(-) (limited to 'src/multiplexer.cc') diff --git a/src/multiplexer.cc b/src/multiplexer.cc index de6180f..d4526bc 100644 --- a/src/multiplexer.cc +++ b/src/multiplexer.cc @@ -33,13 +33,19 @@ #include "util.h" -#define SIZEOF(x) (sizeof(x)-1) +static uint64_t htonll(uint64_t value) +{ + int num = 42; + if(*(char *)&num == 42) { + return ((uint64_t)htonl(value & 0xffffffff) << 32) | + (uint64_t)htonl(value >> 32); + } + + return value; +} +#define ntohll(v) htonll(v) -#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) +#define SIZEOF(x) (sizeof(x)-1) // Audio index lists /* @@ -114,50 +120,16 @@ int Multiplexer::Write(char* data, int size) return Write((void*)data, size); } -int Multiplexer::Write(unsigned long long int val) +int Multiplexer::Write(uint64_t val) { - int res; - int written = 0; - unsigned long int h_u = val & 0xffffffff; - unsigned long int h_l = (val << 32) & 0xffffffff; - - h_u = htonl(h_u); - h_l = htonl(h_l); - - if((res = Write(&h_l, sizeof(h_l))) < 0) { - return res; - } - written += res; - - if((res = Write(&h_u, sizeof(h_u))) < 0) { - return res; - } - written += res; + val = htonll(val); - return written; + return Write((char*)&val, sizeof(val)); } -int Multiplexer::Write(long long int val) +int Multiplexer::Write(int64_t val) { - int res; - int written = 0; - unsigned long int h_u = val & 0xffffffff; - unsigned long int h_l = (val << 32) & 0xffffffff; - - h_u = htonl(h_u); - h_l = htonl(h_l); - - if((res = Write(&h_l, sizeof(h_l))) < 0) { - return res; - } - written += res; - - if((res = Write(&h_u, sizeof(h_u))) < 0) { - return res; - } - written += res; - - return written; + return Write((uint64_t)val); } int Multiplexer::Write(long int val) @@ -174,6 +146,13 @@ int Multiplexer::Write(unsigned long int val) return Write((char*)&val, sizeof(val)); } +int Multiplexer::Write24(uint32_t val) +{ + val = htonl(val) >> 8; + + return Write((char*)&val, 3 /*24 bit*/); +} + int Multiplexer::Write(int val) { val = htonl(val); @@ -348,17 +327,21 @@ void Multiplexer::system_header() // info->info("\t\t[System Header]"); // system_header_start_code (32 bits) - 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; + uint16_t header_length = 8 - 2 + (NUM_TYPES * 3); + // (sizeof(header) - sizeof(header.header_length)) + + // NUM_TYPES * sizeof(ISO11172_1::stream_description); + Write(header_length); - header.bits.marker_bit1 = header.bits.marker_bit2 = - header.bits.marker_bit3 = 1; + uint32_t rate_bound = (1 << 23) | // Marker bit + 3521 << 1 | // FIXME: This value was simply taken from an example! + 1; // Marker bit + Write24(rate_bound); - header.bits.header_length = 8 - 2 + (NUM_TYPES * 3); - // (sizeof(header) - sizeof(header.header_length)) + - // NUM_TYPES * sizeof(ISO11172_1::stream_description); - header.bits.rate_bound = 3521; // FIXME: Taken from the example! + ISO11172_1::system_header header; + header.bits.marker_bit = 1; header.bits.audio_bound = 1; // Only 1 audio stream header.bits.fixed_flag = 1; // Fixed bitrate (0 indicates vbr) header.bits.CSPS_flag = 1; // Standarts compliant? (yes: see lame_set_strict_ISO in liblame_wrapper.cc) @@ -366,33 +349,34 @@ void Multiplexer::system_header() header.bits.system_video_clock_flag = 1; // FIXME: What excactly is this?? header.bits.video_bound = 1; // Only 1 video stream header.bits.reserved_byte = 0xFF; // Must be 0xFF - Write(header.ulli); - + Write24(header.ulli); + ISO11172_1::stream_description audio_stream_description; audio_stream_description.bits.stream_id = 0xC0; - audio_stream_description.bits.market_bits = 0x3; + audio_stream_description.bits.market_bits = 3; audio_stream_description.bits.STD_buffer_bound_scale = 0; // Must be 0 for audio streams audio_stream_description.bits.STD_buffer_size_bound = 32; // Buffer must be 32 * 128 bytes - Write(audio_stream_description.uli); + Write24(audio_stream_description.uli); ISO11172_1::stream_description video_stream_description; video_stream_description.bits.stream_id = 0xE3; video_stream_description.bits.market_bits = 0x3; video_stream_description.bits.STD_buffer_bound_scale = 1; // Must be 1 for video streams video_stream_description.bits.STD_buffer_size_bound = 46; // Buffer must be 32 * 1024 bytes - Write(video_stream_description.uli); + + Write24(video_stream_description.uli); } /** - * Create and write a pack + * Write pack header */ -bool Multiplexer::pack() +void Multiplexer::pack_header() { - // info->info("\t[Pack"); - Write((void*)ISO11172_1::pack_start_code, SIZEOF(ISO11172_1::pack_start_code)); ISO11172_1::pack_header header; + header.ulli = 0; // Reset all bits + // Set marker bits to 1 header.bits.marker_bit1 = header.bits.marker_bit2 = @@ -402,6 +386,18 @@ bool Multiplexer::pack() header.bits.padding = 0x2; + header.bits.system_clock_reference1 = TIMECODE32_30(SCR); + header.bits.system_clock_reference2 = TIMECODE29_15(SCR); + header.bits.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 video_data_rate; unsigned int audio_data_rate; @@ -412,11 +408,11 @@ bool Multiplexer::pack() 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) + audio_data_rate, + 20, // packet_header_size, + 12, // pack_header_size, + PACKETS_PER_PACK, // packets_per_pack, + PACKET_SIZE);// packet_data_size) header.bits.mux_rate = Rmux; //0x1B82; @@ -429,18 +425,15 @@ bool Multiplexer::pack() // SCR = 0x40010003LL; - header.bits.system_clock_reference1 = TIMECODE32_30(SCR); - header.bits.system_clock_reference2 = TIMECODE29_15(SCR); - header.bits.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 - ); - */ Write(header.ulli); +} + +/** + * Create and write a pack + */ +bool Multiplexer::pack() +{ + pack_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, ... -- cgit v1.2.3