summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libhb/common.h39
-rw-r--r--libhb/deca52.c113
-rw-r--r--libhb/decavcodec.c71
-rw-r--r--libhb/declpcm.c44
-rw-r--r--libhb/decmpeg2.c64
-rw-r--r--libhb/decsub.c336
-rw-r--r--libhb/encavcodec.c100
-rw-r--r--libhb/encfaac.c96
-rw-r--r--libhb/enclame.c87
-rw-r--r--libhb/encvorbis.c112
-rw-r--r--libhb/encx264.c101
-rw-r--r--libhb/encxvid.c88
-rw-r--r--libhb/internal.h115
-rw-r--r--libhb/muxmp4.c18
-rw-r--r--libhb/render.c71
-rw-r--r--libhb/sync.c273
-rw-r--r--libhb/work.c61
17 files changed, 882 insertions, 907 deletions
diff --git a/libhb/common.h b/libhb/common.h
index 402ae7f29..7bc48940b 100644
--- a/libhb/common.h
+++ b/libhb/common.h
@@ -172,27 +172,7 @@ struct hb_job_s
hb_list_t * list_work;
- union
- {
- struct
- {
- uint8_t * config;
- int config_length;
- } mpeg4;
-
- struct
- {
- uint8_t * sps;
- int sps_length;
- uint8_t * pps;
- int pps_length;
- } h264;
-
- } config;
-
- /* MPEG-4 / AVC */
- uint8_t * es_config;
- int es_config_length;
+ hb_esconfig_t config;
hb_mux_data_t * mux_data;
#endif
@@ -214,22 +194,7 @@ struct hb_audio_s
hb_fifo_t * fifo_sync; /* Resampled, synced raw audio */
hb_fifo_t * fifo_out; /* MP3/AAC/Vorbis ES */
- union
- {
- struct
- {
- uint8_t * decinfo;
- unsigned long size;
- } faac;
-
- struct
- {
- uint8_t * headers[3];
- int sizes[3];
- } vorbis;
-
- } config;
-
+ hb_esconfig_t config;
hb_mux_data_t * mux_data;
#endif
};
diff --git a/libhb/deca52.c b/libhb/deca52.c
index a4f7492b3..b18acf641 100644
--- a/libhb/deca52.c
+++ b/libhb/deca52.c
@@ -8,12 +8,9 @@
#include "a52dec/a52.h"
-struct hb_work_object_s
+struct hb_work_private_s
{
- HB_WORK_COMMON;
-
hb_job_t * job;
- hb_audio_t * audio;
/* liba52 handle */
a52_state_t * state;
@@ -33,12 +30,22 @@ struct hb_work_object_s
hb_list_t * list;
};
+int deca52Init( hb_work_object_t *, hb_job_t * );
+int deca52Work( hb_work_object_t *, hb_buffer_t **, hb_buffer_t ** );
+void deca52Close( hb_work_object_t * );
+
+hb_work_object_t hb_deca52 =
+{
+ WORK_DECA52,
+ "AC3 decoder",
+ deca52Init,
+ deca52Work,
+ deca52Close
+};
+
/***********************************************************************
* Local prototypes
**********************************************************************/
-static void Close( hb_work_object_t ** _w );
-static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
- hb_buffer_t ** buf_out );
static hb_buffer_t * Decode( hb_work_object_t * w );
/***********************************************************************
@@ -46,22 +53,19 @@ static hb_buffer_t * Decode( hb_work_object_t * w );
***********************************************************************
* Allocate the work object, initialize liba52
**********************************************************************/
-hb_work_object_t * hb_work_deca52_init( hb_job_t * job, hb_audio_t * audio )
+int deca52Init( hb_work_object_t * w, hb_job_t * job )
{
- hb_work_object_t * w = calloc( sizeof( hb_work_object_t ), 1 );
- w->name = strdup( "AC3 decoder" );
- w->work = Work;
- w->close = Close;
+ hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
+ w->private_data = pv;
- w->job = job;
- w->audio = audio;
+ pv->job = job;
- w->list = hb_list_init();
- w->state = a52_init( 0 );
- w->flags_out = A52_STEREO;
- w->level = 32768.0;
+ pv->list = hb_list_init();
+ pv->state = a52_init( 0 );
+ pv->flags_out = A52_STEREO;
+ pv->level = 32768.0;
- return w;
+ return 0;
}
/***********************************************************************
@@ -69,13 +73,10 @@ hb_work_object_t * hb_work_deca52_init( hb_job_t * job, hb_audio_t * audio )
***********************************************************************
* Free memory
**********************************************************************/
-static void Close( hb_work_object_t ** _w )
+void deca52Close( hb_work_object_t * w )
{
- hb_work_object_t * w = *_w;
- a52_free( w->state );
- free( w->name );
- free( w );
- *_w = NULL;
+ hb_work_private_t * pv = w->private_data;
+ a52_free( pv->state );
}
/***********************************************************************
@@ -84,12 +85,13 @@ static void Close( hb_work_object_t ** _w )
* Add the given buffer to the data we already have, and decode as much
* as we can
**********************************************************************/
-static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
- hb_buffer_t ** buf_out )
+int deca52Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
+ hb_buffer_t ** buf_out )
{
+ hb_work_private_t * pv = w->private_data;
hb_buffer_t * buf;
- hb_list_add( w->list, *buf_in );
+ hb_list_add( pv->list, *buf_in );
*buf_in = NULL;
/* If we got more than a frame, chain raw buffers */
@@ -110,80 +112,81 @@ static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
**********************************************************************/
static hb_buffer_t * Decode( hb_work_object_t * w )
{
+ hb_work_private_t * pv = w->private_data;
hb_buffer_t * buf;
int i, j;
uint64_t pts;
int pos;
/* Get a frame header if don't have one yet */
- if( !w->sync )
+ if( !pv->sync )
{
- while( hb_list_bytes( w->list ) >= 7 )
+ while( hb_list_bytes( pv->list ) >= 7 )
{
/* We have 7 bytes, check if this is a correct header */
- hb_list_seebytes( w->list, w->frame, 7 );
- w->size = a52_syncinfo( w->frame, &w->flags_in, &w->rate,
- &w->bitrate );
- if( w->size )
+ hb_list_seebytes( pv->list, pv->frame, 7 );
+ pv->size = a52_syncinfo( pv->frame, &pv->flags_in, &pv->rate,
+ &pv->bitrate );
+ if( pv->size )
{
/* It is. W00t. */
- if( w->error )
+ if( pv->error )
{
hb_log( "a52_syncinfo ok" );
}
- w->error = 0;
- w->sync = 1;
+ pv->error = 0;
+ pv->sync = 1;
break;
}
/* It is not */
- if( !w->error )
+ if( !pv->error )
{
hb_log( "a52_syncinfo failed" );
- w->error = 1;
+ pv->error = 1;
}
/* Try one byte later */
- hb_list_getbytes( w->list, w->frame, 1, NULL, NULL );
+ hb_list_getbytes( pv->list, pv->frame, 1, NULL, NULL );
}
}
- if( !w->sync ||
- hb_list_bytes( w->list ) < w->size )
+ if( !pv->sync ||
+ hb_list_bytes( pv->list ) < pv->size )
{
/* Need more data */
return NULL;
}
/* Get the whole frame */
- hb_list_getbytes( w->list, w->frame, w->size, &pts, &pos );
+ hb_list_getbytes( pv->list, pv->frame, pv->size, &pts, &pos );
/* AC3 passthrough: don't decode the AC3 frame */
- if( w->job->acodec & HB_ACODEC_AC3 )
+ if( pv->job->acodec & HB_ACODEC_AC3 )
{
- buf = hb_buffer_init( w->size );
- memcpy( buf->data, w->frame, w->size );
- buf->start = pts + ( pos / w->size ) * 6 * 256 * 90000 / w->rate;
- buf->stop = buf->start + 6 * 256 * 90000 / w->rate;
- w->sync = 0;
+ buf = hb_buffer_init( pv->size );
+ memcpy( buf->data, pv->frame, pv->size );
+ buf->start = pts + ( pos / pv->size ) * 6 * 256 * 90000 / pv->rate;
+ buf->stop = buf->start + 6 * 256 * 90000 / pv->rate;
+ pv->sync = 0;
return buf;
}
/* Feed liba52 */
- a52_frame( w->state, w->frame, &w->flags_out, &w->level, 0 );
+ a52_frame( pv->state, pv->frame, &pv->flags_out, &pv->level, 0 );
/* 6 blocks per frame, 256 samples per block, 2 channels */
buf = hb_buffer_init( 3072 * sizeof( float ) );
- buf->start = pts + ( pos / w->size ) * 6 * 256 * 90000 / w->rate;
- buf->stop = buf->start + 6 * 256 * 90000 / w->rate;
+ buf->start = pts + ( pos / pv->size ) * 6 * 256 * 90000 / pv->rate;
+ buf->stop = buf->start + 6 * 256 * 90000 / pv->rate;
for( i = 0; i < 6; i++ )
{
sample_t * samples_in;
float * samples_out;
- a52_block( w->state );
- samples_in = a52_samples( w->state );
+ a52_block( pv->state );
+ samples_in = a52_samples( pv->state );
samples_out = ((float *) buf->data) + 512 * i;
/* Interleave */
@@ -194,7 +197,7 @@ static hb_buffer_t * Decode( hb_work_object_t * w )
}
}
- w->sync = 0;
+ pv->sync = 0;
return buf;
}
diff --git a/libhb/decavcodec.c b/libhb/decavcodec.c
index f18579f36..4d74fc68f 100644
--- a/libhb/decavcodec.c
+++ b/libhb/decavcodec.c
@@ -8,12 +8,22 @@
#include "ffmpeg/avcodec.h"
-struct hb_work_object_s
+int decavcodecInit( hb_work_object_t *, hb_job_t * );
+int decavcodecWork( hb_work_object_t *, hb_buffer_t **, hb_buffer_t ** );
+void decavcodecClose( hb_work_object_t * );
+
+hb_work_object_t hb_decavcodec =
{
- HB_WORK_COMMON;
+ WORK_DECAVCODEC,
+ "MPGA decoder (libavcodec)",
+ decavcodecInit,
+ decavcodecWork,
+ decavcodecClose
+};
+struct hb_work_private_s
+{
hb_job_t * job;
- hb_audio_t * audio;
AVCodecContext * context;
int64_t pts_last;
@@ -21,35 +31,24 @@ struct hb_work_object_s
/***********************************************************************
- * Local prototypes
- **********************************************************************/
-static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
- hb_buffer_t ** buf_out );
-static void Close( hb_work_object_t ** _w );
-
-/***********************************************************************
* hb_work_decavcodec_init
***********************************************************************
*
**********************************************************************/
-hb_work_object_t * hb_work_decavcodec_init( hb_job_t * job,
- hb_audio_t * audio )
+int decavcodecInit( hb_work_object_t * w, hb_job_t * job )
{
- hb_work_object_t * w = calloc( sizeof( hb_work_object_t ), 1 );
AVCodec * codec;
- w->name = strdup( "MPGA decoder (libavcodec)" );
- w->work = Work;
- w->close = Close;
+ hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
+ w->private_data = pv;
- w->job = job;
- w->audio = audio;
+ pv->job = job;
codec = avcodec_find_decoder( CODEC_ID_MP2 );
- w->context = avcodec_alloc_context();
- avcodec_open( w->context, codec );
- w->pts_last = -1;
+ pv->context = avcodec_alloc_context();
+ avcodec_open( pv->context, codec );
+ pv->pts_last = -1;
- return w;
+ return 0;
}
/***********************************************************************
@@ -57,13 +56,10 @@ hb_work_object_t * hb_work_decavcodec_init( hb_job_t * job,
***********************************************************************
*
**********************************************************************/
-static void Close( hb_work_object_t ** _w )
+void decavcodecClose( hb_work_object_t * w )
{
- hb_work_object_t * w = *_w;
- avcodec_close( w->context );
- free( w->name );
- free( w );
- *_w = NULL;
+ hb_work_private_t * pv = w->private_data;
+ avcodec_close( pv->context );
}
/***********************************************************************
@@ -71,9 +67,10 @@ static void Close( hb_work_object_t ** _w )
***********************************************************************
*
**********************************************************************/
-static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
- hb_buffer_t ** buf_out )
+int decavcodecWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
+ hb_buffer_t ** buf_out )
{
+ hb_work_private_t * pv = w->private_data;
hb_buffer_t * in = *buf_in, * buf, * last = NULL;
int pos, len, out_size, i;
short buffer[AVCODEC_MAX_AUDIO_FRAME_SIZE];
@@ -82,11 +79,11 @@ static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
*buf_out = NULL;
if( in->start < 0 ||
- ( w->pts_last > 0 &&
- in->start > w->pts_last &&
- in->start - w->pts_last < 5000 ) ) /* Hacky */
+ ( pv->pts_last > 0 &&
+ in->start > pv->pts_last &&
+ in->start - pv->pts_last < 5000 ) ) /* Hacky */
{
- cur = w->pts_last;
+ cur = pv->pts_last;
}
else
{
@@ -96,7 +93,7 @@ static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
pos = 0;
while( pos < in->size )
{
- len = avcodec_decode_audio( w->context, buffer, &out_size,
+ len = avcodec_decode_audio( pv->context, buffer, &out_size,
in->data + pos, in->size - pos );
if( out_size )
{
@@ -107,7 +104,7 @@ static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
buf->start = cur;
buf->stop = cur + 90000 * ( out_size / 4 ) /
- w->context->sample_rate;
+ pv->context->sample_rate;
cur = buf->stop;
s16 = buffer;
@@ -130,7 +127,7 @@ static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
pos += len;
}
- w->pts_last = cur;
+ pv->pts_last = cur;
return HB_WORK_OK;
}
diff --git a/libhb/declpcm.c b/libhb/declpcm.c
index 5b9d5a3b6..f6a703d38 100644
--- a/libhb/declpcm.c
+++ b/libhb/declpcm.c
@@ -6,15 +6,25 @@
#include "hb.h"
-struct hb_work_object_s
-{
- HB_WORK_COMMON;
-
- hb_job_t * job;
- hb_audio_t * audio;
+int declpcmInit( hb_work_object_t *, hb_job_t * );
+int declpcmWork( hb_work_object_t *, hb_buffer_t **, hb_buffer_t ** );
+void declpcmClose( hb_work_object_t * );
+
+hb_work_object_t hb_declpcm =
+{
+ WORK_DECLPCM,
+ "LPCM decoder",
+ declpcmInit,
+ declpcmWork,
+ declpcmClose
};
-static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
+int declpcmInit( hb_work_object_t * w, hb_job_t * job )
+{
+ return 0;
+}
+
+int declpcmWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
hb_buffer_t ** buf_out )
{
hb_buffer_t * in = *buf_in, * out;
@@ -75,24 +85,6 @@ static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
return HB_WORK_OK;
}
-static void Close( hb_work_object_t ** _w )
+void declpcmClose( hb_work_object_t * w )
{
- hb_work_object_t * w = *_w;
- free( w->name );
- free( w );
- *_w = NULL;
}
-
-hb_work_object_t * hb_work_declpcm_init( hb_job_t * job, hb_audio_t * audio )
-{
- hb_work_object_t * w = calloc( sizeof( hb_work_object_t ), 1 );
- w->name = strdup( "LPCM decoder" );
- w->work = Work;
- w->close = Close;
-
- w->job = job;
- w->audio = audio;
-
- return w;
-}
-
diff --git a/libhb/decmpeg2.c b/libhb/decmpeg2.c
index d914c03a6..214444a05 100644
--- a/libhb/decmpeg2.c
+++ b/libhb/decmpeg2.c
@@ -173,36 +173,28 @@ void hb_libmpeg2_close( hb_libmpeg2_t ** _m )
**********************************************************************
*
*********************************************************************/
-struct hb_work_object_s
+struct hb_work_private_s
{
- HB_WORK_COMMON;
-
hb_libmpeg2_t * libmpeg2;
hb_list_t * list;
};
-/***********************************************************************
- * Local prototypes
- **********************************************************************/
-static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
- hb_buffer_t ** buf_out );
-static void Close( hb_work_object_t ** _w );
-
/**********************************************************************
* hb_work_decmpeg2_init
**********************************************************************
*
*********************************************************************/
-hb_work_object_t * hb_work_decmpeg2_init( hb_job_t * job )
+int decmpeg2Init( hb_work_object_t * w, hb_job_t * job )
{
- hb_work_object_t * w = calloc( sizeof( hb_work_object_t ), 1 );
- w->name = strdup( "MPEG-2 decoder (libmpeg2)" );
- w->work = Work;
- w->close = Close;
-
- w->libmpeg2 = hb_libmpeg2_init();
- w->list = hb_list_init();
- return w;
+ hb_work_private_t * pv;
+
+ pv = calloc( 1, sizeof( hb_work_private_t ) );
+ w->private_data = pv;
+
+ pv->libmpeg2 = hb_libmpeg2_init();
+ pv->list = hb_list_init();
+
+ return 0;
}
/**********************************************************************
@@ -210,18 +202,18 @@ hb_work_object_t * hb_work_decmpeg2_init( hb_job_t * job )
**********************************************************************
*
*********************************************************************/
-static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
- hb_buffer_t ** buf_out )
+int decmpeg2Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
+ hb_buffer_t ** buf_out )
{
+ hb_work_private_t * pv = w->private_data;
hb_buffer_t * buf, * last = NULL;
- hb_libmpeg2_decode( w->libmpeg2, *buf_in, w->list );
+ hb_libmpeg2_decode( pv->libmpeg2, *buf_in, pv->list );
*buf_out = NULL;
-
- while( ( buf = hb_list_item( w->list, 0 ) ) )
+ while( ( buf = hb_list_item( pv->list, 0 ) ) )
{
- hb_list_rem( w->list, buf );
+ hb_list_rem( pv->list, buf );
if( last )
{
last->next = buf;
@@ -242,12 +234,20 @@ static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
**********************************************************************
*
*********************************************************************/
-static void Close( hb_work_object_t ** _w )
+void decmpeg2Close( hb_work_object_t * w )
{
- hb_work_object_t * w = *_w;
- hb_list_close( &w->list );
- hb_libmpeg2_close( &w->libmpeg2 );
- free( w->name );
- free( w );
- *_w = NULL;
+ hb_work_private_t * pv = w->private_data;
+ hb_list_close( &pv->list );
+ hb_libmpeg2_close( &pv->libmpeg2 );
+ free( pv );
}
+
+hb_work_object_t hb_decmpeg2 =
+{
+ WORK_DECMPEG2,
+ "MPEG-2 decoder (libmpeg2)",
+ decmpeg2Init,
+ decmpeg2Work,
+ decmpeg2Close
+};
+
diff --git a/libhb/decsub.c b/libhb/decsub.c
index de844a1c1..3666ea3fe 100644
--- a/libhb/decsub.c
+++ b/libhb/decsub.c
@@ -6,10 +6,8 @@
#include "hb.h"
-struct hb_work_object_s
+struct hb_work_private_s
{
- HB_WORK_COMMON;
-
hb_job_t * job;
uint8_t buf[0xFFFF];
@@ -29,57 +27,25 @@ struct hb_work_object_s
uint8_t alpha[4];
};
+static hb_buffer_t * Decode( hb_work_object_t * );
-/***********************************************************************
- * Local prototypes
- **********************************************************************/
-static void Close( hb_work_object_t ** _w );
-static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
- hb_buffer_t ** buf_out );
-static hb_buffer_t * Decode( hb_work_object_t * w );
-static void ParseControls( hb_work_object_t * w );
-static hb_buffer_t * CropSubtitle( hb_work_object_t * w,
- uint8_t * raw );
-
-/***********************************************************************
- * hb_work_decsub_init
- ***********************************************************************
- *
- **********************************************************************/
-hb_work_object_t * hb_work_decsub_init( hb_job_t * job )
+int decsubInit( hb_work_object_t * w, hb_job_t * job )
{
- hb_work_object_t * w = calloc( sizeof( hb_work_object_t ), 1 );
- w->name = strdup( "Subtitle decoder" );
- w->work = Work;
- w->close = Close;
-
- w->job = job;
- w->pts = -1;
+ hb_work_private_t * pv;
+
+ pv = calloc( 1, sizeof( hb_work_private_t ) );
+ w->private_data = pv;
- return w;
-}
+ pv->job = job;
+ pv->pts = -1;
-/***********************************************************************
- * Close
- ***********************************************************************
- * Free memory
- **********************************************************************/
-static void Close( hb_work_object_t ** _w )
-{
- hb_work_object_t * w = *_w;
- free( w->name );
- free( w );
- *_w = NULL;
+ return 0;
}
-/***********************************************************************
- * Work
- ***********************************************************************
- *
- **********************************************************************/
-static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
- hb_buffer_t ** buf_out )
+int decsubWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
+ hb_buffer_t ** buf_out )
{
+ hb_work_private_t * pv = w->private_data;
hb_buffer_t * in = *buf_in;
int size_sub, size_rle;
@@ -87,124 +53,66 @@ static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
size_sub = ( in->data[0] << 8 ) | in->data[1];
size_rle = ( in->data[2] << 8 ) | in->data[3];
- if( !w->size_sub )
+ if( !pv->size_sub )
{
/* We are looking for the start of a new subtitle */
if( size_sub && size_rle && size_sub > size_rle &&
in->size <= size_sub )
{
/* Looks all right so far */
- w->size_sub = size_sub;
- w->size_rle = size_rle;
+ pv->size_sub = size_sub;
+ pv->size_rle = size_rle;
- memcpy( w->buf, in->data, in->size );
- w->size_got = in->size;
- w->pts = in->start;
+ memcpy( pv->buf, in->data, in->size );
+ pv->size_got = in->size;
+ pv->pts = in->start;
}
}
else
{
/* We are waiting for the end of the current subtitle */
- if( in->size <= w->size_sub - w->size_got )
+ if( in->size <= pv->size_sub - pv->size_got )
{
- memcpy( w->buf + w->size_got, in->data, in->size );
- w->size_got += in->size;
+ memcpy( pv->buf + pv->size_got, in->data, in->size );
+ pv->size_got += in->size;
if( in->start >= 0 )
{
- w->pts = in->start;
+ pv->pts = in->start;
}
}
}
*buf_out = NULL;
- if( w->size_sub && w->size_sub == w->size_got )
+ if( pv->size_sub && pv->size_sub == pv->size_got )
{
/* We got a complete subtitle, decode it */
*buf_out = Decode( w );
/* Wait for the next one */
- w->size_sub = 0;
- w->size_got = 0;
- w->size_rle = 0;
- w->pts = -1;
+ pv->size_sub = 0;
+ pv->size_got = 0;
+ pv->size_rle = 0;
+ pv->pts = -1;
}
return HB_WORK_OK;
}
-static hb_buffer_t * Decode( hb_work_object_t * w )
+void decsubClose( hb_work_object_t * w )
{
- int code, line, col;
- int offsets[2];
- int * offset;
- hb_buffer_t * buf;
- uint8_t * buf_raw = NULL;
-
- /* Get infos about the subtitle */
- ParseControls( w );
-
- /* Do the actual decoding now */
- buf_raw = malloc( w->width * w->height * 2 );
-
-#define GET_NEXT_NIBBLE code = ( code << 4 ) | ( ( ( *offset & 1 ) ? \
-( w->buf[((*offset)>>1)] & 0xF ) : ( w->buf[((*offset)>>1)] >> 4 ) ) ); \
-(*offset)++
-
- offsets[0] = w->offsets[0] * 2;
- offsets[1] = w->offsets[1] * 2;
-
- for( line = 0; line < w->height; line++ )
- {
- /* Select even or odd field */
- offset = ( line & 1 ) ? &offsets[1] : &offsets[0];
-
- for( col = 0; col < w->width; col += code >> 2 )
- {
- uint8_t * lum, * alpha;
-
- code = 0;
- GET_NEXT_NIBBLE;
- if( code < 0x4 )
- {
- GET_NEXT_NIBBLE;
- if( code < 0x10 )
- {
- GET_NEXT_NIBBLE;
- if( code < 0x40 )
- {
- GET_NEXT_NIBBLE;
- if( code < 0x100 )
- {
- /* End of line */
- code |= ( w->width - col ) << 2;
- }
- }
- }
- }
-
- lum = buf_raw;
- alpha = lum + w->width * w->height;
- memset( lum + line * w->width + col,
- w->lum[code & 3], code >> 2 );
- memset( alpha + line * w->width + col,
- w->alpha[code & 3], code >> 2 );
- }
-
- /* Byte-align */
- if( *offset & 1 )
- {
- (*offset)++;
- }
- }
-
- /* Crop subtitle (remove transparent borders) */
- buf = CropSubtitle( w, buf_raw );
+ free( w->private_data );
+}
- free( buf_raw );
+hb_work_object_t hb_decsub =
+{
+ WORK_DECSUB,
+ "Subtitle decoder",
+ decsubInit,
+ decsubWork,
+ decsubClose
+};
- return buf;
-}
/***********************************************************************
* ParseControls
@@ -215,24 +123,25 @@ static hb_buffer_t * Decode( hb_work_object_t * w )
**********************************************************************/
static void ParseControls( hb_work_object_t * w )
{
- hb_job_t * job = w->job;
+ hb_work_private_t * pv = w->private_data;
+ hb_job_t * job = pv->job;
hb_title_t * title = job->title;
int i;
int command;
int date, next;
- w->pts_start = 0;
- w->pts_stop = 0;
+ pv->pts_start = 0;
+ pv->pts_stop = 0;
- for( i = w->size_rle; ; )
+ for( i = pv->size_rle; ; )
{
- date = ( w->buf[i] << 8 ) | w->buf[i+1]; i += 2;
- next = ( w->buf[i] << 8 ) | w->buf[i+1]; i += 2;
+ date = ( pv->buf[i] << 8 ) | pv->buf[i+1]; i += 2;
+ next = ( pv->buf[i] << 8 ) | pv->buf[i+1]; i += 2;
for( ;; )
{
- command = w->buf[i++];
+ command = pv->buf[i++];
if( command == 0xFF )
{
@@ -245,11 +154,11 @@ static void ParseControls( hb_work_object_t * w )
break;
case 0x01:
- w->pts_start = w->pts + date * 900;
+ pv->pts_start = pv->pts + date * 900;
break;
case 0x02:
- w->pts_stop = w->pts + date * 900;
+ pv->pts_stop = pv->pts + date * 900;
break;
case 0x03:
@@ -257,41 +166,41 @@ static void ParseControls( hb_work_object_t * w )
int colors[4];
int j;
- colors[0] = (w->buf[i+0]>>4)&0x0f;
- colors[1] = (w->buf[i+0])&0x0f;
- colors[2] = (w->buf[i+1]>>4)&0x0f;
- colors[3] = (w->buf[i+1])&0x0f;
+ colors[0] = (pv->buf[i+0]>>4)&0x0f;
+ colors[1] = (pv->buf[i+0])&0x0f;
+ colors[2] = (pv->buf[i+1]>>4)&0x0f;
+ colors[3] = (pv->buf[i+1])&0x0f;
for( j = 0; j < 4; j++ )
{
uint32_t color = title->palette[colors[j]];
- w->lum[3-j] = (color>>16) & 0xff;
+ pv->lum[3-j] = (color>>16) & 0xff;
}
i += 2;
break;
}
case 0x04:
{
- w->alpha[3] = (w->buf[i+0]>>4)&0x0f;
- w->alpha[2] = (w->buf[i+0])&0x0f;
- w->alpha[1] = (w->buf[i+1]>>4)&0x0f;
- w->alpha[0] = (w->buf[i+1])&0x0f;
+ pv->alpha[3] = (pv->buf[i+0]>>4)&0x0f;
+ pv->alpha[2] = (pv->buf[i+0])&0x0f;
+ pv->alpha[1] = (pv->buf[i+1]>>4)&0x0f;
+ pv->alpha[0] = (pv->buf[i+1])&0x0f;
i += 2;
break;
}
case 0x05:
{
- w->x = (w->buf[i+0]<<4) | ((w->buf[i+1]>>4)&0x0f);
- w->width = (((w->buf[i+1]&0x0f)<<8)| w->buf[i+2]) - w->x + 1;
- w->y = (w->buf[i+3]<<4)| ((w->buf[i+4]>>4)&0x0f);
- w->height = (((w->buf[i+4]&0x0f)<<8)| w->buf[i+5]) - w->y + 1;
+ pv->x = (pv->buf[i+0]<<4) | ((pv->buf[i+1]>>4)&0x0f);
+ pv->width = (((pv->buf[i+1]&0x0f)<<8)| pv->buf[i+2]) - pv->x + 1;
+ pv->y = (pv->buf[i+3]<<4)| ((pv->buf[i+4]>>4)&0x0f);
+ pv->height = (((pv->buf[i+4]&0x0f)<<8)| pv->buf[i+5]) - pv->y + 1;
i += 6;
break;
}
case 0x06:
{
- w->offsets[0] = ( w->buf[i] << 8 ) | w->buf[i+1]; i += 2;
- w->offsets[1] = ( w->buf[i] << 8 ) | w->buf[i+1]; i += 2;
+ pv->offsets[0] = ( pv->buf[i] << 8 ) | pv->buf[i+1]; i += 2;
+ pv->offsets[1] = ( pv->buf[i] << 8 ) | pv->buf[i+1]; i += 2;
break;
}
}
@@ -304,10 +213,10 @@ static void ParseControls( hb_work_object_t * w )
i = next;
}
- if( !w->pts_stop )
+ if( !pv->pts_stop )
{
/* Show it for 3 seconds */
- w->pts_stop = w->pts_start + 3 * 90000;
+ pv->pts_stop = pv->pts_start + 3 * 90000;
}
}
@@ -320,8 +229,9 @@ static void ParseControls( hb_work_object_t * w )
**********************************************************************/
static int LineIsTransparent( hb_work_object_t * w, uint8_t * p )
{
+ hb_work_private_t * pv = w->private_data;
int i;
- for( i = 0; i < w->width; i++ )
+ for( i = 0; i < pv->width; i++ )
{
if( p[i] )
{
@@ -332,10 +242,11 @@ static int LineIsTransparent( hb_work_object_t * w, uint8_t * p )
}
static int ColumnIsTransparent( hb_work_object_t * w, uint8_t * p )
{
+ hb_work_private_t * pv = w->private_data;
int i;
- for( i = 0; i < w->height; i++ )
+ for( i = 0; i < pv->height; i++ )
{
- if( p[i*w->width] )
+ if( p[i*pv->width] )
{
return 0;
}
@@ -344,6 +255,7 @@ static int ColumnIsTransparent( hb_work_object_t * w, uint8_t * p )
}
static hb_buffer_t * CropSubtitle( hb_work_object_t * w, uint8_t * raw )
{
+ hb_work_private_t * pv = w->private_data;
int i;
int crop[4] = { -1,-1,-1,-1 };
uint8_t * alpha;
@@ -351,12 +263,12 @@ static hb_buffer_t * CropSubtitle( hb_work_object_t * w, uint8_t * raw )
hb_buffer_t * buf;
uint8_t * lum_in, * lum_out, * alpha_in, * alpha_out;
- alpha = raw + w->width * w->height;
+ alpha = raw + pv->width * pv->height;
/* Top */
- for( i = 0; i < w->height; i++ )
+ for( i = 0; i < pv->height; i++ )
{
- if( !LineIsTransparent( w, &alpha[i*w->width] ) )
+ if( !LineIsTransparent( w, &alpha[i*pv->width] ) )
{
crop[0] = i;
break;
@@ -370,9 +282,9 @@ static hb_buffer_t * CropSubtitle( hb_work_object_t * w, uint8_t * raw )
}
/* Bottom */
- for( i = w->height - 1; i >= 0; i-- )
+ for( i = pv->height - 1; i >= 0; i-- )
{
- if( !LineIsTransparent( w, &alpha[i*w->width] ) )
+ if( !LineIsTransparent( w, &alpha[i*pv->width] ) )
{
crop[1] = i;
break;
@@ -380,7 +292,7 @@ static hb_buffer_t * CropSubtitle( hb_work_object_t * w, uint8_t * raw )
}
/* Left */
- for( i = 0; i < w->width; i++ )
+ for( i = 0; i < pv->width; i++ )
{
if( !ColumnIsTransparent( w, &alpha[i] ) )
{
@@ -390,7 +302,7 @@ static hb_buffer_t * CropSubtitle( hb_work_object_t * w, uint8_t * raw )
}
/* Right */
- for( i = w->width - 1; i >= 0; i-- )
+ for( i = pv->width - 1; i >= 0; i-- )
{
if( !ColumnIsTransparent( w, &alpha[i] ) )
{
@@ -403,15 +315,15 @@ static hb_buffer_t * CropSubtitle( hb_work_object_t * w, uint8_t * raw )
realheight = crop[1] - crop[0] + 1;
buf = hb_buffer_init( realwidth * realheight * 2 );
- buf->start = w->pts_start;
- buf->stop = w->pts_stop;
- buf->x = w->x + crop[2];
- buf->y = w->y + crop[0];
+ buf->start = pv->pts_start;
+ buf->stop = pv->pts_stop;
+ buf->x = pv->x + crop[2];
+ buf->y = pv->y + crop[0];
buf->width = realwidth;
buf->height = realheight;
- lum_in = raw + crop[0] * w->width + crop[2];
- alpha_in = lum_in + w->width * w->height;
+ lum_in = raw + crop[0] * pv->width + crop[2];
+ alpha_in = lum_in + pv->width * pv->height;
lum_out = buf->data;
alpha_out = lum_out + realwidth * realheight;
@@ -419,11 +331,85 @@ static hb_buffer_t * CropSubtitle( hb_work_object_t * w, uint8_t * raw )
{
memcpy( lum_out, lum_in, realwidth );
memcpy( alpha_out, alpha_in, realwidth );
- lum_in += w->width;
- alpha_in += w->width;
+ lum_in += pv->width;
+ alpha_in += pv->width;
lum_out += realwidth;
alpha_out += realwidth;
}
return buf;
}
+
+static hb_buffer_t * Decode( hb_work_object_t * w )
+{
+ hb_work_private_t * pv = w->private_data;
+ int code, line, col;
+ int offsets[2];
+ int * offset;
+ hb_buffer_t * buf;
+ uint8_t * buf_raw = NULL;
+
+ /* Get infos about the subtitle */
+ ParseControls( w );
+
+ /* Do the actual decoding now */
+ buf_raw = malloc( pv->width * pv->height * 2 );
+
+#define GET_NEXT_NIBBLE code = ( code << 4 ) | ( ( ( *offset & 1 ) ? \
+( pv->buf[((*offset)>>1)] & 0xF ) : ( pv->buf[((*offset)>>1)] >> 4 ) ) ); \
+(*offset)++
+
+ offsets[0] = pv->offsets[0] * 2;
+ offsets[1] = pv->offsets[1] * 2;
+
+ for( line = 0; line < pv->height; line++ )
+ {
+ /* Select even or odd field */
+ offset = ( line & 1 ) ? &offsets[1] : &offsets[0];
+
+ for( col = 0; col < pv->width; col += code >> 2 )
+ {
+ uint8_t * lum, * alpha;
+
+ code = 0;
+ GET_NEXT_NIBBLE;
+ if( code < 0x4 )
+ {
+ GET_NEXT_NIBBLE;
+ if( code < 0x10 )
+ {
+ GET_NEXT_NIBBLE;
+ if( code < 0x40 )
+ {
+ GET_NEXT_NIBBLE;
+ if( code < 0x100 )
+ {
+ /* End of line */
+ code |= ( pv->width - col ) << 2;
+ }
+ }
+ }
+ }
+
+ lum = buf_raw;
+ alpha = lum + pv->width * pv->height;
+ memset( lum + line * pv->width + col,
+ pv->lum[code & 3], code >> 2 );
+ memset( alpha + line * pv->width + col,
+ pv->alpha[code & 3], code >> 2 );
+ }
+
+ /* Byte-align */
+ if( *offset & 1 )
+ {
+ (*offset)++;
+ }
+ }
+
+ /* Crop subtitle (remove transparent borders) */
+ buf = CropSubtitle( w, buf_raw );
+
+ free( buf_raw );
+
+ return buf;
+}
diff --git a/libhb/encavcodec.c b/libhb/encavcodec.c
index deff7c527..45c79fddc 100644
--- a/libhb/encavcodec.c
+++ b/libhb/encavcodec.c
@@ -8,38 +8,35 @@
#include "ffmpeg/avcodec.h"
-struct hb_work_object_s
+struct hb_work_private_s
{
- HB_WORK_COMMON;
-
hb_job_t * job;
AVCodecContext * context;
FILE * file;
};
-/***********************************************************************
- * Local prototypes
- **********************************************************************/
-static void Close( hb_work_object_t ** _w );
-static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
- hb_buffer_t ** buf_out );
+int encavcodecInit( hb_work_object_t *, hb_job_t * );
+int encavcodecWork( hb_work_object_t *, hb_buffer_t **, hb_buffer_t ** );
+void encavcodecClose( hb_work_object_t * );
-/***********************************************************************
- * hb_work_encavcodec_init
- ***********************************************************************
- *
- **********************************************************************/
-hb_work_object_t * hb_work_encavcodec_init( hb_job_t * job )
+hb_work_object_t hb_encavcodec =
+{
+ WORK_DECSUB,
+ "MPEG-4 encoder (libavcodec)",
+ encavcodecInit,
+ encavcodecWork,
+ encavcodecClose
+};
+
+int encavcodecInit( hb_work_object_t * w, hb_job_t * job )
{
AVCodec * codec;
AVCodecContext * context;
- hb_work_object_t * w = calloc( sizeof( hb_work_object_t ), 1 );
- w->name = strdup( "MPEG-4 encoder (libavcodec)" );
- w->work = Work;
- w->close = Close;
+ hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
+ w->private_data = pv;
- w->job = job;
+ pv->job = job;
codec = avcodec_find_encoder( CODEC_ID_MPEG4 );
if( !codec )
@@ -84,7 +81,7 @@ hb_work_object_t * hb_work_encavcodec_init( hb_job_t * job )
if( job->pass == 1 )
{
- w->file = fopen( filename, "wb" );
+ pv->file = fopen( filename, "wb" );
context->flags |= CODEC_FLAG_PASS1;
}
else
@@ -92,15 +89,15 @@ hb_work_object_t * hb_work_encavcodec_init( hb_job_t * job )
int size;
char * log;
- w->file = fopen( filename, "rb" );
- fseek( w->file, 0, SEEK_END );
- size = ftell( w->file );
- fseek( w->file, 0, SEEK_SET );
+ pv->file = fopen( filename, "rb" );
+ fseek( pv->file, 0, SEEK_END );
+ size = ftell( pv->file );
+ fseek( pv->file, 0, SEEK_SET );
log = malloc( size + 1 );
log[size] = '\0';
- fread( log, size, 1, w->file );
- fclose( w->file );
- w->file = NULL;
+ fread( log, size, 1, pv->file );
+ fclose( pv->file );
+ pv->file = NULL;
context->flags |= CODEC_FLAG_PASS2;
context->stats_in = log;
@@ -111,19 +108,16 @@ hb_work_object_t * hb_work_encavcodec_init( hb_job_t * job )
{
hb_log( "hb_work_encavcodec_init: avcodec_open failed" );
}
- w->context = context;
+ pv->context = context;
if( ( job->mux & HB_MUX_MP4 ) && job->pass != 1 )
{
-#define c job->config.mpeg4
/* Hem hem */
- c.config = malloc( 15 );
- c.config_length = 15;
- memcpy( c.config, context->extradata + 15, 15 );
-#undef c
+ w->config->mpeg4.length = 15;
+ memcpy( w->config->mpeg4.bytes, context->extradata + 15, 15 );
}
- return w;
+ return 0;
}
/***********************************************************************
@@ -131,30 +125,19 @@ hb_work_object_t * hb_work_encavcodec_init( hb_job_t * job )
***********************************************************************
*
**********************************************************************/
-static void Close( hb_work_object_t ** _w )
+void encavcodecClose( hb_work_object_t * w )
{
- hb_work_object_t * w = *_w;
- hb_job_t * job = w->job;
+ hb_work_private_t * pv = w->private_data;
- if( w->context )
+ if( pv->context )
{
hb_log( "encavcodec: closing libavcodec" );
- avcodec_close( w->context );
+ avcodec_close( pv->context );
}
- if( w->file )
+ if( pv->file )
{
- fclose( w->file );
+ fclose( pv->file );
}
- if( job->es_config )
- {
- free( job->es_config );
- job->es_config = NULL;
- job->es_config_length = 0;
- }
-
- free( w->name );
- free( w );
- *_w = NULL;
}
/***********************************************************************
@@ -162,10 +145,11 @@ static void Close( hb_work_object_t ** _w )
***********************************************************************
*
**********************************************************************/
-static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
- hb_buffer_t ** buf_out )
+int encavcodecWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
+ hb_buffer_t ** buf_out )
{
- hb_job_t * job = w->job;
+ hb_work_private_t * pv = w->private_data;
+ hb_job_t * job = pv->job;
AVFrame * frame;
hb_buffer_t * in = *buf_in, * buf;
@@ -179,18 +163,18 @@ static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
/* Should be way too large */
buf = hb_buffer_init( 3 * job->width * job->height / 2 );
- buf->size = avcodec_encode_video( w->context, buf->data, buf->alloc,
+ buf->size = avcodec_encode_video( pv->context, buf->data, buf->alloc,
frame );
buf->start = in->start;
buf->stop = in->stop;
- buf->key = w->context->coded_frame->key_frame;
+ buf->key = pv->context->coded_frame->key_frame;
av_free( frame );
if( job->pass == 1 )
{
/* Write stats */
- fprintf( w->file, "%s", w->context->stats_out );
+ fprintf( pv->file, "%s", pv->context->stats_out );
}
*buf_out = buf;
diff --git a/libhb/encfaac.c b/libhb/encfaac.c
index a5b704f4c..4c0d19e72 100644
--- a/libhb/encfaac.c
+++ b/libhb/encfaac.c
@@ -8,12 +8,9 @@
#include "faac.h"
-struct hb_work_object_s
+struct hb_work_private_s
{
- HB_WORK_COMMON;
-
hb_job_t * job;
- hb_audio_t * audio;
faacEncHandle * faac;
unsigned long input_samples;
@@ -24,34 +21,38 @@ struct hb_work_object_s
int64_t pts;
};
-/***********************************************************************
- * Local prototypes
- **********************************************************************/
-static void Close( hb_work_object_t ** _w );
-static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
- hb_buffer_t ** buf_out );
+int encfaacInit( hb_work_object_t *, hb_job_t * );
+int encfaacWork( hb_work_object_t *, hb_buffer_t **, hb_buffer_t ** );
+void encfaacClose( hb_work_object_t * );
+
+hb_work_object_t hb_encfaac =
+{
+ WORK_ENCFAAC,
+ "AAC encoder (libfaac)",
+ encfaacInit,
+ encfaacWork,
+ encfaacClose
+};
/***********************************************************************
* hb_work_encfaac_init
***********************************************************************
*
**********************************************************************/
-hb_work_object_t * hb_work_encfaac_init( hb_job_t * job, hb_audio_t * audio )
+int encfaacInit( hb_work_object_t * w, hb_job_t * job )
{
- hb_work_object_t * w = calloc( sizeof( hb_work_object_t ), 1 );
+ hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
+ w->private_data = pv;
+
faacEncConfigurationPtr cfg;
- w->name = strdup( "AAC encoder (libfaac)" );
- w->work = Work;
- w->close = Close;
- w->job = job;
- w->audio = audio;
+ pv->job = job;
- w->faac = faacEncOpen( job->arate, 2, &w->input_samples,
- &w->output_bytes );
- w->buf = malloc( w->input_samples * sizeof( float ) );
+ pv->faac = faacEncOpen( job->arate, 2, &pv->input_samples,
+ &pv->output_bytes );
+ pv->buf = malloc( pv->input_samples * sizeof( float ) );
- cfg = faacEncGetCurrentConfiguration( w->faac );
+ cfg = faacEncGetCurrentConfiguration( pv->faac );
cfg->mpegVersion = MPEG4;
cfg->aacObjectType = LOW;
cfg->allowMidside = 1;
@@ -61,20 +62,25 @@ hb_work_object_t * hb_work_encfaac_init( hb_job_t * job, hb_audio_t * audio )
cfg->bandWidth = 0;
cfg->outputFormat = 0;
cfg->inputFormat = FAAC_INPUT_FLOAT;
- if( !faacEncSetConfiguration( w->faac, cfg ) )
+ if( !faacEncSetConfiguration( pv->faac, cfg ) )
{
hb_log( "faacEncSetConfiguration failed" );
}
- if( faacEncGetDecoderSpecificInfo( w->faac, &audio->config.faac.decinfo,
- &audio->config.faac.size ) < 0 )
+
+ uint8_t * bytes;
+ unsigned long length;
+ if( faacEncGetDecoderSpecificInfo( pv->faac, &bytes, &length ) < 0 )
{
hb_log( "faacEncGetDecoderSpecificInfo failed" );
}
+ memcpy( w->config->aac.bytes, bytes, length );
+ w->config->aac.length = length;
+ free( bytes );
- w->list = hb_list_init();
- w->pts = -1;
+ pv->list = hb_list_init();
+ pv->pts = -1;
- return w;
+ return 0;
}
/***********************************************************************
@@ -82,18 +88,12 @@ hb_work_object_t * hb_work_encfaac_init( hb_job_t * job, hb_audio_t * audio )
***********************************************************************
*
**********************************************************************/
-static void Close( hb_work_object_t ** _w )
+void encfaacClose( hb_work_object_t * w )
{
- hb_work_object_t * w = *_w;
-
- faacEncClose( w->faac );
- free( w->buf );
- hb_list_empty( &w->list );
- free( w->audio->config.faac.decinfo );
-
- free( w->name );
- free( w );
- *_w = NULL;
+ hb_work_private_t * pv = w->private_data;
+ faacEncClose( pv->faac );
+ free( pv->buf );
+ hb_list_empty( &pv->list );
}
/***********************************************************************
@@ -103,24 +103,25 @@ static void Close( hb_work_object_t ** _w )
**********************************************************************/
static hb_buffer_t * Encode( hb_work_object_t * w )
{
+ hb_work_private_t * pv = w->private_data;
hb_buffer_t * buf;
uint64_t pts;
int pos;
- if( hb_list_bytes( w->list ) < w->input_samples * sizeof( float ) )
+ if( hb_list_bytes( pv->list ) < pv->input_samples * sizeof( float ) )
{
/* Need more data */
return NULL;
}
- hb_list_getbytes( w->list, w->buf, w->input_samples * sizeof( float ),
+ hb_list_getbytes( pv->list, pv->buf, pv->input_samples * sizeof( float ),
&pts, &pos );
- buf = hb_buffer_init( w->output_bytes );
- buf->start = pts + 90000 * pos / 2 / sizeof( float ) / w->job->arate;
- buf->stop = buf->start + 90000 * w->input_samples / w->job->arate / 2;
- buf->size = faacEncEncode( w->faac, (int32_t *) w->buf,
- w->input_samples, buf->data, w->output_bytes );
+ buf = hb_buffer_init( pv->output_bytes );
+ buf->start = pts + 90000 * pos / 2 / sizeof( float ) / pv->job->arate;
+ buf->stop = buf->start + 90000 * pv->input_samples / pv->job->arate / 2;
+ buf->size = faacEncEncode( pv->faac, (int32_t *) pv->buf,
+ pv->input_samples, buf->data, pv->output_bytes );
buf->key = 1;
if( !buf->size )
@@ -145,12 +146,13 @@ static hb_buffer_t * Encode( hb_work_object_t * w )
***********************************************************************
*
**********************************************************************/
-static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
+int encfaacWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
hb_buffer_t ** buf_out )
{
+ hb_work_private_t * pv = w->private_data;
hb_buffer_t * buf;
- hb_list_add( w->list, *buf_in );
+ hb_list_add( pv->list, *buf_in );
*buf_in = NULL;
*buf_out = buf = Encode( w );
diff --git a/libhb/enclame.c b/libhb/enclame.c
index 19014ac26..f663e62eb 100644
--- a/libhb/enclame.c
+++ b/libhb/enclame.c
@@ -8,12 +8,22 @@
#include "lame/lame.h"
-struct hb_work_object_s
+int enclameInit( hb_work_object_t *, hb_job_t * );
+int enclameWork( hb_work_object_t *, hb_buffer_t **, hb_buffer_t ** );
+void enclameClose( hb_work_object_t * );
+
+hb_work_object_t hb_enclame =
{
- HB_WORK_COMMON;
+ WORK_ENCLAME,
+ "MP3 encoder (libmp3lame)",
+ enclameInit,
+ enclameWork,
+ enclameClose
+};
+struct hb_work_private_s
+{
hb_job_t * job;
- hb_audio_t * audio;
/* LAME handle */
lame_global_flags * lame;
@@ -26,44 +36,29 @@ struct hb_work_object_s
int64_t pts;
};
-/***********************************************************************
- * Local prototypes
- **********************************************************************/
-static void Close( hb_work_object_t ** _w );
-static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
- hb_buffer_t ** buf_out );
-
-/***********************************************************************
- * hb_work_enclame_init
- ***********************************************************************
- *
- **********************************************************************/
-hb_work_object_t * hb_work_enclame_init( hb_job_t * job, hb_audio_t * audio )
+int enclameInit( hb_work_object_t * w, hb_job_t * job )
{
- hb_work_object_t * w = calloc( sizeof( hb_work_object_t ), 1 );
- w->name = strdup( "MP3 encoder (libmp3lame)" );
- w->work = Work;
- w->close = Close;
+ hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
+ w->private_data = pv;
- w->job = job;
- w->audio = audio;
+ pv->job = job;
hb_log( "enclame: opening libmp3lame" );
- w->lame = lame_init();
- lame_set_brate( w->lame, job->abitrate );
- lame_set_in_samplerate( w->lame, job->arate );
- lame_set_out_samplerate( w->lame, job->arate );
- lame_init_params( w->lame );
+ pv->lame = lame_init();
+ lame_set_brate( pv->lame, job->abitrate );
+ lame_set_in_samplerate( pv->lame, job->arate );
+ lame_set_out_samplerate( pv->lame, job->arate );
+ lame_init_params( pv->lame );
- w->input_samples = 1152 * 2;
- w->output_bytes = LAME_MAXMP3BUFFER;
- w->buf = malloc( w->input_samples * sizeof( float ) );
+ pv->input_samples = 1152 * 2;
+ pv->output_bytes = LAME_MAXMP3BUFFER;
+ pv->buf = malloc( pv->input_samples * sizeof( float ) );
- w->list = hb_list_init();
- w->pts = -1;
+ pv->list = hb_list_init();
+ pv->pts = -1;
- return w;
+ return 0;
}
/***********************************************************************
@@ -71,12 +66,8 @@ hb_work_object_t * hb_work_enclame_init( hb_job_t * job, hb_audio_t * audio )
***********************************************************************
*
**********************************************************************/
-static void Close( hb_work_object_t ** _w )
+void enclameClose( hb_work_object_t * w )
{
- hb_work_object_t * w = *_w;
- free( w->name );
- free( w );
- *_w = NULL;
}
/***********************************************************************
@@ -86,28 +77,29 @@ static void Close( hb_work_object_t ** _w )
**********************************************************************/
static hb_buffer_t * Encode( hb_work_object_t * w )
{
+ hb_work_private_t * pv = w->private_data;
hb_buffer_t * buf;
int16_t samples_s16[1152 * 2];
uint64_t pts;
int pos, i;
- if( hb_list_bytes( w->list ) < w->input_samples * sizeof( float ) )
+ if( hb_list_bytes( pv->list ) < pv->input_samples * sizeof( float ) )
{
return NULL;
}
- hb_list_getbytes( w->list, w->buf, w->input_samples * sizeof( float ),
+ hb_list_getbytes( pv->list, pv->buf, pv->input_samples * sizeof( float ),
&pts, &pos);
for( i = 0; i < 1152 * 2; i++ )
{
- samples_s16[i] = ((float*) w->buf)[i];
+ samples_s16[i] = ((float*) pv->buf)[i];
}
- buf = hb_buffer_init( w->output_bytes );
- buf->start = pts + 90000 * pos / 2 / sizeof( float ) / w->job->arate;
- buf->stop = buf->start + 90000 * 1152 / w->job->arate;
- buf->size = lame_encode_buffer_interleaved( w->lame, samples_s16,
+ buf = hb_buffer_init( pv->output_bytes );
+ buf->start = pts + 90000 * pos / 2 / sizeof( float ) / pv->job->arate;
+ buf->stop = buf->start + 90000 * 1152 / pv->job->arate;
+ buf->size = lame_encode_buffer_interleaved( pv->lame, samples_s16,
1152, buf->data, LAME_MAXMP3BUFFER );
buf->key = 1;
@@ -133,12 +125,13 @@ static hb_buffer_t * Encode( hb_work_object_t * w )
***********************************************************************
*
**********************************************************************/
-static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
+int enclameWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
hb_buffer_t ** buf_out )
{
+ hb_work_private_t * pv = w->private_data;
hb_buffer_t * buf;
- hb_list_add( w->list, *buf_in );
+ hb_list_add( pv->list, *buf_in );
*buf_in = NULL;
*buf_out = buf = Encode( w );
diff --git a/libhb/encvorbis.c b/libhb/encvorbis.c
index 86b824372..4bdb6efeb 100644
--- a/libhb/encvorbis.c
+++ b/libhb/encvorbis.c
@@ -10,12 +10,22 @@
#define OGGVORBIS_FRAME_SIZE 1024
-struct hb_work_object_s
+int encvorbisInit( hb_work_object_t *, hb_job_t * );
+int encvorbisWork( hb_work_object_t *, hb_buffer_t **, hb_buffer_t ** );
+void encvorbisClose( hb_work_object_t * );
+
+hb_work_object_t hb_encvorbis =
{
- HB_WORK_COMMON;
+ WORK_ENCVORBIS,
+ "Vorbis encoder (libvorbis)",
+ encvorbisInit,
+ encvorbisWork,
+ encvorbisClose
+};
+struct hb_work_private_s
+{
hb_job_t * job;
- hb_audio_t * audio;
vorbis_info vi;
vorbis_comment vc;
@@ -29,70 +39,53 @@ struct hb_work_object_s
hb_list_t * list;
};
-/***********************************************************************
- * Local prototypes
- **********************************************************************/
-static void Close( hb_work_object_t ** _w );
-static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
- hb_buffer_t ** buf_out );
-
-/***********************************************************************
- * hb_work_encvorbis_init
- ***********************************************************************
- *
- **********************************************************************/
-hb_work_object_t * hb_work_encvorbis_init( hb_job_t * job, hb_audio_t * audio )
+int encvorbisInit( hb_work_object_t * w, hb_job_t * job )
{
int i;
ogg_packet header[3];
- hb_work_object_t * w = calloc( sizeof( hb_work_object_t ), 1 );
- w->name = strdup( "Vorbis encoder (libvorbis)" );
- w->work = Work;
- w->close = Close;
+ hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
+ w->private_data = pv;
- w->job = job;
- w->audio = audio;
+ pv->job = job;
hb_log( "encvorbis: opening libvorbis" );
/* init */
- vorbis_info_init( &w->vi );
- if( vorbis_encode_setup_managed( &w->vi, 2,
+ vorbis_info_init( &pv->vi );
+ if( vorbis_encode_setup_managed( &pv->vi, 2,
job->arate, -1, 1000 * job->abitrate, -1 ) ||
- vorbis_encode_ctl( &w->vi, OV_ECTL_RATEMANAGE_AVG, NULL ) ||
- vorbis_encode_setup_init( &w->vi ) )
+ vorbis_encode_ctl( &pv->vi, OV_ECTL_RATEMANAGE_AVG, NULL ) ||
+ vorbis_encode_setup_init( &pv->vi ) )
{
hb_log( "encvorbis: vorbis_encode_setup_managed failed" );
}
/* add a comment */
- vorbis_comment_init( &w->vc );
- vorbis_comment_add_tag( &w->vc, "Encoder", "HandBrake");
+ vorbis_comment_init( &pv->vc );
+ vorbis_comment_add_tag( &pv->vc, "Encoder", "HandBrake");
/* set up the analysis state and auxiliary encoding storage */
- vorbis_analysis_init( &w->vd, &w->vi);
- vorbis_block_init( &w->vd, &w->vb);
+ vorbis_analysis_init( &pv->vd, &pv->vi);
+ vorbis_block_init( &pv->vd, &pv->vb);
/* get the 3 headers */
- vorbis_analysis_headerout( &w->vd, &w->vc,
+ vorbis_analysis_headerout( &pv->vd, &pv->vc,
&header[0], &header[1], &header[2] );
for( i = 0; i < 3; i++ )
{
- audio->config.vorbis.headers[i] =
- malloc( sizeof( ogg_packet ) + header[i].bytes );
- memcpy( audio->config.vorbis.headers[i], &header[i],
+ memcpy( w->config->vorbis.headers[i], &header[i],
sizeof( ogg_packet ) );
- memcpy( audio->config.vorbis.headers[i] + sizeof( ogg_packet ),
+ memcpy( w->config->vorbis.headers[i] + sizeof( ogg_packet ),
header[i].packet, header[i].bytes );
}
- w->input_samples = 2 * OGGVORBIS_FRAME_SIZE;
- w->buf = malloc( w->input_samples * sizeof( float ) );
+ pv->input_samples = 2 * OGGVORBIS_FRAME_SIZE;
+ pv->buf = malloc( pv->input_samples * sizeof( float ) );
- w->list = hb_list_init();
+ pv->list = hb_list_init();
- return w;
+ return 0;
}
/***********************************************************************
@@ -100,12 +93,8 @@ hb_work_object_t * hb_work_encvorbis_init( hb_job_t * job, hb_audio_t * audio )
***********************************************************************
*
**********************************************************************/
-static void Close( hb_work_object_t ** _w )
+void encvorbisClose( hb_work_object_t * w )
{
- hb_work_object_t * w = *_w;
- free( w->name );
- free( w );
- *_w = NULL;
}
/***********************************************************************
@@ -115,26 +104,27 @@ static void Close( hb_work_object_t ** _w )
**********************************************************************/
static hb_buffer_t * Flush( hb_work_object_t * w )
{
+ hb_work_private_t * pv = w->private_data;
hb_buffer_t * buf;
- if( vorbis_analysis_blockout( &w->vd, &w->vb ) == 1 )
+ if( vorbis_analysis_blockout( &pv->vd, &pv->vb ) == 1 )
{
ogg_packet op;
- vorbis_analysis( &w->vb, NULL );
- vorbis_bitrate_addblock( &w->vb );
+ vorbis_analysis( &pv->vb, NULL );
+ vorbis_bitrate_addblock( &pv->vb );
- if( vorbis_bitrate_flushpacket( &w->vd, &op ) )
+ if( vorbis_bitrate_flushpacket( &pv->vd, &op ) )
{
buf = hb_buffer_init( sizeof( ogg_packet ) + op.bytes );
memcpy( buf->data, &op, sizeof( ogg_packet ) );
memcpy( buf->data + sizeof( ogg_packet ), op.packet,
op.bytes );
buf->key = 1;
- buf->start = w->pts; /* No exact, but who cares - the OGM
+ buf->start = pv->pts; /* No exact, but who cares - the OGM
muxer doesn't use it */
buf->stop = buf->start +
- 90000 * OGGVORBIS_FRAME_SIZE + w->job->arate;
+ 90000 * OGGVORBIS_FRAME_SIZE + pv->job->arate;
return buf;
}
@@ -150,6 +140,7 @@ static hb_buffer_t * Flush( hb_work_object_t * w )
**********************************************************************/
static hb_buffer_t * Encode( hb_work_object_t * w )
{
+ hb_work_private_t * pv = w->private_data;
hb_buffer_t * buf;
float ** buffer;
int i;
@@ -160,21 +151,21 @@ static hb_buffer_t * Encode( hb_work_object_t * w )
return buf;
}
- if( hb_list_bytes( w->list ) < w->input_samples * sizeof( float ) )
+ if( hb_list_bytes( pv->list ) < pv->input_samples * sizeof( float ) )
{
return NULL;
}
/* Process more samples */
- hb_list_getbytes( w->list, w->buf, w->input_samples * sizeof( float ),
- &w->pts, NULL );
- buffer = vorbis_analysis_buffer( &w->vd, OGGVORBIS_FRAME_SIZE );
+ hb_list_getbytes( pv->list, pv->buf, pv->input_samples * sizeof( float ),
+ &pv->pts, NULL );
+ buffer = vorbis_analysis_buffer( &pv->vd, OGGVORBIS_FRAME_SIZE );
for( i = 0; i < OGGVORBIS_FRAME_SIZE; i++ )
{
- buffer[0][i] = ((float *) w->buf)[2*i] / 32768.f;
- buffer[1][i] = ((float *) w->buf)[2*i+1] / 32768.f;
+ buffer[0][i] = ((float *) pv->buf)[2*i] / 32768.f;
+ buffer[1][i] = ((float *) pv->buf)[2*i+1] / 32768.f;
}
- vorbis_analysis_wrote( &w->vd, OGGVORBIS_FRAME_SIZE );
+ vorbis_analysis_wrote( &pv->vd, OGGVORBIS_FRAME_SIZE );
/* Try to extract again */
return Flush( w );
@@ -185,12 +176,13 @@ static hb_buffer_t * Encode( hb_work_object_t * w )
***********************************************************************
*
**********************************************************************/
-static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
- hb_buffer_t ** buf_out )
+int encvorbisWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
+ hb_buffer_t ** buf_out )
{
+ hb_work_private_t * pv = w->private_data;
hb_buffer_t * buf;
- hb_list_add( w->list, *buf_in );
+ hb_list_add( pv->list, *buf_in );
*buf_in = NULL;
*buf_out = buf = Encode( w );
diff --git a/libhb/encx264.c b/libhb/encx264.c
index cf58452e7..806fc4c88 100644
--- a/libhb/encx264.c
+++ b/libhb/encx264.c
@@ -10,10 +10,21 @@
#include "x264.h"
-struct hb_work_object_s
+int encx264Init( hb_work_object_t *, hb_job_t * );
+int encx264Work( hb_work_object_t *, hb_buffer_t **, hb_buffer_t ** );
+void encx264Close( hb_work_object_t * );
+
+hb_work_object_t hb_encx264 =
{
- HB_WORK_COMMON;
+ WORK_ENCX264,
+ "H.264/AVC encoder (libx264)",
+ encx264Init,
+ encx264Work,
+ encx264Close
+};
+struct hb_work_private_s
+{
hb_job_t * job;
x264_t * x264;
x264_picture_t pic_in;
@@ -23,33 +34,23 @@ struct hb_work_object_s
};
/***********************************************************************
- * Local prototypes
- **********************************************************************/
-static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
- hb_buffer_t ** buf_out );
-static void Close( hb_work_object_t ** _w );
-
-/***********************************************************************
* hb_work_encx264_init
***********************************************************************
*
**********************************************************************/
-hb_work_object_t * hb_work_encx264_init( hb_job_t * job )
+int encx264Init( hb_work_object_t * w, hb_job_t * job )
{
- hb_work_object_t * w;
x264_param_t param;
x264_nal_t * nal;
int nal_count;
- w = calloc( sizeof( hb_work_object_t ), 1 );
- w->name = strdup( "AVC encoder (libx264)" );
- w->work = Work;
- w->close = Close;
+ hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
+ w->private_data = pv;
- w->job = job;
+ pv->job = job;
- memset( w->filename, 0, 1024 );
- hb_get_tempory_filename( job->h, w->filename, "x264.log" );
+ memset( pv->filename, 0, 1024 );
+ hb_get_tempory_filename( job->h, pv->filename, "x264.log" );
x264_param_default( &param );
@@ -85,83 +86,75 @@ hb_work_object_t * hb_work_encx264_init( hb_job_t * job )
{
case 1:
param.rc.b_stat_write = 1;
- param.rc.psz_stat_out = w->filename;
+ param.rc.psz_stat_out = pv->filename;
break;
case 2:
param.rc.b_stat_read = 1;
- param.rc.psz_stat_in = w->filename;
+ param.rc.psz_stat_in = pv->filename;
break;
}
}
hb_log( "encx264: opening libx264 (pass %d)", job->pass );
- w->x264 = x264_encoder_open( &param );
+ pv->x264 = x264_encoder_open( &param );
-#define c job->config.h264
- x264_encoder_headers( w->x264, &nal, &nal_count );
+ x264_encoder_headers( pv->x264, &nal, &nal_count );
/* Sequence Parameter Set */
- c.sps_length = 1 + nal[1].i_payload;
- c.sps = malloc( c.sps_length);
- c.sps[0] = 0x67;
- memcpy( &c.sps[1], nal[1].p_payload, nal[1].i_payload );
+ w->config->h264.sps_length = 1 + nal[1].i_payload;
+ w->config->h264.sps[0] = 0x67;
+ memcpy( &w->config->h264.sps[1], nal[1].p_payload, nal[1].i_payload );
/* Picture Parameter Set */
- c.pps_length = 1 + nal[2].i_payload;
- c.pps = malloc( c.pps_length );
- c.pps[0] = 0x68;
- memcpy( &c.pps[1], nal[2].p_payload, nal[2].i_payload );
-#undef c
+ w->config->h264.pps_length = 1 + nal[2].i_payload;
+ w->config->h264.pps[0] = 0x68;
+ memcpy( &w->config->h264.pps[1], nal[2].p_payload, nal[2].i_payload );
- x264_picture_alloc( &w->pic_in, X264_CSP_I420,
+ x264_picture_alloc( &pv->pic_in, X264_CSP_I420,
job->width, job->height );
- return w;
+ return 0;
}
-static void Close( hb_work_object_t ** _w )
+void encx264Close( hb_work_object_t * w )
{
- hb_work_object_t * w = *_w;
-
- x264_encoder_close( w->x264 );
+ hb_work_private_t * pv = w->private_data;
+ x264_encoder_close( pv->x264 );
/* TODO */
-
- free( w->name );
- free( w );
- *_w = NULL;
}
-static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
- hb_buffer_t ** buf_out )
+int encx264Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
+ hb_buffer_t ** buf_out )
{
- hb_job_t * job = w->job;
+ hb_work_private_t * pv = w->private_data;
+ hb_job_t * job = pv->job;
hb_buffer_t * in = *buf_in, * buf;
int i_nal;
x264_nal_t * nal;
int i;
/* XXX avoid this memcpy ? */
- memcpy( w->pic_in.img.plane[0], in->data, job->width * job->height );
+ memcpy( pv->pic_in.img.plane[0], in->data, job->width * job->height );
if( job->grayscale )
{
/* XXX x264 has currently no option for grayscale encoding */
- memset( w->pic_in.img.plane[1], 0x80, job->width * job->height / 4 );
- memset( w->pic_in.img.plane[2], 0x80, job->width * job->height / 4 );
+ memset( pv->pic_in.img.plane[1], 0x80, job->width * job->height / 4 );
+ memset( pv->pic_in.img.plane[2], 0x80, job->width * job->height / 4 );
}
else
{
- memcpy( w->pic_in.img.plane[1], in->data + job->width * job->height,
+ memcpy( pv->pic_in.img.plane[1], in->data + job->width * job->height,
job->width * job->height / 4 );
- memcpy( w->pic_in.img.plane[2], in->data + 5 * job->width *
+ memcpy( pv->pic_in.img.plane[2], in->data + 5 * job->width *
job->height / 4, job->width * job->height / 4 );
}
- w->pic_in.i_type = X264_TYPE_AUTO;
- w->pic_in.i_qpplus1 = 0;
+ pv->pic_in.i_type = X264_TYPE_AUTO;
+ pv->pic_in.i_qpplus1 = 0;
- x264_encoder_encode( w->x264, &nal, &i_nal,
- &w->pic_in, &w->pic_out );
+ x264_encoder_encode( pv->x264, &nal, &i_nal,
+ &pv->pic_in, &pv->pic_out );
/* Should be way too large */
buf = hb_buffer_init( 3 * job->width * job->height / 2 );
diff --git a/libhb/encxvid.c b/libhb/encxvid.c
index a874d9f00..87c42b0a4 100644
--- a/libhb/encxvid.c
+++ b/libhb/encxvid.c
@@ -8,29 +8,29 @@
#include "xvid.h"
-struct hb_work_object_s
+int encxvidInit( hb_work_object_t *, hb_job_t * );
+int encxvidWork( hb_work_object_t *, hb_buffer_t **, hb_buffer_t ** );
+void encxvidClose( hb_work_object_t * );
+
+hb_work_object_t hb_encxvid =
{
- HB_WORK_COMMON;
+ WORK_ENCXVID,
+ "MPEG-4 encoder (libxvidcore)",
+ encxvidInit,
+ encxvidWork,
+ encxvidClose
+};
+struct hb_work_private_s
+{
hb_job_t * job;
void * xvid;
char filename[1024];
int quant;
+ int configDone;
};
-/***********************************************************************
- * Local prototypes
- **********************************************************************/
-static void Close( hb_work_object_t ** _w );
-static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
- hb_buffer_t ** buf_out );
-
-/***********************************************************************
- * hb_work_encxvid_init
- ***********************************************************************
- *
- **********************************************************************/
-hb_work_object_t * hb_work_encxvid_init( hb_job_t * job )
+int encxvidInit( hb_work_object_t * w, hb_job_t * job )
{
xvid_gbl_init_t xvid_gbl_init;
xvid_enc_create_t create;
@@ -39,15 +39,13 @@ hb_work_object_t * hb_work_encxvid_init( hb_job_t * job )
xvid_plugin_2pass2_t rc2pass2;
xvid_enc_plugin_t plugins[1];
- hb_work_object_t * w = calloc( sizeof( hb_work_object_t ), 1 );
- w->name = strdup( "MPEG-4 encoder (libxvidcore)" );
- w->work = Work;
- w->close = Close;
+ hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
+ w->private_data = pv;
- w->job = job;
+ pv->job = job;
- memset( w->filename, 0, 1024 );
- hb_get_tempory_filename( job->h, w->filename, "xvid.log" );
+ memset( pv->filename, 0, 1024 );
+ hb_get_tempory_filename( job->h, pv->filename, "xvid.log" );
memset( &xvid_gbl_init, 0, sizeof( xvid_gbl_init ) );
xvid_gbl_init.version = XVID_VERSION;
@@ -69,14 +67,14 @@ hb_work_object_t * hb_work_encxvid_init( hb_job_t * job )
{
/* Rate control */
single.bitrate = 1000 * job->vbitrate;
- w->quant = 0;
+ pv->quant = 0;
}
else
{
/* Constant quantizer */
- w->quant = 31 - job->vquality * 30;
+ pv->quant = 31 - job->vquality * 30;
hb_log( "encxvid: encoding at constant quantizer %d",
- w->quant );
+ pv->quant );
}
plugins[0].func = xvid_plugin_single;
plugins[0].param = &single;
@@ -85,7 +83,7 @@ hb_work_object_t * hb_work_encxvid_init( hb_job_t * job )
case 1:
memset( &rc2pass1, 0, sizeof( rc2pass1 ) );
rc2pass1.version = XVID_VERSION;
- rc2pass1.filename = w->filename;
+ rc2pass1.filename = pv->filename;
plugins[0].func = xvid_plugin_2pass1;
plugins[0].param = &rc2pass1;
break;
@@ -93,7 +91,7 @@ hb_work_object_t * hb_work_encxvid_init( hb_job_t * job )
case 2:
memset( &rc2pass2, 0, sizeof( rc2pass2 ) );
rc2pass2.version = XVID_VERSION;
- rc2pass2.filename = w->filename;
+ rc2pass2.filename = pv->filename;
rc2pass2.bitrate = 1000 * job->vbitrate;
plugins[0].func = xvid_plugin_2pass2;
plugins[0].param = &rc2pass2;
@@ -114,9 +112,9 @@ hb_work_object_t * hb_work_encxvid_init( hb_job_t * job )
create.global = 0;
xvid_encore( NULL, XVID_ENC_CREATE, &create, NULL );
- w->xvid = create.handle;
+ pv->xvid = create.handle;
- return w;
+ return 0;
}
/***********************************************************************
@@ -124,19 +122,15 @@ hb_work_object_t * hb_work_encxvid_init( hb_job_t * job )
***********************************************************************
*
**********************************************************************/
-static void Close( hb_work_object_t ** _w )
+void encxvidClose( hb_work_object_t * w )
{
- hb_work_object_t * w = *_w;
+ hb_work_private_t * pv = w->private_data;
- if( w->xvid )
+ if( pv->xvid )
{
hb_log( "encxvid: closing libxvidcore" );
- xvid_encore( w->xvid, XVID_ENC_DESTROY, NULL, NULL);
+ xvid_encore( pv->xvid, XVID_ENC_DESTROY, NULL, NULL);
}
-
- free( w->name );
- free( w );
- *_w = NULL;
}
/***********************************************************************
@@ -144,10 +138,11 @@ static void Close( hb_work_object_t ** _w )
***********************************************************************
*
**********************************************************************/
-static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
+int encxvidWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
hb_buffer_t ** buf_out )
{
- hb_job_t * job = w->job;
+ hb_work_private_t * pv = w->private_data;
+ hb_job_t * job = pv->job;
xvid_enc_frame_t frame;
hb_buffer_t * in = *buf_in, * buf;
@@ -172,7 +167,7 @@ static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
frame.vop_flags |= XVID_VOP_GREYSCALE;
}
frame.type = XVID_TYPE_AUTO;
- frame.quant = w->quant;
+ frame.quant = pv->quant;
frame.motion = XVID_ME_ADVANCEDDIAMOND16 | XVID_ME_HALFPELREFINE16 |
XVID_ME_EXTSEARCH16 | XVID_ME_ADVANCEDDIAMOND8 |
XVID_ME_HALFPELREFINE8 | XVID_ME_EXTSEARCH8 |
@@ -180,11 +175,10 @@ static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
frame.quant_intra_matrix = NULL;
frame.quant_inter_matrix = NULL;
- buf->size = xvid_encore( w->xvid, XVID_ENC_ENCODE, &frame, NULL );
+ buf->size = xvid_encore( pv->xvid, XVID_ENC_ENCODE, &frame, NULL );
buf->key = ( frame.out_flags & XVID_KEYFRAME );
-#define c job->config.mpeg4
- if( !c.config )
+ if( !pv->configDone )
{
int vol_start, vop_start;
for( vol_start = 0; ; vol_start++ )
@@ -209,11 +203,11 @@ static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
}
hb_log( "encxvid: VOL size is %d bytes", vop_start - vol_start );
- c.config = malloc( vop_start - vol_start );
- c.config_length = vop_start - vol_start;
- memcpy( c.config, &buf->data[vol_start], c.config_length );
+ job->config.mpeg4.length = vop_start - vol_start;
+ memcpy( job->config.mpeg4.bytes, &buf->data[vol_start],
+ job->config.mpeg4.length );
+ pv->configDone = 1;
}
-#undef c
*buf_out = buf;
diff --git a/libhb/internal.h b/libhb/internal.h
index c93d48245..d241ae5c1 100644
--- a/libhb/internal.h
+++ b/libhb/internal.h
@@ -114,45 +114,94 @@ void hb_dvd_close( hb_dvd_t ** );
/***********************************************************************
* Work objects
**********************************************************************/
-typedef struct hb_work_object_s hb_work_object_t;
-
-#define HB_WORK_COMMON \
- hb_lock_t * lock; \
- int used; \
- uint64_t time; \
- char * name; \
- hb_fifo_t * fifo_in; \
- hb_fifo_t * fifo_out; \
- int (* work) ( hb_work_object_t *, hb_buffer_t **, \
- hb_buffer_t ** ); \
- void (* close) ( hb_work_object_t ** )
+#define HB_CONFIG_MAX_SIZE 8192
+typedef union hb_esconfig_u
+{
+ struct
+ {
+ uint8_t bytes[HB_CONFIG_MAX_SIZE];
+ int length;
+ } mpeg4;
+
+ struct
+ {
+ uint8_t sps[HB_CONFIG_MAX_SIZE];
+ int sps_length;
+ uint8_t pps[HB_CONFIG_MAX_SIZE];
+ int pps_length;
+ } h264;
+
+ struct
+ {
+ uint8_t bytes[HB_CONFIG_MAX_SIZE];
+ int length;
+ } aac;
+
+ struct
+ {
+ uint8_t headers[3][HB_CONFIG_MAX_SIZE];
+ } vorbis;
+} hb_esconfig_t;
+
+typedef struct hb_work_private_s hb_work_private_t;
+typedef struct hb_work_object_s hb_work_object_t;
+struct hb_work_object_s
+{
+ int id;
+ char * name;
+
+ int (* init) ( hb_work_object_t *, hb_job_t * );
+ int (* work) ( hb_work_object_t *, hb_buffer_t **,
+ hb_buffer_t ** );
+ void (* close) ( hb_work_object_t * );
+
+ hb_fifo_t * fifo_in;
+ hb_fifo_t * fifo_out;
+ hb_esconfig_t * config;
+
+ hb_work_private_t * private_data;
+
+ hb_lock_t * lock;
+ int used;
+ uint64_t time;
+};
+
+enum
+{
+ WORK_SYNC = 1,
+ WORK_DECMPEG2,
+ WORK_DECSUB,
+ WORK_RENDER,
+ WORK_ENCAVCODEC,
+ WORK_ENCXVID,
+ WORK_ENCX264,
+ WORK_DECA52,
+ WORK_DECAVCODEC,
+ WORK_DECLPCM,
+ WORK_ENCFAAC,
+ WORK_ENCLAME,
+ WORK_ENCVORBIS
+};
+
+extern hb_work_object_t hb_sync;
+extern hb_work_object_t hb_decmpeg2;
+extern hb_work_object_t hb_decsub;
+extern hb_work_object_t hb_render;
+extern hb_work_object_t hb_encavcodec;
+extern hb_work_object_t hb_encxvid;
+extern hb_work_object_t hb_encx264;
+extern hb_work_object_t hb_deca52;
+extern hb_work_object_t hb_decavcodec;
+extern hb_work_object_t hb_declpcm;
+extern hb_work_object_t hb_encfaac;
+extern hb_work_object_t hb_enclame;
+extern hb_work_object_t hb_encvorbis;
#define HB_WORK_IDLE 0
#define HB_WORK_OK 1
#define HB_WORK_ERROR 2
#define HB_WORK_DONE 3
-
-#define DECLARE_WORK_NORMAL( a ) \
- hb_work_object_t * hb_work_##a##_init( hb_job_t * );
-
-#define DECLARE_WORK_AUDIO( a ) \
- hb_work_object_t * hb_work_##a##_init( hb_job_t *, hb_audio_t * );
-
-DECLARE_WORK_NORMAL( sync );
-DECLARE_WORK_NORMAL( decmpeg2 );
-DECLARE_WORK_NORMAL( decsub );
-DECLARE_WORK_NORMAL( render );
-DECLARE_WORK_NORMAL( encavcodec );
-DECLARE_WORK_NORMAL( encxvid );
-DECLARE_WORK_NORMAL( encx264 );
-DECLARE_WORK_AUDIO( deca52 );
-DECLARE_WORK_AUDIO( decavcodec );
-DECLARE_WORK_AUDIO( declpcm );
-DECLARE_WORK_AUDIO( encfaac );
-DECLARE_WORK_AUDIO( enclame );
-DECLARE_WORK_AUDIO( encvorbis );
-
/***********************************************************************
* Muxers
**********************************************************************/
diff --git a/libhb/muxmp4.c b/libhb/muxmp4.c
index 646a2546e..d5002fa4a 100644
--- a/libhb/muxmp4.c
+++ b/libhb/muxmp4.c
@@ -56,26 +56,23 @@ static int MP4Init( hb_mux_object_t * m )
if( job->vcodec == HB_VCODEC_X264 )
{
-#define c job->config.h264
/* Stolen from mp4creator */
MP4SetVideoProfileLevel( m->file, 0x7F );
mux_data->track = MP4AddH264VideoTrack( m->file, job->arate,
MP4_INVALID_DURATION, job->width, job->height,
- c.sps[1], /* AVCProfileIndication */
- c.sps[2], /* profile_compat */
- c.sps[3], /* AVCLevelIndication */
+ job->config.h264.sps[1], /* AVCProfileIndication */
+ job->config.h264.sps[2], /* profile_compat */
+ job->config.h264.sps[3], /* AVCLevelIndication */
3 ); /* 4 bytes length before each NAL unit */
MP4AddH264SequenceParameterSet( m->file, mux_data->track,
- c.sps, c.sps_length );
+ job->config.h264.sps, job->config.h264.sps_length );
MP4AddH264PictureParameterSet( m->file, mux_data->track,
- c.pps, c.pps_length );
-#undef c
+ job->config.h264.pps, job->config.h264.pps_length );
}
else /* FFmpeg or XviD */
{
-#define c job->config.mpeg4
MP4SetVideoProfileLevel( m->file, MPEG4_SP_L3 );
mux_data->track = MP4AddVideoTrack( m->file, job->arate,
MP4_INVALID_DURATION, job->width, job->height,
@@ -83,8 +80,7 @@ static int MP4Init( hb_mux_object_t * m )
/* VOL from FFmpeg or XviD */
MP4SetTrackESConfiguration( m->file, mux_data->track,
- c.config, c.config_length );
-#undef c
+ job->config.mpeg4.bytes, job->config.mpeg4.length );
}
for( i = 0; i < hb_list_count( title->list_audio ); i++ )
@@ -97,7 +93,7 @@ static int MP4Init( hb_mux_object_t * m )
job->arate, 1024, MP4_MPEG4_AUDIO_TYPE );
MP4SetAudioProfileLevel( m->file, 0x0F );
MP4SetTrackESConfiguration( m->file, mux_data->track,
- audio->config.faac.decinfo, audio->config.faac.size );
+ audio->config.aac.bytes, audio->config.aac.length );
}
return 0;
diff --git a/libhb/render.c b/libhb/render.c
index cdada7f18..cf6d7b31c 100644
--- a/libhb/render.c
+++ b/libhb/render.c
@@ -8,10 +8,8 @@
#include "ffmpeg/avcodec.h"
-struct hb_work_object_s
+struct hb_work_private_s
{
- HB_WORK_COMMON;
-
hb_job_t * job;
ImgReSampleContext * context;
@@ -21,6 +19,19 @@ struct hb_work_object_s
hb_buffer_t * buf_deint;
};
+int renderInit( hb_work_object_t *, hb_job_t * );
+int renderWork( hb_work_object_t *, hb_buffer_t **, hb_buffer_t ** );
+void renderClose( hb_work_object_t * );
+
+hb_work_object_t hb_render =
+{
+ WORK_RENDER,
+ "Renderer",
+ renderInit,
+ renderWork,
+ renderClose
+};
+
static void ApplySub( hb_job_t * job, hb_buffer_t * buf,
hb_buffer_t ** _sub )
{
@@ -84,45 +95,46 @@ static void ApplySub( hb_job_t * job, hb_buffer_t * buf,
hb_buffer_close( _sub );
}
-static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
- hb_buffer_t ** buf_out )
+int renderWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
+ hb_buffer_t ** buf_out )
{
- hb_job_t * job = w->job;
+ hb_work_private_t * pv = w->private_data;
+ hb_job_t * job = pv->job;
hb_title_t * title = job->title;
hb_buffer_t * in = *buf_in, * buf;
- avpicture_fill( &w->pic_raw, in->data, PIX_FMT_YUV420P,
+ avpicture_fill( &pv->pic_raw, in->data, PIX_FMT_YUV420P,
title->width, title->height );
buf = hb_buffer_init( 3 * job->width * job->height / 2 );
buf->start = in->start;
buf->stop = in->stop;
- if( job->deinterlace && w->context )
+ if( job->deinterlace && pv->context )
{
- avpicture_fill( &w->pic_render, buf->data, PIX_FMT_YUV420P,
+ avpicture_fill( &pv->pic_render, buf->data, PIX_FMT_YUV420P,
job->width, job->height );
- avpicture_deinterlace( &w->pic_deint, &w->pic_raw,
+ avpicture_deinterlace( &pv->pic_deint, &pv->pic_raw,
PIX_FMT_YUV420P, title->width,
title->height );
- ApplySub( job, w->buf_deint, &in->sub );
- img_resample( w->context, &w->pic_render, &w->pic_deint );
+ ApplySub( job, pv->buf_deint, &in->sub );
+ img_resample( pv->context, &pv->pic_render, &pv->pic_deint );
}
else if( job->deinterlace )
{
- avpicture_fill( &w->pic_deint, buf->data, PIX_FMT_YUV420P,
+ avpicture_fill( &pv->pic_deint, buf->data, PIX_FMT_YUV420P,
job->width, job->height );
- avpicture_deinterlace( &w->pic_deint, &w->pic_raw,
+ avpicture_deinterlace( &pv->pic_deint, &pv->pic_raw,
PIX_FMT_YUV420P, title->width,
title->height );
ApplySub( job, buf, &in->sub );
}
- else if( w->context )
+ else if( pv->context )
{
ApplySub( job, in, &in->sub );
- avpicture_fill( &w->pic_render, buf->data, PIX_FMT_YUV420P,
+ avpicture_fill( &pv->pic_render, buf->data, PIX_FMT_YUV420P,
job->width, job->height );
- img_resample( w->context, &w->pic_render, &w->pic_raw );
+ img_resample( pv->context, &pv->pic_render, &pv->pic_raw );
}
else
{
@@ -137,31 +149,25 @@ static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
return HB_WORK_OK;
}
-static void Close( hb_work_object_t ** _w )
+void renderClose( hb_work_object_t * w )
{
- hb_work_object_t * w = *_w;
- free( w->name );
- free( w );
- *_w = NULL;
}
-hb_work_object_t * hb_work_render_init( hb_job_t * job )
+int renderInit( hb_work_object_t * w, hb_job_t * job )
{
hb_title_t * title;
- hb_work_object_t * w = calloc( sizeof( hb_work_object_t ), 1 );
- w->name = strdup( "Renderer" );
- w->work = Work;
- w->close = Close;
+ hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
+ w->private_data = pv;
title = job->title;
- w->job = job;
+ pv->job = job;
if( job->crop[0] || job->crop[1] || job->crop[2] || job->crop[3] ||
job->width != title->width || job->height != title->height )
{
- w->context = img_resample_full_init(
+ pv->context = img_resample_full_init(
job->width, job->height, title->width, title->height,
job->crop[0], job->crop[1], job->crop[2], job->crop[3],
0, 0, 0, 0 );
@@ -170,10 +176,11 @@ hb_work_object_t * hb_work_render_init( hb_job_t * job )
if( job->deinterlace )
{
/* Allocate a constant buffer used for deinterlacing */
- w->buf_deint = hb_buffer_init( 3 * title->width *
+ pv->buf_deint = hb_buffer_init( 3 * title->width *
title->height / 2 );
- avpicture_fill( &w->pic_deint, w->buf_deint->data,
+ avpicture_fill( &pv->pic_deint, pv->buf_deint->data,
PIX_FMT_YUV420P, title->width, title->height );
}
- return w;
+
+ return 0;
}
diff --git a/libhb/sync.c b/libhb/sync.c
index 61e567bbc..cd526c11a 100644
--- a/libhb/sync.c
+++ b/libhb/sync.c
@@ -31,10 +31,8 @@ typedef struct
} hb_sync_audio_t;
-struct hb_work_object_s
+struct hb_work_private_s
{
- HB_WORK_COMMON;
-
hb_job_t * job;
int done;
@@ -59,9 +57,6 @@ struct hb_work_object_s
* Local prototypes
**********************************************************************/
static void InitAudio( hb_work_object_t * w, int i );
-static void Close( hb_work_object_t ** _w );
-static int Work( hb_work_object_t * w, hb_buffer_t ** unused1,
- hb_buffer_t ** unused2 );
static int SyncVideo( hb_work_object_t * w );
static void SyncAudio( hb_work_object_t * w, int i );
static int NeedSilence( hb_work_object_t * w, hb_audio_t * );
@@ -73,23 +68,21 @@ static void UpdateState( hb_work_object_t * w );
***********************************************************************
* Initialize the work object
**********************************************************************/
-hb_work_object_t * hb_work_sync_init( hb_job_t * job )
+int syncInit( hb_work_object_t * w, hb_job_t * job )
{
- hb_work_object_t * w;
hb_title_t * title = job->title;
hb_chapter_t * chapter;
int i;
uint64_t duration;
+ hb_work_private_t * pv;
- w = calloc( sizeof( hb_work_object_t ), 1 );
- w->name = strdup( "Synchronization" );
- w->work = Work;
- w->close = Close;
+ pv = calloc( 1, sizeof( hb_work_private_t ) );
+ w->private_data = pv;
- w->job = job;
- w->pts_offset = INT64_MIN;
- w->pts_offset_old = INT64_MIN;
- w->count_frames = 0;
+ pv->job = job;
+ pv->pts_offset = INT64_MIN;
+ pv->pts_offset_old = INT64_MIN;
+ pv->count_frames = 0;
/* Calculate how many video frames we are expecting */
duration = 0;
@@ -100,9 +93,9 @@ hb_work_object_t * hb_work_sync_init( hb_job_t * job )
}
duration += 90000;
/* 1 second safety so we're sure we won't miss anything */
- w->count_frames_max = duration * job->vrate / job->vrate_base / 90000;
+ pv->count_frames_max = duration * job->vrate / job->vrate_base / 90000;
- hb_log( "sync: expecting %lld video frames", w->count_frames_max );
+ hb_log( "sync: expecting %lld video frames", pv->count_frames_max );
/* Initialize libsamplerate for every audio track we have */
for( i = 0; i < hb_list_count( title->list_audio ); i++ )
@@ -111,18 +104,80 @@ hb_work_object_t * hb_work_sync_init( hb_job_t * job )
}
/* Get subtitle info, if any */
- w->subtitle = hb_list_item( title->list_subtitle, 0 );
+ pv->subtitle = hb_list_item( title->list_subtitle, 0 );
+
+ return 0;
+}
+
+/***********************************************************************
+ * Close
+ ***********************************************************************
+ *
+ **********************************************************************/
+void syncClose( hb_work_object_t * w )
+{
+ hb_work_private_t * pv = w->private_data;
+ hb_job_t * job = pv->job;
+ hb_title_t * title = job->title;
+
+ int i;
+
+ if( pv->cur ) hb_buffer_close( &pv->cur );
+
+ for( i = 0; i < hb_list_count( title->list_audio ); i++ )
+ {
+ if( job->acodec & HB_ACODEC_AC3 )
+ {
+ free( pv->sync_audio[i].ac3_buf );
+ }
+ else
+ {
+ src_delete( pv->sync_audio[i].state );
+ }
+ }
+}
+
+/***********************************************************************
+ * Work
+ ***********************************************************************
+ * The root routine of this work abject
+ **********************************************************************/
+int syncWork( hb_work_object_t * w, hb_buffer_t ** unused1,
+ hb_buffer_t ** unused2 )
+{
+ hb_work_private_t * pv = w->private_data;
+ int i;
- return w;
+ /* If we ever got a video frame, handle audio now */
+ if( pv->pts_offset != INT64_MIN )
+ {
+ for( i = 0; i < hb_list_count( pv->job->title->list_audio ); i++ )
+ {
+ SyncAudio( w, i );
+ }
+ }
+
+ /* Handle video */
+ return SyncVideo( w );
}
+hb_work_object_t hb_sync =
+{
+ WORK_SYNC,
+ "Synchronization",
+ syncInit,
+ syncWork,
+ syncClose
+};
+
static void InitAudio( hb_work_object_t * w, int i )
{
- hb_job_t * job = w->job;
+ hb_work_private_t * pv = w->private_data;
+ hb_job_t * job = pv->job;
hb_title_t * title = job->title;
hb_sync_audio_t * sync;
- sync = &w->sync_audio[i];
+ sync = &pv->sync_audio[i];
sync->audio = hb_list_item( title->list_audio, i );
if( job->acodec & HB_ACODEC_AC3 )
@@ -171,60 +226,7 @@ static void InitAudio( hb_work_object_t * w, int i )
}
}
-/***********************************************************************
- * Close
- ***********************************************************************
- *
- **********************************************************************/
-static void Close( hb_work_object_t ** _w )
-{
- hb_work_object_t * w = *_w;
- hb_job_t * job = w->job;
- hb_title_t * title = job->title;
-
- int i;
-
- if( w->cur ) hb_buffer_close( &w->cur );
-
- for( i = 0; i < hb_list_count( title->list_audio ); i++ )
- {
- if( job->acodec & HB_ACODEC_AC3 )
- {
- free( w->sync_audio[i].ac3_buf );
- }
- else
- {
- src_delete( w->sync_audio[i].state );
- }
- }
- free( w->name );
- free( w );
- *_w = NULL;
-}
-
-/***********************************************************************
- * Work
- ***********************************************************************
- * The root routine of this work abject
- **********************************************************************/
-static int Work( hb_work_object_t * w, hb_buffer_t ** unused1,
- hb_buffer_t ** unused2 )
-{
- int i;
-
- /* If we ever got a video frame, handle audio now */
- if( w->pts_offset != INT64_MIN )
- {
- for( i = 0; i < hb_list_count( w->job->title->list_audio ); i++ )
- {
- SyncAudio( w, i );
- }
- }
-
- /* Handle video */
- return SyncVideo( w );
-}
#define PTS_DISCONTINUITY_TOLERANCE 90000
@@ -235,11 +237,12 @@ static int Work( hb_work_object_t * w, hb_buffer_t ** unused1,
**********************************************************************/
static int SyncVideo( hb_work_object_t * w )
{
+ hb_work_private_t * pv = w->private_data;
hb_buffer_t * cur, * next, * sub = NULL;
- hb_job_t * job = w->job;
+ hb_job_t * job = pv->job;
int64_t pts_expected;
- if( w->done )
+ if( pv->done )
{
return HB_WORK_DONE;
}
@@ -251,17 +254,17 @@ static int SyncVideo( hb_work_object_t * w )
/* All video data has been processed already, we won't get
more */
hb_log( "sync: got %lld frames, %lld expected",
- w->count_frames, w->count_frames_max );
- w->done = 1;
+ pv->count_frames, pv->count_frames_max );
+ pv->done = 1;
return HB_WORK_DONE;
}
- if( !w->cur && !( w->cur = hb_fifo_get( job->fifo_raw ) ) )
+ if( !pv->cur && !( pv->cur = hb_fifo_get( job->fifo_raw ) ) )
{
/* We haven't even got a frame yet */
return HB_WORK_OK;
}
- cur = w->cur;
+ cur = pv->cur;
/* At this point we have a frame to process. Let's check
1) if we will be able to push into the fifo ahead
@@ -272,11 +275,11 @@ static int SyncVideo( hb_work_object_t * w )
{
hb_buffer_t * buf_tmp;
- if( w->pts_offset == INT64_MIN )
+ if( pv->pts_offset == INT64_MIN )
{
/* This is our first frame */
hb_log( "sync: first pts is %lld", cur->start );
- w->pts_offset = cur->start;
+ pv->pts_offset = cur->start;
}
/* Check for PTS jumps over 0.5 second */
@@ -287,9 +290,9 @@ static int SyncVideo( hb_work_object_t * w )
cur->start, next->start );
/* Trash all subtitles */
- if( w->subtitle )
+ if( pv->subtitle )
{
- while( ( sub = hb_fifo_get( w->subtitle->fifo_raw ) ) )
+ while( ( sub = hb_fifo_get( pv->subtitle->fifo_raw ) ) )
{
hb_buffer_close( &sub );
}
@@ -297,24 +300,24 @@ static int SyncVideo( hb_work_object_t * w )
/* Trash current picture */
hb_buffer_close( &cur );
- w->cur = cur = hb_fifo_get( job->fifo_raw );
+ pv->cur = cur = hb_fifo_get( job->fifo_raw );
/* Calculate new offset */
- w->pts_offset_old = w->pts_offset;
- w->pts_offset = cur->start -
- w->count_frames * w->job->vrate_base / 300;
+ pv->pts_offset_old = pv->pts_offset;
+ pv->pts_offset = cur->start -
+ pv->count_frames * pv->job->vrate_base / 300;
continue;
}
/* Look for a subtitle for this frame */
- if( w->subtitle )
+ if( pv->subtitle )
{
hb_buffer_t * sub2;
- while( ( sub = hb_fifo_see( w->subtitle->fifo_raw ) ) )
+ while( ( sub = hb_fifo_see( pv->subtitle->fifo_raw ) ) )
{
/* If two subtitles overlap, make the first one stop
when the second one starts */
- sub2 = hb_fifo_see2( w->subtitle->fifo_raw );
+ sub2 = hb_fifo_see2( pv->subtitle->fifo_raw );
if( sub2 && sub->stop > sub2->start )
sub->stop = sub2->start;
@@ -322,7 +325,7 @@ static int SyncVideo( hb_work_object_t * w )
break;
/* The subtitle is older than this picture, trash it */
- sub = hb_fifo_get( w->subtitle->fifo_raw );
+ sub = hb_fifo_get( pv->subtitle->fifo_raw );
hb_buffer_close( &sub );
}
@@ -336,20 +339,20 @@ static int SyncVideo( hb_work_object_t * w )
}
/* The PTS of the frame we are expecting now */
- pts_expected = w->pts_offset +
- w->count_frames * w->job->vrate_base / 300;
+ pts_expected = pv->pts_offset +
+ pv->count_frames * pv->job->vrate_base / 300;
- if( cur->start < pts_expected - w->job->vrate_base / 300 / 2 &&
- next->start < pts_expected + w->job->vrate_base / 300 / 2 )
+ if( cur->start < pts_expected - pv->job->vrate_base / 300 / 2 &&
+ next->start < pts_expected + pv->job->vrate_base / 300 / 2 )
{
/* The current frame is too old but the next one matches,
let's trash */
hb_buffer_close( &cur );
- w->cur = cur = hb_fifo_get( job->fifo_raw );
+ pv->cur = cur = hb_fifo_get( job->fifo_raw );
continue;
}
- if( next->start > pts_expected + 3 * w->job->vrate_base / 300 / 2 )
+ if( next->start > pts_expected + 3 * pv->job->vrate_base / 300 / 2 )
{
/* We'll need the current frame more than one time. Make a
copy of it and keep it */
@@ -361,14 +364,14 @@ static int SyncVideo( hb_work_object_t * w )
/* The frame has the expected date and won't have to be
duplicated, just put it through */
buf_tmp = cur;
- w->cur = cur = hb_fifo_get( job->fifo_raw );
+ pv->cur = cur = hb_fifo_get( job->fifo_raw );
}
/* Replace those MPEG-2 dates with our dates */
- buf_tmp->start = (uint64_t) w->count_frames *
- w->job->vrate_base / 300;
- buf_tmp->stop = (uint64_t) ( w->count_frames + 1 ) *
- w->job->vrate_base / 300;
+ buf_tmp->start = (uint64_t) pv->count_frames *
+ pv->job->vrate_base / 300;
+ buf_tmp->stop = (uint64_t) ( pv->count_frames + 1 ) *
+ pv->job->vrate_base / 300;
/* If we have a subtitle for this picture, copy it */
/* FIXME: we should avoid this memcpy */
@@ -389,10 +392,10 @@ static int SyncVideo( hb_work_object_t * w )
UpdateState( w );
/* Make sure we won't get more frames then expected */
- if( w->count_frames >= w->count_frames_max )
+ if( pv->count_frames >= pv->count_frames_max )
{
- hb_log( "sync: got %lld frames", w->count_frames );
- w->done = 1;
+ hb_log( "sync: got %lld frames", pv->count_frames );
+ pv->done = 1;
break;
}
}
@@ -407,6 +410,7 @@ static int SyncVideo( hb_work_object_t * w )
**********************************************************************/
static void SyncAudio( hb_work_object_t * w, int i )
{
+ hb_work_private_t * pv = w->private_data;
hb_job_t * job;
hb_audio_t * audio;
hb_buffer_t * buf;
@@ -418,8 +422,8 @@ static void SyncAudio( hb_work_object_t * w, int i )
int64_t pts_expected;
int64_t start;
- job = w->job;
- sync = &w->sync_audio[i];
+ job = pv->job;
+ sync = &pv->sync_audio[i];
audio = sync->audio;
if( job->acodec & HB_ACODEC_AC3 )
@@ -437,15 +441,15 @@ static void SyncAudio( hb_work_object_t * w, int i )
( buf = hb_fifo_see( audio->fifo_raw ) ) )
{
/* The PTS of the samples we are expecting now */
- pts_expected = w->pts_offset + sync->count_frames * 90000 / rate;
+ pts_expected = pv->pts_offset + sync->count_frames * 90000 / rate;
if( ( buf->start > pts_expected + PTS_DISCONTINUITY_TOLERANCE ||
buf->start < pts_expected - PTS_DISCONTINUITY_TOLERANCE ) &&
- w->pts_offset_old > INT64_MIN )
+ pv->pts_offset_old > INT64_MIN )
{
/* There has been a PTS discontinuity, and this frame might
be from before the discontinuity */
- pts_expected = w->pts_offset_old + sync->count_frames *
+ pts_expected = pv->pts_offset_old + sync->count_frames *
90000 / rate;
if( buf->start > pts_expected + PTS_DISCONTINUITY_TOLERANCE ||
@@ -458,11 +462,11 @@ static void SyncAudio( hb_work_object_t * w, int i )
}
/* Use the older offset */
- start = pts_expected - w->pts_offset_old;
+ start = pts_expected - pv->pts_offset_old;
}
else
{
- start = pts_expected - w->pts_offset;
+ start = pts_expected - pv->pts_offset;
}
/* Tolerance: 100 ms */
@@ -541,7 +545,8 @@ static void SyncAudio( hb_work_object_t * w, int i )
static int NeedSilence( hb_work_object_t * w, hb_audio_t * audio )
{
- hb_job_t * job = w->job;
+ hb_work_private_t * pv = w->private_data;
+ hb_job_t * job = pv->job;
if( hb_fifo_size( audio->fifo_in ) ||
hb_fifo_size( audio->fifo_raw ) ||
@@ -576,12 +581,13 @@ static int NeedSilence( hb_work_object_t * w, hb_audio_t * audio )
static void InsertSilence( hb_work_object_t * w, int i )
{
+ hb_work_private_t * pv = w->private_data;
hb_job_t * job;
hb_sync_audio_t * sync;
hb_buffer_t * buf;
- job = w->job;
- sync = &w->sync_audio[i];
+ job = pv->job;
+ sync = &pv->sync_audio[i];
if( job->acodec & HB_ACODEC_AC3 )
{
@@ -616,40 +622,41 @@ static void InsertSilence( hb_work_object_t * w, int i )
static void UpdateState( hb_work_object_t * w )
{
+ hb_work_private_t * pv = w->private_data;
hb_state_t state;
- if( !w->count_frames )
+ if( !pv->count_frames )
{
- w->st_first = hb_get_date();
+ pv->st_first = hb_get_date();
}
- w->count_frames++;
+ pv->count_frames++;
- if( hb_get_date() > w->st_dates[3] + 1000 )
+ if( hb_get_date() > pv->st_dates[3] + 1000 )
{
- memmove( &w->st_dates[0], &w->st_dates[1],
+ memmove( &pv->st_dates[0], &pv->st_dates[1],
3 * sizeof( uint64_t ) );
- memmove( &w->st_counts[0], &w->st_counts[1],
+ memmove( &pv->st_counts[0], &pv->st_counts[1],
3 * sizeof( uint64_t ) );
- w->st_dates[3] = hb_get_date();
- w->st_counts[3] = w->count_frames;
+ pv->st_dates[3] = hb_get_date();
+ pv->st_counts[3] = pv->count_frames;
}
#define p state.param.working
state.state = HB_STATE_WORKING;
- p.progress = (float) w->count_frames / (float) w->count_frames_max;
+ p.progress = (float) pv->count_frames / (float) pv->count_frames_max;
if( p.progress > 1.0 )
{
p.progress = 1.0;
}
p.rate_cur = 1000.0 *
- (float) ( w->st_counts[3] - w->st_counts[0] ) /
- (float) ( w->st_dates[3] - w->st_dates[0] );
- if( hb_get_date() > w->st_first + 4000 )
+ (float) ( pv->st_counts[3] - pv->st_counts[0] ) /
+ (float) ( pv->st_dates[3] - pv->st_dates[0] );
+ if( hb_get_date() > pv->st_first + 4000 )
{
int eta;
- p.rate_avg = 1000.0 * (float) w->st_counts[3] /
- (float) ( w->st_dates[3] - w->st_first );
- eta = (float) ( w->count_frames_max - w->st_counts[3] ) /
+ p.rate_avg = 1000.0 * (float) pv->st_counts[3] /
+ (float) ( pv->st_dates[3] - pv->st_first );
+ eta = (float) ( pv->count_frames_max - pv->st_counts[3] ) /
p.rate_avg;
p.hours = eta / 3600;
p.minutes = ( eta % 3600 ) / 60;
@@ -664,5 +671,5 @@ static void UpdateState( hb_work_object_t * w )
}
#undef p
- hb_set_state( w->job->h, &state );
+ hb_set_state( pv->job->h, &state );
}
diff --git a/libhb/work.c b/libhb/work.c
index 6c0be24e3..c22585313 100644
--- a/libhb/work.c
+++ b/libhb/work.c
@@ -6,11 +6,6 @@
#include "hb.h"
-struct hb_work_object_s
-{
- HB_WORK_COMMON;
-};
-
typedef struct
{
hb_list_t * jobs;
@@ -56,6 +51,27 @@ static void work_func( void * _work )
free( work );
}
+static hb_work_object_t * getWork( int id )
+{
+ switch( id )
+ {
+ case WORK_SYNC: return &hb_sync;
+ case WORK_DECMPEG2: return &hb_decmpeg2;
+ case WORK_DECSUB: return &hb_decsub;
+ case WORK_RENDER: return &hb_render;
+ case WORK_ENCAVCODEC: return &hb_encavcodec;
+ case WORK_ENCXVID: return &hb_encxvid;
+ case WORK_ENCX264: return &hb_encx264;
+ case WORK_DECA52: return &hb_deca52;
+ case WORK_DECAVCODEC: return &hb_decavcodec;
+ case WORK_DECLPCM: return &hb_declpcm;
+ case WORK_ENCFAAC: return &hb_encfaac;
+ case WORK_ENCLAME: return &hb_enclame;
+ case WORK_ENCVORBIS: return &hb_encvorbis;
+ }
+ return NULL;
+}
+
static void do_job( hb_job_t * job, int cpu_count )
{
hb_title_t * title;
@@ -98,41 +114,39 @@ static void do_job( hb_job_t * job, int cpu_count )
job->fifo_mpeg4 = hb_fifo_init( 8 );
/* Synchronization */
- w = hb_work_sync_init( job );
+ hb_list_add( job->list_work, ( w = getWork( WORK_SYNC ) ) );
w->fifo_in = NULL;
w->fifo_out = NULL;
- hb_list_add( job->list_work, w );
/* Video decoder */
- w = hb_work_decmpeg2_init( job );
+ hb_list_add( job->list_work, ( w = getWork( WORK_DECMPEG2 ) ) );
w->fifo_in = job->fifo_mpeg2;
w->fifo_out = job->fifo_raw;
- hb_list_add( job->list_work, w );
/* Video renderer */
- w = hb_work_render_init( job );
+ hb_list_add( job->list_work, ( w = getWork( WORK_RENDER ) ) );
w->fifo_in = job->fifo_sync;
w->fifo_out = job->fifo_render;
- hb_list_add( job->list_work, w );
/* Video encoder */
switch( job->vcodec )
{
case HB_VCODEC_FFMPEG:
hb_log( " + encoder FFmpeg" );
- w = hb_work_encavcodec_init( job );
+ w = getWork( WORK_ENCAVCODEC );
break;
case HB_VCODEC_XVID:
hb_log( " + encoder XviD" );
- w = hb_work_encxvid_init( job );
+ w = getWork( WORK_ENCXVID );
break;
case HB_VCODEC_X264:
hb_log( " + encoder x264" );
- w = hb_work_encx264_init( job );
+ w = getWork( WORK_ENCX264 );
break;
}
w->fifo_in = job->fifo_render;
w->fifo_out = job->fifo_mpeg4;
+ w->config = &job->config;
hb_list_add( job->list_work, w );
subtitle = hb_list_item( title->list_subtitle, 0 );
@@ -143,10 +157,9 @@ static void do_job( hb_job_t * job, int cpu_count )
subtitle->fifo_in = hb_fifo_init( 8 );
subtitle->fifo_raw = hb_fifo_init( 8 );
- w = hb_work_decsub_init( job );
+ hb_list_add( job->list_work, ( w = getWork( WORK_DECSUB ) ) );
w->fifo_in = subtitle->fifo_in;
w->fifo_out = subtitle->fifo_raw;
- hb_list_add( job->list_work, w );
}
if( job->acodec & HB_ACODEC_AC3 )
@@ -174,13 +187,13 @@ static void do_job( hb_job_t * job, int cpu_count )
switch( audio->codec )
{
case HB_ACODEC_AC3:
- w = hb_work_deca52_init( job, audio );
+ w = getWork( WORK_DECA52 );
break;
case HB_ACODEC_MPGA:
- w = hb_work_decavcodec_init( job, audio );
+ w = getWork( WORK_DECAVCODEC );
break;
case HB_ACODEC_LPCM:
- w = hb_work_declpcm_init( job, audio );
+ w = getWork( WORK_DECLPCM );
break;
}
w->fifo_in = audio->fifo_in;
@@ -190,19 +203,20 @@ static void do_job( hb_job_t * job, int cpu_count )
switch( job->acodec )
{
case HB_ACODEC_FAAC:
- w = hb_work_encfaac_init( job, audio );
+ w = getWork( WORK_ENCFAAC );
break;
case HB_ACODEC_LAME:
- w = hb_work_enclame_init( job, audio );
+ w = getWork( WORK_ENCLAME );
break;
case HB_ACODEC_VORBIS:
- w = hb_work_encvorbis_init( job, audio );
+ w = getWork( WORK_ENCVORBIS );
break;
}
if( job->acodec != HB_ACODEC_AC3 )
{
w->fifo_in = audio->fifo_sync;
w->fifo_out = audio->fifo_out;
+ w->config = &audio->config;
hb_list_add( job->list_work, w );
}
}
@@ -219,6 +233,7 @@ static void do_job( hb_job_t * job, int cpu_count )
w->lock = hb_lock_init();
w->used = 0;
w->time = 0;
+ w->init( w, job );
}
job->done = 0;
@@ -272,7 +287,7 @@ static void do_job( hb_job_t * job, int cpu_count )
{
hb_list_rem( job->list_work, w );
hb_lock_close( &w->lock );
- w->close( &w );
+ w->close( w );
}
/* Close fifos */