基于avd7181c解决视频输入效果差的问题<四>---android显示相关实现调试手记

基于avd7181c解决视频输入效果差的问题<四>---android显示相关实现调试手记

 

         笔者在前几篇文章中提到的都是AVD7181C的信号通过CSI的数据通道,然后给camera APK来显示,就可以看到YPBPR\CVBS的输入信号了。利用camera
apk调试AVD7181C也是为了加快调试进度,笔者在实践中确实感觉很有益。通过它,我们可以先把AVD7181C以及CSI的驱动先调试稳定下来,调试正确,确保数据到应用之前是正确的,但是最终我们是要作产品,总不能用camera的apk来看这种视频输入的图像,从理论上当然也可以通过改造camera
apk来控制ui显示,但是这样也会比较麻烦,因为系统本身还需要camera apk,因为有真正的camera也在系统中。那怎么办呢?

        从HAL layer到应用重新做一套,这个工作量会有一点,主要是在硬件抽象层的代码设计上。还好全志平台提供了TVD的一套东西。笔者就可以模仿这一套东西来做,这样也省了不少事情,当然硬件抽象层是跟硬件打交道的,TVD跟CSI还是不大一样的,设置的参数、fmt这些会很大不同,因为硬件驱动是不一样的,全志TVD驱动做得不是很标准,代码写得比较乱,CSI那边的驱动做得要好一些。

        借鉴TVD的框架是可以的,稍微改动一些可以为我所用。笔者同样也借鉴了Camera硬件抽象层的代码实现,两种合理结合一些,这是就成了,当然还得加入一些里面没有实现的东西。

/*****************************************************************************************************/
声明:本博内容均由http://blog.csdn.net/sundesheng125原创,转载请注明出处,谢谢!
/*****************************************************************************************************/

        首先来看一下总得初始化接口实现,里面是先打开设备,在打开设备里面会设置输入视频源,查询视频设备驱动能力,紧接着设置视频模式,是V4L2_MODE_VIDEO的,再来设置video的参数,比如宽高、pixel的格式、filed等,然后再申请buffer,绑定匹配buffer地址,最后就是启动视频设备数据流,整个设备就工作起了。代码具体如下:

 

status_t CCSIDecoderHardware::v4l2Init(int mOldSystem)
{
	F_LOG;

	CHECK_ERROR(openCameraDev());

	// set capture mode
	struct v4l2_streamparm params;
        params.parm.capture.timeperframe.numerator = 1;
	params.parm.capture.timeperframe.denominator = 25;
	params.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	params.parm.capture.capturemode = V4L2_MODE_VIDEO;//V4L2_MODE_IMAGE

	v4l2setCaptureParams(¶ms);

	// set v4l2 device parameters
	CHECK_ERROR(v4l2SetVideoParams(mOldSystem));

	// v4l2 request buffers
	CHECK_ERROR(v4l2ReqBufs());

	// v4l2 query buffers
	CHECK_ERROR(v4l2QueryBuf());

	// stream on the v4l2 device
	CHECK_ERROR(v4l2StartStreaming());

	return OK;
}

       笔者移植了tryFmt()这个用来寻找对应的fmt,会有一下参数关联,比如输入CSI的fmt格式,CSI输出数据格式、CSI数据接口类型等,代码示例如下:

  

	struct v4l2_fmtdesc fmtdesc;
	fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	for(int i = 0; i < 12; i++)
	{
		fmtdesc.index = i;
		if (-1 == ioctl (mV4l2Handle, VIDIOC_ENUM_FMT, &fmtdesc))
		{
			break;
		}
		LOGV("format index = %d, name = %s, v4l2 pixel format = %x\n",
			i, fmtdesc.description, fmtdesc.pixelformat);

		if (fmtdesc.pixelformat == format)
		{
			return OK;
		}
          }

