diff options
| -rw-r--r-- | src/libfame_wrapper.cc | 12 | ||||
| -rw-r--r-- | src/liblame_wrapper.cc | 78 | ||||
| -rw-r--r-- | src/liblame_wrapper.h | 12 | ||||
| -rw-r--r-- | src/mov_encoder.cc | 19 | ||||
| -rw-r--r-- | src/mov_encoder.h | 7 | ||||
| -rw-r--r-- | src/mov_encoder_writer.cc | 133 | ||||
| -rw-r--r-- | src/mov_encoder_writer.h | 7 | 
7 files changed, 231 insertions, 37 deletions
| diff --git a/src/libfame_wrapper.cc b/src/libfame_wrapper.cc index ab60b36..64eb9f5 100644 --- a/src/libfame_wrapper.cc +++ b/src/libfame_wrapper.cc @@ -31,6 +31,9 @@  /*   * $Log$ + * Revision 1.2  2005/07/05 23:15:16  deva + * *** empty log message *** + *   * Revision 1.1  2005/07/02 11:39:51  deva   * Added some audiocode.   * Moved libfame code out of mov_encoder @@ -68,17 +71,8 @@ LibFAMEWrapper::LibFAMEWrapper(Info *i)    /////////LIBFAME STUFF///////////    // Allocate the output buffer. -  //  fame_buffer = new unsigned char [FAME_BUFFER_SIZE]; -  /* -  // Open output file -  f=fopen(filename, "wb"); -  if(!f) { -    fprintf(stderr, "Failed to open output file [%s] due to the following error: %s", filename, strerror(errno)); -    return; -  } -  */    // Open a new session of the fame library.    // (If initialization was successful, it returns a non-null context which     // can then be used for subsequent library calls.) diff --git a/src/liblame_wrapper.cc b/src/liblame_wrapper.cc index 751c41b..7af9b68 100644 --- a/src/liblame_wrapper.cc +++ b/src/liblame_wrapper.cc @@ -31,6 +31,9 @@  /*   * $Log$ + * Revision 1.2  2005/07/05 23:15:16  deva + * *** empty log message *** + *   * Revision 1.1  2005/07/02 11:39:51  deva   * Added some audiocode.   * Moved libfame code out of mov_encoder @@ -45,25 +48,45 @@ LibLAMEWrapper::LibLAMEWrapper(Info *i)    info = i;    // Init library. -  lamegf = lame_init(); -  if(!lamegf) { +  if( (gfp = lame_init()) == NULL) {      info->error("LAME initialization failed (due to malloc failure!)"); +    return;    } -  lame_init_params(lamegf); +	lame_set_in_samplerate(gfp, SAMPLE_RATE); +	lame_set_out_samplerate(gfp, SAMPLE_RATE); +	lame_set_num_channels(gfp, CHANNELS); +	// lame 3.91 dies on quality != 5 +	lame_set_quality(gfp, 5); +	// lame 3.91 doesn't work in mono +	lame_set_mode(gfp, STEREO); +	lame_set_brate(gfp, 192); +  lame_set_strict_ISO(gfp, 1); + +	if (lame_init_params(gfp) < 0) { +    info->error("LAME parameter initialization failed."); +    return; +  } -  decoder = NULL; +  lame_init_bitstream(gfp);    audio_buffer[0] = new int16_t[AUDIO_BUFFER_SIZE];    audio_buffer[1] = new int16_t[AUDIO_BUFFER_SIZE]; +  audio_buffer[2] = new int16_t[AUDIO_BUFFER_SIZE]; +  audio_buffer[3] = new int16_t[AUDIO_BUFFER_SIZE]; +  // And now for the dv decoder! +  decoder = NULL;  }  LibLAMEWrapper::~LibLAMEWrapper()  { +  lame_close(gfp); +    delete audio_buffer[0];    delete audio_buffer[1]; - +  delete audio_buffer[2]; +  delete audio_buffer[3];  }  Frame *LibLAMEWrapper::encode(Frame *dvframe) @@ -90,12 +113,17 @@ Frame *LibLAMEWrapper::encode(Frame *dvframe)     */    //  int n, i;    //  int16_t* s = ( int16_t * ) sound; +    dv_decode_full_audio( decoder, dvframe->data, audio_buffer );    /* -  for ( n = 0; n < SAMPLES; ++n ) -    for ( i = 0; i < CHANNELS; i++ ) -      *s++ = audio_buffer[ i ][ n ]; -      */ +  memset(audio_buffer[0], 0, sizeof(audio_buffer[0])); +  memset(audio_buffer[1], 0, sizeof(audio_buffer[1])); +  */ +  /* +    for ( n = 0; n < SAMPLES; ++n ) +      for ( i = 0; i < CHANNELS; i++ ) +        *s++ = audio_buffer[ i ][ n ]; +    */  /*   * input pcm data, output (maybe) mp3 frames. @@ -104,6 +132,9 @@ Frame *LibLAMEWrapper::encode(Frame *dvframe)   * The required mp3buf_size can be computed from num_samples,    * samplerate and encoding rate, but here is a worst case estimate:   * + * return code     number of bytes output in mp3buffer.  can be 0  + *                 if return code = -1:  mp3buffer was too small + *   * mp3buf_size in bytes = 1.25*num_samples + 7200   *   * I think a tighter bound could be:  (mt, March 2000) @@ -127,12 +158,12 @@ Frame *LibLAMEWrapper::encode(Frame *dvframe)    Frame* audio_frame = new Frame(NULL, (int)(1.25 * SAMPLES + 7200));    const short int     *buffer_l = audio_buffer[0];   // PCM data for left channel -  const short int     *buffer_r = audio_buffer[0];   // PCM data for right channel +  const short int     *buffer_r = audio_buffer[1];   // PCM data for right channel    const int           nsamples = SAMPLES;      // number of samples per channel    unsigned char*      mp3buf = audio_frame->data;        // pointer to encoded MP3 stream    const int           mp3buf_size = audio_frame->size;   // number of valid octets in this -  int val = lame_encode_buffer(lamegf, buffer_l, buffer_r, nsamples, mp3buf, mp3buf_size); +  int val = lame_encode_buffer(gfp, buffer_l, buffer_r, nsamples, mp3buf, mp3buf_size);    if(val < 0) {      switch(val) { @@ -154,5 +185,30 @@ Frame *LibLAMEWrapper::encode(Frame *dvframe)      }    } +  /* +  val = lame_encode_flush(gfp, mp3buf, val); + +  if(val < 0) { +    switch(val) { +    case -1:  // mp3buf was too small +      info->error("Lame encoding failed (during flush), mp3buf was too small."); +      break; +    case -2:  // malloc() problem +      info->error("Lame encoding failed (during flush), due to malloc() problem."); +      break; +    case -3:  // lame_init_params() not called +      info->error("Lame encoding failed (during flush), lame_init_params() not called."); +      break; +    case -4:  // psycho acoustic problems  +      info->error("Lame encoding failed (during flush), due to psycho acoustic problems."); +      break; +    default: +      info->error("Lame encoding failed (during flush), due to unknown error."); +      break; +    } +  } +  */ +  audio_frame->size = val; +    return audio_frame;  } diff --git a/src/liblame_wrapper.h b/src/liblame_wrapper.h index 2d3a769..f30cb9c 100644 --- a/src/liblame_wrapper.h +++ b/src/liblame_wrapper.h @@ -31,6 +31,9 @@  /*   * $Log$ + * Revision 1.2  2005/07/05 23:15:16  deva + * *** empty log message *** + *   * Revision 1.1  2005/07/02 11:39:51  deva   * Added some audiocode.   * Moved libfame code out of mov_encoder @@ -52,8 +55,9 @@  #include "info.h"  #define CHANNELS 2 -#define SAMPLES 44100 -#define AUDIO_BUFFER_SIZE SAMPLES/25*sizeof(int16_t) +#define SAMPLE_RATE 48000 +#define SAMPLES SAMPLE_RATE / 25 +#define AUDIO_BUFFER_SIZE DV_AUDIO_MAX_SAMPLES  class LibLAMEWrapper {  public: @@ -66,11 +70,11 @@ private:    Info *info;    // LAME stuff -  lame_global_flags *lamegf; +  lame_global_flags *gfp;    // libdv stuff    dv_decoder_t *decoder; -  int16_t *audio_buffer[2]; +  int16_t *audio_buffer[4];  }; diff --git a/src/mov_encoder.cc b/src/mov_encoder.cc index 38622c6..fa83830 100644 --- a/src/mov_encoder.cc +++ b/src/mov_encoder.cc @@ -39,6 +39,9 @@  /*   * $Log$ + * Revision 1.34  2005/07/05 23:15:16  deva + * *** empty log message *** + *   * Revision 1.33  2005/07/02 11:39:52  deva   * Added some audiocode.   * Moved libfame code out of mov_encoder @@ -144,8 +147,8 @@ MovEncoder::MovEncoder(sem_t *r_sem,    info = i;    info->info("MovEncoder"); -  fame = new LibFAMEWrapper(info); -  lame = new LibLAMEWrapper(info); +  //  fame = new LibFAMEWrapper(info); +  //  lame = new LibLAMEWrapper(info);    running = true; @@ -165,8 +168,8 @@ MovEncoder::~MovEncoder()  {    info->info("~MovEncoder"); -  delete fame; -  delete lame; +  //  delete fame; +  //  delete lame;  }  // this runs in a thread @@ -185,9 +188,13 @@ void MovEncoder::thread_main()    Frame *out_v_frame;    Frame *out_a_frame; +  LibFAMEWrapper fame(info); +    while(running) {      sem_wait(input_sem); +    LibLAMEWrapper lame(info); +      // Lock inout mutex      pthread_mutex_lock(input_mutex);      item = inputqueue->front(); @@ -203,11 +210,11 @@ void MovEncoder::thread_main()          in_frame = item->at(cnt);          // Encode video -        out_v_frame = fame->encode(in_frame); +        out_v_frame = fame.encode(in_frame);          out_v_frame->number = in_frame->number+1;          // Encode audio -        out_a_frame = lame->encode(in_frame); +        out_a_frame = lame.encode(in_frame);          out_a_frame->number = in_frame->number;          delete in_frame; diff --git a/src/mov_encoder.h b/src/mov_encoder.h index a54b145..1be2ac5 100644 --- a/src/mov_encoder.h +++ b/src/mov_encoder.h @@ -36,6 +36,9 @@  /*   * $Log$ + * Revision 1.15  2005/07/05 23:15:16  deva + * *** empty log message *** + *   * Revision 1.14  2005/07/02 11:39:52  deva   * Added some audiocode.   * Moved libfame code out of mov_encoder @@ -108,8 +111,8 @@ public:    volatile bool running;  private: -  LibFAMEWrapper *fame; -  LibLAMEWrapper *lame; +  //  LibFAMEWrapper *fame; +  //  LibLAMEWrapper *lame;    Info *info; diff --git a/src/mov_encoder_writer.cc b/src/mov_encoder_writer.cc index e1179b9..7f982de 100644 --- a/src/mov_encoder_writer.cc +++ b/src/mov_encoder_writer.cc @@ -31,6 +31,9 @@  /*   * $Log$ + * Revision 1.9  2005/07/05 23:15:16  deva + * *** empty log message *** + *   * Revision 1.8  2005/06/30 10:04:35  deva   * *** empty log message ***   * @@ -134,11 +137,11 @@ void MovEncoderWriter::thread_main()    Frame *frame; +  write_multiplex_header(); +    while(running) {      sem_wait(sem); -    //    int poolsize; -      // Lock output mutex      pthread_mutex_lock(mutex);      frame = queue->top(); @@ -150,7 +153,7 @@ void MovEncoderWriter::thread_main()      int wrote = 0;      while(frame && (frame->number == frame_number)) { -      int ret; +      int ret = 0;        ret = file->Write(frame->data, frame->size);        frame_number++; @@ -171,9 +174,129 @@ void MovEncoderWriter::thread_main()        pthread_mutex_unlock(mutex);        // Unlock output mutex      } - -    //    info->info("Wrote %d frames, pool size %d - exp: %d", wrote, poolsize, frame_number);    }    info->info("MovEncoderWriter::stop");  } + + +/** + *  Byte#      Data                Details + *  =================================================================== + *  1-4        Sequence header     In Hex 000001B3 + *             code + *  12 bits    Horizontal size     In pixels + *  12 bits    Vertical size       In pixels + *   4 bits    Pel aspect ratio    See below + *  18 bits    Frame rate          See below + *   1 bit     Marker bit          Always 1 + *  10 bits    VBV buffer size     Minimum buffer needed to decode this + *                                 sequence of pictures; in 16KB units + *   1 bit     Constrained + *             parameter flag + *   1 bit     Load intra          0: false; 1: true (matrix follows) + *             quantizer matrix + *  64 bytes   Intra quantizer     Optional + *             matrix + *   1 bit     Load nonintra       0: false; 1: true (matrix follows) + *             quantizer matrix + *  64 bytes   Nonintra quantizer  Optional + *             matrix + *   -         Squence extension   Optional + *             Data + *   -         User data           Optional application-dependent data + *  =================================================================== + */ +/** + *  Pel aspect ratio: + *  The actual height of a 12 pixels wide area (normal is 12 = square) + *   Aspect Ratio (from http://homepage.mac.com/rnc/EditMpegHeaderIFO.html) + *   1 = 1:1 + *   2 = 4:3 + *   3 = 16:9 + *   4 = 2.211 (not used in dvd) + *  12 = unknown (or undefined!) + */ + +/** + *  Frame rates: + *  1 = 23.976 frames/sec + *  2 = 24 + *  3 = 25 + *  4 = 29.97 + *  5 = 30 + *  6 = 50 + *  7 = 59.94 + *  8 = 60 + */ +void MovEncoderWriter::write_video_header() +{ +  char header[] = { +    0x00, 0x00, 0x01, 0xB3, // Header +    0x2D, 0x02, 0x40, // 12 bits width, 12 bits height - 720 (hex: 2D0) x 576 (hex: 240) +    0x23, // 4 bits aspect (12 (hex C) works!) 4 bits frameratecode - 3 := 25fps (hex: 3) +    0x00, 0x00, // Bitrate - 0 (hex : 0) +    0x20, 0xA5, 0x10, 0x12, 0x12, 0x14, +    0x14, 0x14, 0x16, 0x16, 0x16, 0x16, 0x18, 0x18, 0x19, 0x18, 0x18, 0x1A, 0x1B, 0x1B, 0x1B, 0x1B, +    0x1A, 0x1C, 0x1D, 0x1E, 0x1E, 0x1E, 0x1D, 0x1C, 0x1E, 0x1F, 0x20, 0x21, 0x21, 0x20, 0x1F, 0x1E, +    0x21, 0x23, 0x23, 0x24, 0x23, 0x23, 0x21, 0x25, 0x26, 0x27, 0x27, 0x26, 0x25, 0x29, 0x2A, 0x2A, +    0x2A, 0x29, 0x2D, 0x2D, 0x2D, 0x2D, 0x30, 0x31, 0x30, 0x34, 0x34, 0x38, 0x16, 0x00, 0xF0, 0xC4, +    0x00, 0x00, 0x01, 0xB8, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0A, 0x72, 0x00, +    0x00, 0x00, 0x01, 0x01, 0x13, 0xF9, 0x50, 0x02, 0xBC, 0xB2, 0xB8, 0xBE, 0x68, 0x8B, 0xA4, 0x9F, +    0xC5, 0xB5, 0xCA, 0x00, 0x56, 0x76, 0x39, 0x65, 0xF2, 0x30, 0x8B, 0xA6, 0x9D, 0x50, 0x69, 0xE7, +    0xDA, 0xFE, 0x13, 0xCF, 0xB7, 0xFF, 0x8F, 0xF4, 0xCE, 0x7B, 0xFA, 0x0E, 0xF0, 0x66, 0xAE, 0x1C, +    0x5D, 0xE7, 0x00, 0xC8, 0x0A, 0x92, 0xB9, 0x29, 0x3C, 0x21, 0x23, 0xF1, 0xD6, 0x40, 0x13, 0x06, +    0xF0, 0x10, 0x10, 0xC6, 0x27, 0x80, 0xA0, 0x34, 0xE1, 0xC8, 0xE4, 0x0F, 0x74, 0x91, 0xDA, 0xC4, +    0x03, 0xA0, 0xDC, 0x03, 0x12, 0x60, 0x18, 0x49, 0x27, 0x1D, 0xD4, 0xBC, 0x67, 0x0E, 0x54, 0x8C, +    0x96, 0xFC, 0x5D, 0xC0, 0x06, 0xE0, 0x1A, 0x72, 0x11, 0x7C, 0x9A, 0x8D, 0xC9, 0x45, 0x89, 0x6D, +    0xCD, 0xC4, 0x0B, 0x63, 0xDC, 0x90, 0x18, 0x24, 0x00, 0xEC, 0x84, 0x90, 0x18, 0x10, 0xC9, 0x3B, +    0x1E, 0xA7, 0x60, 0x3C, 0x9D, 0x74, 0x80, 0x76, 0x05, 0x0B, 0x02, 0x81, 0xA9, 0x29, 0x39, 0x68, +    0x53, 0x8F, 0x59, 0xF1, 0xBF, 0x93, 0xFB, 0xA0, 0x04, 0x01, 0xBC, 0xB0, 0xCE, 0x18, 0xE1, 0x25 +  }; + +  file->Write(header, sizeof(header)); + +   +} +/* +4449 0433 0000 0000 +*/ +void MovEncoderWriter::write_audio_header() +{ +  char header[] = { +    0x44, 0x49, 0x04, 0x33,  +    0x00, 0x00, 0x00, 0x00 +  }; + +  file->Write(header, sizeof(header)); +} + +void MovEncoderWriter::write_multiplex_header() +{ +  char header[] = { +    0x00, 0x00, 0xba, 0x01,  +    0x00,  +    0x21, 0x00, 0x01, 0x80, 0x19, 0x8d, 0x0a,  +    0x00, 0x00, 0xbb, 0x01, +    0x0c, 0x00, 0x0a, 0x80, 0x06, 0x8d, 0xff, 0xe1, 0xe0, 0xe0, 0xc0, 0x25, 0x20, 0xc0a, 0x00, 0x00, +    0xba, 0x01, 0x00, 0x21, 0x15, 0x01, 0x80, 0x6d, 0x8d, 0x0a +    /* +    0x00, 0x00, 0xe0, 0x01a, 0x3d, 0x04, +    0x25, 0x60, 0x00, 0x31, 0xd7, 0x03, 0x11, 0x8f, 0x03, 0x00, 0x19, 0xc0, 0x00, 0x00a, 0xb3, 0x01, +    0x00, 0x16, 0xc4, 0xf0, 0x38, 0x01, 0x85, 0xa0, 0x11, 0x10, 0x12, 0x11, 0x12, 0x12a, 0x13, 0x13, +    0x13, 0x13, 0x14, 0x14, 0x14, 0x14, 0x15, 0x14, 0x15, 0x15, 0x15, 0x15, 0x16, 0x15a, 0x16, 0x16, +    0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x18, 0x18a, 0x19, 0x18, +    0x18, 0x18, 0x19, 0x18, 0x1a, 0x1a, 0x1a, 0x1a, 0x1b, 0x19, 0x1b, 0x1b, 0x1b, 0x1ba, 0x1c, 0x1c, +    0x1c, 0x1c, 0x1e, 0x1e, 0x1f, 0x1e, 0x21, 0x1f, 0x00, 0x00, 0xb2, 0x01, 0x87, 0x00a, 0x00, 0x81, +    0x65, 0x26, 0x63, 0x6e, 0x64, 0x6f, 0x64, 0x65, 0x62, 0x20, 0x20, 0x79, 0x4d, 0x54a, 0x47, 0x50, +    0x6e, 0x45, 0x20, 0x63, 0x76, 0x28, 0x72, 0x65, 0x20, 0x2e, 0x2e, 0x32, 0x32, 0x35a, 0x2e, 0x31, +    0x38, 0x35, 0x31, 0x2e, 0x39, 0x36, 0x00, 0x29, 0x00, 0x00, 0xb8, 0x01, 0xab, 0x00a, 0x20, 0x22, +    0x00, 0x00, 0x00, 0x01, 0x8d, 0x00, 0x78, 0x09, 0x00, 0x00, 0x01, 0x01, 0xf9, 0x1ba, 0x20, 0xf8, +    0x02, 0x5e, 0xa1, 0x18, 0x11, 0x30, 0x70, 0xfe, 0xd3, 0x00, 0x4c, 0xdf, 0x84, 0x02a, 0x30, 0xd0, +    0x9e, 0x5b, 0x77, 0x81, 0x41, 0xcc, 0xf4, 0x02, 0xc5, 0x10, 0x40, 0x08, 0xf3, 0x8fa, 0x06, 0x80, +    0xfa, 0x9e, 0xe7, 0x95, 0x3c, 0x80, 0x09, 0xc1, 0x20, 0xbd, 0xbf, 0x07, 0xd0, 0xe2a, 0xaa, 0x62 +    */ +  }; + +  file->Write(header, sizeof(header)); +} diff --git a/src/mov_encoder_writer.h b/src/mov_encoder_writer.h index 6419b25..63ddec4 100644 --- a/src/mov_encoder_writer.h +++ b/src/mov_encoder_writer.h @@ -31,6 +31,9 @@  /*   * $Log$ + * Revision 1.5  2005/07/05 23:15:16  deva + * *** empty log message *** + *   * Revision 1.4  2005/06/16 21:28:57  deva   * Rewrote thread object   * Fixed bug in mov_encoder (pushed read_sem too many times, whihc lead to @@ -83,6 +86,10 @@ private:    sem_t *sem;    unsigned int frame_number; + +  void write_audio_header(); +  void write_video_header(); +  void write_multiplex_header();  }; | 
