Merge \\\\"Decoder: Initialize first_pb_nal_in_pic for error slices\\\\" into mnc-dev am: b9d7cba8bf am: c73e000665 am: 59248aa67c
am: c4ef0f6129

Change-Id: I57e93af0f4f9d3f3f2d0cbbccbf21397602cc87a
diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/MODULE_LICENSE_APACHE2
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..8a57d10
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,20 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+*/
+/*****************************************************************************/
diff --git a/decoder/ih264d_parse_headers.c b/decoder/ih264d_parse_headers.c
index 1d97071..e6cd61f 100644
--- a/decoder/ih264d_parse_headers.c
+++ b/decoder/ih264d_parse_headers.c
@@ -494,7 +494,7 @@
     UWORD32 u2_crop_offset_y = 0;
     UWORD32 u2_crop_offset_uv = 0;
     WORD32 ret;
-
+    UWORD32 u4_num_reorder_frames;
     /* High profile related syntax element */
     WORD32 i4_i;
     /* G050 */
@@ -571,6 +571,18 @@
     if(NULL == ps_dec->ps_cur_sps)
         ps_dec->ps_cur_sps = ps_seq;
 
+    if((3 == ps_dec->i4_header_decoded) && (ps_seq->u1_profile_idc != u1_profile_idc))
+    {
+        ps_dec->u1_res_changed = 1;
+        return IVD_RES_CHANGED;
+    }
+
+    if((3 == ps_dec->i4_header_decoded) && (ps_seq->u1_level_idc != u1_level_idc))
+    {
+        ps_dec->u1_res_changed = 1;
+        return IVD_RES_CHANGED;
+    }
+
     ps_seq->u1_profile_idc = u1_profile_idc;
     ps_seq->u1_level_idc = u1_level_idc;
     ps_seq->u1_seq_parameter_set_id = u1_seq_parameter_set_id;
@@ -737,6 +749,14 @@
     {
         return ERROR_NUM_REF;
     }
+
+    /* Compare with older num_ref_frames is header is already once */
+    if((3 == ps_dec->i4_header_decoded) && (ps_seq->u1_num_ref_frames != u4_temp))
+    {
+        ps_dec->u1_res_changed = 1;
+        return IVD_RES_CHANGED;
+    }
+
     ps_seq->u1_num_ref_frames = u4_temp;
     COPYTHECONTEXT("SPS: num_ref_frames",ps_seq->u1_num_ref_frames);
 
@@ -904,6 +924,17 @@
 
     }
 
+    /* Backup u4_num_reorder_frames if header is already decoded */
+    if((3 == ps_dec->i4_header_decoded) &&
+                    (1 == ps_seq->u1_vui_parameters_present_flag) &&
+                    (1 == ps_seq->s_vui.u1_bitstream_restriction_flag))
+    {
+        u4_num_reorder_frames =  ps_seq->s_vui.u4_num_reorder_frames;
+    }
+    else
+    {
+        u4_num_reorder_frames = -1;
+    }
     if(1 == ps_seq->u1_vui_parameters_present_flag)
     {
         ret = ih264d_parse_vui_parametres(&ps_seq->s_vui, ps_bitstrm);
@@ -911,6 +942,17 @@
             return ret;
     }
 
+    /* Compare older u4_num_reorder_frames with the new one if header is already decoded */
+    if((3 == ps_dec->i4_header_decoded) &&
+                    (-1 != (WORD32)u4_num_reorder_frames) &&
+                    (1 == ps_seq->u1_vui_parameters_present_flag) &&
+                    (1 == ps_seq->s_vui.u1_bitstream_restriction_flag) &&
+                    (ps_seq->s_vui.u4_num_reorder_frames != u4_num_reorder_frames))
+    {
+        ps_dec->u1_res_changed = 1;
+        return IVD_RES_CHANGED;
+    }
+
     ps_dec->u2_pic_wd = u2_pic_wd;
     ps_dec->u2_pic_ht = u2_pic_ht;
 
diff --git a/encoder/ih264e_api.c b/encoder/ih264e_api.c
index 69085ab..1c9a48b 100644
--- a/encoder/ih264e_api.c
+++ b/encoder/ih264e_api.c
@@ -1420,6 +1420,16 @@
                         return IV_FAIL;
                     }
 