要设置video的参数;

	struct v4l2_format format;

	LOGD("#####################VIDIOC_S_PARM\n");
	memset(&format, 0, sizeof(format));
        format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        format.fmt.pix.width  = mVideoWidth;
        format.fmt.pix.height = mVideoHeight;
        format.fmt.pix.pixelformat = mVideoFormat; //pix_fmt
	format.fmt.pix.field = V4L2_FIELD_NONE;

	ret = ioctl(mV4l2Handle, VIDIOC_S_FMT, &format);
	if (ret < 0)
	{
		LOGE("VIDIOC_S_FMT Failed: %s", strerror(errno));
		return ret;
	}

      得起一个线程来负责读数据帧,以及把数据帧数据处理掉。在这个线程中还需要加入实时检测视频信号的有无,以及信号的制式,是NTSC还是PAL,监测代码如下:

  struct v4l2_control ctrl;
  ctrl.value = 0;
  ctrl.id = V4L2_CID_BRIGHTNESS;/*just use this channel to read fmt & detect signals*/
	ret = ioctl (mV4l2Handle, VIDIOC_G_CTRL, &ctrl);
	if (ret < 0)
	{
		LOGE("vidioc_g_ctrl: %s", strerror(errno));
	} 

	LOGE("get_system ctrl.value 0x%02x", ctrl.value);
  mDetectcvbsSignal = ((ctrl.value & 0x10) == 0x10)? 0:1 ;/*bit4 1:no signal 0: has signal*/

  fmt = ctrl.value & 0x7;
  if((0 == fmt) || (1 == fmt))
		 *__system = 0;/*NTSC*/
	else
	   *__system = 1;/*PAL*/

       笔者在信号制式的处理上稍微做了一下变通,因为这两种制式在大小上是不一样,但是我们可以用大一点的那个buffer,这样我们就不需要重新去设置这些buffer,而只需要控制后面取buffer的数据大小就可以,这样也是简便了一下。同时,笔者在调试发现NTSC的制式上,开始会有是十几个像素高度的脏数据,显示是乱的,这样我用大buffer就可以把N制的整个数据都截下来,起始地址移动一下就可以了,这样确实真实有效,里面使用了native
window的操作,直接把数据帧的buffer地址赋给了hwcoposer,也就是到内核里的硬件驱动里,这样就减少了数据拷贝的工作,cpu使用率非常低,这样主芯片可以干很多其他的事情。代码如下:

    int hight = 0;
    hight = (mOldSystem == 0)? 480:576;
    LOGV("mOldSystem = %d, hight =%d\n", mOldSystem, hight);
		ret = native_window_set_buffers_geometryex(mPreviewWindow ,
		   mVideoWidth,     hight,HWC_FORMAT_YUV422PLANAR_UV_COMBINED, //*/HWC_FORMAT_DEFAULT,HWC_FORMAT_YUV420PLANAR
        	   0);
		if (ret != NO_ERROR)
		{
			LOGE("%s: Error in set_buffers_geometry %d -> %s",__FUNCTION__, -ret, strerror(-ret));
			return ret;
		}
