summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordeva <deva>2005-09-15 19:31:16 +0000
committerdeva <deva>2005-09-15 19:31:16 +0000
commit0ef298aa78a315f64a6a686407f8f10694f0ea5d (patch)
treefc593bbee27eec1118d9d86131bea0757bf429ae
parent2a6d51ad49faa39af5e627df605d3365503b5cb4 (diff)
*** empty log message ***
-rw-r--r--src/iso11172-1.h17
-rw-r--r--src/libfame_wrapper.cc17
-rw-r--r--src/libfame_wrapper.h1
-rw-r--r--src/liblame_wrapper.cc44
-rw-r--r--src/liblame_wrapper.h3
-rw-r--r--src/mov_encoder.cc6
-rw-r--r--src/multiplexer.cc148
-rw-r--r--src/multiplexer.h12
8 files changed, 208 insertions, 40 deletions
diff --git a/src/iso11172-1.h b/src/iso11172-1.h
index f284410..e01b45b 100644
--- a/src/iso11172-1.h
+++ b/src/iso11172-1.h
@@ -38,6 +38,23 @@
namespace ISO11172_1 {
////////////////////////////////////////////////////
+ // Types
+ ////////////////////////////////////////////////////
+ // 64 bits (8 bytes)
+ typedef struct {
+ unsigned long long int marker_bit5:1;
+ unsigned long long int mux_rate:22;
+ unsigned long long int marker_bit4:1;
+ unsigned long long int marker_bit3:1;
+ unsigned long long int system_clock_reference3:15;
+ unsigned long long int marker_bit2:1;
+ unsigned long long int system_clock_reference2:15;
+ unsigned long long int marker_bit1:1;
+ unsigned long long int system_clock_reference1:3;
+ unsigned long long int padding:4;
+ } pack_header;
+
+ ////////////////////////////////////////////////////
// Constants
////////////////////////////////////////////////////
const char pack_start_code[] = "\x00\x00\x01\xBA";
diff --git a/src/libfame_wrapper.cc b/src/libfame_wrapper.cc
index 94989f1..5c71154 100644
--- a/src/libfame_wrapper.cc
+++ b/src/libfame_wrapper.cc
@@ -49,7 +49,8 @@ LibFAMEWrapper::LibFAMEWrapper(Info *i)
yuv.v = new unsigned char [w*h];// [w*h/4]
calc_bitrate = 0;
-
+ frame_number = 0;
+
////////////LIBDV STUFF///////////////
dvdecoder = NULL; // Initialize in encode method
@@ -99,7 +100,7 @@ LibFAMEWrapper::LibFAMEWrapper(Info *i)
fame_par.quality = config->readInt("frame_quality");
// Bitrate
- fame_par.bitrate = 0; // video bitrate (0=VBR)
+ fame_par.bitrate = 150000; // video bitrate in bytes pr second (0=VBR)
// slices_per_frame is the number of frame slices per frame. More slices provide
// better error recovery. There must be at least one slice per frame, and at most
@@ -226,8 +227,6 @@ Frame *LibFAMEWrapper::encode(Frame *dvframe)
// Allocate a new frame for the output
Frame *output = new Frame(NULL, FAME_BUFFER_SIZE);
- fame_frame_statistics_t stats;
-
// Init frame params
dv_get_timestamp(dvdecoder, output->timecode); // Set timecode
output->size = 0; // Init size (incremented as we read)
@@ -242,7 +241,10 @@ Frame *LibFAMEWrapper::encode(Frame *dvframe)
pt += written;
output->size += written;
}
- fame_end_frame(fame_context, &stats);
+
+ // fame_frame_statistics_t stats;
+
+ // fame_end_frame(fame_context, &stats);
/*
info->info("frame_number: %d, coding: %c, target_bits: %d, actual_bits: %d, spatial_activity: %d, quant_scale: %f",
stats.frame_number,
@@ -262,8 +264,9 @@ Frame *LibFAMEWrapper::encode(Frame *dvframe)
float quant_scale;
}
*/
- calc_bitrate += stats.actual_bits;
- output->bitrate = (unsigned int)(((double)calc_bitrate / (double)(stats.frame_number+1)) * 25.0);
+ frame_number++;
+ calc_bitrate += output->size; //stats.actual_bits;
+ output->bitrate = (unsigned int)((double)calc_bitrate / (double)frame_number) * 25;
return output;
}
diff --git a/src/libfame_wrapper.h b/src/libfame_wrapper.h
index 6a6b569..bf9e7b9 100644
--- a/src/libfame_wrapper.h
+++ b/src/libfame_wrapper.h
@@ -50,6 +50,7 @@ public:
private:
unsigned long long calc_bitrate;
+ unsigned int frame_number;
Info* info;
diff --git a/src/liblame_wrapper.cc b/src/liblame_wrapper.cc
index 6d78380..08765b7 100644
--- a/src/liblame_wrapper.cc
+++ b/src/liblame_wrapper.cc
@@ -42,7 +42,8 @@ LibLAMEWrapper::LibLAMEWrapper(Info *i)
lame_set_out_samplerate(gfp, OUTPUT_SAMPLE_RATE);
lame_set_num_channels(gfp, CHANNELS);
- lame_set_num_samples(gfp, SAMPLES);
+ lame_set_num_samples(gfp, 1152);
+ // lame_set_num_samples(gfp, SAMPLES);
lame_set_quality(gfp, config->readInt("mp3_quality"));
lame_set_mode(gfp, STEREO);
@@ -79,6 +80,9 @@ LibLAMEWrapper::LibLAMEWrapper(Info *i)
// And now for the dv decoder!
decoder = NULL;
+
+ calc_bitrate = 0;
+ frame_number = 0;
}
LibLAMEWrapper::~LibLAMEWrapper()
@@ -195,9 +199,43 @@ Frame *LibLAMEWrapper::encode(Frame *dvframe)
mp3buf_size - val); // number of valid octets in this stream
audio_frame->size = val + flush_sz;
+ /*
+
+ int bitrate_kbps[14];
+ // lame_bitrate_kbps(gfp, bitrate_kbps);
+ lame_bitrate_hist(gfp, bitrate_kbps);
+ // 32 40 48 56 64 80 96 112 128 160 192 224 256 320
+ info->info("%d %d %d %d %d %d %d %d %d %d %d %d %d %d",
+ bitrate_kbps[0],
+ bitrate_kbps[1],
+ bitrate_kbps[2],
+ bitrate_kbps[3],
+ bitrate_kbps[4],
+ bitrate_kbps[5],
+ bitrate_kbps[6],
+ bitrate_kbps[7],
+ bitrate_kbps[8],
+ bitrate_kbps[9],
+ bitrate_kbps[10],
+ bitrate_kbps[11],
+ bitrate_kbps[12],
+ bitrate_kbps[13]);
+ */
+ // while(frame_number != lame_get_frameNum(gfp)) {
+
+ calc_bitrate += audio_frame->size;//lame_get_framesize(gfp);
+ frame_number ++;//= 1;//lame_get_frameNum(gfp);
+
+ // info->info("lame_get_frameNum(gfp) %d ?= frame_number %d", lame_get_frameNum(gfp), frame_number);
+ // }
// Bits pr. second
- audio_frame->bitrate = config->readInt("mp3_bitrate") * 1000;
-
+ // 25 * 7 frames pr.second (it seems!)
+ audio_frame->bitrate = (unsigned int)((double)calc_bitrate / (double)(frame_number)) * 25;
+ /*
+ info->info("Audio size: %d, bitrate: %.4f",
+ audio_frame->bitrate,
+ (float)(config->readInt("mp3_bitrate") * 1000)/(float)(audio_frame->bitrate));
+ */
return audio_frame;
}
diff --git a/src/liblame_wrapper.h b/src/liblame_wrapper.h
index 75f3b3d..b2851bf 100644
--- a/src/liblame_wrapper.h
+++ b/src/liblame_wrapper.h
@@ -54,6 +54,9 @@ public:
Frame *encode(Frame *dvframe);
private:
+ unsigned long long calc_bitrate;
+ int frame_number;
+
Info *info;
// LAME stuff
diff --git a/src/mov_encoder.cc b/src/mov_encoder.cc
index a9a2ca2..4e8189c 100644
--- a/src/mov_encoder.cc
+++ b/src/mov_encoder.cc
@@ -165,5 +165,11 @@ void MovEncoder::thread_main()
}
}
+ // Kick multiplexer (audio)
+ sem_post(audio_output_sem);
+
+ // Kick multiplexer (video)
+ sem_post(video_output_sem);
+
info->info("MovEncoder thread has stopped.");
}
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
diff --git a/src/multiplexer.h b/src/multiplexer.h
index 25c89e0..c0ac663 100644
--- a/src/multiplexer.h
+++ b/src/multiplexer.h
@@ -40,7 +40,7 @@
* Multiplexer configuration
*/
// How many packets should we put in one pack
-#define NUMBER_OF_PACKETS_IN_A_PACK 3
+#define PACKETS_PER_PACK 3
// How many packets bewteen audio packs
#define AUDIO_PACKET_FREQUENCY 10
@@ -49,7 +49,7 @@
#define SYSTEM_HEADER_FREQUENCY 5
// Size of video or audio data pr. packet
-#define PACKET_SIZE 2048
+#define PACKET_SIZE 2028
/**
* Other stuff
@@ -74,13 +74,15 @@ public:
void multiplex();
private:
+ unsigned long long int SCR;
+
double written[NUM_TYPES];
void iso11172_stream();
- void pack();
+ bool pack();
void system_header();
- void packet();
- void packet(StreamType type);
+ bool packet();
+ bool packet(StreamType type);
/*
void audio_packet();
void video_packet();