summaryrefslogtreecommitdiff
path: root/src/mov_encoder.cc
diff options
context:
space:
mode:
authordeva <deva>2005-05-09 16:40:20 +0000
committerdeva <deva>2005-05-09 16:40:20 +0000
commitca47f85bf3274fc970650763398795fc5e8e666c (patch)
tree09add0d76506c523bfe56ebb058086a4c005d4af /src/mov_encoder.cc
parent9145542156e3f45330e831ebddbcf735018a1d7f (diff)
Added optimize yuv conversion code
Diffstat (limited to 'src/mov_encoder.cc')
-rw-r--r--src/mov_encoder.cc102
1 files changed, 70 insertions, 32 deletions
diff --git a/src/mov_encoder.cc b/src/mov_encoder.cc
index f9d47e7..0e2b935 100644
--- a/src/mov_encoder.cc
+++ b/src/mov_encoder.cc
@@ -39,6 +39,10 @@
/*
* $Log$
+ * Revision 1.15 2005/05/09 16:40:20 deva
+ *
+ * Added optimize yuv conversion code
+ *
* Revision 1.14 2005/05/07 10:56:18 deva
* Changed print outs
*
@@ -80,9 +84,9 @@ MovEncoder::MovEncoder(const char *filename)
yuv.w = w;
yuv.h = h;
yuv.p = w;
- yuv.y = new unsigned char [w*h];
- yuv.u = new unsigned char [w*h/4];
- yuv.v = new unsigned char [w*h/4];
+ 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///////////////
@@ -132,7 +136,7 @@ MovEncoder::MovEncoder(const char *filename)
fame_par.coding = coding;
// quality is a percentage, which controls compression versus quality.
- fame_par.quality = 100;
+ fame_par.quality = 100; // FIXME: This should be in config file!
// 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
@@ -150,7 +154,7 @@ MovEncoder::MovEncoder(const char *filename)
// shape_quality is percentage determing the average binary shape accuracy in
// video with arbitrary shape.
- fame_par.shape_quality = 100;
+ fame_par.shape_quality = 1;
// search_range specifies the motion estimation search range in pixel unit.
// Small search ranges work best with slow motion videos, whereas larger search
@@ -159,7 +163,7 @@ MovEncoder::MovEncoder(const char *filename)
// verbose when set to 1 outputs information on copyright, modules used and
// current frame on standard error.
- fame_par.verbose = 1;
+ fame_par.verbose = 0;
fame_init(fame_context, &fame_par, fame_buffer, FAME_BUFFER_SIZE);
// FIXME: fame_init return a new context, or NULL if an error occurred.
@@ -182,7 +186,9 @@ void MovEncoder::encode(Frame *dvframe)
encode_audio(dvframe);
}
+//#define RGB
+#ifdef RGB
#define _CLAMP(x) (unsigned char) ((x)<0?0:(((x)>255)?255:(x)))
inline void rgb_to_yuv(unsigned char *rgb, unsigned char &y, unsigned char &u, unsigned char &v)
@@ -191,17 +197,18 @@ inline void rgb_to_yuv(unsigned char *rgb, unsigned char &y, unsigned char &u, u
v = _CLAMP( 0.439 * rgb[0] - 0.368 * rgb[1] - 0.071 * rgb[2] + 128);
u = _CLAMP(-0.148 * rgb[0] - 0.291 * rgb[1] + 0.439 * rgb[2] + 128);
}
+#endif
void MovEncoder::encode_video(Frame *dvframe)
{
// Decode DV Frame to YUV
int w = 720;
int h = 576;
- unsigned char rgb[720*576*4];
unsigned char *pixels[3];
int pitches[3];
+#ifdef RGB
pixels[ 0 ] = rgb;
pixels[ 1 ] = NULL;
pixels[ 2 ] = NULL;
@@ -209,6 +216,7 @@ void MovEncoder::encode_video(Frame *dvframe)
pitches[ 0 ] = 720 * 3;
pitches[ 1 ] = 0;
pitches[ 2 ] = 0;
+#endif
if(!dvdecoder) {
dvdecoder = dv_decoder_new(FALSE/*this value is unused*/, FALSE, FALSE);
@@ -223,39 +231,69 @@ void MovEncoder::encode_video(Frame *dvframe)
dvdecoder->num_dif_seqs = 12;
}
+#ifdef RGB
dv_decode_full_frame(dvdecoder,
dvframe->data,
e_dv_color_rgb,
pixels,
pitches);
- /*
- e_dv_color_yuv,
- (uint8_t**) &yuv.y, //pixels,
- (int*) &yuv.w);//pitches);
- */
// cvt rgb to yuv
- for (int y=0; y<h; y+=2)
- {
- for (int x=0; x<w; x+=2)
- {
- unsigned char vy[4],vu[4],vv[4];
-
- rgb_to_yuv(rgb + 3*((y+0)*w + (x+0)), vy[0],vu[0],vv[0]);
- rgb_to_yuv(rgb + 3*((y+0)*w + (x+1)), vy[1],vu[1],vv[1]);
- rgb_to_yuv(rgb + 3*((y+1)*w + (x+0)), vy[2],vu[2],vv[2]);
- rgb_to_yuv(rgb + 3*((y+1)*w + (x+1)), vy[3],vu[3],vv[3]);
- // Y
- yuv.y[(y+0)*w+(x+0)] = vy[0];
- yuv.y[(y+0)*w+(x+1)] = vy[1];
- yuv.y[(y+1)*w+(x+0)] = vy[2];
- yuv.y[(y+1)*w+(x+1)] = vy[3];
- // Cb
- yuv.u[y*w/4+x/2] = (vu[0]+vu[1]+vu[2]+vu[3])/4;
- // Cr
- yuv.v[y*w/4+x/2] = (vv[0]+vv[1]+vv[2]+vv[3])/4;
- }
+ for (int y=0; y<h; y+=2) {
+ for (int x=0; x<w; x+=2) {
+ unsigned char vy[4],vu[4],vv[4];
+
+ rgb_to_yuv(rgb + 3*((y+0)*w + (x+0)), vy[0],vu[0],vv[0]);
+ rgb_to_yuv(rgb + 3*((y+0)*w + (x+1)), vy[1],vu[1],vv[1]);
+ rgb_to_yuv(rgb + 3*((y+1)*w + (x+0)), vy[2],vu[2],vv[2]);
+ rgb_to_yuv(rgb + 3*((y+1)*w + (x+1)), vy[3],vu[3],vv[3]);
+ // Y
+ yuv.y[(y+0)*w+(x+0)] = vy[0];
+ yuv.y[(y+0)*w+(x+1)] = vy[1];
+ yuv.y[(y+1)*w+(x+0)] = vy[2];
+ yuv.y[(y+1)*w+(x+1)] = vy[3];
+ // Cb
+ yuv.u[y*w/4+x/2] = (vu[0]+vu[1]+vu[2]+vu[3])/4;
+ // Cr
+ yuv.v[y*w/4+x/2] = (vv[0]+vv[1]+vv[2]+vv[3])/4;
}
+ }
+#else
+ pixels[ 0 ] = rgb; // We use this as the output buffer
+ pitches[ 0 ] = w * 2;
+
+ dv_decode_full_frame(dvdecoder,
+ dvframe->data,
+ e_dv_color_yuv,
+ pixels,
+ pitches);
+
+ int w2 = w / 2;
+ uint8_t *y = yuv.y;
+ uint8_t *cb = yuv.u;
+ uint8_t *cr = yuv.v;
+ uint8_t *p = rgb;
+
+ 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++;
+ }
+ }
+#endif
// Encode YUV frame and write it to disk.
fame_start_frame(fame_context, &yuv, 0);