diff --git a/src/media.cpp b/src/media.cpp index 8cf1369f..1ae4c1c7 100644 --- a/src/media.cpp +++ b/src/media.cpp @@ -61,6 +61,8 @@ typedef AVCodec FeAVCodec; #define FORMAT_CTX_URL m_imp->m_format_ctx->filename #endif +#define HAVE_CH_LAYOUT (LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(57, 28, 100)) + void try_hw_accel( AVCodecContext *&codec_ctx, FeAVCodec *&dec ); std::string g_decoder; @@ -321,11 +323,19 @@ FeAudioImp::~FeAudioImp() bool FeAudioImp::process_frame( AVFrame *frame, sf::SoundStream::Chunk &data, int &offset ) { +#ifdef HAVE_CH_LAYOUT + int data_size = av_samples_get_buffer_size( + NULL, + codec_ctx->ch_layout.nb_channels, + frame->nb_samples, + codec_ctx->sample_fmt, 1); +#else int data_size = av_samples_get_buffer_size( NULL, codec_ctx->channels, frame->nb_samples, codec_ctx->sample_fmt, 1); +#endif if ( codec_ctx->sample_fmt == AV_SAMPLE_FMT_S16 ) { @@ -349,17 +359,24 @@ bool FeAudioImp::process_frame( AVFrame *frame, sf::SoundStream::Chunk &data, in return false; } +#ifdef HAVE_CH_LAYOUT + AVChannelLayout layout = frame->ch_layout.u.mask; + av_channel_layout_default(&layout, codec_ctx->ch_layout.nb_channels); + av_opt_set_chlayout(resample_ctx, "in_chlayout", &layout, 0); + av_opt_set_chlayout(resample_ctx, "out_chlayout", &layout, 0); +#else int64_t channel_layout = frame->channel_layout; if ( !channel_layout ) { channel_layout = av_get_default_channel_layout( codec_ctx->channels ); } - av_opt_set_int( resample_ctx, "in_channel_layout", channel_layout, 0 ); + av_opt_set_int( resample_ctx, "out_channel_layout", channel_layout, 0 ); +#endif + av_opt_set_int( resample_ctx, "in_sample_fmt", frame->format, 0 ); av_opt_set_int( resample_ctx, "in_sample_rate", frame->sample_rate, 0 ); - av_opt_set_int( resample_ctx, "out_channel_layout", channel_layout, 0 ); av_opt_set_int( resample_ctx, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0 ); av_opt_set_int( resample_ctx, "out_sample_rate", frame->sample_rate, 0 ); @@ -382,11 +399,19 @@ bool FeAudioImp::process_frame( AVFrame *frame, sf::SoundStream::Chunk &data, in if ( resample_ctx ) { int out_linesize; +#ifdef HAVE_CH_LAYOUT + av_samples_get_buffer_size( + &out_linesize, + codec_ctx->ch_layout.nb_channels, + frame->nb_samples, + AV_SAMPLE_FMT_S16, 0 ); +#else av_samples_get_buffer_size( &out_linesize, codec_ctx->channels, frame->nb_samples, AV_SAMPLE_FMT_S16, 0 ); +#endif uint8_t *tmp_ptr = (uint8_t *)(audio_buff + offset); @@ -402,8 +427,13 @@ bool FeAudioImp::process_frame( AVFrame *frame, sf::SoundStream::Chunk &data, in FeLog() << "Error performing audio conversion." << std::endl; return false; } +#ifdef HAVE_CH_LAYOUT + offset += out_samples * codec_ctx->ch_layout.nb_channels; + data.sampleCount += out_samples * codec_ctx->ch_layout.nb_channels; +#else offset += out_samples * codec_ctx->channels; data.sampleCount += out_samples * codec_ctx->channels; +#endif data.samples = audio_buff; } } @@ -752,8 +782,17 @@ void FeVideoImp::video_thread() if ( raw_frame->pts == AV_NOPTS_VALUE ) raw_frame->pts = packet->dts; -// This only works on FFmpeg, exclude libav (it doesn't have pkt_duration -#if (LIBAVUTIL_VERSION_MICRO >= 100 ) + +#if (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT( 57, 30, 100 )) + // Correct for out of bounds pts + if ( raw_frame->pts < prev_pts ) + raw_frame->pts = prev_pts + prev_duration; + + // Track pts and duration if we need to correct next frame + prev_pts = raw_frame->pts; + prev_duration = raw_frame->duration; +#elif (LIBAVUTIL_VERSION_MICRO >= 100 ) + // This only works on FFmpeg, exclude libav (it doesn't have pkt_duration // Correct for out of bounds pts if ( raw_frame->pts < prev_pts ) raw_frame->pts = prev_pts + prev_duration; @@ -1064,10 +1103,15 @@ bool FeMedia::open( const std::string &archive, MAX_AUDIO_FRAME_SIZE + AV_INPUT_BUFFER_PADDING_SIZE + codec_ctx->sample_rate ); - +#ifdef HAVE_CH_LAYOUT + sf::SoundStream::initialize( + codec_ctx->ch_layout.nb_channels, + codec_ctx->sample_rate ); +#else sf::SoundStream::initialize( codec_ctx->channels, codec_ctx->sample_rate ); +#endif sf::SoundStream::setLoop( false ); }