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.
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;
}
I am trying to get information about all attached devices.
This is my code:
libusb_device_descriptor desc;
libusb_config_descriptor *conDesc;
char szBuffer[256] = { 0 };
unsigned char strDesc[256];
libusb_device_handle *devHandle = NULL;
int retVal = 0;
__int64 i64Temp;
DWORD dwProdId;
DWORD dwProdId1;
i64Temp = 13888;
dwProdId = (DWORD)i64Temp;
retVal = libusb_open(dev, &devHandle);
int r = libusb_get_device_descriptor(dev, &desc);
if (r < 0)
{
cout << "failed to get device descriptor" << endl;
return;
}
r = libusb_get_config_descriptor(dev, 0, &conDesc);
printf("Interface Class = %d\n", conDesc->interface->altsetting->bInterfaceClass);
cout << "Number of possible configurations: " << (int)desc.bNumConfigurations << "" << endl;
cout << "Device Class: " << desc.bDeviceClass << endl;
cout << "Device Class: " << desc.bDeviceSubClass << endl;
printf("Class = %d\n", desc.bDeviceClass);
cout << "VendorID: " << desc.idVendor << endl;
cout << "ProductID: " << desc.idProduct << endl;
if (retVal == LIBUSB_SUCCESS)
{
retVal = libusb_get_string_descriptor_ascii(devHandle, desc.iManufacturer, strDesc, 256);
printf("Manufacturer: %s\n", strDesc);
retVal = libusb_get_string_descriptor_ascii(devHandle, desc.iSerialNumber, strDesc, 256);
printf("SerialNumber: %s\n", strDesc);
retVal = libusb_get_string_descriptor_ascii(devHandle, desc.iProduct, strDesc, 256);
printf("Product: %s\n", strDesc);
printf("\n\n");
}
else if (retVal != LIBUSB_SUCCESS)
{
printf("retVal failed");
printf("\n\n");
}
My code knows that there are 8 devices connected but it's getting manufacturer or serial number only on two of them. I would like to get this information for all of the attached devices.
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);
}
So my code compiles well, but whenever I try running the program, it seg faults. I ran it through gdb and got this set of error:
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_S_construct null not valid
Program received signal SIGABRT, Aborted.
0x00007ffff722bcc9 in __GI_raise (sig=sig#entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56 ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
Here is my code if it helps:
using namespace std;
#include <iostream>
#include <vector>
#include <cmath>
#include<fstream>
#include <cstdlib>
#include <utility>
#include <string>
class Page
{
public:
int TimeStamp;
int ProgramOwner;
int LocalPageNumber;
};
//Pair: first entry is local page, second entry is global page
//Second entry: 1 if in main memory, 0 if not
class Program
{
public:
vector< pair<int,int> > MemoryMap;
};
class Memory
{
public:
vector<Program> Programs;
vector<Page> Pages;
};
void checkArguments(int argc, char *argv[]);
bool checkPageAlgorithm(char *argv[]);
bool checkPageSize(int pagesize);
bool checkPageStyle(char *argv[]);
bool checkPTrace(string ProgramTraceFile);
bool checkPList(string ProgramListFile);
int main(int argc, char *argv[])
{
//checkArguments(argc, argv);
const int MemSize = 512;
int pageSize = atoi(argv[3]);
string programListFile = argv[1];
string ProgramTraceFile = argv[2];
string pageAlgorithm = argv[4];
string pageStyle = argv[5];
int programNumber;
int programSize;
int PagesNeeded;
Memory MainMemory;
int numberFrames;
int pageFaults = 0;
int numPrograms = 0;
int PagesPerProgram;
int LocalPage;
int activeProgram;
int requestedLocation;
int newPageLocation;
bool foundInMemory;
ifstream fileIn;
fileIn.open(programListFile.c_str());
if(fileIn.fail())
{
cerr << "List file not found." << endl;
fileIn.close();
exit(1);
}
else
{
while(!fileIn.eof())
{
cout << "hey0";
fileIn >> programNumber;
fileIn >> programSize;
numPrograms++;
}
}
numberFrames = ceil(MemSize/pageSize);
PagesPerProgram = ceil(numberFrames/numPrograms);
MainMemory.Pages.resize(numberFrames);
cout << "hey1";
while(!fileIn.eof())
{
cout << "hey2";
fileIn >> programNumber;
fileIn >> programSize;
cout << "hey3";
PagesNeeded = ceil(programSize/pageSize);
for(int i = 0; i < PagesNeeded; i++)
{
LocalPage = i;
MainMemory.Pages[i].ProgramOwner = programNumber;
MainMemory.Pages[i].LocalPageNumber = LocalPage;
}
cout << "hey3";
if(PagesNeeded > PagesPerProgram)
PagesNeeded = PagesPerProgram;
for(int i = 0; i < PagesNeeded; i++)
{
MainMemory.Programs[programNumber].MemoryMap[i].first = MainMemory.Pages[i].LocalPageNumber;
MainMemory.Programs[programNumber].MemoryMap[i].second = 1;
if(pageAlgorithm == "clock")
MainMemory.Pages[i].TimeStamp = 1;
else
MainMemory.Pages[i].TimeStamp = 0;
}
}
fileIn.close();
//LRU Algorithm Implementation
if(pageAlgorithm == "lru")
{
cout << "here1";
fileIn.open(ProgramTraceFile.c_str());
if(fileIn.fail())
{
cerr << "That file does not exist." << endl;
fileIn.close();
exit(1);
}
else
{
fileIn >> activeProgram;
fileIn >> requestedLocation;
newPageLocation = ceil(requestedLocation/pageSize);
while(!fileIn.eof())
{
foundInMemory = false;
for(int i = 0; i < static_cast<int>(MainMemory.Programs[activeProgram].MemoryMap.size()); i++)
{
if((MainMemory.Programs[activeProgram].MemoryMap[i].second == 1) &&
(MainMemory.Programs[activeProgram].MemoryMap[i].first == newPageLocation))
foundInMemory = true;
if(foundInMemory)
break;
}
if(!foundInMemory)
{
pageFaults++;
if(static_cast<int>(MainMemory.Programs[activeProgram].MemoryMap.size()) < PagesPerProgram)
{
pair<int, int> temp;
temp.first = newPageLocation;
temp.second = 1;
MainMemory.Programs[activeProgram].MemoryMap.push_back(temp);
}
else
{
for(int i = 0; i < (static_cast<int>(MainMemory.Programs[activeProgram].MemoryMap.size()) - 1); i++)
{
if(MainMemory.Pages[i].TimeStamp >= MainMemory.Pages[i+1].TimeStamp)
{
MainMemory.Programs[activeProgram].MemoryMap[i].first = newPageLocation;
}
if(pageStyle == "1")
{
if(MainMemory.Pages[i].TimeStamp >= MainMemory.Pages[i+1].TimeStamp)
{
MainMemory.Programs[activeProgram].MemoryMap[i].first = MainMemory.Pages[i].LocalPageNumber;
}
}
MainMemory.Pages[i].TimeStamp++;
}
}
}
fileIn >> activeProgram;
fileIn >> requestedLocation;
newPageLocation = ceil(requestedLocation/pageSize);
}
}
}
cout << "------------------------------------" << endl;
cout << "Page Size: " << pageSize << endl;
cout << "Page Replacement Algorithm: " << pageAlgorithm << endl;
cout << "Paging Style: ";
if(pageStyle == "0")
cout << "Demand" << endl;
else
cout << "Prepaging" << endl;
cout << "Number of Page Faults: " << pageFaults << endl;
cout << "------------------------------------" << endl;
return 0;
}
bool checkPList(string programlistfile)
{
ifstream ListFile(programlistfile.c_str());
if(ListFile.fail())
{
cerr << "Cannot find file " << programlistfile << endl;
ListFile.close();
return false;
}
else
{
ListFile.close();
return true;
}
}
bool checkPTrace(string programTraceFile)
{
ifstream TraceFile;
TraceFile.open(programTraceFile.c_str());
if(TraceFile.fail())
{
cerr << "Cannot find file " << programTraceFile << endl;
TraceFile.close();
return false;
}
else
{
TraceFile.close();
return true;
}
}
bool checkPageStyle(string pageStyle)
{
if(pageStyle == "0")
return true;
else if(pageStyle == "1")
return true;
else
{
cerr << "Page Style can be: 0 or 1." << endl;
return false;
}
}
bool checkPageSize(int pagesize)
{
bool isValid = false;
switch(pagesize)
{
case 1:
isValid = true;
break;
case 2:
isValid = true;
break;
case 4:
isValid = true;
break;
case 8:
isValid = true;
break;
case 16:
isValid = true;
break;
default:
cerr << "Page Size can be: 1, 2, 4, 8, or 16." << endl;
isValid = false;
}
return isValid;
}
bool checkPageAlgorithm(string pageAlgorithm)
{
if(pageAlgorithm == "lru")
return true;
else if(pageAlgorithm == "fifo")
return true;
else if(pageAlgorithm == "clock")
return true;
else
{
cerr << "Valid Page Algorithms are: lru, fifo, or clock" << endl;
return false;
}
}
void checkArguments(int argc, char *argv[])
{
if(argc < 6)
{
cerr << "Invalid number of arguments. Should be: programlist programtrace pagesize pagealgorithm pagingstyle" << endl;
exit(1);
}
else if(argc > 6)
{
cerr << "Invalid number of arguments. Should be: programlist programtrace pagesize pagealgorithm pagingstyle" << endl;
exit(1);
}
else if(!checkPageAlgorithm(argv[4]))
exit(1);
else if(!checkPageSize(atoi(argv[3])))
exit(1);
else if(!checkPageStyle(argv[5]))
exit(1);
else if(!checkPTrace(argv[2]))
exit(1);
else if(!checkPList(argv[1]))
exit(1);
return;
}
The output 'heys' are just to see if they get triggered within gdb, which they don't.
You forgot to actually ask any question.
Presumably, your question is "why does my program die with SIGABRT?"
The answer was provided by the program itself: you've tried to construct std::string from a NULL character pointer, which throws std::logic_error exception (because it's not a valid thing to do).
You may have a follow-up quesiton: "where in my program does this happen?".
You could find the answer by using GDB where command. As a first guess, you didn't invoke your program with sufficient number of arguments. For example, if you did this:
gdb ./a.out
(gdb) run
then argv[1] is NULL, and this statement:
string programListFile = argv[1];
would throw the exception you are getting.
The common solution to this problem is to insist that you do have correct number of arguments, e.g. put this:
if (argc < 6) {
std::cerr << "Not enough arguments" << std::endl;
return 1;
}
at the start of main. Or just comment the call to checkArguments() back in.