Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
GStreamer_audioRecorder
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
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
m3
GStreamer_audioRecorder
Commits
a187cafe
Commit
a187cafe
authored
Oct 09, 2017
by
d.basulto
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
change the way that the bytes to add is calculated
parent
262b856b
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
142 additions
and
185 deletions
+142
-185
StreamRecorder.cpp
StreamRecorder.cpp
+92
-142
StreamRecorder.h
StreamRecorder.h
+50
-43
No files found.
StreamRecorder.cpp
View file @
a187cafe
...
...
@@ -17,6 +17,8 @@
#include <glib.h>
#include <unistd.h>
#include <cstring>
#include <cstdint>
#include <cstdio>
#include "FLAC/metadata.h"
#include "FLAC/stream_encoder.h"
...
...
@@ -43,6 +45,8 @@ StreamRecorder::StreamRecorder(const char* source, int time)
bufferSize
=
nFrames
*
READSIZE
*
STREAMRECORDER_BYTESPERSAMPLE
;
audioBuffer
=
new
unsigned
char
[
bufferSize
];
bytesPerSecond
=
bufferSize
/
audioFileDuration
;
// New buffer
memset
(
audioBuffer
,
0
,
bufferSize
);
audioBufferPosition
=
audioBuffer
;
...
...
@@ -64,7 +68,7 @@ int StreamRecorder::connect()
{
disconnect
();
cout
<<
"connecting to "
<<
pluginUri
<<
endl
;
cout
<<
"connecting to "
<<
pluginUri
<<
"..."
<<
endl
;
gst_element_set_state
(
mainPipeline
,
GST_STATE_NULL
);
gst_element_set_state
(
mainPipeline
,
GST_STATE_READY
);
...
...
@@ -151,7 +155,7 @@ int StreamRecorder::createMainPipeline()
*/
gboolean
StreamRecorder
::
reconnectURIStream
(
void
*
instance
)
{
cout
<<
"
\n
Trying to reconnect with the stream..."
<<
endl
<<
endl
;
cout
<<
"Trying to reconnect with the stream..."
<<
endl
<<
endl
;
((
StreamRecorder
*
)
instance
)
->
connect
();
return
FALSE
;
...
...
@@ -170,160 +174,70 @@ gboolean StreamRecorder::reconnectURIStream(void* instance)
int
StreamRecorder
::
bus_callback
(
GstBus
*
bus
,
GstMessage
*
message
,
void
*
user_data
)
{
//printf("StreamRecorder got %s message\n", GST_MESSAGE_TYPE_NAME (message));
if
(
GST_MESSAGE_TYPE
(
message
)
==
GST_MESSAGE_EOS
)
{
((
StreamRecorder
*
)
user_data
)
->
isConnectionLost
=
true
;
}
switch
(
GST_MESSAGE_TYPE
(
message
))
{
case
GST_MESSAGE_EOS
:
cout
<<
"** End of stream **
\n
"
<<
endl
;
cout
<<
"** End of stream **
"
<<
endl
<<
endl
;
if
(((
StreamRecorder
*
)
user_data
)
->
isConnectionLost
)
//Enter only if the connection is lost
{
// ----------------------------------------------------------------------------------------
long
int
actualRecordTime
;
long
int
currentTime
=
time
(
NULL
);
long
int
addTime
;
long
int
bytesToAdd
;
//cout << "Audio start time (timestamp): " << ((StreamRecorder*)user_data)->timestamp << endl;
//cout << "Actual time (timestamp): " << currentTime << endl;
actualRecordTime
=
currentTime
-
((
StreamRecorder
*
)
user_data
)
->
timestamp
;
cout
<<
"Record time: "
<<
actualRecordTime
<<
endl
;
// ----------------------------------------------------------------------------------------
/** The calculated record time is greater? */
if
(
actualRecordTime
>=
((
StreamRecorder
*
)
user_data
)
->
audioFileDuration
)
{
cout
<<
"Bytes readed: "
<<
((
StreamRecorder
*
)
user_data
)
->
nBytes
<<
endl
;
saveBuffer
(
user_data
);
}
else
{
/** Moves the pointer to the position corresponding to the difference of the timestamps */
addTime
=
currentTime
-
((
StreamRecorder
*
)
user_data
)
->
oldTmpTimestamp
;
cout
<<
"Time to add: "
<<
addTime
<<
endl
;
bytesToAdd
=
addTime
*
READSIZE
*
STREAMRECORDER_BYTESPERSAMPLE
*
10
;
cout
<<
"-------------------------------------"
<<
endl
;
cout
<<
"Actual Bytes number: "
<<
"("
<<
((
StreamRecorder
*
)
user_data
)
->
nBytes
<<
") + "
;
cout
<<
"Bytes t/add: "
<<
"("
<<
bytesToAdd
<<
")"
<<
endl
;
/** Update the pointer and the bytes number */
((
StreamRecorder
*
)
user_data
)
->
nBytes
+=
bytesToAdd
;
((
StreamRecorder
*
)
user_data
)
->
audioBufferPosition
+=
bytesToAdd
;
cout
<<
"Result : "
<<
((
StreamRecorder
*
)
user_data
)
->
nBytes
<<
endl
;
cout
<<
"Buffer size: "
<<
((
StreamRecorder
*
)
user_data
)
->
bufferSize
<<
endl
;
cout
<<
"-------------------------------------"
<<
endl
;
}
((
StreamRecorder
*
)
user_data
)
->
isConnectionLost
=
false
;
/** Try reconnect with the radio stream*/
g_timeout_add
(
RECONNECTION_DELAY
*
1000
,
reconnectURIStream
,
user_data
);
}
((
StreamRecorder
*
)
user_data
)
->
isDisconnected
=
true
;
break
;
case
GST_MESSAGE_ERROR
:
gchar
*
debug
;
GError
*
error
;
gchar
*
debug
;
gst_message_parse_error
(
message
,
&
error
,
&
debug
);
g_free
(
debug
);
strcpy
(((
StreamRecorder
*
)
user_data
)
->
errorMessage
,
error
->
message
);
/** The message doesn't contains null character*/
((
StreamRecorder
*
)
user_data
)
->
errorMessage
[
ERROR_MSG_SIZE
-
1
]
=
'\0'
;
//cerr << "Error: "<< ((StreamRecorder*)user_data)->errorMessage << endl;
g_error_free
(
error
);
cerr
<<
"Error - code: ("
<<
error
->
code
<<
") - Message:"
<<
error
->
message
<<
endl
;
if
(
strcmp
(((
StreamRecorder
*
)
user_data
)
->
errorMessage
,
"Stream doesn't contain enough data."
)
==
0
)
switch
(
error
->
code
)
{
/** Not audio stream received */
if
(((
StreamRecorder
*
)
user_data
)
->
timestamp
==
0
)
{
g_timeout_add
(
RECONNECTION_DELAY
*
1000
,
reconnectURIStream
,
user_data
);
}
else
{
// ----------------------------------------------------------------------------------------
long
int
actualRecordTime
;
long
int
currentTime
=
time
(
NULL
);
//long int addTime;
long
int
bytesToAdd
;
actualRecordTime
=
currentTime
-
((
StreamRecorder
*
)
user_data
)
->
timestamp
;
cout
<<
"Record time: "
<<
actualRecordTime
<<
endl
;
// ----------------------------------------------------------------------------------------
/** Record time is greater than th required */
if
(
actualRecordTime
>=
((
StreamRecorder
*
)
user_data
)
->
audioFileDuration
)
{
cout
<<
"Bytes readed: "
<<
((
StreamRecorder
*
)
user_data
)
->
nBytes
<<
endl
;
saveBuffer
(
user_data
);
}
else
{
/** Moves the pointer to the position corresponding to the difference of the timestamps */
//addTime = currentTime - ((StreamRecorder *) user_data)->oldTmpTimestamp;
cout
<<
"Time to add: "
<<
RECONNECTION_DELAY
<<
endl
;
bytesToAdd
=
RECONNECTION_DELAY
*
READSIZE
*
STREAMRECORDER_BYTESPERSAMPLE
*
10
;
cout
<<
"-------------------------------------"
<<
endl
;
cout
<<
"Actual Bytes number: "
<<
"("
<<
((
StreamRecorder
*
)
user_data
)
->
nBytes
<<
") + "
;
cout
<<
"Bytes t/add: "
<<
"("
<<
bytesToAdd
<<
")"
<<
endl
;
/** Update the pointer and the bytes number */
((
StreamRecorder
*
)
user_data
)
->
nBytes
+=
bytesToAdd
;
((
StreamRecorder
*
)
user_data
)
->
audioBufferPosition
+=
bytesToAdd
;
cout
<<
"Result : "
<<
((
StreamRecorder
*
)
user_data
)
->
nBytes
<<
endl
;
cout
<<
"Buffer size: "
<<
((
StreamRecorder
*
)
user_data
)
->
bufferSize
<<
endl
;
cout
<<
"-------------------------------------"
<<
endl
;
}
((
StreamRecorder
*
)
user_data
)
->
isConnectionLost
=
false
;
/** Try reconnect with the radio stream*/
g_timeout_add
(
RECONNECTION_DELAY
*
1000
,
reconnectURIStream
,
user_data
);
}
case
STREAM_ENOUGH_DATA_ERROR
:
/** Last message in errors secuence*/
((
StreamRecorder
*
)
user_data
)
->
isDisconnected
=
true
;
break
;
default
:
return
TRUE
;
}
g_error_free
(
error
);
break
;
default
:
break
;
return
TRUE
;
}
if
(((
StreamRecorder
*
)
user_data
)
->
isDisconnected
)
{
/** Try reconnect with the radio stream*/
cout
<<
"
\n
Reconnection started..."
<<
endl
;
g_timeout_add
(
RECONNECTION_DELAY
*
1000
,
reconnectURIStream
,
user_data
);
}
return
TRUE
;
}
//------------------------------------------------------------------------------
void
StreamRecorder
::
saveBuffer
(
void
*
user_data
)
{
int
missingBytes
=
((
StreamRecorder
*
)
user_data
)
->
bufferSize
-
((
StreamRecorder
*
)
user_data
)
->
nBytes
;
//((StreamRecorder*)user_data)->audioBufferPosition+=missingBytes;
((
StreamRecorder
*
)
user_data
)
->
nBytes
+=
missingBytes
;
((
StreamRecorder
*
)
user_data
)
->
compressBuffer
();
((
StreamRecorder
*
)
user_data
)
->
audioBufferPosition
=
((
StreamRecorder
*
)
user_data
)
->
audioBuffer
;
memset
(((
StreamRecorder
*
)
user_data
)
->
audioBuffer
,
0
,
((
StreamRecorder
*
)
user_data
)
->
bufferSize
);
((
StreamRecorder
*
)
user_data
)
->
nBytes
=
0
;
/**
* Do all the buffer saving and restart operations
*/
void
StreamRecorder
::
saveBuffer
()
{
compressBuffer
();
audioBufferPosition
=
audioBuffer
;
memset
(
audioBuffer
,
0
,
bufferSize
);
nBytes
=
0
;
}
//------------------------------------------------------------------------------
/**
* CallBack to link the pads created by uridecodebin
...
...
@@ -361,6 +275,7 @@ void StreamRecorder::srcNewPad_callback(GstElement *element, GstPad *pad, void *
cout
<<
"Link succeeded "
<<
new_pad_type
<<
endl
;
}
}
//------------------------------------------------------------------------------
/**
...
...
@@ -370,15 +285,50 @@ void StreamRecorder::srcNewPad_callback(GstElement *element, GstPad *pad, void *
* @param user_data this
* @return unimplemented
*/
int
StreamRecorder
::
filter_handoff_callback
(
GstElement
*
filter
,
GstBuffer
*
buffer
,
void
*
user_data
)
{
GstMapInfo
info
;
if
(
!
gst_buffer_map
(
buffer
,
&
info
,
GST_MAP_READ
))
cout
<<
"ERROR: MAPPING IS NOT VALID"
<<
endl
;
long
int
currentTime
;
long
int
actualRecordTime
;
//GST_BUFFER_DATA is for gst v0.1
// ((StreamRecorder*)user_data)->addToBuffer((unsigned char*)GST_BUFFER_DATA (buffer));
if
(((
StreamRecorder
*
)
user_data
)
->
isDisconnected
){
currentTime
=
time
(
NULL
);
actualRecordTime
=
currentTime
-
((
StreamRecorder
*
)
user_data
)
->
timestamp
;
if
(
actualRecordTime
>=
((
StreamRecorder
*
)
user_data
)
->
audioFileDuration
)
{
/** Complete the buffer with missing bytes*/
((
StreamRecorder
*
)
user_data
)
->
nBytes
=
((
StreamRecorder
*
)
user_data
)
->
bufferSize
;
((
StreamRecorder
*
)
user_data
)
->
saveBuffer
();
cout
<<
"The buffer has been saved..."
<<
endl
;
}
else
{
long
int
bytesToAdd
=
actualRecordTime
*
((
StreamRecorder
*
)
user_data
)
->
bytesPerSecond
;
unsigned
char
*
newPosition
;
printf
(
"Bytes to add %d
\n
"
,
bytesToAdd
);
newPosition
=
((
StreamRecorder
*
)
user_data
)
->
audioBuffer
;
newPosition
+=
bytesToAdd
;
((
StreamRecorder
*
)
user_data
)
->
audioBufferPosition
=
newPosition
;
((
StreamRecorder
*
)
user_data
)
->
nBytes
=
bytesToAdd
;
cout
<<
"The pointer has been updated..."
<<
endl
;
}
((
StreamRecorder
*
)
user_data
)
->
isDisconnected
=
false
;
}
// user data is the class
((
StreamRecorder
*
)
user_data
)
->
addToBuffer
((
unsigned
char
*
)
info
.
data
,
info
.
size
);
gst_buffer_unmap
(
buffer
,
&
info
);
...
...
@@ -395,8 +345,6 @@ int StreamRecorder::filter_handoff_callback(GstElement* filter, GstBuffer* buffe
int
StreamRecorder
::
addToBuffer
(
unsigned
char
*
data
,
int
length
)
{
int
bytesRead
=
length
;
// READSIZE*STREAMRECORDER_BYTESPERSAMPLE;
long
int
currentTime
;
long
int
actualRecordTime
;
bool
isNewAudioFile
;
/** Useful for obtain the filename*/
...
...
@@ -404,13 +352,13 @@ int StreamRecorder::addToBuffer(unsigned char* data, int length) {
cout
<<
"Data size: "
<<
bytesRead
<<
endl
;
//if(nBytes < bufferSize)
//{
/** Update pointer*/
/** add info to buffer*/
printf
(
"Audio buffer position %d
\n
"
,
audioBufferPosition
);
memcpy
((
char
*
)
audioBufferPosition
,
(
char
*
)
data
,
bytesRead
);
/** Update pointer*/
nBytes
+=
bytesRead
;
audioBufferPosition
+=
bytesRead
;
//}
if
(
isNewAudioFile
)
{
...
...
@@ -419,14 +367,14 @@ int StreamRecorder::addToBuffer(unsigned char* data, int length) {
/** filename */
timestamp
=
time
(
NULL
);
cout
<<
"Audio filename (timestamp): "
<<
timestamp
<<
endl
;
printf
(
"Audio buffer %d
\n
"
,
audioBuffer
);
}
else
{
long
int
currentTime
;
long
int
actualRecordTime
;
currentTime
=
time
(
NULL
);
oldTmpTimestamp
=
newTmpTimestamp
;
newTmpTimestamp
=
currentTime
;
actualRecordTime
=
currentTime
-
timestamp
;
cout
<<
"Record time: "
<<
actualRecordTime
<<
endl
;
...
...
@@ -436,10 +384,12 @@ int StreamRecorder::addToBuffer(unsigned char* data, int length) {
/** If the buffer is full, save it in flac file */
if
(
nBytes
>=
bufferSize
)
{
compressBuffer
();
audioBufferPosition
=
audioBuffer
;
memset
(
audioBuffer
,
0
,
bufferSize
);
nBytes
=
0
;
cout
<<
"ENTROOOO"
<<
endl
;
printf
(
"Audio buffer %d
\n
"
,
audioBuffer
);
printf
(
"Audio buffer position %d
\n
"
,
audioBufferPosition
);
cout
<<
"Bytes readed "
<<
nBytes
<<
endl
;
cout
<<
"Buffer size "
<<
bufferSize
<<
endl
;
saveBuffer
();
}
}
...
...
StreamRecorder.h
View file @
a187cafe
...
...
@@ -28,6 +28,8 @@
#define DST_URI_SIZE 80
#define RECONNECTION_DELAY 1
#define STREAM_ENOUGH_DATA_ERROR 4
//------------------------------------------------------------------------------
/** Class declaration */
...
...
@@ -36,60 +38,65 @@ class StreamRecorder
{
private
:
unsigned
char
*
audioBuffer
;
unsigned
char
*
audioBufferPosition
;
unsigned
char
*
audioBuffer
;
unsigned
char
*
audioBufferPosition
;
char
errorMessage
[
ERROR_MSG_SIZE
];
char
pluginUri
[
DST_URI_SIZE
];
char
errorMessage
[
ERROR_MSG_SIZE
];
char
pluginUri
[
DST_URI_SIZE
];
unsigned
int
nBytes
;
unsigned
int
bufferSize
;
unsigned
int
nBytes
;
unsigned
int
bufferSize
;
int
recordTime
;
int
audioFileDuration
;
/** Audio filename */
long
int
timestamp
=
0
;
long
int
oldTmpTimestamp
=
0
;
long
int
newTmpTimestamp
=
0
;
int
recordTime
;
int
audioFileDuration
;
bool
isConnectionLost
;
//char* sourceName;
//GstElement* audioResample;
//GstElement* tempBin;
//GstElement* audioSink;
GstElement
*
streamSrc
;
GstElement
*
audioConvert
;
GstElement
*
filterCaps
;
GstElement
*
queue0
;
GstElement
*
queue1
;
GstElement
*
filter
;
GstElement
*
fakeSink
;
GstElement
*
mainPipeline
;
/** Audio filename */
long
int
timestamp
=
0
;
long
int
oldTmpTimestamp
=
0
;
long
int
newTmpTimestamp
=
0
;
long
int
bytesPerSecond
=
0
;
bool
isDisconnected
=
false
;
bool
isValidDisconnectedEvent
=
false
;
int
createMainPipeline
();
int
connect
();
int
disconnect
();
//char* sourceName;
//GstElement* audioResample;
//GstElement* tempBin;
//GstElement* audioSink;
GstElement
*
streamSrc
;
GstElement
*
audioConvert
;
GstElement
*
filterCaps
;
GstElement
*
queue0
;
GstElement
*
queue1
;
GstElement
*
filter
;
GstElement
*
fakeSink
;
GstElement
*
mainPipeline
;
int
createMainPipeline
();
int
connect
();
int
disconnect
();
/** add data to buffer */
int
addToBuffer
(
unsigned
char
*
data
,
int
length
);
int
compressBuffer
();
/** add data to buffer */
int
addToBuffer
(
unsigned
char
*
data
,
int
length
);
int
compressBuffer
();
/** plugin's callbacks */
static
void
srcNewPad_callback
(
GstElement
*
element
,
GstPad
*
pad
,
void
*
data
);
static
int
bus_callback
(
GstBus
*
bus
,
GstMessage
*
message
,
void
*
data
);
static
int
filter_handoff_callback
(
GstElement
*
filter
,
GstBuffer
*
buffer
,
void
*
user_data
);
/** plugin's callbacks */
static
void
srcNewPad_callback
(
GstElement
*
element
,
GstPad
*
pad
,
void
*
data
);
static
int
bus_callback
(
GstBus
*
bus
,
GstMessage
*
message
,
void
*
data
);
static
int
filter_handoff_callback
(
GstElement
*
filter
,
GstBuffer
*
buffer
,
void
*
user_data
);
/** Save audio*/
static
void
saveBuffer
(
void
*
user_data
);
/** Save audio*/
void
saveBuffer
(
);
/** Restart the pipeline */
static
gboolean
reconnectURIStream
(
void
*
data
);
/** Restart the pipeline */
static
gboolean
reconnectURIStream
(
void
*
data
);
public
:
public
:
StreamRecorder
(
const
char
*
source
,
int
time
);
StreamRecorder
(
const
char
*
source
,
int
time
);
};
//------------------------------------------------------------------------------
#endif
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