###user=Sayaka ###link=https://forum.makemkv.com/forum/viewtopic.php?p=204010#p204010 from pathlib import Path p = Path("libffabi/src/ffabi.c") s = p.read_text() start = s.index("#ifndef FFABI_HAVE_OLD_CHANNEL_LAYOUT\nstatic int set_codec_info_extended") end = s.index("\nFFM_AudioConvert* __cdecl ffm_audio_convert_alloc", start) replacement = r'''#ifndef FFABI_HAVE_OLD_CHANNEL_LAYOUT static int set_codec_info_extended(FFM_CodecInfo* info, const AVCodec* codec) { char* exinfo; size_t len; int count_ch_layouts_in = 0; unsigned int count_ch_layouts_out = 0; uint64_t* channel_layouts; const AVChannelLayout* ch_layouts = NULL; unsigned int i; int ret; len = strlen(codec->name); if (len >= FFM_CODEC_INFO_NAME_MAX_LENGTH) return -1; ret = avcodec_get_supported_config( NULL, codec, AV_CODEC_CONFIG_CHANNEL_LAYOUT, 0, (const void**)&ch_layouts, &count_ch_layouts_in ); if (ret < 0) return -1; exinfo = (char*)ffabi_memalign( sizeof(uint64_t), FFM_CODEC_INFO_NAME_MAX_LENGTH + FFM_CODEC_INFO_EXMARK_LENGTH + ((count_ch_layouts_in + 1) * sizeof(uint64_t)) ); if (NULL == exinfo) return -1; memcpy(exinfo, codec->name, len + 1); memcpy(exinfo + FFM_CODEC_INFO_NAME_MAX_LENGTH, FFM_CODEC_INFO_EXMARK_MAGIC, FFM_CODEC_INFO_EXMARK_LENGTH); channel_layouts = (uint64_t*)( exinfo + FFM_CODEC_INFO_NAME_MAX_LENGTH + FFM_CODEC_INFO_EXMARK_LENGTH ); info->name = exinfo; info->channel_layouts = channel_layouts; for (i = 0; i < (unsigned int)count_ch_layouts_in; i++) { if (AV_CHANNEL_ORDER_NATIVE != ch_layouts[i].order) continue; channel_layouts[count_ch_layouts_out++] = ch_layouts[i].u.mask; } channel_layouts[count_ch_layouts_out] = 0; return 0; } #endif int __cdecl ffm_audio_get_codec_information( FFM_CodecInfo* info, const char* name, int encode) { AVCodec* codec; const int* sample_rates = NULL; const enum AVSampleFormat* sample_fmts = NULL; #ifndef FFABI_HAVE_OLD_CHANNEL_LAYOUT const AVChannelLayout* ch_layouts = NULL; #endif int num_sample_rates = 0; int num_sample_fmts = 0; #ifndef FFABI_HAVE_OLD_CHANNEL_LAYOUT int num_ch_layouts = 0; #endif int ret; int i; memset(info, 0, sizeof(*info)); if (encode) { codec = (AVCodec*)avcodec_find_encoder_by_name(name); } else { codec = (AVCodec*)avcodec_find_decoder_by_name(name); } if (!codec) return ffmerr(1, encode); info->name = codec->name; info->long_name = codec->long_name; ret = avcodec_get_supported_config( NULL, codec, AV_CODEC_CONFIG_SAMPLE_RATE, 0, (const void**)&sample_rates, &num_sample_rates ); if (ret < 0) return ffmerr(2, 0); info->sample_rates = sample_rates; #ifdef FFABI_HAVE_OLD_CHANNEL_LAYOUT info->channel_layouts = codec->channel_layouts; #else ret = avcodec_get_supported_config( NULL, codec, AV_CODEC_CONFIG_CHANNEL_LAYOUT, 0, (const void**)&ch_layouts, &num_ch_layouts ); if (ret < 0) return ffmerr(2, 0); if (NULL == ch_layouts) { info->channel_layouts = NULL; } else { if (set_codec_info_extended(info, codec)) return ffmerr(2, 0); } #endif info->id = codec->id; info->capabilities = codec->capabilities; if (codec->profiles) { for (i = 0; i < 32; i++) { if (codec->profiles[i].profile == AV_PROFILE_UNKNOWN) break; info->profiles_names[i] = codec->profiles[i].name; info->profiles_values[i] = codec->profiles[i].profile; info->profiles_count = i + 1; } } ret = avcodec_get_supported_config( NULL, codec, AV_CODEC_CONFIG_SAMPLE_FORMAT, 0, (const void**)&sample_fmts, &num_sample_fmts ); if (ret < 0) return ffmerr(2, 0); if (sample_fmts) { for (i = 0; i < num_sample_fmts && i < 16; i++) { info->sample_formats[i] = (uint8_t)back_translate_sample_fmt(sample_fmts[i]); info->sample_formats_count = i + 1; } } return 0; } ''' p.write_text(s[:start] + replacement + s[end:]) print("Patched:", p)