summaryrefslogtreecommitdiff
path: root/src/multiplexer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/multiplexer.cc')
-rw-r--r--src/multiplexer.cc495
1 files changed, 0 insertions, 495 deletions
diff --git a/src/multiplexer.cc b/src/multiplexer.cc
deleted file mode 100644
index 7a8b095..0000000
--- a/src/multiplexer.cc
+++ /dev/null
@@ -1,495 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/***************************************************************************
- * multiplexer.cc
- *
- * Wed Aug 31 13:05:18 CEST 2005
- * Copyright 2005 Bent Bisballe Nyeng
- * deva@aasimon.org
- ****************************************************************************/
-
-/*
- * This file is part of MIaV.
- *
- * MIaV is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MIaV is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with MIaV; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "config.h"
-#include "multiplexer.h"
-
-#include <netinet/in.h>
-#include <math.h>
-
-#include "util.h"
-
-#define SIZEOF(x) (sizeof(x)-1)
-
-#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)
-
-// Audio index lists
-/*
-static unsigned int frequency_index[4] = {44100, 48000, 32000, 0};
-//static unsigned int slots [4] = {12, 144, 0, 0};
-//static unsigned int slot_index [4] = {144, 144, 144, 0};
-//static unsigned int sample_index [4] = {384, 1152, 0, 0};
-static unsigned int bitrate_index [4][16] = {
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0}, // Reserved
- {0,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320,0}, // Layer III
- {0,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384,0}, // Layer II
- {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0} // Layer I
-};
-static char layer_index[4][12] = { "Reserved", "Layer III", "Layer II", "Layer I" };
-static char mode_index[4][32] = { "Stereo", "Joint Stereo", "Dual Channel", "Single Channel"};
-static char protection_index[2][32] = { "CRC check enabled", "CRC check disabled" };
-*/
-//static unsigned short int syncword = 0xFFF;
-
-// Video index lists
-/*
-#define FORBIDDEN -1.0
-#define RESERVED -2.0
-static double picture_rate_index[16] = {
- FORBIDDEN, 23.976, 24.0, 25.0, 29.97, 30.0, 50.0, 59.94, 60,
- RESERVED, RESERVED, RESERVED, RESERVED, RESERVED, RESERVED, RESERVED
-};
-*/
-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;
- written[TYPE_VIDEO] = 0.0;
-
- frame[TYPE_AUDIO] = NULL;
- written[TYPE_AUDIO] = 0.0;
-
- write_audio_packet = 0;
- write_system_header = 0;
-
- audio_header_read = false;
-
- queue[TYPE_VIDEO] = video_q;
- queue[TYPE_AUDIO] = audio_q;
-
- SCR = 3904;//0x40010003LL;//0x1E80;
-
-}
-
-Multiplexer::~Multiplexer()
-{
-}
-
-int Multiplexer::Write(void* data, int size)
-{
- int ret;
-
- if(multicast && multicast->multicast_audio == true) 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");
-
- read[type] = 0;
-
- Frame *frame = queue[type]->pop();
-
- // If we multicast without audio, we better write the raw video stream.
- if(type == TYPE_VIDEO && multicast && multicast->multicast_audio == false)
- multicast->Write(frame->data, frame->size);
-
- return frame;
-}
-
-int Multiplexer::read_stream(char *buf, unsigned int size, StreamType type)
-{
- unsigned int copied = 0;
-
- while( copied < size ) {
-
- // If we read the entire frame, prepare to get a new one
- if(frame[type] && read[type] == frame[type]->size) {
- delete frame[type];
- frame[type] = NULL;
- }
-
- // If no frame is in the buffer, get one from the queue
- if(frame[type] == NULL) frame[type] = getFrame(type);
-
- // check for end of stream
- if( frame[type]->endOfFrameStream == true) {
- info->info("endOfFrameStream in Multiplexer %s-stream.", type==TYPE_VIDEO?"video\0":"audio\0");
- return copied;
- }
-
- // If a frame exists in the buffer copy it to the output buffer
- // (No frame ocurres when *running is set to false)
- if( frame[type] ) {
- unsigned int doread = (size - copied) < (frame[type]->size - read[type]) ?
- size - copied : (frame[type]->size - read[type]);
-
- //info->info("Requested: %d. Read: %d. Doread: %d. In buffer %d", size, (*read), doread, (*frame)->size);
-
- memcpy(buf + copied, frame[type]->data + read[type], doread);
- read[type] += doread;
- copied += doread;
- }
- }
-
- return copied;
-}
-
-bool Multiplexer::packet(StreamType type)
-{
- 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);
-
- Write((void*)ISO11172_1::packet_start_code_prefix, SIZEOF(ISO11172_1::packet_start_code_prefix));
- switch(type) {
- case TYPE_VIDEO:
- Write((void*)ISO11172_1::stream_id_video1, SIZEOF(ISO11172_1::stream_id_video1));
- break;
- case TYPE_AUDIO:
- Write((void*)ISO11172_1::stream_id_audio1, SIZEOF(ISO11172_1::stream_id_audio1));
- break;
- }
-
- ISO11172_1::packet_header header;
- header.marker_bit1 = header.marker_bit2 = header.marker_bit3 = 1;
- header.padding = 0x2; // Must be 2
- header.stuffing_byte = 0xFF;
- header.packet_length = framesize + sizeof(ISO11172_1::packet_header) - sizeof(short);
- header.system_clock_reference1 = TIMECODE32_30(SCR);
- header.system_clock_reference2 = TIMECODE29_15(SCR);
- header.system_clock_reference3 = TIMECODE14_0(SCR);
- Write(*((unsigned long long int*)&header));
-
- Write(buf, framesize);
-
- if(framesize != PACKET_SIZE) return false;
-
- written[type] += (double)PACKET_SIZE / (double)frame[type]->size;//bitrate;
-
- return true;
-}
-
-/**
- * Create and write a packet
- */
-bool Multiplexer::packet()
-{
- //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]) {
- type = TYPE_AUDIO;
- } else {
- type = TYPE_VIDEO;
- }
- */
-
- // Newer switching mechanism
- if(queue[TYPE_AUDIO]->size() > queue[TYPE_VIDEO]->size()) {
- type = TYPE_AUDIO;
- } else {
- type = TYPE_VIDEO;
- }
-
-
- 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);
- } else {
- packet(TYPE_VIDEO);
- }
- */
-}
-
-/**
- * Create and write the system header
- */
-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));
-
- ISO11172_1::system_header header;
-
- header.marker_bit1 = header.marker_bit2 = header.marker_bit3 = 1;
-
- header.header_length = 8 - 2 + (NUM_TYPES * 3);
- // (sizeof(header) - sizeof(header.header_length)) +
- // NUM_TYPES * sizeof(ISO11172_1::stream_description);
- header.rate_bound = 3521; // FIXME: Taken from the example!
- header.audio_bound = 1; // Only 1 audio stream
- header.fixed_flag = 1; // Fixed bitrate (0 indicates vbr)
- header.CSPS_flag = 1; // Standarts compliant? (yes: see lame_set_strict_ISO in liblame_wrapper.cc)
- header.system_audio_clock_flag = 1; // FIXME: What excactly is this??
- 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
- 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
- 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
- Write(*((unsigned long int*)&video_stream_description));
-}
-
-/**
- * Create and write a pack
- */
-bool Multiplexer::pack()
-{
- // info->info("\t[Pack");
-
- Write((void*)ISO11172_1::pack_start_code, SIZEOF(ISO11172_1::pack_start_code));
-
- 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
- );
- */
- 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, ...
- write_system_header++;
-
- for(int cnt = 0; cnt < PACKETS_PER_PACK; cnt++)
- if(!packet()) return false;
-
- // info->info("\t]");
-
- return true;
-}
-
-/**
- *
- */
-void Multiplexer::iso11172_stream()
-{
- // info->info("[iso11172_stream");
-
- while(pack());
-
- // info->info("]");
- // info->info("[iso11172_end_code]");
- 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
-//#define BYPASS TYPE_AUDIO
-void Multiplexer::multiplex()
-{
-#ifdef BYPASS
-
- int frmsz;
- char buf[1024];
- do {
- frmsz = read_stream(buf, sizeof(buf), BYPASS);
- info->info("Wrote %d bytes", frmsz);
- Write(buf, frmsz);
- } while(frmsz == sizeof(buf));
- return;
-
-#else/*BYPASS*/
-
- iso11172_stream();
-
-#endif/*BYPASS*/
-}