diff options
-rw-r--r-- | src/AudioEncoder.cc | 29 | ||||
-rw-r--r-- | src/iso11172-1.h | 22 | ||||
-rw-r--r-- | src/liblame_wrapper.cc | 40 | ||||
-rw-r--r-- | src/liblame_wrapper.h | 5 | ||||
-rw-r--r-- | src/mov_encoder.cc | 18 | ||||
-rw-r--r-- | src/multiplexer.cc | 64 |
6 files changed, 129 insertions, 49 deletions
diff --git a/src/AudioEncoder.cc b/src/AudioEncoder.cc deleted file mode 100644 index 237dee0..0000000 --- a/src/AudioEncoder.cc +++ /dev/null @@ -1,29 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/*************************************************************************** - * AudioEncoder.cc - * - * Sat Sep 17 18:33:47 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 "AudioEncoder.h" - diff --git a/src/iso11172-1.h b/src/iso11172-1.h index e01b45b..6dda687 100644 --- a/src/iso11172-1.h +++ b/src/iso11172-1.h @@ -54,6 +54,28 @@ namespace ISO11172_1 { unsigned long long int padding:4; } pack_header; + typedef struct { + unsigned long long int reserved_byte:8; + unsigned long long int video_bound:5; + unsigned long long int marker_bit3:1; + unsigned long long int system_video_clock_flag:1; + unsigned long long int system_audio_clock_flag:1; + unsigned long long int CSPS_flag:1; + unsigned long long int fixed_flag:1; + unsigned long long int audio_bound:6; + unsigned long long int marker_bit2:1; + unsigned long long int rate_bound:22; + unsigned long long int marker_bit1:1; + unsigned long long int header_length:16; + } system_header; + + typedef struct { + unsigned long int STD_buffer_size_bound:13; + unsigned long int STD_buffer_bound_scale:1; + unsigned long int market_bits:2; + unsigned long int stream_id:8; + } stream_description; + //////////////////////////////////////////////////// // Constants //////////////////////////////////////////////////// diff --git a/src/liblame_wrapper.cc b/src/liblame_wrapper.cc index 08765b7..87b2f11 100644 --- a/src/liblame_wrapper.cc +++ b/src/liblame_wrapper.cc @@ -42,8 +42,9 @@ LibLAMEWrapper::LibLAMEWrapper(Info *i) lame_set_out_samplerate(gfp, OUTPUT_SAMPLE_RATE); lame_set_num_channels(gfp, CHANNELS); - lame_set_num_samples(gfp, 1152); + // lame_set_num_samples(gfp, 1152); // lame_set_num_samples(gfp, SAMPLES); + // lame_set_num_samples(gfp, 0); lame_set_quality(gfp, config->readInt("mp3_quality")); lame_set_mode(gfp, STEREO); @@ -87,12 +88,31 @@ LibLAMEWrapper::LibLAMEWrapper(Info *i) LibLAMEWrapper::~LibLAMEWrapper() { - lame_close(gfp); - delete audio_buffer[0]; delete audio_buffer[1]; } +Frame *LibLAMEWrapper::close(Frame *oldframe) +{ + Frame *frame = new Frame(NULL, oldframe->size + 7200); + frame->number = oldframe->number; + + memcpy(frame->data, oldframe->data, oldframe->size); + + int flush; + + flush = lame_encode_finish(gfp, frame->data + oldframe->size, 7200); + + frame->size = oldframe->size + flush; + + calc_bitrate += flush; + frame->bitrate = (unsigned int)((double)calc_bitrate / (double)(frame_number)) * 25; + + delete oldframe; + + return frame; +} + Frame *LibLAMEWrapper::encode(Frame *dvframe) { @@ -193,12 +213,19 @@ Frame *LibLAMEWrapper::encode(Frame *dvframe) * * return code = number of bytes output to mp3buf. Can be 0 */ + + int flush_sz = 0; + + /* + flush_sz = lame_encode_flush_nogap(gfp, // global context handle + mp3buf + val, // pointer to encoded MP3 stream + mp3buf_size - val); // number of valid octets in this stream + */ - int flush_sz = lame_encode_flush_nogap(gfp, // global context handle - mp3buf + val, // pointer to encoded MP3 stream - mp3buf_size - val); // number of valid octets in this stream + info->info("VAL: %d - FLUSH_SZ: %d - TOTAL: %d", val, flush_sz, (val + flush_sz)); audio_frame->size = val + flush_sz; + /* int bitrate_kbps[14]; @@ -237,5 +264,6 @@ Frame *LibLAMEWrapper::encode(Frame *dvframe) 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 b2851bf..cf8e688 100644 --- a/src/liblame_wrapper.h +++ b/src/liblame_wrapper.h @@ -43,8 +43,7 @@ #define CHANNELS 2 #define INPUT_SAMPLE_RATE 48000 #define OUTPUT_SAMPLE_RATE 48000 -#define SAMPLES AUDIO_BUFFER_SIZE -//OUTPUT_SAMPLE_RATE / 25 +#define SAMPLES OUTPUT_SAMPLE_RATE / 25 class LibLAMEWrapper { public: @@ -53,6 +52,8 @@ public: Frame *encode(Frame *dvframe); + Frame *close(Frame *dvframe); + private: unsigned long long calc_bitrate; int frame_number; diff --git a/src/mov_encoder.cc b/src/mov_encoder.cc index 4e8189c..118a338 100644 --- a/src/mov_encoder.cc +++ b/src/mov_encoder.cc @@ -97,13 +97,14 @@ void MovEncoder::thread_main() LibFAMEWrapper fame(info); // LibLAMEWrapper lame(info); - while(running) { - sem_wait(input_sem); - // Make a new instance for every frame sequence (usually 5) to ensure no // frame dependencies are broken when running multithreaded. LibLAMEWrapper lame(info); + while(running) { + sem_wait(input_sem); + + // Lock inout mutex pthread_mutex_lock(input_mutex); item = inputqueue->front(); @@ -119,16 +120,19 @@ void MovEncoder::thread_main() in_frame = item->at(cnt); // Encode video - out_v_frame = new Frame(in_frame->data, in_frame->size); - out_v_frame->number = in_frame->number; + //out_v_frame = new Frame(in_frame->data, in_frame->size); + //out_v_frame->number = in_frame->number; out_v_frame = fame.encode(in_frame); out_v_frame->number = in_frame->number; // Encode audio - out_a_frame = new Frame(in_frame->data, in_frame->size); - out_a_frame->number = in_frame->number; + //out_a_frame = new Frame(in_frame->data, in_frame->size); + //out_a_frame->number = in_frame->number; out_a_frame = lame.encode(in_frame); out_a_frame->number = in_frame->number; + + // Last frame - we need to close LAME + // if(cnt == item->size() - 1) out_a_frame = lame.close(out_a_frame); delete in_frame; diff --git a/src/multiplexer.cc b/src/multiplexer.cc index d479627..a94c150 100644 --- a/src/multiplexer.cc +++ b/src/multiplexer.cc @@ -187,7 +187,7 @@ bool Multiplexer::packet(StreamType type) if(framesize != PACKET_SIZE) return false; - written[type] += (double)PACKET_SIZE / (double)frame[type]->bitrate; + written[type] += (double)PACKET_SIZE / (double)frame[type]->size;//bitrate; return true; } @@ -235,10 +235,57 @@ bool Multiplexer::packet() 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)); + + ISO11172_1::system_header header; + unsigned long int *h_u = (unsigned long int *)&header; + unsigned long int *h_l = (unsigned long int *)(((char*)&header) + sizeof(unsigned int)); + + 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 + + *h_u = htonl(*h_u); + *h_l = htonl(*h_l); + + file->Write((char*)h_l, sizeof(*h_l)); + file->Write((char*)h_u, sizeof(*h_u)); + unsigned int *d; + + 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 + + d = (unsigned int*)&audio_stream_description; + *d = htonl(*d); + file->Write((char*)d, sizeof(*d)); + + 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 + + d = (unsigned int*)&video_stream_description; + *d = htonl(*d); + file->Write((char*)d, sizeof(*d)); + + /* // old code! // header_length (16 bits) char system_header_length[] = "\x00\x0C"; file->Write(system_header_length, SIZEOF(system_header_length)); @@ -265,7 +312,9 @@ void Multiplexer::system_header() // reserved_byte (8 bit) char reserved_byte[] = "\xFF"; file->Write(reserved_byte, SIZEOF(reserved_byte)); + */ + /* { // Audio // stream_id (8 bit) char stream_id[] = "\xC0"; @@ -289,6 +338,7 @@ void Multiplexer::system_header() char reserved_byte[] = "\xE0\x2E"; file->Write(reserved_byte, SIZEOF(reserved_byte)); } + */ } #define MASK3 0x7 @@ -355,10 +405,10 @@ bool Multiplexer::pack() ); */ unsigned int *hton_header_u = (unsigned int *)&header; - unsigned int *hton_header_l = (unsigned int *)((char*)&header + sizeof(unsigned int)); + 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); + *hton_header_u = htonl(*hton_header_u); file->Write((char*)hton_header_u, sizeof(*hton_header_u)); file->Write((char*)hton_header_l, sizeof(*hton_header_l)); @@ -401,8 +451,12 @@ void Multiplexer::multiplex() { #ifdef BYPASS + int frmsz; char buf[1024]; - while(*running) file->Write(buf, read_stream(buf, sizeof(buf), BYPASS)); + do { + frmsz = read_stream(buf, sizeof(buf), BYPASS); + file->Write(buf, frmsz); + } while(frmsz == sizeof(buf)); return; #else/*BYPASS*/ |