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

简介: 基于avd7181c解决视频输入效果差的问题---android显示相关实现调试手记            笔者在前几篇文章中提到的都是AVD7181C的信号通过CSI的数据通道,然后给camera APK来显示,就可以看到YPBPR\CVBS的输入信号了。

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

 

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

        从HAL layer到应用重新做一套,这个工作量会有一点,主要是在硬件抽象层的代码设计上。还好全志平台提供了TVD的一套东西。笔者就可以模仿这一套东西来做,这样也省了不少事情,当然硬件抽象层是跟硬件打交道的,TVDCSI还是不大一样的,设置的参数、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,会有一下参数关联,比如输入CSIfmt格式,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上稍微改改,难度不大,这里就不再详述。贴一张整个实现后的应用截图吧!

 

 

目录
相关文章
|
6月前
|
存储 Java Linux
Android Mstar增加IR 自定义遥控头码完整调试过程
Android Mstar增加IR 自定义遥控头码完整调试过程
127 1
|
3月前
|
Shell Linux 开发工具
"开发者的救星:揭秘如何用adb神器征服Android设备,开启高效调试之旅!"
【8月更文挑战第20天】Android Debug Bridge (adb) 是 Android 开发者必备工具,用于实现计算机与 Android 设备间通讯,执行调试及命令操作。adb 提供了丰富的命令行接口,覆盖从基础设备管理到复杂系统操作的需求。本文详细介绍 adb 的安装配置流程,并列举实用命令示例,包括设备连接管理、应用安装调试、文件系统访问等基础功能,以及端口转发、日志查看等高级技巧。此外,还提供了常见问题的故障排除指南,帮助开发者快速解决问题。掌握 adb 将极大提升 Android 开发效率,助力项目顺利推进。
82 0
|
5月前
|
Android开发 容器
35. 【Android教程】视频页面:ViewPager
35. 【Android教程】视频页面:ViewPager
58 3
|
3月前
|
Ubuntu Android开发
安卓系统调试与优化:(一)bootchart 的配置和使用
本文介绍了如何在安卓系统中配置和使用bootchart工具来分析系统启动时间,包括安装工具、设备端启用bootchart、PC端解析数据及分析结果的详细步骤。
176 0
安卓系统调试与优化:(一)bootchart 的配置和使用
|
3月前
|
编解码 监控 API
惊艳登场!揭秘如何在Android平台上轻松玩转GB28181标准,实现多视频通道接入的超实用指南!
【8月更文挑战第14天】GB28181是公共安全视频监控联网的技术标准。本文介绍如何在Android平台上实现该标准下的多视频通道接入。首先准备开发环境,接着引入GB28181 SDK依赖并初始化SDK。实现设备注册与登录后,通过指定不同通道号请求多路视频流。最后,处理接收到的数据并显示给用户。此过程涉及视频解码,需确保应用稳定及良好的用户体验。
41 0
|
5月前
|
安全 API Android开发
Android打开USB调试命令
【6月更文挑战第20天】
184 1
|
5月前
|
监控 Android开发 数据安全/隐私保护
安卓kotlin JetPack Compose 实现摄像头监控画面变化并录制视频
在这个示例中,开发者正在使用Kotlin和Jetpack Compose构建一个Android应用程序,该程序 能够通过手机后置主摄像头录制视频、检测画面差异、实时预览并将视频上传至FTP服务器的Android应用
|
4月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的高校后勤网上报修系统安卓app附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的高校后勤网上报修系统安卓app附带文章源码部署视频讲解等
53 0
|
5月前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的安卓的微博客系统附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的安卓的微博客系统附带文章和源代码部署视频讲解等
46 2
|
6月前
|
存储 定位技术 开发工具
Android 开发前的设计,Android之内存泄漏调试学习与总结
Android 开发前的设计,Android之内存泄漏调试学习与总结
下一篇
无影云桌面