OSDN Git Service

Structural changes, in order to eventually be able to compile HB
authortiter <titer@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Thu, 16 Mar 2006 06:58:39 +0000 (06:58 +0000)
committertiter <titer@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Thu, 16 Mar 2006 06:58:39 +0000 (06:58 +0000)
without certain encoders

git-svn-id: svn://localhost/HandBrake/trunk@34 b64f7644-9d1e-0410-96f1-a4d463321fa5

17 files changed:
libhb/common.h
libhb/deca52.c
libhb/decavcodec.c
libhb/declpcm.c
libhb/decmpeg2.c
libhb/decsub.c
libhb/encavcodec.c
libhb/encfaac.c
libhb/enclame.c
libhb/encvorbis.c
libhb/encx264.c
libhb/encxvid.c
libhb/internal.h
libhb/muxmp4.c
libhb/render.c
libhb/sync.c
libhb/work.c

index 402ae7f..7bc4894 100644 (file)
@@ -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
 };
index a4f7492..b18acf6 100644 (file)
@@ -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;
 }
 
index f18579f..4d74fc6 100644 (file)
@@ -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;
 }
index 5b9d5a3..f6a703d 100644 (file)
@@ -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;
-}
-
index d914c03..214444a 100644 (file)
@@ -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
+};
+
index de844a1..3666ea3 100644 (file)
@@ -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;
+}
index deff7c5..45c79fd 100644 (file)
@@ -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;
index a5b704f..4c0d19e 100644 (file)
@@ -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 );
index 19014ac..f663e62 100644 (file)
@@ -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 );
index 86b8243..4bdb6ef 100644 (file)
 
 #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 );
index cf58452..806fc4c 100644 (file)
 
 #include "x264.h"
 
-struct hb_work_object_s
+int  encx264Init( hb_work_object_t *, hb_job_t * );
+int  encx264Work( hb_work_object_t *, hb_buffer_t **, hb_buffer_t ** );
+void encx264Close( hb_work_object_t * );
+
+hb_work_object_t hb_encx264 =
 {
-    HB_WORK_COMMON;
+    WORK_ENCX264,
+    "H.264/AVC encoder (libx264)",
+    encx264Init,
+    encx264Work,
+    encx264Close
+};
 
+struct hb_work_private_s
+{
     hb_job_t       * job;
     x264_t         * x264;
     x264_picture_t   pic_in;
@@ -23,33 +34,23 @@ struct hb_work_object_s
 };
 
 /***********************************************************************
- * Local prototypes
- **********************************************************************/
-static int  Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
-                  hb_buffer_t ** buf_out );
-static void Close( hb_work_object_t ** _w );
-
-/***********************************************************************
  * hb_work_encx264_init
  ***********************************************************************
  *
  **********************************************************************/
-hb_work_object_t * hb_work_encx264_init( hb_job_t * job )
+int encx264Init( hb_work_object_t * w, hb_job_t * job )
 {
-    hb_work_object_t * w;
     x264_param_t       param;
     x264_nal_t       * nal;
     int                nal_count;
 
-    w        = calloc( sizeof( hb_work_object_t ), 1 );
-    w->name  = strdup( "AVC encoder (libx264)" );
-    w->work  = Work;
-    w->close = Close;
+    hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
+    w->private_data = pv;
 
-    w->job = job;
+    pv->job = job;
 
-    memset( w->filename, 0, 1024 );
-    hb_get_tempory_filename( job->h, w->filename, "x264.log" );
+    memset( pv->filename, 0, 1024 );
+    hb_get_tempory_filename( job->h, pv->filename, "x264.log" );
 
     x264_param_default( &param );
 
@@ -85,83 +86,75 @@ hb_work_object_t * hb_work_encx264_init( hb_job_t * job )
         {
             case 1:
                 param.rc.b_stat_write  = 1;
-                param.rc.psz_stat_out = w->filename;
+                param.rc.psz_stat_out = pv->filename;
                 break;
             case 2:
                 param.rc.b_stat_read = 1;
-                param.rc.psz_stat_in = w->filename;
+                param.rc.psz_stat_in = pv->filename;
                 break;
         }
     }
 
     hb_log( "encx264: opening libx264 (pass %d)", job->pass );
-    w->x264 = x264_encoder_open( &param );
+    pv->x264 = x264_encoder_open( &param );
 
