How can I improve file read performance? - c++

I created a c++ program that reads and analyzes pcap files via fread function.
It is a program that reads the global header of pcap file, reads the pcap header, and extracts a specific field value by specifying each protocol header structure. Compared to tcpdump tool, tcpdump read the pcap file about three times faster. My program is really simple, but I don't know why it is slow. What do I need to do to improve my program's performance?
The following is my code. Note that the type of result(Variable) is ostringstream. and The Program is work by calling analyze() repeatly to read all the pcap files.
PcapAnalyzer::PcapAnalyzer(const std::string& filename)
{
PcapAnalyzerfile = fopen("test.pcap", "r");
if (PcapAnalyzerfile == nullptr)
throw std::runtime_error("Failed to read Pcap");
struct PcapAnalyzer_file_header pfh;
if (fread(&pfh, sizeof(pfh), 1, PcapAnalyzerfile) < 1)
throw std::runtime_error("Failed to read Pcap");
if(pfh.linktype != 1)
throw std::runtime_error("No Support");
}
std::string PcapAnalyzer::analyze()
{
int process_len = 0;
int packet_len = 0;
result.str("");
result.clear();
packet_len = PcapAnalyzer_header();
if (packet_len == -1)
return {};
process_len = ethernet();
if (process_len == -1)
throw std::runtime_error("failed to analyze");
packet_len -= process_len;
if (!payload(packet_len))
throw std::runtime_error("failed to analyze");
return result.str();
}
int PcapAnalyzer::PcapAnalyzer_header()
{
struct PcapAnalyzer_pkthdr pp;
char* cap_time;
long sec;
if (fread(&pp, sizeof(pp), 1, PcapAnalyzerfile) < 1)
return -1;
sec = (long)pp.ts.tv_sec;
cap_time = (char*)ctime((const time_t*)&sec);
cap_time[strlen(cap_time) - 1] = '\0';
result << std::dec;
result << pp.len << " ";
result << cap_time << " ";
return pp.caplen;
}
int PcapAnalyzer::ethernet()
{
struct ether_header eh;
int process_len = 0;
if (fread(&eh, sizeof(eh), 1, PcapAnalyzerfile) < 1)
return -1;
process_len += sizeof(eh);
if(htons(eh.ether_type) != ETHERTYPE_IP)
return process_len;
process_len += ipv4();
if (process_len == -1)
throw std::runtime_error("failed to analyze");
return process_len;
}
int PcapAnalyzer::ipv4()
{
struct ip iph;
int opt = 0;
int process_len = 0;
if (fread(&iph, 20, 1, PcapAnalyzerfile) < 1)
return -1;
result << IP_V(iph.ip_vhl) << " ";
result << IP_HL(iph.ip_vhl) << " ";
result << iph.ip_tos << " ";
result << iph.ip_len << " ";
result << iph.ip_id << " ";
result << iph.ip_off << " ";
result << iph.ip_ttl << " ";
process_len += 20;
opt = IP_HL(iph.ip_vhl) * 4 - sizeof(iph);
if (opt != 0) {
fseek(PcapAnalyzerfile, opt, SEEK_CUR);
process_len += opt;
result << "ip_opt ";
}
if(iph.ip_p != IPPROTO_UDP)
return process_len;
process_len += udp();
if (process_len == -1)
throw std::runtime_error("failed to read transport header");
return process_len;
}
int PcapAnalyzer::udp()
{
struct udphdr udph;
int process_len = 0;
if (fread(&udph, sizeof(udph), 1, PcapAnalyzerfile) < 1)
return -1;
process_len += sizeof(udph);
result << ntohs(udph.uh_sport) << " ";
result << ntohs(udph.uh_dport) << " ";
result << ntohs(udph.uh_ulen) << " ";
result << ntohs(udph.uh_sum) << " ";
return process_len;
}
bool PcapAnalyzer::payload(int remain_len)
{
if (remain_len == 0)
return true;
char buffer[remain_len];
if (fread(buffer, remain_len, 1, PcapAnalyzerfile) < 1)
return false;
return true;
}

Related

audio do not stop recording after pause ffmpeg c++

