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

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

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

Prakash Rokade
I have created CLI/CPP wrapper over Ffmpe,
And i want to write audio to file that is in IntPtr format.
I don't know how to do, can any one suggest something..
Thank You.

_______________________________________________
Libav-user mailing list
[hidden email]
http://ffmpeg.org/mailman/listinfo/libav-user
Reply | Threaded
Open this post in threaded view
|

Re: IntPtr to Packet data is not woking

Gonzalo Garramuño


El 14/02/17 a las 08:00, Prakash Rokade escribió:
> I have created CLI/CPP wrapper over Ffmpe,
> And i want to write audio to file that is in IntPtr format.
> I don't know how to do, can any one suggest something..
> Thank You.
You need to select a codec to save your audio in and initialize it
appropiately.  Then use the swresample part of ffmpeg to turn your int
samples into what the codec expects (for example, planar float or fltp ).
The docs/examples/muxing.c should prove useful.

--
Gonzalo Garramuño

_______________________________________________
Libav-user mailing list
[hidden email]
http://ffmpeg.org/mailman/listinfo/libav-user
Reply | Threaded
Open this post in threaded view
|

Re: IntPtr to Packet data is not woking

Prakash Rokade
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.

ref struct WriterData
{
        public:
                Ffmpeg::AVFormatContext*                FormatContext;

                Ffmpeg::AVStream*                               AudioStream;
                Ffmpeg::AVFrame*                                AudioFrame;
                Ffmpeg::AVCodec                         *Audio_Codec;

                int AudioBitRate;
                int SampleRate;
                int Channels;

                int AudioReceived;
                int AudioWritten;

                Ffmpeg::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;

                AudioWriterData()
                {
                        FormatContext = NULL;

                        AudioStream = NULL;

                        Audio_Codec = NULL;

                        AudioFrame = NULL;

                        AudioReceived = 0;
                        AudioWritten = 0;
                }
};

void Encoder::Open(String^ fileName, AudioCodec audioCodec, int
audioBitrate, int sampleRate, int channels)
{
        CheckIfDisposed();

        Close();

        data = gcnew WriterData();
        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 codecId = (audioCodec == AudioCodec::Default) ?
outputFormat->audio_codec : (Ffmpeg::AVCodecID)
audio_codecs[(int)audioCodec];

                data->FormatContext->oformat->audio_codec = codecId;

                add_audio_stream(data, codecId);

                open_audio(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 video file.");
                }

                Ffmpeg::avformat_write_header(data->FormatContext, NULL);

                success = true;
        }
        finally
        {
                nativeFileName = NULL;
                delete[] nativeFileName;

                if (!success)
                        Close();
        }
}

void add_audio_stream(WriterData^ data, enum Ffmpeg::AVCodecID codecId)
{
        data->AudioStream = Ffmpeg::avformat_new_stream(data->FormatContext,
data->FormatContext->audio_codec);

        if (!data->AudioStream)
                throw gcnew Exception("Could not alloc audio stream");

        Ffmpeg::AVCodecContext *codecContext = data->AudioStream->codec;

        codecContext->codec_id = codecId;
        codecContext->codec_type = Ffmpeg::AVMEDIA_TYPE_AUDIO;
        codecContext->sample_fmt = Ffmpeg::AV_SAMPLE_FMT_S16;
        codecContext->channels = data->Channels;
        codecContext->delay = 0;
        codecContext->bit_rate = data->AudioBitRate;

        if (codecContext->bit_rate == 0)
                codecContext->bit_rate = data->SampleRate * data->Channels * 16;

        codecContext->bit_rate = codecContext->bit_rate;
        codecContext->bit_rate_tolerance = codecContext->bit_rate;
        codecContext->rc_min_rate = 0;
        codecContext->rc_max_rate = 0;
        codecContext->frame_size = 0;
        codecContext->channel_layout = (codecContext->channels == 2 ?
AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO);

        codecContext->sample_rate = data->SampleRate;

        codecContext->time_base.den = data->SampleRate;
        codecContext->time_base.num = 1;

        //data->AudioStream->time_base.den = codecContext->time_base.den;
        //data->AudioStream->time_base.num = codecContext->time_base.num;

        if (data->FormatContext->oformat->flags & AVFMT_GLOBALHEADER)
                codecContext->flags |= CODEC_FLAG_GLOBAL_HEADER;
}