+                    if ((ps_ip->s_ive_ip.u4_constrained_intra_pred != 0)
+                                    && (ps_ip->s_ive_ip.u4_constrained_intra_pred != 1))
+                    {
+                        ps_op->s_ive_op.u4_error_code |= 1
+                                        << IVE_UNSUPPORTEDPARAM;
+                        ps_op->s_ive_op.u4_error_code |=
+                                        IH264E_INVALID_CONSTRAINED_INTRA_PREDICTION_MODE;
+                        return IV_FAIL;
+                    }
+
                     if ((ps_ip->s_ive_ip.u4_enc_speed_preset != IVE_CONFIG)
                                     && (ps_ip->s_ive_ip.u4_enc_speed_preset != IVE_SLOWEST)
                                     && (ps_ip->s_ive_ip.u4_enc_speed_preset != IVE_NORMAL)
@@ -1979,7 +1989,7 @@
     else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_IPE_PARAMS)
     {
         ps_curr_cfg->u4_enc_speed_preset = ps_cfg->u4_enc_speed_preset;
-
+        ps_curr_cfg->u4_constrained_intra_pred = ps_cfg->u4_constrained_intra_pred;
         if (ps_curr_cfg->u4_enc_speed_preset == IVE_SLOWEST)
         {/* high quality */
             /* enable diamond search */
@@ -3915,7 +3925,7 @@
             }
         }
 
-        ps_codec->pu2_intr_rfrsh_map = (UWORD16 *) (pu1_buf + max_mb_cnt * 2);
+        ps_codec->pu2_intr_rfrsh_map = (UWORD16 *) (pu1_buf + max_mb_cnt * MAX_CTXT_SETS);
     }
 
     ps_mem_rec = &ps_mem_rec_base[MEM_REC_SLICE_MAP];
@@ -5069,6 +5079,8 @@
     ps_cfg->u4_enable_intra_4x4 = ps_ip->s_ive_ip.u4_enable_intra_4x4;
     ps_cfg->u4_enc_speed_preset = ps_ip->s_ive_ip.u4_enc_speed_preset;
 
+    ps_cfg->u4_constrained_intra_pred = ps_ip->s_ive_ip.u4_constrained_intra_pred;
+
     ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
     ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
 
diff --git a/encoder/ih264e_error.h b/encoder/ih264e_error.h
index 5a7a560..ba489c9 100644
--- a/encoder/ih264e_error.h
+++ b/encoder/ih264e_error.h
@@ -226,6 +226,9 @@
     /**Invalid entropy coding mode */
     IH264E_INVALID_ENTROPY_CODING_MODE                              = IH264E_CODEC_ERROR_START + 0x31,
 
+    /**Invalid Constrained Intra prediction mode */
+    IH264E_INVALID_CONSTRAINED_INTRA_PREDICTION_MODE                = IH264E_CODEC_ERROR_START + 0x32,
+
     /**max failure error code to ensure enum is 32 bits wide */
     IH264E_FAIL                                                     = -1,
 
diff --git a/encoder/ih264e_intra_modes_eval.c b/encoder/ih264e_intra_modes_eval.c
index 52b3034..871bdd4 100644
--- a/encoder/ih264e_intra_modes_eval.c
+++ b/encoder/ih264e_intra_modes_eval.c
@@ -363,15 +363,17 @@
     UWORD8 *pu1_mb_a = pu1_ref_mb - 1;
     UWORD8 *pu1_mb_b = pu1_ref_mb - i4_rec_strd;
     UWORD8 *pu1_mb_d = pu1_mb_b - 1;
-
+    UWORD8 u1_mb_a, u1_mb_b, u1_mb_d;
     /* valid intra modes map */
     UWORD32 u4_valid_intra_modes;
 
     /* lut for valid intra modes */
-    const UWORD8 u1_valid_intra_modes[8] = {4, 6, 12, 14, 5, 7, 13, 15};
+    const UWORD8 u1_valid_intra_modes[8] = {4, 6, 4, 6, 5, 7, 5, 15};
 
     /* temp var */
     UWORD32 i, u4_enable_fast_sad = 0, offset = 0;
+    mb_info_t *ps_top_mb_syn_ele = ps_proc->ps_top_row_mb_syntax_ele + ps_proc->i4_mb_x;
+    UWORD32 u4_constrained_intra_pred = ps_proc->ps_codec->s_cfg.u4_constrained_intra_pred;
 
     /* init temp var */
     if (ps_proc->i4_slice_type != ISLICE)
