00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <math.h>
00015
00016 #include "global.h"
00017 #include "image.h"
00018 #include "rc_quadratic.h"
00019 #include "wp.h"
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 void rd_picture_coding(ImageParameters *p_Img, InputParameters *p_Inp)
00030 {
00031 int second_qp = p_Img->qp, rd_qp = p_Img->qp;
00032 int previntras = p_Img->intras;
00033 int prevtype = p_Img->type;
00034 int skip_encode = 0;
00035 pic_parameter_set_rbsp_t *sec_pps;
00036 int tmpFrameQP = p_Img->SumFrameQP;
00037 int num_ref_idx_l0 = p_Img->num_ref_idx_l0_active;
00038 int num_ref_idx_l1 = p_Img->num_ref_idx_l1_active;
00039 float rateRatio = 1.0F;
00040
00041 if ( p_Inp->RCEnable )
00042 rc_save_state(p_Img, p_Inp);
00043
00044 if ( p_Inp->WPMCPrecision )
00045 p_Img->pWPX->curr_wp_rd_pass = p_Img->pWPX->wp_rd_passes + 1;
00046
00047 if (p_Img->type!=I_SLICE && p_Inp->GenerateMultiplePPS)
00048 {
00049 if ( p_Inp->WPMCPrecision )
00050 {
00051 p_Img->pWPX->curr_wp_rd_pass->algorithm = WP_REGULAR;
00052 if (p_Img->type==P_SLICE)
00053 {
00054 p_Img->active_pps = p_Img->PicParSet[1];
00055 }
00056 else
00057 {
00058 p_Img->active_pps = p_Img->PicParSet[2];
00059 }
00060 }
00061 else
00062 {
00063 if (p_Img->type==P_SLICE)
00064 {
00065 if ((p_Inp->RDPSliceWeightOnly != 2) && (p_Img->TestWPPSlice(p_Img, p_Inp, 0) == 1))
00066 {
00067 p_Img->active_pps = p_Img->PicParSet[1];
00068 }
00069 else
00070 {
00071 skip_encode = p_Inp->RDPSliceWeightOnly;
00072 p_Img->active_pps = p_Img->PicParSet[0];
00073
00074 if (!p_Img->AdaptiveRounding)
00075 {
00076 p_Img->qp-=1;
00077 if ( p_Inp->RCEnable )
00078 rateRatio = 1.15F;
00079 }
00080 }
00081 }
00082 else
00083 {
00084 p_Img->active_pps = p_Img->PicParSet[2];
00085 }
00086 }
00087 }
00088 else
00089 {
00090 if (!p_Img->AdaptiveRounding)
00091 {
00092 p_Img->qp-=1;
00093 if ( p_Inp->RCEnable )
00094 rateRatio = 1.15F;
00095 }
00096 }
00097
00098 sec_pps = p_Img->active_pps;
00099 second_qp = p_Img->qp;
00100
00101 p_Img->write_macroblock = FALSE;
00102
00103 if (skip_encode)
00104 {
00105 p_Img->rd_pass = 0;
00106 p_Img->enc_frame_picture[1] = NULL;
00107 }
00108 else
00109 {
00110 if(p_Inp->RCEnable)
00111 rc_init_frame_rdpic( p_Img, p_Inp, rateRatio );
00112
00113 p_Img->qp = iClip3( p_Img->RCMinQP, p_Img->RCMaxQP, p_Img->qp );
00114 frame_picture (p_Img, p_Inp, p_Img->frame_pic[1], &p_Img->imgData, 1);
00115 p_Img->rd_pass = picture_coding_decision(p_Img, p_Inp, p_Img->frame_pic[0], p_Img->frame_pic[1], rd_qp);
00116 }
00117
00118 if (p_Img->rd_pass==0)
00119 {
00120 p_Img->enc_picture=p_Img->enc_frame_picture[0];
00121 if (p_Img->type!=I_SLICE && p_Inp->GenerateMultiplePPS)
00122 {
00123 p_Img->qp = rd_qp;
00124 p_Img->active_pps = p_Img->PicParSet[0];
00125 }
00126 else
00127 {
00128 p_Img->qp = rd_qp;
00129 }
00130 p_Img->intras = previntras;
00131 p_Img->p_frame_pic = p_Img->frame_pic[0];
00132 }
00133 else
00134 {
00135 previntras = p_Img->intras;
00136 p_Img->p_frame_pic = p_Img->frame_pic[1];
00137 tmpFrameQP = p_Img->SumFrameQP;
00138 num_ref_idx_l0 = p_Img->num_ref_idx_l0_active;
00139 num_ref_idx_l1 = p_Img->num_ref_idx_l1_active;
00140
00141
00142 if(p_Inp->RCEnable)
00143 rc_save_state(p_Img, p_Inp);
00144 }
00145
00146
00147 if ( p_Inp->RCEnable )
00148 rateRatio = 1.0F;
00149
00150 if ( p_Inp->WPMCPrecision )
00151 p_Img->pWPX->curr_wp_rd_pass = p_Img->pWPX->wp_rd_passes + 2;
00152
00153 if (p_Img->type != I_SLICE )
00154 {
00155 skip_encode = 0;
00156 p_Img->qp = rd_qp;
00157
00158 if (p_Img->type == P_SLICE && (p_Img->intras * 100 )/p_Img->FrameSizeInMbs >=75)
00159 {
00160 set_slice_type(p_Img, p_Inp, I_SLICE );
00161 p_Img->active_pps = p_Img->PicParSet[0];
00162 }
00163 else if (p_Img->type==P_SLICE)
00164 {
00165 if (p_Inp->GenerateMultiplePPS)
00166 {
00167 if ((p_Inp->RDPSliceWeightOnly != 2) && (p_Img->TestWPPSlice(p_Img, p_Inp, 1) == 1))
00168 {
00169 p_Img->active_pps = p_Img->PicParSet[1];
00170 if ( p_Inp->WPMCPrecision )
00171 p_Img->pWPX->curr_wp_rd_pass->algorithm = WP_REGULAR;
00172 }
00173 else if ( p_Inp->WPMCPrecision == 2 )
00174 p_Img->active_pps = p_Img->PicParSet[1];
00175 else if (p_Inp->RDPSliceBTest && p_Img->active_sps->profile_idc != BASELINE)
00176 {
00177 set_slice_type(p_Img, p_Inp, B_SLICE );
00178 p_Img->active_pps = p_Img->PicParSet[0];
00179 }
00180 else
00181 {
00182 skip_encode = p_Inp->RDPSliceWeightOnly;
00183 p_Img->active_pps = p_Img->PicParSet[0];
00184 if (!p_Img->AdaptiveRounding)
00185 {
00186 p_Img->qp+=1;
00187 if ( p_Inp->RCEnable )
00188 rateRatio = 0.85F;
00189 }
00190 }
00191 }
00192 }
00193 else
00194 {
00195 if (p_Inp->GenerateMultiplePPS && (p_Inp->RDBSliceWeightOnly != 2) && p_Img->TestWPBSlice(p_Img, p_Inp, 0) == 1)
00196 {
00197 p_Img->active_pps = p_Img->PicParSet[1];
00198 if ( p_Inp->WPMCPrecision )
00199 p_Img->pWPX->curr_wp_rd_pass->algorithm = WP_REGULAR;
00200 }
00201 else if ( p_Inp->WPMCPrecision == 2 && (p_Inp->WPMCPrecBSlice == 2 || (p_Inp->WPMCPrecBSlice == 1 && p_Img->nal_reference_idc) ) )
00202 p_Img->active_pps = p_Img->PicParSet[1];
00203 else
00204 {
00205 skip_encode = (p_Inp->RDBSliceWeightOnly == 1);
00206 p_Img->qp = rd_qp + (p_Img->nal_reference_idc ? - 1 : 1);
00207 if ( p_Inp->RCEnable )
00208 rateRatio = p_Img->nal_reference_idc ? 1.15F : 0.85F;
00209 if ( p_Inp->WPMCPrecision )
00210 p_Img->pWPX->curr_wp_rd_pass->algorithm = WP_REGULAR;
00211 }
00212 }
00213 }
00214 else
00215 {
00216 p_Img->active_pps = p_Img->PicParSet[0];
00217 if (!p_Img->AdaptiveRounding)
00218 p_Img->qp = (rd_qp + 1);
00219 }
00220
00221 p_Img->write_macroblock = FALSE;
00222
00223 if (skip_encode)
00224 {
00225 p_Img->enc_frame_picture[2] = NULL;
00226 p_Img->qp = rd_qp;
00227 }
00228 else
00229 {
00230 if(p_Inp->RCEnable)
00231 rc_init_frame_rdpic( p_Img, p_Inp, rateRatio );
00232
00233 p_Img->qp = iClip3( p_Img->RCMinQP, p_Img->RCMaxQP, p_Img->qp );
00234 frame_picture (p_Img, p_Inp, p_Img->frame_pic[2], &p_Img->imgData, 2);
00235
00236 if (p_Img->rd_pass==0)
00237 p_Img->rd_pass = 2 * picture_coding_decision(p_Img, p_Inp, p_Img->frame_pic[0], p_Img->frame_pic[2], rd_qp);
00238 else
00239 p_Img->rd_pass += picture_coding_decision(p_Img, p_Inp, p_Img->frame_pic[1], p_Img->frame_pic[2], rd_qp);
00240
00241 if ( p_Inp->RCEnable && p_Img->rd_pass == 2 )
00242 rc_save_state(p_Img, p_Inp);
00243
00244 if ( p_Img->rd_pass == 2 )
00245 {
00246 tmpFrameQP = p_Img->SumFrameQP;
00247 num_ref_idx_l0 = p_Img->num_ref_idx_l0_active;
00248 num_ref_idx_l1 = p_Img->num_ref_idx_l1_active;
00249 }
00250 }
00251
00252 if (p_Img->rd_pass==0)
00253 {
00254 p_Img->enc_picture = p_Img->enc_frame_picture[0];
00255 set_slice_type( p_Img, p_Inp, prevtype );
00256 p_Img->active_pps = p_Img->PicParSet[0];
00257 p_Img->qp = rd_qp;
00258 p_Img->intras = previntras;
00259 }
00260 else if (p_Img->rd_pass==1)
00261 {
00262 p_Img->enc_picture = p_Img->enc_frame_picture[1];
00263 set_slice_type( p_Img, p_Inp, prevtype );
00264 p_Img->active_pps = sec_pps;
00265 p_Img->qp = second_qp;
00266 p_Img->intras = previntras;
00267 }
00268
00269 if ( p_Inp->RCEnable )
00270 rc_restore_state(p_Img, p_Inp);
00271
00272 p_Img->SumFrameQP = tmpFrameQP;
00273 p_Img->num_ref_idx_l0_active = num_ref_idx_l0;
00274 p_Img->num_ref_idx_l1_active = num_ref_idx_l1;
00275 }
00276