diff options
| author | deva <deva> | 2005-07-02 11:39:51 +0000 | 
|---|---|---|
| committer | deva <deva> | 2005-07-02 11:39:51 +0000 | 
| commit | 91e9b782cc9ea0252ab2b211b15e8da4a3043d5f (patch) | |
| tree | 335f800ae82b1385b6eb635d34ccc4a84be0a2d9 /src | |
| parent | 55c83847016699a18006f9f728076ab9cd2d873b (diff) | |
Added some audiocode.
Moved libfame code out of mov_encoder
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile.am | 4 | ||||
| -rw-r--r-- | src/libfame_wrapper.cc | 265 | ||||
| -rw-r--r-- | src/libfame_wrapper.h | 80 | ||||
| -rw-r--r-- | src/liblame_wrapper.cc | 158 | ||||
| -rw-r--r-- | src/liblame_wrapper.h | 77 | ||||
| -rw-r--r-- | src/miav_config.cc | 489 | ||||
| -rw-r--r-- | src/miav_config.h | 42 | ||||
| -rw-r--r-- | src/mov_encoder.cc | 251 | ||||
| -rw-r--r-- | src/mov_encoder.h | 35 | ||||
| -rw-r--r-- | src/mov_encoder_thread.cc | 6 | 
10 files changed, 1018 insertions, 389 deletions
| diff --git a/src/Makefile.am b/src/Makefile.am index 0afb24a..a611de5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -19,6 +19,8 @@ miav_SOURCES = $(shell  if [ $QT_CXXFLAGS ] ; then ../tools/MocList cc; fi ) \  	info.cc \  	info_console.cc \  	info_gui.cc \ +	libfame_wrapper.cc \ +	liblame_wrapper.cc \  	mainwindow.cc \  	messagebox.cc \  	miav.cc \ @@ -52,6 +54,8 @@ EXTRA_DIST = \  	info.h \  	info_console.h \  	info_gui.h \ +	libfame_wrapper.h \ +	liblame_wrapper.h \  	mainwindow.h \  	messagebox.h \  	miav.h \ diff --git a/src/libfame_wrapper.cc b/src/libfame_wrapper.cc new file mode 100644 index 0000000..ab60b36 --- /dev/null +++ b/src/libfame_wrapper.cc @@ -0,0 +1,265 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            libfame_wrapper.cc + * + *  Sat Jul  2 11:11:31 CEST 2005 + *  Copyright  2005 Bent Bisballe + *  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. + */ + +/* + * $Id$ + */ + +/* + * $Log$ + * Revision 1.1  2005/07/02 11:39:51  deva + * Added some audiocode. + * Moved libfame code out of mov_encoder + * + */ + +#include <config.h> +#include "libfame_wrapper.h" + +#include <errno.h> + +#include "miav_config.h" +#include "frame.h" + +LibFAMEWrapper::LibFAMEWrapper(Info *i) +{ +  info = i; +   +  // FIXME: Hmmm... should this be detected somewhere?! +  int w = 720; +  int h = 576; + +  // Initialize yuv structure. +  yuv.w = w; +  yuv.h = h; +  yuv.p = w; +  yuv.y = new unsigned char [w*h * 2]; +  yuv.u = new unsigned char [w*h];// [w*h/4] +  yuv.v = new unsigned char [w*h];// [w*h/4] + +  ////////////LIBDV STUFF/////////////// +   +  dvdecoder = NULL; // Initialize in encode method + +  /////////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.) +  fame_context = fame_open(); +  if(!fame_context) { +    info->error("Unable to open FAME context, due to the following error: %s", strerror(errno)); +    return; +  } + +  /* +  typedef struct _fame_parameters_ { +    int width;                        // width of the video sequence +    int height;                       // height of the video sequence +    char const *coding;               // coding sequence +    int quality;                      // video quality +    int slices_per_frame;             // number of slices per frame +    unsigned int frames_per_sequence; // number of frames per sequence +    int frame_rate_num;               // numerator of frames per second +    int frame_rate_den;               // denominator of frames per second +    unsigned int shape_quality;       // binary shape quality +    unsigned int search_range;        // motion estimation search range +    unsigned char verbose;            // verbosity +  } fame_parameters_t; +  */ +  // width and height specify the size of each frames of the video sequence.  +  // Both must be multiple of 16. width and height must be less than 4096x4096 +  fame_par.width = 720; +  fame_par.height = 576; + +  // coding is a string of I, P or B characters representing the sequence of  +  // frames the encoder must produce. I frames are intra-coded frames (similar  +  // to JPEG), whereas P and B frames are motion compressed, respectively  +  // predicted from past reference (I or P) frame, or bidirectionally predicted  +  // from past and future reference frame. +  fame_par.coding = config->readString("frame_sequence")->c_str(); + +  // quality is a percentage, which controls compression versus quality. +  fame_par.quality = config->readInt("frame_quality"); + +  // Bitrate +  fame_par.bitrate = 0; // video bitrate (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  +  // height / 16 +  fame_par.slices_per_frame = 1;//fame_par.height / 16; + +  // frames_per_sequence is the maximum number of frames contained in a video  +  // sequence. +  fame_par.frames_per_sequence = 0xffffffff; // Unlimited length + +  // frame_rate_num/frame_rate_den specify the number of frames per second for  +  // playback. +  fame_par.frame_rate_num = 25; // 25 / 1 fps = 25 fps +  fame_par.frame_rate_den = 1; + +  // shape_quality is percentage determing the average binary shape accuracy in  +  // video with arbitrary shape. +  fame_par.shape_quality = 100; // Original shape + +  // search_range specifies the motion estimation search range in pixel unit.  +  // Small search ranges work best with slow motion videos, whereas larger search  +  // ranges are rather for fast motion videos. +  fame_par.search_range = 0; // Adaptive search range + +  // verbose when set to 1 outputs information on copyright, modules used and  +  // current frame on standard error. +  fame_par.verbose = 0; + +  static const char profilename[] = "MIaV\0"; +  fame_par.profile = profilename;              // profile name +  fame_par.total_frames = 0;        // total number of frames + +  if(strcmp(config->readString("encoding_codec")->c_str(), "mpeg4") == 0) { + +    info->info("Using mpeg4 compression."); +    fame_object_t *object; +     +    object = fame_get_object(fame_context, "profile/mpeg4/simple"); +    if(object) fame_register(fame_context, "profile", object); + +  } else if(strcmp(config->readString("encoding_codec")->c_str(), "mpeg1") == 0) { + +    info->info("Using mpeg1 compression."); +    fame_object_t *object; +     +    object = fame_get_object(fame_context, "profile/mpeg1"); +    if(object) fame_register(fame_context, "profile", object); + +  } else if(strcmp(config->readString("encoding_codec")->c_str(), "mpeg1") == 0) { +  } else { +    info->info("Using default (mpeg1) compression."); +  } + +  fame_init(fame_context, &fame_par, fame_buffer, FAME_BUFFER_SIZE); +} + +LibFAMEWrapper::~LibFAMEWrapper() +{ +  delete [] yuv.y; +  delete [] yuv.u; +  delete [] yuv.v; +} + +Frame *LibFAMEWrapper::encode(Frame *dvframe) +{ +  //  if(!f) return; // The file was not opened. + +  // Decode DV Frame to YUV422 +  int w = 720; +  int h = 576; + +  unsigned char *pixels[3]; +  int pitches[3]; + +  if(!dvdecoder) { +    dvdecoder = dv_decoder_new(FALSE/*this value is unused*/, FALSE, FALSE); +    dvdecoder->quality = DV_QUALITY_BEST; + +    dv_parse_header(dvdecoder, dvframe->data); +    //dv_parse_packs(decoder, frame->data); // Not needed anyway! +     +    dvdecoder->system = e_dv_system_625_50;  // PAL lines, PAL framerate +    dvdecoder->sampling = e_dv_sample_422;  // 4 bytes y, 2 bytes u, 2 bytes v +    dvdecoder->std = e_dv_std_iec_61834; +    dvdecoder->num_dif_seqs = 12; +  } + +  pixels[ 0 ] = picture; // We use this as the output buffer +  pitches[ 0 ] = w * 2; +  +  dv_decode_full_frame(dvdecoder,  +                       dvframe->data,  +                       e_dv_color_yuv, +                       pixels, +                       pitches); + +  // Convert YUV422 to YUV420p +  int w2 = w / 2; +  uint8_t *y = yuv.y; +  uint8_t *cb = yuv.u; +  uint8_t *cr = yuv.v; +  uint8_t *p = picture; +  +  for ( int i = 0; i < h; i += 2 ) { +    // process two scanlines (one from each field, interleaved) +    for ( int j = 0; j < w2; j++ ) { +      // packed YUV 422 is: Y[i] U[i] Y[i+1] V[i] +      *( y++ ) = *( p++ ); +      *( cb++ ) = *( p++ ); +      *( y++ ) = *( p++ ); +      *( cr++ ) = *( p++ ); +    } + +    // process next two scanlines (one from each field, interleaved) +    for ( int j = 0; j < w2; j++ ) { +      // skip every second line for U and V +      *( y++ ) = *( p++ ); +      p++; +      *( y++ ) = *( p++ ); +      p++; +    } +  } + +  // Allocate a new frame for the output +  Frame *output = new Frame(NULL, FAME_BUFFER_SIZE); +  output->size = 0; +  unsigned char* pt = output->data; + +  // Encode YUV frame and write it to disk. +  fame_start_frame(fame_context, &yuv, 0); +  int written; +   +  while((written = fame_encode_slice(fame_context))) { +    //    fwrite(fame_buffer, written, 1, f); +    memcpy(pt, fame_buffer, written); +    pt += written; +    output->size += written; +  } +  fame_end_frame(fame_context,0); + +  return output; +} + diff --git a/src/libfame_wrapper.h b/src/libfame_wrapper.h new file mode 100644 index 0000000..9f3e0e8 --- /dev/null +++ b/src/libfame_wrapper.h @@ -0,0 +1,80 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            libfame_wrapper.h + * + *  Sat Jul  2 11:11:31 CEST 2005 + *  Copyright  2005 Bent Bisballe + *  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. + */ + +/* + * $Id$ + */ + +/* + * $Log$ + * Revision 1.1  2005/07/02 11:39:51  deva + * Added some audiocode. + * Moved libfame code out of mov_encoder + * + */ + +#include <config.h> +#ifndef __MIAV_LIBFAME_WRAPPER_H__ +#define __MIAV_LIBFAME_WRAPPER_H__ + +// Use libfame +#include <fame.h> + +// Use libdv +#include <libdv/dv.h> +#include <libdv/dv_types.h> + +#include "frame.h" +#include "info.h" + +// size specifies the length of the buffer.  +#define FAME_BUFFER_SIZE	(1024*1024)	// FIXME: One size fits all... + +class LibFAMEWrapper { +public: +  LibFAMEWrapper(Info *info); +  ~LibFAMEWrapper(); + +  Frame *encode(Frame *dvframe); + +private: +  Info* info; + +  // libFAME encoder +  //  unsigned char *fame_buffer; +  fame_parameters_t fame_par; +  fame_context_t *fame_context; +  fame_yuv_t yuv; +  unsigned char fame_buffer[FAME_BUFFER_SIZE]; + +  // libdv decoder + 	dv_decoder_t *dvdecoder; + +  unsigned char picture[FAME_BUFFER_SIZE]; +}; + +#endif/*__MIAV_LIBFAME_WRAPPER_H__*/ diff --git a/src/liblame_wrapper.cc b/src/liblame_wrapper.cc new file mode 100644 index 0000000..751c41b --- /dev/null +++ b/src/liblame_wrapper.cc @@ -0,0 +1,158 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            liblame_wrapper.cc + * + *  Sat Jul  2 11:11:34 CEST 2005 + *  Copyright  2005 Bent Bisballe + *  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. + */ + +/* + * $Id$ + */ + +/* + * $Log$ + * Revision 1.1  2005/07/02 11:39:51  deva + * Added some audiocode. + * Moved libfame code out of mov_encoder + * + */ + +#include <config.h> +#include "liblame_wrapper.h" + +LibLAMEWrapper::LibLAMEWrapper(Info *i) +{ +  info = i; + +  // Init library. +  lamegf = lame_init(); +  if(!lamegf) { +    info->error("LAME initialization failed (due to malloc failure!)"); +  } + +  lame_init_params(lamegf); + +  decoder = NULL; + +  audio_buffer[0] = new int16_t[AUDIO_BUFFER_SIZE]; +  audio_buffer[1] = new int16_t[AUDIO_BUFFER_SIZE]; + +} + +LibLAMEWrapper::~LibLAMEWrapper() +{ +  delete audio_buffer[0]; +  delete audio_buffer[1]; + +} + +Frame *LibLAMEWrapper::encode(Frame *dvframe) +{ + +  if(!decoder) { +    decoder = dv_decoder_new(FALSE/*this value is unused*/, FALSE, FALSE); +    decoder->quality = DV_QUALITY_BEST; +     +    dv_parse_header(decoder, dvframe->data); +   +    decoder->system = e_dv_system_625_50;  // PAL lines, PAL framerate +    decoder->sampling = e_dv_sample_422;  // 4 bytes y, 2 bytes u, 2 bytes v +    decoder->std = e_dv_std_iec_61834; +    decoder->num_dif_seqs = 12; +  } + +  // See +  // http://www.koders.com/cpp/fidE614E999154E2B4A813DA272C4421633063C78CA.aspx +  // line 769 + +  /** +   * Decode audio using libdv +   */ +  //  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 ]; +      */ + +/* + * input pcm data, output (maybe) mp3 frames. + * This routine handles all buffering, resampling and filtering for you. + *  + * The required mp3buf_size can be computed from num_samples,  + * samplerate and encoding rate, but here is a worst case estimate: + * + * mp3buf_size in bytes = 1.25*num_samples + 7200 + * + * I think a tighter bound could be:  (mt, March 2000) + * MPEG1: + *    num_samples*(bitrate/8)/samplerate + 4*1152*(bitrate/8)/samplerate + 512 + * MPEG2: + *    num_samples*(bitrate/8)/samplerate + 4*576*(bitrate/8)/samplerate + 256 + * + * but test first if you use that! + * + * set mp3buf_size = 0 and LAME will not check if mp3buf_size is + * large enough. + * + * NOTE: + * if gfp->num_channels=2, but gfp->mode = 3 (mono), the L & R channels + * will be averaged into the L channel before encoding only the L channel + * This will overwrite the data in buffer_l[] and buffer_r[]. + *  +*/ + +  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 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); + +  if(val < 0) { +    switch(val) { +    case -1:  // mp3buf was too small +      info->error("Lame encoding failed, mp3buf was too small."); +      break; +    case -2:  // malloc() problem +      info->error("Lame encoding failed, due to malloc() problem."); +      break; +    case -3:  // lame_init_params() not called +      info->error("Lame encoding failed, lame_init_params() not called."); +      break; +    case -4:  // psycho acoustic problems  +      info->error("Lame encoding failed, due to psycho acoustic problems."); +      break; +    default: +      info->error("Lame encoding failed, due to unknown error."); +      break; +    } +  } + +  return audio_frame; +} diff --git a/src/liblame_wrapper.h b/src/liblame_wrapper.h new file mode 100644 index 0000000..2d3a769 --- /dev/null +++ b/src/liblame_wrapper.h @@ -0,0 +1,77 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            liblame_wrapper.h + * + *  Sat Jul  2 11:11:34 CEST 2005 + *  Copyright  2005 Bent Bisballe + *  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. + */ + +/* + * $Id$ + */ + +/* + * $Log$ + * Revision 1.1  2005/07/02 11:39:51  deva + * Added some audiocode. + * Moved libfame code out of mov_encoder + * + */ + +#include <config.h> +#ifndef __MIAV_LIBLAME_WRAPPER_H__ +#define __MIAV_LIBLAME_WRAPPER_H__ + +// Use libdv +#include <libdv/dv.h> +#include <libdv/dv_types.h> + +// Use liblame +#include <lame/lame.h> + +#include "frame.h" +#include "info.h" + +#define CHANNELS 2 +#define SAMPLES 44100 +#define AUDIO_BUFFER_SIZE SAMPLES/25*sizeof(int16_t) + +class LibLAMEWrapper { +public: +  LibLAMEWrapper(Info *info); +  ~LibLAMEWrapper(); + +  Frame *encode(Frame *dvframe); + +private: +  Info *info; + +  // LAME stuff +  lame_global_flags *lamegf; + +  // libdv stuff +  dv_decoder_t *decoder; +  int16_t *audio_buffer[2]; + +}; + +#endif/*__MIAV_LIBLAME_WRAPPER_H__*/ diff --git a/src/miav_config.cc b/src/miav_config.cc index f7d56ce..f59b6b3 100644 --- a/src/miav_config.cc +++ b/src/miav_config.cc @@ -31,6 +31,10 @@  /*   * $Log$ + * Revision 1.11  2005/07/02 11:39:51  deva + * Added some audiocode. + * Moved libfame code out of mov_encoder + *   * Revision 1.10  2005/06/14 12:29:40  deva   * Incorporated the use of the Info object everywhere... also using the log functionality.   * @@ -65,7 +69,7 @@ MiavConfig::MiavConfig(char *file, Info *i)      return;    }    fseek(fp, 0, SEEK_END); -  int fsz = ftell(fp); +  int fsz = ftell(fp) + 1;    fseek(fp, 0, SEEK_SET);    char *raw = (char*)calloc(fsz, 1); @@ -73,7 +77,8 @@ MiavConfig::MiavConfig(char *file, Info *i)    fclose(fp); -  parse(raw); +  configs = parse(raw); +    free(raw);  } @@ -93,173 +98,384 @@ MiavConfig::~MiavConfig()  /**   * Prints a reasonable error message when a parse error occurres.   */ -_cfg *MiavConfig::parseError(char* msg, char* line) +void MiavConfig::parseError(char* msg, _cfg* cfg)  { -  if(info) info->error("Error parsing file %s at line:\n\t%s\n\t%s\n", filename.c_str(), line, msg); -  else fprintf(stderr, "Error parsing file %s at line:\n\t%s\n\t%s\n", filename.c_str(), line, msg); -  return NULL; +  if(info) info->error("Error parsing file %s at line %d:\n\t%s\n\t%s\n",  +                       filename.c_str(),  +                       cfg->line, +                       cfg->orig, +                       msg); +  else fprintf(stderr, "Error parsing file %s at line %d:\n\t%s\n\t%s\n", +               filename.c_str(),  +               cfg->line, +               cfg->orig, +               msg);  } -/**  - * Adds one configuration entry, from a single zero terminated line. - */ -_cfg *MiavConfig::addConfig(_cfg *parent, char* conf) +_cfg* MiavConfig::readLines(char* raw)  { -  // Check for wellformed input: -  // Check for = -  if(strstr(conf, "=") == 0) return parseError("Missing '='", conf); -  /* -  if(strstr(conf, "\"")) { -    if(strstr(conf, "=") > strstr(conf, "\"")) -    return parseError("Missing '=', first occurrence inside string", conf); -  } -  */ +  int line = 1; +   +  _cfg *first = (_cfg*)calloc(1, sizeof(_cfg)); +  _cfg *current = first; +  _cfg *next = NULL; -  // Check for nonempty left side -  if(strstr(conf, "=") == conf) return parseError("Empty left side", conf); +  char *nl = strchr(raw, '\n'); -  // Check for nonempty right side -  if(strstr(conf, "=") == conf + strlen(conf) - 1) return parseError("Empty right side.", conf); +  while(nl != NULL) { +    int len = nl - raw; -  // Parse this wellformed input. -  _cfg *cfg; +    current->line = line; -  cfg = (_cfg*) malloc(sizeof(_cfg)); -  if(!parent) configs = cfg; +    current->orig = (char*) calloc(len + 1, 1); +    strncpy(current->orig, raw, len); -  int namelen = strchr(conf, '=') - conf; -  char* name = (char*)calloc(namelen + 1, 1); -  strncpy(name, conf, namelen); +    // Find next newline +    raw = nl+1; +    nl = strchr(raw, '\n'); -  int vallen = conf + strlen(conf) - (strchr(conf, '=') + 1); -  char* val = (char*)calloc(vallen + 1, 1); -  strncpy(val, conf + strlen(conf) - vallen, vallen); +    line++; -  // TODO: Check valid rightside (true, false, number or "..") +    // Add _cfg +    if(nl != NULL) { +      next = (_cfg*)calloc(1, sizeof(_cfg)); +      current->next = next; +      current = next; +    } else { +      current->next = NULL; +    } +  } -  cfg->name = new string((const char*)name); -  free(name); +  return first; +} -  cfg->stringval = new string((const char*)val); -  cfg->intval = atoi(val); -  cfg->floatval = atof(val); -  cfg->boolval = atoi(val) != 0; -  free(val); +_cfg* MiavConfig::parseLines(_cfg *cfg) +{ +  if(cfg == NULL) return NULL; -  cfg->next = NULL; +  char *l = cfg->left = (char*)calloc(1, strlen(cfg->orig)); +  char *r = cfg->right = (char*)calloc(1, strlen(cfg->orig)); -  if(parent) parent->next = cfg; -  return cfg; -} +  char *p = cfg->orig; -/** - * Main parse function, iterates the lines of the file. - */ -int MiavConfig::parse(char* raw) -{ -  // Strip the string -  char *conf = strip(raw); -  char *conf_end = conf + strlen(conf); -  char *start = conf; -  char *p; - -  _cfg *cfg = NULL; - -  // Iterate the lines in the string -  for(p = conf; p < conf_end; p++) { -    if(*p == '\n') { -      *p = '\0'; -      if(!(cfg = addConfig(cfg, start))) return 1; -      start = p+1; +  // Skip leftmost whitespace +  while(p < cfg->orig + strlen(cfg->orig) && strchr("\t ", *p)) { +    p++; +  } + +  // Empty line, with whitespaces +  if(p == cfg->orig + strlen(cfg->orig)) { +    _cfg* next = cfg->next; +    free(cfg->orig); +    free(cfg->left); +    free(cfg->right); +    free(cfg); +    return parseLines(next); +  } + +  // Parse left side +  while(p < cfg->orig + strlen(cfg->orig) && !strchr("\t ", *p)) { +    if(strchr("#", *p)) { +      if(l != cfg->left) parseError("Incomplete line.", cfg); +      _cfg* next = cfg->next; +      free(cfg->orig); +      free(cfg->left); +      free(cfg->right); +      free(cfg); +      return parseLines(next); +    } + +    if(strchr("=", *p)) break; + +    if(strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_", *p)) { +      *l = *p; +      l++; +    } else { +      char buf[256]; +      sprintf(buf, "Invalid left hand side character at [%s].", p); +      parseError(buf, cfg); +      _cfg* next = cfg->next; +      free(cfg->orig); +      free(cfg->left); +      free(cfg->right); +      free(cfg); +      return parseLines(next);      } + +    p++;    } -  // Allocated in strip -  free(conf); -  return 0; -} -/** - * Strip all unwanted data from the string, initial to parsing. - */ -char* MiavConfig::strip(char* conf) -{ -  // Freed in parse!!! -  char *stripped = (char*)calloc(strlen(conf) + 2, 1); -  char *r; -  char *w = stripped; - -  bool instring = false; -  bool incomment = false; - -  // Iterate over the characters in the input string. -  for(r = conf; r < conf + strlen(conf); r++) { -    if(strchr("#", *r)) incomment = true; -    if(strchr("\n", *r)) incomment = false; - -    if(!incomment) { -      if(instring) { -        // When in a string, accept anything, except ". -        if(*r != '\"') { -          *w = *r; -          w++; -        } -      } else { -        // Only copy valid characters -        if(strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890-_,.=", *r)) { -          // Change comma into dot -          if(*r == ',') *r = '.'; -          *w = *r; -          w++; -        } -        // We don't want double newlines and initial newline! -        if((*r == '\n') && (*(w-1) != '\n') && (w != stripped)) { -          *w = *r; -          w++; -        } +  // Skip whitespace +  while(p < cfg->orig + strlen(cfg->orig) && strchr("\t ", *p)) { +    p++; +  } + +  if(*p != '=') { +     parseError("Expected '='.", cfg); +      _cfg* next = cfg->next; +      free(cfg->orig); +      free(cfg->left); +      free(cfg->right); +      free(cfg); +      return parseLines(next); +  } +  p++; // Get past the '=' + +  // Skip whitespace +  while(p < cfg->orig + strlen(cfg->orig) && strchr("\t ", *p)) { +    p++; +  } + +  // Parse right hand side +  int instring = 0; +  while(p < cfg->orig + strlen(cfg->orig) && !(strchr("\t ", *p) && instring != 1)) { +    if(*p == '\"') instring++; +    if(instring > 2) { +      parseError("Too many '\"'.", cfg); +      _cfg* next = cfg->next; +      free(cfg->orig); +      free(cfg->left); +      free(cfg->right); +      free(cfg); +      return parseLines(next); +    }  +     +    if(instring == 1) { +      // Accept all chars +      *r= *p; +      r++; +    } else { +      // Accept only those chars valid for the data types. +      if(strchr("truefalseyesnoTRUEFALSEYESNO1234567890\",.-", *p)) { +        if(*p == ',') *r= '.'; +        *r = *p; +        r++; +      } else if(!strchr("\n", *p)) { +        char buf[256]; +        sprintf(buf, "Invalid right hand side character at [%s].", p); +        parseError(buf, cfg); +        _cfg* next = cfg->next; +        free(cfg->orig); +        free(cfg->left); +        free(cfg->right); +        free(cfg); +        return parseLines(next);        } +      if(*p == '#') break;      } -    if(strchr("\"", *r)) instring = !instring; +    p++; +  } + +  // Skip whitespace +  while(p < cfg->orig + strlen(cfg->orig) && strchr("\t ", *p)) { +    p++; +  } + +  // Detect if whitespace ocurred inside righthand value. +  if(p != cfg->orig + strlen(cfg->orig)) { +    parseError("Invalid use of whitespace.", cfg); +    _cfg* next = cfg->next; +    free(cfg->orig); +    free(cfg->left); +    free(cfg->right); +    free(cfg); +    return parseLines(next); +  } + +  // Check for instring (string not ended) +  if(instring == 1) { +    parseError("String not closed.", cfg); +    _cfg* next = cfg->next; +    free(cfg->orig); +    free(cfg->left); +    free(cfg->right); +    free(cfg); +    return parseLines(next); +  } + +  // Check for empty line +  if(l == cfg->left && r == cfg->right) { +    _cfg* next = cfg->next; +    free(cfg->orig); +    free(cfg->left); +    free(cfg->right); +    free(cfg); +    return parseLines(next); +  } + +  // Check for empty left side. +  if(l == cfg->left) { +    parseError("Empty left side.", cfg); +    _cfg* next = cfg->next; +    free(cfg->orig); +    free(cfg->left); +    free(cfg->right); +    free(cfg); +    return parseLines(next);    } -  // If we are not ending on a newline, we better append one -  if(*(w-1) != '\n') { -    *w = '\n'; -    w++; +  // Check for empty right side. +  if(r == cfg->right) { +    parseError("Empty right side.", cfg); +    _cfg* next = cfg->next; +    free(cfg->orig); +    free(cfg->left); +    free(cfg->right); +    free(cfg); +    return parseLines(next);    } -  // Make sure we are nullterminated. -  *w = '\0'; +  cfg->next = parseLines(cfg->next); +  return cfg; +} + + +_cfg *MiavConfig::createSemantics(_cfg *cfg) { +  if(cfg == NULL) return NULL; + +  cfg->type = CONFIG_UNKNOWN; + +  // Boolean - true +  if(strcasecmp(cfg->right, "yes") == 0 || +     strcasecmp(cfg->right, "true")  == 0) { +    cfg->type = CONFIG_BOOL; +    cfg->boolval = true; +  } + +  // Boolean - false +  if(strcasecmp(cfg->right, "no") == 0 || +     strcasecmp(cfg->right, "false") == 0) { +    cfg->type = CONFIG_BOOL; +    cfg->boolval = false; +  } -  return stripped; +  // String +  if(cfg->right[0] == '\"') { +    cfg->type = CONFIG_STRING; +    cfg->right[strlen(cfg->right) - 1] = '\0'; +    cfg->stringval = new string(cfg->right + 1); +     +  } + +  // Number +  bool number = true; +  char *p = cfg->right; +  while(p < cfg->right + strlen(cfg->right)) { +    if(!strchr("01234567890.-", *p)) number = false; +    p++; +  } +     +  // Integer +  if(number && strstr(cfg->right, ".") == NULL ) { +    cfg->type = CONFIG_INT; +    cfg->intval = atoi(cfg->right); +  } + +  // Float +  if(number && strstr(cfg->right, ".") != NULL) { +    cfg->type = CONFIG_FLOAT; +    cfg->floatval = atof(cfg->right); +  } + +  if(cfg->type == CONFIG_UNKNOWN) { +    parseError("Unknown type (see 'man miav.conf' for valid right hand sides).", cfg); +    _cfg* next = cfg->next; +    free(cfg->orig); +    free(cfg->left); +    free(cfg->right); +    free(cfg); +    return createSemantics(next); +  } + +  // Create name +  cfg->name = new string(cfg->left); + +  cfg->next = createSemantics(cfg->next); +  return cfg; +} + + +_cfg* MiavConfig::parse(char* raw) +{ +  _cfg *first = readLines(raw); +  first = parseLines(first); + +  first = createSemantics(first); + +  /* +  _cfg* cfg = first; +  while(cfg) { +    printf("Node:\n"); +    printf("\tLine: [%d]\n", cfg->line); +    printf("\tOrig: [%s]\n", cfg->orig); +    printf("\tLeft: [%s]\n", cfg->left); +    printf("\tRight: [%s]\n", cfg->right); + +    switch(cfg->type) { +    case CONFIG_INT: +      printf("\tInt value: %d\n", cfg->intval); +      break; +    case CONFIG_BOOL: +      printf("\tBool value: %d\n", cfg->boolval); +      break; +    case CONFIG_FLOAT: +      printf("\tFloat value: %f\n", cfg->floatval); +      break; +    case CONFIG_STRING: +      printf("\tString value: %s\n", cfg->stringval->c_str()); +      break; +    case CONFIG_UNKNOWN: +      printf("\tUnknown type: %s\n", cfg->right); +      break; +    } + +    cfg= cfg->next; +  } +  */ +  return first;  }  int MiavConfig::readInt(char *node)  {    _cfg* n = findNode(node); -  if(n) return n->intval; -  else return 0; +  if(n) { +    if(n->type == CONFIG_INT) return n->intval; +    parseError("Expected integer.", n); +  } +  return 0;  }  bool MiavConfig::readBool(char *node)  { -  _cfg* n = findNode(node); -  if(n) return n->boolval; -  else return false; +  _cfg* n = findNode(node);  +  if(n) { +    if(n->type == CONFIG_BOOL) return n->boolval; +    if(n->type == CONFIG_INT) return (n->intval != 0); +    parseError("Expected boolean.", n); +  } +  return false;  }  string *MiavConfig::readString(char *node)  {    _cfg* n = findNode(node); -  if(n) return n->stringval; -  else return &emptyString; +  if(n) { +    if(n->type == CONFIG_STRING) return n->stringval; +    parseError("Expected string.", n); +  } +  return &emptyString;  }  float MiavConfig::readFloat(char *node)  {    _cfg* n = findNode(node); -  if(n) return n->floatval; -  else return 0.0f; +  if(n) { +    if(n->type == CONFIG_FLOAT) return n->floatval; +    if(n->type == CONFIG_INT) return (float)n->intval; +    parseError("Expected float.", n); +  } +  return 0.0f;  }  _cfg *MiavConfig::findNode(char* node) @@ -270,8 +486,31 @@ _cfg *MiavConfig::findNode(char* node)      if(!strcmp(node, cfg->name->c_str())) return cfg;      cfg = cfg->next;    } -  if(info) info->error("Request for nonexisting node \"%s\"!\n", node); -  else fprintf(stderr, "Request for nonexisting node \"%s\"!\n", node); +  if(info) info->error("Missing line in configuration file: \"%s\"!\n", node); +  else fprintf(stderr, "Missing line in configuration file: \"%s\"!\n", node);    return NULL;  } + +#ifdef __TEST_MIAV_CONFIG + +int main(int argc, char *argv[]) { +  if(argc < 2) { +    fprintf(stderr, "usage:\n\tmiav_config [filename]\n"); +    return 1; +  } + +  MiavConfig cfg(argv[1]); +  printf("Server user: [%s]\n", cfg.readString("server_user")->c_str()); +  printf("Resolution: [%f]\n", cfg.readFloat("screensize")); +  printf("Resolution (as int): [%d]\n", cfg.readInt("screensize")); +  printf("Width: [%d]\n", cfg.readInt("pixel_width")); +  printf("Width (as float): [%f]\n", cfg.readFloat("pixel_width")); +  printf("Frame quality: [%d]\n", cfg.readInt("frame_quality")); +  printf("Skip frames: [%d]\n", cfg.readBool("player_skip_frames")); +  printf("Skip frames (as int): [%d]\n", cfg.readInt("player_skip_frames")); +  printf("Frame quality (as bool): [%d]\n", cfg.readBool("frame_quality")); + +} + +#endif/* __TEST_MIAV_CONFIG*/ diff --git a/src/miav_config.h b/src/miav_config.h index 4bbcc59..a4c432a 100644 --- a/src/miav_config.h +++ b/src/miav_config.h @@ -31,6 +31,10 @@  /*   * $Log$ + * Revision 1.8  2005/07/02 11:39:51  deva + * Added some audiocode. + * Moved libfame code out of mov_encoder + *   * Revision 1.7  2005/06/14 12:29:40  deva   * Incorporated the use of the Info object everywhere... also using the log functionality.   * @@ -52,18 +56,36 @@ using namespace std;  // Cyclic include :(  class Info; +typedef enum { +  CONFIG_UNKNOWN, +  CONFIG_INT, +  CONFIG_BOOL, +  CONFIG_FLOAT, +  CONFIG_STRING +} ConfigType; + +  typedef struct __cfg { +  // For parsing +  char* orig; +  int line; +  char* left; +  char* right; + +  // For traversal    string *name; -  bool boolval; +  ConfigType type;    int intval; -  string *stringval; +  bool boolval;    float floatval; +  string *stringval; +    struct __cfg* next;  } _cfg;  class MiavConfig {  public: -  MiavConfig(char *file, Info *info); +  MiavConfig(char *file, Info *info = NULL);    ~MiavConfig();    int readInt(char *node); @@ -73,13 +95,21 @@ public:  private:    Info *info; +  string filename; +  _cfg *createSemantics(_cfg *cfg); +  _cfg* readLines(char* raw); +  _cfg* parseLines(_cfg *cfg); +  _cfg *parse(char* raw);    string emptyString; -  string filename; + + +#if 0    _cfg *addConfig(_cfg *parent, char* conf); -  int parse(char* conf);    char *strip(char* conf); -  _cfg *parseError(char* msg, char* line); +#endif + +  void parseError(char* msg, _cfg *cfg);    _cfg *findNode(char* node);    _cfg *configs;  }; diff --git a/src/mov_encoder.cc b/src/mov_encoder.cc index 3aa7a49..38622c6 100644 --- a/src/mov_encoder.cc +++ b/src/mov_encoder.cc @@ -39,6 +39,10 @@  /*   * $Log$ + * Revision 1.33  2005/07/02 11:39:52  deva + * Added some audiocode. + * Moved libfame code out of mov_encoder + *   * Revision 1.32  2005/06/19 20:04:43  deva   * ImgEncoder now uses the file class for output, through jpeg_mem_dest.   * @@ -140,131 +144,8 @@ MovEncoder::MovEncoder(sem_t *r_sem,    info = i;    info->info("MovEncoder"); -  // FIXME: Hmmm... should this be detected somewhere?! -  int w = 720; -  int h = 576; - -  // Initialize yuv strucutre. -  yuv.w = w; -  yuv.h = h; -  yuv.p = w; -  yuv.y = new unsigned char [w*h * 2]; -  yuv.u = new unsigned char [w*h];// [w*h/4] -  yuv.v = new unsigned char [w*h];// [w*h/4] - -  ////////////LIBDV STUFF/////////////// -   -  dvdecoder = NULL; // Initialize in encode method - -  /////////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.) -  fame_context = fame_open(); -  if(!fame_context) { -    info->error("Unable to open FAME context, due to the following error: %s", strerror(errno)); -    return; -  } - -  /* -  typedef struct _fame_parameters_ { -    int width;                        // width of the video sequence -    int height;                       // height of the video sequence -    char const *coding;               // coding sequence -    int quality;                      // video quality -    int slices_per_frame;             // number of slices per frame -    unsigned int frames_per_sequence; // number of frames per sequence -    int frame_rate_num;               // numerator of frames per second -    int frame_rate_den;               // denominator of frames per second -    unsigned int shape_quality;       // binary shape quality -    unsigned int search_range;        // motion estimation search range -    unsigned char verbose;            // verbosity -  } fame_parameters_t; -  */ -  // width and height specify the size of each frames of the video sequence.  -  // Both must be multiple of 16. width and height must be less than 4096x4096 -  fame_par.width = 720; -  fame_par.height = 576; - -  // coding is a string of I, P or B characters representing the sequence of  -  // frames the encoder must produce. I frames are intra-coded frames (similar  -  // to JPEG), whereas P and B frames are motion compressed, respectively  -  // predicted from past reference (I or P) frame, or bidirectionally predicted  -  // from past and future reference frame. -  fame_par.coding = config->readString("frame_sequence")->c_str(); - -  // quality is a percentage, which controls compression versus quality. -  fame_par.quality = config->readInt("frame_quality"); - -  // Bitrate -  fame_par.bitrate = 0; // video bitrate (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  -  // height / 16 -  fame_par.slices_per_frame = 1;//fame_par.height / 16; - -  // frames_per_sequence is the maximum number of frames contained in a video  -  // sequence. -  fame_par.frames_per_sequence = 0xffffffff; // Unlimited length - -  // frame_rate_num/frame_rate_den specify the number of frames per second for  -  // playback. -  fame_par.frame_rate_num = 25; // 25 / 1 fps = 25 fps -  fame_par.frame_rate_den = 1; - -  // shape_quality is percentage determing the average binary shape accuracy in  -  // video with arbitrary shape. -  fame_par.shape_quality = 100; // Original shape - -  // search_range specifies the motion estimation search range in pixel unit.  -  // Small search ranges work best with slow motion videos, whereas larger search  -  // ranges are rather for fast motion videos. -  fame_par.search_range = 0; // Adaptive search range - -  // verbose when set to 1 outputs information on copyright, modules used and  -  // current frame on standard error. -  fame_par.verbose = 0; - -  static const char profilename[] = "MIaV\0"; -  fame_par.profile = profilename;              // profile name -  fame_par.total_frames = 0;        // total number of frames - -  if(strcmp(config->readString("encoding_codec")->c_str(), "mpeg4") == 0) { - -    info->info("Using mpeg4 compression."); -    fame_object_t *object; -     -    object = fame_get_object(fame_context, "profile/mpeg4/simple"); -    if(object) fame_register(fame_context, "profile", object); - -  } else if(strcmp(config->readString("encoding_codec")->c_str(), "mpeg1") == 0) { - -    info->info("Using mpeg1 compression."); -    fame_object_t *object; -     -    object = fame_get_object(fame_context, "profile/mpeg1"); -    if(object) fame_register(fame_context, "profile", object); - -  } else if(strcmp(config->readString("encoding_codec")->c_str(), "mpeg1") == 0) { -  } else { -    info->info("Using default (mpeg1) compression."); -  } - -  fame_init(fame_context, &fame_par, fame_buffer, FAME_BUFFER_SIZE); +  fame = new LibFAMEWrapper(info); +  lame = new LibLAMEWrapper(info);    running = true; @@ -283,108 +164,9 @@ MovEncoder::MovEncoder(sem_t *r_sem,  MovEncoder::~MovEncoder()  {    info->info("~MovEncoder"); -  /* -  if(f) { // The file was opened. -    int written = fame_close(fame_context); -    fwrite(fame_buffer, written, 1, f); -    fclose(f); -  } -  */ -  //  delete [] fame_buffer; -  delete [] yuv.y; -  delete [] yuv.u; -  delete [] yuv.v; -} - -Frame *MovEncoder::encode(Frame *dvframe) -{ -  return encode_video(dvframe); -  //  encode_audio(dvframe); -} - -Frame *MovEncoder::encode_video(Frame *dvframe) -{ -  //  if(!f) return; // The file was not opened. - -  // Decode DV Frame to YUV422 -  int w = 720; -  int h = 576; - -  unsigned char *pixels[3]; -  int pitches[3]; - -  if(!dvdecoder) { -    dvdecoder = dv_decoder_new(FALSE/*this value is unused*/, FALSE, FALSE); -    dvdecoder->quality = DV_QUALITY_BEST; - -    dv_parse_header(dvdecoder, dvframe->data); -    //dv_parse_packs(decoder, frame->data); // Not needed anyway! -     -    dvdecoder->system = e_dv_system_625_50;  // PAL lines, PAL framerate -    dvdecoder->sampling = e_dv_sample_422;  // 4 bytes y, 2 bytes u, 2 bytes v -    dvdecoder->std = e_dv_std_iec_61834; -    dvdecoder->num_dif_seqs = 12; -  } - -  pixels[ 0 ] = picture; // We use this as the output buffer -  pitches[ 0 ] = w * 2; -  -  dv_decode_full_frame(dvdecoder,  -                       dvframe->data,  -                       e_dv_color_yuv, -                       pixels, -                       pitches); - -  // Convert YUV422 to YUV420p -  int w2 = w / 2; -  uint8_t *y = yuv.y; -  uint8_t *cb = yuv.u; -  uint8_t *cr = yuv.v; -  uint8_t *p = picture; -  -  for ( int i = 0; i < h; i += 2 ) { -    // process two scanlines (one from each field, interleaved) -    for ( int j = 0; j < w2; j++ ) { -      // packed YUV 422 is: Y[i] U[i] Y[i+1] V[i] -      *( y++ ) = *( p++ ); -      *( cb++ ) = *( p++ ); -      *( y++ ) = *( p++ ); -      *( cr++ ) = *( p++ ); -    } - -    // process next two scanlines (one from each field, interleaved) -    for ( int j = 0; j < w2; j++ ) { -      // skip every second line for U and V -      *( y++ ) = *( p++ ); -      p++; -      *( y++ ) = *( p++ ); -      p++; -    } -  } - -  // Allocate a new frame for the output -  Frame *output = new Frame(NULL, FAME_BUFFER_SIZE); -  output->size = 0; -  unsigned char* pt = output->data; - -  // Encode YUV frame and write it to disk. -  fame_start_frame(fame_context, &yuv, 0); -  int written; -  while((written = fame_encode_slice(fame_context))) { -    //    fwrite(fame_buffer, written, 1, f); -    memcpy(pt, fame_buffer, written); -    pt += written; -    output->size += written; -  } -  fame_end_frame(fame_context,0); - -  return output; -} - -void MovEncoder::encode_audio(Frame *dvframe) -{ -  // TODO: Do some audio stuff here sometime! +  delete fame; +  delete lame;  }  // this runs in a thread @@ -398,10 +180,10 @@ void MovEncoder::thread_main()    // Run with slightly lower priority than MovEncoderWriter    nice(1); -    FrameVector *item;    Frame *in_frame; -  Frame *out_frame; +  Frame *out_v_frame; +  Frame *out_a_frame;    while(running) {      sem_wait(input_sem); @@ -419,14 +201,21 @@ void MovEncoder::thread_main()      if(item) {        for(unsigned int cnt = 0; cnt < item->size(); cnt++) {          in_frame = item->at(cnt); -        out_frame = encode(in_frame); -        out_frame->number = in_frame->number; + +        // Encode video +        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->number = in_frame->number; +          delete in_frame;          // Lock output mutex          pthread_mutex_lock(output_mutex); -        outputqueue->push(out_frame); +        outputqueue->push(out_v_frame); +        outputqueue->push(out_a_frame);          outsize = outputqueue->size(); diff --git a/src/mov_encoder.h b/src/mov_encoder.h index 76f0c7a..a54b145 100644 --- a/src/mov_encoder.h +++ b/src/mov_encoder.h @@ -36,6 +36,10 @@  /*   * $Log$ + * Revision 1.14  2005/07/02 11:39:52  deva + * Added some audiocode. + * Moved libfame code out of mov_encoder + *   * Revision 1.13  2005/06/16 21:54:22  deva   * *** empty log message ***   * @@ -77,14 +81,6 @@  #include <stdlib.h>  #include <string.h> - -// Use libfame -#include <fame.h> - -// Use libdv -#include <libdv/dv.h> -#include <libdv/dv_types.h> -  #include <vector>  using namespace std; @@ -96,8 +92,8 @@ using namespace std;  #include "info.h" -// size specifies the length of the buffer.  -#define FAME_BUFFER_SIZE	(1024*1024)	// FIXME: One size fits all... +#include "libfame_wrapper.h" +#include "liblame_wrapper.h"  class MovEncoder : public Thread {  public: @@ -106,13 +102,15 @@ public:               FramePriorityQueue *out, sem_t *out_sem, pthread_mutex_t *out_mutex,               Info *info);    ~MovEncoder(); -  Frame* encode(Frame *frame);    void thread_main();    volatile bool running;  private: +  LibFAMEWrapper *fame; +  LibLAMEWrapper *lame; +    Info *info;    // Input/Output queues @@ -127,21 +125,6 @@ private:    pthread_mutex_t *input_mutex;    pthread_mutex_t *output_mutex; - -  Frame *encode_video(Frame *frame); -  void encode_audio(Frame *frame); - -  // libFAME encoder -  //  unsigned char *fame_buffer; -  fame_parameters_t fame_par; -  fame_context_t *fame_context; -  fame_yuv_t yuv; -  unsigned char fame_buffer[FAME_BUFFER_SIZE]; - -  // libdv decoder - 	dv_decoder_t *dvdecoder; - -  unsigned char picture[FAME_BUFFER_SIZE];  };  #endif diff --git a/src/mov_encoder_thread.cc b/src/mov_encoder_thread.cc index 49ba24c..d24e3f3 100644 --- a/src/mov_encoder_thread.cc +++ b/src/mov_encoder_thread.cc @@ -31,6 +31,10 @@  /*   * $Log$ + * Revision 1.13  2005/07/02 11:39:52  deva + * Added some audiocode. + * Moved libfame code out of mov_encoder + *   * Revision 1.12  2005/06/16 21:28:57  deva   * Rewrote thread object   * Fixed bug in mov_encoder (pushed read_sem too many times, whihc lead to @@ -203,5 +207,5 @@ void MovEncoderThread::encode(Frame* frame)      block = new FrameVector;    } -  frame_number ++; +  frame_number += 2;  } | 