void open_audio(WriterData^ data)
{
        Ffmpeg::AVCodecContext* codecContext = data->AudioStream->codec;
        Ffmpeg::AVCodec* codec = avcodec_find_encoder(codecContext->codec_id);

        if (!codec)
                throw gcnew Exception("Cannot find audio codec.");

        codecContext->codec_id = codec->id;
        codecContext->codec_type = Ffmpeg::AVMEDIA_TYPE_AUDIO;
        codecContext->sample_fmt = codec->sample_fmts[0];
        codecContext->sample_rate = data->SampleRate;
        codecContext->channel_layout = AV_CH_LAYOUT_STEREO;
        codecContext->channels =
Ffmpeg::av_get_channel_layout_nb_channels(codecContext->channel_layout);
        codecContext->bit_rate = data->AudioBitRate;

        int ret = Ffmpeg::avcodec_open2(codecContext, codec, NULL);
        if (ret < 0)
                throw gcnew Exception("Cannot open audio codec.");
}


void Encoder::WriteAudioChunk(IntPtr chunk, int lenght, TimeSpan timestamp)
{
        CheckIfDisposed();

        if (data == nullptr)
                throw gcnew System::IO::IOException("A video file was not opened yet.");

        int bufferSize = lenght;

        data->AudioFrame = Ffmpeg::av_frame_alloc();

        Ffmpeg::av_frame_unref(data->AudioFrame);
        data->AudioFrame->pts = AV_NOPTS_VALUE;
        data->AudioFrame->format = data->AudioStream->codec->sample_fmt;

        int bytePerSample =
Ffmpeg::av_get_bytes_per_sample(data->AudioStream->codec->sample_fmt);
        int dataSize = data->Channels * bytePerSample;
        data->AudioStream->codec->frame_size = data->Channels *
data->SampleRate * bytePerSample;
        data->AudioFrame->nb_samples = data->AudioStream->codec->frame_size;

        Ffmpeg::uint8_t *buf =
reinterpret_cast<Ffmpeg::uint8_t*>(static_cast<void*>(chunk));

        int ret = Ffmpeg::avcodec_fill_audio_frame(data->AudioFrame,
data->Channels, data->AudioStream->codec->sample_fmt, buf, bufferSize,
1);

        if (!ret)
                throw gcnew System::IO::IOException("A video file was not opened yet.");

        data->AudioReceived++;

        write_audio_chunk(data, buf, ret,timestamp.TotalMilliseconds);
}

void write_audio_chunk(WriterData^ data, Ffmpeg::uint8_t *ut, int
size,double timeStamp)
{
        Ffmpeg::AVCodecContext* codecContext = data->AudioStream->codec;
        int out_size, ret = 0;

        Ffmpeg::AVPacket packet;

        int64_t dts = timeStamp;
        dts = dts * data->FrameRate;

        if (data->PreviousAudioDts < 0)
                data->PreviousAudioDts = dts;

        int got_packet;
        Ffmpeg::av_init_packet(&packet);
        packet.data = ut;
        packet.size = size;

        out_size = Ffmpeg::avcodec_send_frame(codecContext, data->AudioFrame);
        got_packet = Ffmpeg::avcodec_receive_packet(codecContext, &packet);



        if (got_packet)
        {
                if (codecContext->coded_frame->pts != AV_NOPTS_VALUE)
                {
                        packet.pts = Ffmpeg::av_rescale_q(packet.pts,
codecContext->time_base, data->AudioStream->time_base);
                        packet.dts = Ffmpeg::av_rescale_q(packet.dts,
codecContext->time_base, data->AudioStream->time_base);
                        packet.duration = Ffmpeg::av_rescale_q(packet.duration,
codecContext->time_base, data->AudioStream->time_base);
                }

                packet.stream_index = data->AudioStream->index;

                ret = Ffmpeg::av_interleaved_write_frame(data->FormatContext, &packet);
                //ret = Ffmpeg::av_write_frame(data->FormatContext, &packet);
                data->AudioWritten++;
        }


        av_packet_unref(&packet);
        got_packet = 0;

        if (ret != 0)
                throw gcnew Exception("Error while writing audio frame.");
}

On 15 February 2017 at 03:07, Gonzalo Garramuño <[hidden email]> wrote:


El 14/02/17 a las 08:00, Prakash Rokade escribió:

