@@ -225,6 +225,7 @@ BEGIN_FFMPEG_NAMESPACE_V
225225 outputAudioStream->codecpar ->bit_rate = 128000 ;
226226 outputAudioStream->codecpar ->format = AVSampleFormat::AV_SAMPLE_FMT_FLTP;
227227 outputAudioStream->codecpar ->frame_size = frameSize;
228+ outputAudioStream->time_base = AVRational{1 , static_cast <int >(sampleRate)};
228229
229230 outputFormatContext->audio_codec = avcodec_find_encoder (AV_CODEC_ID_AAC);
230231 outputFormatContext->audio_codec_id = AV_CODEC_ID_AAC;
@@ -242,9 +243,13 @@ BEGIN_FFMPEG_NAMESPACE_V
242243 audio_codec_context_encoder->sample_fmt = audioCodec->sample_fmts ? audioCodec->sample_fmts [0 ] : AV_SAMPLE_FMT_FLTP;
243244 audio_codec_context_encoder->time_base = AVRational{1 , static_cast <int >(sampleRate)};
244245
246+ if (outputFormatContext->oformat ->flags & AVFMT_GLOBALHEADER)
247+ audio_codec_context_encoder->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
248+
245249 ret = avcodec_open2 (audio_codec_context_encoder, audioCodec, nullptr );
246250 if (ret < 0 )
247251 return geode::Err (" Could not open encoder: " + utils::getErrorString (ret));
252+ avcodec_parameters_from_context (outputAudioStream->codecpar , audio_codec_context_encoder);
248253
249254 if (!(outputFormatContext->oformat ->flags & AVFMT_NOFILE)) {
250255 if (ret = avio_open (&outputFormatContext->pb , outputMp4File.string ().c_str (), AVIO_FLAG_WRITE); ret < 0 ) {
@@ -265,7 +270,7 @@ BEGIN_FFMPEG_NAMESPACE_V
265270 while (true ) {
266271 if (av_read_frame (videoFormatContext, &packet) >= 0 ) {
267272 av_packet_rescale_ts (&packet, videoFormatContext->streams [videoStreamIndex]->time_base , outputVideoStream->time_base );
268- packet.stream_index = videoStreamIndex ;
273+ packet.stream_index = outputVideoStream-> index ;
269274 av_interleaved_write_frame (outputFormatContext, &packet);
270275 av_packet_unref (&packet);
271276 } else {
@@ -282,6 +287,9 @@ BEGIN_FFMPEG_NAMESPACE_V
282287 audioFrame->format = AV_SAMPLE_FMT_FLTP;
283288 audioFrame->ch_layout = AV_CHANNEL_LAYOUT_STEREO;
284289
290+ AVPacket* audioPacket = av_packet_alloc ();
291+ if (!audioPacket) return geode::Err (" Failed to allocate audio packet." );
292+
285293 for (size_t i = 0 ; i < resampled.size (); i += frameSize * channels) {
286294 int samplesToEncode = std::min (frameSize, static_cast <int >((resampled.size () - i) / channels));
287295
@@ -301,9 +309,6 @@ BEGIN_FFMPEG_NAMESPACE_V
301309 if (ret = avcodec_send_frame (audio_codec_context_encoder, audioFrame); ret < 0 )
302310 return geode::Err (" Could not send audio frame to encoder: " + utils::getErrorString (ret));
303311
304- AVPacket* audioPacket = av_packet_alloc ();
305- if (!audioPacket) return geode::Err (" Failed to allocate audio packet." );
306-
307312 while (true ) {
308313 int ret = avcodec_receive_packet (audio_codec_context_encoder, audioPacket);
309314 if (ret == 0 ) {
@@ -318,6 +323,26 @@ BEGIN_FFMPEG_NAMESPACE_V
318323 }
319324 }
320325
326+ avcodec_send_frame (audio_codec_context_encoder, nullptr );
327+
328+ while (true ) {
329+ int recv_ret = avcodec_receive_packet (audio_codec_context_encoder, audioPacket);
330+ if (recv_ret == 0 ) {
331+ av_packet_rescale_ts (audioPacket,
332+ audio_codec_context_encoder->time_base ,
333+ outputAudioStream->time_base );
334+
335+ audioPacket->stream_index = outputAudioStream->index ;
336+ av_interleaved_write_frame (outputFormatContext, audioPacket);
337+ av_packet_unref (audioPacket);
338+ } else if (recv_ret == AVERROR_EOF || recv_ret == AVERROR (EAGAIN)) {
339+ break ;
340+ } else {
341+ return geode::Err (" Could not receive audio packet: " + utils::getErrorString (ret));
342+ }
343+ }
344+
345+ av_packet_free (&audioPacket);
321346 av_frame_free (&audioFrame);
322347
323348 av_write_trailer (outputFormatContext);
0 commit comments