基于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上稍微改改,难度不大,这里就不再详述。贴一张整个实现后的应用截图吧!

 

 

目录
相关文章
|
21天前
|
存储 消息中间件 人工智能
【03】AI辅助编程完整的安卓二次商业实战-本地构建运行并且调试-二次开发改注册登陆按钮颜色以及整体资源结构熟悉-优雅草伊凡
【03】AI辅助编程完整的安卓二次商业实战-本地构建运行并且调试-二次开发改注册登陆按钮颜色以及整体资源结构熟悉-优雅草伊凡
56 3
|
21天前
|
缓存 Unix Android开发
Android安卓项目调试之Gradle 与 Gradle Wrapper的概念以及常用gradle命令深度详解-优雅草卓伊凡
Android安卓项目调试之Gradle 与 Gradle Wrapper的概念以及常用gradle命令深度详解-优雅草卓伊凡
115 8
|
21天前
|
存储 API Android开发
【02】完整的安卓二次商业实战-配置gradle-构建打包原生安卓项目-调试本地运行模拟器-优雅草伊凡
【02】完整的安卓二次商业实战-配置gradle-构建打包原生安卓项目-调试本地运行模拟器-优雅草伊凡
79 4
【02】完整的安卓二次商业实战-配置gradle-构建打包原生安卓项目-调试本地运行模拟器-优雅草伊凡
|
9月前
|
编解码 安全 Android开发
如何修复 Android 和 Windows 不支持视频编解码器的问题?
视频播放时遇到“编解码器不支持”错误(如0xc00d36c4或0xc00d5212)是常见问题,即使文件格式为MP4或MKV。编解码器是编码和解码数据的工具,不同设备和版本支持不同的编解码器。解决方法包括:1) 安装所需编解码器,如K-Lite Codec Pack;2) 使用自带编解码器的第三方播放器,如VLC、KMPlayer等。这些方法能帮助你顺利播放视频。
|
7月前
|
监控 Shell Linux
Android调试终极指南:ADB安装+多设备连接+ANR日志抓取全流程解析,覆盖环境变量配置/多设备调试/ANR日志分析全流程,附Win/Mac/Linux三平台解决方案
ADB(Android Debug Bridge)是安卓开发中的重要工具,用于连接电脑与安卓设备,实现文件传输、应用管理、日志抓取等功能。本文介绍了 ADB 的基本概念、安装配置及常用命令。包括:1) 基本命令如 `adb version` 和 `adb devices`;2) 权限操作如 `adb root` 和 `adb shell`;3) APK 操作如安装、卸载应用;4) 文件传输如 `adb push` 和 `adb pull`;5) 日志记录如 `adb logcat`;6) 系统信息获取如屏幕截图和录屏。通过这些功能,用户可高效调试和管理安卓设备。
|
8月前
|
缓存 Java 测试技术
【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
861 3
【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
|
9月前
|
缓存 前端开发 Android开发
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
388 12
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
|
Shell Linux 开发工具
"开发者的救星:揭秘如何用adb神器征服Android设备,开启高效调试之旅!"
【8月更文挑战第20天】Android Debug Bridge (adb) 是 Android 开发者必备工具,用于实现计算机与 Android 设备间通讯,执行调试及命令操作。adb 提供了丰富的命令行接口,覆盖从基础设备管理到复杂系统操作的需求。本文详细介绍 adb 的安装配置流程,并列举实用命令示例,包括设备连接管理、应用安装调试、文件系统访问等基础功能,以及端口转发、日志查看等高级技巧。此外,还提供了常见问题的故障排除指南,帮助开发者快速解决问题。掌握 adb 将极大提升 Android 开发效率,助力项目顺利推进。
372 0
|
Android开发 容器
35. 【Android教程】视频页面:ViewPager
35. 【Android教程】视频页面:ViewPager
141 3
|
11月前
|
前端开发 数据处理 Android开发
Flutter前端开发中的调试技巧与工具使用方法,涵盖调试的重要性、基本技巧如打印日志与断点调试、常用调试工具如Android Studio/VS Code调试器和Flutter Inspector的介绍
本文深入探讨了Flutter前端开发中的调试技巧与工具使用方法,涵盖调试的重要性、基本技巧如打印日志与断点调试、常用调试工具如Android Studio/VS Code调试器和Flutter Inspector的介绍,以及具体操作步骤、常见问题解决、高级调试技巧、团队协作中的调试应用和未来发展趋势,旨在帮助开发者提高调试效率,提升应用质量。
298 8

热门文章

最新文章