
Recherche avancée
Médias (1)
-
Bug de détection d’ogg
22 mars 2013, par
Mis à jour : Avril 2013
Langue : français
Type : Video
Autres articles (28)
-
Des sites réalisés avec MediaSPIP
2 mai 2011, parCette page présente quelques-uns des sites fonctionnant sous MediaSPIP.
Vous pouvez bien entendu ajouter le votre grâce au formulaire en bas de page. -
Emballe médias : à quoi cela sert ?
4 février 2011, parCe plugin vise à gérer des sites de mise en ligne de documents de tous types.
Il crée des "médias", à savoir : un "média" est un article au sens SPIP créé automatiquement lors du téléversement d’un document qu’il soit audio, vidéo, image ou textuel ; un seul document ne peut être lié à un article dit "média" ; -
Automated installation script of MediaSPIP
25 avril 2011, parTo overcome the difficulties mainly due to the installation of server side software dependencies, an "all-in-one" installation script written in bash was created to facilitate this step on a server with a compatible Linux distribution.
You must have access to your server via SSH and a root account to use it, which will install the dependencies. Contact your provider if you do not have that.
The documentation of the use of this installation script is available here.
The code of this (...)
Sur d’autres sites (4706)
-
audio do not stop recording after pause ffmpeg c++
15 septembre 2021, par C1ngh10I 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 mainwhile
. 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;
}



-
Segmentation fault on debian 9 when decoding audio with ffmpeg and libopus
27 août 2021, par Ramil DautovI wrote the program that takes as an input some .opus file, decodes it using libavcodec and libopus and then plays it using SDL2. Program works on Windows 10 and Ubuntu 18.04, however it crashes with the segmentation fault on Debian 9.


I've tried to update libavcodec and libopus libraries, tried to compile using clang and gcc - nothing helped.


Address sanitizer shows that stack overflow happens :


ASAN:DEADLYSIGNAL
=================================================================
==12167==ERROR: AddressSanitizer: stack-overflow on address 0x2b3e74c81ff8 (pc 0x2b3e7a098803 bp 0x2b3e74c82690 sp 0x2b3e74c81eb0 T2)
 #0 0x2b3e7a098802 in quant_all_bands celt/bands.c:1403
 #1 0x2b3e7a0a2a37 in celt_decode_with_ec celt/celt_decoder.c:1083
 #2 0x2b3e7a0c8afb in opus_decode_frame src/opus_decoder.c:518
 #3 0x2b3e7a0c9e40 in opus_decode_native src/opus_decoder.c:721
 #4 0x2b3e7a0d33f3 in opus_multistream_decode_native src/opus_multistream_decoder.c:253
 #5 0x2b3e7a0d37a8 in opus_multistream_decode src/opus_multistream_decoder.c:398
 #6 0x2b3e760ad83c (/usr/lib/x86_64-linux-gnu/libavcodec.so.57+0x43583c)
 #7 0x2b3e75e4ca27 (/usr/lib/x86_64-linux-gnu/libavcodec.so.57+0x1d4a27)
 #8 0x2b3e75e4f62a in avcodec_send_packet (/usr/lib/x86_64-linux-gnu/libavcodec.so.57+0x1d762a)
 #9 0x2b3e75e4f9e6 (/usr/lib/x86_64-linux-gnu/libavcodec.so.57+0x1d79e6)
 #10 0x55ef09511882 in decode(AVCodecContext*, AVPacket*, unsigned char*, int) /home/ram/my/player3/speaker.cpp:296
 #11 0x55ef09511626 in fillBuffer(AVCodecContext*, unsigned char*, int) /home/ram/my/player3/speaker.cpp:251
 #12 0x55ef09511294 in process(AVCodecContext*, unsigned char*, int) /home/ram/my/player3/speaker.cpp:194
 #13 0x55ef095105b9 in audio_callback(void*, unsigned char*, int) /home/ram/my/player3/speaker.cpp:69
 #14 0x2b3e7815cc31 (/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0+0x1fc31)
 #15 0x2b3e781bcf8b (/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0+0x7ff8b)
 #16 0x2b3e7820c6c8 (/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0+0xcf6c8)
 #17 0x2b3e77be74a3 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x74a3)
 #18 0x2b3e7940ed0e in __clone (/lib/x86_64-linux-gnu/libc.so.6+0xe8d0e)

