summaryrefslogtreecommitdiff
path: root/src/mov_encoder.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/mov_encoder.cc')
-rw-r--r--src/mov_encoder.cc251
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();