This article will increase the Avfifobuffer and audio samples are Av_sample_fmt_is_planar style sample rate explained below on the code
Avfifobuffer * M_fifo = NULL; Swrcontext * Init_pcm_resample (avframe *in_frame, Avframe *out_frame) {Swrcontext * swr_ctx = NULL;swr_ctx = Swr_alloc (); I F (!swr_ctx) {printf ("Swr_alloc error \ n"); return NULL;} Avcodeccontext * Audio_dec_ctx = icodec->streams[audio_stream_idx]->codec; Avsampleformat sample_fmt;sample_fmt = (avsampleformat) m_dwbitspersample; Sample if (Audio_dec_ctx->channel_layout = = 0) {audio_dec_ctx->channel_layout = Av_get_default_channel_layout ( Icodec->streams[audio_stream_idx]->codec->channels);} /* Set options */av_opt_set_int (Swr_ctx, "In_channel_layout", Audio_dec_ctx->channel_layout, 0); Av_opt_set_int ( Swr_ctx, "In_sample_rate", audio_dec_ctx->sample_rate, 0); Av_opt_set_sample_fmt (Swr_ctx, "in_sample_fmt", Audio_ DEC_CTX->SAMPLE_FMT, 0); Av_opt_set_int (Swr_ctx, "Out_channel_layout", Audio_dec_ctx->channel_layout, 0); av_ Opt_set_int (Swr_ctx, "Out_sample_rate", audio_dec_ctx->sample_rate, 0); Av_opt_set_sample_fmt (Swr_ctx, "OUt_sample_fmt ", sample_fmt, 0); Swr_init (swr_ctx); int64_t src_nb_samples = In_frame->nb_samples;out_frame->nb_ Samples = Av_rescale_rnd (Swr_get_delay (swr_ctx,oaudio_st->codec->sample_rate) + src_nb_samples,oaudio_st- >codec->sample_rate, Oaudio_st->codec->sample_rate, av_round_up); int ret = Av_samples_alloc (out_frame- >data, &out_frame->linesize[0], Icodec->streams[audio_stream_idx]->codec->channels, out_frame- >nb_samples,oaudio_st->codec->sample_fmt,1); if (Ret < 0) {return NULL;} PCM packet initialization int buffersize = Av_samples_get_buffer_size (NULL, oaudio_st->codec->channels,2048, oaudio_st-> CODEC->SAMPLE_FMT, 1); M_fifo = Av_fifo_alloc (buffersize); return swr_ctx;} int Preform_pcm_resample (Swrcontext * pswrctx,avframe *in_frame, avframe *out_frame) {int ret = 0;IF (pSwrCtx! = NULL) {RET = Swr_convert (Pswrctx, Out_frame->data, Out_frame->nb_samples, (const uint8_t**) In_frame->data, in_frame- >nb_samples); if (Ret < 0) {return-1;} Modify the subcontracting memory int buffersize = Av_samples_get_buffer_size (&out_frame->linesize[0], oaudio_st->codec-> Channels,ret, OAUDIO_ST->CODEC->SAMPLE_FMT, 1); int sss = Av_fifo_size (M_FIFO); sss = AV_FIFO_REALLOC2 (M_fifo, av_ Fifo_size (M_FIFO) + out_frame->linesize[0]); sss = Av_fifo_size (M_FIFO); Av_fifo_generic_write (M_fifo, out_frame- >data[0], out_frame->linesize[0], NULL); out_frame->pkt_pts = In_frame->pkt_pts;out_frame->pkt_dts = in_frame->pkt_dts;//sometimes pkt_pts and Pkt_dts different, and pkt_pts is the pre-coding DTS, here to avframe into Pkt_dts instead of pkt_pts//out_frame-> pts = out_frame->pkt_pts;out_frame->pts = In_frame->pkt_dts;} return 0;} void Uinit_pcm_resample (Avframe * poutframe,swrcontext * swr_ctx) {if (poutframe) {avcodec_free_frame (&poutframe); Poutframe = NULL;} if (swr_ctx) {swr_free (&swr_ctx); swr_ctx = NULL;} The destructor of the PCM packet structure if (M_FIFO) {av_fifo_free (M_FIFO); m_fifo = NULL;}} int perform_code (int stream_type,avframe * picture) {Avcodeccontext *cctext = NULL; Avpacket Pkt_t;av_init_pacKet (&pkt_t);p kt_t.data = NULL; Packet data is allocated by the Encoderpkt_t.size = 0;int framefinished = 0; if (stream_type = = audio_id) {Cctext = oaudio_st->codec;//if the input and exit channels, samples, sample rates are different, resampling is required if (icodec->streams[audio_stream_idx]->codec->sample_fmt ! = (avsampleformat) m_dwbitspersample | | Icodec->streams[audio_stream_idx]->codec->channels! = M_dwchannelcount | | Icodec->streams[audio_stream_idx]->codec->sample_rate! = m_dwfrequency) {int64_t pts_t = picture->pts; int duration_t = (double) cctext->frame_size * (icodec->streams[audio_stream_idx]->time_base.den/icodec- >streams[audio_stream_idx]->time_base.num)/Icodec->streams[audio_stream_idx]->codec->sample_ Rate;int frame_bytes = cctext->frame_size * Av_get_bytes_per_sample (CCTEXT->SAMPLE_FMT) * cctext->channels; Avframe * pframeresample = Avcodec_alloc_frame (); uint8_t * Readbuff = new Uint8_t[frame_bytes];if (av_sample_fmt_is_ Planar (cctext->sample_fmt)) {frame_bytes/=Cctext->channels;} while (Av_fifo_size (M_FIFO) >= frame_bytes)//Remove unread packets written {pframeresample->nb_samples = Cctext->frame_size;av_ Fifo_generic_read (M_fifo, Readbuff, Frame_bytes, NULL);//The problem of audio sharding must be considered here//if it is a shard of Avcodec_fill_audio_ Frame incoming buf is mono, but buf_size is two channels plus the amount of data together//if the avcodec_fill_audio_frame that is not a shard are passed in BUF is two channels, Buf_size is two channels plus the amount of data if (av_ Sample_fmt_is_planar (CCTEXT->SAMPLE_FMT)) {Avcodec_fill_audio_frame (Pframeresample,cctext->channels, Cctext->sample_fmt,readbuff,frame_bytes * cctext->channels,1);} Else{avcodec_fill_audio_frame (pframeresample,cctext->channels,cctext->sample_fmt,readbuff,frame_bytes,0) ;} if (m_is_first_audio_pts = = 0) {m_first_audio_pts = Pts_t;m_is_first_audio_pts = 1;} pframeresample->pts = m_first_audio_pts;m_first_audio_pts + = Duration_t;pframeresample->pts = Av_rescale_q_rnd (Pframeresample->pts, Icodec->streams[audio_stream_idx]->codec->time_base, oaudio_st->codec-> Time_base, av_round_near_inf); nret = Avcodec_encode_audio2(cctext,&pkt_t,pframeresample,&framefinished), if (nret>=0 && framefinished) {write_frame (Ocodec , audio_id,pkt_t); Av_free_packet (&pkt_t);}} if (readbuff) {delete []readbuff;} if (pframeresample) {av_free (pframeresample);p frameresample = NULL;}} Else{nret = Avcodec_encode_audio2 (cctext,&pkt_t,picture,&framefinished); if (nret>=0 && framefinished) {write_frame (ocodec,audio_id,pkt_t); Av_free_packet (&pkt_t);}}} else if (Stream_type = = video_id) {Cctext = Ovideo_st->codec;if (icodec->streams[video_stream_idx]->codec- >ticks_per_frame! = 1) {avrational time_base_video_t;time_base_video_t.num = Icodec->streams[video_stream_idx] ->codec->time_base.num;time_base_video_t.den = Icodec->streams[video_stream_idx]->codec->time_ Base.den/icodec->streams[video_stream_idx]->codec->ticks_per_frame;picture->pts = Av_rescale_q_rnd ( Picture->pts, time_base_video_t, Ovideo_st->codec->time_base, Av_round_near_inf);} else{picture->pts = Av_rescale_q_rnd (picture->pts, Icodec->streams[video_stream_idx]->codec->time_base, Ovideo_ St->codec->time_base, Av_round_near_inf);} Avcodec_encode_video2 (cctext,&pkt_t,picture,&framefinished);p icture->pts++;if (frameFinished) {Write_ FRAME (ocodec,video_id,pkt_t); Av_free_packet (&pkt_t);}} return 1;}
1: Because MP3 's sample is 1152 AAC is 1024 sometimes decoding MP3 encoded into AAC if not do avfifobuffer operation, encoded AAC audio sample will be much less than the original, the resulting audio will be a card one card of the obvious less sound.
2: When the audio sample to be encoded is a Av_sample_fmt_is_planar shard, the decoded video needs to be added to the AVFRAME structure: but
I don't know what ffmpeg is designed for or what I'm using wrong. But it was a success.
Exchange Please add QQ Group: 62054820
qq:379969650
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
FFmpeg Implementing Audio Resample (resampling) (ii)