@@ -382,17 +384,13 @@
     }
 
     /* locating neighbors that are available for prediction */
-    /* TODO : update the neighbor availability information basing on constrained intra pred information */
-    /* TODO : i4_ngbr_avbl is only being used in DC mode. Can the DC mode be split in to distinct routines
-     * basing on neighbors available and hence evade the computation of neighbor availability totally. */
-    /* i4_ngbr_avbl = blk_a * LEFT_MB_AVAILABLE_MASK + blk_b * TOP_MB_AVAILABLE_MASK + blk_d * TOP_LEFT_MB_AVAILABLE_MASK */
-    i4_ngbr_avbl = (ps_proc->ps_ngbr_avbl->u1_mb_a) + (ps_proc->ps_ngbr_avbl->u1_mb_b << 2) + (ps_proc->ps_ngbr_avbl->u1_mb_d << 1);
-    ps_proc->i4_ngbr_avbl_16x16_mb = i4_ngbr_avbl;
 
     /* gather prediction pels from the neighbors, if particular set is not available
      * it is set to zero*/
     /* left pels */
-    if (ps_proc->ps_ngbr_avbl->u1_mb_a)
+    u1_mb_a = ((ps_proc->ps_ngbr_avbl->u1_mb_a)
+                    && (u4_constrained_intra_pred ? ps_proc->s_left_mb_syntax_ele.u2_is_intra : 1));
+    if (u1_mb_a)
     {
         for(i = 0; i < 16; i++)
             pu1_ngbr_pels_i16[16-1-i] = pu1_mb_a[i * i4_rec_strd];
@@ -402,33 +400,32 @@
         ps_codec->pf_mem_set_mul8(pu1_ngbr_pels_i16,0,MB_SIZE);
     }
     /* top pels */
-    if (ps_proc->ps_ngbr_avbl->u1_mb_b)
+    u1_mb_b = ((ps_proc->ps_ngbr_avbl->u1_mb_b)
+                    && (u4_constrained_intra_pred ? ps_top_mb_syn_ele->u2_is_intra : 1));
+    if (u1_mb_b)
     {
         ps_codec->pf_mem_cpy_mul8(pu1_ngbr_pels_i16+16+1,pu1_mb_b,16);
-        /*for(i = 0; i < 16; i++)
-            pu1_ngbr_pels_i16[16+1+i] = pu1_mb_b[i];*/
     }
     else
     {
         ps_codec->pf_mem_set_mul8(pu1_ngbr_pels_i16+16+1,0,MB_SIZE);
     }
     /* topleft pels */
-    if (ps_proc->ps_ngbr_avbl->u1_mb_d)
+    u1_mb_d = ((ps_proc->ps_ngbr_avbl->u1_mb_d)
+                    && (u4_constrained_intra_pred ? ps_proc->s_top_left_mb_syntax_ele.u2_is_intra : 1));
+    if (u1_mb_d)
+    {
         pu1_ngbr_pels_i16[16] = *pu1_mb_d;
+    }
     else
+    {
         pu1_ngbr_pels_i16[16] = 0;
+    }
+
+    i4_ngbr_avbl = (u1_mb_a) + (u1_mb_b << 2) + (u1_mb_d << 1);
+    ps_proc->i4_ngbr_avbl_16x16_mb = i4_ngbr_avbl;
 
     /* set valid intra modes for evaluation */
-//    u4_valid_intra_modes = 15;
-////    ih264e_filter_intra16x16modes(pu1_mb_curr, i4_src_strd, &u4_valid_intra_modes);
-//    if (!ps_proc->ps_ngbr_avbl->u1_mb_a)
-//        u4_valid_intra_modes &= ~(1 << HORZ_I16x16);
-//    if (!ps_proc->ps_ngbr_avbl->u1_mb_b)
-//        u4_valid_intra_modes &= ~(1 << VERT_I16x16);
-////    if (!ps_proc->ps_ngbr_avbl->u1_mb_a || !ps_proc->ps_ngbr_avbl->u1_mb_b || !ps_proc->ps_ngbr_avbl->u1_mb_d)
-//    if (i4_ngbr_avbl != 7)
-//        u4_valid_intra_modes &= ~(1 << PLANE_I16x16);
-
     u4_valid_intra_modes = u1_valid_intra_modes[i4_ngbr_avbl];
 
     if (ps_codec->s_cfg.u4_enc_speed_preset == IVE_FAST)