-#define c job->config.h264
-    x264_encoder_headers( w->x264, &nal, &nal_count );
+    x264_encoder_headers( pv->x264, &nal, &nal_count );
 
     /* Sequence Parameter Set */
-    c.sps_length = 1 + nal[1].i_payload;
-    c.sps        = malloc( c.sps_length);
-    c.sps[0]     = 0x67;
-    memcpy( &c.sps[1], nal[1].p_payload, nal[1].i_payload );
+    w->config->h264.sps_length = 1 + nal[1].i_payload;
+    w->config->h264.sps[0] = 0x67;
+    memcpy( &w->config->h264.sps[1], nal[1].p_payload, nal[1].i_payload );
 
     /* Picture Parameter Set */
-    c.pps_length = 1 + nal[2].i_payload;
-    c.pps        = malloc( c.pps_length );
-    c.pps[0]     = 0x68;
-    memcpy( &c.pps[1], nal[2].p_payload, nal[2].i_payload );
-#undef c
+    w->config->h264.pps_length = 1 + nal[2].i_payload;
+    w->config->h264.pps[0] = 0x68;
+    memcpy( &w->config->h264.pps[1], nal[2].p_payload, nal[2].i_payload );
 
-    x264_picture_alloc( &w->pic_in, X264_CSP_I420,
+    x264_picture_alloc( &pv->pic_in, X264_CSP_I420,
                         job->width, job->height );
 
-    return w;
+    return 0;
 }
 
-static void Close( hb_work_object_t ** _w )
+void encx264Close( hb_work_object_t * w )
 {
-    hb_work_object_t * w = *_w;
-
-    x264_encoder_close( w->x264 );
+    hb_work_private_t * pv = w->private_data;
+    x264_encoder_close( pv->x264 );
 
     /* TODO */
-
-    free( w->name );
-    free( w );
-    *_w = NULL;
 }
 
-static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
-                 hb_buffer_t ** buf_out )
+int encx264Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
+                  hb_buffer_t ** buf_out )
 {
-    hb_job_t    * job = w->job;
+    hb_work_private_t * pv = w->private_data;
+    hb_job_t    * job = pv->job;
     hb_buffer_t * in = *buf_in, * buf;
     int           i_nal;
     x264_nal_t  * nal;
     int i;
 
     /* XXX avoid this memcpy ? */
-    memcpy( w->pic_in.img.plane[0], in->data, job->width * job->height );
+    memcpy( pv->pic_in.img.plane[0], in->data, job->width * job->height );
     if( job->grayscale )
     {
         /* XXX x264 has currently no option for grayscale encoding */
-        memset( w->pic_in.img.plane[1], 0x80, job->width * job->height / 4 );
-        memset( w->pic_in.img.plane[2], 0x80, job->width * job->height / 4 );
+        memset( pv->pic_in.img.plane[1], 0x80, job->width * job->height / 4 );
+        memset( pv->pic_in.img.plane[2], 0x80, job->width * job->height / 4 );
     }
     else
     {
-        memcpy( w->pic_in.img.plane[1], in->data + job->width * job->height,
+        memcpy( pv->pic_in.img.plane[1], in->data + job->width * job->height,
                 job->width * job->height / 4 );
-        memcpy( w->pic_in.img.plane[2], in->data + 5 * job->width *
+        memcpy( pv->pic_in.img.plane[2], in->data + 5 * job->width *
                 job->height / 4, job->width * job->height / 4 );
     }
 
-    w->pic_in.i_type    = X264_TYPE_AUTO;
-    w->pic_in.i_qpplus1 = 0;
+    pv->pic_in.i_type    = X264_TYPE_AUTO;
+    pv->pic_in.i_qpplus1 = 0;
 
-    x264_encoder_encode( w->x264, &nal, &i_nal,
-                         &w->pic_in, &w->pic_out );
+    x264_encoder_encode( pv->x264, &nal, &i_nal,
+                         &pv->pic_in, &pv->pic_out );
 
     /* Should be way too large */
     buf        = hb_buffer_init( 3 * job->width * job->height / 2 );
index a874d9f..87c42b0 100644 (file)
@@ -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;
 
index c93d482..d241ae5 100644 (file)
@@ -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
  **********************************************************************/
index 646a254..d5002fa 100644 (file)
@@ -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;
index cdada7f..cf6d7b3 100644 (file)
@@ -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;
 }
index 61e567b..cd526c1 100644 (file)
@@ -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 );
 }
index 6c0be24..c225853 100644 (file)
@@ -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 */