From: Carl Hetherington Date: Fri, 29 Mar 2024 22:23:10 +0000 (+0100) Subject: Merge remote-tracking branch 'origin/main' into v2.17.x X-Git-Tag: v2.17.15~2 X-Git-Url: https://main.carlh.net/gitweb/?a=commitdiff_plain;h=a115088ca904a26d100e479a7fde21c9235bf7c9;hp=-c;p=dcpomatic.git Merge remote-tracking branch 'origin/main' into v2.17.x --- a115088ca904a26d100e479a7fde21c9235bf7c9 diff --combined src/lib/ffmpeg_content.cc index 8baa40c1b,4a7c87b34..c80bdec69 --- a/src/lib/ffmpeg_content.cc +++ b/src/lib/ffmpeg_content.cc @@@ -197,61 -197,61 +197,61 @@@ FFmpegContent::FFmpegContent (vectoradd_child("Type")->add_child_text("FFmpeg"); - Content::as_xml (node, with_paths); + cxml::add_text_child(element, "Type", "FFmpeg"); + Content::as_xml(element, with_paths); if (video) { - video->as_xml (node); + video->as_xml(element); } if (audio) { - audio->as_xml (node); + audio->as_xml(element); for (auto i: audio->streams()) { auto f = dynamic_pointer_cast (i); DCPOMATIC_ASSERT (f); - f->as_xml (node->add_child("AudioStream")); + f->as_xml(cxml::add_child(element, "AudioStream")); } } if (only_text()) { - only_text()->as_xml (node); + only_text()->as_xml(element); } boost::mutex::scoped_lock lm (_mutex); for (auto i: _subtitle_streams) { - auto t = node->add_child("SubtitleStream"); + auto t = cxml::add_child(element, "SubtitleStream"); if (_subtitle_stream && i == _subtitle_stream) { - t->add_child("Selected")->add_child_text("1"); + cxml::add_text_child(t, "Selected", "1"); } i->as_xml (t); } for (auto i: _filters) { - node->add_child("Filter")->add_child_text(i.id()); + cxml::add_text_child(element, "Filter", i.id()); } if (_first_video) { - node->add_child("FirstVideo")->add_child_text(raw_convert(_first_video.get().get())); + cxml::add_text_child(element, "FirstVideo", raw_convert(_first_video.get().get())); } if (_color_range) { - node->add_child("ColorRange")->add_child_text(raw_convert(static_cast(*_color_range))); + cxml::add_text_child(element, "ColorRange", raw_convert(static_cast(*_color_range))); } if (_color_primaries) { - node->add_child("ColorPrimaries")->add_child_text(raw_convert(static_cast(*_color_primaries))); + cxml::add_text_child(element, "ColorPrimaries", raw_convert(static_cast(*_color_primaries))); } if (_color_trc) { - node->add_child("ColorTransferCharacteristic")->add_child_text(raw_convert(static_cast(*_color_trc))); + cxml::add_text_child(element, "ColorTransferCharacteristic", raw_convert(static_cast(*_color_trc))); } if (_colorspace) { - node->add_child("Colorspace")->add_child_text(raw_convert(static_cast(*_colorspace))); + cxml::add_text_child(element, "Colorspace", raw_convert(static_cast(*_colorspace))); } if (_bits_per_pixel) { - node->add_child("BitsPerPixel")->add_child_text(raw_convert(*_bits_per_pixel)); + cxml::add_text_child(element, "BitsPerPixel", raw_convert(*_bits_per_pixel)); } } @@@ -295,8 -295,10 +295,10 @@@ FFmpegContent::examine (shared_ptrrotate_size(); } else if (fabs (rot - 270) < 1.0) { _filters.push_back(*Filter::from_id("90anticlock")); + video->rotate_size(); } } if (examiner->has_alpha()) { diff --combined src/lib/ffmpeg_examiner.cc index 583ea1297,787198e4a..f7d3f9df3 --- a/src/lib/ffmpeg_examiner.cc +++ b/src/lib/ffmpeg_examiner.cc @@@ -73,6 -73,14 +73,6 @@@ FFmpegExaminer::FFmpegExaminer (shared_ auto codec = _codec_context[i] ? _codec_context[i]->codec : nullptr; if (s->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && codec) { - /* This is a hack; sometimes it seems that _audio_codec_context->channel_layout isn't set up, - so bodge it here. No idea why we should have to do this. - */ - - if (s->codecpar->channel_layout == 0) { - s->codecpar->channel_layout = av_get_default_channel_layout (s->codecpar->channels); - } - DCPOMATIC_ASSERT (_format_context->duration != AV_NOPTS_VALUE); DCPOMATIC_ASSERT (codec->name); @@@ -83,7 -91,7 +83,7 @@@ s->id, s->codecpar->sample_rate, llrint ((double(_format_context->duration) / AV_TIME_BASE) * s->codecpar->sample_rate), - s->codecpar->channels, + s->codecpar->ch_layout.nb_channels, s->codecpar->bits_per_raw_sample ? s->codecpar->bits_per_raw_sample : s->codecpar->bits_per_coded_sample ) ); @@@ -153,7 -161,7 +153,7 @@@ av_packet_free (&packet); - if (_first_video && got_all_audio && temporal_reference.size() >= (PULLDOWN_CHECK_FRAMES * 2)) { + if (got_all_audio && (!_video_stream || (_first_video && temporal_reference.size() >= (PULLDOWN_CHECK_FRAMES * 2)))) { /* All done */ break; } @@@ -173,8 -181,8 +173,6 @@@ /* This code taken from get_rotation() in ffmpeg:cmdutils.c */ auto stream = _format_context->streams[*_video_stream]; auto rotate_tag = av_dict_get (stream->metadata, "rotate", 0, 0); - _rotation = 0; - uint8_t* displaymatrix = av_stream_get_side_data (stream, AV_PKT_DATA_DISPLAYMATRIX, 0); -- if (rotate_tag && *rotate_tag->value && strcmp(rotate_tag->value, "0")) { char *tail; _rotation = av_strtod (rotate_tag->value, &tail); @@@ -183,9 -191,8 +181,9 @@@ } } - if (displaymatrix && !_rotation) { - _rotation = - av_display_rotation_get ((int32_t*) displaymatrix); + auto side_data = av_packet_side_data_get(stream->codecpar->coded_side_data, stream->codecpar->nb_coded_side_data, AV_PKT_DATA_DISPLAYMATRIX); + if (side_data && !_rotation) { + _rotation = - av_display_rotation_get(reinterpret_cast(side_data->data)); } _rotation = *_rotation - 360 * floor (*_rotation / 360 + 0.9 / 360); @@@ -244,7 -251,7 +242,7 @@@ FFmpegExaminer::video_packet (AVCodecCo ).get_value_or (ContentTime ()).frames_round (video_frame_rate().get ()); } if (temporal_reference.size() < (PULLDOWN_CHECK_FRAMES * 2)) { - temporal_reference += (_video_frame->top_field_first ? "T" : "B"); + temporal_reference += ((_video_frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) ? "T" : "B"); temporal_reference += (_video_frame->repeat_pict ? "3" : "2"); } diff --combined src/lib/video_content.cc index e84462ed2,6c027ff11..10dd5ff1e --- a/src/lib/video_content.cc +++ b/src/lib/video_content.cc @@@ -273,37 -273,37 +273,37 @@@ VideoContent::VideoContent (Content* pa void -VideoContent::as_xml (xmlpp::Node* node) const +VideoContent::as_xml(xmlpp::Element* element) const { boost::mutex::scoped_lock lm (_mutex); - node->add_child("Use")->add_child_text (_use ? "1" : "0"); - node->add_child("VideoLength")->add_child_text (raw_convert (_length)); + cxml::add_text_child(element, "Use", _use ? "1" : "0"); + cxml::add_text_child(element, "VideoLength", raw_convert(_length)); if (_size) { - node->add_child("VideoWidth")->add_child_text(raw_convert(_size->width)); - node->add_child("VideoHeight")->add_child_text(raw_convert(_size->height)); + cxml::add_text_child(element, "VideoWidth", raw_convert(_size->width)); + cxml::add_text_child(element, "VideoHeight", raw_convert(_size->height)); } - node->add_child("VideoFrameType")->add_child_text (video_frame_type_to_string (_frame_type)); + cxml::add_text_child(element, "VideoFrameType", video_frame_type_to_string(_frame_type)); if (_sample_aspect_ratio) { - node->add_child("SampleAspectRatio")->add_child_text (raw_convert (_sample_aspect_ratio.get ())); + cxml::add_text_child(element, "SampleAspectRatio", raw_convert (_sample_aspect_ratio.get ())); } - _crop.as_xml (node); + _crop.as_xml(element); if (_custom_ratio) { - node->add_child("CustomRatio")->add_child_text(raw_convert(*_custom_ratio)); + cxml::add_text_child(element, "CustomRatio", raw_convert(*_custom_ratio)); } if (_custom_size) { - node->add_child("CustomWidth")->add_child_text(raw_convert(_custom_size->width)); - node->add_child("CustomHeight")->add_child_text(raw_convert(_custom_size->height)); + cxml::add_text_child(element, "CustomWidth", raw_convert(_custom_size->width)); + cxml::add_text_child(element, "CustomHeight", raw_convert(_custom_size->height)); } if (_colour_conversion) { - _colour_conversion.get().as_xml (node->add_child("ColourConversion")); + _colour_conversion.get().as_xml(cxml::add_child(element, "ColourConversion")); } - node->add_child("YUV")->add_child_text (_yuv ? "1" : "0"); - node->add_child("FadeIn")->add_child_text (raw_convert (_fade_in)); - node->add_child("FadeOut")->add_child_text (raw_convert (_fade_out)); - node->add_child("Range")->add_child_text(_range == VideoRange::FULL ? "full" : "video"); - _pixel_quanta.as_xml(node->add_child("PixelQuanta")); + cxml::add_text_child(element, "YUV", _yuv ? "1" : "0"); + cxml::add_text_child(element, "FadeIn", raw_convert(_fade_in)); + cxml::add_text_child(element, "FadeOut", raw_convert(_fade_out)); + cxml::add_text_child(element, "Range", _range == VideoRange::FULL ? "full" : "video"); + _pixel_quanta.as_xml(cxml::add_child(element, "PixelQuanta")); if (_burnt_subtitle_language) { - node->add_child("BurntSubtitleLanguage")->add_child_text(_burnt_subtitle_language->to_string()); + cxml::add_text_child(element, "BurntSubtitleLanguage", _burnt_subtitle_language->to_string()); } } @@@ -424,29 -424,27 +424,29 @@@ VideoContent::size_after_crop () cons } -/** @param f Frame index within the whole (untrimmed) content. +/** @param time Time within the whole (untrimmed) content. * @return Fade factor (between 0 and 1) or unset if there is no fade. */ optional -VideoContent::fade (shared_ptr film, Frame f) const +VideoContent::fade(shared_ptr film, ContentTime time) const { - DCPOMATIC_ASSERT (f >= 0); + DCPOMATIC_ASSERT(time.get() >= 0); double const vfr = _parent->active_video_frame_rate(film); - auto const ts = _parent->trim_start().frames_round(vfr); - if ((f - ts) < fade_in()) { - return double (f - ts) / fade_in(); + auto const ts = _parent->trim_start(); + auto const fade_in_time = ContentTime::from_frames(fade_in(), vfr); + if ((time - ts) < fade_in_time) { + return double(ContentTime(time - ts).get()) / fade_in_time.get(); } - auto fade_out_start = length() - _parent->trim_end().frames_round(vfr) - fade_out(); - if (f >= fade_out_start) { - return 1 - double (f - fade_out_start) / fade_out(); + auto const fade_out_time = ContentTime::from_frames(fade_out(), vfr); + auto fade_out_start = ContentTime::from_frames(length(), vfr) - _parent->trim_end() - fade_out_time; + if (time >= fade_out_start) { + return 1 - double(ContentTime(time - fade_out_start).get()) / fade_out_time.get(); } - return optional (); + return {}; } string @@@ -724,3 -722,12 +724,12 @@@ VideoContent::actual_crop () cons ); } + + void + VideoContent::rotate_size() + { + if (_size) { + std::swap(_size->width, _size->height); + } + } + diff --combined src/lib/video_content.h index a7b630b14,495d000e1..eb106cc75 --- a/src/lib/video_content.h +++ b/src/lib/video_content.h @@@ -66,7 -66,7 +66,7 @@@ public VideoContent (Content* parent, cxml::ConstNodePtr node, int version, VideoRange video_range_hint); VideoContent (Content* parent, std::vector>); - void as_xml (xmlpp::Node *) const; + void as_xml(xmlpp::Element*) const; std::string technical_summary () const; std::string identifier () const; void take_settings_from (std::shared_ptr c); @@@ -208,7 -208,7 +208,7 @@@ boost::optional size_after_crop() const; boost::optional scaled_size(dcp::Size container_size); - boost::optional fade (std::shared_ptr film, Frame) const; + boost::optional fade(std::shared_ptr film, dcpomatic::ContentTime time) const; std::string processing_description (std::shared_ptr film); @@@ -220,6 -220,8 +220,8 @@@ void modify_position (std::shared_ptr film, dcpomatic::DCPTime& pos) const; void modify_trim_start (dcpomatic::ContentTime& pos) const; + void rotate_size(); + static std::shared_ptr from_xml (Content* parent, cxml::ConstNodePtr node, int version, VideoRange video_range_hint); private: diff --combined wscript index fb2598dc9,f6f73a52a..19fd4260c --- a/wscript +++ b/wscript @@@ -61,7 -61,6 +61,6 @@@ def options(opt) opt.add_option('--disable-tests', action='store_true', default=False, help='disable building of tests') opt.add_option('--target-windows-64', action='store_true', default=False, help='set up to do a cross-compile for Windows 64-bit') opt.add_option('--target-windows-32', action='store_true', default=False, help='set up to do a cross-compile for Windows 32-bit') - opt.add_option('--target-macos-arm64', action='store_true', default=False, help='set up to do a cross-compile for macOS arm64') opt.add_option('--static-dcpomatic', action='store_true', default=False, help='link to components of DCP-o-matic statically') opt.add_option('--static-boost', action='store_true', default=False, help='link statically to Boost') opt.add_option('--static-wxwidgets', action='store_true', default=False, help='link statically to wxWidgets') @@@ -76,12 -75,10 +75,12 @@@ opt.add_option('--workaround-gssapi', action='store_true', default=False, help='link to gssapi_krb5') opt.add_option('--use-lld', action='store_true', default=False, help='use lld linker') opt.add_option('--enable-disk', action='store_true', default=False, help='build dcpomatic2_disk tool; requires Boost process, lwext4 and nanomsg libraries') + opt.add_option('--enable-grok', action='store_true', default=False, help='build with support for grok J2K encoder') opt.add_option('--warnings-are-errors', action='store_true', default=False, help='build with -Werror') opt.add_option('--wx-config', help='path to wx-config') opt.add_option('--enable-asan', action='store_true', help='build with asan') opt.add_option('--disable-more-warnings', action='store_true', default=False, help='disable some warnings raised by Xcode 15 with the 2.16 branch') + opt.add_option('--c++17', action='store_true', default=False, help='build with C++17 and libxml++-4.0') def configure(conf): conf.load('compiler_cxx') @@@ -89,17 -86,6 +88,17 @@@ if conf.options.target_windows_64 or conf.options.target_windows_32: conf.load('winres') + if vars(conf.options)['c++17']: + cpp_std = '17' + conf.env.XMLPP_API = '4.0' + conf.env.PANGOMM_API = '2.48' + conf.env.CAIROMM_API = '1.16' + else: + cpp_std = '11' + conf.env.XMLPP_API = '2.6' + conf.env.PANGOMM_API = '1.4' + conf.env.CAIROMM_API = '1.0' + # Save conf.options that we need elsewhere in conf.env conf.env.DISABLE_GUI = conf.options.disable_gui conf.env.DISABLE_TESTS = conf.options.disable_tests @@@ -111,12 -97,13 +110,14 @@@ conf.env.DEBUG = conf.options.enable_debug conf.env.STATIC_DCPOMATIC = conf.options.static_dcpomatic conf.env.ENABLE_DISK = conf.options.enable_disk + conf.env.ENABLE_GROK = conf.options.enable_grok if conf.options.destdir == '': conf.env.INSTALL_PREFIX = conf.options.prefix else: conf.env.INSTALL_PREFIX = conf.options.destdir + conf.check_cxx(cxxflags=['-msse', '-mfpmath=sse'], msg='Checking for SSE support', mandatory=False, define_name='SSE') + # Common CXXFLAGS conf.env.append_value('CXXFLAGS', ['-D__STDC_CONSTANT_MACROS', '-D__STDC_LIMIT_MACROS', @@@ -125,13 -112,11 +126,13 @@@ '-Wall', '-Wextra', '-Wwrite-strings', + # getMessengerLogger() in the grok code triggers these warnings + '-Wno-nonnull', '-Wno-error=deprecated', # I tried and failed to ignore these with _Pragma '-Wno-ignored-qualifiers', '-D_FILE_OFFSET_BITS=64', - '-std=c++11']) + '-std=c++' + cpp_std]) if conf.options.disable_more_warnings: # These are for Xcode 15.0.1 with the v2.16.x-era @@@ -145,8 -130,8 +146,8 @@@ if conf.options.warnings_are_errors: conf.env.append_value('CXXFLAGS', '-Werror') - if not conf.options.target_macos_arm64: - conf.env.append_value('CXXFLAGS', '-msse') + if conf.env.SSE: + conf.env.append_value('CXXFLAGS', ['-msse', '-mfpmath=sse']) if conf.options.enable_asan: conf.env.append_value('CXXFLAGS', '-fsanitize=address') @@@ -159,10 -144,8 +160,10 @@@ conf.env.append_value('CXXFLAGS', ['-Wno-cast-function-type']) # Most gccs still give these warnings from boost::optional conf.env.append_value('CXXFLAGS', ['-Wno-maybe-uninitialized']) - if int(gcc[0]) > 4: + if int(gcc[0]) > 8: # gcc 4.8.5 on Centos 7 does not have this warning + # gcc 7.5.0 on Ubuntu 18.04 and gcc 8.3.0 on Debian 10 do, but + # I didn't manage to turn it back off again with a pragma conf.env.append_value('CXXFLAGS', ['-Wsuggest-override']) if conf.options.enable_debug: @@@ -173,9 -156,6 +174,9 @@@ if conf.options.enable_disk: conf.env.append_value('CXXFLAGS', '-DDCPOMATIC_DISK') + if conf.options.enable_grok: + conf.env.append_value('CXXFLAGS', '-DDCPOMATIC_GROK') + if conf.options.use_lld: try: conf.find_program('ld.lld') @@@ -193,7 -173,6 +194,6 @@@ conf.env.append_value('CXXFLAGS', '-DWIN32_LEAN_AND_MEAN') conf.env.append_value('CXXFLAGS', '-DBOOST_USE_WINDOWS_H') conf.env.append_value('CXXFLAGS', '-DBOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN') - conf.env.append_value('CXXFLAGS', '-mfpmath=sse') conf.env.append_value('CXXFLAGS', '-Wcast-align') wxrc = os.popen('wx-config --rescomp').read().split()[1:] conf.env.append_value('WINRCFLAGS', wxrc) @@@ -230,7 -209,6 +230,6 @@@ # Linux if conf.env.TARGET_LINUX: - conf.env.append_value('CXXFLAGS', '-mfpmath=sse') conf.env.append_value('CXXFLAGS', '-DLINUX_LOCALE_PREFIX="%s/share/locale"' % conf.env['INSTALL_PREFIX']) conf.env.append_value('CXXFLAGS', '-DLINUX_SHARE_PREFIX="%s/share"' % conf.env['INSTALL_PREFIX']) conf.env.append_value('CXXFLAGS', '-DDCPOMATIC_LINUX') @@@ -340,10 -318,10 +339,10 @@@ conf.check_cfg(package='fontconfig', args='--cflags --libs', uselib_store='FONTCONFIG', mandatory=True) # pangomm - conf.check_cfg(package='pangomm-1.4', args='--cflags --libs', uselib_store='PANGOMM', mandatory=True) + conf.check_cfg(package='pangomm-' + conf.env.PANGOMM_API, args='--cflags --libs', uselib_store='PANGOMM', mandatory=True) # cairomm - conf.check_cfg(package='cairomm-1.0', args='--cflags --libs', uselib_store='CAIROMM', mandatory=True) + conf.check_cfg(package='cairomm-' + conf.env.CAIROMM_API, args='--cflags --libs', uselib_store='CAIROMM', mandatory=True) # leqm_nrt conf.check_cfg(package='leqm_nrt', args='--cflags --libs', uselib_store='LEQM_NRT', mandatory=True) @@@ -377,7 -355,7 +376,7 @@@ if conf.options.static_dcp: conf.check_cfg(package='libdcp-1.0', args='libdcp-1.0 >= %s --cflags' % libdcp_version, uselib_store='DCP', mandatory=True) conf.env.DEFINES_DCP = [f.replace('\\', '') for f in conf.env.DEFINES_DCP] - conf.env.STLIB_DCP = ['dcp-1.0', 'asdcp-carl', 'kumu-carl', 'openjp2'] + conf.env.STLIB_DCP = ['dcp-1.0', 'asdcp-dcpomatic', 'kumu-dcpomatic', 'openjp2'] conf.env.LIB_DCP = ['glibmm-2.4', 'ssl', 'crypto', 'bz2', 'xslt', 'xerces-c'] else: conf.check_cfg(package='libdcp-1.0', args='libdcp-1.0 >= %s --cflags --libs' % libdcp_version, uselib_store='DCP', mandatory=True) @@@ -394,10 -372,10 +393,10 @@@ # libxml++ if conf.options.static_xmlpp: - conf.env.STLIB_XMLPP = ['xml++-2.6'] + conf.env.STLIB_XMLPP = ['xml++-' + conf.env.XMLPP_API] conf.env.LIB_XMLPP = ['xml2'] else: - conf.check_cfg(package='libxml++-2.6', args='--cflags --libs', uselib_store='XMLPP', mandatory=True) + conf.check_cfg(package='libxml++-' + conf.env.XMLPP_API, args='--cflags --libs', uselib_store='XMLPP', mandatory=True) # libxmlsec if conf.options.static_xmlsec: @@@ -489,7 -467,7 +488,7 @@@ int main () { av_ebur128_get_true_peaks (0); }\n """, msg='Checking for EBUR128-patched FFmpeg', - uselib='AVCODEC AVFILTER', + uselib='AVCODEC AVFILTER AVUTIL SWRESAMPLE', define_name='DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG', mandatory=False) @@@ -673,21 -651,6 +672,21 @@@ def build(bld): create_version_cc(VERSION, bld.env.CXXFLAGS) + # waf can't find these dependencies by itself because they are only included if DCPOMATIC_GROK is defined, + # and I can't find a way to pass that to waf's dependency scanner + if bld.env.ENABLE_GROK: + for dep in ( + 'src/lib/j2k_encoder.cc', + 'src/tools/dcpomatic.cc', + 'src/tools/dcpomatic_server.cc', + 'src/tools/dcpomatic_server_cli.cc', + 'src/tools/dcpomatic_batch.cc' + ): + bld.add_manual_dependency(bld.path.find_node(dep), bld.path.find_node('src/lib/grok/context.h')) + bld.add_manual_dependency(bld.path.find_node(dep), bld.path.find_node('src/lib/grok/messenger.h')) + + bld.add_manual_dependency(bld.path.find_node('src/wx/full_config_dialog.cc'), bld.path.find_node('src/wx/grok/gpu_config_panel.h')) + bld.recurse('src') bld.recurse('graphics')