Commit 877df57d authored by Mikhail Karpenko's avatar Mikhail Karpenko

WIP: compile video interface without errors

parent b929b395
/** /**
* @file FILENAME * @file video.cpp
* @brief BRIEF DESCRIPTION * @brief Provides video interface for streamer
* @copyright Copyright (C) YEAR Elphel Inc. * @copyright Copyright (C) 2017 Elphel Inc.
* @author AUTHOR <EMAIL> * @author AUTHOR <EMAIL>
* *
* @par License: * @par License:
...@@ -28,19 +28,21 @@ ...@@ -28,19 +28,21 @@
#include <arpa/inet.h> #include <arpa/inet.h>
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <asm/elphel/c313a.h>
#include <iostream> #include <iostream>
#include <sstream>
#include <string>
#include <elphel/x393_devices.h>
#include "streamer.h" #include "streamer.h"
using namespace std; using namespace std;
#undef VIDEO_DEBUG //#undef VIDEO_DEBUG
#undef VIDEO_DEBUG_2 // for timestamp monitoring //#undef VIDEO_DEBUG_2 // for timestamp monitoring
#undef VIDEO_DEBUG_3 // for FPS monitoring //#undef VIDEO_DEBUG_3 // for FPS monitoring
//#define VIDEO_DEBUG #define VIDEO_DEBUG
//#define VIDEO_DEBUG_2 // for timestamp monitoring #define VIDEO_DEBUG_2 // for timestamp monitoring
//#define VIDEO_DEBUG_3 // for FPS monitoring #define VIDEO_DEBUG_3 // for FPS monitoring
#ifdef VIDEO_DEBUG #ifdef VIDEO_DEBUG
#define D(a) a #define D(a) a
...@@ -64,8 +66,8 @@ using namespace std; ...@@ -64,8 +66,8 @@ using namespace std;
#define QTABLES_INCLUDE #define QTABLES_INCLUDE
int fd_circbuf = 0; //int fd_circbuf = 0;
int fd_jpeghead = 0; /// to get quantization tables //int fd_jpeghead = 0; /// to get quantization tables
//int fd_fparmsall = 0; //int fd_fparmsall = 0;
int lastDaemonBit = DAEMON_BIT_STREAMER; int lastDaemonBit = DAEMON_BIT_STREAMER;
...@@ -73,37 +75,66 @@ int lastDaemonBit = DAEMON_BIT_STREAMER; ...@@ -73,37 +75,66 @@ int lastDaemonBit = DAEMON_BIT_STREAMER;
//struct framepars_t *framePars; //struct framepars_t *framePars;
//unsigned long *globalPars; /// parameters that are not frame-related, their changes do not initiate any actions //unsigned long *globalPars; /// parameters that are not frame-related, their changes do not initiate any actions
Video::Video(void) { static const char *circbuf_file_names[] = {
D( cerr << "Video::Video()" << endl;) DEV393_PATH(DEV393_CIRCBUF0), DEV393_PATH(DEV393_CIRCBUF1),
D( cerr << __FILE__<< ":"<< __FUNCTION__ << ":" <<__LINE__ << endl;) DEV393_PATH(DEV393_CIRCBUF2), DEV393_PATH(DEV393_CIRCBUF3)
};
static const char *jhead_file_names[] = {
DEV393_PATH(DEV393_JPEGHEAD0), DEV393_PATH(DEV393_JPEGHEAD1),
DEV393_PATH(DEV393_JPEGHEAD2), DEV393_PATH(DEV393_JPEGHEAD3)
};
Video::Video(int port, Parameters *pars) {
string err_msg;
D( cerr << "Video::Video() on port " << port << endl;)
D( cerr << __FILE__<< ":"<< __FUNCTION__ << ":" <<__LINE__ << endl;)
params = pars;
sensor_port = port;
stream_name = "video"; stream_name = "video";
params = Parameters::instance(); // params = Parameters::instance();
waitDaemonEnabled(-1); /// <0 - use default waitDaemonEnabled(-1); /// <0 - use default
fd_circbuf = open("/dev/circbuf", O_RDONLY); fd_circbuf = open(circbuf_file_names[sensor_port], O_RDONLY);
if(fd_circbuf < 0) if (fd_circbuf < 0) {
throw("can't open /dev/circbuf"); err_msg = "can't open " + static_cast<ostringstream &>(ostringstream() << dec << sensor_port).str();
throw runtime_error(err_msg);
}
buffer_length = lseek(fd_circbuf, 0, SEEK_END); buffer_length = lseek(fd_circbuf, 0, SEEK_END);
/// mmap for all the lifetime of the program, not per stream. AF /// mmap for all the lifetime of the program, not per stream. AF
buffer_ptr = (unsigned long *)mmap(0, buffer_length, PROT_READ, MAP_SHARED, fd_circbuf, 0); buffer_ptr = (unsigned long *) mmap(0, buffer_length, PROT_READ, MAP_SHARED, fd_circbuf, 0);
if((int)buffer_ptr == -1) if ((int) buffer_ptr == -1) {
throw("Error in mmap /dev/circbuf"); err_msg = "can't mmap " + *circbuf_file_names[sensor_port];
buffer_ptr_s = (unsigned long *)mmap(buffer_ptr + (buffer_length >>2 ), buffer_length, PROT_READ, MAP_FIXED | MAP_SHARED, fd_circbuf, 0); /// preventing buffer rollovers throw runtime_error(err_msg);
if((int)buffer_ptr_s == -1) }
throw("Error in second mmap /dev/circbuf"); cout << "<-- 1" << endl;
// buffer_ptr_s = (unsigned long *) mmap(buffer_ptr + (buffer_length >> 2), buffer_length,
// PROT_READ, MAP_FIXED | MAP_SHARED, fd_circbuf, 0); /// preventing buffer rollovers
buffer_ptr_s = (unsigned long *) mmap(buffer_ptr + (buffer_length >> 2), 100 * 4096,
PROT_READ, MAP_FIXED | MAP_SHARED, fd_circbuf, 0); /// preventing buffer rollovers
cout << "<-- 2" << endl;
if ((int) buffer_ptr_s == -1) {
err_msg = "can't create second mmap for " + *circbuf_file_names[sensor_port];
throw runtime_error(err_msg);
}
cout << "<-- 3" << endl;
/// Skip several frames if it is just booted /// Skip several frames if it is just booted
/// May get stuck here if compressor is off, it should be enabled externally /// May get stuck here if compressor is off, it should be enabled externally
D( cerr << __FILE__<< ":"<< __FUNCTION__ << ":" <<__LINE__ << " frame=" << params->getGPValue(G_THIS_FRAME) << " buffer_length=" << buffer_length << endl;) D( cerr << __FILE__<< ":"<< __FUNCTION__ << ":" <<__LINE__ << " frame=" << params->getGPValue(G_THIS_FRAME) << " buffer_length=" << buffer_length << endl;)
while(params->getGPValue(G_THIS_FRAME) < 10) { while (params->getGPValue(G_THIS_FRAME) < 10) {
lseek(fd_circbuf, LSEEK_CIRC_TOWP, SEEK_END); /// get to the end of buffer lseek(fd_circbuf, LSEEK_CIRC_TOWP, SEEK_END); /// get to the end of buffer
lseek(fd_circbuf, LSEEK_CIRC_WAIT, SEEK_END); /// wait frame got ready there lseek(fd_circbuf, LSEEK_CIRC_WAIT, SEEK_END); /// wait frame got ready there
} }
/// One more wait always to make sure compressor is actually running /// One more wait always to make sure compressor is actually running
lseek(fd_circbuf, LSEEK_CIRC_WAIT, SEEK_END); lseek(fd_circbuf, LSEEK_CIRC_WAIT, SEEK_END);
lseek(fd_circbuf, LSEEK_CIRC_WAIT, SEEK_END); lseek(fd_circbuf, LSEEK_CIRC_WAIT, SEEK_END);
D(cerr << __FILE__<< ":"<< __FUNCTION__ << ":" <<__LINE__ << " frame=" << params->getGPValue(G_THIS_FRAME) << " buffer_length=" << buffer_length <<endl;) D(cerr << __FILE__<< ":"<< __FUNCTION__ << ":" <<__LINE__ << " frame=" << params->getGPValue(G_THIS_FRAME) << " buffer_length=" << buffer_length <<endl;)
fd_jpeghead = open("/dev/jpeghead", O_RDWR); fd_jpeghead = open(jhead_file_names[sensor_port], O_RDWR);
if(fd_jpeghead < 0) if (fd_jpeghead < 0) {
throw("can't open /dev/jpeghead"); err_msg = "can't open " + *jhead_file_names[sensor_port];
throw runtime_error(err_msg);
}
qtables_include = true; qtables_include = true;
SSRC = 12; SSRC = 12;
...@@ -112,19 +143,26 @@ D( cerr << __FILE__<< ":"<< __FUNCTION__ << ":" <<__LINE__ << " frame=" << para ...@@ -112,19 +143,26 @@ D( cerr << __FILE__<< ":"<< __FUNCTION__ << ":" <<__LINE__ << " frame=" << para
rtcp_socket = NULL; rtcp_socket = NULL;
_play = false; _play = false;
prev_jpeg_wp = 0; prev_jpeg_wp = 0;
// buffer_length = 0;
f_quality = -1; f_quality = -1;
// create thread... // create thread...
init_pthread((void *)this); init_pthread((void *) this);
D( cerr << __FILE__<< ":" << __FUNCTION__ << ":" << __LINE__ << endl;) D( cerr << __FILE__<< ":" << __FUNCTION__ << ":" << __LINE__ << endl;)
} }
Video::~Video(void) { Video::~Video(void) {
cerr << "Video::~Video()" << endl; cerr << "Video::~Video() on port " << sensor_port << endl;
if(fd_circbuf > 0) if (buffer_ptr != NULL) {
munmap(buffer_ptr, buffer_length);
buffer_ptr = NULL;
}
if (buffer_ptr_s != NULL) {
munmap(buffer_ptr_s, buffer_length);
buffer_ptr_s = NULL;
}
if (fd_circbuf > 0)
close(fd_circbuf); close(fd_circbuf);
if(fd_jpeghead > 0) if (fd_jpeghead > 0)
close(fd_jpeghead); close(fd_jpeghead);
} }
...@@ -183,16 +221,16 @@ void Video::Stop(void) { ...@@ -183,16 +221,16 @@ void Video::Stop(void) {
* @return (after possible waiting) true if there was no waiting, false if there was waiting * @return (after possible waiting) true if there was no waiting, false if there was waiting
*/ */
bool Video::waitDaemonEnabled(int daemonBit) { // <0 - use default bool Video::waitDaemonEnabled(int daemonBit) { // <0 - use default
if((daemonBit >= 0) && (daemonBit < 32)) if ((daemonBit >= 0) && (daemonBit < 32))
lastDaemonBit = daemonBit; lastDaemonBit = daemonBit;
unsigned long this_frame = params->getGPValue(G_THIS_FRAME); unsigned long this_frame = params->getGPValue(G_THIS_FRAME);
/// No semaphors, so it is possible to miss event and wait until the streamer will be re-enabled before sending message, /// No semaphors, so it is possible to miss event and wait until the streamer will be re-enabled before sending message,
/// but it seems not so terrible /// but it seems not so terrible
D(cerr << " lseek(fd_circbuf, LSEEK_DAEMON_CIRCBUF+lastDaemonBit, SEEK_END)... " << endl;) D(cerr << " lseek(fd_circbuf" << fd_circbuf << ", LSEEK_DAEMON_CIRCBUF+lastDaemonBit, SEEK_END)... " << endl;)
lseek(fd_circbuf, LSEEK_DAEMON_CIRCBUF + lastDaemonBit, SEEK_END); /// lseek(fd_circbuf, LSEEK_DAEMON_CIRCBUF + lastDaemonBit, SEEK_END); ///
D(cerr << "...done" << endl;) D(cerr << "...done" << endl;)
if(this_frame == params->getGPValue(G_THIS_FRAME)) if (this_frame == params->getGPValue(G_THIS_FRAME))
return true; return true;
return false; return false;
} }
...@@ -322,8 +360,6 @@ D3(cerr << "delta == " << _f << endl << endl;) ...@@ -322,8 +360,6 @@ D3(cerr << "delta == " << _f << endl << endl;)
return video_desc; return video_desc;
} }
//#define FRAMES_AHEAD_FPS 3 /// number of frames ahead of current to frite FPS limit
//#define FRAMES_SKIP_FPS 3 /// number of frames to wait after target so circbuf will have at least 2 frames with new fps for calculation
void Video::fps(float fps) { void Video::fps(float fps) {
if(fps < 0.01) if(fps < 0.01)
return; return;
......
/** /**
* @file FILENAME * @file video.h
* @brief BRIEF DESCRIPTION * @brief Provides video interface for streamer
* @copyright Copyright (C) YEAR Elphel Inc. * @copyright Copyright (C) 2017 Elphel Inc.
* @author AUTHOR <EMAIL> * @author AUTHOR <EMAIL>
* *
* @par License: * @par License:
...@@ -28,10 +28,8 @@ ...@@ -28,10 +28,8 @@
using namespace std; using namespace std;
#include <asm/elphel/c313a.h> #define FRAMES_AHEAD_FPS 3 /// number of frames ahead of current to write FPS limit
#define FRAMES_SKIP_FPS 3 /// number of frames to wait after target so circbuf will have at least 2 frames with new FPS for calculation
#define FRAMES_AHEAD_FPS 3 /// number of frames ahead of current to frite FPS limit
#define FRAMES_SKIP_FPS 3 /// number of frames to wait after target so circbuf will have at least 2 frames with new fps for calculation
/// structure to store current video description /// structure to store current video description
struct video_desc_t { struct video_desc_t {
...@@ -51,7 +49,7 @@ public: ...@@ -51,7 +49,7 @@ public:
SIZE_CHANGE SIZE_CHANGE
}; };
Video(void); Video(int port, Parameters *pars);
virtual ~Video(void); virtual ~Video(void);
/// return description of the current frame - i.e. current video parameters /// return description of the current frame - i.e. current video parameters
...@@ -81,6 +79,8 @@ protected: ...@@ -81,6 +79,8 @@ protected:
unsigned long *buffer_ptr; unsigned long *buffer_ptr;
unsigned long *buffer_ptr_s; /// Second copy of the circbuf just after the end of the first to prevent rollovers unsigned long *buffer_ptr_s; /// Second copy of the circbuf just after the end of the first to prevent rollovers
void *frame_ptr; void *frame_ptr;
int fd_circbuf;
int fd_jpeghead;
long capture(void); long capture(void);
// bool process(void); // bool process(void);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment