diff --git a/common/common.c b/common/common.c
index 4617387..205af07 100644
--- a/common/common.c
+++ b/common/common.c
@@ -75,7 +75,7 @@ void    x264_param_default( x264_param_t *param )
     param->i_scenecut_threshold = 40;
     param->i_bframe_adaptive = X264_B_ADAPT_FAST;
     param->i_bframe_bias = 0;
-    param->b_bframe_pyramid = 0;
+    param->i_bframe_pyramid = 0;
 
     param->b_deblocking_filter = 1;
     param->i_deblocking_filter_alphac0 = 0;
@@ -363,7 +363,7 @@ int x264_param_parse( x264_param_t *p, const char *name, const char *value )
     OPT("b-bias")
         p->i_bframe_bias = atoi(value);
     OPT("b-pyramid")
-        p->b_bframe_pyramid = atobool(value);
+        p->i_bframe_pyramid = atoi(value);
     OPT("nf")
         p->b_deblocking_filter = !atobool(value);
     OPT2("filter", "deblock")
@@ -882,7 +882,7 @@ char *x264_param2string( x264_param_t *p, int b_res )
     if( p->i_bframe )
     {
         s += sprintf( s, " b_pyramid=%d b_adapt=%d b_bias=%d direct=%d wpredb=%d",
-                      p->b_bframe_pyramid, p->i_bframe_adaptive, p->i_bframe_bias,
+                      p->i_bframe_pyramid, p->i_bframe_adaptive, p->i_bframe_bias,
                       p->analyse.i_direct_mv_pred, p->analyse.b_weighted_bipred );
     }
 
diff --git a/common/common.h b/common/common.h
index 81c7b00..d6ffa05 100644
--- a/common/common.h
+++ b/common/common.h
@@ -220,11 +220,18 @@ typedef struct
 
     int b_ref_pic_list_reordering_l0;
     int b_ref_pic_list_reordering_l1;
-    struct {
+    struct
+    {
         int idc;
         int arg;
     } ref_pic_list_order[2][16];
 
+    int i_mmco_idx;
+    struct // struct for future expansion
+    {
+        int i_difference_of_pic_nums;
+    } mmco[16];
+
     int i_cabac_init_idc;
 
     int i_qp;
@@ -394,6 +401,11 @@ struct x264_t
     x264_frame_t    *fref1[16+3];     /* ref list 1 */
     int             b_ref_reorder[2];
 
+    int             i_mmco_idx;
+    struct
+    {
+        int         i_difference_of_pic_nums;
+    } mmco[16];
 
 
     /* Current MB DCT coeffs */
diff --git a/common/macroblock.c b/common/macroblock.c
index 0fa3676..25d4c07 100644
--- a/common/macroblock.c
+++ b/common/macroblock.c
@@ -694,7 +694,7 @@ int x264_macroblock_cache_init( x264_t *h )
 
     for( i=0; i<2; i++ )
     {
-        int i_refs = X264_MIN(16, (i ? 1 : h->param.i_frame_reference) + h->param.b_bframe_pyramid) << h->param.b_interlaced;
+        int i_refs = X264_MIN(16, (i ? 1 : h->param.i_frame_reference) + !!h->param.i_bframe_pyramid) << h->param.b_interlaced;
         for( j=0; j < i_refs; j++ )
             CHECKED_MALLOC( h->mb.mvr[i][j], 2 * i_mb_count * sizeof(int16_t) );
     }
diff --git a/encoder/encoder.c b/encoder/encoder.c
index 56e5d5b..15adb2e 100644
--- a/encoder/encoder.c
+++ b/encoder/encoder.c
@@ -122,6 +122,14 @@ static void x264_slice_header_init( x264_t *h, x264_slice_header_t *sh,
 
     sh->b_ref_pic_list_reordering_l0 = h->b_ref_reorder[0];
     sh->b_ref_pic_list_reordering_l1 = h->b_ref_reorder[1];
+    
+    sh->i_mmco_idx = h->i_mmco_idx;
+    if( h->i_mmco_idx )
+    {
+        int j = 0;
+        for( ; j < h->i_mmco_idx; j++ )
+            sh->mmco[j].i_difference_of_pic_nums = h->mmco[j].i_difference_of_pic_nums;
+    }
 
     /* If the ref list isn't in the default order, construct reordering header */
     /* List1 reordering isn't needed yet */
@@ -139,6 +147,21 @@ static void x264_slice_header_init( x264_t *h, x264_slice_header_t *sh,
         }
     }
 
+    if( sh->b_ref_pic_list_reordering_l1 )
+    {
+        int pred_frame_num = i_frame;
+        for( i = 0; i < h->i_ref1; i++ )
+        {
+            
+            int diff = h->fref1[i]->i_frame_num - pred_frame_num;
+            if( diff == 0 )
+                x264_log( h, X264_LOG_ERROR, "diff frame num == 0\n" );
+            sh->ref_pic_list_order[1][i].idc = ( diff > 0 );
+            sh->ref_pic_list_order[1][i].arg = abs( diff ) - 1;
+            pred_frame_num = h->fref1[i]->i_frame_num;
+        }
+    }
+
     sh->i_cabac_init_idc = param->i_cabac_init_idc;
 
     sh->i_qp = i_qp;
@@ -272,7 +295,17 @@ static void x264_slice_header_write( bs_t *s, x264_slice_header_t *sh, int i_nal
         }
         else
         {
-            bs_write1( s, 0 );  /* adaptive_ref_pic_marking_mode_flag */
+            bs_write1( s, sh->i_mmco_idx > 0 ); /* adaptive_ref_pic_marking_mode_flag */
+            if( sh->i_mmco_idx > 0 )
+            {
+                int i = 0;
+                for( ; i < sh->i_mmco_idx; i++ )
+                {
+                    bs_write_ue( s, 1 ); /* mark short term ref as unused */
+                    bs_write_ue( s, sh->mmco[i].i_difference_of_pic_nums - 1 );
+                }
+                bs_write_ue( s, 0 );
+            }
         }
     }
 
