Skip to content

Commit

Permalink
Video mode working
Browse files Browse the repository at this point in the history
  • Loading branch information
Barna Keresztes committed Dec 17, 2021
1 parent 41ebcc0 commit 8b0b5bd
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 85 deletions.
18 changes: 12 additions & 6 deletions example/takephoto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,20 @@ int main()
{
cv::Mat image;
lccv::PiCamera cam;
cam.options->width=4056;
cam.options->height=3040;
//cam.options->width=4056;
//cam.options->height=3040;
cam.options->photo_width=2028;
cam.options->photo_height=1520;
cam.options->verbose=true;
if(!cam.captureFrame(image)){
std::cout<<"Camera error"<<std::endl;
}
cv::namedWindow("Image",cv::WINDOW_NORMAL);
cv::imshow("Image",image);
for(int i=0;i<100;i++){
std::cout<<i<<std::endl;
if(!cam.capturePhoto(image)){
std::cout<<"Camera error"<<std::endl;
}
cv::imshow("Image",image);
cv::waitKey(30);
}
cv::waitKey();
cv::destroyWindow("Image");
}
28 changes: 28 additions & 0 deletions example/takevideo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include <lccv.hpp>
#include <opencv2/opencv.hpp>

int main()
{
std::cout<<"Sample program for LCCV video capture"<<std::endl;
std::cout<<"Press ESC to stop."<<std::endl;
cv::Mat image;
lccv::PiCamera cam;
cam.options->video_width=1024;
cam.options->video_height=768;
cam.options->framerate=5;
cam.options->verbose=true;
cv::namedWindow("Video",cv::WINDOW_NORMAL);
cam.startVideo();
int ch=0;
while(ch!=27){
if(!cam.getVideoFrame(image,1000)){
std::cout<<"Camera error"<<std::endl;
}
else{
cv::imshow("Video",image);
ch=cv::waitKey(10);
}
}
cam.stopVideo();
cv::destroyWindow("Video");
}
10 changes: 5 additions & 5 deletions include/lccv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,16 @@ class PiCamera {

protected:
void run();
private:
protected:
LibcameraApp *app;
void getImage(cv::Mat &frame, CompletedRequestPtr &payload);
static void *videoThreadFunc(void *p);
pthread_t videothread;
unsigned int still_flags;
static unsigned int vw,vh,vstr;
static std::atomic<bool> running,frameready;
static uint8_t *framebuffer;
static std::mutex mtx;
unsigned int vw,vh,vstr;
std::atomic<bool> running,frameready;
uint8_t *framebuffer;
std::mutex mtx;
};

}
Expand Down
2 changes: 1 addition & 1 deletion include/libcamera_app.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ class LibcameraApp
void CloseCamera();

void ConfigureStill(unsigned int flags = FLAG_STILL_NONE);
void ConfigureVideo(unsigned int flags = FLAG_VIDEO_NONE);
void ConfigureViewfinder();

void Teardown();
void StartCamera();
Expand Down
68 changes: 32 additions & 36 deletions src/lccv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ PiCamera::PiCamera()
options->photo_height = 3040;
options->video_width = 640;
options->video_height = 480;
options->framerate = 30;
options->denoise = "auto";
options->timeout = 1000;
options->setMetering(Metering_Modes::METERING_MATRIX);
Expand Down Expand Up @@ -47,7 +48,6 @@ void PiCamera::getImage(cv::Mat &frame, CompletedRequestPtr &payload)
}
}


bool PiCamera::capturePhoto(cv::Mat &frame)
{
app->OpenCamera();
Expand Down Expand Up @@ -82,10 +82,10 @@ bool PiCamera::startVideo()
}
frameready.store(false, std::memory_order_release);
app->OpenCamera();
app->ConfigureVideo();
app->ConfigureViewfinder();
app->StartCamera();
libcamera::Stream *stream = app->VideoStream(&vw,&vh,&vstr);
bool ret = pthread_create(&videothread, NULL, &videoThreadFunc, stream);