SUMMARY: AddressSanitizer: stack-overflow celt/bands.c:1403 in quant_all_bands
Thread T2 (SDLAudioDev2) created by T0 here:
 #0 0x2b3e74d0df59 in __interceptor_pthread_create (/usr/lib/x86_64-linux-gnu/libasan.so.3+0x30f59)
 #1 0x2b3e7820c732 (/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0+0xcf732)




I also tried to increase stack size using ulimit -s unlimited and tried to increase stack size for the thread that starts decoding, didn't work.


In main.cpp file I have this :


#include <iostream>
#include <memory>
#include <mutex>
#include "speaker.h"
#include "SDL2/SDL.h"

extern "C"{
#include <libavutil></libavutil>opt.h>
#include <libavcodec></libavcodec>avcodec.h>
#include <libavformat></libavformat>avformat.h>
#include <libswresample></libswresample>swresample.h>
}

static int decode_audio_file(const char* path) {
 
 av_register_all();

 // get format from audio file
 AVFormatContext* format = avformat_alloc_context();
 if (avformat_open_input(&format, path, NULL, NULL) != 0) {
 std::cout << "Could not open file" << std::endl;
 return -1;
 }
 if (avformat_find_stream_info(format, NULL) < 0) {
 std::cout << "Could not retrieve stream info from file" << std::endl;
 return -1;
 }

 // Find the index of the first audio stream
 int stream_index =- 1;
 for (int i=0; i< format->nb_streams; i++) {
 if (format->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
 stream_index = i;
 break;
 }
 }
 if (stream_index == -1) {
 std::cout << "Could not retrieve audio stream from file" << std::endl;
 return -1;
 }
 AVStream* stream = format->streams[stream_index];

 // Initialize speaker
 init_Speaker("OPUS",
 48000,
 2,
 15,
 3,
 av_get_channel_layout("stereo"),
 av_get_sample_fmt("s16"));

 // prepare to read data
 AVPacket* packet;
 packet = av_packet_alloc();
 av_init_packet(packet);

 // iterate through frames
 while (av_read_frame(format, packet) >= 0) {
 play(packet->data, packet->size, std::chrono::microseconds{packet->pts},
 std::chrono::microseconds{packet->dts});
 av_packet_unref(packet);
 }

 // clean up
 avformat_free_context(format);
 close_Speaker();

 // success
 return 0;
}

int main(int argc, char const *argv[]) {
 // check parameters
 if (argc < 2) {
 std::cout << "Please provide the path to an audio file as first command-line argument.\n";
 return -1;
 }

 // Init Audio
 SDL_Init(SDL_INIT_AUDIO);

 // decode data
 if (decode_audio_file(argv[1]) != 0) {
 return -1;
 }

 std::cout << "Finish" << std::endl;
 return 0;
}

</mutex></memory></iostream>


In speaker.cpp :


#include "speaker.h"
#include "pthread.h"
#include "avcodec.h"
#include "common.h"
#include <iostream>

extern "C"
{
#include <libswresample></libswresample>swresample.h>
#include <libavutil></libavutil>hwcontext.h>
}

using std::chrono::microseconds;

SDL_AudioDeviceID m_id;

AVCodecParserContext *parser = nullptr;

//
constexpr static auto buffer_size{1024}; // 2048
constexpr static auto buffer_max_size{AVCODEC_MAX_AUDIO_FRAME_SIZE * 4};
uint32_t m_samplerate;
uint32_t m_queue_limit;
uint32_t m_queue_dropfactor;
int64_t m_channel_layout;
AVSampleFormat m_device_format;
AVCodecID audio_codec_id{AV_CODEC_ID_NONE};
AVCodecContext* adecoder;

player::PacketQueue queue(0, true); 


static uint8_t* buf = nullptr;
uint32_t absize{};
uint32_t abpos{};
int32_t max_decoder_size{};
// need a converter?
uint8_t* convbuf{};
SwrContext* swrctx{};
int32_t sframes{};
AVCodec* codec{};

uint8_t * audio_buffer_init() {
 if(buf == nullptr) {
 buf = (uint8_t*) malloc(buffer_max_size);
 if(buf == nullptr) {
 return nullptr;
 }
 }
 return buf;
}

