diff options
| author | deva <deva> | 2005-09-15 19:31:16 +0000 | 
|---|---|---|
| committer | deva <deva> | 2005-09-15 19:31:16 +0000 | 
| commit | 0ef298aa78a315f64a6a686407f8f10694f0ea5d (patch) | |
| tree | fc593bbee27eec1118d9d86131bea0757bf429ae | |
| parent | 2a6d51ad49faa39af5e627df605d3365503b5cb4 (diff) | |
*** empty log message ***
| -rw-r--r-- | src/iso11172-1.h | 17 | ||||
| -rw-r--r-- | src/libfame_wrapper.cc | 17 | ||||
| -rw-r--r-- | src/libfame_wrapper.h | 1 | ||||
| -rw-r--r-- | src/liblame_wrapper.cc | 44 | ||||
| -rw-r--r-- | src/liblame_wrapper.h | 3 | ||||
| -rw-r--r-- | src/mov_encoder.cc | 6 | ||||
| -rw-r--r-- | src/multiplexer.cc | 148 | ||||
| -rw-r--r-- | src/multiplexer.h | 12 | 
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(); | 
