Am 8/13/2015 um 9:47 AM schrieb Jan Drabner:
(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.
Obviously, I meant that 22050/44100 is 0.5 ;)
_______________________________________________
Libav-user mailing list
[email protected]
http://ffmpeg.org/mailman/listinfo/libav-user