@@ -443,7 +440,7 @@
     /* cost = distortion + lambda*rate */
     i4_mb_cost_least = i4_mb_distortion_least;
 
-    if (( (u4_valid_intra_modes >> 3) & 1) != 0 && (ps_codec->s_cfg.u4_enc_speed_preset != IVE_FASTEST ||
+    if ((( (u4_valid_intra_modes >> 3) & 1) != 0) && (ps_codec->s_cfg.u4_enc_speed_preset != IVE_FASTEST ||
                     ps_proc->i4_slice_type == ISLICE))
     {
         /* intra prediction for PLANE mode*/
@@ -562,14 +559,37 @@
 
     /* temp vars */
     UWORD32  b8, u4_pix_x, u4_pix_y;
+    UWORD32 u4_constrained_intra_pred = ps_proc->ps_codec->s_cfg.u4_constrained_intra_pred;
+    block_neighbors_t s_ngbr_avbl_MB;
 
     /* ngbr mb syntax information */
     UWORD8 *pu1_top_mb_intra_modes = ps_proc->pu1_top_mb_intra_modes + (ps_proc->i4_mb_x << 4);
     mb_info_t *ps_top_mb_syn_ele = ps_proc->ps_top_row_mb_syntax_ele + ps_proc->i4_mb_x;
-
+    mb_info_t *ps_top_right_mb_syn_ele = ps_proc->ps_top_row_mb_syntax_ele + ps_proc->i4_mb_x;
     /* valid intra modes map */
     UWORD32 u4_valid_intra_modes;
 
+    if (ps_proc->ps_ngbr_avbl->u1_mb_c)
+    {
+        ps_top_right_mb_syn_ele = ps_proc->ps_top_row_mb_syntax_ele + (ps_proc->i4_mb_x + 1);
+    }
+    /* left pels */
+    s_ngbr_avbl_MB.u1_mb_a = ((ps_proc->ps_ngbr_avbl->u1_mb_a)
+                                  && (u4_constrained_intra_pred ? ps_proc->s_left_mb_syntax_ele.u2_is_intra : 1));
+
+    /* top pels */
+    s_ngbr_avbl_MB.u1_mb_b = ((ps_proc->ps_ngbr_avbl->u1_mb_b)
+                                  && (u4_constrained_intra_pred ? ps_top_mb_syn_ele->u2_is_intra : 1));
+
+    /* topleft pels */
+    s_ngbr_avbl_MB.u1_mb_d = ((ps_proc->ps_ngbr_avbl->u1_mb_d)
+                                  && (u4_constrained_intra_pred ? ps_proc->s_top_left_mb_syntax_ele.u2_is_intra : 1));
+
+    /* top right */
+    s_ngbr_avbl_MB.u1_mb_c = ((ps_proc->ps_ngbr_avbl->u1_mb_c)
+                                  && (u4_constrained_intra_pred ? ps_top_right_mb_syn_ele->u2_is_intra : 1));
+
+
     for(b8 = 0; b8 < 4; b8++)
     {
         u4_pix_x = (b8 & 0x01) << 3;
@@ -586,10 +606,10 @@
         /* TODO : update the neighbor availability information basing on constrained intra pred information */
         /* TODO : i4_ngbr_avbl is only being used in DC mode. Can the DC mode be split in to distinct routines */
         /* basing on neighbors available and hence evade the computation of neighbor availability totally. */
-        s_ngbr_avbl.u1_mb_a = ih264e_derive_ngbr_avbl_of_mb_partitions(ps_proc->ps_ngbr_avbl, u4_pix_x - 1, u4_pix_y); /* xD = -1, yD = 0 */
-        s_ngbr_avbl.u1_mb_b = ih264e_derive_ngbr_avbl_of_mb_partitions(ps_proc->ps_ngbr_avbl, u4_pix_x, u4_pix_y - 1); /* xD = 0, yD = -1 */
-        s_ngbr_avbl.u1_mb_c = ih264e_derive_ngbr_avbl_of_mb_partitions(ps_proc->ps_ngbr_avbl, u4_pix_x + 8, u4_pix_y - 1); /* xD = BLK_8x8_SIZE, yD = -1 */
-        s_ngbr_avbl.u1_mb_d = ih264e_derive_ngbr_avbl_of_mb_partitions(ps_proc->ps_ngbr_avbl, u4_pix_x - 1, u4_pix_y - 1); /* xD = -1, yD = -1 */
+        s_ngbr_avbl.u1_mb_a = ih264e_derive_ngbr_avbl_of_mb_partitions(&s_ngbr_avbl_MB, u4_pix_x - 1, u4_pix_y); /* xD = -1, yD = 0 */
+        s_ngbr_avbl.u1_mb_b = ih264e_derive_ngbr_avbl_of_mb_partitions(&s_ngbr_avbl_MB, u4_pix_x, u4_pix_y - 1); /* xD = 0, yD = -1 */
+        s_ngbr_avbl.u1_mb_c = ih264e_derive_ngbr_avbl_of_mb_partitions(&s_ngbr_avbl_MB, u4_pix_x + 8, u4_pix_y - 1); /* xD = BLK_8x8_SIZE, yD = -1 */
+        s_ngbr_avbl.u1_mb_d = ih264e_derive_ngbr_avbl_of_mb_partitions(&s_ngbr_avbl_MB, u4_pix_x - 1, u4_pix_y - 1); /* xD = -1, yD = -1 */
 
         /* i4_ngbr_avbl = blk_a * LEFT_MB_AVAILABLE_MASK + blk_b * TOP_MB_AVAILABLE_MASK + blk_c * TOP_RIGHT_MB_AVAILABLE_MASK + blk_d * TOP_LEFT_MB_AVAILABLE_MASK */
         i4_ngbr_avbl = (s_ngbr_avbl.u1_mb_a) + (s_ngbr_avbl.u1_mb_d << 1) + (s_ngbr_avbl.u1_mb_b << 2) +  (s_ngbr_avbl.u1_mb_c << 3) +
@@ -799,12 +819,35 @@
     /* ngbr sub mb modes */
     UWORD8 *pu1_top_mb_intra_modes = ps_proc->pu1_top_mb_intra_modes + (ps_proc->i4_mb_x << 4);
     mb_info_t *ps_top_mb_syn_ele = ps_proc->ps_top_row_mb_syntax_ele + ps_proc->i4_mb_x;
+    mb_info_t *ps_top_right_mb_syn_ele = ps_proc->ps_top_row_mb_syntax_ele + ps_proc->i4_mb_x;
 
     /* valid intra modes map */
     UWORD32 u4_valid_intra_modes;
     UWORD16 u2_valid_modes[8] = {4, 262, 4, 262, 141, 399, 141, 511};
 
-    i4_ngbr_avbl = (ps_proc->ps_ngbr_avbl->u1_mb_a) + (ps_proc->ps_ngbr_avbl->u1_mb_d << 1) + (ps_proc->ps_ngbr_avbl->u1_mb_b << 2) + (ps_proc->ps_ngbr_avbl->u1_mb_c << 3);
+    UWORD32 u4_constrained_intra_pred = ps_proc->ps_codec->s_cfg.u4_constrained_intra_pred;
+    UWORD8 u1_mb_a, u1_mb_b, u1_mb_c, u1_mb_d;
+    if (ps_proc->ps_ngbr_avbl->u1_mb_c)
+    {
+        ps_top_right_mb_syn_ele = ps_proc->ps_top_row_mb_syntax_ele + ps_proc->i4_mb_x + 1;
+    }
+    /* left pels */
+    u1_mb_a = ((ps_proc->ps_ngbr_avbl->u1_mb_a)
+                    && (u4_constrained_intra_pred ? ps_proc->s_left_mb_syntax_ele.u2_is_intra : 1));
+
+    /* top pels */
+    u1_mb_b = ((ps_proc->ps_ngbr_avbl->u1_mb_b)
+                    && (u4_constrained_intra_pred ? ps_top_mb_syn_ele->u2_is_intra : 1));
+
+    /* topleft pels */
+    u1_mb_d = ((ps_proc->ps_ngbr_avbl->u1_mb_d)
+                    && (u4_constrained_intra_pred ? ps_proc->s_top_left_mb_syntax_ele.u2_is_intra : 1));
+
+    /* top right */
+    u1_mb_c = ((ps_proc->ps_ngbr_avbl->u1_mb_c)
+                    && (u4_constrained_intra_pred ? ps_top_right_mb_syn_ele->u2_is_intra : 1));
+
+    i4_ngbr_avbl = (u1_mb_a) + (u1_mb_d << 1) + (u1_mb_b << 2) + (u1_mb_c << 3);
     memcpy(ps_proc->au1_ngbr_avbl_4x4_subblks, gau1_ih264_4x4_ngbr_avbl[i4_ngbr_avbl], 16);
 
     for (b8 = 0; b8 < 4; b8++)
@@ -1057,6 +1100,7 @@
     /* ngbr sub mb modes */
     UWORD8 *pu1_top_mb_intra_modes = ps_proc->pu1_top_mb_intra_modes + (ps_proc->i4_mb_x << 4);
     mb_info_t *ps_top_mb_syn_ele = ps_proc->ps_top_row_mb_syntax_ele + ps_proc->i4_mb_x;
+    mb_info_t *ps_top_right_mb_syn_ele = ps_proc->ps_top_row_mb_syntax_ele + ps_proc->i4_mb_x;
 
     /* valid intra modes map */
     UWORD32 u4_valid_intra_modes;
@@ -1064,9 +1108,32 @@
 
     /* Dummy variable for 4x4 trans function */
     WORD16 i2_dc_dummy;
+    UWORD8 u1_mb_a, u1_mb_b, u1_mb_c, u1_mb_d;
+    UWORD32 u4_constrained_intra_pred = ps_proc->ps_codec->s_cfg.u4_constrained_intra_pred;
 
     /* compute ngbr availability for sub blks */
-    i4_ngbr_avbl = (ps_proc->ps_ngbr_avbl->u1_mb_a) + (ps_proc->ps_ngbr_avbl->u1_mb_d << 1) + (ps_proc->ps_ngbr_avbl->u1_mb_b << 2) + (ps_proc->ps_ngbr_avbl->u1_mb_c << 3);
+    if (ps_proc->ps_ngbr_avbl->u1_mb_c)
+    {
+        ps_top_right_mb_syn_ele = ps_proc->ps_top_row_mb_syntax_ele + (ps_proc->i4_mb_x + 1);
+    }
+
+    /* left pels */
+    u1_mb_a = ((ps_proc->ps_ngbr_avbl->u1_mb_a)
+                    && (u4_constrained_intra_pred ? ps_proc->s_left_mb_syntax_ele.u2_is_intra : 1));
+
+       /* top pels */
+    u1_mb_b = ((ps_proc->ps_ngbr_avbl->u1_mb_b)
+                    && (u4_constrained_intra_pred ? ps_top_mb_syn_ele->u2_is_intra : 1));
+
+       /* topleft pels */
+    u1_mb_d = ((ps_proc->ps_ngbr_avbl->u1_mb_d)
+                    && (u4_constrained_intra_pred ? ps_proc->s_top_left_mb_syntax_ele.u2_is_intra : 1));
+
+       /* top right pels */
+    u1_mb_c = ((ps_proc->ps_ngbr_avbl->u1_mb_c)
+                    && (u4_constrained_intra_pred ? ps_top_right_mb_syn_ele->u2_is_intra : 1));
+
+    i4_ngbr_avbl = (u1_mb_a) + (u1_mb_d << 1) + (u1_mb_b << 2) + (u1_mb_c << 3);
     memcpy(ps_proc->au1_ngbr_avbl_4x4_subblks, gau1_ih264_4x4_ngbr_avbl[i4_ngbr_avbl], 16);
 
     for(b8 = 0; b8 < 4; b8++)
@@ -1328,26 +1395,24 @@
     UWORD8 *pu1_mb_d = pu1_mb_b - 2;
 
     /* neighbor availability */
-    const UWORD8  u1_valid_intra_modes[8] = {1, 3, 9, 11, 5, 7, 13, 15,};
+    const UWORD8  u1_valid_intra_modes[8] = {1, 3, 1, 3, 5, 7, 5, 15};
     WORD32 i4_ngbr_avbl;
 
     /* valid intra modes map */
     UWORD32 u4_valid_intra_modes;
+    mb_info_t *ps_top_mb_syn_ele = ps_proc->ps_top_row_mb_syntax_ele + ps_proc->i4_mb_x;
 
     /* temp var */
     UWORD8 i;
-
+    UWORD32 u4_constrained_intra_pred = ps_proc->ps_codec->s_cfg.u4_constrained_intra_pred;
+    UWORD8 u1_mb_a, u1_mb_b, u1_mb_d;
     /* locating neighbors that are available for prediction */
-    /* TODO : update the neighbor availability information basing on constrained intra pred information */
-    /* TODO : i4_ngbr_avbl is only being used in DC mode. Can the DC mode be split in to distinct routines
-     * basing on neighbors available and hence evade the computation of neighbor availability totally. */
-    /* i4_ngbr_avbl = blk_a * LEFT_MB_AVAILABLE_MASK + blk_b * TOP_MB_AVAILABLE_MASK + blk_d * TOP_LEFT_MB_AVAILABLE_MASK */
-    i4_ngbr_avbl = (ps_proc->ps_ngbr_avbl->u1_mb_a) + (ps_proc->ps_ngbr_avbl->u1_mb_b << 2) + (ps_proc->ps_ngbr_avbl->u1_mb_d << 1);
-    ps_proc->i4_chroma_neighbor_avail_8x8_mb = i4_ngbr_avbl;
 
     /* gather prediction pels from the neighbors */
     /* left pels */
-    if (ps_proc->ps_ngbr_avbl->u1_mb_a)
+    u1_mb_a = ((ps_proc->ps_ngbr_avbl->u1_mb_a)
+                    && (u4_constrained_intra_pred ?  ps_proc->s_left_mb_syntax_ele.u2_is_intra : 1));
+    if (u1_mb_a)
     {
         for (i = 0; i < 16; i += 2)
         {
@@ -1361,7 +1426,9 @@
     }
 
     /* top pels */
-    if (ps_proc->ps_ngbr_avbl->u1_mb_b)
+    u1_mb_b = ((ps_proc->ps_ngbr_avbl->u1_mb_b)
+                    && (u4_constrained_intra_pred ? ps_top_mb_syn_ele->u2_is_intra : 1));
+    if (u1_mb_b)
     {
         ps_codec->pf_mem_cpy_mul8(&pu1_ngbr_pels_c_i8x8[18], pu1_mb_b, 16);
     }
@@ -1371,11 +1438,15 @@
     }
 
     /* top left pels */
-    if (ps_proc->ps_ngbr_avbl->u1_mb_d)
+    u1_mb_d = ((ps_proc->ps_ngbr_avbl->u1_mb_d)
+                    && (u4_constrained_intra_pred ? ps_proc->s_top_left_mb_syntax_ele.u2_is_intra : 1));
+    if (u1_mb_d)
     {
         pu1_ngbr_pels_c_i8x8[16] = *pu1_mb_d;
         pu1_ngbr_pels_c_i8x8[17] = *(pu1_mb_d + 1);
     }
+    i4_ngbr_avbl = (u1_mb_a) + (u1_mb_b << 2) + (u1_mb_d << 1);
+    ps_proc->i4_chroma_neighbor_avail_8x8_mb = i4_ngbr_avbl;
 
     u4_valid_intra_modes = u1_valid_intra_modes[i4_ngbr_avbl];
 
diff --git a/encoder/ih264e_process.c b/encoder/ih264e_process.c
index c21931d..fce7e35 100644
--- a/encoder/ih264e_process.c
+++ b/encoder/ih264e_process.c
@@ -2008,7 +2008,6 @@
 
             /* force intra refresh ? */
             WORD32 i4_air_enable_inter = (ps_codec->s_cfg.e_air_mode == IVE_AIR_MODE_NONE) ||
-                            (ps_proc->pu1_is_intra_coded[i4_mb_id] != 0) ||
                             (ps_codec->pu2_intr_rfrsh_map[i4_mb_id] != ps_codec->i4_air_pic_cnt);
 
             /* evaluate inter 16x16 modes */
diff --git a/encoder/ive2.h b/encoder/ive2.h
index cbf7087..411f376 100644
--- a/encoder/ive2.h
+++ b/encoder/ive2.h
@@ -1251,6 +1251,9 @@
      * from which this command takes effect                             */
     UWORD32                                     u4_timestamp_high;
 
+    /** Constrained intra pred flag                                     */
+    UWORD32                                     u4_constrained_intra_pred;
+
 }ive_ctl_set_ipe_params_ip_t;
 
 /** Output structure : Set IPE Params                                   */
diff --git a/test/encoder/app.h b/test/encoder/app.h
index ad45f5a..223ad5c 100644
--- a/test/encoder/app.h
+++ b/test/encoder/app.h
@@ -122,6 +122,7 @@
 #define DEFAULT_SRCH_RNG_Y          48
 #define DEFAULT_I_INTERVAL          30
 #define DEFAULT_IDR_INTERVAL        1000
+#define DEFAULT_CONSTRAINED_INTRAPRED  0
 #define DEFAULT_B_FRAMES            0
 #define DEFAULT_DISABLE_DEBLK_LEVEL 0
 #define DEFAULT_HPEL                1
@@ -285,6 +286,7 @@
     UWORD32 u4_srch_rng_y;
     UWORD32 u4_i_interval;
     UWORD32 u4_idr_interval;
+    UWORD32 u4_constrained_intra_pred;
     UWORD32 u4_b_frames;
     UWORD32 u4_num_bframes;
     UWORD32 u4_disable_deblk_level;
diff --git a/test/encoder/main.c b/test/encoder/main.c
index 3510e2b..0c7d4f0 100644
--- a/test/encoder/main.c
+++ b/test/encoder/main.c
@@ -106,6 +106,7 @@
     SRCH_RNG_Y,
     I_INTERVAL,
     IDR_INTERVAL,
+    CONSTRAINED_INTRA_PRED,
     B_FRMS,
     NUM_B_FRMS,
     DISABLE_DBLK,
@@ -156,6 +157,7 @@
                 { "--", "--src_framerate", SRC_FRAMERATE, "Source frame rate \n" },
                 { "--", "--i_interval", I_INTERVAL,  "Intra frame interval \n" },
                 { "--", "--idr_interval", IDR_INTERVAL,  "IDR frame interval \n" },
+                { "--", "--constrained_intrapred", CONSTRAINED_INTRA_PRED,  "Constrained IntraPrediction Flag \n" },
                 { "--", "--bframes", NUM_B_FRMS, "Maximum number of consecutive B frames \n" },
                 { "--", "--speed", ENC_SPEED, "Encoder speed preset 0 (slowest) and 100 (fastest)\n" },
                 { "--", "--me_speed", ME_SPEED, "Encoder speed preset 0 (slowest) and 100 (fastest)\n" },
@@ -750,6 +752,10 @@
         sscanf(value, "%d", &ps_app_ctxt->u4_idr_interval);
         break;
 
+      case CONSTRAINED_INTRA_PRED:
+        sscanf(value, "%d", &ps_app_ctxt->u4_constrained_intra_pred);
+        break;
+
       case NUM_B_FRMS:
         sscanf(value, "%d", &ps_app_ctxt->u4_num_bframes);
         break;
@@ -976,6 +982,7 @@
     ps_app_ctxt->u4_srch_rng_y           = DEFAULT_SRCH_RNG_Y;
     ps_app_ctxt->u4_i_interval           = DEFAULT_I_INTERVAL;
     ps_app_ctxt->u4_idr_interval         = DEFAULT_IDR_INTERVAL;
+    ps_app_ctxt->u4_constrained_intra_pred  = DEFAULT_CONSTRAINED_INTRAPRED;
     ps_app_ctxt->u4_disable_deblk_level  = DEFAULT_DISABLE_DEBLK_LEVEL;
     ps_app_ctxt->u4_hpel                 = DEFAULT_HPEL;
     ps_app_ctxt->u4_qpel                 = DEFAULT_QPEL;
@@ -1088,6 +1095,9 @@
     s_ipe_params_ip.s_ive_ip.u4_size    =   sizeof(ih264e_ctl_set_ipe_params_ip_t);
     s_ipe_params_op.s_ive_op.u4_size    =   sizeof(ih264e_ctl_set_ipe_params_op_t);
 
+    s_ipe_params_ip.s_ive_ip.u4_constrained_intra_pred =
+                                            ps_app_ctxt->u4_constrained_intra_pred;
+
     status = ih264e_api_function(ps_app_ctxt->ps_enc,&s_ipe_params_ip,&s_ipe_params_op);
     if(status != IV_SUCCESS)
     {