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

WIP: compile video interface without errors

parent b929b395
Loading
Loading
Loading
Loading
+83 −47
Original line number Diff line number Diff line
/**
 * @file FILENAME
 * @brief BRIEF DESCRIPTION
 * @copyright Copyright (C) YEAR Elphel Inc.
 * @file video.cpp
 * @brief Provides video interface for streamer
 * @copyright Copyright (C) 2017 Elphel Inc.
 * @author AUTHOR <EMAIL>
 *
 * @par License:
@@ -28,19 +28,21 @@
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>

#include <asm/elphel/c313a.h>

#include <iostream>
#include <sstream>
#include <string>
#include <elphel/x393_devices.h>

#include "streamer.h"

using namespace std;

#undef VIDEO_DEBUG
#undef VIDEO_DEBUG_2	// for timestamp monitoring
#undef VIDEO_DEBUG_3	// for FPS monitoring
//#define VIDEO_DEBUG
//#define VIDEO_DEBUG_2	// for timestamp monitoring
//#define VIDEO_DEBUG_3	// for FPS monitoring
//#undef VIDEO_DEBUG
//#undef VIDEO_DEBUG_2	// for timestamp monitoring
//#undef VIDEO_DEBUG_3	// for FPS monitoring
#define VIDEO_DEBUG
#define VIDEO_DEBUG_2	// for timestamp monitoring
#define VIDEO_DEBUG_3	// for FPS monitoring

#ifdef VIDEO_DEBUG
	#define D(a) a
@@ -64,8 +66,8 @@ using namespace std;

#define QTABLES_INCLUDE

int fd_circbuf = 0;
int fd_jpeghead = 0; /// to get quantization tables
//int fd_circbuf = 0;
//int fd_jpeghead = 0; /// to get quantization tables
//int fd_fparmsall = 0;
int lastDaemonBit = DAEMON_BIT_STREAMER;

@@ -73,23 +75,50 @@ int lastDaemonBit = DAEMON_BIT_STREAMER;
//struct framepars_t       *framePars;
//unsigned long            *globalPars; /// parameters that are not frame-related, their changes do not initiate any actions

Video::Video(void) {
D(	cerr << "Video::Video()" << endl;)
static const char *circbuf_file_names[] = {
		DEV393_PATH(DEV393_CIRCBUF0), DEV393_PATH(DEV393_CIRCBUF1),
		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";
	params = Parameters::instance();
//	params = Parameters::instance();
	waitDaemonEnabled(-1); /// <0 - use default
	fd_circbuf = open("/dev/circbuf", O_RDONLY);
	if(fd_circbuf < 0)
		throw("can't open /dev/circbuf");
	fd_circbuf = open(circbuf_file_names[sensor_port], O_RDONLY);
	if (fd_circbuf < 0) {
		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);
	/// 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);
	if((int)buffer_ptr == -1)
		throw("Error in mmap /dev/circbuf");
	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
	if((int)buffer_ptr_s == -1)
		throw("Error in second mmap /dev/circbuf");
	if ((int) buffer_ptr == -1) {
		err_msg = "can't mmap " + *circbuf_file_names[sensor_port];
		throw runtime_error(err_msg);
	}
	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
	/// 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;)
@@ -101,9 +130,11 @@ D( cerr << __FILE__<< ":"<< __FUNCTION__ << ":" <<__LINE__ << " frame=" << para
	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;)
	fd_jpeghead = open("/dev/jpeghead", O_RDWR);
	if(fd_jpeghead < 0)
		throw("can't open /dev/jpeghead");
	fd_jpeghead = open(jhead_file_names[sensor_port], O_RDWR);
	if (fd_jpeghead < 0) {
		err_msg = "can't open " + *jhead_file_names[sensor_port];
		throw runtime_error(err_msg);
	}
	qtables_include = true;

	SSRC = 12;
@@ -112,7 +143,6 @@ D( cerr << __FILE__<< ":"<< __FUNCTION__ << ":" <<__LINE__ << " frame=" << para
	rtcp_socket = NULL;
	_play = false;
	prev_jpeg_wp = 0;
//	buffer_length = 0;
	f_quality = -1;

	// create thread...
@@ -121,7 +151,15 @@ D( cerr << __FILE__<< ":" << __FUNCTION__ << ":" << __LINE__ << endl;)
}

Video::~Video(void) {
cerr << "Video::~Video()" << endl;
	cerr << "Video::~Video() on port " << sensor_port << endl;
	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);
	if (fd_jpeghead > 0)
@@ -188,7 +226,7 @@ bool Video::waitDaemonEnabled(int daemonBit) { // <0 - use default
	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,
/// 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); /// 
	D(cerr << "...done" << endl;)

@@ -322,8 +360,6 @@ D3(cerr << "delta == " << _f << endl << endl;)
	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) {
	if(fps < 0.01)
		return;
+8 −8
Original line number Diff line number Diff line
/**
 * @file FILENAME
 * @brief BRIEF DESCRIPTION
 * @copyright Copyright (C) YEAR Elphel Inc.
 * @file video.h
 * @brief Provides video interface for streamer
 * @copyright Copyright (C) 2017 Elphel Inc.
 * @author AUTHOR <EMAIL>
 *
 * @par License:
@@ -28,10 +28,8 @@

using namespace std;

#include <asm/elphel/c313a.h>

#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
#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

/// structure to store current video description
struct video_desc_t {
@@ -51,7 +49,7 @@ public:
		SIZE_CHANGE
	};

	Video(void);
	Video(int port, Parameters *pars);

	virtual ~Video(void);
	/// return description of the current frame - i.e. current video parameters
@@ -81,6 +79,8 @@ protected:
	unsigned long *buffer_ptr;
	unsigned long *buffer_ptr_s;  /// Second copy of the circbuf just after the end of the first to prevent rollovers
	void *frame_ptr;
	int fd_circbuf;
	int fd_jpeghead;

	long capture(void);
//	bool process(void);