void audio_callback(void* userdata, uint8_t* stream, int len) {
 AVCodecContext* decoder = (AVCodecContext*)userdata;
 process(decoder, stream, len);
};

void init_Speaker(const std::string& codecName,
 int32_t samplerate,
 uint8_t channels,
 uint32_t queue_limit,
 uint32_t queue_dropfactor,
 int64_t channel_layout,
 AVSampleFormat format)
{
 m_samplerate = samplerate;
 m_queue_limit = queue_limit;
 m_queue_dropfactor = queue_dropfactor;
 m_device_format = format;
 m_channel_layout = channel_layout;


 SDL_SetHint(SDL_HINT_THREAD_STACK_SIZE, "8388608");

 if(codecName.empty())
 throw std::runtime_error("audio decoder: no codec specified.");

 auto names = player::lookup_ffmpeg_decoders(codecName);
 if(names == nullptr)
 throw std::runtime_error("audio decoder: cannot find decoder names for {}"+codecName);

 audio_codec_id = player::lookup_codec_id(codecName);
 codec = player::avcodec_find_decoder(names, AV_CODEC_ID_NONE);
 if(codec == nullptr)
 throw std::runtime_error("audio decoder: cannot find the decoder for {}"+codecName);

 adecoder = avcodec_alloc_context3(codec);
 if(adecoder == nullptr)
 throw std::runtime_error("audio decoder: cannot allocate context");

 adecoder->channels = channels;
 adecoder->sample_rate = samplerate;
 if(adecoder->channels == 1)
 {
 adecoder->channel_layout = AV_CH_LAYOUT_MONO;
 }
 else if(adecoder->channels == 2)
 {
 adecoder->channel_layout = AV_CH_LAYOUT_STEREO;
 }
 else
 throw std::runtime_error("audio decoder: unsupported number of channels ({})"+ adecoder->channels);
 

 if(avcodec_open2(adecoder, codec, nullptr) != 0)
 throw std::runtime_error("audio decoder: cannot open decoder");

 parser = av_parser_init(codec->id);

 SDL_AudioSpec wanted, spec;
 wanted.freq = samplerate;
 wanted.format = AUDIO_S16SYS;
 wanted.channels = channels;
 wanted.silence = 0;
 wanted.samples = buffer_size;
 wanted.userdata = adecoder;
 wanted.callback = audio_callback;
 

 m_id = SDL_OpenAudioDevice(nullptr, 0, &wanted, &spec, 0);
 if(m_id == 0)
 throw std::runtime_error(SDL_GetError());

 SDL_PauseAudioDevice(m_id, 0);
}

void close_Speaker()
{
 SDL_CloseAudioDevice(m_id);
 
 if(adecoder != nullptr)
 player::avcodec_close(adecoder);

}

void play(uint8_t* buffer, size_t bufsize, microseconds pts, microseconds dts)
{
 if(!buffer || !bufsize) {
 return;
 }
 
 AVPacket* avpkt;
 avpkt = av_packet_alloc();
 av_init_packet(avpkt);
 uint8_t bf[bufsize + 64];
 memcpy(bf, buffer, bufsize);

 av_parser_parse2(parser, adecoder, &avpkt->data, &avpkt->size,
 bf, bufsize,
 pts.count(), dts.count(), 0);

 queue.put(av_packet_clone(avpkt));
 queue.drop(m_queue_limit, m_queue_dropfactor); 

}

//

void process(AVCodecContext* decoder, uint8_t* stream, int ssize)
{
 auto filled = fillBuffer(decoder, stream, ssize);

 auto unfilled{(ssize - filled) / 4};
 auto dummy{sframes};

 sframes = unfilled == 0 ? 0 : sframes + unfilled;
 memset(stream + filled, 0, unfilled * 4);
 
 if(sframes != dummy)
 queue.add_silence((int64_t)sframes * 1000000 / m_samplerate);
}

