From 91e9b782cc9ea0252ab2b211b15e8da4a3043d5f Mon Sep 17 00:00:00 2001 From: deva Date: Sat, 2 Jul 2005 11:39:51 +0000 Subject: Added some audiocode. Moved libfame code out of mov_encoder --- src/mov_encoder.cc | 251 +++++------------------------------------------------ 1 file changed, 20 insertions(+), 231 deletions(-) (limited to 'src/mov_encoder.cc') 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(); -- cgit v1.2.3