Commit a187cafe authored by d.basulto's avatar d.basulto

change the way that the bytes to add is calculated

parent 262b856b
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
#include <glib.h> #include <glib.h>
#include <unistd.h> #include <unistd.h>
#include <cstring> #include <cstring>
#include <cstdint>
#include <cstdio>
#include "FLAC/metadata.h" #include "FLAC/metadata.h"
#include "FLAC/stream_encoder.h" #include "FLAC/stream_encoder.h"
...@@ -43,6 +45,8 @@ StreamRecorder::StreamRecorder(const char* source, int time) ...@@ -43,6 +45,8 @@ StreamRecorder::StreamRecorder(const char* source, int time)
bufferSize=nFrames*READSIZE*STREAMRECORDER_BYTESPERSAMPLE; bufferSize=nFrames*READSIZE*STREAMRECORDER_BYTESPERSAMPLE;
audioBuffer = new unsigned char[bufferSize]; audioBuffer = new unsigned char[bufferSize];
bytesPerSecond= bufferSize/audioFileDuration;
// New buffer // New buffer
memset(audioBuffer, 0, bufferSize); memset(audioBuffer, 0, bufferSize);
audioBufferPosition=audioBuffer; audioBufferPosition=audioBuffer;
...@@ -64,7 +68,7 @@ int StreamRecorder::connect() ...@@ -64,7 +68,7 @@ int StreamRecorder::connect()
{ {
disconnect(); 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_NULL);
gst_element_set_state (mainPipeline, GST_STATE_READY); gst_element_set_state (mainPipeline, GST_STATE_READY);
...@@ -151,7 +155,7 @@ int StreamRecorder::createMainPipeline() ...@@ -151,7 +155,7 @@ int StreamRecorder::createMainPipeline()
*/ */
gboolean StreamRecorder::reconnectURIStream(void* instance) gboolean StreamRecorder::reconnectURIStream(void* instance)
{ {
cout << "\nTrying to reconnect with the stream..." << endl << endl; cout << "Trying to reconnect with the stream..." << endl << endl;
((StreamRecorder*)instance)->connect(); ((StreamRecorder*)instance)->connect();
return FALSE; return FALSE;
...@@ -170,160 +174,70 @@ gboolean StreamRecorder::reconnectURIStream(void* instance) ...@@ -170,160 +174,70 @@ gboolean StreamRecorder::reconnectURIStream(void* instance)
int StreamRecorder::bus_callback (GstBus *bus, GstMessage *message, void *user_data) int StreamRecorder::bus_callback (GstBus *bus, GstMessage *message, void *user_data)
{ {
//printf("StreamRecorder got %s message\n", GST_MESSAGE_TYPE_NAME (message)); //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)) switch (GST_MESSAGE_TYPE (message))
{ {
case GST_MESSAGE_EOS: 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 ((StreamRecorder*)user_data)->isDisconnected = true;
{
// ----------------------------------------------------------------------------------------
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);
}
break; break;
case GST_MESSAGE_ERROR: case GST_MESSAGE_ERROR:
gchar *debug;
GError *error; GError *error;
gchar *debug;
gst_message_parse_error (message, &error, &debug); gst_message_parse_error (message, &error, &debug);
g_free (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; cerr << "Error - code: (" << error->code << ") - Message:" << error->message << endl;
g_error_free (error);
if(strcmp(((StreamRecorder*)user_data)->errorMessage, "Stream doesn't contain enough data.") == 0) switch (error->code)
{ {
case STREAM_ENOUGH_DATA_ERROR:
/** Not audio stream received */ /** Last message in errors secuence*/
if(((StreamRecorder*)user_data)->timestamp == 0) ((StreamRecorder*)user_data)->isDisconnected = true;
{ break;
g_timeout_add(RECONNECTION_DELAY*1000, reconnectURIStream, user_data);
} default:
else return TRUE;
{
// ----------------------------------------------------------------------------------------
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);
}
} }
g_error_free (error);
break; break;
default: default:
break; return TRUE;
} }
if(((StreamRecorder*)user_data)->isDisconnected)
{
/** Try reconnect with the radio stream*/
cout << "\nReconnection started..." << endl;
g_timeout_add(RECONNECTION_DELAY*1000, reconnectURIStream, user_data);
}
return TRUE; 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 * CallBack to link the pads created by uridecodebin
...@@ -361,6 +275,7 @@ void StreamRecorder::srcNewPad_callback(GstElement *element, GstPad *pad, void * ...@@ -361,6 +275,7 @@ void StreamRecorder::srcNewPad_callback(GstElement *element, GstPad *pad, void *
cout <<"Link succeeded " << new_pad_type << endl; cout <<"Link succeeded " << new_pad_type << endl;
} }
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/** /**
...@@ -370,15 +285,50 @@ void StreamRecorder::srcNewPad_callback(GstElement *element, GstPad *pad, void * ...@@ -370,15 +285,50 @@ void StreamRecorder::srcNewPad_callback(GstElement *element, GstPad *pad, void *
* @param user_data this * @param user_data this
* @return unimplemented * @return unimplemented
*/ */
int StreamRecorder::filter_handoff_callback(GstElement* filter, GstBuffer* buffer, void* user_data) int StreamRecorder::filter_handoff_callback(GstElement* filter, GstBuffer* buffer, void* user_data)
{ {
GstMapInfo info; GstMapInfo info;
if(!gst_buffer_map (buffer, &info, GST_MAP_READ)) if(!gst_buffer_map (buffer, &info, GST_MAP_READ))
cout << "ERROR: MAPPING IS NOT VALID" << endl; cout << "ERROR: MAPPING IS NOT VALID" << endl;
long int currentTime;
long int actualRecordTime;
//GST_BUFFER_DATA is for gst v0.1 //GST_BUFFER_DATA is for gst v0.1
// ((StreamRecorder*)user_data)->addToBuffer((unsigned char*)GST_BUFFER_DATA (buffer)); // ((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 // user data is the class
((StreamRecorder*)user_data)->addToBuffer((unsigned char*)info.data, info.size); ((StreamRecorder*)user_data)->addToBuffer((unsigned char*)info.data, info.size);
gst_buffer_unmap (buffer, &info); gst_buffer_unmap (buffer, &info);
...@@ -395,8 +345,6 @@ int StreamRecorder::filter_handoff_callback(GstElement* filter, GstBuffer* buffe ...@@ -395,8 +345,6 @@ int StreamRecorder::filter_handoff_callback(GstElement* filter, GstBuffer* buffe
int StreamRecorder::addToBuffer(unsigned char* data, int length) { int StreamRecorder::addToBuffer(unsigned char* data, int length) {
int bytesRead = length;// READSIZE*STREAMRECORDER_BYTESPERSAMPLE; int bytesRead = length;// READSIZE*STREAMRECORDER_BYTESPERSAMPLE;
long int currentTime;
long int actualRecordTime;
bool isNewAudioFile; bool isNewAudioFile;
/** Useful for obtain the filename*/ /** Useful for obtain the filename*/
...@@ -404,13 +352,13 @@ int StreamRecorder::addToBuffer(unsigned char* data, int length) { ...@@ -404,13 +352,13 @@ int StreamRecorder::addToBuffer(unsigned char* data, int length) {
cout << "Data size: " << bytesRead << endl; cout << "Data size: " << bytesRead << endl;
//if(nBytes < bufferSize) /** add info to buffer*/
//{ printf("Audio buffer position %d\n", audioBufferPosition);
/** Update pointer*/
memcpy((char*)audioBufferPosition, (char*)data, bytesRead); memcpy((char*)audioBufferPosition, (char*)data, bytesRead);
/** Update pointer*/
nBytes+=bytesRead; nBytes+=bytesRead;
audioBufferPosition+=bytesRead; audioBufferPosition+=bytesRead;
//}
if(isNewAudioFile) if(isNewAudioFile)
{ {
...@@ -419,14 +367,14 @@ int StreamRecorder::addToBuffer(unsigned char* data, int length) { ...@@ -419,14 +367,14 @@ int StreamRecorder::addToBuffer(unsigned char* data, int length) {
/** filename */ /** filename */
timestamp = time(NULL); timestamp = time(NULL);
cout << "Audio filename (timestamp): " << timestamp << endl; cout << "Audio filename (timestamp): " << timestamp << endl;
printf("Audio buffer %d\n", audioBuffer);
} }
else else
{ {
long int currentTime;
long int actualRecordTime;
currentTime = time(NULL); currentTime = time(NULL);
oldTmpTimestamp = newTmpTimestamp;
newTmpTimestamp = currentTime;
actualRecordTime = currentTime-timestamp; actualRecordTime = currentTime-timestamp;
cout << "Record time: " << actualRecordTime << endl; cout << "Record time: " << actualRecordTime << endl;
...@@ -436,10 +384,12 @@ int StreamRecorder::addToBuffer(unsigned char* data, int length) { ...@@ -436,10 +384,12 @@ int StreamRecorder::addToBuffer(unsigned char* data, int length) {
/** If the buffer is full, save it in flac file */ /** If the buffer is full, save it in flac file */
if(nBytes >= bufferSize) if(nBytes >= bufferSize)
{ {
compressBuffer(); cout << "ENTROOOO" << endl;
audioBufferPosition=audioBuffer; printf("Audio buffer %d\n", audioBuffer );
memset (audioBuffer, 0, bufferSize); printf("Audio buffer position %d\n", audioBufferPosition);
nBytes=0; cout << "Bytes readed " << nBytes << endl;
cout << "Buffer size " << bufferSize << endl;
saveBuffer();
} }
} }
......
...@@ -28,6 +28,8 @@ ...@@ -28,6 +28,8 @@
#define DST_URI_SIZE 80 #define DST_URI_SIZE 80
#define RECONNECTION_DELAY 1 #define RECONNECTION_DELAY 1
#define STREAM_ENOUGH_DATA_ERROR 4
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/** Class declaration */ /** Class declaration */
...@@ -36,60 +38,65 @@ class StreamRecorder ...@@ -36,60 +38,65 @@ class StreamRecorder
{ {
private: private:
unsigned char* audioBuffer; unsigned char* audioBuffer;
unsigned char* audioBufferPosition; unsigned char* audioBufferPosition;
char errorMessage[ERROR_MSG_SIZE]; char errorMessage[ERROR_MSG_SIZE];
char pluginUri[DST_URI_SIZE]; char pluginUri[DST_URI_SIZE];
unsigned int nBytes; unsigned int nBytes;
unsigned int bufferSize; unsigned int bufferSize;
int recordTime; int recordTime;
int audioFileDuration; int audioFileDuration;
/** Audio filename */
long int timestamp = 0;
long int oldTmpTimestamp = 0;
long int newTmpTimestamp = 0;
bool isConnectionLost; /** Audio filename */
long int timestamp = 0;
//char* sourceName; long int oldTmpTimestamp = 0;
//GstElement* audioResample; long int newTmpTimestamp = 0;
//GstElement* tempBin; long int bytesPerSecond = 0;
//GstElement* audioSink;
GstElement* streamSrc;
GstElement* audioConvert; bool isDisconnected = false;
GstElement* filterCaps; bool isValidDisconnectedEvent = false;
GstElement* queue0;
GstElement* queue1;
GstElement* filter;
GstElement* fakeSink;
GstElement* mainPipeline;
int createMainPipeline(); //char* sourceName;
int connect(); //GstElement* audioResample;
int disconnect(); //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 */ /** add data to buffer */
int addToBuffer(unsigned char* data, int length); int addToBuffer(unsigned char* data, int length);
int compressBuffer(); int compressBuffer();
/** plugin's callbacks */ /** plugin's callbacks */
static void srcNewPad_callback(GstElement *element, GstPad *pad, void *data); static void srcNewPad_callback(GstElement *element, GstPad *pad, void *data);
static int bus_callback(GstBus *bus, GstMessage *message, void *data); static int bus_callback(GstBus *bus, GstMessage *message, void *data);
static int filter_handoff_callback(GstElement *filter, GstBuffer* buffer, void* user_data); static int filter_handoff_callback(GstElement *filter, GstBuffer* buffer, void* user_data);
/** Save audio*/ /** Save audio*/
static void saveBuffer(void *user_data); void saveBuffer();
/** Restart the pipeline */ /** Restart the pipeline */
static gboolean reconnectURIStream(void* data); static gboolean reconnectURIStream(void* data);
public: public:
StreamRecorder(const char* source, int time); StreamRecorder(const char* source, int time);
}; };
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
#endif #endif
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