Thanks for reply... The code is only sample, and method writeaudiochunk is get called from outside. I am using directshow graph as audio source. if you want full code I can give it to you.
Now the sample is working. But I have recorded audio for 2 min but output file has only 3 sec duration and audio is also so fast... Can you make some suggestions... On 20 Feb 2017 22:42, "Gonzalo Garramuno" <[email protected]> wrote: > I am unable to compile your code, but at first glance you are missing the > main loop. The one that would call writeaudiochunk. > > El feb. 20, 2017 12:41 PM, "Prakash Rokade" <[email protected]> > escribió: > > Hiii Gonzalo Garramuño, > > I have modified the code but there is issue that i am not able to figure > out. > No error while encoding, resampling , and writting the audio data. But > output file only have the 1 sec audio. can you check the code and suggest > some changes. > > ref struct AudioWriterData > > { > public: > Ffmpeg::AVFormatContext* FormatContext; > > Ffmpeg::AVStream* AudioStream; > Ffmpeg::AVFrame* AudioFrame; > Ffmpeg::AVCodec *Audio_Codec; > > int AudioBitRate; > int SampleRate; > int Channels; > > int AudioReceived; > int AudioWritten; > > int64_t next_pts; > int samples_count; > > Ffmpeg::AVFrame *tmp_frame; > > float t, tincr, tincr2; > struct Ffmpeg::SwsContext *sws_ctx; > struct Ffmpeg::SwrContext *swr_ctx; > > double PreviousAudioDts; > > double EncodedAudioFrame; > > > AudioWriterData() > { > FormatContext = NULL; > > AudioStream = NULL; > > Audio_Codec = NULL; > > AudioFrame = NULL; > > AudioReceived = 0; > AudioWritten = 0; > EncodedAudioFrame = 0; > } > }; > > > //Open the audio file with specified settings > void AudioWriter::Open(String^ fileName, AudioCodec audioCodec, int > audioBitrate, int sampleRate, int channels) > { > CheckIfDisposed(); > > Close(); > > data = gcnew AudioWriterData(); > > bool success = false; > > if (((int)audioCodec < -1) || ((int)audioCodec >= > AUDIO_CODECS_COUNT)) > throw gcnew ArgumentException("Invalid audio codec is > specified."); > > m_acodec = audioCodec; > m_audioBitrate = audioBitrate; > m_sampleRate = sampleRate; > m_channels = channels; > > data->AudioBitRate = audioBitrate; > data->SampleRate = sampleRate; > data->Channels = channels; > > char* nativeFileName = (char*)System::Runtime::Intero > pServices::Marshal::StringToHGlobalAnsi(fileName).ToPointer(); > > try > { > Ffmpeg::AVOutputFormat* outputFormat = > Ffmpeg::av_guess_format(NULL, nativeFileName, NULL); > > if (!outputFormat) > { > outputFormat = Ffmpeg::av_guess_format("mp3", NULL, NULL); > > if (!outputFormat) > throw gcnew Exception("Cannot find suitable output > format."); > } > > data->FormatContext = Ffmpeg::avformat_alloc_context(); > > if (!data->FormatContext) > throw gcnew Exception("Cannot allocate format context."); > > data->FormatContext->oformat = outputFormat; > strcpy_s(data->FormatContext->filename, nativeFileName); > > Ffmpeg::AVCodecID avcodecid = (audioCodec == > AudioCodec::Default) ? outputFormat->audio_codec : (Ffmpeg::AVCodecID) > audio_codecs[(int)audioCodec]; > data->FormatContext->oformat->audio_codec = avcodecid; > > add_stream(data, data->FormatContext, data->Audio_Codec, > avcodecid); > > open_audio(data->FormatContext, data->Audio_Codec, data); > > > Ffmpeg::av_dump_format(data->FormatContext, 0, > nativeFileName, 1); > > if (!(outputFormat->flags & AVFMT_NOFILE)) > { > if (Ffmpeg::avio_open(&data->FormatContext->pb, > nativeFileName, AVIO_FLAG_WRITE) < 0) > throw gcnew System::IO::IOException("Cannot open the > audio file."); > > } > > Ffmpeg::avformat_write_header(data->FormatContext, NULL); > > success = true; > } > finally > { > nativeFileName = NULL; > delete[] nativeFileName; > > if (!success) > Close(); > } > } > > static void add_stream(AudioWriterData^ ost, Ffmpeg::AVFormatContext > *oc, Ffmpeg::AVCodec *codec, enum Ffmpeg::AVCodecID codec_id) > { > Ffmpeg::AVCodecContext *c; > int i; > > codec = Ffmpeg::avcodec_find_encoder(codec_id); > > if (!(codec)) > throw gcnew Exception("Invalid audio codec is specified."); > > ost->AudioStream = Ffmpeg::avformat_new_stream(oc, codec); > > if (!ost->AudioStream) > throw gcnew Exception("Unable to add audio stream."); > > ost->AudioStream->id = oc->nb_streams - 1; > c = ost->AudioStream->codec; > c->sample_fmt = (codec)->sample_fmts ? (codec)->sample_fmts[0] : > Ffmpeg::AV_SAMPLE_FMT_FLTP; > c->bit_rate = ost->AudioBitRate; > c->sample_rate = 44100; > if ((codec)->supported_samplerates) > { > c->sample_rate = (codec)->supported_samplerates[0]; > for (i = 0; (codec)->supported_samplerates[i]; i++) > { > if ((codec)->supported_samplerates[i] == 44100) > c->sample_rate = 44100; > } > } > c->channels = Ffmpeg::av_get_channel_layout_ > nb_channels(c->channel_layout); > c->channel_layout = AV_CH_LAYOUT_STEREO; > if ((codec)->channel_layouts) > { > c->channel_layout = (codec)->channel_layouts[0]; > for (i = 0; (codec)->channel_layouts[i]; i++) > { > if ((codec)->channel_layouts[i] == AV_CH_LAYOUT_STEREO) > c->channel_layout = AV_CH_LAYOUT_STEREO; > } > } > c->channels = Ffmpeg::av_get_channel_layout_ > nb_channels(c->channel_layout); > ost->AudioStream->time_base.num = 1; > ost->AudioStream->time_base.den = c->sample_rate; > > if (oc->oformat->flags & AVFMT_GLOBALHEADER) > c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; > } > > static Ffmpeg::AVFrame *alloc_audio_frame(enum Ffmpeg::AVSampleFormat > sample_fmt,uint64_t channel_layout,int sample_rate, int nb_samples) > { > Ffmpeg::AVFrame *frame = Ffmpeg::av_frame_alloc(); > int ret; > if (!frame) > throw gcnew Exception("Unable to allocate frame."); > > frame->format = sample_fmt; > frame->channel_layout = channel_layout; > frame->sample_rate = sample_rate; > frame->nb_samples = nb_samples; > > if (nb_samples) > { > ret = av_frame_get_buffer(frame, 0); > if (ret < 0) > throw gcnew Exception("Unable to buffer frame."); > } > > return frame; > } > > static void open_audio(Ffmpeg::AVFormatContext *oc, Ffmpeg::AVCodec > *codec, AudioWriterData^ ost) > { > Ffmpeg::AVCodecContext *c; > int nb_samples; > int ret; > c = ost->AudioStream->codec; > > ret = avcodec_open2(c, codec, NULL); > > if (ret < 0) > throw gcnew Exception("Cannot open audio codec."); > > ost->t = 0; > ost->tincr = 2 * M_PI * 110.0 / c->sample_rate; > ost->tincr2 = 2 * M_PI * 110.0 / c->sample_rate / c->sample_rate; > > if (c->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE) > nb_samples = 10000; > else > nb_samples = c->frame_size; > > ost->AudioFrame = alloc_audio_frame(c->sample_fmt, > c->channel_layout, c->sample_rate, nb_samples); > ost->tmp_frame = alloc_audio_frame(Ffmpeg::AV_SAMPLE_FMT_S16, > c->channel_layout, c->sample_rate, nb_samples); > > ost->swr_ctx = Ffmpeg::swr_alloc(); > if (!ost->swr_ctx) > throw gcnew Exception("Could not allocate resampler context."); > > Ffmpeg::av_opt_set_int(ost->swr_ctx, "in_channel_count", > c->channels, 0); > Ffmpeg::av_opt_set_int(ost->swr_ctx, "in_sample_rate", > c->sample_rate, 0); > Ffmpeg::av_opt_set_sample_fmt(ost->swr_ctx, "in_sample_fmt", > Ffmpeg::AV_SAMPLE_FMT_S16, 0); > Ffmpeg::av_opt_set_int(ost->swr_ctx, "out_channel_count", > c->channels, 0); > Ffmpeg::av_opt_set_int(ost->swr_ctx, "out_sample_rate", > c->sample_rate, 0); > Ffmpeg::av_opt_set_sample_fmt(ost->swr_ctx, "out_sample_fmt", > c->sample_fmt, 0); > > if ((ret = Ffmpeg::swr_init(ost->swr_ctx)) < 0) > throw gcnew Exception("Failed to initialize the resampling > context."); > } > > void AudioWriter::WriteAudioChunk(IntPtr chunk, int lenght) > { > uint8_t *audioData = reinterpret_cast<uint8_t*>(sta > tic_cast<void*>(chunk)); > > int buffer_size = Ffmpeg::av_samples_get_buffer_size(NULL, > data->tmp_frame->channels, data->tmp_frame->nb_samples, > data->AudioStream->codec->sample_fmt, 0); > > uint8_t *buf = reinterpret_cast<uint8_t*>(sta > tic_cast<void*>(chunk)); > int ret = Ffmpeg::avcodec_fill_audio_frame(data->tmp_frame, > data->Channels, data->AudioStream->codec->sample_fmt, buf, buffer_size, > 1); > > if (!ret) > throw gcnew System::IO::IOException("A video file was not > opened yet."); > > write_audio_frame(data->FormatContext, data, audioData); > } > > static int write_audio_frame(Ffmpeg::AVFormatContext *oc, > AudioWriterData^ ost, uint8_t *audioData) > { > Ffmpeg::AVCodecContext *c; > Ffmpeg::AVPacket pkt = { 0 }; > int ret; > int got_packet; > int dst_nb_samples; > > Ffmpeg::av_init_packet(&pkt); > c = ost->AudioStream->codec; > > Ffmpeg::AVFrame *frame = ost->tmp_frame; > > if (frame) > { > dst_nb_samples = > Ffmpeg::av_rescale_rnd(swr_get_delay(ost->swr_ctx, > c->sample_rate) + frame->nb_samples, > c->sample_rate, c->sample_rate, Ffmpeg::AV_ROUND_UP); > if (dst_nb_samples != frame->nb_samples) > throw gcnew Exception("dst_nb_samples != > frame->nb_samples"); > > ret = Ffmpeg::av_frame_make_writable(ost->AudioFrame); > if (ret < 0) > throw gcnew Exception("Unable to make writable."); > > ret = swr_convert(ost->swr_ctx, ost->AudioFrame->data, > dst_nb_samples, (const uint8_t **)frame->data, frame->nb_samples); > if (ret < 0) > throw gcnew Exception("Unable to convert to destination > format."); > > frame = ost->AudioFrame; > > Ffmpeg::AVRational timebase = { 1, c->sample_rate }; > frame->pts = Ffmpeg::av_rescale_q(ost->samples_count, > timebase, c->time_base); > ost->samples_count += dst_nb_samples; > } > > ret = avcodec_encode_audio2(c, &pkt, frame, &got_packet); > if (ret < 0) > throw gcnew Exception("Error encoding audio frame."); > > if (got_packet) > { > Console::WriteLine("Audio packet encode successfully."); > ret = write_frame(oc, &c->time_base, ost->AudioStream, &pkt); > if (ret < 0) > Console::WriteLine("Audio is not written."); > } > else > Console::WriteLine("Audio packet encode failed."); > > return (ost->AudioFrame || got_packet) ? 0 : 1; > } > > static int write_frame(Ffmpeg::AVFormatContext *fmt_ctx, const > Ffmpeg::AVRational *time_base, Ffmpeg::AVStream *st, Ffmpeg::AVPacket *pkt) > { > Ffmpeg::av_packet_rescale_ts(pkt, *time_base, st->time_base); > pkt->stream_index = st->index; > return Ffmpeg::av_interleaved_write_frame(fmt_ctx, pkt); > } > > On 16 February 2017 at 03:13, Gonzalo Garramuño <[email protected]> > wrote: > >> >> >> El 15/02/17 a las 03:58, Prakash Rokade escribió: >> >> Thanks Gonzalo, >> >> According to your suggestion i have written the below code can you check >> ones, because audio is written but in output file no audio is present. >> >> You are opening the stream with AV_SAMPLE_FMT_S16 and then using >> sample_fmt[0]. That's inconsistent to say the least. >> You are not using swresample to take one audio format to another. >> You have a swscale ptr which has nothing to do with audio. >> You are using the new API but are not handling the AVERROR(EAGAIN) >> cases. For this trial, use the old api which is more reliable for muxing. >> Try to get the sample in doc/examples working and slowly modify it to fit >> your need. >> >> -- >> Gonzalo Garramuño >> >> >> _______________________________________________ >> Libav-user mailing list >> [email protected] >> http://ffmpeg.org/mailman/listinfo/libav-user >> >> > > _______________________________________________ > Libav-user mailing list > [email protected] > http://ffmpeg.org/mailman/listinfo/libav-user > > > > _______________________________________________ > Libav-user mailing list > [email protected] > http://ffmpeg.org/mailman/listinfo/libav-user > >
_______________________________________________ Libav-user mailing list [email protected] http://ffmpeg.org/mailman/listinfo/libav-user
