Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
E
elphel-apps-astreamer
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Elphel
elphel-apps-astreamer
Commits
877df57d
Commit
877df57d
authored
Feb 21, 2017
by
Mikhail Karpenko
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
WIP: compile video interface without errors
parent
b929b395
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
91 additions
and
55 deletions
+91
-55
video.cpp
src/video.cpp
+83
-47
video.h
src/video.h
+8
-8
No files found.
src/video.cpp
View file @
877df57d
/**
* @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,37 +75,66 @@ 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
;)
D
(
cerr
<<
__FILE__
<<
":"
<<
__FUNCTION__
<<
":"
<<
__LINE__
<<
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"
);
buffer_ptr
=
(
unsigned
long
*
)
mmap
(
0
,
buffer_length
,
PROT_READ
,
MAP_SHARED
,
fd_circbuf
,
0
);
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
;)
while
(
params
->
getGPValue
(
G_THIS_FRAME
)
<
10
)
{
D
(
cerr
<<
__FILE__
<<
":"
<<
__FUNCTION__
<<
":"
<<
__LINE__
<<
" frame="
<<
params
->
getGPValue
(
G_THIS_FRAME
)
<<
" buffer_length="
<<
buffer_length
<<
endl
;)
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_WAIT
,
SEEK_END
);
/// wait frame got ready there
}
/// 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
);
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"
);
D
(
cerr
<<
__FILE__
<<
":"
<<
__FUNCTION__
<<
":"
<<
__LINE__
<<
" frame="
<<
params
->
getGPValue
(
G_THIS_FRAME
)
<<
" buffer_length="
<<
buffer_length
<<
endl
;)
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,19 +143,26 @@ D( cerr << __FILE__<< ":"<< __FUNCTION__ << ":" <<__LINE__ << " frame=" << para
rtcp_socket
=
NULL
;
_play
=
false
;
prev_jpeg_wp
=
0
;
// buffer_length = 0;
f_quality
=
-
1
;
// create thread...
init_pthread
((
void
*
)
this
);
D
(
cerr
<<
__FILE__
<<
":"
<<
__FUNCTION__
<<
":"
<<
__LINE__
<<
endl
;)
init_pthread
((
void
*
)
this
);
D
(
cerr
<<
__FILE__
<<
":"
<<
__FUNCTION__
<<
":"
<<
__LINE__
<<
endl
;)
}
Video
::~
Video
(
void
)
{
cerr
<<
"Video::~Video()"
<<
endl
;
if
(
fd_circbuf
>
0
)
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
)
if
(
fd_jpeghead
>
0
)
close
(
fd_jpeghead
);
}
...
...
@@ -183,16 +221,16 @@ void Video::Stop(void) {
* @return (after possible waiting) true if there was no waiting, false if there was waiting
*/
bool
Video
::
waitDaemonEnabled
(
int
daemonBit
)
{
// <0 - use default
if
((
daemonBit
>=
0
)
&&
(
daemonBit
<
32
))
if
((
daemonBit
>=
0
)
&&
(
daemonBit
<
32
))
lastDaemonBit
=
daemonBit
;
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
;)
if
(
this_frame
==
params
->
getGPValue
(
G_THIS_FRAME
))
D
(
cerr
<<
"...done"
<<
endl
;)
if
(
this_frame
==
params
->
getGPValue
(
G_THIS_FRAME
))
return
true
;
return
false
;
}
...
...
@@ -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
;
...
...
src/video.h
View file @
877df57d
/**
* @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);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment