30 lines
1.7 KiB
C++
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;}
|