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

Prakash Rokade prakash.rokade420 at gmail.com
Wed Feb 15 08:58:30 EET 2017


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 <ggarra13 at gmail.com> 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
> 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/20170215/05481a6d/attachment.html>


More information about the Libav-user mailing list