I am developing an application that record the screen and the audio from microphone. I implemented the pause function stopping video and audio thread on a condition variable, resuming them with a notify on the same condition variable. This is done in captureAudio(), in the main while. In this way works on macOS and linux, where I use avfoudation and alsa respectively, but on windows, with dshow, keep recording audio during the pause, when the thread is waiting on the condition variable. Does anybody know how can I fix this behaviour?
#include "ScreenRecorder.h"
using namespace std;
ScreenRecorder::ScreenRecorder() : pauseCapture(false), stopCapture(false), started(false), activeMenu(true) {
avcodec_register_all();
avdevice_register_all();
width = 1920;
height = 1200;
}
ScreenRecorder::~ScreenRecorder() {
if (started) {
value = av_write_trailer(outAVFormatContext);
if (value < 0) {
cerr << "Error in writing av trailer" << endl;
exit(-1);
}
avformat_close_input(&inAudioFormatContext);
if(inAudioFormatContext == nullptr){
cout << "inAudioFormatContext close successfully" << endl;
}
else{
cerr << "Error: unable to close the inAudioFormatContext" << endl;
exit(-1);
//throw "Error: unable to close the file";
}
avformat_free_context(inAudioFormatContext);
if(inAudioFormatContext == nullptr){
cout << "AudioFormat freed successfully" << endl;
}
else{
cerr << "Error: unable to free AudioFormatContext" << endl;
exit(-1);
}
avformat_close_input(&pAVFormatContext);
if (pAVFormatContext == nullptr) {
cout << "File close successfully" << endl;
}
else {
cerr << "Error: unable to close the file" << endl;
exit(-1);
//throw "Error: unable to close the file";
}
avformat_free_context(pAVFormatContext);
if (pAVFormatContext == nullptr) {
cout << "VideoFormat freed successfully" << endl;
}
else {
cerr << "Error: unable to free VideoFormatContext" << endl;
exit(-1);
}
}
}
/*==================================== VIDEO ==============================*/
int ScreenRecorder::openVideoDevice() throw() {
value = 0;
options = nullptr;
pAVFormatContext = nullptr;
pAVFormatContext = avformat_alloc_context();
string dimension = to_string(width) + "x" + to_string(height);
av_dict_set(&options, "video_size", dimension.c_str(), 0); //option to set the dimension of the screen section to record
#ifdef _WIN32
pAVInputFormat = av_find_input_format("gdigrab");
if (avformat_open_input(&pAVFormatContext, "desktop", pAVInputFormat, &options) != 0) {
cerr << "Couldn't open input stream" << endl;
exit(-1);
}
#elif defined linux
int offset_x = 0, offset_y = 0;
string url = ":0.0+" + to_string(offset_x) + "," + to_string(offset_y); //custom string to set the start point of the screen section
pAVInputFormat = av_find_input_format("x11grab");
value = avformat_open_input(&pAVFormatContext, url.c_str(), pAVInputFormat, &options);
if (value != 0) {
cerr << "Error in opening input device (video)" << endl;
exit(-1);
}
#else
value = av_dict_set(&options, "pixel_format", "0rgb", 0);
if (value < 0) {
cerr << "Error in setting pixel format" << endl;
exit(-1);
}
value = av_dict_set(&options, "video_device_index", "1", 0);
if (value < 0) {
cerr << "Error in setting video device index" << endl;
exit(-1);
}
pAVInputFormat = av_find_input_format("avfoundation");
if (avformat_open_input(&pAVFormatContext, "Capture screen 0:none", pAVInputFormat, &options) != 0) { //TODO trovare un modo per selezionare sempre lo schermo (forse "Capture screen 0")
cerr << "Error in opening input device" << endl;
exit(-1);
}
#endif
//set frame per second
value = av_dict_set(&options, "framerate", "30", 0);
if (value < 0) {
cerr << "Error in setting dictionary value (setting framerate)" << endl;
exit(-1);
}
value = av_dict_set(&options, "preset", "medium", 0);
if (value < 0) {
cerr << "Error in setting dictionary value (setting preset value)" << endl;
exit(-1);
}
/*
value = av_dict_set(&options, "vsync", "1", 0);
if(value < 0){
cerr << "Error in setting dictionary value (setting vsync value)" << endl;
exit(-1);
}
*/
value = av_dict_set(&options, "probesize", "60M", 0);
if (value < 0) {
cerr << "Error in setting probesize value" << endl;
exit(-1);
}
//get video stream infos from context
value = avformat_find_stream_info(pAVFormatContext, nullptr);
if (value < 0) {
cerr << "Error in retrieving the stream info" << endl;
exit(-1);
}
VideoStreamIndx = -1;
for (int i = 0; i < pAVFormatContext->nb_streams; i++) {
if (pAVFormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
VideoStreamIndx = i;
break;
}
}
if (VideoStreamIndx == -1) {
cerr << "Error: unable to find video stream index" << endl;
exit(-2);
}
pAVCodecContext = pAVFormatContext->streams[VideoStreamIndx]->codec;
pAVCodec = avcodec_find_decoder(pAVCodecContext->codec_id/*params->codec_id*/);
if (pAVCodec == nullptr) {
cerr << "Error: unable to find decoder video" << endl;
exit(-1);
}
cout << "Insert height and width [h w]: "; //custom screen dimension to record
cin >> h >> w;*/
return 0;
}
/*========================================== AUDIO ============================*/
int ScreenRecorder::openAudioDevice() {
audioOptions = nullptr;
inAudioFormatContext = nullptr;
inAudioFormatContext = avformat_alloc_context();
value = av_dict_set(&audioOptions, "sample_rate", "44100", 0);
if (value < 0) {
cerr << "Error: cannot set audio sample rate" << endl;
exit(-1);
}
value = av_dict_set(&audioOptions, "async", "1", 0);
if (value < 0) {
cerr << "Error: cannot set audio sample rate" << endl;
exit(-1);
}
#if defined linux
audioInputFormat = av_find_input_format("alsa");
value = avformat_open_input(&inAudioFormatContext, "hw:0", audioInputFormat, &audioOptions);
if (value != 0) {
cerr << "Error in opening input device (audio)" << endl;
exit(-1);
}
#endif
#if defined _WIN32
audioInputFormat = av_find_input_format("dshow");
value = avformat_open_input(&inAudioFormatContext, "audio=Microfono (Realtek(R) Audio)", audioInputFormat, &audioOptions);
if (value != 0) {
cerr << "Error in opening input device (audio)" << endl;
exit(-1);
}
#endif
value = avformat_find_stream_info(inAudioFormatContext, nullptr);
if (value != 0) {
cerr << "Error: cannot find the audio stream information" << endl;
exit(-1);
}
audioStreamIndx = -1;
for (int i = 0; i < inAudioFormatContext->nb_streams; i++) {
if (inAudioFormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
audioStreamIndx = i;
break;
}
}
if (audioStreamIndx == -1) {
cerr << "Error: unable to find audio stream index" << endl;
exit(-2);
}
}
int ScreenRecorder::initOutputFile() {
value = 0;
outAVFormatContext = nullptr;
outputAVFormat = av_guess_format(nullptr, "output.mp4", nullptr);
if (outputAVFormat == nullptr) {
cerr << "Error in guessing the video format, try with correct format" << endl;
exit(-5);
}
avformat_alloc_output_context2(&outAVFormatContext, outputAVFormat, outputAVFormat->name, "..\\media\\output.mp4");
if (outAVFormatContext == nullptr) {
cerr << "Error in allocating outAVFormatContext" << endl;
exit(-4);
}
/*===========================================================================*/
this->generateVideoStream();
this->generateAudioStream();
//create an empty video file
if (!(outAVFormatContext->flags & AVFMT_NOFILE)) {
if (avio_open2(&outAVFormatContext->pb, "..\\media\\output.mp4", AVIO_FLAG_WRITE, nullptr, nullptr) < 0) {
cerr << "Error in creating the video file" << endl;
exit(-10);
}
}
if (outAVFormatContext->nb_streams == 0) {
cerr << "Output file does not contain any stream" << endl;
exit(-11);
}
value = avformat_write_header(outAVFormatContext, &options);
if (value < 0) {
cerr << "Error in writing the header context" << endl;
exit(-12);
}
return 0;
}
/*=================================== VIDEO ==================================*/
void ScreenRecorder::generateVideoStream() {
//Generate video stream
videoSt = avformat_new_stream(outAVFormatContext, nullptr);
if (videoSt == nullptr) {
cerr << "Error in creating AVFormatStream" << endl;
exit(-6);
}
outVideoCodec = avcodec_find_encoder(AV_CODEC_ID_MPEG4); //AV_CODEC_ID_MPEG4
if (outVideoCodec == nullptr) {
cerr << "Error in finding the AVCodec, try again with the correct codec" << endl;
exit(-8);
}
avcodec_alloc_context3(outAVCodec)
outVideoCodecContext = avcodec_alloc_context3(outVideoCodec);
if (outVideoCodecContext == nullptr) {
cerr << "Error in allocating the codec context" << endl;
exit(-7);
}
//set properties of the video file (stream)
outVideoCodecContext = videoSt->codec;
outVideoCodecContext->codec_id = AV_CODEC_ID_MPEG4;
outVideoCodecContext->codec_type = AVMEDIA_TYPE_VIDEO;
outVideoCodecContext->pix_fmt = AV_PIX_FMT_YUV420P;
outVideoCodecContext->bit_rate = 10000000;
outVideoCodecContext->width = width;
outVideoCodecContext->height = height;
outVideoCodecContext->gop_size = 10;
outVideoCodecContext->global_quality = 500;
outVideoCodecContext->max_b_frames = 2;
outVideoCodecContext->time_base.num = 1;
outVideoCodecContext->time_base.den = 30;
outVideoCodecContext->bit_rate_tolerance = 400000;
if (outVideoCodecContext->codec_id == AV_CODEC_ID_H264) {
av_opt_set(outVideoCodecContext->priv_data, "preset", "slow", 0);
}
if (outAVFormatContext->oformat->flags & AVFMT_GLOBALHEADER) {
outVideoCodecContext->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
}
value = avcodec_open2(outVideoCodecContext, outVideoCodec, nullptr);
if (value < 0) {
cerr << "Error in opening the AVCodec" << endl;
exit(-9);
}
outVideoStreamIndex = -1;
for (int i = 0; i < outAVFormatContext->nb_streams; i++) {
if (outAVFormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_UNKNOWN) {
outVideoStreamIndex = i;
}
}
if (outVideoStreamIndex < 0) {
cerr << "Error: cannot find a free stream index for video output" << endl;
exit(-1);
}
avcodec_parameters_from_context(outAVFormatContext->streams[outVideoStreamIndex]->codecpar, outVideoCodecContext);
}
/*=============================== AUDIO ==================================*/
void ScreenRecorder::generateAudioStream() {
AVCodecParameters* params = inAudioFormatContext->streams[audioStreamIndx]->codecpar;
inAudioCodec = avcodec_find_decoder(params->codec_id);
if (inAudioCodec == nullptr) {
cerr << "Error: cannot find the audio decoder" << endl;
exit(-1);
}
inAudioCodecContext = avcodec_alloc_context3(inAudioCodec);
if (avcodec_parameters_to_context(inAudioCodecContext, params) < 0) {
cout << "Cannot create codec context for audio input" << endl;
}
value = avcodec_open2(inAudioCodecContext, inAudioCodec, nullptr);
if (value < 0) {
cerr << "Error: cannot open the input audio codec" << endl;
exit(-1);
}
//Generate audio stream
outAudioCodecContext = nullptr;
outAudioCodec = nullptr;
int i;
AVStream* audio_st = avformat_new_stream(outAVFormatContext, nullptr);
if (audio_st == nullptr) {
cerr << "Error: cannot create audio stream" << endl;
exit(1);
}
outAudioCodec = avcodec_find_encoder(AV_CODEC_ID_AAC);
if (outAudioCodec == nullptr) {
cerr << "Error: cannot find requested encoder" << endl;
exit(1);
}
outAudioCodecContext = avcodec_alloc_context3(outAudioCodec);
if (outAudioCodecContext == nullptr) {
cerr << "Error: cannot create related VideoCodecContext" << endl;
exit(1);
}
if ((outAudioCodec)->supported_samplerates) {
outAudioCodecContext->sample_rate = (outAudioCodec)->supported_samplerates[0];
for (i = 0; (outAudioCodec)->supported_samplerates[i]; i++) {
if ((outAudioCodec)->supported_samplerates[i] == inAudioCodecContext->sample_rate)
outAudioCodecContext->sample_rate = inAudioCodecContext->sample_rate;
}
}
outAudioCodecContext->codec_id = AV_CODEC_ID_AAC;
outAudioCodecContext->sample_fmt = (outAudioCodec)->sample_fmts ? (outAudioCodec)->sample_fmts[0] : AV_SAMPLE_FMT_FLTP;
outAudioCodecContext->channels = inAudioCodecContext->channels;
outAudioCodecContext->channel_layout = av_get_default_channel_layout(outAudioCodecContext->channels);
outAudioCodecContext->bit_rate = 96000;
outAudioCodecContext->time_base = { 1, inAudioCodecContext->sample_rate };
outAudioCodecContext->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
if ((outAVFormatContext)->oformat->flags & AVFMT_GLOBALHEADER) {
outAudioCodecContext->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
}
if (avcodec_open2(outAudioCodecContext, outAudioCodec, nullptr) < 0) {
cerr << "error in opening the avcodec" << endl;
exit(1);
}
//find a free stream index
outAudioStreamIndex = -1;
for (i = 0; i < outAVFormatContext->nb_streams; i++) {
if (outAVFormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_UNKNOWN) {
outAudioStreamIndex = i;
}
}
if (outAudioStreamIndex < 0) {
cerr << "Error: cannot find a free stream for audio on the output" << endl;
exit(1);
}
avcodec_parameters_from_context(outAVFormatContext->streams[outAudioStreamIndex]->codecpar, outAudioCodecContext);
}
int ScreenRecorder::init_fifo()
{
/* Create the FIFO buffer based on the specified output sample format. */
if (!(fifo = av_audio_fifo_alloc(outAudioCodecContext->sample_fmt,
outAudioCodecContext->channels, 1))) {
fprintf(stderr, "Could not allocate FIFO\n");
return AVERROR(ENOMEM);
}
return 0;
}
int ScreenRecorder::add_samples_to_fifo(uint8_t** converted_input_samples, const int frame_size) {
int error;
/* Make the FIFO as large as it needs to be to hold both,
* the old and the new samples. */
if ((error = av_audio_fifo_realloc(fifo, av_audio_fifo_size(fifo) + frame_size)) < 0) {
fprintf(stderr, "Could not reallocate FIFO\n");
return error;
}
/* Store the new samples in the FIFO buffer. */
if (av_audio_fifo_write(fifo, (void**)converted_input_samples, frame_size) < frame_size) {
fprintf(stderr, "Could not write data to FIFO\n");
return AVERROR_EXIT;
}
return 0;
}
int ScreenRecorder::initConvertedSamples(uint8_t*** converted_input_samples,
AVCodecContext* output_codec_context,
int frame_size) {
int error;
/* Allocate as many pointers as there are audio channels.
* Each pointer will later point to the audio samples of the corresponding
* channels (although it may be NULL for interleaved formats).
*/
if (!(*converted_input_samples = (uint8_t**)calloc(output_codec_context->channels,
sizeof(**converted_input_samples)))) {
fprintf(stderr, "Could not allocate converted input sample pointers\n");
return AVERROR(ENOMEM);
}
/* Allocate memory for the samples of all channels in one consecutive
* block for convenience. */
if (av_samples_alloc(*converted_input_samples, nullptr,
output_codec_context->channels,
frame_size,
output_codec_context->sample_fmt, 0) < 0) {
exit(1);
}
return 0;
}
static int64_t pts = 0;
void ScreenRecorder::captureAudio() {
int ret;
AVPacket* inPacket, * outPacket;
AVFrame* rawFrame, * scaledFrame;
uint8_t** resampledData;
init_fifo();
//allocate space for a packet
inPacket = (AVPacket*)av_malloc(sizeof(AVPacket));
if (!inPacket) {
cerr << "Cannot allocate an AVPacket for encoded video" << endl;
exit(1);
}
av_init_packet(inPacket);
//allocate space for a packet
rawFrame = av_frame_alloc();
if (!rawFrame) {
cerr << "Cannot allocate an AVPacket for encoded video" << endl;
exit(1);
}
scaledFrame = av_frame_alloc();
if (!scaledFrame) {
cerr << "Cannot allocate an AVPacket for encoded video" << endl;
exit(1);
}
outPacket = (AVPacket*)av_malloc(sizeof(AVPacket));
if (!outPacket) {
cerr << "Cannot allocate an AVPacket for encoded video" << endl;
exit(1);
}
//init the resampler
SwrContext* resampleContext = nullptr;
resampleContext = swr_alloc_set_opts(resampleContext,
av_get_default_channel_layout(outAudioCodecContext->channels),
outAudioCodecContext->sample_fmt,
outAudioCodecContext->sample_rate,
av_get_default_channel_layout(inAudioCodecContext->channels),
inAudioCodecContext->sample_fmt,
inAudioCodecContext->sample_rate,
0,
nullptr);
if (!resampleContext) {
cerr << "Cannot allocate the resample context" << endl;
exit(1);
}
if ((swr_init(resampleContext)) < 0) {
fprintf(stderr, "Could not open resample context\n");
swr_free(&resampleContext);
exit(1);
}
while (true) {
if (pauseCapture) {
cout << "Pause audio" << endl;
}
cv.wait(ul, [this]() { return !pauseCapture; });
if (stopCapture) {
break;
}
ul.unlock();
if (av_read_frame(inAudioFormatContext, inPacket) >= 0 && inPacket->stream_index == audioStreamIndx) {
//decode audio routing
av_packet_rescale_ts(outPacket, inAudioFormatContext->streams[audioStreamIndx]->time_base, inAudioCodecContext->time_base);
if ((ret = avcodec_send_packet(inAudioCodecContext, inPacket)) < 0) {
cout << "Cannot decode current audio packet " << ret << endl;
continue;
}
while (ret >= 0) {
ret = avcodec_receive_frame(inAudioCodecContext, rawFrame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
break;
else if (ret < 0) {
cerr << "Error during decoding" << endl;
exit(1);
}
if (outAVFormatContext->streams[outAudioStreamIndex]->start_time <= 0) {
outAVFormatContext->streams[outAudioStreamIndex]->start_time = rawFrame->pts;
}
initConvertedSamples(&resampledData, outAudioCodecContext, rawFrame->nb_samples);
swr_convert(resampleContext,
resampledData, rawFrame->nb_samples,
(const uint8_t**)rawFrame->extended_data, rawFrame->nb_samp
add_samples_to_fifo(resampledData, rawFrame->nb_samples);
//raw frame ready
av_init_packet(outPacket);
outPacket->data = nullptr;
outPacket->size = 0;
const int frame_size = FFMAX(av_audio_fifo_size(fifo), outAudioCodecContext->frame_size);
scaledFrame = av_frame_alloc();
if (!scaledFrame) {
cerr << "Cannot allocate an AVPacket for encoded video" << endl;
exit(1);
}
scaledFrame->nb_samples = outAudioCodecContext->frame_size;
scaledFrame->channel_layout = outAudioCodecContext->channel_layout;
scaledFrame->format = outAudioCodecContext->sample_fmt;
scaledFrame->sample_rate = outAudioCodecContext->sample_rate;
av_frame_get_buffer(scaledFrame, 0);
while (av_audio_fifo_size(fifo) >= outAudioCodecContext->frame_size) {
ret = av_audio_fifo_read(fifo, (void**)(scaledFrame->data), outAudioCodecContext->frame_size);
scaledFrame->pts = pts;
pts += scaledFrame->nb_samples;
if (avcodec_send_frame(outAudioCodecContext, scaledFrame) < 0) {
cout << "Cannot encode current audio packet " << endl;
exit(1);
}
while (ret >= 0) {
ret = avcodec_receive_packet(outAudioCodecContext, outPacket);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
break;
else if (ret < 0) {
cerr << "Error during encoding" << endl;
exit(1);
}
av_packet_rescale_ts(outPacket, outAudioCodecContext->time_base, outAVFormatContext->streams[outAudioStreamIndex]->time_base);
outPacket->stream_index = outAudioStreamIndex;
write_lock.lock();
if (av_write_frame(outAVFormatContext, outPacket) != 0)
{
cerr << "Error in writing audio frame" << endl;
}
write_lock.unlock();
av_packet_unref(outPacket);
}
ret = 0;
}
av_frame_free(&scaledFrame);
av_packet_unref(outPacket);
}
}
}
}
int ScreenRecorder::captureVideoFrames() {
int64_t pts = 0;
int flag;
int frameFinished = 0;
bool endPause = false;
int numPause = 0;
ofstream outFile{ "..\\media\\log.txt", ios::out };
int frameIndex = 0;
value = 0;
pAVPacket = (AVPacket*)av_malloc(sizeof(AVPacket));
if (pAVPacket == nullptr) {
cerr << "Error in allocating AVPacket" << endl;
exit(-1);
}
pAVFrame = av_frame_alloc();
if (pAVFrame == nullptr) {
cerr << "Error: unable to alloc the AVFrame resources" << endl;
exit(-1);
}
outFrame = av_frame_alloc();
if (outFrame == nullptr) {
cerr << "Error: unable to alloc the AVFrame resources for out frame" << endl;
exit(-1);
}
int videoOutBuffSize;
int nBytes = av_image_get_buffer_size(outVideoCodecContext->pix_fmt, outVideoCodecContext->width, outVideoCodecContext->height, 32);
uint8_t* videoOutBuff = (uint8_t*)av_malloc(nBytes);
if (videoOutBuff == nullptr) {
cerr << "Error: unable to allocate memory" << endl;
exit(-1);
}
value = av_image_fill_arrays(outFrame->data, outFrame->linesize, videoOutBuff, AV_PIX_FMT_YUV420P, outVideoCodecContext->width, outVideoCodecContext->height, 1);
if (value < 0) {
cerr << "Error in filling image array" << endl;
}
SwsContext* swsCtx_;
if (avcodec_open2(pAVCodecContext, pAVCodec, nullptr) < 0) {
cerr << "Could not open codec" << endl;
exit(-1);
}
swsCtx_ = sws_getContext(pAVCodecContext->width, pAVCodecContext->height, pAVCodecContext->pix_fmt, outVideoCodecContext->width, outVideoCodecContext->height, outVideoCodecContext->pix_fmt, SWS_BICUBIC,
nullptr, nullptr, nullptr);
AVPacket outPacket;
int gotPicture;
time_t startTime;
time(&startTime);
while (true) {
if (pauseCapture) {
cout << "Pause" << endl;
outFile << "/////////////////// Pause ///////////////////" << endl;
cout << "outVideoCodecContext->time_base: " << outVideoCodecContext->time_base.num << ", " << outVideoCodecContext->time_base.den << endl;
}
cv.wait(ul, [this]() { return !pauseCapture; }); //pause capture (not busy waiting)
if (endPause) {
endPause = false;
}
if (stopCapture) //check if the capture has to stop
break;
ul.unlock();
if (av_read_frame(pAVFormatContext, pAVPacket) >= 0 && pAVPacket->stream_index == VideoStreamIndx) {
av_packet_rescale_ts(pAVPacket, pAVFormatContext->streams[VideoStreamIndx]->time_base, pAVCodecContext->time_base);
value = avcodec_decode_video2(pAVCodecContext, pAVFrame, &frameFinished, pAVPacket);
if (value < 0) {
cout << "Unable to decode video" << endl;
}
if (frameFinished) { //frame successfully decoded
//sws_scale(swsCtx_, pAVFrame->data, pAVFrame->linesize, 0, pAVCodecContext->height, outFrame->data, outFrame->linesize);
av_init_packet(&outPacket);
outPacket.data = nullptr;
outPacket.size = 0;
if (outAVFormatContext->streams[outVideoStreamIndex]->start_time <= 0) {
outAVFormatContext->streams[outVideoStreamIndex]->start_time = pAVFrame->pts;
}
//disable warning on the console
outFrame->width = outVideoCodecContext->width;
outFrame->height = outVideoCodecContext->height;
outFrame->format = outVideoCodecContext->pix_fmt;
sws_scale(swsCtx_, pAVFrame->data, pAVFrame->linesize, 0, pAVCodecContext->height, outFrame->data, outFrame->linesize);
avcodec_encode_video2(outVideoCodecContext, &outPacket, outFrame, &gotPicture);
if (gotPicture) {
if (outPacket.pts != AV_NOPTS_VALUE) {
outPacket.pts = av_rescale_q(outPacket.pts, videoSt->codec->time_base, videoSt->time_base);
}
if (outPacket.dts != AV_NOPTS_VALUE) {
outPacket.dts = av_rescale_q(outPacket.dts, videoSt->codec->time_base, videoSt->time_base);
}
//cout << "Write frame " << j++ << " (size = " << outPacket.size / 1000 << ")" << endl;
//cout << "(size = " << outPacket.size << ")" << endl;
//av_packet_rescale_ts(&outPacket, outVideoCodecContext->time_base, outAVFormatContext->streams[outVideoStreamIndex]->time_base);
//outPacket.stream_index = outVideoStreamIndex;
outFile << "outPacket->duration: " << outPacket.duration << ", " << "pAVPacket->duration: " << pAVPacket->duration << endl;
outFile << "outPacket->pts: " << outPacket.pts << ", " << "pAVPacket->pts: " << pAVPacket->pts << endl;
outFile << "outPacket.dts: " << outPacket.dts << ", " << "pAVPacket->dts: " << pAVPacket->dts << endl;
time_t timer;
double seconds;
mu.lock();
if (!activeMenu) {
time(&timer);
seconds = difftime(timer, startTime);
int h = (int)(seconds / 3600);
int m = (int)(seconds / 60) % 60;
int s = (int)(seconds) % 60;
std::cout << std::flush << "\r" << std::setw(2) << std::setfill('0') << h << ':'
<< std::setw(2) << std::setfill('0') << m << ':'
<< std::setw(2) << std::setfill('0') << s << std::flush;
}
mu.unlock();
write_lock.lock();
if (av_write_frame(outAVFormatContext, &outPacket) != 0) {
cerr << "Error in writing video frame" << endl;
}
write_lock.unlock();
av_packet_unref(&outPacket);
}
av_packet_unref(&outPacket);
av_free_packet(pAVPacket); //avoid memory saturation
}
}
}
outFile.close();
av_free(videoOutBuff);
return 0;
}
I resolved this problem performing an avformat_close_input(&inAudioFormatContext) before enter in pause, and an avformat_open_input(&inAudioFormatContext, "audio=Microfono (Realtek(R) Audio)", audioInputFormat, &audioOptions) after resume the recording. In this way the final file seems well syncronized with video.

Quectel EC25 Sending SMS and getting +CMS ERROR 305

This code sends some of SMS messages. But it gives error for some of the messages. It may about some wrong character that GSM module does not recognize like `(.
Is there any one can help to fix the code.
I am checking if GSM device is attached to ttyUSB2.
This is C++ code.
int sendSms(UsbPort &device, string phoneNumber, string message) {
char buf[MAXBUF] = {0};
int n;
if(device.fildes > 0) {
int max_check = 0;
if (write(device.fildes, "ATZ\r", 4) < 4) {
printf("ATZ write error - %s \n", strerror(errno));
return -1;
}
this_thread::sleep_for(chrono::seconds(1));
if (write(device.fildes, "AT+CMGF=1\r", 10) < 10) {
printf("AT+CMGF=1 write error - %s \n", strerror(errno));
return -1;
}
if (tcdrain(device.fildes) != 0) {
perror("tcdrain() error");
return -1;
}
this_thread::sleep_for(chrono::seconds(1));
bzero(buf, sizeof(buf));
read(device.fildes, buf, MAXBUF - 1);
cout << "Buffer-1 = " << buf << endl;
if (write(device.fildes, "ATE+CSMS=1\r", 11) < 11) {
printf("ATE+CSMS=1 write error - %s \n", strerror(errno));
return -1;
}
if (tcdrain(device.fildes) != 0) {
perror("tcdrain() error");
return -1;
}
this_thread::sleep_for(chrono::seconds(1));
bzero(buf, sizeof(buf));
if ((n = read(device.fildes, buf, MAXBUF - 1)) > -1) {
int length = strlen(buf);
cout << "length = " << length << endl;
buf[length] = '\0';
cout << "Buffer-2 = " << buf << endl;
if (strstr(buf, "+CSMS:") != NULL) { // Ready to send SMS
cout << "Can send SMS: " + string(buf) << endl;
// Send SMS
string data1 = "AT+CMGS=\"" + phoneNumber + "\"\r";
if (write(device.fildes, data1.c_str(), data1.length()) < data1.length()) {
printf("AT+CMGS write error - %s \n", strerror(errno));
return -1;
}
else {
this_thread::sleep_for(chrono::seconds(1));
string data2 = message + "\x1A";
if (write(device.fildes, data2.c_str(), data2.length()) < data2.length()) {
printf("ATE+CSMS=1 write error - %s \n", strerror(errno));
return -1;
}
if (tcdrain(device.fildes) != 0) {
perror("tcdrain() error");
return -1;
}
this_thread::sleep_for(chrono::seconds(1));
bzero(buf, sizeof(buf));
if ((n = read(device.fildes, buf, MAXBUF - 1)) > -1) {
int length = strlen(buf);
cout << "length = " << length << endl;
buf[length] = '\0';
cout << "Buffer-2 = " << buf << endl;
if (strstr(buf, "OK") != NULL) {
cout << message + " sent to : " + telNo + " successfully." << endl;
return 0;
}
}
else {
cout << message + " sent to : " + telNo + " unsuccessful!" << endl;
return -1;
}
}
}
else {
cout << "Error: buf = " + string(buf) << endl;
return -1;
}
}
}
return -1;
}
this is the example of which it cannot send sms.
The problem was not about ASCII characters, but about sending a message longer than it should be.
When we use Concatenated SMS it solved our problem. It Send Sms without problem.
AT+CGMF=1
AT+CSCS="GSM"
AT+CSMP=17,167,0,241
AT+CMGS="Number"
> Message <CTRL+Z>

Write and Read method stop my execution - pipes c++

I'm just trying to make a "Tree" where I've a ctrsis and (for now) n "Children" connected to the ctrsis by pipes; But something happen when I try to pass data through pipes from childen to parent and parent to children using stdin and stdout, specificly when I use write() cpp function.
//ctrsis.cpp
int
main(void) {
vector<WriteIn> TubesReference;
WriteIn mainTube;
TubesReference.push_back(mainTube);
const char* file = "ctrsis.cfg";
int levelOneProcesses = 0;
string line;
ifstream configFile(file);
if(configFile.is_open()){
while ( getline (configFile,line) ){
WriteIn structure = createTube(line);
TubesReference.push_back(structure);
levelOneProcesses++;
}
}else{
cout << "Unable to open file" << endl;
}
configFile.close();
if ((TubesReference[0].in = open("ctrsis.cfg", O_RDONLY)) == -1) {
std::cerr << "Error open file" << std::endl;
return 1;
}
TubesReference[0].out = TubesReference[1].pipeOut[1];
for (int i = 1; i < levelOneProcesses; ++i){
TubesReference[i].in = TubesReference[i].pipeIn[0];
if(i != TubesReference.size()-1){
TubesReference[i].out = TubesReference[i+1].pipeOut[1];
}else{
TubesReference[TubesReference.size()-1].out = 1;
}
}
pthread_t levelOneThreads[levelOneProcesses];
for(int i = 0; i < levelOneProcesses; ++i){
vector<string> vec;
istringstream iss(TubesReference[i+1].line);
copy(istream_iterator<string>(iss),
istream_iterator<string>(),
back_inserter(vec));
string file = "FICHEROCFG=" + vec[4];
string folder = "DIRDETRABAJO=" + vec[3];
char* formatFile = new char[file.length()+1];
memcpy(formatFile, file.c_str(), file.length()+1);
char* formatFolder= new char[folder.length()+1];
memcpy(formatFolder, folder.c_str(), folder.length()+1);
putenv(formatFile);
putenv(formatFolder);
cout << "CTRSIS: CREATE THREAD " << i << endl;
int ret = pthread_create(&levelOneThreads[i],NULL, readWriteThread, &TubesReference[i]);
if(ret != 0) {
cerr << "Error: pthread_create() failed\n" << endl;
exit(EXIT_FAILURE);
}else{
cout << "CTRSIS: JOIN THREAD " << i << endl;
pthread_join(levelOneThreads[i], NULL);
}
}
//system( "./ctreval" );
return 0;
}
void* readWriteThread(void *arg) {
sleep(3);
WriteIn *dataInOut = (struct WriteIn *) arg;
cout << "CTRSIS: METHOD" << endl;
char c;
while (read(dataInOut->in, &c, 1) > 0) {
write(dataInOut->out, &c, 1);
}
close(dataInOut->in);
close(dataInOut->out);
return NULL;
}
This is the evaluator
#include <iostream>
#include <cctype>
int
main(void) {
int c;
while ((c = std::cin.get()) != EOF) {
c = ::toupper(c);
std::cout << (char) c;
}
return 0;
}

server freezes when handling large messages in simple server c++

I have a client and server running, and it seems to run great, until I either a really large message, or a partial message. In either of those events it freezes. The buffer is set to 1024, but changing it doesn't seem to affect the message at all. I've copied the getRequest function where it freezes below.
If anyone knows why it freezes or how to deal with large and partial messages, that would be great, thanks.
It freezes on the line int nread = (client, buf_,1024,0); Any solutions?
cout << "entered get request while loop" << endl;
int nread = recv(client,buf_,1024,0);
cout << "number read: " << nread << endl;
string
Server::get_request(int client) {
cout << "getting request" << endl;
string request = "";
// read until we get a newline
while (cache.find("\n") == string::npos) {
cout << "entered get request while loop" << endl;
int nread = recv(client,buf_,1024,0);
if (nread < 0) {
if (errno == EINTR)
// the socket call was interrupted -- try again
continue;
else
// an error occurred, so break out
return "";
} else if (nread == 0) {
// the socket is closed
return "";
}
// be sure to use append in case we have binary data
cache.append(buf_,nread);
cout << "cache: " << cache << " : " << endl;
}
int position = cache.find("\n");
if (position == -1){
request = cache;
cache = "";
}
else{
cout << "Cache position: " << position << endl;
request = cache.substr(0,position+1);
cache.erase(0,position+1);
}
cout << "request: " << request << " : " << endl;
return request;
}
This is the full server.cc file
#include "server.h"
#include <vector>
#include <map>
#include <sstream>
#include <iostream>
Server::Server(int port) {
// setup variables
port_ = port;
buflen_ = 1024;
buf_ = new char[buflen_+1];
// cache = "";
}
Server::~Server() {
delete[] buf_;
users.clear();
}
void
Server::run() {
// create and run the server
create();
serve();
}
void
Server::create() {
struct sockaddr_in server_addr;
// setup socket address structure
memset(&server_addr,0,sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port_);
server_addr.sin_addr.s_addr = INADDR_ANY;
// create socket
server_ = socket(PF_INET,SOCK_STREAM,0);
if (!server_) {
perror("socket");
exit(-1);
}
// set socket to immediately reuse port when the application closes
int reuse = 1;
if (setsockopt(server_, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0) {
perror("setsockopt");
exit(-1);
}
// call bind to associate the socket with our local address and
// port
if (bind(server_,(const struct sockaddr *)&server_addr,sizeof(server_addr)) < 0) {
perror("bind");
exit(-1);
}
// convert the socket to listen for incoming connections
if (listen(server_,SOMAXCONN) < 0) {
perror("listen");
exit(-1);
}
}
void
Server::close_socket() {
close(server_);
}
void
Server::serve() {
// setup client
int client;
struct sockaddr_in client_addr;
socklen_t clientlen = sizeof(client_addr);
// accept clients
while ((client = accept(server_,(struct sockaddr *)&client_addr,&clientlen)) > 0) {
handle(client);
}
close_socket();
}
Server::Message Server::parse_request(string request){
stringstream ss;
istringstream istr(request);
Message message;
message.needed = false;
message.valid = true;
message.user = "";
message.index = -1;
// istream_iterator<string> be
istr >> message.command;
//message.command = ss.str();
cout << "got command:" << message.command << ":" << endl;
if(message.command == "put")
{
istr >> message.user;
//ss << istr;
istr >> message.subject;
istr >> message.length;
cout << "message.length = " << message.length <<endl;
message.needed = false;
}
else if (message.command == "list"){
istr >> message.user;
message.needed = false;
message.length = 0;
}
else if (message.command == "get"){
istr >> message.user;
istr >> message.index;
message.needed = false;
message.length = 0;
}
else if (message.command == "reset"){
message.needed = false;
message.length = 0;
}
else{
cout << "I don't recognize that request.";
message.valid = false;
}
return message;
}
void Server::get_value(int client, Message message){
//call recv until all bytes needed are recieved
while(message.needed){
int nread = recv(client,buf_,1024,0);
if (nread < 0) {
if (errno == EINTR)
// the socket call was interrupted -- try again
continue;
else
// an error occurred, so break out
return;
} else if (nread == 0) {
// the socket is closed
return;
}
cache.append(buf_,nread);
cout << "cache length " << cache.size();
if(message.length <= cache.size()){
cout << "Message value " << message.value;
cout << "cache length " << cache.size();
message.needed = false;
message.value = cache.substr(0,message.length);
cache.erase(0,message.length);
cout << "Message value " << message.value;
cout << "cache length " << cache.size();
}
}
}
string
Server::get_request(int client) {
cout << "getting request" << endl;
string request = "";
// read until we get a newline
while (cache.find("\n") == string::npos) {
cout << "entered get request while loop" << endl;
int nread = recv(client,buf_,1024,0);
if (nread < 0) {
if (errno == EINTR)
// the socket call was interrupted -- try again
continue;
else
// an error occurred, so break out
return "";
} else if (nread == 0) {
// the socket is closed
return "";
}
// be sure to use append in case we have binary data
cache.append(buf_,nread);
cout << "cache: " << cache << " : " << endl;
}
int position = cache.find("\n");
// int position = 0;
// while (cache.find("/n") == string::npos)
// {
// position++;
// }
if (position == -1){
request = cache;
cache = "";
}
else{
cout << "Cache position: " << position << endl;
request = cache.substr(0,position+1);
cache.erase(0,position+1);
}
cout << "request: " << request << " : " << endl;
// a better server would cut off anything after the newline and
// save it in a cache
return request;
}
bool Server::send_response(int client, string response) {
// prepare to send response
cout << "sending response:" << response << ":" << endl;
const char* ptr = response.c_str();
int nleft = response.length();
int nwritten;
// loop to be sure it is all sent
while (nleft) {
if ((nwritten = send(client, ptr, nleft, 0)) < 0) {
if (errno == EINTR) {
// the socket call was interrupted -- try again
continue;
} else {
// an error occurred, so break out
perror("write");
return false;
}
} else if (nwritten == 0) {
// the socket is closed
return false;
}
nleft -= nwritten;
ptr += nwritten;
cout << "number written: " << nwritten << endl;
}
cout << "finished sending response " << endl;
return true;
}
bool Server::handle_response(int client, Message message) {
cout << "handling response" << endl;
bool success = false;
if(message.command == "put"){
if(message.length == 0){
return false;
}
message.value = cache.substr(0,message.length);
cache.erase(0,message.length);
if(subjects.count(message.user) == 0){
vector<string> userSubjects;
subjects[message.user] = userSubjects;
}
subjects[message.user].push_back(message.subject);
if(users.count(message.user) == 0){
vector<Message> messages;
users[message.user] = messages;
}
users[message.user].push_back(message);
// users.insert(message.user, message.subject);
cout << "sending response to client" << endl;
success = send_response(client, "OK\n");
}
else if("list" == message.command){
if(message.user == ""){
return false;
}
vector<string> currentSubjects = subjects[message.user];
cout << "subjects for message.user: " << message.user << endl;
stringstream sstream;
sstream << "list " << currentSubjects.size() << "\n";
//success = send_response(client, sstream.str());
// if(success == false){
// return false;
// }
// cout << "client sent user" << endl;
for (int i=0; i<currentSubjects.size(); i++){
// stringstream sstm;
sstream << (i+1) << " " << currentSubjects[i] << "\n";
}
success = send_response(client, sstream.str());
if(success == false){
return false;
}
// success = true;
cout << "message list sent successfully" << endl;
}
else if (message.command == "get"){
if(message.index == -1){
return false;
}
if(message.user == ""){
return false;
}
vector<Message> currentMessages = users[message.user];
if(message.index > currentMessages.size()){
return false;
}
stringstream sstm;
for (int i=0; i<currentMessages.size(); i++){
if ((i+1) == message.index){
sstm << "message " << currentMessages[i].subject << " " << currentMessages[i].length << "\n" << currentMessages[i].value;
cout << "message.value = " << currentMessages[i].value << endl;
}
}
cout << "message to send " << sstm.str() << endl;
success = send_response(client, sstm.str());
if(success == false){
return false;
}
// success = true;
}
else if (message.command == "reset"){
users.clear();
subjects.clear();
success = send_response(client, "OK\n");
// success = true;
}
else {
debug = true;
if (debug == true){
cout << "Debug message: " << "No valid command found in handle" << endl;
}
}
return success;
}
void
Server::handle(int client) {
// loop to handle all requests
while (1) {
// get a request
cout << "looking for new request" << endl;
string request = get_request(client);
cout << "request = " << request << endl;
// break if client is done or an error occurred
if (request.empty()) {
cout << "empty request" << endl;
break;
}
cout << "request:" << request << ":" << endl;
//parse
Message message = parse_request(request);
cout << "finished parsing" << endl;
if(message.valid == false){
cout << "invalid message" << endl;
send_response(client, "error unrecognized command\n");
cout << "cache after break from bad command: " << cache << endl;
continue;
}
if(message.length > cache.size()){
message.needed = true;
cout << "message length greater than cache size" << endl;
cout << "cache.size = " << cache.size() << endl;
}
if(message.needed){
get_value(client, message);
}
// handle message
bool success = handle_response(client, message);
cout << "finished handling response" << endl;
cout << "cache after handle: " << cache << " : " << endl;
// break if an error occurred
if (!success) {
cout << "error handling request" << endl;
send_response(client, "error handling request\n");
continue;
}
cout << "end of request" << endl;
}
close(client);
}

segfault variable creation c++

So I'm having some troubles with a segfault right now.
The problem appears to be on line 122
file_stream.read(binaryData, fileSizeInt);
The message seems to be unable to create variable object.
I'm using the debugger on CLion, if this is of any help.
I'm fairly new to C++ so please bear with me on this. I've included my source code below, since I have no idea what will and wont be relevant.
#include <fstream>
#include <iostream>
#include <math.h>
using namespace std;
//string dataLocation = "/dev/rdisk2"; // Variable for the mounting point of the SD Card.
string dataLocation = "/Volumes/Untitled/data/smith_data_backup.dat"; // Test location
int sectorSize = 512;
int bytesRead = 0;
string outDir = "/Volumes/Untitled/data/readData/";
char data_stop[10] = "Data_Stop";
char* findHeader(char* inputData) {
int i = 1;
//look for the end of the header
while(true) {
//cout << data[i] << '\n';
if (inputData[i] == '}') {
// found the end of the header
cout << "found the end of the header" << '\n';
break;
}
if (i > 200) { // don't get into an infinite loop here
cout << "something went wrong here" << '\n';
break;
}
i++;
}
// copy the header to a new char array
char* header = new char[i+1];
memcpy(header, &inputData[0], (size_t) (i +1));
return header;
}
int main() {
ifstream file_stream;
file_stream.open(dataLocation);
for( int j = 0; j < 10; j++ ) {
char data[sectorSize]; // figure out a decent size for this.....
string date = "";
string time = "";
string site = "";
string intId = "";
string totalFiles = "";
string fileNo = "";
string fileSize = "";
try {
// read the data file... this will be fun
cout << "Reading the data file" << '\n';
file_stream.read(data, sectorSize);
bytesRead += sectorSize;
if (data[0] == '{') {
char *header = findHeader(data);
cout << header << '\n';
//loop over the header to find the date, time, site ID, Instrument ID, and expected file size.
int commasFound = 0;
for(int i = 1; header[i] != '}', i++;) {
// increment the number of commas that have been found
if (header[i] == ',') {
commasFound ++;
continue;
}
//check for the end f the header
if (header[i] == '}') {
break;
}
//for some reason the first one never gets added
if (i==2) {
date += header[1];
}
// append to appropriate strings based on the number of commas that have been passed in the header
if (commasFound == 0) {
date += header[i];
}
if (commasFound == 1 && time.length() < 6) {
time += header[i];
}
if (commasFound == 2) {
fileNo += header[i];
}
if (commasFound == 6) {
site += header[i];
}
if (commasFound == 8) {
intId += header[i];
}
if (commasFound == 16) {
fileSize += header[i];
}
if (commasFound == 17) {
totalFiles += header[i];
}
//paranoia of infinite loops
if (i > 150) {
break;
}
}
string formattedDate = "20" + date.substr(4,2) + date.substr(2,2) + date.substr(0,2);
cout << formattedDate << " " << time << " " << " " << site << " " << intId << " " << fileSize << " " << totalFiles<< " " << '\n';
// Read in the data size
int fileSizeInt = atoi(fileSize.c_str()) * atoi(fileSize.c_str());
char binaryData[fileSizeInt];
file_stream.read(binaryData, fileSizeInt);
bytesRead += fileSizeInt;
string dateDir = outDir + formattedDate.substr(0,4) + "/" + date.substr(2,2) + "/" + site + "/" + date.substr(0,2) + "/";
string fileName = dateDir + formattedDate + "_" + time + "_" + site + "_" + intId + "_Full_Data.dat";
//cout << fileName << '\n';
//create the directory with the date.
string mkdirCommand = "mkdir -p " + dateDir;
system(mkdirCommand.c_str());
cout << "size " << sizeof(binaryData) << '\n';
//write data to file
try {
cout << "Write the data file " << '\n';
cout << header << " " << strlen(header) << '\n';
ofstream outFile;
outFile.open(fileName.c_str());
outFile.write(header, strlen(header));
outFile.write(binaryData, sizeof(binaryData));
outFile.write(data_stop, sizeof(data_stop));
outFile.close();
} catch (ofstream::failure e ) {
cout << "Unable to write the file " << fileName << '\n';
}
//read till the start of the next sector
int nextSector = (int) ceil(((double) bytesRead)/512.0);
int startOfNextSector = nextSector * 512;
cout << startOfNextSector << '\n';
int bytesToRead = startOfNextSector - bytesRead;
char dump[bytesToRead];
file_stream.read(dump, bytesToRead);
bytesRead += bytesToRead;
// The first block may be empty, quick check to see if the first block needs to be skipped
} else if (j == 0 && data[0] != '{') {
cout << "Skipping the first block" << '\n';
continue;
} else {
//cout << "no start here....." << bytesRead << '\n';
}
}
catch (ifstream::failure& e) {
cout << "Error" << "\n";
break;
}
}
file_stream.close();
return 0;
}