diff --git a/src/audio/audio_reader.cc b/src/audio/audio_reader.cc index be706f10..ef1da9c7 100644 --- a/src/audio/audio_reader.cc +++ b/src/audio/audio_reader.cc @@ -128,7 +128,11 @@ namespace decord { pCodecParameters = tempCodecParameters; originalSampleRate = tempCodecParameters->sample_rate; if (targetSampleRate == -1) targetSampleRate = originalSampleRate; + #if LIBAVCODEC_VERSION_MAJOR >= 59 + numChannels = tempCodecParameters->ch_layout.nb_channels; + #else numChannels = tempCodecParameters->channels; + #endif break; } } @@ -148,7 +152,6 @@ namespace decord { if (codecOpenRet < 0) { char errstr[200]; av_strerror(codecOpenRet, errstr, 200); - avcodec_close(pCodecContext); avcodec_free_context(&pCodecContext); avformat_close_input(&pFormatContext); LOG(FATAL) << "ERROR open codec through avcodec_open2: " << errstr; @@ -210,7 +213,6 @@ namespace decord { // clean up av_frame_free(&pFrame); av_packet_free(&pPacket); - avcodec_close(pCodecContext); swr_close(swr); swr_free(&swr); avcodec_free_context(&pCodecContext); @@ -229,7 +231,11 @@ namespace decord { // allocate resample buffer float** outBuffer; int outLinesize = 0; + #if LIBAVCODEC_VERSION_MAJOR >= 59 + int outNumChannels = mono ? 1 : pFrame->ch_layout.nb_channels; + #else int outNumChannels = av_get_channel_layout_nb_channels(mono ? AV_CH_LAYOUT_MONO : pFrame->channel_layout); + #endif numChannels = outNumChannels; int outNumSamples = av_rescale_rnd(pFrame->nb_samples, this->targetSampleRate, pFrame->sample_rate, AV_ROUND_UP); @@ -281,11 +287,33 @@ namespace decord { if (!this->swr) { LOG(FATAL) << "ERROR Failed to allocate resample context"; } + + #if LIBAVCODEC_VERSION_MAJOR >= 59 + // FFmpeg 6+ uses AVChannelLayout API + AVChannelLayout in_ch_layout = pCodecContext->ch_layout; + AVChannelLayout out_ch_layout; + + if (mono) { + av_channel_layout_default(&out_ch_layout, 1); + } else { + av_channel_layout_copy(&out_ch_layout, &in_ch_layout); + } + + av_opt_set_chlayout(this->swr, "in_chlayout", &in_ch_layout, 0); + av_opt_set_chlayout(this->swr, "out_chlayout", &out_ch_layout, 0); + + if (!mono) { + av_channel_layout_uninit(&out_ch_layout); + } + #else + // FFmpeg 5 and earlier use channel_layout if (pCodecContext->channel_layout == 0) { pCodecContext->channel_layout = av_get_default_channel_layout( pCodecContext->channels ); } av_opt_set_channel_layout(this->swr, "in_channel_layout", pCodecContext->channel_layout, 0); av_opt_set_channel_layout(this->swr, "out_channel_layout", mono ? AV_CH_LAYOUT_MONO : pCodecContext->channel_layout, 0); + #endif + av_opt_set_int(this->swr, "in_sample_rate", pCodecContext->sample_rate, 0); av_opt_set_int(this->swr, "out_sample_rate", this->targetSampleRate, 0); av_opt_set_sample_fmt(this->swr, "in_sample_fmt", pCodecContext->sample_fmt, 0); diff --git a/src/video/ffmpeg/ffmpeg_common.h b/src/video/ffmpeg/ffmpeg_common.h index b0b973f9..4d66980f 100644 --- a/src/video/ffmpeg/ffmpeg_common.h +++ b/src/video/ffmpeg/ffmpeg_common.h @@ -21,6 +21,7 @@ extern "C" { #endif #include +#include #include #include #include @@ -33,6 +34,7 @@ extern "C" { #include #include #include +#include #include #ifdef DECORD_USE_LIBAVDEVICE #include diff --git a/src/video/video_reader.cc b/src/video/video_reader.cc index af4858d2..0e11e144 100644 --- a/src/video/video_reader.cc +++ b/src/video/video_reader.cc @@ -145,7 +145,11 @@ VideoReader::~VideoReader(){ void VideoReader::SetVideoStream(int stream_nb) { if (!fmt_ctx_) return; + #if LIBAVCODEC_VERSION_MAJOR >= 59 + const AVCodec *dec; + #else AVCodec *dec; + #endif int st_nb = av_find_best_stream(fmt_ctx_.get(), AVMEDIA_TYPE_VIDEO, stream_nb, -1, &dec, 0); // LOG(INFO) << "find best stream: " << st_nb; CHECK_GE(st_nb, 0) << "ERROR cannot find video stream with wanted index: " << stream_nb; @@ -554,7 +558,12 @@ double VideoReader::GetRotation() const { if (rotate && *rotate->value && strcmp(rotate->value, "0")) theta = atof(rotate->value); + #if LIBAVCODEC_VERSION_MAJOR >= 59 + const AVPacketSideData* side_data = av_packet_side_data_get(active_st->codecpar->coded_side_data, active_st->codecpar->nb_coded_side_data, AV_PKT_DATA_DISPLAYMATRIX); + const uint8_t* displaymatrix = side_data ? side_data->data : NULL; + #else uint8_t* displaymatrix = av_stream_get_side_data(active_st, AV_PKT_DATA_DISPLAYMATRIX, NULL); + #endif if (displaymatrix && !theta) theta = -av_display_rotation_get((int32_t*) displaymatrix);