[Libav-user] IntPtr to Packet data is not woking

Prakash Rokade prakash.rokade420 at gmail.com
Tue Feb 21 10:32:26 EET 2017


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" <ggarra13 at gmail.com> 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" <prakash.rokade420 at gmail.com>
> 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 <ggarra13 at gmail.com>
> 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
>> Libav-user at ffmpeg.org
>> http://ffmpeg.org/mailman/listinfo/libav-user
>>
>>
>
> _______________________________________________
> Libav-user mailing list
> Libav-user at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/libav-user
>
>
>
> _______________________________________________
> Libav-user mailing list
> Libav-user at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/libav-user
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20170221/b8610162/attachment.html>


More information about the Libav-user mailing list