Skip to content

Commit

Permalink
FFMPEG 7 compatibility
Browse files Browse the repository at this point in the history
thanks @eclipseo
  • Loading branch information
substring committed May 4, 2024
1 parent c08ad9b commit 67ca08c
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 5 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ jobs:
- name: Install MacOS brew
if: runner.os == 'macOS'
run: |
brew install pkg-config ffmpeg@6 libarchive libvorbis flac jpeg-turbo openal-soft boost
brew install pkg-config ffmpeg libarchive libvorbis flac jpeg-turbo openal-soft boost
- name: Build AM+ (ARM)
if: matrix.platform.name == 'armv7' || matrix.platform.name == 'aarch64'
Expand Down Expand Up @@ -121,7 +121,7 @@ jobs:
run: |
make -C am -j${{ steps.vars.outputs.nbproc }} VERBOSE=1 FE_VERSION=${{ steps.vars.outputs.fe_version }} ${{matrix.platform.amflags}} ${{matrix.config.amflags}} ${{env.cross_toolchain}}
env:
PKG_CONFIG_PATH: "/usr/local/opt/openal-soft/lib/pkgconfig:/usr/local/opt/ffmpeg@6/lib/pkgconfig"
PKG_CONFIG_PATH: "/usr/local/opt/openal-soft/lib/pkgconfig"

- name: Build AM+ attract-console.exe (Windows only)
if: matrix.platform.name == 'Windows x64'
Expand Down
59 changes: 56 additions & 3 deletions src/media.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ typedef AVCodec FeAVCodec;
#define FORMAT_CTX_URL m_imp->m_format_ctx->filename
#endif

#if (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT( 61, 3, 100 ))
#define USE_CH_LAYOUT
#endif

void try_hw_accel( AVCodecContext *&codec_ctx, FeAVCodec *&dec );

std::string g_decoder;
Expand Down Expand Up @@ -323,11 +327,19 @@ FeAudioImp::~FeAudioImp()

bool FeAudioImp::process_frame( AVFrame *frame, sf::SoundStream::Chunk &data, int &offset )
{
#ifdef USE_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 )
{
Expand All @@ -351,17 +363,31 @@ bool FeAudioImp::process_frame( AVFrame *frame, sf::SoundStream::Chunk &data, in
return false;
}

#ifdef USE_CH_LAYOUT
int64_t channel_layout = frame->ch_layout.u.mask;
if ( !channel_layout )
{
AVChannelLayout l;
av_channel_layout_default(&l,
codec_ctx->ch_layout.nb_channels );
}
#else
int64_t channel_layout = frame->channel_layout;
if ( !channel_layout )
{
channel_layout = av_get_default_channel_layout(
codec_ctx->channels );
}
#endif

#ifndef USE_CH_LAYOUT
av_opt_set_int( resample_ctx, "in_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 );
#ifndef USE_CH_LAYOUT
av_opt_set_int( resample_ctx, "out_channel_layout", channel_layout, 0 );
#endif
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 );

Expand All @@ -384,11 +410,19 @@ bool FeAudioImp::process_frame( AVFrame *frame, sf::SoundStream::Chunk &data, in
if ( resample_ctx )
{
int out_linesize;
#ifdef USE_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);

Expand All @@ -404,8 +438,13 @@ bool FeAudioImp::process_frame( AVFrame *frame, sf::SoundStream::Chunk &data, in
FeLog() << "Error performing audio conversion." << std::endl;
return false;
}
#ifdef USE_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;
}
}
Expand Down Expand Up @@ -739,8 +778,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;
Expand Down Expand Up @@ -1051,10 +1099,15 @@ bool FeMedia::open( const std::string &archive,
MAX_AUDIO_FRAME_SIZE
+ AV_INPUT_BUFFER_PADDING_SIZE
+ codec_ctx->sample_rate );

#ifdef USE_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 );
}
Expand Down

1 comment on commit 67ca08c

@eclipseo
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@substring this was reworked mickelson/attract@master...eclipseo:attract:fix_for_ffmpeg7

Please check the difference, significant problems with the first draft.

Please sign in to comment.