X-Git-Url: https://main.carlh.net/gitweb/?p=dcpomatic.git;a=blobdiff_plain;f=src%2Flib%2Fffmpeg_content.cc;h=2c2d36a986c6eb3b725b40c9222e38d5f9e043d6;hp=608c8cdb7e31391f8f8fb1ddb0e33919387e6b68;hb=aeb835a18c8df347e0ed68fb24631b320abeb611;hpb=0d65e6ab06f798ca905c0ae5c1d0203ac254377c diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc index 608c8cdb7..2c2d36a98 100644 --- a/src/lib/ffmpeg_content.cc +++ b/src/lib/ffmpeg_content.cc @@ -34,39 +34,44 @@ #include extern "C" { #include +#include } +#include #include +#include #include "i18n.h" -#define LOG_GENERAL(...) film->log()->log (String::compose (__VA_ARGS__), Log::TYPE_GENERAL); +#define LOG_GENERAL(...) film->log()->log (String::compose (__VA_ARGS__), LogEntry::TYPE_GENERAL); using std::string; using std::vector; using std::list; using std::cout; using std::pair; +using std::make_pair; using boost::shared_ptr; using boost::dynamic_pointer_cast; +using boost::optional; int const FFmpegContentProperty::SUBTITLE_STREAMS = 100; int const FFmpegContentProperty::SUBTITLE_STREAM = 101; int const FFmpegContentProperty::FILTERS = 102; -FFmpegContent::FFmpegContent (shared_ptr f, boost::filesystem::path p) - : Content (f, p) - , VideoContent (f, p) - , AudioContent (f, p) - , SubtitleContent (f, p) +FFmpegContent::FFmpegContent (shared_ptr film, boost::filesystem::path p) + : Content (film, p) + , VideoContent (film, p) + , AudioContent (film, p) + , SubtitleContent (film, p) { } -FFmpegContent::FFmpegContent (shared_ptr f, cxml::ConstNodePtr node, int version, list& notes) - : Content (f, node) - , VideoContent (f, node, version) - , AudioContent (f, node) - , SubtitleContent (f, node, version) +FFmpegContent::FFmpegContent (shared_ptr film, cxml::ConstNodePtr node, int version, list& notes) + : Content (film, node) + , VideoContent (film, node, version) + , AudioContent (film, node) + , SubtitleContent (film, node, version) { list c = node->node_children ("SubtitleStream"); for (list::const_iterator i = c.begin(); i != c.end(); ++i) { @@ -95,14 +100,26 @@ FFmpegContent::FFmpegContent (shared_ptr f, cxml::ConstNodePtr node, } } - _first_video = node->optional_number_child ("FirstVideo"); + optional const f = node->optional_number_child ("FirstVideo"); + if (f) { + _first_video = ContentTime (f.get ()); + } + + _color_range = static_cast (node->optional_number_child("ColorRange").get_value_or (AVCOL_RANGE_UNSPECIFIED)); + _color_primaries = static_cast (node->optional_number_child("ColorPrimaries").get_value_or (AVCOL_PRI_UNSPECIFIED)); + _color_trc = static_cast ( + node->optional_number_child("ColorTransferCharacteristic").get_value_or (AVCOL_TRC_UNSPECIFIED) + ); + _colorspace = static_cast (node->optional_number_child("Colorspace").get_value_or (AVCOL_SPC_UNSPECIFIED)); + _bits_per_pixel = node->optional_number_child ("BitsPerPixel"); + } -FFmpegContent::FFmpegContent (shared_ptr f, vector > c) - : Content (f, c) - , VideoContent (f, c) - , AudioContent (f, c) - , SubtitleContent (f, c) +FFmpegContent::FFmpegContent (shared_ptr film, vector > c) + : Content (film, c) + , VideoContent (film, c) + , AudioContent (film, c) + , SubtitleContent (film, c) { shared_ptr ref = dynamic_pointer_cast (c[0]); DCPOMATIC_ASSERT (ref); @@ -150,6 +167,14 @@ FFmpegContent::as_xml (xmlpp::Node* node) const if (_first_video) { node->add_child("FirstVideo")->add_child_text (raw_convert (_first_video.get().get())); } + + node->add_child("ColorRange")->add_child_text (raw_convert (_color_range)); + node->add_child("ColorPrimaries")->add_child_text (raw_convert (_color_primaries)); + node->add_child("ColorTransferCharacteristic")->add_child_text (raw_convert (_color_trc)); + node->add_child("Colorspace")->add_child_text (raw_convert (_colorspace)); + if (_bits_per_pixel) { + node->add_child("BitsPerPixel")->add_child_text (raw_convert (_bits_per_pixel.get ())); + } } void @@ -172,7 +197,7 @@ FFmpegContent::examine (shared_ptr job) if (!_subtitle_streams.empty ()) { _subtitle_stream = _subtitle_streams.front (); } - + _audio_streams = examiner->audio_streams (); if (!_audio_streams.empty ()) { @@ -182,6 +207,12 @@ FFmpegContent::examine (shared_ptr job) } _first_video = examiner->first_video (); + + _color_range = examiner->color_range (); + _color_primaries = examiner->color_primaries (); + _color_trc = examiner->color_trc (); + _colorspace = examiner->colorspace (); + _bits_per_pixel = examiner->bits_per_pixel (); } signal_changed (FFmpegContentProperty::SUBTITLE_STREAMS); @@ -214,7 +245,7 @@ FFmpegContent::technical_summary () const } string filt = Filter::ffmpeg_string (_filters); - + return Content::technical_summary() + " - " + VideoContent::technical_summary() + " - " + AudioContent::technical_summary() + " - " @@ -252,7 +283,7 @@ FFmpegContent::full_length () const shared_ptr film = _film.lock (); DCPOMATIC_ASSERT (film); FrameRateChange const frc (video_frame_rate (), film->video_frame_rate ()); - return DCPTime::from_frames (rint (video_length_after_3d_combine() * frc.factor()), film->video_frame_rate()); + return DCPTime::from_frames (llrint (video_length_after_3d_combine() * frc.factor()), film->video_frame_rate()); } void @@ -271,7 +302,8 @@ FFmpegContent::identifier () const { SafeStringStream s; - s << VideoContent::identifier(); + s << VideoContent::identifier() << "_" + << SubtitleContent::identifier(); boost::mutex::scoped_lock lm (_mutex); @@ -298,7 +330,13 @@ FFmpegContent::subtitles_during (ContentTimePeriod period, bool starting) const } bool -FFmpegContent::has_subtitles () const +FFmpegContent::has_text_subtitles () const +{ + return false; +} + +bool +FFmpegContent::has_image_subtitles () const { return !subtitle_streams().empty (); } @@ -321,8 +359,106 @@ vector FFmpegContent::audio_streams () const { boost::mutex::scoped_lock lm (_mutex); - + vector s; copy (_audio_streams.begin(), _audio_streams.end(), back_inserter (s)); return s; } + +void +FFmpegContent::add_properties (list >& p) const +{ + VideoContent::add_properties (p); + + if (_bits_per_pixel) { + int const sub = 219 * pow (2, _bits_per_pixel.get() - 8); + int const total = pow (2, _bits_per_pixel.get()); + + switch (_color_range) { + case AVCOL_RANGE_UNSPECIFIED: + p.push_back (make_pair (_("Colour range"), _("Unspecified"))); + break; + case AVCOL_RANGE_MPEG: + p.push_back (make_pair (_("Colour range"), String::compose (_("Limited (%1-%2)"), (total - sub) / 2, (total + sub) / 2))); + break; + case AVCOL_RANGE_JPEG: + p.push_back (make_pair (_("Colour range"), String::compose (_("Full (0-%1)"), total))); + break; + default: + DCPOMATIC_ASSERT (false); + } + } else { + switch (_color_range) { + case AVCOL_RANGE_UNSPECIFIED: + p.push_back (make_pair (_("Colour range"), _("Unspecified"))); + break; + case AVCOL_RANGE_MPEG: + p.push_back (make_pair (_("Colour range"), _("Limited"))); + break; + case AVCOL_RANGE_JPEG: + p.push_back (make_pair (_("Colour range"), _("Full"))); + break; + default: + DCPOMATIC_ASSERT (false); + } + } + + char const * primaries[] = { + _("Unspecified"), + _("BT709"), + _("Unspecified"), + _("Unspecified"), + _("BT470M"), + _("BT470BG"), + _("SMPTE 170M (BT601)"), + _("SMPTE 240M"), + _("Film"), + _("BT2020") + }; + + DCPOMATIC_ASSERT (AVCOL_PRI_NB == 10); + p.push_back (make_pair (_("Colour primaries"), primaries[_color_primaries])); + + char const * transfers[] = { + _("Unspecified"), + _("BT709"), + _("Unspecified"), + _("Unspecified"), + _("Gamma 22 (BT470M)"), + _("Gamma 28 (BT470BG)"), + _("SMPTE 170M (BT601)"), + _("SMPTE 240M"), + _("Linear"), + _("Logarithmic (100:1 range)"), + _("Logarithmic (316:1 range)"), + _("IEC61966-2-4"), + _("BT1361 extended colour gamut"), + _("IEC61966-2-1 (sRGB or sYCC)"), + _("BT2020 for a 10-bit system"), + _("BT2020 for a 12-bit system") + }; + + DCPOMATIC_ASSERT (AVCOL_TRC_NB == 16); + p.push_back (make_pair (_("Colour transfer characteristic"), transfers[_color_trc])); + + char const * spaces[] = { + _("RGB / sRGB (IEC61966-2-1)"), + _("BT709"), + _("Unspecified"), + _("Unspecified"), + _("FCC"), + _("BT470BG (BT601-6)"), + _("SMPTE 170M (BT601-6)"), + _("SMPTE 240M"), + _("YCOCG"), + _("BT2020 non-constant luminance"), + _("BT2020 constant luminance"), + }; + + DCPOMATIC_ASSERT (AVCOL_SPC_NB == 11); + p.push_back (make_pair (_("Colourspace"), spaces[_colorspace])); + + if (_bits_per_pixel) { + p.push_back (make_pair (_("Bits per pixel"), raw_convert (_bits_per_pixel.get ()))); + } +}