]> granicus.if.org Git - handbrake/commitdiff
Implements core library support for all current and future x264 options, a la mencoder.
authorjbrjake <jb.rubin@gmail.com>
Wed, 14 Feb 2007 22:55:02 +0000 (22:55 +0000)
committerjbrjake <jb.rubin@gmail.com>
Wed, 14 Feb 2007 22:55:02 +0000 (22:55 +0000)
git-svn-id: svn://svn.handbrake.fr/HandBrake/branches/0.8.0_beta2_5.1@332 b64f7644-9d1e-0410-96f1-a4d463321fa5

libmediafork/common.h
libmediafork/encx264.c
libmediafork/muxmp4.c

index 082b1300c4dcd1fa2ec16fe733424e2bfe1f8b19..7b4fd97436c027a3ffc944d5f72b40da605e59e0 100644 (file)
@@ -135,6 +135,8 @@ struct hb_job_s
     int             h264_13;
        int                             h264_level;
        int                             crf;
+       const char                      *x264opts;
+       int                             areBframes;
        
     /* Audio tracks:
          audios:         Indexes in hb_title_t's audios list, starting from 0.
index cdd8e9b697345a8ef27e07dddb1aec0a17c2cf0e..4b991bd6d903d44cf484a57f15c9174610e3759b 100644 (file)
@@ -60,7 +60,7 @@ int encx264Init( hb_work_object_t * w, hb_job_t * job )
     param.i_fps_num    = job->vrate;
     param.i_fps_den    = job->vrate_base;
     param.i_keyint_max = 20 * job->vrate / job->vrate_base;
-    param.i_log_level  = X264_LOG_NONE;
+    param.i_log_level  = X264_LOG_INFO;
        if( job->h264_level )
        {
        param.i_threads   = 1;
@@ -73,6 +73,69 @@ int encx264Init( hb_work_object_t * w, hb_job_t * job )
        /* Slightly faster with minimal quality lost */
        param.analyse.i_subpel_refine = 4;
 
+       /*      This section passes the string x264opts to libx264 for parsing into parameter names and values.
+
+       The string is set up like this:
+       option1=value1:option2=value 2
+
+       So, you have to iterate through based on the colons, and then put the left side of the equals sign in "name"
+       and the right side into "value." Then you hand those strings off to x264 for interpretation.
+
+       This is all based on the universal x264 option handling Loren Merritt implemented in the Mplayer/Mencoder project.
+       */
+       char *x264opts = job->x264opts;
+       if(x264opts != NULL && *x264opts != '\0')
+       {
+               while(*x264opts)
+               {
+               char *name = x264opts;
+               char *value;
+               int ret;
+
+               x264opts += strcspn(x264opts, ":");
+               if(*x264opts)
+                       {
+                       *x264opts = 0;
+                       x264opts++;
+                       }
+
+               value = strchr( name, '=' );
+               if(value)
+                       {
+                       *value = 0;
+                       value++;
+                       }
+               
+                       /*
+                               When B-frames are enabled, the max frame count increments by 1 (regardless of the number of B-frames).
+                               If you don't change the duration of the video track when you mux, libmp4 barfs.
+                               So, check if the x264opts are using B-frames, and when they are, set the boolean job->areBframes as true.
+                       */
+
+                       if (!(strcmp(name, "bframes")))
+                       {
+                               if (atoi(value) > 0)
+                               {
+                                       job->areBframes = 1;
+                               }
+                       }
+
+                       /*      Here's where the strings are passed to libx264 for parsing. */
+               ret = x264_param_parse(&param, name, value);
+       
+                       /*      Let x264 sanity check the options for us*/
+               if(ret == X264_PARAM_BAD_NAME)
+                       hb_log("Option x264encopts: Unknown suboption %s\n", name);
+               if(ret == X264_PARAM_BAD_VALUE)
+                       hb_log("Option x264encopts: Bad argument %s=%s\n", name, value ? value : "(null)");
+               if(ret)
+                       return 0;
+
+                       }
+               }
+
+
        if( job->pixel_ratio )
        {
            param.vui.i_sar_width = job->pixel_aspect_width;
index 1fc201f4df68a0b70b246955e3f7e4c1616b989b..5e23f3d89fbc2bebf902ef93d18ee9733cc90005 100644 (file)
@@ -62,12 +62,26 @@ static int MP4Init( hb_mux_object_t * m )
         /* Stolen from mp4creator */
         MP4SetVideoProfileLevel( m->file, 0x7F );
 
-        mux_data->track = MP4AddH264VideoTrack( m->file, job->arate,
-                MP4_INVALID_DURATION, job->width, job->height,
-                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 */
+               if (job->areBframes == 1)
+               {
+                       hb_log("muxmp4: Adjusting duration for B-frames");
+                   mux_data->track = MP4AddH264VideoTrack( m->file, job->arate,
+                           MP4_INVALID_DURATION+1, job->width, job->height,
+                           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 */                 
+               }
+               else
+               {
+                       hb_log("muxmp4: Using default duration as there are no B-frames");
+               mux_data->track = MP4AddH264VideoTrack( m->file, job->arate,
+                       MP4_INVALID_DURATION, job->width, job->height,
+                       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,
                 job->config.h264.sps, job->config.h264.sps_length );