diff options
-rw-r--r-- | libhb/common.h | 39 | ||||
-rw-r--r-- | libhb/deca52.c | 113 | ||||
-rw-r--r-- | libhb/decavcodec.c | 71 | ||||
-rw-r--r-- | libhb/declpcm.c | 44 | ||||
-rw-r--r-- | libhb/decmpeg2.c | 64 | ||||
-rw-r--r-- | libhb/decsub.c | 336 | ||||
-rw-r--r-- | libhb/encavcodec.c | 100 | ||||
-rw-r--r-- | libhb/encfaac.c | 96 | ||||
-rw-r--r-- | libhb/enclame.c | 87 | ||||
-rw-r--r-- | libhb/encvorbis.c | 112 | ||||
-rw-r--r-- | libhb/encx264.c | 101 | ||||
-rw-r--r-- | libhb/encxvid.c | 88 | ||||
-rw-r--r-- | libhb/internal.h | 115 | ||||
-rw-r--r-- | libhb/muxmp4.c | 18 | ||||
-rw-r--r-- | libhb/render.c | 71 | ||||
-rw-r--r-- | libhb/sync.c | 273 | ||||
-rw-r--r-- | libhb/work.c | 61 |
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( ¶m ); @@ -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( ¶m ); + pv->x264 = x264_encoder_open( ¶m ); -#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 */ |