int fillBuffer(AVCodecContext* decoder, uint8_t* stream, int ssize)
{
 int filled{};
 AVPacket avpkt;
 audio_buffer_init();
 while(filled < ssize)
 {
 int dsize{}, delta{};

 // buffer has enough data
 if(absize - abpos >= static_cast<unsigned int="int">(ssize - filled))
 {
 delta = ssize - filled;
 std::copy(buf + abpos, buf + abpos + delta, stream);
 abpos += delta;
 filled += delta;
 return ssize;
 }
 else if(absize - abpos > 0)
 {
 delta = absize - abpos;
 std::copy(buf + abpos, buf + abpos + delta, stream);
 stream += delta;
 filled += delta;
 abpos = absize = 0;
 }
 // move data to head, leave more ab buffers
 if(abpos != 0)
 {
 std::copy(buf + abpos, buf + abpos + absize - abpos, buf);
 absize -= abpos;
 abpos = 0;
 }
 // decode more packets
 if(!queue.get(&avpkt, false))
 break;
 if((dsize = decode(decoder, &avpkt, buf + absize, buffer_max_size - absize)) < 0)
 break;
 absize += dsize;
 }

 return filled;
}

int decode(AVCodecContext* decoder, AVPacket* pkt, uint8_t* dstbuf, int dstlen)
{
 const uint8_t* srcplanes[SWR_CH_MAX];
 uint8_t* dstplanes[SWR_CH_MAX];
 int filled{};

 AVFrame* aframe = av_frame_alloc();

 auto saveptr = pkt->data;

 while(pkt->size > 0)
 {
 int len{}, got_frame{};
 unsigned char* srcbuf{};
 int datalen{};

 if((len = avcodec_decode_audio4(decoder, aframe, &got_frame, pkt)) < 0)
 {
 return -1;
 }
 if(got_frame == 0)
 {
 pkt->size -= len;
 pkt->data += len;
 continue;
 }

 if(aframe->format == m_device_format)
 {
 datalen = av_samples_get_buffer_size(nullptr,
 aframe->channels /*rtspconf->audio_channels*/,
 aframe->nb_samples,
 (AVSampleFormat)aframe->format,
 1 /*no-alignment*/);
 srcbuf = aframe->data[0];
 }
 else
 {
 // need conversion!
 if(swrctx == nullptr)
 {
 if((swrctx = swr_alloc_set_opts(nullptr,
 m_channel_layout,
 m_device_format,
 m_samplerate,
 aframe->channel_layout,
 (AVSampleFormat)aframe->format,
 aframe->sample_rate,
 0,
 nullptr)) == nullptr)
 {
 return -1;
 }
 auto err = swr_init(swrctx);
 if(err < 0)
 {
 char msg[1024];
 av_strerror(err, msg, 1024);
 return -1;
 }
 max_decoder_size = av_samples_get_buffer_size(nullptr,
 2, 
 m_samplerate,
 m_device_format,
 1 /*no-alignment*/);
 if((convbuf = (unsigned char*)::malloc(max_decoder_size)) == nullptr)
 {
 return -1;
 }
 }
 datalen = av_samples_get_buffer_size(nullptr,
 2,
 aframe->nb_samples,
 m_device_format,
 1 /*no-alignment*/);
 if(datalen > max_decoder_size)
 {
 return -1;
 }
 srcplanes[0] = aframe->data[0];
 if(av_sample_fmt_is_planar((AVSampleFormat)aframe->format) != 0)
 {
 // planar
 int i;
 for(i = 1; i < aframe->channels; i++)
 {
 srcplanes[i] = aframe->data[i];
 }
 srcplanes[i] = nullptr;
 }
 else
 {
 srcplanes[1] = nullptr;
 }
 dstplanes[0] = convbuf;
 dstplanes[1] = nullptr;

 swr_convert(swrctx, dstplanes, aframe->nb_samples, srcplanes, aframe->nb_samples);
 srcbuf = convbuf;
 }
 if(datalen > dstlen)
 {
 datalen = dstlen;
 }

 std::copy(srcbuf, srcbuf + datalen, dstbuf);
 dstbuf += datalen;
 dstlen -= datalen;
 filled += datalen;

 pkt->size -= len;
 pkt->data += len;
 av_frame_unref(aframe);
 }
 pkt->data = saveptr;
 if(pkt->data)
 av_packet_unref(pkt);
 if(aframe != nullptr)
 av_frame_free(&aframe);
 
 return filled;
}
</unsigned></iostream>


In packet_queue.cpp :


#include "packet_queue.h"

using player::PacketQueue;
using lock_guard = std::lock_guard;
using unique_lock = std::unique_lock;
using std::chrono::milliseconds;