bool ret = pthread_create(&videothread, NULL, &videoThreadFunc, this);
if (ret != 0) {
std::cerr<<"Error starting video thread";
return false;
Expand Down Expand Up @@ -140,42 +140,38 @@ bool PiCamera::getVideoFrame(cv::Mat &frame, unsigned int timeout)

void *PiCamera::videoThreadFunc(void *p)
{
running.store(true, std::memory_order_release);

PiCamera *t = (PiCamera *)p;
t->running.store(true, std::memory_order_release);
//allocate framebuffer
//libcamera::Stream *stream = (libcamera::Stream *)p;
(void)p;
int buffersize=vh*vstr;
if(framebuffer)delete[] framebuffer;
framebuffer=new uint8_t[buffersize];
const std::vector<libcamera::Span<uint8_t>> mem;
//unsigned int vw,vh,vstr;
libcamera::Stream *stream = t->app->ViewfinderStream(&t->vw,&t->vh,&t->vstr);
int buffersize=t->vh*t->vstr;
if(t->framebuffer)delete[] t->framebuffer;
std::cout<<"Allocating buffer"<<buffersize<<" ("<<t->vh<<"x"<<t->vstr<<")"<<std::endl;
t->framebuffer=new uint8_t[buffersize];
std::vector<libcamera::Span<uint8_t>> mem;

//main loop
while(running.load(std::memory_order_acquire)){
//grab buffer ***
mtx.lock();
memcpy(framebuffer,mem[0].data(),buffersize);
mtx.unlock();
frameready.store(true, std::memory_order_release);
while(t->running.load(std::memory_order_acquire)){
LibcameraApp::Msg msg = t->app->Wait();
if (msg.type == LibcameraApp::MsgType::Quit){
std::cerr<<"Quit message received"<<std::endl;
t->running.store(false,std::memory_order_release);
}
else if (msg.type != LibcameraApp::MsgType::RequestComplete)
throw std::runtime_error("unrecognised message!");


CompletedRequestPtr payload = std::get<CompletedRequestPtr>(msg.payload);
mem = t->app->Mmap(payload->buffers[stream]);
t->mtx.lock();
memcpy(t->framebuffer,mem[0].data(),buffersize);
t->mtx.unlock();
t->frameready.store(true, std::memory_order_release);
}
if(framebuffer){
delete[] framebuffer;
framebuffer=nullptr;
if(t->framebuffer){
delete[] t->framebuffer;
t->framebuffer=nullptr;
}
return NULL;
}
/*void PiCamera::videoThread()
{
cv::Mat frame;
while(GoOn){
LibcameraApp::Msg msg = app->Wait();
if (msg.type == LibcameraApp::MsgType::Quit)
GoOn=false;
else if (msg.type != LibcameraApp::MsgType::RequestComplete)
throw std::runtime_error("unrecognised message!");
getVideoFrame(frame,std::get<CompletedRequestPtr>(msg.payload));
}
app->StopCamera();
app->CloseCamera();
}*/
54 changes: 17 additions & 37 deletions src/libcamera_app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,51 +124,31 @@ void LibcameraApp::ConfigureStill(unsigned int flags)
std::cerr << "Still capture setup complete" << std::endl;
}

void LibcameraApp::ConfigureVideo(unsigned int flags)
void LibcameraApp::ConfigureViewfinder()
{
if (options_->verbose)
std::cerr << "Configuring video..." << std::endl;
if (options_->verbose)
std::cerr << "Configuring viewfinder..." << std::endl;

bool have_raw_stream = flags & FLAG_VIDEO_RAW;
StreamRoles stream_roles = { StreamRole::VideoRecording };
if (have_raw_stream)
{
stream_roles.push_back(StreamRole::Raw);
}
configuration_ = camera_->generateConfiguration(stream_roles);
if (!configuration_)
throw std::runtime_error("failed to generate video configuration");
StreamRoles stream_roles = { StreamRole::Viewfinder };
configuration_ = camera_->generateConfiguration(stream_roles);
if (!configuration_)
throw std::runtime_error("failed to generate viewfinder configuration");

// Now we get to override any of the default settings from the options_->
configuration_->at(0).pixelFormat = libcamera::formats::YUV420;
configuration_->at(0).bufferCount = 6; // 6 buffers is better than 4
if (options_->video_width)
configuration_->at(0).size.width = options_->video_width;
if (options_->video_height)
configuration_->at(0).size.height = options_->video_height;
// Now we get to override any of the default settings from the options_->
configuration_->at(0).pixelFormat = libcamera::formats::RGB888;
configuration_->at(0).size.width = options_->video_width;
configuration_->at(0).size.height = options_->video_height;
configuration_->at(0).bufferCount = 4;

configuration_->transform = options_->transform;

if (have_raw_stream)
{
if (!options_->rawfull)
{
configuration_->at(1).size.width = configuration_->at(0).size.width;
configuration_->at(1).size.height = configuration_->at(0).size.height;
}
configuration_->at(1).bufferCount = configuration_->at(0).bufferCount;
}
configuration_->transform = options_->transform;

configureDenoise(options_->denoise == "auto" ? "cdn_fast" : options_->denoise);
setupCapture();
configureDenoise(options_->denoise == "auto" ? "cdn_off" : options_->denoise);
setupCapture();

streams_["video"] = configuration_->at(0).stream();
if (have_raw_stream)
streams_["raw"] = configuration_->at(1).stream();
streams_["viewfinder"] = configuration_->at(0).stream();

if (options_->verbose)
std::cerr << "Video setup complete" << std::endl;
if (options_->verbose)
std::cerr << "Viewfinder setup complete" << std::endl;
}

void LibcameraApp::Teardown()
Expand Down

0 comments on commit 8b0b5bd

Please sign in to comment.