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:: InteropServices::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*>( static_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*>( static_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