PacketQueue::PacketQueue(uint32_t playback_queue_silence, bool playback_queue_debug) :
 m_playback_queue_debug(playback_queue_debug), m_playback_queue_silence(playback_queue_silence)
{
}

void PacketQueue::clear()
{
 lock_guard lk{m_mtx};
 for(auto& pkt : queue)
 av_packet_unref(pkt);

 m_size = 0;
 queue.clear();
}

void PacketQueue::add_silence(int64_t silence_pts)
{
 if(m_playback_queue_silence == 0)
 {
 return;
 }

 lock_guard lk{m_mtx};
 silence_pts = filtered_packets > 0 ? silence_pts : last_pts + silence_pts;

 auto tv = std::chrono::microseconds{last_pts};
 auto tv2 = std::chrono::microseconds{silence_pts};
}

bool PacketQueue::put(AVPacket* pkt)
{
 if(pkt == nullptr)
 {
 return false;
 }

 lock_guard lk{m_mtx};
 if((silence_pts - pkt->pts) > (m_playback_queue_silence * 1000))
 {
 auto tv = std::chrono::microseconds{pkt->pts};
 filtered_packets++;
 if(m_playback_queue_debug)
 return true;
 }

 queue.push_back(pkt);
 filtered_packets = 0;
 return true;
}

bool PacketQueue::get(AVPacket* pkt, bool block, milliseconds timeout)
{
 unique_lock lk{m_mtx};

 for(;;)
 {
 if(queue.size() > 0)
 {
 auto ptr = queue.front();
 queue.pop_front();
 m_size -= ptr->size;
 last_pts = ptr->pts;
 av_packet_move_ref(pkt, ptr);
 return true;
 }
 else if(!block)
 {
 return false;
 }
 else if(!m_cv.wait_for(lk, timeout, [&] { return !queue.empty(); }))
 {
 return false;
 }

 }
 return false;
}

bool PacketQueue::drop(size_t limit, size_t dropfactor)
{
 int dropped, count = 0;

 lock_guard lk{m_mtx};

 // queue size exceeded?
 if(queue.size() <= limit)
 {
 return false;
 }

 // start dropping
 dropped = queue.size() / dropfactor;
 // keep at least one
 if(dropped == queue.size())
 dropped--;

 AVPacket* pkt;
 while(dropped-- > 0 && !queue.empty())
 {
 pkt = queue.front();

 if(pkt->flags != AV_PKT_FLAG_KEY)
 {
 queue.pop_front();
 m_size -= pkt->size;
 av_packet_unref(pkt);
 ++count;
 }
 }

 return true; // count;
}

int PacketQueue::drop2(size_t limit, bool error)
{
 int count = 0;

 // dropping enabled?
 if(limit <= 0 && !error)
 return 0;

 lock_guard lk{m_mtx};
 // queue size exceeded?
 if(queue.size() <= limit && !error)
 return false;

 for(auto i = queue.begin(); i != queue.end();)
 {
 AVPacket* pkt = *i;
 if(pkt->flags != AV_PKT_FLAG_KEY)
 {
 m_size -= pkt->size;
 av_packet_unref(pkt);
 i = queue.erase(i);
 count++;
 }
 else
 ++i;
 }

 return count;
}



1403 line of celt/bands.c :
screenshot


Versions of libraries that I tried on Debian 9 :
libavcodec.so.57.64.101 and libopus.so.0.5.3


also I built manually libavcodec.so.57.107.100 and libopus.so.0.8.0 and tried to use them - the same error appears.


As I already mentioned, everything works fine on Windows 10 and Ubuntu 18.04. So I have no clue what could be the reason of the issue. Any help is appreciated.


