編碼音頻aac的時候 (avcodec_encode_audio2)提示FFMPEG more samples than frame size 的錯誤

原因:

音頻編碼器AVCodecContext (編碼器的能力)的frame_size 比編入幀AVFrame的nb_samples小 。

解決方法:

通過調試可以得到aac編碼器的frame_size 爲1024 所以每次應該給編碼器1024個採樣。可以採樣AVAudioFifo緩存確保每次編入aac的數據爲編碼器的frame_size(1024)。


代碼如下:

                                      while (( ret=av_audio_fifo_size(fifo)) < output_frame_size) 
					{
						if (init_converted_samples(&converted_input_samples, ac,
							oAFrame->nb_samples))
						{

						}

						if (convert_samples((const uint8_t**)oAFrame->extended_data, converted_input_samples,
							oAFrame->nb_samples, resample_context))
						{

						}

						add_samples_to_fifo(fifo, converted_input_samples,oAFrame->nb_samples);

						if (converted_input_samples) 
						{
							av_freep(&converted_input_samples[0]);
							free(converted_input_samples);
						}

					}

					while(av_audio_fifo_size(fifo) >= output_frame_size)
					{
						AVFrame *frame;

						frame = av_frame_alloc();

						const int frame_size = FFMIN(av_audio_fifo_size(fifo),ac->frame_size);

						(frame)->nb_samples     = frame_size;
						(frame)->channel_layout = ac->channel_layout;
						(frame)->format         = ac->sample_fmt;
						(frame)->sample_rate    = ac->sample_rate;

						int error;

						if ((error = av_frame_get_buffer(frame, 0)) < 0) 
						{

							av_frame_free(&frame);

							return error;
						}

						if (av_audio_fifo_read(fifo, (void **)frame->data, frame_size) < frame_size) 
						{
							av_frame_free(&frame);

							return AVERROR_EXIT;
						}

						AVPacket pkt;

						av_init_packet(&pkt);
						pkt.data = NULL;
						pkt.size = 0;

						//fflush(stdout);
						frame->pts = av_frame_get_best_effort_timestamp(frame);

						frame->pict_type=AV_PICTURE_TYPE_NONE;

						if ((error = avcodec_encode_audio2(ac, &pkt,frame, &data_present)) < 0) 
						{
							av_free_packet(&pkt);
							return error;
						}

						av_frame_free(&frame);

						if (data_present) 
						{
							pkt.stream_index = audio_st->index;  

							pkt.dts = av_rescale_q_rnd(pkt.dts,
								oc->streams[audioindex]->codec->time_base,
								oc->streams[audioindex]->time_base,
								(AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
							pkt.pts = av_rescale_q_rnd(pkt.pts,
								oc->streams[audioindex]->codec->time_base,
								oc->streams[audioindex]->time_base,
								(AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
							pkt.duration = av_rescale_q(pkt.duration,
								oc->streams[audioindex]->codec->time_base,
								oc->streams[audioindex]->time_base);

							if ((error = av_interleaved_write_frame(oc, &pkt)) < 0)
							{
								av_free_packet(&pkt);

								return error;
							}

						}//end if(data_present)

						av_free_packet(&pkt);

						}


output_frame_size 即爲AVCodecContext 的frame_size



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章