2021年2月3日星期三

Hi3559AV100板载开发系列-pthread_create()下V4L2接口MJPEG像素格式的VIDIOC_DQBUF error问题解决-采用阻塞方式下select监听

   最近一直加班加点进行基于Hi3559AV100平台的BOXER-8410AI板载开发,在开发的过程中,遇到了相当多的问题,其一是板载的开发资料没有且功能不完整,厂家不提供太多售后技术支持,厂家对部分硬件没有进行开发,如MIPI接口没有进行开发,且最基本的SDK版本包及环境搭建也需要自己去网上找且从头弄,好在之前有Hi3519A平台的开发经验,但还是遇到了很多问题;其二是网上相关H3559AV100平台开发资料很少,也导致了开发的周期拉长;其三是个人项目经验还是相对较少(虽然之前搞过电赛、robmaster等都拿了国奖,但是知识储备还是不够),之后将陆续记录基于Hi3559AV100平台的开发过程,希望能给您带来一些技术支持。早之前开发的记录将稍后推出,今天和大家说下关于pthread_create()下MJPEG格式的select监听。

  参考man pthread_create,pthread_create()函数在调用中启动一个新线程处理,给出pthread_create的特征:

1 #include <pthread.h>2 3   int pthread_create(pthread_t *thread, const pthread_attr_t *attr,4       void *(*start_routine) (void *), void *arg);5 //例如在VDEC 向视频解码通道发送码流数据 对函数 HI_MPI_VDEC_SendStream()进行操作时6 pthread_create(&pVdecThread[i], 0, SAMPLE_COMM_VDEC_SendStream, (HI_VOID *)&pstVdecSend[i]);

  新的线程通过调用start_routine()来开始执行,在此处,start_routine()为SAMPLE_COMM_VDEC_SendStream,arg<------->pstVdecSend[i]作为start_routine()的唯一参数传递;而thread这个标识符是用来引用在后续调用其他pthread功能,成功创建线程后,返回0。

  线程分两类,一类是joinable,一类是detached,对于joinable线程,需要用pthread_join()来等待线程结束并获取状态;而对于detached线程终止,其所用的资源系统会自动回收的,不需要进行操作,对于线程创建来说,默认是joinable线程,如果大家需要detached线程,则需要修改attr参数。

  创建SAMPLE_COMM_VDEC_SendStream线程后,其主要是实现了PT_MJPEG解码协议类型数据的帧头帧尾判别及数据发送,但是在线程中用了V4L2接口:

 1 ioctl(video_fd, VIDIOC_DQBUF, &readbuffer)  

出现了VIDIOC_DQBUF /capture data failed及Segmentation fault等等:

  Segmentation fault的原因很大程度上是数组的索引超界了,根据自己的程序修改相应的位置,我改的位置为:

1 pu8Buf = malloc(pic_size); //6144002 //pu8Buf = malloc(pstVdecThreadParam->s32MinBufSize);

  而关于VIDIOC_DQBUF fault,网上说可能是使用非阻塞方式打开设备文件造成的,即对应用程序进行一些非阻塞(non-blocking)操作(对文件或者socket),如果使用非阻塞模式调用视频设备,即使尚未捕获到信息,驱动依旧会把缓存(DQBUFF)里的东西返回给应用程序。例如,以O_NONBLOCK的标志打开文件/socket/FIFO,如果你连续做read操作而没有数据可读。此时程序不会阻塞起来等待数据准备就绪返回,read函数会返回一个error。

  因此open设备节点的时候(如open /dev/video*时),不建议用非阻塞形式打开,因为MJEPG格式时,每次去读取数据,底层数据不一定就绪了,因此会返回错误,串口会有茫茫多的错误打印。建议是阻塞方式打开,用select去监听所有的fd。

 1 /* According to POSIX.1-2001, POSIX.1-2008 */ 2  #include <sys/select.h> 3  4  /* According to earlier standards */ 5  #include <sys/time.h> 6  #include <sys/types.h> 7  #include <unistd.h> 8  9  int select(int nfds, fd_set *readfds, fd_set *writefds,10     fd_set *exceptfds, struct timeval *timeout);

  首先和大家说一下select监听的机制:用阻塞的方式去open设备节点,select去监听所有的fd;select函数用于在非阻塞中,当一个套接字或一组套接字有信号时通知你,系统提供select函数来实现多路复用输入/输出模型。select一旦发现监听的设备都不可用(不可读、也不可写、也没有异常),那么主进程进入休眠状态,一旦监听的设备中,只要有一个设备可用(可读或者可写或者有异常)都会唤醒休眠的主进程,select也就会返回。注意这个函数仅仅起到一个监听的功能,数据的后续处理,通过read,write,ioctl来进行的,本项目中测试实现:

 1  s_value = select(fdmax + 1, &fds, NULL, NULL, &tv); 2    3    if(s_value == -1) 4   { 5   if(EINTR == errno) 6    { 7    perror("select"); 8    continue;  9    } 10   SAMPLE_PRT("Fail to select\n");11   break;12   }13  if(s_value == 0)14   {15   SAMPLE_PRT("select Timeout\n");16   continue;17  }

 









原文转载:http://www.shaoqun.com/a/524578.html

跨境电商:https://www.ikjzd.com/

mymall:https://www.ikjzd.com/w/1050

贝恩投资公司:https://www.ikjzd.com/w/1336


最近一直加班加点进行基于Hi3559AV100平台的BOXER-8410AI板载开发,在开发的过程中,遇到了相当多的问题,其一是板载的开发资料没有且功能不完整,厂家不提供太多售后技术支持,厂家对部分硬件没有进行开发,如MIPI接口没有进行开发,且最基本的SDK版本包及环境搭建也需要自己去网上找且从头弄,好在之前有Hi3519A平台的开发经验,但还是遇到了很多问题;其二是网上相关H3559AV100
败欧洲:败欧洲
飞书互动:飞书互动
美国最高法院出手,电商销售税将全面来袭……:美国最高法院出手,电商销售税将全面来袭……
Email营销大补帖!扭转EDM营销撞墙期的特效药:Email营销大补帖!扭转EDM营销撞墙期的特效药
UPC,站外引流,差评处理,VAT与定价因素:UPC,站外引流,差评处理,VAT与定价因素

没有评论:

发表评论