void RGB24_to_IYUV_reference(unsigned char *Src_RGB, int width, int height, int src_stride, unsigned char *Dst_IYUV, int dst_stride) { int i,j; unsigned char * out_Y = Dst_IYUV ; unsigned char * out_U = out_Y + dst_stride*height ; unsigned char * out_V = out_U + dst_stride/2*height/2 ; for( j = 0; j < height; j++) { for( i = 0; i < width; i++) { int R, G, B; int iX3 = i+i+i; B = Src_RGB[iX3+0]; G = Src_RGB[iX3+1]; R = Src_RGB[iX3+2]; out_Y[i] = CLIP3(0, 255, ( ( 66*R + 129*G + 25*B + 128 ) / 256 ) + 16); if( (i&1) == 0 && (j&1) == 0) { out_U[i>>1] = CLIP3(0, 255, ( (-38*R - 74*G + 112*B + 128) / 256 ) + 128 ); out_V[i>>1] = CLIP3(0, 255, ( (112*R - 94*G - 18*B + 128) / 256 ) + 128 ); } } out_Y += dst_stride; if((j&1)==0) { out_U += (dst_stride>>1); out_V += (dst_stride>>1); }
/** Same as previous but without SliceIgroup table. */ void PPSCut (unsigned char *data, PPS *pps, SPS *sps, int NalBytesInNalunit ) { int Position = 8; unsigned char Pps_id = (unsigned char) read_ue(data, &Position); unsigned char Sps_id = (unsigned char) read_ue(data, &Position); unsigned char pic_parameter_set_id = CLIP3(0, PPS_BUF_SIZE - 1, Pps_id); unsigned char seq_parameter_set_id = CLIP3(0, SPS_BUF_SIZE - 1, Sps_id); PPS *pt_pps = &pps[pic_parameter_set_id]; pt_pps -> seq_parameter_set_id = seq_parameter_set_id; //Initialization of the maximun number of pps if(pic_parameter_set_id > pps[0] . MaxPpsId){ pps[0] . MaxPpsId = pic_parameter_set_id; } PpsFirstHeader(data, &Position, pt_pps); PpsSliceGroupHeaderCut(data, &Position, pt_pps); PpsEndOfHeader(data, &Position, pt_pps); if( more_rbsp_data(data, &Position, &NalBytesInNalunit) ) { // Position < NalBytesInNalunit << 3 SPS *pt_sps = &sps[seq_parameter_set_id]; PpsHighProfile(data, &Position, pt_pps, pt_sps); } rbsp_trailing_bits(&Position); }
void seq_parameter_set( unsigned char *data, SPS *sps){ int position = 8; int profile_idc = getNbits(data, &position, 8); int constraint = getNbits(data, &position, 8); int level_idc = getNbits(data, &position, 8); //level_idc = if (profile_idc && !(constraint & 0xf)){ char Sps_id = read_ue(data, &position); char seq_parameter_set_id = CLIP3(0, SPS_BUF_SIZE, Sps_id); SPS *pt_sps = &sps [seq_parameter_set_id]; //To save parameter before resetting short b_stride = pt_sps -> b_stride; short b8_stride = pt_sps -> b8_stride; //Initialization of the maximun number of sps if(seq_parameter_set_id > sps[0] . MaxSpsId){ sps[0] . MaxSpsId = seq_parameter_set_id; } //Intilaize the SPS to zero memset(pt_sps, 0, sizeof(SPS)); pt_sps -> b_stride = b_stride; pt_sps -> b8_stride = b8_stride; pt_sps -> profile_idc = profile_idc; pt_sps -> level_idc = level_idc; seq_parameter_set_data(data, &position, pt_sps); pt_sps -> slice_header_restriction_flag = -1; rbsp_trailing_bits(&position); } }
static HI_VOID Ge_GetRegCfg(ISP_DEV IspDev, ISP_GE_REG_CFG_S* pstGeReg, HI_U32 iso) { ISP_GREEN_EQUALIZATION_S *pstGe = HI_NULL; GE_GET_CTX(IspDev, pstGe); pstGeReg->detail_th = CLIP3((HI_S32)pstGe->u16SensiThr ,0,(1<<pstGe->bitDepth)); pstGeReg->detail_slop = CLIP3((HI_S32)pstGe->u8SensiSlope,0, pstGe->bitDepth) ; pstGeReg->ge_th = CLIP3((HI_S32)GeGetThreshold(iso, pstGe),0,(1<<pstGe->bitDepth)); pstGeReg->ge_th_slop = CLIP3((HI_S32)pstGe->u8Slope,0, pstGe->bitDepth) ; pstGeReg->u16GeStrength = GeGetStrength(iso, pstGe); pstGeReg->ct_th1 = GeGetNpOffset(iso, pstGe); pstGeReg->ge_enable = pstGe->bEnable; return; }
static HI_VOID FrameWDRRegsInitialize(ISP_DEV IspDev) { HI_U32 u32ExpoRatio; ISP_FS_WDR_S *pstFSWDRCtx; FS_WDR_GET_CTX(IspDev, pstFSWDRCtx); hi_isp_wdr_bmdtstrong_write (IspDev, HI_ISP_WDR_MDT_STRONG_DEFAULT ); hi_isp_wdr_fl_bmdtmnu_write (IspDev, HI_ISP_WDR_FL_MDTMNU_DEFAULT ); hi_isp_wdr_zoomblc_write (IspDev, HI_ISP_WDR_ZOOMBLC_DEFAULT ); hi_isp_wdr_bldrlhfidx_write (IspDev, HI_ISP_WDR_BLDRLHFIDX_DEFAULT ); hi_isp_wdr_bldrclridx_write (IspDev, HI_ISP_WDR_BLDRCLRIDX_DEFAULT ); hi_isp_wdr_flrgtth_low_write (IspDev, HI_ISP_WDR_RGTLOWTHFL_DEFAULT ); hi_isp_wdr_flrgtth_high_write (IspDev, HI_ISP_WDR_RGTHIGTHFL_DEFAULT ); hi_isp_wdr_fl_dftwgt_write (IspDev, HI_ISP_WDR_DFTWGTTHFL_DEFAULT ); hi_isp_wdr_bmdthf_write (IspDev, HI_ISP_WDR_BMDTHF_DEFAULT ); hi_isp_wdr_fsnr_judge_write (IspDev, HI_ISP_WDR_FSNR_JUDGE_DEFAULT ); hi_isp_wdr_fsnrth_high_write (IspDev, HI_ISP_WDR_FSNRTH_HIGHT_DEFAULT); hi_isp_wdr_fsnrth_low_write (IspDev, HI_ISP_WDR_FSNRTH_LOW_DEFAULT ); hi_isp_wdr_fsnrgn_high_write (IspDev, HI_ISP_WDR_FSNRGN_HIGH_DEFAULT); hi_isp_wdr_fsnrgn_low_write (IspDev, HI_ISP_WDR_FSNRGN_LOW_DEFAULT ); hi_isp_wdr_bmdtrefnos_write (IspDev, HI_ISP_WDR_BMDTREFNOS_DEFAULT ); hi_isp_wdr_balgprocmdt_write (IspDev, HI_ISP_WDR_FL_MDTPROC_DEFAULT ); hi_isp_wdr_width_write (IspDev, hi_ext_sync_total_width_read () - 1); hi_isp_wdr_height_write (IspDev, hi_ext_sync_total_height_read() - 1); pstFSWDRCtx->u8BitDepth = HI_WDR_BITDEPTH; pstFSWDRCtx->u32PreIso = 0; pstFSWDRCtx->s32PreMDTNoise = 0; u32ExpoRatio = CLIP3((HI_S32)(ISP_BITFIX(10) * 64.0 / HI_ISP_WDR_EXPORATIO_DEFAULT), 0, ISP_BITFIX(10)); hi_isp_wdr_exporatio0_write(IspDev, HI_ISP_WDR_EXPORATIO_DEFAULT); hi_isp_flick_exp_ratios0_write(IspDev, HI_ISP_WDR_EXPORATIO_DEFAULT); hi_isp_wdr_exporatio_r_write(IspDev, u32ExpoRatio); return; }
void CX264Encoder::ConfigParam(void* param) { if(!param) return; //fred user_param mode_normal_alg_param = { 2, /* b_rc_vbv 0x00-cqp 0x01-abr 0x02 vbv */ // 0.3, /*vbv_buffer_percent*/ // 1.5, /*vbv_drop_thr*/ 1, /*max_drop_num*/ 0, /*b_mbrc_strict*/ // 2, /*drop_start_pos*/ 1, /*b_adaptive_qp*/ //! 25 //cqp // }; user_param mode_desktop_alg_param = { 2, /* b_rc_vbv 0x00-cqp 0x01-abr 0x02 vbv */ 4, /*vbv_buffer_percent*/ 1.0, /*vbv_drop_thr*/ 5, /*max_drop_num*/ 0, /*b_mbrc_strict*/ 0, /*drop_start_pos*/ 0, /*b_adaptive_qp*/ 25 //cqp }; user_param mode_normal_abr_alg_param = { 2, /* b_rc_vbv 0x00-cqp 0x01-abr 0x02 vbv */ 0.3, /*vbv_buffer_percent*/ 1.7, /*vbv_drop_thr*/ 1, /*max_drop_num*/ 0, /*b_mbrc_strict*/ 2, /*drop_start_pos*/ 1, /*b_adaptive_qp*/ 25 //cqp }; user_param *pUsrParam; x264_param_t* pParam = (x264_param_t*)param; x264_param_default( (x264_param_t*)pParam ); pParam->i_width = m_stEncParam.iWidth; pParam->i_height = m_stEncParam.iHeight; pParam->rc.i_bitrate = m_stEncParam.iBitrate; pParam->rc.i_rc_method = X264_RC_ABR; pParam->i_fps_den = 1; pParam->i_fps_num = m_stEncParam.iFPS * pParam->i_fps_den; pParam->i_frame_reference = 3; pParam->analyse.b_psnr = 0; pParam->analyse.b_ssim = 0; pParam->b_annexb = 1; pParam->analyse.b_weighted_bipred = 0; pParam->i_threads = 1;//CLIP3(m_stEncParam.iThreads, 1, 16); pParam->rc.i_qp_min = CLIP3(m_stEncParam.iMinQP, 0, 51); pParam->rc.i_qp_max = CLIP3(m_stEncParam.iMaxQP, 20, 51); pParam->pf_log = x264_log_default; pParam->i_log_level = X264_LOG_INFO; pParam->analyse.b_psy = 0; pParam->rc.i_aq_mode = 0; //emMode pParam->intra_period = m_stEncParam.iGOP; pParam->gf_period = m_stEncParam.igfGOP; pParam->sp_period = m_stEncParam.ispGOP; if ( X264ENCPARAM::emMode_Dsktop == m_stEncParam.mode ) { pParam->em_rc_mode = em_mode_dsktop; pUsrParam = &mode_desktop_alg_param; pParam->rc.i_qp_step = 2; } else if(X264ENCPARAM::emMode_Normal_abr == m_stEncParam.mode) { pParam->em_rc_mode = em_mode_normal; pUsrParam = &mode_normal_abr_alg_param; } else { pParam->em_rc_mode = em_mode_normal;//normal as default pUsrParam = &mode_normal_alg_param; } pParam->rc.vbv_drop_thr = pUsrParam->vbv_drop_thr; pParam->rc.max_drop_num = pUsrParam->max_drop_num; pParam->rc.drop_start_pos = pUsrParam->drop_start_pos; // mdou pParam->rc.use_drop_frame = 1; if (pParam->rc.i_qp_max == pParam->rc.i_qp_min || pParam->em_rc_mode == em_mode_dsktop) // mdou cqp { pParam->rc.use_drop_frame = 0; pParam->rc.i_qp_min = 30; pParam->rc.i_qp_max = 45; } #ifdef WIN32 //complexity + -标识相对于normal的变化 switch (m_stEncParam.cp) { case X264ENCPARAM::cp_best: pParam->analyse.i_subpel_refine = 4; //+ pParam->analyse.i_mv_range = -1; pParam->analyse.b_mixed_references = 1; pParam->analyse.i_trellis = 1; pParam->b_cabac = 1; pParam->analyse.b_transform_8x8 = 1; pParam->analyse.i_me_method = X264_ME_HEX; pParam->analyse.inter = X264_ANALYSE_I4x4 | X264_ANALYSE_PSUB16x16 | X264_ANALYSE_BSUB16x16 | X264_ANALYSE_PSUB8x8; //+ pParam->analyse.intra = X264_ANALYSE_I4x4 | X264_ANALYSE_I8x8; pParam->analyse.i_cmplx_level = 2; break; case X264ENCPARAM::cp_fast: pParam->analyse.i_subpel_refine = 1; //- pParam->analyse.i_mv_range = 64;//- pParam->analyse.b_mixed_references = 0; //- pParam->analyse.i_trellis = 0; //- pParam->b_cabac = 1; pParam->analyse.b_transform_8x8 = 0; //- pParam->analyse.i_me_method = X264_ME_DIA; //- pParam->analyse.inter = X264_ANALYSE_I4x4 | X264_ANALYSE_PSUB16x16; pParam->analyse.intra = X264_ANALYSE_I4x4; //- pParam->analyse.i_cmplx_level = 0; break; case X264ENCPARAM::cp_normal: default: pParam->analyse.i_subpel_refine = 3; pParam->analyse.i_mv_range = -1; pParam->analyse.b_mixed_references = 1; pParam->analyse.i_trellis = 1; pParam->b_cabac = 1; pParam->analyse.b_transform_8x8 = 1; pParam->analyse.i_me_method = X264_ME_HEX; pParam->analyse.inter = X264_ANALYSE_I4x4 | X264_ANALYSE_PSUB16x16 | X264_ANALYSE_BSUB16x16; pParam->analyse.intra = X264_ANALYSE_I4x4 | X264_ANALYSE_I8x8; pParam->analyse.i_cmplx_level = 1; break; } #else //complexity + -标识相对于normal的变化 switch (m_stEncParam.cp) { case X264ENCPARAM::cp_best: pParam->analyse.i_subpel_refine = 3; pParam->analyse.b_mixed_references = 1; pParam->b_cabac = 1; pParam->analyse.i_me_method = X264_ME_HEX; pParam->analyse.inter = X264_ANALYSE_I4x4 | X264_ANALYSE_PSUB16x16; pParam->analyse.intra = X264_ANALYSE_I4x4; pParam->analyse.i_cmplx_level = 2; break; case X264ENCPARAM::cp_fast: pParam->analyse.i_subpel_refine = 0; //- pParam->b_cabac = 1; pParam->analyse.i_me_method = X264_ME_DIA; //- pParam->analyse.inter = X264_ANALYSE_I4x4 | X264_ANALYSE_PSUB16x16; pParam->analyse.intra = X264_ANALYSE_I4x4; pParam->analyse.i_cmplx_level = 0; break; case X264ENCPARAM::cp_normal: default: pParam->analyse.i_subpel_refine = 0; //- pParam->b_cabac = 1; pParam->analyse.i_me_method = X264_ME_DIA; //- pParam->analyse.inter = X264_ANALYSE_I4x4 | X264_ANALYSE_PSUB16x16; pParam->analyse.intra = X264_ANALYSE_I4x4; pParam->analyse.i_cmplx_level = 1; break; } #endif //profile, force to conform with H.264 standard switch (m_stEncParam.eProfileLevel) { case X264ENCPARAM::emProfileLevel_High: break; case X264ENCPARAM::emProfileLevel_Main: pParam->analyse.b_transform_8x8 = 0; break; case X264ENCPARAM::emProfileLevel_Base: pParam->analyse.b_transform_8x8 = 0; pParam->b_cabac = 0; break; default: break; } #ifdef WIN32 //桌面模式I帧开I8x8,反正新码控对桌面模式又没啥用 kevin 2013.11.27 if ( X264ENCPARAM::emMode_Dsktop == m_stEncParam.mode ) { pParam->analyse.intra |= X264_ANALYSE_I8x8; } if ( X264ENCPARAM::emMode_Dsktop == m_stEncParam.mode ) { //桌面模式关键在于I帧的质量,I帧开启I8x8可以提升压缩3%,关掉trellis不影响I帧的质量,但是可以提升整体压缩性能50% pParam->analyse.i_trellis = 0; pParam->analyse.intra |= X264_ANALYSE_I8x8; } #endif #if ENCODER_DEBUG_OPT pUsrParam = m_stEncParam.usr_ptr; #endif #if ENCODER_DEBUG_OPT if ( 0 == pUsrParam->b_rc_vbv ) { pParam->rc.i_rc_method = X264_RC_CQP; pParam->rc.i_qp_constant = CLIP3(pUsrParam->cqp_qp, 0, 51);//demo cqp } else #endif { if(0 == pUsrParam->b_adaptive_qp) pParam->rc.i_aq_mode = X264_AQ_NONE; if ( 1 == pUsrParam->b_rc_vbv ) { pParam->rc.i_vbv_max_bitrate = 0; pParam->rc.i_vbv_buffer_size = 0; } else { pParam->rc.i_vbv_max_bitrate = (int)( pParam->rc.i_bitrate * pUsrParam->vbv_buffer_percent ); pParam->rc.i_vbv_buffer_size = (int)( pParam->rc.i_bitrate * pUsrParam->vbv_buffer_percent ); } if(pParam->i_threads > 1) { pParam->rc.i_bitrate = (int)(pParam->rc.i_bitrate * 0.9); } } }
//for init access unit int slice_header_svc_cut(unsigned char *data, SPS *sps, PPS *pps, int *position, SLICE *Slice, NAL *Nal) { PPS *pt_pps_id ; SPS *pt_sps_id ; int PicParameterId; int SeqParameterId; //Read header data Slice -> first_mb_in_slice = read_ue(data, position); Slice -> slice_type = read_ue(data, position); if ( Slice -> slice_type > 4 ) { Slice -> slice_type -= 5 ; } PicParameterId = read_ue(data, position); Nal -> pic_parameter_id[Nal -> LayerId] = PicParameterId = CLIP3(0, PPS_BUF_SIZE - 1, PicParameterId); pt_pps_id = &pps[PicParameterId]; //Should be in slice header //Sometimes Subset SPS are after PPS (rtsp) if(pt_pps_id -> seq_parameter_set_id > sps[0] . MaxSpsId){ pt_pps_id -> seq_parameter_set_id = sps[0] . MaxSpsId; } SeqParameterId = pt_pps_id -> seq_parameter_set_id + (Nal -> LayerId ? 16: 0); pt_sps_id = &sps[SeqParameterId]; Slice -> frame_num = getNbits(data, position, pt_sps_id -> log2_max_frame_num ); //Read Frame parameter if ( !pt_sps_id -> frame_mbs_only_flag ) { Slice -> field_pic_flag = getNbits(data, position, 1); if ( Slice -> field_pic_flag ) { Slice->bottom_field_flag = getNbits(data, position, 1); } } else { Slice->field_pic_flag = 0; } if ( 1 == Nal -> IdrFlag) { Slice->idr_pic_id = read_ue(data, position);//idr_pic_id = } if ( pt_sps_id -> pic_order_cnt_type == 0 ) { Slice -> pic_order_cnt_lsb = getNbits(data, position, pt_sps_id -> log2_max_pic_order_cnt_lsb ); if ( pt_pps_id -> pic_order_present_flag && !Slice -> field_pic_flag ) Slice -> delta_pic_order_cnt_bottom = read_se(data, position); } if ( pt_sps_id -> pic_order_cnt_type == 1 && !pt_sps_id -> delta_pic_order_always_zero_flag ) { Slice -> delta_pic_order_cnt [0] = read_se(data, position); if ( pt_pps_id -> pic_order_present_flag && !Slice -> field_pic_flag ) Slice -> delta_pic_order_cnt [1] = read_se(data, position); } if ( pt_pps_id -> redundant_pic_cnt_present_flag ) { read_ue(data, position);//redundant_pic_cnt = } return 0; }
static HI_VOID hiisp_wdr_func(ISP_DEV IspDev, HI_U32 u32Iso, ISP_FS_WDR_S* pstFsWdr, ISP_WDR_REG_CFG_S* pstWDRReg) { HI_S32 s32MDTNoise, s32MDTClip, s32MDTLowTh, s32MDTHigTh, s32MDTMaxTh; HI_S32 s32CurISO = (HI_S32)u32Iso; ISP_CMOS_BLACK_LEVEL_S *pstSnsBlackLevel = HI_NULL; ISP_CMOS_DEFAULT_S *pstSnsDft = HI_NULL; ISP_SensorGetDefault(IspDev, &pstSnsDft); ISP_SensorGetBlc(IspDev, &pstSnsBlackLevel); pstWDRReg->au16InBLC[0] = (pstSnsBlackLevel->au16BlackLevel[0] << 2); pstWDRReg->au16InBLC[1] = (pstSnsBlackLevel->au16BlackLevel[1] << 2); pstWDRReg->u32OutBLC = (((HI_U32)pstSnsBlackLevel->au16BlackLevel[0]) << 2); if (hi_ext_system_wdr_manual_mode_read()) { pstWDRReg->au16InBLC[0] = hi_ext_system_wdr_blc0_read(); pstWDRReg->au16InBLC[1] = hi_ext_system_wdr_blc1_read(); pstWDRReg->u32OutBLC = hi_ext_system_wdr_out_blc_read(); pstWDRReg->u16NosClipTH = hi_ext_system_manual_wdr_lutmdtclip_read (); pstWDRReg->u8NosFactorLow = hi_ext_system_manual_wdr_lutmdtlowth_read(); pstWDRReg->u8NosFactorHig = hi_ext_system_manual_wdr_lutmdthigth_read(); pstWDRReg->u8BldrMdtMax = hi_ext_system_manual_wdr_mdtmaxth_read(); } else { s32MDTClip = GetValueFromLut(s32CurISO, g_as32WdrIsoLut, &pstFsWdr->as32LutMDTClips[0], ISP_AUTO_ISO_STRENGTH_NUM); // UI control s32MDTLowTh = GetValueFromLut(s32CurISO, g_as32WdrIsoLut, &pstFsWdr->as32LutMDTLowTh[0], ISP_AUTO_ISO_STRENGTH_NUM); // UI control s32MDTHigTh = GetValueFromLut(s32CurISO, g_as32WdrIsoLut, &pstFsWdr->as32LutMDTHigTh[0], ISP_AUTO_ISO_STRENGTH_NUM); // UI control s32MDTMaxTh = GetValueFromLut(s32CurISO, g_as32WdrIsoLut, &pstFsWdr->as32LutMDTMaxTH[0], ISP_AUTO_ISO_STRENGTH_NUM); // UI control pstWDRReg->u16NosClipTH = s32MDTClip; pstWDRReg->u8NosFactorLow = s32MDTLowTh; pstWDRReg->u8NosFactorHig = s32MDTHigTh; pstWDRReg->u8BldrMdtMax = s32MDTMaxTh; } s32MDTNoise = GetValueFromLut(s32CurISO, g_as32WdrIsoLut, &pstFsWdr->as32LutMDTNoise[0], ISP_AUTO_ISO_STRENGTH_NUM); // UI control pstWDRReg->bAlgProcMDT = pstFsWdr->bMotionComp; pstWDRReg->bFlBmdtMnu = pstFsWdr->bMotionComMode; pstWDRReg->bMDRefNoise = pstFsWdr->bMDRefNoise; pstWDRReg->u16LongThr = pstFsWdr->u16LongThr; pstWDRReg->u16ShortThr = pstFsWdr->u16ShortThr; pstWDRReg->u16MDSfNrThr = pstFsWdr->u16MDSfNrThr; pstWDRReg->bUpdateNosLut = HI_FALSE; if(pstWDRReg->bAlgProcMDT) { static HI_DOUBLE k ; k = getKfromNoiseLut(pstSnsDft->stBayerNr.afCalibrationCoef, pstSnsDft->stBayerNr.u16CalibrationLutNum, s32CurISO); HI_S32 n = 0, bitScale = ISP_BITFIX(pstFsWdr->u8BitDepth - 8); HI_FLOAT sigma ; if ((u32Iso != pstFsWdr->u32PreIso)|| (s32MDTNoise != pstFsWdr->s32PreMDTNoise)) { pstFsWdr->u32PreIso = u32Iso; pstFsWdr->s32PreMDTNoise = s32MDTNoise; pstWDRReg->bUpdateNosLut = HI_TRUE; } if (pstWDRReg->bUpdateNosLut) { for(n = 0; n < NLUT_LENGTH; n++) { sigma = (HI_FLOAT)(k * n * 256 / (NLUT_LENGTH - 1)); sigma = sqrtf(sigma); sigma *= bitScale; pstWDRReg->au16NosMDTLut[n] = CLIP3((HI_S32)sigma, 0, ISP_BITMASK(14)); } } } }
void CIYuv::setDataFromImgYUV(IplImage *imgYUV) { int h, w; int iu, iv; unsigned char *bufYUV1, *bufYUV2; switch(sampling) { case 400: for(h=0; h<height; h++) { bufYUV1 = (unsigned char *)&(imgYUV->imageData[h*imgYUV->widthStep]); for(w=0; w<width; w++) { Y[h][w] = *bufYUV1; // Y bufYUV1 += 3; } } break; case 420: for(h=0; h<height; h+=2) { bufYUV1 = (unsigned char *)&(imgYUV->imageData[ h *imgYUV->widthStep]); bufYUV2 = (unsigned char *)&(imgYUV->imageData[(h+1)*imgYUV->widthStep]); for(w=0; w<width; w+=2) { Y[h ][w ] = *bufYUV1++; iu = *bufYUV1++; iv = *bufYUV1++; Y[h+1][w ] = *bufYUV2++; iu += *bufYUV2++; iv += *bufYUV2++; Y[h ][w+1] = *bufYUV1++; iu += *bufYUV1++; iv += *bufYUV1++; Y[h+1][w+1] = *bufYUV2++; iu += *bufYUV2++; iv += *bufYUV2++; U[h/2][w/2] = CLIP3((iu + 2)/4, 0, 255); V[h/2][w/2] = CLIP3((iv + 2)/4, 0, 255); } } break; case 422: for(h=0; h<height; h++) { bufYUV1 = (unsigned char *)&(imgYUV->imageData[h*imgYUV->widthStep]); for(w=0; w<width; w+=2) { Y[h][w ] = *bufYUV1++; iu = *bufYUV1++; iv = *bufYUV1++; Y[h][w+1] = *bufYUV1++; iu += *bufYUV1++; iv += *bufYUV1++; U[h][w/2] = CLIP3((iu + 1)/2, 0, 255); V[h][w/2] = CLIP3((iv + 1)/2, 0, 255); } } break; case 444: for(h=0; h<height; h++) { bufYUV1 = (unsigned char *)&(imgYUV->imageData[h*imgYUV->widthStep]); for(w=0; w<width; w++) { Y[h][w] = *bufYUV1++; U[h][w] = *bufYUV1++; V[h][w] = *bufYUV1++; } } break; } }
bool CIYuv::setData444_inIBGR(CIYuv *yuvSrc) { int h, w, cH, cW; int ir, ig, ib; if(sampling!=444 || Y==NULL || height!=yuvSrc->getHeight() || width!=yuvSrc->getWidth()) return false; switch(yuvSrc->getSampling()) { case 400: memcpy(comp[0][0], yuvSrc->Y[0], picsizeY); memcpy(comp[1][0], yuvSrc->Y[0], picsizeY); memcpy(comp[2][0], yuvSrc->Y[0], picsizeY); case 420: for(h=cH=0; h<height; h++) { cH = h>>1; for(w=cW=0; w<width; w++, cW++) { ib = (int) (yuvSrc->Y[h][w] + 1.772*(yuvSrc->U[cH][cW]-127) + 0.5); ig = (int) (yuvSrc->Y[h][w] - 0.344*(yuvSrc->U[cH][cW]-127) - 0.714*(yuvSrc->V[cH][cW]-127) + 0.5); ir = (int) (yuvSrc->Y[h][w] + 1.402*(yuvSrc->V[cH][cW]-127) + 0.5); comp[0][h][w] = CLIP3(ib, 0, 255); comp[1][h][w] = CLIP3(ig, 0, 255); comp[2][h][w] = CLIP3(ir, 0, 255); w++; ib = (int) (yuvSrc->Y[h][w] + 1.772*(yuvSrc->U[cH][cW]-127) + 0.5); ig = (int) (yuvSrc->Y[h][w] - 0.344*(yuvSrc->U[cH][cW]-127) - 0.714*(yuvSrc->V[cH][cW]-127) + 0.5); ir = (int) (yuvSrc->Y[h][w] + 1.402*(yuvSrc->V[cH][cW]-127) + 0.5); comp[0][h][w] = CLIP3(ib, 0, 255); comp[1][h][w] = CLIP3(ig, 0, 255); comp[2][h][w] = CLIP3(ir, 0, 255); } } break; case 422: for(h=0; h<height; h++) { for(w=cW=0; w<width; w++, cW++) { ib = (int) (yuvSrc->Y[h][w] + 1.772*(yuvSrc->U[h][cW]-127) + 0.5); ig = (int) (yuvSrc->Y[h][w] - 0.344*(yuvSrc->U[h][cW]-127) - 0.714*(yuvSrc->V[h][cW]-127) + 0.5); ir = (int) (yuvSrc->Y[h][w] + 1.402*(yuvSrc->V[h][cW]-127) + 0.5); comp[0][h][w] = CLIP3(ib, 0, 255); comp[1][h][w] = CLIP3(ig, 0, 255); comp[2][h][w] = CLIP3(ir, 0, 255); w++; ib = (int) (yuvSrc->Y[h][w] + 1.772*(yuvSrc->U[h][cW]-127) + 0.5); ig = (int) (yuvSrc->Y[h][w] - 0.344*(yuvSrc->U[h][cW]-127) - 0.714*(yuvSrc->V[h][cW]-127) + 0.5); ir = (int) (yuvSrc->Y[h][w] + 1.402*(yuvSrc->V[h][cW]-127) + 0.5); comp[0][h][w] = CLIP3(ib, 0, 255); comp[1][h][w] = CLIP3(ig, 0, 255); comp[2][h][w] = CLIP3(ir, 0, 255); } } break; case 444: for(h=0; h<height; h++) { for(w=0; w<width; w++) { ib = (int) (yuvSrc->Y[h][w] + 1.772*(yuvSrc->U[h][w]-127) + 0.5); ig = (int) (yuvSrc->Y[h][w] - 0.344*(yuvSrc->U[h][w]-127) - 0.714*(yuvSrc->V[h][w]-127) + 0.5); ir = (int) (yuvSrc->Y[h][w] + 1.402*(yuvSrc->V[h][w]-127) + 0.5); comp[0][h][w] = CLIP3(ib, 0, 255); comp[1][h][w] = CLIP3(ig, 0, 255); comp[2][h][w] = CLIP3(ir, 0, 255); } } break; default: memset(comp[0][0], 0, size_in_byte); break; } return true; }
void CIYuv::setDataFromImgBGR(IplImage *imgBGR) { int h, w; int fr, fg, fb; int iy, iu, iv; unsigned char *bufBGR; switch(sampling) { case 400: for(h=0; h<height; h++) { bufBGR = (unsigned char *)&(imgBGR->imageData[h*imgBGR->widthStep]); for(w=0; w<width; w++) { fb = *bufBGR++; //B fg = *bufBGR++; //G fr = *bufBGR++; //R iy = (int)(0.299 * fr + 0.587 * fg + 0.114 * fb + 0.5); Y[h][w] = CLIP3(iy, 0, 255); } } break; case 420: for(h=0; h<height; h++) { bufBGR = (unsigned char *)&(imgBGR->imageData[h*imgBGR->widthStep]); for(w=0; w<width; w++) { fb = *bufBGR++; //B fg = *bufBGR++; //G fr = *bufBGR++; //R iy = (int)(0.299 * fr + 0.587 * fg + 0.114 * fb + 0.5); Y[h][w] = CLIP3(iy, 0, 255); if(h%2==0 && w%2==0) { iu = (int)(-0.169 * fr - 0.331 * fg + 0.500 * fb + 127.5); iv = (int)( 0.500 * fr - 0.419 * fg - 0.081 * fb + 127.5); U[h/2][w/2] = CLIP3(iu, 0, 255); V[h/2][w/2] = CLIP3(iv, 0, 255); } } } break; case 422: for(h=0; h<height; h++) { bufBGR = (unsigned char *)&(imgBGR->imageData[h*imgBGR->widthStep]); for(w=0; w<width; w++) { fb = *bufBGR++; //B fg = *bufBGR++; //G fr = *bufBGR++; //R iy = (int)(0.299 * fr + 0.587 * fg + 0.114 * fb + 0.5); Y[h][w] = CLIP3(iy, 0, 255); if(w%2==0) { iu = (int)(-0.169 * fr - 0.331 * fg + 0.500 * fb + 127.5); iv = (int)( 0.500 * fr - 0.419 * fg - 0.081 * fb + 127.5); U[h][w/2] = CLIP3(iu, 0, 255); V[h][w/2] = CLIP3(iv, 0, 255); } } } break; case 444: for(h=0; h<height; h++) { bufBGR = (unsigned char *)&(imgBGR->imageData[h*imgBGR->widthStep]); for(w=0; w<width; w++) { fb = *bufBGR++; //B fg = *bufBGR++; //G fr = *bufBGR++; //R iy = (int)(0.299 * fr + 0.587 * fg + 0.114 * fb + 0.5); iu = (int)(-0.169 * fr - 0.331 * fg + 0.500 * fb + 127.5); iv = (int)( 0.500 * fr - 0.419 * fg - 0.081 * fb + 127.5); Y[h][w] = CLIP3(iy, 0, 255); U[h][w] = CLIP3(iu, 0, 255); V[h][w] = CLIP3(iv, 0, 255); } } break; } }
void CIYuv::getData_inBGR(IplImage *imgBGR) { int h, w, cH, cW; int ir, ig, ib; unsigned char *bufBGR; switch(sampling) { case 400: for(h=0; h<height; h++) { bufBGR = (unsigned char *)&(imgBGR->imageData[h*imgBGR->widthStep]); for(w=0; w<width; w++) { *bufBGR++ = Y[h][w]; *bufBGR++ = Y[h][w]; *bufBGR++ = Y[h][w]; } } break; case 420: for(h=cH=0; h<height; h++) { cH = h>>1; bufBGR = (unsigned char *)&(imgBGR->imageData[h*imgBGR->widthStep]); for(w=cW=0; w<width; w++, cW++) { ib = (int) (Y[h][w] + 1.772*(U[cH][cW]-127) + 0.5); *bufBGR++ = CLIP3(ib, 0, 255); ig = (int) (Y[h][w] - 0.344*(U[cH][cW]-127) - 0.714*(V[cH][cW]-127) + 0.5); *bufBGR++ = CLIP3(ig, 0, 255); ir = (int) (Y[h][w] + 1.402*(V[cH][cW]-127) + 0.5); *bufBGR++ = CLIP3(ir, 0, 255); w++; ib = (int) (Y[h][w] + 1.772*(U[cH][cW]-127) + 0.5); *bufBGR++ = CLIP3(ib, 0, 255); ig = (int) (Y[h][w] - 0.344*(U[cH][cW]-127) - 0.714*(V[cH][cW]-127) + 0.5); *bufBGR++ = CLIP3(ig, 0, 255); ir = (int) (Y[h][w] + 1.402*(V[cH][cW]-127) + 0.5); *bufBGR++ = CLIP3(ir, 0, 255); } } break; case 422: for(h=0; h<height; h++) { bufBGR = (unsigned char *)&(imgBGR->imageData[h*imgBGR->widthStep]); for(w=cW=0; w<width; w++, cW++) { ib = (int) (Y[h][w] + 1.772*(U[h][cW]-127) + 0.5); *bufBGR++ = CLIP3(ib, 0, 255); ig = (int) (Y[h][w] - 0.344*(U[h][cW]-127) - 0.714*(V[h][cW]-127) + 0.5); *bufBGR++ = CLIP3(ig, 0, 255); ir = (int) (Y[h][w] + 1.402*(V[h][cW]-127) + 0.5); *bufBGR++ = CLIP3(ir, 0, 255); w++; ib = (int) (Y[h][w] + 1.772*(U[h][cW]-127) + 0.5); *bufBGR++ = CLIP3(ib, 0, 255); ig = (int) (Y[h][w] - 0.344*(U[h][cW]-127) - 0.714*(V[h][cW]-127) + 0.5); *bufBGR++ = CLIP3(ig, 0, 255); ir = (int) (Y[h][w] + 1.402*(V[h][cW]-127) + 0.5); *bufBGR++ = CLIP3(ir, 0, 255); } } break; case 444: for(h=0; h<height; h++) { bufBGR = (unsigned char *)&(imgBGR->imageData[h*imgBGR->widthStep]); for(w=0; w<width; w++) { ib = (int) (Y[h][w] + 1.772*(U[h][w]-127) + 0.5); *bufBGR++ = CLIP3(ib, 0, 255); ig = (int) (Y[h][w] - 0.344*(U[h][w]-127) - 0.714*(V[h][w]-127) + 0.5); *bufBGR++ = CLIP3(ig, 0, 255); ir = (int) (Y[h][w] + 1.402*(V[h][w]-127) + 0.5); *bufBGR++ = CLIP3(ir, 0, 255); } } break; default: cvZero(imgBGR); break; } }
long TheoraEncodeInputPin::encodeRGB32toYV12(unsigned char* inBuf, long inNumBytes) { std::vector<unsigned char> ayuvBuf; ayuvBuf.resize(inNumBytes); //Scaled by factor of 65536 to integerise. const int KR = 19596; const int KB = 7472; const int ROUNDER = 32768; const int G_FACTOR = 38470; const int U_FACTOR = 12716213; const int V_FACTOR = 10061022; int locL = 0; int locB = 0; int locR = 0; //unsigned char* locSourcePtr = inBuf; unsigned char* pDest = &*ayuvBuf.begin(); //SOURCE: Blue Green Red Blue Green Red. //DEST: v u y a unsigned char* pSourceEnds = inBuf + inNumBytes; unsigned char* pSource = 0; unsigned char* pEnd = 0; long stride = 0; if (m_flipImageVerticaly) { stride = m_width * 4; pSource = inBuf; pEnd = pSourceEnds; } else { // Negative stride stride = 0 - m_width * 4; pSource = pSourceEnds - std::abs(stride); pEnd = inBuf - std::abs(stride); } for (; pSource != pEnd; pSource += stride) { unsigned char* pColSource = pSource; unsigned char* pColEnd = pColSource + std::abs(stride); while (pColSource < pColEnd) { locB = pColSource[0]; //Blue locL = KB * (locB); //Blue locL += G_FACTOR * (pColSource[1]); //Green locR = pColSource[2]; //Red locL += KR * (locR); //Red *(pDest++) = CLIP3(0, 255, ((112 * ( (locR<<16) - locL)) / V_FACTOR) + 128); //V for Victor *(pDest++) = CLIP3(0, 255, ((112 * ( (locB<<16) - locL)) / U_FACTOR) + 128); //U for ugly *(pDest++) = CLIP3(0, 255, locL >> 16); //Y for yellow *(pDest++) = pColSource[3]; //A for alpha pColSource += 4; } } encodeAYUVtoYV12(&*ayuvBuf.begin(), ayuvBuf.size()); return 0; }
long TheoraEncodeInputPin::encodeRGB24toYV12(unsigned char* inBuf, long inNumBytes) { /* Conversion from RGB to YUV is defined by starting with the following: L = Kr * R + Kb * B + (1 – Kr – Kb) * G The YUV values are then obtained as follows: Y = floor(2^(M-8) * (219*(L–Z)/S + 16) + 0.5) U = clip3(0, 2^M-1, floor(2^(M-8) * (112*(B-L) / ((1-Kb)*S) + 128) + 0.5)) V = clip3(0, 2^M-1, floor(2^(M-8) * (112*(R-L) / ((1-Kr)*S) + 128) + 0.5)) where Z = 16 S = 219 M = 8 bits per sample. ==> Y = floor(L + 0.5) U = (112*(B-L) / ((1-Kb)*S) + 128) Kr' = Kr * 65536 Kb' = Kb * 65536 G_FACTOR = (1 - Kr - Kb) * 65536 L' = (Kr' * R) + (Kb' * B) + (G_FACTOR * G) = 65536 * ( (Kr * R) + (Kb * B) + ((1 - Kr - Kb) * G) ) = 65536 * L Y = round( 219 * (L-Z)/S + 16 ) = round ( L-Z + 16 ) = round( L ) Y' = L' = 65536 * L Y = L' >> 16 U_FACTOR = ( 1 - Kb) * S U_FACTOR' = 12716213 = 65536 * U_FACTOR V_FACTOR' = 10061022 B' = 65536 * B R' = 65536 * R _U_ = round( 112 * (B-L) / ( (1-Kb)*S ) + 128 ) = round( (112 * (B-L) / U_FACTOR) + 128 ) = (112 * (B' - L') / U_FACTOR') + 128 = (112 * 65536 * (B - L) / (U_FACTOR * 65536)) + 128 = (112 * (B - L) / U_FACTOR) + 128 Hence integerisation scaling cancels ==> _U_ = (112 * (B' - L') / U_FACTOR') + 128 _V_ = (112 * (R' - L') / V_FACTOR') + 128 */ /* Kr = 0.299 Kb = 0.114 */ //Blue Green Red Blue Green Red. unsigned long numPixels = inNumBytes / 3; std::vector<unsigned char> ayuvBuf; ayuvBuf.resize(numPixels * 4); //Scaled by factor of 65536 to integerise. const int KR = 19596; const int KB = 7472; const int ROUNDER = 32768; const int G_FACTOR = 38470; const int U_FACTOR = 12716213; const int V_FACTOR = 10061022; int locL = 0; int locB = 0; int locR = 0; //unsigned char* locSourcePtr = inBuf; unsigned char* pDest = &*ayuvBuf.begin(); //SOURCE: Blue Green Red Blue Green Red. //DEST: v u y a unsigned char* pSourceEnds = inBuf + inNumBytes; unsigned char* pSource = 0; unsigned char* pEnd = 0; long stride = 0; if (m_flipImageVerticaly) { stride = m_width * 3; pSource = inBuf; pEnd = pSourceEnds; } else { // Negative stride stride = 0 - m_width * 3; pSource = pSourceEnds - std::abs(stride); pEnd = inBuf - std::abs(stride); } for (; pSource != pEnd; pSource += stride) { unsigned char* pColSource = pSource; unsigned char* pColEnd = pColSource + std::abs(stride); while (pColSource < pColEnd) { locB = pColSource[0]; //Blue locL = KB * (locB); //Blue locL += G_FACTOR * (pColSource[1]); //Green locR = pColSource[2]; //Red locL += KR * (locR); //Red *(pDest++) = CLIP3(0, 255, ((112 * ( (locR<<16) - locL)) / V_FACTOR) + 128); //V for Victor *(pDest++) = CLIP3(0, 255, ((112 * ( (locB<<16) - locL)) / U_FACTOR) + 128); //U for ugly *(pDest++) = CLIP3(0, 255, locL >> 16); //Y for yellow *(pDest++) = 255; //A for alpha pColSource += 3; } } encodeAYUVtoYV12(&*ayuvBuf.begin(), ayuvBuf.size()); return 0; }