-
Use Named Pipe (C++) to send images to FFMPEG
28 août 2015, par user1829136I have the following code in C++ :
#include <iostream>
#include
#include <iostream> // std::cout
#include <fstream> // std::ifstream
#include <vector>
#include
using namespace std;
int main(int argc, const char **argv)
{
wcout << "Creating an instance of a named pipe..." << endl;
// Create a pipe to send data
HANDLE pipe = CreateNamedPipe(
L"\\\\.\\pipe\\my_pipe", // name of the pipe
PIPE_ACCESS_OUTBOUND, // 1-way pipe -- send only
PIPE_TYPE_BYTE, // send data as a byte stream
1, // only allow 1 instance of this pipe
0, // no outbound buffer
0, // no inbound buffer
0, // use default wait time
NULL // use default security attributes
);
if (pipe == NULL || pipe == INVALID_HANDLE_VALUE) {
wcout << "Failed to create outbound pipe instance.";
// look up error code here using GetLastError()
system("pause");
return 1;
}
wcout << "Waiting for a client to connect to the pipe..." << endl;
// This call blocks until a client process connects to the pipe
BOOL result = ConnectNamedPipe(pipe, NULL);
if (!result) {
wcout << "Failed to make connection on named pipe." << endl;
// look up error code here using GetLastError()
CloseHandle(pipe); // close the pipe
system("pause");
return 1;
}
wcout << "Sending data to pipe..." << endl;
//opening file
ifstream infile;
infile.open("E:/xmen.jpg",std::ios::binary);
ofstream out("E:/lelel.jpg",std::ios::binary);
infile.seekg(0,std::ios::end);
size_t file_size_in_byte = infile.tellg();
vector<char> file_vec;
file_vec.resize(file_size_in_byte);
infile.seekg(0,std::ios::beg);
infile.read(&file_vec[0],file_size_in_byte);
out.write(&file_vec[0],file_vec.size());
wcout</ This call blocks until a client process reads all the data
DWORD numBytesWritten = 0;
result = WriteFile(
pipe, // handle to our outbound pipe
&file_vec[0], // data to send
61026, // length of data to send (bytes)
&numBytesWritten, // will store actual amount of data sent
NULL // not using overlapped IO
);
if (result) {
wcout << "Number of bytes sent: " << numBytesWritten << endl;
} else {
wcout << "Failed to send data." << endl;
// look up error code here using GetLastError()
}
// Close the pipe (automatically disconnects client too)
CloseHandle(pipe);
wcout << "Done." << endl;
system("pause");
return 0;
}
</char></vector></fstream></iostream></iostream>Which I use to create a named pipe \.\pipe\my_pipe, to which FFMPEG connects to, using the following command :
64-static\bin\Video>ffmpeg.exe -loop 1 -s 4cif -f image2 -y -i \\.\pipe\\my_pipe
-r 25 -vframes 250 -vcodec rawvideo -an eaeew.mov
Output :
ffmpeg version N-54233-g86190af Copyright (c) 2000-2013 the FFmpeg developers
built on Jun 27 2013 16:49:12 with gcc 4.7.3 (GCC)
configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libcaca --enable-libfreetype --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libxavs --enable-libxvid --enable-zlib libavutil 52. 37.101 / 52. 37.101
libavcodec 55. 17.100 / 55. 17.100
libavformat 55. 10.100 / 55. 10.100
libavdevice 55. 2.100 / 55. 2.100
libavfilter 3. 77.101 / 3. 77.101
libswscale 2. 3.100 / 2. 3.100
libswresample 0. 17.102 / 0. 17.102
libpostproc 52. 3.100 / 52. 3.100
[image2 @ 0000000003ee04a0] Could find no file with with path '\\.\pipe\\my_pipe
' and index in the range 0-4
\\.\pipe\\my_pipe: No such file or directoryI can see on my console that my C++ app received a connection, but I get the error above in FFMPEG. Can someone please advise ?
EDIT 1
Using the command belowffmpeg.exe -s 4cif -i \\.\pipe\my_pipe -r 25 -vframes 250 -vcodec rawvideo -an tess.mov
I get the following output
ffmpeg version N-54233-g86190af Copyright (c) 2000-2013 the FFmpeg developers
built on Jun 27 2013 16:49:12 with gcc 4.7.3 (GCC)
configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libcaca --enable-libfreetype --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libxavs --enable-libxvid --enable-zlib
libavutil 52. 37.101 / 52. 37.101
libavcodec 55. 17.100 / 55. 17.100
libavformat 55. 10.100 / 55. 10.100
libavdevice 55. 2.100 / 55. 2.100
libavfilter 3. 77.101 / 3. 77.101
libswscale 2. 3.100 / 2. 3.100
libswresample 0. 17.102 / 0. 17.102
libpostproc 52. 3.100 / 52. 3.100
\\.\pipe\my_pipe: Invalid data found when processing inputSo, now it seems it was able to connect to the pipe but is not able to process the input.