Files
vision-anti-pinch/tests/v4l2_reopen_test.cpp

30 lines
1.7 KiB
C++

#include "v4l2_capture.h"
#include <linux/videodev2.h>
#include <sys/mman.h>
#include <cstdarg>
#include <cerrno>
#include <cstdlib>
#include <stdexcept>
#include <iostream>
static int mappings=0;static bool failSecondMap=false;
extern "C" {
int __wrap_open(char const*,int,...){return 50;}
int __wrap_close(int){return 0;}
void* __wrap_mmap(void*,size_t n,int,int,int,off_t){if(failSecondMap&&mappings==1){errno=ENOMEM;return MAP_FAILED;}++mappings;return std::malloc(n);}
int __wrap_munmap(void* p,size_t){if(!p||p==MAP_FAILED||mappings<1)std::abort();std::free(p);--mappings;return 0;}
int __wrap_ioctl(int,unsigned long req,...){
va_list args;va_start(args,req);void* p=va_arg(args,void*);va_end(args);
if(req==VIDIOC_QUERYCAP){*static_cast<v4l2_capability*>(p)={};static_cast<v4l2_capability*>(p)->capabilities=V4L2_CAP_VIDEO_CAPTURE|V4L2_CAP_STREAMING;return 0;}
if(req==VIDIOC_S_FMT){if(mappings){errno=EBUSY;return -1;}static_cast<v4l2_format*>(p)->fmt.pix.bytesperline=4;return 0;}
if(req==VIDIOC_QUERYBUF){static_cast<v4l2_buffer*>(p)->length=8;return 0;}
return 0;
}
}
static void check(bool b){if(!b)throw std::runtime_error("V4L2 reopen regression");}
int main()try{
V4l2Capture camera;
for(int i=0;i<3;++i){check(camera.open("/mock"));check(camera.setFormat(2,2,V4L2_PIX_FMT_UYVY));check(camera.initMmap(2));check(camera.startStreaming());camera.close();check(mappings==0);}
check(camera.open("/mock"));check(camera.setFormat(2,2,V4L2_PIX_FMT_UYVY));failSecondMap=true;check(!camera.initMmap(2));camera.close();check(mappings==0);
std::cout<<"PASS repeated reopen and partial mmap failure release every mapping\n";return 0;
}catch(std::exception const& e){std::cerr<<e.what()<<'\n';return 1;}