diff options
Diffstat (limited to 'src/mov_encoder.cc')
| -rw-r--r-- | src/mov_encoder.cc | 251 | 
1 files changed, 20 insertions, 231 deletions
| 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(); | 
