RK平台MJPEG硬编码接口函数实现

JPEG软编码比较耗时,可能满足不了帧率的需求,RK平台自带JPEG硬编码,支持NV12和RGB565格式编码为MJPEG ,下面是封装后的函数实现

int hw_jpeg_encode_nv12(long input_phy_addr,long output_phy_addr,uint8*  input_vir_addr,uint8* output_vir_addr,int width,int height,int picfmt,int quality,int thumbquality )
{
	JpegEncInInfo JpegInInfo;
	JpegEncOutInfo JpegOutInfo;
	RkExifInfo exifInfo;
	RkGPSInfo gpsInfo;
	JpegEncType encodetype;
	int jpeg_w,jpeg_h,err;
	int jpegbuf_size,jpeg_buf_w,jpeg_buf_h;;
	vpu_display_mem_pool *pool;
	
	if (create_vpu_memory_pool_allocator(&pool, 10, 200*200*2) < 0) {
		LOGE("Create vpu memory pool for post process failed\n");
		pool = NULL;
	} else {
		LOG1("============ create_vpu_memory_pool_allocator 10*80kB ==========");
	}
	
	memset(&JpegInInfo,0x00,sizeof(JpegEncInInfo));
	memset(&JpegOutInfo,0x00,sizeof(JpegEncOutInfo));
	memset(&exifInfo,0x00,sizeof(exifInfo));
	
	jpeg_w = width;
	jpeg_h = height;
	
	if(picfmt ==V4L2_PIX_FMT_RGB565){
		encodetype = HWJPEGENC_RGB565;
		jpegbuf_size = jpeg_w * jpeg_h *2;
	}else{
		encodetype = JPEGENC_YUV420_SP;
		jpeg_buf_w = jpeg_w;
		jpeg_buf_h = jpeg_h;
		if(jpeg_buf_w%16)
			jpeg_buf_w += 8;
		if(jpeg_buf_h%16)
			jpeg_buf_h += 8;
		jpegbuf_size = jpeg_buf_w*jpeg_buf_h*3/2;
		
	}
	if (jpegbuf_size & 0xfff) {
		jpegbuf_size = (jpegbuf_size & 0xfffff000) + 0x1000;
	}
	JpegInInfo.rotateDegree = DEGREE_0;
	JpegInInfo.frameHeader = 1;
	JpegInInfo.yuvaddrfor180 = (int)NULL;
	JpegInInfo.type = encodetype;
	JpegInInfo.y_rgb_addr = input_phy_addr;
	JpegInInfo.uv_addr = input_phy_addr + jpeg_w*jpeg_h;
	//JpegInInfo.y_vir_addr = input_vir_addr;
  	//JpegInInfo.uv_vir_addr = input_vir_addr + jpeg_w*jpeg_h;
	
	JpegInInfo.inputW = jpeg_w;
	JpegInInfo.inputH = jpeg_h;
	JpegInInfo.pool = pool;
	JpegInInfo.qLvl = quality/10;
	if (JpegInInfo.qLvl < 5) {
		JpegInInfo.qLvl = 5;
	}
	JpegInInfo.thumbqLvl = thumbquality /10;
	if (JpegInInfo.thumbqLvl < 5) {
		JpegInInfo.thumbqLvl = 5;
	}
	if(JpegInInfo.thumbqLvl  >10) {
		JpegInInfo.thumbqLvl = 9;
	}
	#if 1
	JpegInInfo.doThumbNail = 0; 		 //insert thumbnail at APP0 extension
	JpegInInfo.thumbData = NULL;		 //if thumbData is NULL, do scale, the type above can not be 420_P or 422_UYVY
	JpegInInfo.thumbDataLen = -1;
	JpegInInfo.thumbW = 0;//thumbwidth;
	JpegInInfo.thumbH = 0;//thumbheight;
	JpegInInfo.y_vir_addr = 0;
	JpegInInfo.uv_vir_addr = 0;
	#else
	JpegInInfo.doThumbNail = 1; 		 //insert thumbnail at APP0 extension
	JpegInInfo.thumbData = NULL;		 //if thumbData is NULL, do scale, the type above can not be 420_P or 422_UYVY
	JpegInInfo.thumbDataLen = -1;
	JpegInInfo.thumbW = 128;
	JpegInInfo.thumbH = 160;
	JpegInInfo.y_vir_addr = (unsigned char*)input_vir_addr;
	JpegInInfo.uv_vir_addr = (unsigned char*)input_vir_addr+jpeg_w*jpeg_h;
	#endif
	
	#if 1
	static char ExifMaker[32];
	static char ExifModel[32];
	static char ExifSelfDefine[640];
	/*fill in jpeg exif tag*/ 
	strncpy((char *)ExifMaker, "lvjiong",sizeof(ExifMaker) - 1);
	ExifMaker[sizeof(ExifMaker) - 1] = '\0';
	exifInfo.maker = ExifMaker;
	exifInfo.makerchars = strlen(ExifMaker)+1;
	
	strncpy((char *)ExifModel, "rk3399",sizeof(ExifModel) - 1);
	ExifModel[sizeof(ExifModel) - 1] = '\0';
	exifInfo.modelstr = ExifModel;
	exifInfo.modelchars = strlen(ExifModel)+1;  

    //degree 0:1
    //degree 90(clockwise):6
    //degree 180:3
    //degree 270:8
    exifInfo.Orientation = 1;

	// Date time
	time_t rawtime;
	struct tm *timeinfo;
	time(&rawtime);
	timeinfo = localtime(&rawtime);
	strftime((char *)exifInfo.DateTime, 20, "%Y:%m:%d %H:%M:%S", timeinfo);
	
	exifInfo.ExposureTime.num = 100;//lvjiong
	exifInfo.ExposureTime.denom = 10000;
	exifInfo.ApertureFNumber.num = 0x118;
	exifInfo.ApertureFNumber.denom = 0x64;
	exifInfo.ISOSpeedRatings = 10;//lvjiong
	exifInfo.CompressedBitsPerPixel.num = 0x4;
	exifInfo.CompressedBitsPerPixel.denom = 0x1;
	exifInfo.ShutterSpeedValue.num = 0x452;
	exifInfo.ShutterSpeedValue.denom = 0x100;
	exifInfo.ApertureValue.num = 0x2f8;
	exifInfo.ApertureValue.denom = 0x100;
	exifInfo.ExposureBiasValue.num = 0;
	exifInfo.ExposureBiasValue.denom = 0x100;
	exifInfo.MaxApertureValue.num = 0x02f8;
	exifInfo.MaxApertureValue.denom = 0x100;
	exifInfo.MeteringMode = 02;

	exifInfo.Flash = 0;//lvjiong	
	exifInfo.FocalLength.num = 0;//lvjiong
	exifInfo.FocalLength.denom = 0x1;
	
	exifInfo.FocalPlaneXResolution.num = 0x8383;
	exifInfo.FocalPlaneXResolution.denom = 0x67;
	exifInfo.FocalPlaneYResolution.num = 0x7878;
	exifInfo.FocalPlaneYResolution.denom = 0x76;
	exifInfo.SensingMethod = 2;
	exifInfo.FileSource = 3;
	exifInfo.CustomRendered = 1;
	exifInfo.ExposureMode = 0;

	exifInfo.WhiteBalance = 100;//lvjiong
	exifInfo.DigitalZoomRatio.num = width;//lvjiong
	exifInfo.DigitalZoomRatio.denom = width;//lvjiong
	exifInfo.SceneCaptureType = 0x01;	 
	
	/* snprintf(ExifSelfDefine,sizeof(ExifSelfDefine)-1,"XMLVersion=%s   Rg_Proj=%0.5f   s=%0.5f   s_max1=%0.5f  s_max2=%0.5f   Bg1=%0.5f   Rg1=%0.5f   Bg2=%0.5f   Rg2=%0.5f   "
    "colortemperature=%s   ExpPriorIn=%0.2f   ExpPriorOut=%0.2f    region=%d   ",params.cameraparam.XMLVersion,params.cameraparam.f_RgProj,\
    params.cameraparam.f_s,params.cameraparam.f_s_Max1,params.cameraparam.f_s_Max2,params.cameraparam.f_Bg1,params.cameraparam.f_Rg1,params.cameraparam.f_Bg2,\
    params.cameraparam.f_Rg2,params.cameraparam.illuName[params.cameraparam.illuIdx],params.cameraparam.expPriorIn,params.cameraparam.expPriorOut,\
    params.cameraparam.region);
	
	int i;
	char str[64];
	for(i=0; i<params.cameraparam.count; i++)
	{
		snprintf(str,sizeof(str)-1, "illuName[%d]=%s   ",i,params.cameraparam.illuName[i]);
		strncat(ExifSelfDefine, str, sizeof(ExifSelfDefine)-strlen(ExifSelfDefine)-1);
		snprintf(str,sizeof(str)-1, "likehood[%d]=%0.2f   ",i,params.cameraparam.likehood[i]);
		strncat(ExifSelfDefine, str, sizeof(ExifSelfDefine)-strlen(ExifSelfDefine)-1);	
		snprintf(str,sizeof(str)-1, "wight[%d]=%0.2f   ",i,params.cameraparam.wight[i]);
		strncat(ExifSelfDefine, str, sizeof(ExifSelfDefine)-strlen(ExifSelfDefine)-1);	
	}
	exifInfo.makernote = ExifSelfDefine;
	exifInfo.makernotechars = strlen(ExifSelfDefine)+1; */
	#endif
	
	//Jpegfillexifinfo(&exifInfo,mPictureInfo);
	JpegInInfo.exifInfo =&exifInfo;
	
	JpegInInfo.gpsInfo = NULL;
	
	JpegOutInfo.outBufPhyAddr = output_phy_addr;
	JpegOutInfo.outBufVirAddr = output_vir_addr;
	JpegOutInfo.outBuflen = jpegbuf_size;
	JpegOutInfo.jpegFileLen = 0x00;
	JpegOutInfo.cacheflush= /*jpegEncFlushBufferCb*/NULL;
	
	
/* 	LOGE("input_phy_addr %d,JpegOutInfo.outBufPhyAddr:%x,JpegOutInfo.outBufVirAddr:%p,jpegbuf_size:%d",input_phy_addr,JpegOutInfo.outBufPhyAddr,JpegOutInfo.outBufVirAddr,jpegbuf_size);
	
	LOGE("\nJpegInInfo.y_rgb_addr=0x%x\n"
	  "JpegInInfo.uv_addr=0x%x\n"
	  "JpegInInfo.inputW=0x%x\n"
	  "JpegInInfo.inputH=0x%x\n"
	  "JpegInInfo.pool=0x%x\n"
	  "JpegInInfo.qLvl=0x%x\n"
	  "\n"
	  "JpegOutInfo.outBufPhyAddr=0x%x\n"
	  "JpegOutInfo.outBufVirAddr=0x%x\n"
	  "JpegOutInfo.outBuflen=0x%x\n",
	  JpegInInfo.y_rgb_addr,
	  JpegInInfo.uv_addr,
	  JpegInInfo.inputW,
	  JpegInInfo.inputH,
	  JpegInInfo.pool,
	  JpegInInfo.qLvl,
	  JpegOutInfo.outBufPhyAddr,
	  JpegOutInfo.outBufVirAddr,
	  JpegOutInfo.outBuflen); */
	
	err = hw_jpeg_encode(&JpegInInfo, &JpegOutInfo);
	
	if ((err < 0) || (JpegOutInfo.jpegFileLen <=0x00)) 
  		LOGE("%s(%d): hw_jpeg_encode Failed, err: %d  JpegOutInfo.jpegFileLen:0x%x\n",__FUNCTION__,__LINE__,
  			err, JpegOutInfo.jpegFileLen);
		
	if (pool) {
		release_vpu_memory_pool_allocator(pool);
		pool = NULL;
	}		
	return JpegOutInfo.jpegFileLen;
}

调用方法

    long shared_buf_phy, shared_buf_vir;//存放编码后jpeg数据,使用时直接引用虚拟地址即可
    int index = -1;            

//phy_addr,y_addr_vir 为ISP输出的相机数据存放的物理地址和虚拟地址

this->mSharedBufProvider->createBuffer(CONFIG_CAMERA_SHARED_BUF_CNT,SENSOR_WIDTH*SENSOR_HEIGHT*2,JPEGBUFFER,false);

    index = this->mSharedBufProvider->getOneAvailableBuffer(&shared_buf_phy,&shared_buf_vir);
                #if defined(RK_DRM_GRALLOC) // should use fd
                shared_buf_phy = this->mSharedBufProvider->getBufShareFd(index);
                #endif
                outlen = hw_jpeg_encode_nv12(phy_addr,shared_buf_phy,(uint8*)y_addr_vir,(uint8*)shared_buf_vir,width,height,V4L2_PIX_FMT_NV12,80,80);

 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Free飝Fly

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值