[Libav-user] FFmpeg transcoded sound (AAC) stops after half video time
Jan Drabner
jan at jdrabner.eu
Thu Aug 13 09:47:51 CEST 2015
(This is the same post I made on Stackoverflow:
http://stackoverflow.com/questions/31968745/ffmpeg-transcoded-sound-aac-stops-after-half-video-time
)
I have a strange problem in my C/C++ FFmpeg transcoder, which takes an
input MP4 (varying input codecs) and produces and output MP4 (x264,
baseline & AAC LC @44100 sample rate with libfdk_aac):
The resulting mp4 video has fine images (x264) and the audio (AAC LC)
works fine as well, but is only played until exactly the half of the video.
The audio is not slowed down, not stretched and doesn't stutter. It just
stops right in the middle of the video.
One hint may be that the input file has a sample rate of 22050 and
44100/22050 is 0.5, but I really don't get why this would make the sound
just stop. I'd expect such an error leading to sound being at the wrong
speed. Everything works just fine if I don't try to enforce 44100 and
instead just use the incoming sample_rate.
Another guess would be that the pts calculation doesn't work. But the
audio sounds just fine (until it stops) and I do exactly the same for
the video part, where it works flawlessly. "Exactly", as in the same
code, but "audio"-variables replaced with "video"-variables.
FFmpeg reports no errors during the whole process. I also flush the
decoders/encoders/interleaved_writing after all the package reading from
the input is done. It works well for the video so I doubt there is much
wrong with my general approach.
Here are the functions of my code (stripped off the error handling &
other class stuff):
AudioCodecContext Setup
|outContext->_audioCodec
=avcodec_find_encoder(outContext->_audioTargetCodecID);outContext->_audioStream
=avformat_new_stream(outContext->_formatContext,outContext->_audioCodec);outContext->_audioCodecContext
=outContext->_audioStream->codec;outContext->_audioCodecContext->channels =2;outContext->_audioCodecContext->channel_layout
=av_get_default_channel_layout(2);outContext->_audioCodecContext->sample_rate
=44100;outContext->_audioCodecContext->sample_fmt
=outContext->_audioCodec->sample_fmts[0];outContext->_audioCodecContext->bit_rate
=128000;outContext->_audioCodecContext->strict_std_compliance
=FF_COMPLIANCE_EXPERIMENTAL;outContext->_audioCodecContext->time_base
=(AVRational){1,outContext->_audioCodecContext->sample_rate};outContext->_audioStream->time_base
=(AVRational){1,outContext->_audioCodecContext->sample_rate};intretVal
=avcodec_open2(outContext->_audioCodecContext,outContext->_audioCodec,NULL);
|
Resampler Setup
|outContext->_audioResamplerContext
=swr_alloc_set_opts(NULL,outContext->_audioCodecContext->channel_layout,outContext->_audioCodecContext->sample_fmt,outContext->_audioCodecContext->sample_rate,_inputContext._audioCodecContext->channel_layout,_inputContext._audioCodecContext->sample_fmt,_inputContext._audioCodecContext->sample_rate,0,NULL);intretVal
=swr_init(outContext->_audioResamplerContext); |
Decoding
|decodedBytes
=avcodec_decode_audio4(_inputContext._audioCodecContext,_inputContext._audioTempFrame,&p_gotAudioFrame,&_inputContext._currentPacket);
|
Converting (only if decoding produced a frame, of course)
|intretVal
=swr_convert(outContext->_audioResamplerContext,outContext->_audioConvertedFrame->data,outContext->_audioConvertedFrame->nb_samples,(constuint8_t**)_inputContext._audioTempFrame->data,_inputContext._audioTempFrame->nb_samples);
|
Encoding (only if decoding produced a frame, of course)
|outContext->_audioConvertedFrame->pts
=av_frame_get_best_effort_timestamp(_inputContext._audioTempFrame);//
Init the new
packetav_init_packet(&outContext->_audioPacket);outContext->_audioPacket.data
=NULL;outContext->_audioPacket.size =0;// EncodeintretVal
=avcodec_encode_audio2(outContext->_audioCodecContext,&outContext->_audioPacket,outContext->_audioConvertedFrame,&p_gotPacket);//
Set pts/dts time stamps for writing
interleavedav_packet_rescale_ts(&outContext->_audioPacket,outContext->_audioCodecContext->time_base,outContext->_audioStream->time_base);outContext->_audioPacket.stream_index
=outContext->_audioStream->index; |
Writing (only if encoding produced a packet, of course)
|intretVal
=av_interleaved_write_frame(outContext->_formatContext,&outContext->_audioPacket);
|
I am quite out of ideas about what would cause such a behaviour.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20150813/96f304f3/attachment.html>
More information about the Libav-user
mailing list