@@ -498,7 +531,9 @@ static int x264_validate_parameters( x264_t *h )
     if( h->param.i_keyint_max == 1 )
         h->param.i_bframe = 0;
     h->param.i_bframe_bias = x264_clip3( h->param.i_bframe_bias, -90, 100 );
-    h->param.b_bframe_pyramid = h->param.b_bframe_pyramid && h->param.i_bframe > 1;
+    if( h->param.i_bframe <= 1 )
+        h->param.i_bframe_pyramid = 0;
+    h->param.i_bframe_pyramid = x264_clip3( h->param.i_bframe_pyramid, X264_B_PYRAMID_NONE, X264_B_PYRAMID_NORMAL );
     if( !h->param.i_bframe )
     {
         h->param.i_bframe_adaptive = X264_B_ADAPT_NONE;
@@ -603,10 +638,10 @@ static int x264_validate_parameters( x264_t *h )
         h->param.rc.i_aq_mode = 1;
         h->param.rc.f_aq_strength = 0;
     }
-    if( h->param.rc.b_mb_tree && h->param.b_bframe_pyramid )
+    if( h->param.rc.b_mb_tree && h->param.i_bframe_pyramid )
     {
         x264_log( h, X264_LOG_WARNING, "b-pyramid + mb-tree is not supported\n" );
-        h->param.b_bframe_pyramid = 0;
+        h->param.i_bframe_pyramid = 0;
     }
     h->param.analyse.i_noise_reduction = x264_clip3( h->param.analyse.i_noise_reduction, 0, 1<<16 );
     if( h->param.analyse.i_subpel_refine == 10 && (h->param.analyse.i_trellis != 2 || !h->param.rc.i_aq_mode) )
@@ -968,7 +1003,7 @@ int x264_encoder_reconfig( x264_t *h, x264_param_t *param )
     if( h->pps->b_transform_8x8_mode )
         COPY( analyse.b_transform_8x8 );
     if( h->frames.i_max_ref1 > 1 )
-        COPY( b_bframe_pyramid );
+        COPY( i_bframe_pyramid );
     COPY( i_slice_max_size );
     COPY( i_slice_max_mbs );
     COPY( i_slice_count );
@@ -1112,6 +1147,12 @@ static inline void x264_reference_build_list( x264_t *h, int i_poc )
                 break;
             }
     }
+    if( h->param.i_bframe_pyramid && h->sh.i_type != SLICE_TYPE_I )
+    {
+        h->b_ref_reorder[0] = 1;
+        if( h->sh.i_type == SLICE_TYPE_B )
+            h->b_ref_reorder[1] = 1;
+    }
 
     h->i_ref1 = X264_MIN( h->i_ref1, h->frames.i_max_ref1 );
     h->i_ref0 = X264_MIN( h->i_ref0, h->frames.i_max_ref0 );
@@ -1232,6 +1273,41 @@ static inline void x264_reference_reset( x264_t *h )
     h->fenc->i_poc = 0;
 }
 
