[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