diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c
index 7c4ca637849e4326b69339a999ac98a3544b9518..adc1b793531fe428f48dc25633b387cd39c9b2f3 100644
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -353,13 +353,14 @@ static double simple_weight(YV12_BUFFER_CONFIG *source) {
 // This function returns the maximum target rate per frame.
 static int frame_max_bits(VP9_COMP *cpi) {
   int64_t max_bits =
-     ((int64_t)cpi->rc.av_per_frame_bandwidth *
-      (int64_t)cpi->oxcf.two_pass_vbrmax_section) / 100;
+    ((int64_t)cpi->rc.av_per_frame_bandwidth *
+     (int64_t)cpi->oxcf.two_pass_vbrmax_section) / 100;
 
   if (max_bits < 0)
-    return 0;
-  if (max_bits >= INT_MAX)
-    return INT_MAX;
+    max_bits = 0;
+  else if (max_bits > cpi->rc.max_frame_bandwidth)
+    max_bits = cpi->rc.max_frame_bandwidth;
+
   return (int)max_bits;
 }
 
diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c
index 8e60bc96d2c1ed76461110ae61092e8e4b9c13a7..2bcfcd4f07a52448639c31aeab77ce29d21bfff9 100644
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -59,6 +59,11 @@ void vp9_coef_tree_initialize();
 #define DISABLE_COMPOUND_SPLIT    0x18
 #define LAST_AND_INTRA_SPLIT_ONLY 0x1E
 
+// Max rate target for 1080P and below encodes under normal circumstances
+// (1920 * 1080 / (16 * 16)) * MAX_MB_RATE bits per MB
+#define MAX_MB_RATE 250
+#define MAXRATE_1080P 2025000
+
 #if CONFIG_INTERNAL_STATS
 extern double vp9_calc_ssim(YV12_BUFFER_CONFIG *source,
                             YV12_BUFFER_CONFIG *dest, int lumamask,
@@ -1093,6 +1098,9 @@ int vp9_reverse_trans(int x) {
 };
 
 void vp9_new_framerate(VP9_COMP *cpi, double framerate) {
+  VP9_COMMON *const cm = &cpi->common;
+  int64_t vbr_max_bits;
+
   if (framerate < 0.1)
     framerate = 30;
 
@@ -1109,6 +1117,19 @@ void vp9_new_framerate(VP9_COMP *cpi, double framerate) {
   cpi->rc.min_frame_bandwidth = MAX(cpi->rc.min_frame_bandwidth,
                                     FRAME_OVERHEAD_BITS);
 
+  // A maximum bitrate for a frame is defined.
+  // The baseline for this aligns with HW implementations that
+  // can support decode of 1080P content up to a bitrate of MAX_MB_RATE bits
+  // per 16x16 MB (averaged over a frame). However this limit is extended if
+  // a very high rate is given on the command line or the the rate cannnot
+  // be acheived because of a user specificed max q (e.g. when the user
+  // specifies lossless encode.
+  //
+  vbr_max_bits = ((int64_t)cpi->rc.av_per_frame_bandwidth *
+                  (int64_t)cpi->oxcf.two_pass_vbrmax_section) / 100;
+  cpi->rc.max_frame_bandwidth =
+    MAX(MAX((cm->MBs * MAX_MB_RATE), MAXRATE_1080P), vbr_max_bits);
+
   // Set Maximum gf/arf interval
   cpi->rc.max_gf_interval = 16;
 
@@ -2449,10 +2470,14 @@ static int recode_loop_test(VP9_COMP *cpi,
   int force_recode = 0;
   VP9_COMMON *cm = &cpi->common;
 
-  // Is frame recode allowed at all
-  // Yes if either recode mode 1 is selected or mode two is selected
-  // and the frame is a key frame. golden frame or alt_ref_frame
-  if ((cpi->sf.recode_loop == 1) ||
+  // Special case trap if maximum allowed frame size exceeded.
+  if (cpi->rc.projected_frame_size > cpi->rc.max_frame_bandwidth) {
+    force_recode = 1;
+
+  // Is frame recode allowed.
+  // Yes if either recode mode 1 is selected or mode 2 is selected
+  // and the frame is a key frame, golden frame or alt_ref_frame
+  } else if ((cpi->sf.recode_loop == 1) ||
       ((cpi->sf.recode_loop == 2) &&
        ((cm->frame_type == KEY_FRAME) ||
         cpi->refresh_golden_frame ||
@@ -2630,7 +2655,8 @@ static void output_frame_level_debug_stats(VP9_COMP *cpi) {
         "%6d %6d %5d %5d %5d %10d %10.3f"
         "%10.3f %8d %10d %10d %10d\n",
         cpi->common.current_video_frame, cpi->rc.this_frame_target,
-        cpi->rc.projected_frame_size, 0,
+        cpi->rc.projected_frame_size,
+        cpi->rc.projected_frame_size / cpi->common.MBs,
         (cpi->rc.projected_frame_size - cpi->rc.this_frame_target),
         (int)cpi->rc.total_target_vs_actual,
         (int)(cpi->oxcf.starting_buffer_level - cpi->rc.bits_off_target),
@@ -2740,8 +2766,9 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
     if (cpi->oxcf.end_usage == USAGE_CONSTANT_QUALITY) {
       loop = 0;
     } else {
-      // Special case handling for forced key frames
-      if ((cm->frame_type == KEY_FRAME) && cpi->rc.this_key_frame_forced) {
+      if ((cm->frame_type == KEY_FRAME) &&
+           cpi->rc.this_key_frame_forced &&
+           (cpi->rc.projected_frame_size < cpi->rc.max_frame_bandwidth)) {
         int last_q = *q;
         int kf_err = vp9_calc_ss_err(cpi->Source, get_frame_new_buffer(cm));
 
@@ -2780,7 +2807,7 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
         loop = *q != last_q;
       } else if (recode_loop_test(
           cpi, frame_over_shoot_limit, frame_under_shoot_limit,
-          *q, top_index, bottom_index)) {
+          *q, MAX(q_high, top_index), bottom_index)) {
         // Is the projected frame size out of range and are we allowed
         // to attempt to recode.
         int last_q = *q;
@@ -2791,6 +2818,10 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
 
         // Frame is too large
         if (cpi->rc.projected_frame_size > cpi->rc.this_frame_target) {
+          // Special case if the projected size is > the max allowed.
+          if (cpi->rc.projected_frame_size >= cpi->rc.max_frame_bandwidth)
+            q_high = cpi->rc.worst_quality;
+
           // Raise Qlow as to at least the current value
           q_low = *q < q_high ? *q + 1 : q_high;
 
@@ -2804,12 +2835,12 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
             vp9_rc_update_rate_correction_factors(cpi, 0);
 
             *q = vp9_rc_regulate_q(cpi, cpi->rc.this_frame_target,
-                                   bottom_index, top_index);
+                                   bottom_index, MAX(q_high, top_index));
 
             while (*q < q_low && retries < 10) {
               vp9_rc_update_rate_correction_factors(cpi, 0);
               *q = vp9_rc_regulate_q(cpi, cpi->rc.this_frame_target,
-                                     bottom_index, top_index);
+                                     bottom_index, MAX(q_high, top_index));
               retries++;
             }
           }
@@ -2855,7 +2886,9 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
       }
     }
 
-    if (cpi->rc.is_src_frame_alt_ref)
+    // Special case for overlay frame.
+    if (cpi->rc.is_src_frame_alt_ref &&
+        (cpi->rc.projected_frame_size < cpi->rc.max_frame_bandwidth))
       loop = 0;
 
     if (loop) {
diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h
index a5be0f424734548ff66f1d0855deb5384004bbb0..be079d8596ca9af4eb6d8e71c835a545ae585fd4 100644
--- a/vp9/encoder/vp9_onyx_int.h
+++ b/vp9/encoder/vp9_onyx_int.h
@@ -442,9 +442,10 @@ typedef struct {
   unsigned int source_alt_ref_active;
   unsigned int is_src_frame_alt_ref;
 
-  int per_frame_bandwidth;  // Current section per frame bandwidth target
-  int av_per_frame_bandwidth;  // Average frame size target for clip
-  int min_frame_bandwidth;  // Minimum allocation used for any frame
+  int per_frame_bandwidth;        // Current section per frame bandwidth target
+  int av_per_frame_bandwidth;     // Average frame size target for clip
+  int min_frame_bandwidth;        // Minimum allocation used for any frame
+  int max_frame_bandwidth;        // Maximum burst rate allowed for a frame.
 
   int ni_av_qi;
   int ni_tot_qi;
diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c
index 939a7f9983e3864deaa5020ee36958626ea3d0dc..ae1aaa32ea0aaf43d84ea5c0f91e4312440eb727 100644
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -746,8 +746,13 @@ int vp9_rc_pick_q_and_adjust_q_bounds(const VP9_COMP *cpi,
   } else {
     q = vp9_rc_regulate_q(cpi, cpi->rc.this_frame_target,
                           active_best_quality, active_worst_quality);
-    if (q > *top_index)
-      q = *top_index;
+    if (q > *top_index) {
+      // Special case when we are targeting the max allowed rate
+      if (cpi->rc.this_frame_target >= cpi->rc.max_frame_bandwidth)
+        *top_index = q;
+      else
+        q = *top_index;
+    }
   }
 #if CONFIG_MULTIPLE_ARF
   // Force the quantizer determined by the coding order pattern.
@@ -810,6 +815,11 @@ void vp9_rc_compute_frame_size_bounds(const VP9_COMP *cpi,
     *frame_under_shoot_limit -= 200;
     if (*frame_under_shoot_limit < 0)
       *frame_under_shoot_limit = 0;
+
+    // Clip to maximum allowed rate for a frame.
+    if (*frame_over_shoot_limit > cpi->rc.max_frame_bandwidth) {
+      *frame_over_shoot_limit = cpi->rc.max_frame_bandwidth;
+    }
   }
 }
 
@@ -822,6 +832,10 @@ int vp9_rc_pick_frame_size_target(VP9_COMP *cpi) {
   else
     calc_pframe_target_size(cpi);
 
+  // Clip the frame target to the maximum allowed value.
+  if (cpi->rc.this_frame_target > cpi->rc.max_frame_bandwidth)
+    cpi->rc.this_frame_target = cpi->rc.max_frame_bandwidth;
+
   // Target rate per SB64 (including partial SB64s.
   cpi->rc.sb64_target_rate = ((int64_t)cpi->rc.this_frame_target * 64 * 64) /
                              (cpi->common.width * cpi->common.height);