I have created CLI/CPP wrapper over Ffmpe,
And i want to write audio to file that is in IntPtr format.
I don't know how to do, can any one suggest something..
Thank You.
You need to select a codec to save your audio in and initialize it appropiately.  Then use the swresample part of ffmpeg to turn your int samples into what the codec expects (for example, planar float or fltp ).
The docs/examples/muxing.c should prove useful.

--
Gonzalo Garramuño

_______________________________________________
Libav-user mailing list
[hidden email]
http://ffmpeg.org/mailman/listinfo/libav-user


_______________________________________________
Libav-user mailing list
[hidden email]
http://ffmpeg.org/mailman/listinfo/libav-user
Reply | Threaded
Open this post in threaded view
|

Re: IntPtr to Packet data is not woking

Carl Eugen Hoyos-2
2017-02-15 7:58 GMT+01:00 Prakash Rokade <[hidden email]>:
>         codecContext->sample_fmt = codec->sample_fmts[0];

>         int ret = Ffmpeg::avcodec_open2(codecContext, codec, NULL);

I believe you cannot generally do this:
A codec does not necessarily support the sample_fmt you set.
Additionally, the actual supported list of sample_fmts for a codec
is not part of the API, it has changed in the past without any
particular warning (like a version bump).

Carl Eugen
_______________________________________________
Libav-user mailing list
[hidden email]
http://ffmpeg.org/mailman/listinfo/libav-user
Reply | Threaded
Open this post in threaded view
|

Re: IntPtr to Packet data is not woking

Prakash Rokade

Hi Carl,
I am new in ffmpeg community.
May be you are write but the code works fine there is no issue,
while writing the audio data no error. Only the output file has no audio but in file properties it shows the audio bitrate, sample rate...
Can you suggest something so the issue will get resolved. ..
Thanks for suggestion.


On 15 Feb 2017 16:26, "Carl Eugen Hoyos" <[hidden email]> wrote:
2017-02-15 7:58 GMT+01:00 Prakash Rokade <[hidden email]>:
>         codecContext->sample_fmt = codec->sample_fmts[0];

>         int ret = Ffmpeg::avcodec_open2(codecContext, codec, NULL);

I believe you cannot generally do this:
A codec does not necessarily support the sample_fmt you set.
Additionally, the actual supported list of sample_fmts for a codec
is not part of the API, it has changed in the past without any
particular warning (like a version bump).

Carl Eugen
_______________________________________________
Libav-user mailing list
[hidden email]
http://ffmpeg.org/mailman/listinfo/libav-user

_______________________________________________
Libav-user mailing list
[hidden email]
http://ffmpeg.org/mailman/listinfo/libav-user
Reply | Threaded
Open this post in threaded view
|

Re: IntPtr to Packet data is not woking

Gonzalo Garramuño
In reply to this post by Prakash Rokade



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
[hidden email]
http://ffmpeg.org/mailman/listinfo/libav-user
Reply | Threaded
Open this post in threaded view
|

Re: IntPtr to Packet data is not woking

Prakash Rokade
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 <[hidden email]> 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
[hidden email]
http://ffmpeg.org/mailman/listinfo/libav-user



_______________________________________________
Libav-user mailing list
[hidden email]
http://ffmpeg.org/mailman/listinfo/libav-user
Reply | Threaded
Open this post in threaded view
|

Re: IntPtr to Packet data is not woking

Gonzalo Garramuño
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" <[hidden email]> 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 <[hidden email]> 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
[hidden email]
http://ffmpeg.org/mailman/listinfo/libav-user



_______________________________________________
Libav-user mailing list
[hidden email]
http://ffmpeg.org/mailman/listinfo/libav-user



_______________________________________________
Libav-user mailing list
[hidden email]
http://ffmpeg.org/mailman/listinfo/libav-user
Reply | Threaded
Open this post in threaded view
|

Re: IntPtr to Packet data is not woking

Prakash Rokade

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" <[hidden email]> 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" <[hidden email]> 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 <[hidden email]> 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
[hidden email]
http://ffmpeg.org/mailman/listinfo/libav-user



_______________________________________________
Libav-user mailing list
[hidden email]
http://ffmpeg.org/mailman/listinfo/libav-user



_______________________________________________
Libav-user mailing list
[hidden email]
http://ffmpeg.org/mailman/listinfo/libav-user


_______________________________________________
Libav-user mailing list
[hidden email]
http://ffmpeg.org/mailman/listinfo/libav-user