+static inline void x264_reference_partial_reset( x264_t *h )
+{
+    int refs = 0;
+    int lastnonbidx = -1;
+    while( h->frames.reference[refs] )
+    {
+        if( h->frames.reference[refs]->i_type == X264_TYPE_I
+         || h->frames.reference[refs]->i_type == X264_TYPE_IDR
+         || h->frames.reference[refs]->i_type == X264_TYPE_P )
+            lastnonbidx = refs;
+        refs++;
+    }
+    assert( lastnonbidx > -1 );
+    /* Remove any brefs from dpb remembering if current frame is bref
+     * x264 has not added it yet. only will be true for i or P frames. */
+    while( refs > lastnonbidx+1 && h->param.i_bframe_pyramid == X264_B_PYRAMID_STRICT )
+    {
+        int diff = h->i_frame_num - h->frames.reference[refs-1]->i_frame_num;
+        h->mmco[h->i_mmco_idx++].i_difference_of_pic_nums = diff;
+        x264_frame_push_unused( h, x264_frame_pop( h->frames.reference ) );
+        refs--;
+    }
+    /* This makes room in the dpb for the delayed display time of the later b-frame's
+     * the x264_max is to make sure that a foward and backward reference is always left
+     * for b-frames incase too few reference frames are used with b-pyramid. ( < 4 ) */
+    while( ( refs + 2 ) > X264_MAX( h->frames.i_max_dpb, 4 ) && h->param.i_bframe_pyramid )
+    {
+        int diff = h->i_frame_num - h->frames.reference[0]->i_frame_num;
+        h->mmco[h->i_mmco_idx++].i_difference_of_pic_nums = diff;
+        x264_frame_push_unused( h, x264_frame_shift( h->frames.reference ) );
+        lastnonbidx--;
+        refs--;
+    }
+}
+
 static inline void x264_slice_init( x264_t *h, int i_nal_type, int i_global_qp )
 {
     /* ------------------------ Create slice header  ----------------------- */
@@ -1706,18 +1782,21 @@ int     x264_encoder_encode( x264_t *h,
         i_nal_type    = NAL_SLICE;
         i_nal_ref_idc = NAL_PRIORITY_HIGH; /* Not completely true but for now it is (as all I/P are kept as ref)*/
         h->sh.i_type = SLICE_TYPE_I;
+        x264_reference_partial_reset( h );
     }
     else if( h->fenc->i_type == X264_TYPE_P )
     {
         i_nal_type    = NAL_SLICE;
         i_nal_ref_idc = NAL_PRIORITY_HIGH; /* Not completely true but for now it is (as all I/P are kept as ref)*/
         h->sh.i_type = SLICE_TYPE_P;
+        x264_reference_partial_reset( h );
     }
     else if( h->fenc->i_type == X264_TYPE_BREF )
     {
         i_nal_type    = NAL_SLICE;
         i_nal_ref_idc = NAL_PRIORITY_HIGH; /* maybe add MMCO to forget it? -> low */
         h->sh.i_type = SLICE_TYPE_B;
+        x264_reference_partial_reset( h );
     }
     else    /* B frame */
     {
@@ -1725,6 +1804,7 @@ int     x264_encoder_encode( x264_t *h,
         i_nal_ref_idc = NAL_PRIORITY_DISPOSABLE;
         h->sh.i_type = SLICE_TYPE_B;
     }
+    h->i_mmco_idx = 0;
 
     h->fdec->i_poc =
     h->fenc->i_poc = 2 * (h->fenc->i_frame - h->frames.i_last_idr);
diff --git a/encoder/lookahead.c b/encoder/lookahead.c
index 35ed729..53a0bc5 100644
--- a/encoder/lookahead.c
+++ b/encoder/lookahead.c
@@ -213,7 +213,7 @@ static void x264_lookahead_encoder_shift( x264_t *h )
     {
         x264_frame_push( h->frames.current, x264_frame_shift( &h->lookahead->ofbuf.list[bframes] ) );
         h->lookahead->ofbuf.i_size--;
-        if( h->param.b_bframe_pyramid && bframes > 1 )
+        if( h->param.i_bframe_pyramid && bframes > 1 )
         {
             x264_frame_t *mid = x264_frame_shift( &h->lookahead->ofbuf.list[bframes/2] );
             h->lookahead->ofbuf.i_size--;
diff --git a/encoder/ratecontrol.c b/encoder/ratecontrol.c
index cb8a9d4..56485f7 100644
--- a/encoder/ratecontrol.c
+++ b/encoder/ratecontrol.c
@@ -501,7 +501,7 @@ int x264_ratecontrol_new( x264_t *h )
 
             /* since B-adapt doesn't (yet) take into account B-pyramid,
              * the converse is not a problem */
-            if( strstr( opts, "b_pyramid=1" ) && !h->param.b_bframe_pyramid )
+            if( strstr( opts, "b_pyramid=1" ) && !h->param.i_bframe_pyramid )
                 x264_log( h, X264_LOG_WARNING, "1st pass used B-pyramid, 2nd doesn't\n" );
 
             if( ( p = strstr( opts, "keyint=" ) ) && sscanf( p, "keyint=%d", &i )
diff --git a/encoder/set.c b/encoder/set.c
index 5c00096..0f141c5 100644
--- a/encoder/set.c
+++ b/encoder/set.c
@@ -193,7 +193,7 @@ void x264_sps_init( x264_sps_t *sps, int i_id, x264_param_t *param )
         sps->vui.b_fixed_frame_rate = 1;
     }
 
-    sps->vui.i_num_reorder_frames = param->b_bframe_pyramid ? 2 : param->i_bframe ? 1 : 0;
+    sps->vui.i_num_reorder_frames = param->i_bframe_pyramid ? 2 : param->i_bframe ? 1 : 0;
     /* extra slot with pyramid so that we don't have to override the
      * order of forgetting old pictures */
     sps->vui.i_max_dec_frame_buffering =
diff --git a/x264.c b/x264.c
index 0ed538a..9844486 100644
--- a/x264.c
+++ b/x264.c
@@ -190,7 +190,11 @@ static void Help( x264_param_t *defaults, int b_longhelp )
         "                                  - 1: Fast\n"
         "                                  - 2: Optimal (slow with high --bframes)\n", defaults->i_bframe_adaptive );
     H1( "      --b-bias <integer>      Influences how often B-frames are used [%d]\n", defaults->i_bframe_bias );
-    H0( "      --b-pyramid             Keep some B-frames as references\n" );
+    H1( "      --b-pyramid <integer>   Keep some B-frames as references [%d]\n"
+        "                                  - 0: Disabled\n"
+        "                                  - 1: Strictly heirarchical\n"
+        "                                  - 2: Normal (not Blu-ray compatible)\n", defaults->i_bframe_pyramid );
+    H0( "      --b-strict-hierarchical Remove BREFs from dpb so no non B-frame refers to them\n" );
     H0( "      --no-cabac              Disable CABAC\n" );
     H0( "  -r, --ref <integer>         Number of reference frames [%d]\n", defaults->i_frame_reference );
     H1( "      --no-deblock            Disable loop filter\n" );
@@ -394,7 +398,7 @@ static struct option long_options[] =
     { "b-adapt",     required_argument, NULL, 0 },
     { "no-b-adapt",        no_argument, NULL, 0 },
     { "b-bias",      required_argument, NULL, 0 },
-    { "b-pyramid",         no_argument, NULL, 0 },
+    { "b-pyramid",   required_argument, NULL, 0 },
     { "min-keyint",  required_argument, NULL, 'i' },
     { "keyint",      required_argument, NULL, 'I' },
     { "scenecut",    required_argument, NULL, 0 },
diff --git a/x264.h b/x264.h
index 66f4f28..1b6e56c 100644
--- a/x264.h
+++ b/x264.h
@@ -35,7 +35,7 @@
 
 #include <stdarg.h>
 
-#define X264_BUILD 75
+#define X264_BUILD 76
 
 /* x264_t:
  *      opaque handler for encoder */
@@ -95,6 +95,9 @@ typedef struct x264_t x264_t;
 #define X264_B_ADAPT_NONE            0
 #define X264_B_ADAPT_FAST            1
 #define X264_B_ADAPT_TRELLIS         2
+#define X264_B_PYRAMID_NONE          0
+#define X264_B_PYRAMID_STRICT        1
+#define X264_B_PYRAMID_NORMAL        2
 
 static const char * const x264_direct_pred_names[] = { "none", "spatial", "temporal", "auto", 0 };
 static const char * const x264_motion_est_names[] = { "dia", "hex", "umh", "esa", "tesa", 0 };
@@ -196,7 +199,7 @@ typedef struct x264_param_t
     int         i_bframe;   /* how many b-frame between 2 references pictures */
     int         i_bframe_adaptive;
     int         i_bframe_bias;
-    int         b_bframe_pyramid;   /* Keep some B-frames as references */
+    int         i_bframe_pyramid;   /* Keep some B-frames as references: 0=off, 1=on, 2=strict heirarchical */
 
     int         b_deblocking_filter;
     int         i_deblocking_filter_alphac0;    /* [-6, 6] -6 light filter, 6 strong */