<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=utf-8"><meta name=Generator content="Microsoft Word 15 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
.MsoChpDefault
        {mso-style-type:export-only;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:70.85pt 3.0cm 70.85pt 3.0cm;}
div.WordSection1
        {page:WordSection1;}
--></style></head><body lang=PT-BR link=blue vlink="#954F72"><div class=WordSection1><p class=MsoNormal>Hello,</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>I need to reencode and resample raw PCM 44.1KHz to AAC 48 KHz.</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>I’m really lost because have no much information about swr_convert.</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>What I’m doing until now is:</p><p class=MsoNormal>- Allocate AVCodecContext with encoder specifications:</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>void start_encoder(const AVFormatContext* formatContext, AVCodec*& encoderCodec, AVCodecContext*& encoderContext)</p><p class=MsoNormal>{</p><p class=MsoNormal>                encoderCodec = avcodec_find_encoder(AV_CODEC_ID_AAC);</p><p class=MsoNormal>                if (encoderCodec == nullptr)</p><p class=MsoNormal>                               throw std::runtime_error("Could not find encoder for AAC");</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>                //stream->id = mpegtsFormatContext->nb_streams - 1;</p><p class=MsoNormal>                encoderContext = avcodec_alloc_context3(encoderCodec);</p><p class=MsoNormal>                if (!encoderCodec)</p><p class=MsoNormal>                               throw std::runtime_error("Could not allocate an encoding context.");</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>                auto codec = encoderCodec;</p><p class=MsoNormal>                auto c = encoderContext;</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>                // Configura o encoder.</p><p class=MsoNormal>                switch (codec->type)</p><p class=MsoNormal>                {</p><p class=MsoNormal>                case AVMEDIA_TYPE_AUDIO:</p><p class=MsoNormal>                               c->sample_fmt = codec->sample_fmts ? codec->sample_fmts[0] : AV_SAMPLE_FMT_FLTP;</p><p class=MsoNormal>                               c->bit_rate = 128000;</p><p class=MsoNormal>                               c->sample_rate = 48000;</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>                               // Garante que o samplerate de saída requisitado é aceito pelo encoder.</p><p class=MsoNormal>                               {</p><p class=MsoNormal>                                               bool supported{ false };</p><p class=MsoNormal>                                               if (codec->supported_samplerates)</p><p class=MsoNormal>                                               {</p><p class=MsoNormal>                                                               for (auto i = 0; codec->supported_samplerates[i]; i++)</p><p class=MsoNormal>                                                               {</p><p class=MsoNormal>                                                                               if (codec->supported_samplerates[i] == c->sample_rate)</p><p class=MsoNormal>                                                                               {</p><p class=MsoNormal>                                                                                              supported = true;</p><p class=MsoNormal>                                                                                              break;</p><p class=MsoNormal>                                                                               }</p><p class=MsoNormal>                                                               }</p><p class=MsoNormal>                                               }</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>                                               if (!supported)</p><p class=MsoNormal>                                                               throw std::invalid_argument("Sample rate not supported by encoder.");</p><p class=MsoNormal>                               }</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>                               c->channel_layout = AV_CH_LAYOUT_STEREO;</p><p class=MsoNormal>                               c->channels = av_get_channel_layout_nb_channels(c->channel_layout);</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>                               if (codec->channel_layouts)</p><p class=MsoNormal>                               {</p><p class=MsoNormal>                                               c->channel_layout = codec->channel_layouts[0];</p><p class=MsoNormal>                                               for (auto i = 0; codec->channel_layouts[i]; i++)</p><p class=MsoNormal>                                               {</p><p class=MsoNormal>                                                               if (codec->channel_layouts[i] == AV_CH_LAYOUT_STEREO)</p><p class=MsoNormal>                                                                               c->channel_layout = AV_CH_LAYOUT_STEREO;</p><p class=MsoNormal>                                               }</p><p class=MsoNormal>                               }</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>                               c->channels = av_get_channel_layout_nb_channels(c->channel_layout);</p><p class=MsoNormal>                               break;</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>                default:</p><p class=MsoNormal>                               break;</p><p class=MsoNormal>                }</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>                // Some formats want stream headers to be separate. </p><p class=MsoNormal>                if (formatContext->oformat->flags & AVFMT_GLOBALHEADER)</p><p class=MsoNormal>                               c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>                // open it</p><p class=MsoNormal>                AVDictionary* opt{ nullptr };</p><p class=MsoNormal>                check(avcodec_open2(c, codec, &opt));</p><p class=MsoNormal>}</p><p class=MsoNormal> </p><p class=MsoNormal>- Allocating resampler contexto</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>void initialize_resampler(SwrContext*& resamplerCtx, AVCodecContext* encoder, AVFrame*& rawResampledAudioFrame, AVStream* audioFormatStream)</p><p class=MsoNormal>{</p><p class=MsoNormal>                int nb_samples = (encoder->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE) ? encoder->sample_rate : encoder->frame_size;</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>                int encoderFrameSize = encoder->channels * av_get_bytes_per_sample(encoder->sample_fmt) * encoder->frame_size;</p><p class=MsoNormal>                rawResampledAudioFrame = allocate_audioframe(encoder->sample_fmt, encoder->channel_layout, encoder->sample_rate, nb_samples);</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>                // Copy the stream parameters to the muxer</p><p class=MsoNormal>                check(avcodec_parameters_from_context(audioFormatStream->codecpar, encoder));</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>                // Create resampler context</p><p class=MsoNormal>                resamplerCtx = swr_alloc();</p><p class=MsoNormal>                if (resamplerCtx == nullptr)</p><p class=MsoNormal>                               throw std::runtime_error("Could not allocate resampler context");</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>                // Set options</p><p class=MsoNormal>                check(av_opt_set_int(resamplerCtx, "in_channel_count", 2, 0));</p><p class=MsoNormal>                check(av_opt_set_int(resamplerCtx, "in_sample_rate", 44100, 0));</p><p class=MsoNormal>                check(av_opt_set_sample_fmt(resamplerCtx, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0));</p><p class=MsoNormal>                check(av_opt_set_int(resamplerCtx, "out_channel_count", encoder->channels, 0));</p><p class=MsoNormal>                check(av_opt_set_int(resamplerCtx, "out_sample_rate", encoder->sample_rate, 0));</p><p class=MsoNormal>                check(av_opt_set_sample_fmt(resamplerCtx, "out_sample_fmt", encoder->sample_fmt, 0));</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>                // initialize the resampling context</p><p class=MsoNormal>                check(swr_init(resamplerCtx));</p><p class=MsoNormal>}</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>- Allocating AVFrame to decodedFrame:</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>To get AVFrame, I’m sending to a decoder </p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>                                               AVPacket input_packet;</p><p class=MsoNormal>                                               av_init_packet(&input_packet);</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>                                               while (av_read_frame(inputContext, &input_packet) >= 0)</p><p class=MsoNormal>                                               {</p><p class=MsoNormal>                                                               // Allocate data</p><p class=MsoNormal>                                                               uint8_t** convertedData = NULL;</p><p class=MsoNormal>                                                               if (av_samples_alloc_array_and_samples(&convertedData, NULL, STREAM_AUDIO_CHANNELS, RAW_AUDIO_FRAME_SIZE, STREAM_AUDIO_SAMPLE_FORMAT_GM, 0) < 0)</p><p class=MsoNormal>                                                                               throw - 20;</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>                                                               check(avcodec_send_packet(decoderContext, &input_packet));</p><p class=MsoNormal>                                                               check(avcodec_receive_frame(decoderContext, decodedFrame));</p><p class=MsoNormal>                                   }</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>As you can see, I’m Reading a frame from input (microfone), sending the packet to decoder to get AVFrame and what I have to do after?</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>I need to convert AV_SAMPLE_FMT_FLTP to AV_SAMPLE_FMT_S16 but I don’t know how. </p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>My entire loop (doesn’t work):<br><br></p><p class=MsoNormal>                                               AVPacket input_packet;</p><p class=MsoNormal>                                               av_init_packet(&input_packet);</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>                                               while (av_read_frame(inputContext, &input_packet) >= 0)</p><p class=MsoNormal>                                               {</p><p class=MsoNormal>                                                               // Allocate data</p><p class=MsoNormal>                                                               uint8_t** convertedData = NULL;</p><p class=MsoNormal>                                                               if (av_samples_alloc_array_and_samples(&convertedData, NULL, STREAM_AUDIO_CHANNELS, RAW_AUDIO_FRAME_SIZE, STREAM_AUDIO_SAMPLE_FORMAT_GM, 0) < 0)</p><p class=MsoNormal>                                                                               throw - 20;</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>                                                               check(avcodec_send_packet(decoderContext, &input_packet));</p><p class=MsoNormal>                                                               check(avcodec_receive_frame(decoderContext, decodedFrame));</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>                                                               int outSamples = swr_convert(resamplerContext, convertedData, RAW_AUDIO_FRAME_SIZE, const_cast<const uint8_t**>(decodedFrame->data), decodedFrame->nb_samples);</p><p class=MsoNormal>                                                               check(outSamples);</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>                                                               av_init_packet(&pkt);</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>                                                               memcpy(&decodedFrame->data[0][0], convertedData, outSamples * sizeof STREAM_AUDIO_SAMPLE_TYPE * STREAM_AUDIO_CHANNELS);</p><p class=MsoNormal>                                                               auto in_stream = inputContext->streams[pkt.stream_index];</p><p class=MsoNormal>                                                               auto out_stream = outputContext->streams[pkt.stream_index];</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>                                                               //Convert PTS/DTS</p><p class=MsoNormal>                                                               pkt.pts = av_rescale_q_rnd(pkt.pts, in_stream->time_base, out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));</p><p class=MsoNormal>                                                               pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base, out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));</p><p class=MsoNormal>                                                               pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base);</p><p class=MsoNormal>                                                               pkt.pos = -1;</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>                                                               check(av_frame_make_writable(decodedFrame));</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>                                                               check(avcodec_send_frame(encoderContext, decodedFrame));</p><p class=MsoNormal>                                                               check(avcodec_receive_packet(encoderContext, &pkt));</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>                                                               check(av_interleaved_write_frame(outputContext, &pkt));</p><p class=MsoNormal>                                                               av_packet_unref(&pkt);</p><p class=MsoNormal>                                               }</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Enviado do <a href="https://go.microsoft.com/fwlink/?LinkId=550986">Email</a> para Windows 10</p><p class=MsoNormal><o:p> </o:p></p></div></body></html>