....
    

 /*when NTSC shoud shift display buffer*/
 overlay_para.bProgressiveSrc = 0;
 overlay_para.bTopFieldFirst = 1;
 overlay_para.pVideoInfo.frame_rate = 25000;
 if(1 == mOldSystem) {/*PAL*/
  overlay_para.top_y   = (unsigned int)buf.m.offset;
   overlay_para.top_c   = (unsigned int)buf.m.offset +  mVideoWidth * mVideoHeight;
 } else {/*NTSC*/
   overlay_para.top_y   = (unsigned int)buf.m.offset+ 1440;/* 720*20 20 point*/
   overlay_para.top_c   = (unsigned int)buf.m.offset +  mVideoWidth * mVideoHeight+7200;/* 720*20*1/2 20 point*/  
 }
 overlay_para.bottom_y  = 0;
 overlay_para.bottom_c  = 0;
 overlay_para.number  = 0;

 if (mOverlayFirstFrame)
 {
  LOGD("first frame true");
  overlay_para.first_frame_flg = 1;
  mOverlayFirstFrame = false;
 }
 else
 {
  overlay_para.first_frame_flg = 0;
 }

 ret = mPreviewWindow->perform(mPreviewWindow, NATIVE_WINDOW_SETPARAMETER, HWC_LAYER_SETFRAMEPARA, (uint32_t)&overlay_para);
 if (ret != OK)
 {
  LOGE("NATIVE_WINDOW_SETPARAMETER failed");
  return ret;

        HWC_FORMAT_YUV422PLANAR_UV_COMBINED是笔者自定义的格式,全志平台里没有做这种格式,在hwc的硬件抽象层里需要添加需相应的代码实现,贴一部分如下:

            case HWC_FORMAT_YUV422PLANAR_UV_COMBINED:
                disp_format = DISP_FORMAT_YUV422;
                fb_mode = DISP_MOD_NON_MB_UV_COMBINED;
                disp_seq = DISP_SEQ_UYVY;
                break;

      当然,以后如果要做录像的话,就需要把数据帧截下来,通过多媒体那边的库来压缩编码存文件,这个工作可以参考camera里面的实现。硬件抽象层的代码就差不多了。JNI以及应用APK,都可以再TVD上稍微改改,难度不大,这里就不再详述。贴一张整个实现后的应用截图吧!

 

 

时间: 2024-08-18 08:38:29

基于avd7181c解决视频输入效果差的问题&lt;四&gt;---android显示相关实现调试手记的相关文章

基于avd7181c解决视频输入效果差的问题&amp;lt;三&amp;gt;---CVBS无色彩疑难调试手记

基于avd7181c解决视频输入效果差的问题<三>---CVBS无色彩疑难调试手记            笔者在前两篇文章中讲述了基于AVD7181C来解决平台视频输入效果差的问题大概解决方案以及遇到的IIC兼容性问题的解决方法,在本文中将继续解释笔者在调试AVD7181C CVBS输入信号的情况下遇到的没有色彩的问题.笔者经过逐步的验证.推敲终于解决了这个问题,现将过程大概介绍一下.         通过前面的努力,CSI的数据通道已经打通,通过camera APK可以看到YPBPR\CVB

基于avd7181c解决视频输入效果差的问题&amp;lt;二&amp;gt;---疑难调试手记

基于avd7181c解决视频输入效果差的问题<二>---疑难调试手记          笔者在上一篇文章中讲述了基于AVD7181C来解决平台视频输入效果差的问题大概解决方案.在这个探索研究中,也遇到了一些比较麻烦的问题.下面就讲述一些遇到的几个让人欢喜让人忧的问题.       Avd7181c是通过IIC来控制的.因为iic也是一种非常成熟的通讯接口,我们就直接用全志平台里整理过的iic操作sensor_read, sensor_write接口,这两个接口在平台支持的camera有很多种型

基于avd7181c解决视频输入效果差的问题&amp;lt;一&amp;gt;---驱动移植、调试手记

基于avd7181c解决视频输入效果差的问题<一>---驱动移植.调试手记             做过全志A10平台的人都知道,在视频输入方面,虽然有4路TV Decoder,但是做的效果真的不敢恭维.笔者基于全志平台做车载互动娱乐系统以及车载导航主机,客户对视频输入效果有强烈要求,怎么办呢? 加芯片弥补平台的不足.笔者选用的是AVD7181C芯片,可以支持CVBS\S-Video\YPbPr\RGB等多种输入格式,通过该芯片可以输出YUV 4:2:2信号.656信号.YPbPr输入信号的情

归纳企业做竞价广告效果差的三大自身原因

对于每一家资本企业来说,我想经营的目的无非是最小的投入获得最大的收益.对此每一家企业在做一项投资时都会对投入与收益做投资回报率的估算.在线上营销中更是如此.众所周知在线上营销的策略中竞价广告可谓是一项最烧钱的策略,需要企业不断的投入资金,但是很多企业在竞价广告投入大把的资金后却发现效果却不尽如人意.其实竞价广告之所以会失败往往是来自企业自身对于一些细节上的疏忽.下面笔者就以自身的经验谈谈在企业做竞价广告时促使效果差的三大自身原因. 自身原因一:你是否对于投放的技巧进行斟酌过 在竞价广告的投放上也

基于jquery实现放大镜效果_jquery

各大商城详细页面产品图片特效展示,鼠标滑过小图显示中图,鼠标滑过中图显示大图展示,jquery放大镜效果图片类似图片放大镜展示,提高用户体验设计,jquery 图片放大镜效果是典型的一款图片特效展示. 效果图如下: 图片大框初始样式: <div class="goods-imginfo-bimg-box" style="background-image: url(http://www.od.my/images/201507/thumb_img/142_thumb_P_1

JS基于递归实现倒计时效果的方法_javascript技巧

本文实例讲述了JS基于递归实现倒计时效果的方法.分享给大家供大家参考,具体如下: 效果: 事件: //发送验证码 $('.js-sms-code').click(function(){ $(this).attr("disabled", "disabled").html("<span style='color:#666'><span id='countdown'>60</span>s 后再试</span>&qu

基于jquery的loading效果实现代码_jquery

在代码<head></head>里加入以下代码: <script type="text/javascript" src="jquery.js"></script><script type="text/javascript">$(window).load(function(){$("#loading").hide();})</script> 在里<bo

25款室内净化器净化效果差6倍

摘要: 空气净化器已成为污染环境下很多家庭的标配,这些净化器真的能帮助净化空气吗?昨天,中消协对外公布25款净化器的比较试验结果,不同的室内净化器净化效果相差6倍之多.一款售 空气净化器已成为污染环境下很多家庭的"标配",这些净化器真的能帮助净化空气吗?昨天,中消协对外公布25款净化器的比较试验结果,不同的室内净化器净化效果相差6倍之多.一款售价上万元的净化器无论是净化颗粒物还是除甲醛,效果都不理想. 25款室内净化器净化效果差6倍 这25款净化器是中消协人员以消费者身份从北京.天津的

腾云语音报钟器:五大功能彻底解决技师服务差的困扰

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 目前大部分洗浴/足浴行业会遇到这样的问题:生意好,客人峰拥而至,服务员与技师却手忙脚乱,大大降低效率,客户回头率比较低,服务无法提升...针对这一系列问题,洗浴经营管理者该如何应对? 佳驰软件旗下腾云洗浴/足浴管理软件,八年行业经验,为上万家洗浴/足浴行业提供完善的贴心服务,好评率非常高!作为行业首家提出完美智能无线报钟器解决方案,被客户一致